/*\ title: $:/core/modules/new_widgets/widget.js type: application/javascript module-type: new_widget Widget base class \*/ (function(){ /*jslint node: true, browser: true */ /*global $tw: false */ "use strict"; /* Create a widget object for a parse tree node parseTreeNode: reference to the parse tree node to be rendered options: see below Options include: wiki: mandatory reference to wiki associated with this render tree variables: optional hashmap of context variables (see below) parentWidget: optional reference to a parent renderer node for the context chain document: optional document object to use instead of global document Context variables include: currentTiddler: title of the tiddler providing the context */ var Widget = function(parseTreeNode,options) { if(arguments.length > 0) { this.initialise(parseTreeNode,options); } }; /* Initialise widget properties. These steps are pulled out of the constructor so that we can reuse them in subclasses */ Widget.prototype.initialise = function(parseTreeNode,options) { options = options || {}; // Save widget info this.parseTreeNode = parseTreeNode; this.wiki = options.wiki; this.variables = options.variables || {}; this.parentWidget = options.parentWidget; this.document = options.document; this.attributes = {}; this.children = []; this.domNodes = []; this.eventListeners = {}; // Hashmap of the widget classes if(!this.widgetClasses) { Widget.prototype.widgetClasses = $tw.modules.applyMethods("new_widget"); } }; /* Render this widget into the DOM */ Widget.prototype.render = function(parent,nextSibling) { this.parentDomNode = parent; this.execute(); this.renderChildren(parent,nextSibling); }; /* Compute the internal state of the widget */ Widget.prototype.execute = function() { this.makeChildWidgets(); }; /* Get the prevailing value of a context variable name: name of variable options: see below Options include params: array of {name:, value:} for each parameter defaultValue: default value if the variable is not defined */ Widget.prototype.getVariable = function(name,options) { options = options || {}; var actualParams = options.params || []; // Search up the widget tree for the variable name var node = this; while(node && !$tw.utils.hop(node.variables,name)) { node = node.parentWidget; } // If we get to the root then look for a macro module if(!node) { return this.evaluateMacroModule(name,actualParams,options.defaultValue); } // Get the value var value = node.variables[name].value || ""; // Substitute any parameters specified in the definition value = this.substituteVariableParameters(value,node.variables[name].params,actualParams); value = this.substituteVariableReferences(value); return value; }; Widget.prototype.substituteVariableParameters = function(text,formalParams,actualParams) { if(formalParams) { var nextAnonParameter = 0, // Next candidate anonymous parameter in macro call paramInfo, paramValue; // Step through each of the parameters in the macro definition for(var p=0; p 0) { return this.domNodes[0]; } // Otherwise, recursively call our children for(var t=0; t