UNPKG

dashboard

Version:

Create dashboards with gadgets on node.js

864 lines (763 loc) 28.1 kB
<?xml version="1.0" encoding="UTF-8" ?> <!-- data_gadget.xml --> <!-- Author: Ian Smith (imsmith@uw.edu) --> <Module> <ModulePrefs title="DataGadget v0.1" height="90"> <Require feature="dynamic-height"/> <Require feature="opensocial-0.9"/> <Require feature="minimessage"/> <Require feature="settitle"/> </ModulePrefs> <Content type="html"><![CDATA[ <!-- Set title so the DataInterface can find this gadget. This how we identify ourselves, so we must do it first! --> <title>DataGadgetv0.1</title> <div id="divHeader" class="dgHeader"> DataGadget v0.1 </div> <div id="divNamespaceInfo" class="hidden"> </div> <link rel="stylesheet" type="text/css" href="css/dgGadget.css" /> <style type="text/css"> .hidden { display:none; } .dgHeader { font-style:underline; } .dgInfoList { padding:5px; margin:5px; font-size:small; font-weight:bold; background-color:#f0fcff; border-style:solid; border-width:1px; } .dgInfoList ul { font-size:small; font-weight:normal; margin: 0px; } </style> <script type="text/javascript"> /** * Global DataGadget object */ var dg = null; // CONSTANTS /** * Number of seconds to display miniMessages */ var MM_TIMER_DURATION = 4; /** * If true, then write debug messages to console */ var DEBUG = false; /** * Writes to the console of DEBUG is true */ function debugLog(msg){ if (DEBUG && window.console && console.log) { console.log(msg); } } // INIT function init(){ gadgets.window.setTitle("Data Gadget"); dg = new DataGadget(); gadgets.window.adjustHeight(); } /** * @class Trigger * A Trigger contains the gadget name and callback that is executed within * the context of the gadget when an event occurs. * For example: when a datagadget variable is modified, a trigger registered * to that variable is executed. */ /** * @constructor * @param {string} gadgetName Name of gadget registering the trigger * @param {function} func Callback function executed by trigger */ function Trigger(gadgetName, func){ var my = new Object(); // Callback function that is executed var cbFunc = func; // Gadget that created this trigger var cbGadget = gadgetName; debugLog("Creating New Trigger"); // METHODS /** * Gets the name of the gadget that created the trigger * @return {string} Name of gadget */ my.getGadget = function(){ return cbGadget; } /** * Executes the trigger (executes the callback function) */ my.executeTrigger = function(){ debugLog("executing trigger: " + cbFunc.toString()); cbFunc(); } /** * Returns the callback function * @return {function} The callback function for this trigger */ my.returnTrigger = function(){ return cbFunc; } /** * Returns a string representation of the trigger (currently * only the name of the gadget that registered the trigger * @return {string} String representation of the trigger */ my.toString = function(){ return cbGadget; } return my; } // end Trigger class /** * @class DataGadgetVariable * A DataGadgetVariable is a public variable stored in the datagadget. * The variable has a name (by which it is identified for reading and writing), * value, * list of names of gadgets that are registered to read and write to the variable, * and a list of triggers that are executed sequentially when the variable is * modified by the "setValue" method */ /** * Create a DataGadgetVariable object * @constructor * @param {string} name Name of the DataGadgetVariable * @param {object} value Any type of object to be stored in the variable * @param {string} gadgetName Name of gadget that created the variable */ function DataGadgetVariable(name, value, gadgetName){ var my = new Object(); /** * Array of callback Triggers to call when this variable is modified */ var triggerList = []; /** * Array of gadget names that registered this variable. * Creator is added first. */ var gadgetList = [ gadgetName ]; /** * Name of the DataGadgetVariable */ var varName = name; /** * Value of the variable */ var varValue = value; /** * @private * Returns true iff the gadget name is in the list of registered gadgets * @param {string} gadgetName Name of gadget to check if registered * @return {boolean} True iff gadget name is registered */ function isGadgetRegistered(gadgetName){ for (var i=0, len=gadgetList.length; i<len; i++) { if (gadgetList[i].toString() === gadgetName) { // Found it return true; } } // Not found return false; } // METHODS /** * Returns name of DataGadgetVariable * @return {string} Name of DataGadgetVariable */ my.getName = function(){ return varName; } /** * Returns value of the DataGadgetVariable * @return {object} Value of DataGadgetVariable */ my.getValue = function(){ return varValue; } /** * Sets the value of the DataGadgetVariable and executes all triggers associated with the * variable EXCEPT for triggers registered to the gadget that is setting the value * @param {string} Name of gadget setting the value * @param {object} Object to set the new value of the variable to * @return {boolean} True if no errors, False if gadget trying to set the value is not registered */ my.setValue = function(gadgetName, value){ if (!isGadgetRegistered(gadgetName)) { // Gadget not in list debugLog('Cannot write to variable "' + varName + '" because the gadget "' + gadgetName + '" has not registered this variable!'); return false; } // Set the value varValue = value; // Execute all triggers except for triggers set by 'gadgetName' for (var i=0, len = triggerList.length; i<len; i++){ // Dont execute triggers for the gadget that is setting value if (triggerList[i].getGadget() !== gadgetName){ triggerList[i].executeTrigger(); } } // Everything went OK return true; } /** * Adds a gadget to the list of gadgets registered to this variable * or does nothing if the gadget is already registered * @param {string} gadgetName Name of gadget to add to registration list */ my.addGadget = function(gadgetName) { if (!isGadgetRegistered(gadgetName)) { gadgetList.push(gadgetName); } } /** * Adds a new trigger to this variable * @param {string} gadgetName Name of gadget creating trigger * @param {function} callback Callback function for this trigger * @return {boolean} True iff trigger was created successfully * TODO: Return a unique trigger ID so this trigger can be destroyed later? * That might be a difficult change to make since we return booleans all the way * up the stack. */ my.addTrigger = function(gadgetName, callback){ if (isGadgetRegistered(gadgetName)){ newTrig = new Trigger(gadgetName, callback); triggerList.push(newTrig); return true; } else { // Gadget not in list debugLog('Cannot register trigger on "' + varName + '" because the gadget "' + gadgetName + '" has not registered this variable!'); return false; } } /** * NOTE: Not Implemented * Removes a trigger from the list * @param {integer} triggerId ID of trigger to remove * @return {boolean} True iff triggerId is found and trigger with triggerId was * successfully removed */ my.removeTrigger = function(triggerId){ throw "DataGadgetVariable.removeTrigger() Not implemented"; } /** * Returns a string of info about this DataGadgetVariable * Specifically: * An HTML bulleted list of gadgets registered * An HTML bulleted list of trigger info * @return {string} Info about variable */ my.printInfoList = function(){ var txtElem = []; // Add varName txtElem.push(varName + "<ul>" + "<li>Gadgets:</li>" + "<ul>"); // Add the gadgets, and close with a </ul> for (var i=0, len=gadgetList.length; i<len; i++){ txtElem.push("<li>" + gadgetList[i].toString() + "</li>"); } txtElem.push("</ul>"); // end gadgets // Add triggers txtElem.push('<li>Triggers:</li>' + '<ul>'); for (var i=0, len=triggerList.length; i<len; i++){ txtElem.push('<li>' + triggerList[i].toString() + '</li>'); } txtElem.push('</ul>'); // end triggers txtElem.push('</ul>'); // end this variable return txtElem.join(''); } return my; } // end DataGadgetVariable class /** * @class Namespace * Represents a namespace to which gadgets and DataGadgetVariables * are registered. * Gadgets in a Namespace can read and write variables in that Namespace. */ /** * @constructor * Creates a new Namespace object in which to register * gadgets and DataGadgetVariables * @param {string} name Name of the new Namespace */ function Namespace(name) { var my = new Object(); // PRIVATE /** * List of gadgets registered to the Namespace */ var gadgetList = []; /** * list of DataGadgetVariables registered to the Namespace */ var dgVarList = []; /** * Name of the Namespace */ var nsName = name; /** * @private * Returns DataGadgetVariable if it exists, otherwise * returns null * @param {string} varName Name of DataGadgetVariable to find * @return {object} The DataGadgetVariable if it exists, or else null */ function findDGVar(varName) { for (var i=0, len=dgVarList.length; i<len; i++) { if (dgVarList[i].getName() === varName) { return dgVarList[i]; } } // not found, return null return null; } // METHODS /** * Get the name of the Namespace * @return {string} Name of the Namespace */ my.getName = function(){ return nsName; } // Gadget Methods /** * Returns true iff gadget is currently registered in this namespace * @param {string} gadgetName Name of gadget to search for in Namespace * @return {boolean} True iff gadget is currently registered in this Namespace */ my.isGadgetRegistered = function(gadgetName){ var len = gadgetList.length; for (i=0; i<len; i++){ if (gadgetList[i] === gadgetName){ return true; } } return false; } /** * Registers a gadget to this Namespace * @param {string} gadgetName Name of gadget to register */ my.registerGadget = function(gadgetName){ // Check if gadget currently exists in this namespace if (my.isGadgetRegistered(gadgetName)){ debugLog("gadget '" + gadgetName + "' is already registered in\nNamespace '" + nsName + "'"); } else { // Is not yet registered, so add it gadgetList.push(gadgetName); debugLog("gadget '" + gadgetName + "' is now registered in\nNamespace '" + nsName + "'"); } } /** * Removes a gadget from the Namespace by name * @param {string} gadgetName Name of gadget to remove * @return {boolean} True if successfully removed, or false if gadget not found * in the Namespace */ my.dropGadget = function(gadgetName){ // Find gadget and drop it // TODO: we should also delete all the triggers for that gadget! var len = gadgetList.length; for (i=0; i<len; i++){ if (gadgetList[i] === gadgetName){ // Remove this element gadgetList.splice(i,1); // Just in case there are duplicates, we should look through entire array debugLog("gadget '" + gadgetName + "' is now removed from\nNamespace '" + nsName+ "'\nCurrent Gadget List: " + gadgetList.toString()); return true; } } return false; } // DataGadgetVar Methods /** * Create a new DataGadgetVariable in the Namespace (only if the gadget is registered * to the Namespace) * @param {string} gadgetName Name of gadget registering variable * @param {string} varName Name to call DataGadgetVariable * @param {object} varValue Object to store in new variable * @return {boolean} True if variable is successfully registered, otherwise false. * If the gadget is not registered to the namespace, then false will be returned. */ my.registerVariable = function(gadgetName, varName, varValue){ if (my.isGadgetRegistered(gadgetName)) { var dv = findDGVar(varName); if (dv === null) { // Variable doesnt exist, so make it and add it to the list var dgVar = new DataGadgetVariable(varName, varValue, gadgetName); dgVarList.push(dgVar); } else { // Variable already exists, so add gadget to the variable dv.addGadget(gadgetName); } return true; } else { // Gadget not registered to this Namespace alert('Cannot register variable "' + varName + '." First register the gadget "' + gadgetName + '" in the namespace "' + nsName +'."'); return false; } } /** * Writes a value to a DataGadgetVariable * @param {string} gadgetName Name of gadget writing variable * @param {string} varName Name of DataGadgetVariable to write to * @param {object} varValue Object to set variable value to * @return {boolean} Returns true iff value was set correctly. Returns false * if variable doens't exist or if the gadget is not regirstered to the Namespace */ my.writeVariable = function(gadgetName, varName, varValue){ if (my.isGadgetRegistered(gadgetName)) { var dv = findDGVar(varName); if (dv !== null) { // write it! return dv.setValue(gadgetName, varValue); } else { // dgVar doesn't exist, so log it debugLog('Cannot write variable "' + varName + '" because it does not exist. First register the variable in the namespace "' + nsName +'."'); return false; } } else { // gadget not registered debugLog('Cannot write variable "' + varName + '." First register the gadget "' + gadgetName + '" in the namespace "' + nsName +'."'); return false; } return false; } /** * Returns the value of the DataGadgetVariable * @param {string} gadgetName Name of gadget reading variable * @param {string} varName Name of variable to write to * @return {object} Returns the value of the variable (or undefined if * varName doesnt exist or if gadget is not registered in namespace) */ my.readVariable = function(gadgetName, varName){ if (my.isGadgetRegistered(gadgetName)) { var dv = findDGVar(varName); if (dv !== null) { // read it! return dv.getValue(); } else { // dgVar doesn't exist, so log it debugLog('Cannot read variable "' + varName + '" because it does not exist. First register the variable in the namespace "' + nsName +'."'); return undefined; } } else { // gadget not registered debugLog('Cannot read variable "' + varName + '." First register the gadget "' + gadgetName + '" in the namespace "' + nsName +'."'); return undefined; } return undefined; } // Trigger Methods /** * Registers a trigger to a variable * @param {string} gadgetName Name of gadget registering trigger * @param {string} varName Name of variable to register trigger for * @param {function} triggerCallback Callback function for trigger * @return {boolean} Returns true if trigger added successfully, false if variable * doesnt exist or if gadget not registered in the namespace * TODO: return the triggerID of the trigger created. */ my.registerTrigger = function(gadgetName, varName, triggerCallback){ if (my.isGadgetRegistered(gadgetName)) { var dv = findDGVar(varName); if (dv !== null) { // register it! return dv.addTrigger(gadgetName, triggerCallback); } else { // dgVar doesn't exist, so log it debugLog('Cannot register trigger on variable "' + varName + '" because it does not exist. First register the variable in the namespace "' + nsName +'."'); return false; } } // gadget not registered debugLog('Cannot register trigger for variable "' + varName + '." First register the gadget "' + gadgetName + '" in the namespace "' + nsName +'."'); return false; } // Display Methods /** * Returns a list of info about the gadgets in the namespace, and * the variables registered. * @return {string} String representing gadgets and variables registered * in the namespace */ my.printInfoList = function(){ var txtElem = []; // Print gadgets list // begin namespace txtElem.push(nsName + "<ul>" + "<li>Gadgets:</li>" + "<ul>"); // add the gadgets, and close with a </ul></ul> for (var i=0, len=gadgetList.length; i<len; i++){ txtElem.push("<li>" + gadgetList[i].toString() + "</li>"); } txtElem.push("</ul>"); // end gadgets // add variables txtElem.push('<li>Variables:</li>' + '<ul>'); for (var i=0, len=dgVarList.length; i<len; i++){ txtElem.push('<li>' + dgVarList[i].printInfoList() + '</li>'); } txtElem.push('</ul>'); // end vars txtElem.push('</ul>'); // end namespace return txtElem.join(''); } return my; } // end Namespace class /** * @class DataGadget * The DataGadget contains multiple Namespaces, which each contain DataGadgetVariables * Interactions with namespaces can only be done by gadgets registered to the * namespace */ /** * @constructor * Creates a new DataGadget object */ function DataGadget() { var my = new Object(); // CONSTANTS var DATAGADGET_TITLE = "DataGadgetv0.1", DIV_NAMESPACE_INFO = "divNamespaceInfo", SHOW_INFO = false; // PRIVATE /** * Array of current active namespaces */ var nsList = []; // Private helper objects for the gadget /** * MiniMessage to display information about registration on the gadget */ var miniMsg = new gadgets.MiniMessage(); /** * @private * Returns namespace if it exists in the array * @param {string} nsName Name of Namespace to search for * @return {Namespace} Returns the Namespace with the name being searched for, or * null if not found */ // function findNamespace(nsName){ var len = nsList.length; for (i=0; i<len; i++){ if (nsList[i].getName() === nsName){ return nsList[i]; } } return null; } // Display /** * Print a ul (HTML bulleted unordered list) version of the properties of each * Namespace in a div. Then adjust the size of the DataGadget so the info fits. */ function updateNamespaceInfo(){ if (SHOW_INFO) { // find Div we will eventually write to var nsDiv = window.document.getElementById(DIV_NAMESPACE_INFO); var nsInfoHTML = []; nsInfoHTML.push("Namespaces:"); nsInfoHTML.push("<ul>"); for (var i=0, len=nsList.length; i<len; i++){ // append to the fragment the text generated by the namespaces nsInfoHTML.push("<li>" + nsList[i].printInfoList() + "</li>"); } nsInfoHTML.push("</ul>"); // add the fragment to the div to display it nsDiv.innerHTML = nsInfoHTML.join(''); // move from the 'hidden' into the 'dgInfoList' class nsDiv.className = "dgInfoList"; // resize height of gadget gadgets.window.adjustHeight(); } } // METHODS // Namespace Methods /** * NOTE: Not Implemented * Return a list of the names of the namespaces * NOTE: This should only return a list of string names, NOT the * actual list of Namespaces * @return {string[]} Returns an array of strings containing the names * of the Namespaces in the DataGadget */ my.getNamespaceList = function(){ throw "DataGadget.getNamespaceList() is not implemented!" } /** * NOTE: Not Implemented * */ my.createNamespace = function(name){ // check to see if namespace already exists // if doesn't exist, create the namespace // and add to nsList // ns = new Namespace(name); } my.deleteNamespace = function(namespace){ throw "DataGadget.deleteNamespace() is not implemented!" } my.addGadgetToNamespace = function(name, namespace){ throw "DataGadget.addGadgetToNamespace() is not implemented!" } my.removeGadgetFromNamespace = function(name, namespace){ throw "DataGadget.removeGadgetFromNamespace() is not implemented!" } my.removeGadgetFromAllNamespaces = function(name){ throw "DataGadget.removeGadgetFromAllNamespaces() is not implemented!" } my.switchGadgetNamespace = function(name, namespace){ throw "DataGadget.switchGadgetNamespace() is not implemented!" } // GETS /** * Returns array of strings of gadget's current namespaces * @param {string} gadgetName Name of gadget who's namespaces to get * @return {Array[string]} Array of strings of gadget's current namespaces */ my.getGadgetNamespaces = function(gadgetName){ throw "DataGadget.getGadgetNamespaces() is not implemented!" } // GADGET METHODS /** * Registers a gadget to a namespace. If the namespace does not exist, * a new one of specified name is created and the gadget is registered to it. * @param {string} Name of gadget to register * @param {string} Name of namespace in which to register gadget */ my.registerGadget = function(gadgetName, namespace){ var ns = findNamespace(namespace); if (ns !== null){ ns.registerGadget(gadgetName); } else { ns = new Namespace(namespace); ns.registerGadget(gadgetName); nsList.push(ns); } // print on page updateNamespaceInfo(); } // VARIABLE METHODS /** * Registers a gadget to a variable in a specified namespace. * Throws an exception if the namespace doesn't exist. * @param {string} gadgetName Name of gadget to register to variable. * @param {string} namespaceName Namspace name in which gadget and variable are registered. * @param {string} varName Name of variable to register gadget to. * @param {object} varValue Value to set to the variable * @return {boolean} Returns true if the registration is successful, otherwise false */ my.registerVariable = function(gadgetName, namespaceName, varName, varValue){ var ns = findNamespace(namespaceName); if (ns !== null) { // return true if successful, false if not if (ns.registerVariable(gadgetName, varName, varValue)) { updateNamespaceInfo(); return true; } else { // something went wrong return false; } } // namespace not found throw('Namespace "' + namespaceName + '" does not exist yet. Register the gadget "' + gadgetName + '" to the namespace before registering variables.'); return false; } var gadgetList = {}; my.addGadget = function(id){ if(gadgetList.id==undefined){ gadgetList.id = {}; console.log("Declared Component " + id); } else{ console.log("Declared Component " + id + "id already exists. Id must be unique"); } } /** * Writes a value to a variable (which executes triggers on that variable). * All triggers on a variable are executed EXCEPT for triggers that were created by * the gadget that is doing the writing. * @param {string} gadgetName Name of gadget writing to variable. * @param {string} namespaceName Namspace name in which gadget and variable are registered. * @param {string} varName Name of variable to write to. * @param {object} varValue Value to write to the variable * @return {boolean} Returns true if the write is successful, otherwise false */ my.writeVariable = function(gadgetName, namespaceName, varName, value){ var ns = findNamespace(namespaceName); if (ns !== null) { return ns.writeVariable(gadgetName, varName, value); } } /** * Returns the value of a variable * @param {string} gadgetName Name of gadget reading the variable. * @param {string} namespaceName Namspace name in which gadget and variable are registered. * @param {string} varName Name of variable to read. * @return {object} Return value of the variable */ my.readVariable = function(gadgetName, namespaceName, varName){ var ns = findNamespace(namespaceName); if (ns !== null) { return ns.readVariable(gadgetName, varName); } } // TRIGGER METHODS /** * Registers a trigger on a variable. The trigger is a callback function that is * executed every time the variable is written to by "writeVariable()". * @param {string} gadgetName Name of gadget creating the trigger. * @param {string} namespaceName Namspace name in which gadget and variable are registered. * @param {string} varName Name of variable to read. * TODO: @return {integer} TODO: return an ID to this trigger, so it can be deleted later */ my.registerTrigger = function(gadgetName, namespaceName, varName, triggerCallback){ // TODO: return triggerID var ns = findNamespace(namespaceName); if (ns !== null) { if (ns.registerTrigger(gadgetName, varName, triggerCallback)){ updateNamespaceInfo(); return true; } else { return false; } } } // NOT IMPLEMENTED // TODO: When triggers are created, they currently don't return an ID. // But they should so this method can delete the triggers by an ID my.unregisterTrigger = function(triggerID){ throw "DataGadget.unregisterTrigger() is not implemented!" } return my; } // DataGadget class gadgets.util.registerOnLoadHandler(init); </script> ]]></Content> </Module>