home *** CD-ROM | disk | FTP | other *** search
/ Chip 2011 November / CHIP_2011_11.iso / Programy / Narzedzia / AIMP2 / aimp_2.61.583.exe / $TEMP / YandexPackSetup.msi / fil62A122E1531034C084C81A23EACB45AC < prev    next >
Text File  |  2010-07-12  |  28KB  |  724 lines

  1. XB._Parser = {
  2. };
  3.  
  4. XB._Parser.EWidgetSyntax = CustomErrors.ECustom.extend({
  5.     $name: "EWidgetSyntax",
  6.     
  7.     constructor: function EWidgetSyntax_constructor(elementName) {
  8.         this.base("XB widget parse error");
  9.         this._elementName = elementName.toString();
  10.     },
  11.     
  12.     get _details() {
  13.         return [this._elementName];
  14.     },
  15.     
  16.     _elementName: undefined
  17. });
  18.  
  19. XB._Parser.ENoXBName = XB._Parser.EWidgetSyntax.extend({
  20.     $name: "ENoXBName"
  21. });
  22.  
  23. XB._Parser.ENoXBFunction = XB._Parser.EWidgetSyntax.extend({
  24.     $name: "ENoXBFunction"
  25. });
  26.  
  27. XB._Parser.Unit = function XBUnit_constructor(xmlDoc, package_, name, logRoot) {
  28.     if ( !(package_ instanceof XB.WidgetPackage) )
  29.         throw new CustomErrors.EArgType("package_", "XB.WidgetPackage", typeof package_);
  30.     if (!sysutils.isString(name) || name.length < 1)
  31.         throw new CustomErrors.EArgType("name", "String", typeof name);
  32.     this._package = package_;
  33.     this._name = name;
  34.     this._logger = XB._base.application.core.Log4Moz.repository.getLogger(logRoot + "." + name);
  35.     
  36.     this._loadFromDoc(xmlDoc);
  37. };
  38.  
  39. XB._Parser.Unit.prototype = {
  40.     constructor: XB._Parser.Unit,
  41.     
  42.     get name() {
  43.         return this._name;
  44.     },
  45.     
  46.     get unitPackage() {
  47.         return this._package;
  48.     },
  49.     
  50.     get widgetProto() {
  51.         if (!this._widgetProto && this._widgetProtoParseError)
  52.             throw this._widgetProtoParseError;
  53.         return this._widgetProto;
  54.     },
  55.     
  56.     finalize: function() {
  57.         this._widgetProto = null;
  58.         this._widgetProtoParseError = undefined;
  59.         this._name = undefined;
  60.         this._package = null;
  61.         this._logger = null;
  62.     },
  63.     
  64.     _loadFromDoc: function XBUnit_loadFromDoc(unitDoc) {
  65.         if ( !(unitDoc instanceof Ci.nsIDOMDocument) )
  66.             throw new CustomErrors.EArgType("unitDoc", "nsIDOMDocument", typeof unitDoc);
  67.         if (unitDoc.documentElement.localName != XB._base.consts.STR_WIDGET_ELEMENT_NAME)
  68.             throw new XB._Parser.EWidgetSyntax(unitDoc.documentElement.nodeName);
  69.         
  70.         try {
  71.             this._widgetProto = this._parseWidgetElement(unitDoc.documentElement);
  72.         }
  73.         catch (e) {
  74.             this._widgetProtoParseError = e;
  75.             this._logger.error(this._consts.ERR_PARSING_WIDGET + ". " + misc.formatError(e));
  76.         }
  77.     },
  78.     
  79.     _consts: {
  80.         STR_UNIT_NODE_NAME: "unit",
  81.         STR_WIDGET_NAME_ATTR_NAME: "name",
  82.         STR_FUNC_PARAM_ELEM_NAME: "param",
  83.         STR_DEBUGMODE_ATTR_NAME: "__debug",
  84.         
  85.         WARN_UNKNOWN_TOKEN: "Unknown token",
  86.         WARN_WIDGET_ALREADY_REGISTERED: "This unit already parsed a widget",
  87.         WARN_DUPLICATE_ARG: "Duplicate argument",
  88.         
  89.         ERR_NO_WIDGET_ID: "No widget ID",
  90.         ERR_NO_WIDGET_NAME: "No widget name",
  91.         ERR_NO_DATA_NAME: "Unnamed data declaration",
  92.         ERR_NO_VAR_NAME: "Unnamed variable declaration",
  93.         ERR_NO_SETTING_NAME: "Unnamed setting",
  94.         ERR_PARSING_WIDGET: "An error occured while parsing widget",
  95.         ERR_PARSING_FUNC_NODE: "An error occured while parsing node",
  96.         ERR_INVALID_SCOPE: "Invalid scope definition",
  97.         ERR_WPACKAGE_REQUIRED: "Widget package required",
  98.         ERR_VALNODE_AMBIGUITY: "Value node has both a value attribute and a child node(s)",
  99.         ERR_UNKNOWN_VALUE_TYPE: "Unknown value type"
  100.     },
  101.     _name: undefined,
  102.     _logger: null,
  103.     _widgetProto: null,
  104.     _widgetProtoParseError: undefined,
  105.     _package: null,
  106.     _nodeUID: 1,
  107.     
  108.     _parseWidgetElement: function XBUnit_parseWidgetElement(widgetElement) {
  109.         var widgetName = widgetElement.getAttribute(this._consts.STR_WIDGET_NAME_ATTR_NAME);
  110.         if (!widgetName)
  111.             throw new XB._Parser.ENoXBName(widgetElement.nodeName);
  112.         
  113.         var protoID = this.unitPackage.id + "#" + this.name;
  114.         var widgetProto = new XB._Parser.Unit.WidgetPrototype(protoID, widgetElement, this);
  115.         
  116.         var treeWalker = widgetElement.ownerDocument
  117.             .createTreeWalker(widgetElement, XB._Ci.nsIDOMNodeFilter.SHOW_ALL, this._nodeFilter, true);
  118.         
  119.         if (treeWalker.firstChild()) {
  120.             do {
  121.                 var subNode = treeWalker.currentNode;
  122.                 if (subNode.namespaceURI == XB._base.consts.STR_FUNCTIONAL_NS) {
  123.                     switch (subNode.localName) {
  124.                         case "data":
  125.                             this._parseWidgetData(widgetProto, treeWalker);
  126.                             break;
  127.                         case "variable":
  128.                             this._parseWidgetVar(widgetProto, treeWalker);
  129.                             break;
  130.                         case "setting":
  131.                             this._parseWidgetSetting(widgetProto, treeWalker);
  132.                             break;
  133.                         default:
  134.                             this._createFunctionRef(treeWalker, widgetProto);
  135.                     }
  136.                 }
  137.                 else
  138.                     this._parseElement(treeWalker, null, widgetProto);
  139.             }
  140.             while (treeWalker.nextSibling());
  141.         }
  142.         return widgetProto;
  143.     },
  144.     
  145.     _parseWidgetData: function XBUnit_parseWidgetData(parentWidget, treeWalker) {
  146.         var dataNode = treeWalker.currentNode;
  147.         var dataName = dataNode.getAttribute("name");
  148.         if (!dataName)
  149.             throw new XB._Parser.ENoXBName(dataNode.nodeName);
  150.         this._logger.trace("Found widget scope data " + dataName);
  151.         
  152.         var nodeID = this._genNodeUID();
  153.         var calcNode = new XB._calcNodes.FuncNodeProto(nodeID, XB._functions.Data);
  154.         calcNode.debugMode = dataNode.hasAttribute(this._consts.STR_DEBUGMODE_ATTR_NAME);
  155.         this._parseElement(treeWalker, calcNode, parentWidget);
  156.         
  157.         parentWidget.registerData(dataName, calcNode);
  158.     },
  159.     
  160.     _evalScope: function XBUnit_evalScope(scopeName) {
  161.         switch (scopeName) {
  162.             case "widget":
  163.                 return XB._base.consts.ENUM_SCOPE_WIDGET;
  164.             case "instance":
  165.                 return XB._base.consts.ENUM_SCOPE_INSTANCE;
  166.             case undefined:
  167.                 return XB._base.consts.ENUM_SCOPE_WIDGET;
  168.             default:
  169.                 throw new Error(this._consts.ERR_INVALID_SCOPE);
  170.         }
  171.     },
  172.     
  173.     _parseWidgetVar: function XBUnit_parseWidgetVar(parentWidget, treeWalker) {
  174.         var varNode = treeWalker.currentNode;
  175.         var varName = varNode.getAttribute("name");
  176.         if (!varName)
  177.             throw new XB._Parser.ENoXBName(varNode.nodeName);
  178.         this._logger.trace("Found variable " + varName);
  179.         
  180.         var initialValue = varNode.getAttribute("default") || XB.types.empty;
  181.         
  182.         try {
  183.             var varScope = this._evalScope(varNode.getAttribute("scope") || undefined);
  184.         }
  185.         catch (e) {
  186.             throw new XB._Parser.EWidgetSyntax(varNode.nodeName);
  187.         }
  188.         var persist = (varNode.getAttribute("persist") == "true");
  189.         parentWidget.registerVariable(varName, varScope, persist, initialValue);
  190.     },
  191.     
  192.     _parseWidgetSetting: function XBUnit_parseWidgetSetting(parentWidget, treeWalker) {
  193.         var settingNode = treeWalker.currentNode;
  194.         var settingName = settingNode.getAttribute("name");
  195.         if (!settingName)
  196.             throw new XB._Parser.ENoXBName(settingNode.nodeName);
  197.         
  198.         try {
  199.             var settingScope = this._evalScope(settingNode.getAttribute("scope") || undefined);
  200.         }
  201.         catch (e) {
  202.             throw new XB._Parser.EWidgetSyntax(settingNode.nodeName);
  203.         }
  204.         var defaultValue = settingNode.getAttribute("default");
  205.         var controlInfo = undefined;
  206.         if (treeWalker.firstChild())
  207.             try {
  208.                 do {
  209.                     let controlElement = treeWalker.currentNode;
  210.                     if (controlElement.localName == "control") {
  211.                         controlInfo = controlElement;
  212.                         break;
  213.                     }
  214.                 }
  215.                 while (treeWalker.nextSibling());
  216.             }
  217.             finally {
  218.                 treeWalker.parentNode();
  219.             }
  220.         
  221.         this._logger.trace("Found widget setting " + settingName +
  222.                            ", scope " + settingScope +
  223.                            ", default " + defaultValue);
  224.         parentWidget.registerSetting(settingName, settingScope, defaultValue, controlInfo);
  225.     },
  226.     
  227.     _parseElement: function XBUnit_parseElement(treeWalker, parentCalcNode, parentWidget) {
  228.         this._logger.trace("Checking node " + treeWalker.currentNode.nodeName + " children");
  229.         var calcNodeArgs = [];
  230.         
  231.         if (treeWalker.firstChild())
  232.             try {
  233.                 do {
  234.                     var widgetSubNode = treeWalker.currentNode;
  235.                     
  236.                     if (parentCalcNode == null && widgetSubNode.namespaceURI != XB._base.consts.STR_FUNCTIONAL_NS) {
  237.                         this._parseElement(treeWalker, null, parentWidget);
  238.                         continue;
  239.                     }
  240.                     
  241.                     if (parentCalcNode == null) {
  242.                         this._createFunctionRef(treeWalker, parentWidget);
  243.                     }
  244.                     else {
  245.                         var argInfo = this._handleFunctionSubNode(treeWalker, parentWidget);
  246.                         calcNodeArgs.push(argInfo);
  247.                     }
  248.                 }
  249.                 while (treeWalker.nextSibling());
  250.             }
  251.             finally {
  252.                 treeWalker.parentNode();
  253.             }
  254.         
  255.         if (parentCalcNode != null) {
  256.             var unnamedArgs = [];
  257.             for each (let argInfo in calcNodeArgs) {
  258.                 if (argInfo.name) {
  259.                     if (!parentCalcNode.argumentAttached(argInfo.name))
  260.                         parentCalcNode.attachArgument(argInfo.name, argInfo.calcNode);
  261.                     else
  262.                         this._logger.warn(this._consts.WARN_DUPLICATE_ARG + " '" + argInfo.name + "'");
  263.                 }
  264.                 else
  265.                     unnamedArgs.push(argInfo);
  266.             }
  267.             for each (let argInfo in unnamedArgs) {
  268.                 argInfo.name = parentCalcNode.proposeArgName();
  269.                 parentCalcNode.attachArgument(argInfo.name, argInfo.calcNode);
  270.             }
  271.         }
  272.     },
  273.     
  274.     _createFunctionRef: function XBUnit_createFuncRef(treeWalker, parentWidget) {
  275.         var srcXMLNode = treeWalker.currentNode;
  276.         
  277.         var calcNode;
  278.         if (srcXMLNode.localName == "value"){
  279.             calcNode = this._createValNode(srcXMLNode);
  280.         }
  281.         else {
  282.             let funcName = srcXMLNode.localName;
  283.             let calcNodeConstructor = XB._functions["CN_" + funcName];
  284.             if ( !(calcNodeConstructor instanceof Function) )
  285.                 throw new XB._Parser.ENoXBFunction(funcName);
  286.             calcNode = new XB._calcNodes.FuncNodeProto(this._genNodeUID(), calcNodeConstructor);
  287.         }
  288.         var refID = calcNode.baseID;
  289.         parentWidget.registerReference(refID, calcNode);
  290.         
  291.         this._logger.trace("Replacing functional element " + srcXMLNode.localName + " with a reference " + refID);
  292.         var valRefElement = srcXMLNode.ownerDocument.createElementNS(
  293.             XB._base.consts.STR_UI_NS,
  294.             XB._base.consts.STR_VAL_REF_ELEM_NAME);
  295.         valRefElement.setUserData(XB._base.consts.STR_VAL_REF_ID_KEY_NAME, refID, this._userDataHandler);
  296.         srcXMLNode.parentNode.replaceChild(valRefElement, srcXMLNode);
  297.         try {
  298.             if ( !(calcNode instanceof XB._calcNodes.ConstNodeProto) ) {
  299.                 this._parseFuncNodeAttributes(srcXMLNode.attributes, calcNode);
  300.                 this._parseElement(treeWalker, calcNode, parentWidget);
  301.             }
  302.         }
  303.         finally {
  304.             treeWalker.currentNode = valRefElement;
  305.         }
  306.     },
  307.     
  308.     _handleFunctionSubNode: function XBUnit_handleFuncSubNode(treeWalker, parentWidget) {
  309.         this._logger.trace("Handling function arguments");
  310.         
  311.         var calcNode;
  312.         var argName;
  313.         var argXMLNode = treeWalker.currentNode;
  314.         
  315.         if (argXMLNode.nodeType == argXMLNode.ELEMENT_NODE &&
  316.             argXMLNode.localName == this._consts.STR_FUNC_PARAM_ELEM_NAME &&
  317.             argXMLNode.namespaceURI == XB._base.consts.STR_FUNCTIONAL_NS) {
  318.             
  319.             argName = argXMLNode.getAttribute("name") || undefined;
  320.             this._logger.trace("Found <f:param> element, name is " + argName);
  321.             
  322.             var argsLen = 0;
  323.             if (treeWalker.firstChild()) {
  324.                 try {
  325.                     do {
  326.                         argsLen++;
  327.                     }
  328.                     while (treeWalker.nextSibling());
  329.                     
  330.                     if (argsLen == 1)
  331.                         calcNode = this._handleArgumentNode(treeWalker, parentWidget);
  332.                 }
  333.                 finally {
  334.                     treeWalker.parentNode();
  335.                 }
  336.             }
  337.             if (argsLen > 1) {
  338.                 var nodeID = this._genNodeUID();
  339.                 calcNode = new XB._calcNodes.FuncNodeProto(nodeID, XB._functions.CN_concat);
  340.                 this._parseElement(treeWalker, calcNode, parentWidget);
  341.             }
  342.             else
  343.                 if (argsLen == 0)
  344.                     calcNode = new XB._calcNodes.ConstNodeProto(this._genNodeUID(), "");
  345.         }
  346.         else
  347.             calcNode = this._handleArgumentNode(treeWalker, parentWidget);
  348.         
  349.         return {name: argName, calcNode: calcNode};
  350.     },
  351.     
  352.     _handleArgumentNode: function XBUnit_handleArgNode(treeWalker, parentWidget) {
  353.         var calcNode;
  354.         
  355.         var argXMLNode = treeWalker.currentNode;
  356.         if (argXMLNode.nodeType == argXMLNode.ELEMENT_NODE &&
  357.             argXMLNode.namespaceURI == XB._base.consts.STR_FUNCTIONAL_NS) {
  358.             this._logger.trace("Found functional parameter. Subfunction is \"" + argXMLNode.localName + "\"");
  359.             
  360.             if (argXMLNode.localName == "value"){
  361.                 calcNode = this._createValNode(argXMLNode);
  362.             }
  363.             else {
  364.                 let funcName = argXMLNode.localName;
  365.                 let calcNodeConstructor = XB._functions["CN_" + funcName];
  366.                 if ( !(calcNodeConstructor instanceof Function) )
  367.                     throw new XB._Parser.ENoXBFunction(funcName);
  368.                 calcNode = new XB._calcNodes.FuncNodeProto(this._genNodeUID(), calcNodeConstructor);
  369.                 
  370.                 this._parseFuncNodeAttributes(argXMLNode.attributes, calcNode);
  371.                 this._parseElement(treeWalker, calcNode, parentWidget);
  372.             }
  373.         }
  374.         else {
  375.             this._logger.trace("Found XML parameter. Node name is \"" + argXMLNode.nodeName + "\"");
  376.             if (argXMLNode.nodeType == argXMLNode.TEXT_NODE) {
  377.                 var text = sysutils.trimSpaces(argXMLNode.nodeValue);
  378.                 this._logger.trace("Text value is: " + text);
  379.                 calcNode = new XB._calcNodes.ConstNodeProto(this._genNodeUID(), text);
  380.             }
  381.             else {
  382.                 this._parseElement(treeWalker, null, parentWidget);
  383.                 calcNode = new XB._calcNodes.ConstNodeProto(this._genNodeUID(), new XB.types.XML(argXMLNode));
  384.             }
  385.         }
  386.         
  387.         return calcNode;
  388.     },
  389.     
  390.     _parseFuncNodeAttributes: function XBUnit_parseFuncNodeAttrs(attrsNodeMap, calcNode) {
  391.         this._logger.trace("Checking functional node attributes");
  392.         for (let attrIdx = 0, len = attrsNodeMap.length; attrIdx < len; attrIdx++) {
  393.             let attrNode = attrsNodeMap.item(attrIdx);
  394.             let argName = attrNode.localName;
  395.             if (argName == this._consts.STR_DEBUGMODE_ATTR_NAME) {
  396.                 calcNode.debugMode = true;
  397.                 continue;
  398.             }
  399.             let arg;
  400.             
  401.             let text = attrNode.nodeValue;
  402.             let match = text.match(/^\$(.+)$/);
  403.             if (match) {
  404.                 let refName = match[1];
  405.                 let refNameNode = new XB._calcNodes.ConstNodeProto(this._genNodeUID(), refName);
  406.                 arg = new XB._calcNodes.FuncNodeProto(this._genNodeUID(), XB._functions["CN_value-of"]);
  407.                 arg.attachArgument("name", refNameNode);
  408.             }
  409.             else {
  410.                 arg = new XB._calcNodes.ConstNodeProto(this._genNodeUID(), text);
  411.             }
  412.             
  413.             if (!calcNode.argumentAttached(argName))
  414.                 calcNode.attachArgument(argName, arg);
  415.             else
  416.                 this._logger.warn(this._consts.WARN_DUPLICATE_ARG + " '" + argName + "'");
  417.         }
  418.     },
  419.     
  420.     _createValNode: function XBUnit_createValNode(srcXMLNode) {
  421.         if (srcXMLNode.hasAttribute("value") && srcXMLNode.hasChildNodes())
  422.             throw new XB._Parser.EWidgetSyntax(srcXMLNode.nodeName);
  423.         var raw;
  424.         if (valueType == "xml")
  425.             raw = srcXMLNode.childNodes;
  426.         else
  427.             raw = srcXMLNode.getAttribute("value") || sysutils.trimSpaces(srcXMLNode.textContent);
  428.         var val;
  429.         var valueType = srcXMLNode.getAttribute("type") || "string";
  430.         switch (valueType) {
  431.             case "string":
  432.                 val = raw;
  433.                 break;
  434.             case "xml":
  435.                 val = XB._base.runtime.xToXML(raw);
  436.                 break;
  437.             case "number":
  438.                 val = XB._base.runtime.xToNumber(raw);
  439.                 break;
  440.             case "bool":
  441.                 val = XB._base.runtime.xToBool(raw);
  442.                 break;
  443.             case "empty":
  444.                 val = XB.types.empty;
  445.                 break;
  446.             default:
  447.                 throw new XB._Parser.EWidgetSyntax(srcXMLNode.nodeName);
  448.         }
  449.         return new XB._calcNodes.ConstNodeProto(this._genNodeUID(), val);
  450.     },
  451.     
  452.     _genNodeUID: function XBUnit_genNodeUID() {
  453.         return this._nodeUID++;
  454.     },
  455.     
  456.     _nodeFilter: {
  457.         acceptNode : function XBUnit_NF_acceptNode(node) {
  458.             if ( (node.nodeType == node.COMMENT_NODE) ||
  459.                  ((node.nodeType == node.TEXT_NODE) && !this._emptyTextRE.test(node.nodeValue)) )
  460.                 return XB._Ci.nsIDOMNodeFilter.FILTER_REJECT;
  461.             return XB._Ci.nsIDOMNodeFilter.FILTER_ACCEPT;
  462.         },
  463.         
  464.         _emptyTextRE: /[^\t\n\r ]/
  465.     },
  466.     
  467.     _userDataHandler: {
  468.         handle: function XBUnit_UDH_handle(operation, key, data, srcNode, dstNode) {
  469.             try {
  470.                 dstNode.setUserData(key, data, this);
  471.             }
  472.             catch (e) {
  473.                 XB._base.logger.error("Failed setting userData " + misc.formatError(e));
  474.             }
  475.         }
  476.     }
  477. };
  478.  
  479. XB._Parser.Unit.WidgetPrototype = XB._base.WidgetBase.extend({
  480.     constructor: function XBWidgetPrototype_constructor(protoID, srcDOMElement, unit) {
  481.         if ( !(srcDOMElement instanceof XB._Ci.nsIDOMElement) )
  482.             throw new CustomErrors.EArgType("srcDOMElement", "nsIDOMElement", typeof srcDOMElement);
  483.         this._srcDOMElement = srcDOMElement;
  484.         this.base(protoID);
  485.         if ( !(unit instanceof XB._Parser.Unit) )
  486.             throw new CustomErrors.EArgType("unit", "XB._Parser.Unit", typeof unit);
  487.         this._unit = unit;
  488.         
  489.         let loggerName = XB._base.loggersRoot + "." + protoID;
  490.         this._logger = XB._base.application.core.Log4Moz.repository.getLogger(loggerName);
  491.         
  492.         this._unique = (srcDOMElement.getAttribute("unique") != "false");
  493.         this._name = srcDOMElement.getAttribute("name") || undefined;
  494.         this._iconPath = srcDOMElement.getAttribute("icon") || undefined;
  495.         this._instSettings = [];
  496.         this._instVars = [];
  497.         this._spawnedWidgets = [];
  498.     },
  499.     
  500.     createInstance: function XBWidgetPrototype_createInstance(instanceID, widgetHost, instanceSettings) {
  501.         var instance = new XB._Parser.Unit.WidgetInstance(instanceID,
  502.                                                           this,
  503.                                                           widgetHost,
  504.                                                           this._refsMap,
  505.                                                           this._dataMap,
  506.                                                           this._instSettings,
  507.                                                           this._instVars);
  508.         this._spawnedWidgets.push(instance);
  509.         
  510.         if (instanceSettings != undefined)
  511.             XB._base.logger.debug("Instance settings:\n" + misc.dump(instanceSettings));
  512.             try {
  513.                 for (let name in instanceSettings)
  514.                     instance.applySetting(name, instanceSettings[name]);
  515.             }
  516.             catch (e) {
  517.                 XB._base.logger.error("Couldn't apply widget instance settings. " + misc.formatError(e));
  518.             }
  519.         
  520.         return instance;
  521.     },
  522.     
  523.     get spawnedWidgets() {
  524.         return this._spawnedWidgets.slice(0);
  525.     },
  526.     
  527.     get srcElement() {
  528.         return this._srcDOMElement;
  529.     },
  530.     
  531.     registerReference: function XBWIdgetPrototype_registerReference(refID, calcNode) {
  532.         this._refsMap[refID] = calcNode;
  533.     },
  534.     
  535.     registerVariable: function XBWidgetPrototype_registerVariable(varName, varScope, persistent, initialValue) {
  536.         XB._base.logger.trace("Widget prototype " + this.id + " registers var " + varName + ", scope " + varScope);
  537.         if (this._varsMap[varName])
  538.             XB._base.logger.warn(this._consts.WARN_VAR_REDEFINED + " " + varName);
  539.         
  540.         switch (varScope) {
  541.             case XB._base.consts.ENUM_SCOPE_WIDGET:
  542.                 var nodeID = this.id + "_var_" + varName;
  543.                 this._varsMap[varName] = persistent ?
  544.                     new XB._calcNodes.PersistentVarNode(nodeID, this, varName, initialValue) :
  545.                     new XB._calcNodes.VarNode(nodeID, this, initialValue);
  546.                 break;
  547.             case XB._base.consts.ENUM_SCOPE_INSTANCE:
  548.                 this._instVars.push({name: varName, persistent: persistent, initialValue: initialValue});
  549.                 break;
  550.             default:
  551.                 throw new CustomErrors.EArgType("varScope", "ENUM_SCOPE_WIDGET | ENUM_SCOPE_INSTANCE", "" + varScope);
  552.         }
  553.     },
  554.     
  555.     registerData: function XBWidgetPrototype_registerData(dataName, dataNode) {
  556.         if (this._dataMap[dataName])
  557.             XB._base.logger.warn(this._consts.WARN_DATA_REDEFINED + " " + dataName);
  558.         this._dataMap[dataName] = dataNode;
  559.     },
  560.     
  561.     registerSetting: function XBWidgetPrototype_registerSetting(settingName, settingScope, defaultValue, controlInfo) {
  562.         XB._base.logger.trace("Widget prototype " + this.id + " registers setting " + settingName + ", scope " + settingScope);
  563.         
  564.         switch (settingScope) {
  565.             case XB._base.consts.ENUM_SCOPE_WIDGET:
  566.                 var nodeID = "setting_" + settingName;
  567.                 var settingNode = new XB._calcNodes.SettingNode(nodeID, this, settingName, defaultValue);
  568.                 this._settingsMap[settingName] = {node: settingNode, controlInfo: controlInfo};
  569.                 break;
  570.             case XB._base.consts.ENUM_SCOPE_INSTANCE:
  571.                 this._instSettings.push({name: settingName, defaultValue: defaultValue, controlInfo: controlInfo});
  572.                 break;
  573.             default:
  574.                 throw new CustomErrors.EArgType("settingScope", "ENUM_SCOPE_WIDGET | ENUM_SCOPE_INSTANCE", "" + settingScope);
  575.         }
  576.     },
  577.     
  578.     instanceFinalized: function XBWidgetPrototype_instanceFinalized(widgetInstance) {
  579.         for (let index in this._spawnedWidgets)
  580.             if (this._spawnedWidgets[index] == widgetInstance) {
  581.                 this._spawnedWidgets.splice(index, 1);
  582.                 break;
  583.             }
  584.     },
  585.     
  586.     get name() {
  587.         return this._name;
  588.     },
  589.     
  590.     get iconURI() {
  591.         return this.pkg.resolvePath(this._iconPath);
  592.     },
  593.     
  594.     get iconPath() {
  595.         return this._iconPath;
  596.     },
  597.     
  598.     get isUnique() {
  599.         return this._unique;
  600.     },
  601.     
  602.     get unit() {
  603.         return this._unit;
  604.     },
  605.     
  606.     get pkg() {
  607.         return this._unit.unitPackage;
  608.     },
  609.     
  610.     get logger() {
  611.         return this._logger;
  612.     },
  613.     
  614.     _srcDOMElement: undefined,
  615.     _logger: null,
  616.     _name: undefined,
  617.     _iconPath: undefined,
  618.     _unit: null,
  619.     _unique: false,
  620.     _instSettings: null,
  621.     _instVars: null,
  622.     _spawnedIDs: null
  623. });
  624.  
  625. XB._Parser.Unit.WidgetInstance = XB._base.WidgetBase.extend({
  626.     constructor: function XBWidgetInstance_constructor(IID, proto, host, refsMap, dataMap, settingsArr, varsArr) {
  627.         if ( !(proto instanceof XB._Parser.Unit.WidgetPrototype) )
  628.             throw new CustomErrors.EArgType("proto", "XB._Parser.Unit.WidgetPrototype", typeof proto);
  629.         this.base(IID);
  630.         this._proto = proto;
  631.         this._host = host;
  632.         
  633.         for (let refID in refsMap)
  634.             this._refsMap[refID] = refsMap[refID].createInstance(this);
  635.         
  636.         for (let dataName in dataMap)
  637.             this._dataMap[dataName] = dataMap[dataName].createInstance(this);
  638.         
  639.         for each (let setting in settingsArr)
  640.             this._registerSetting(setting.name, setting.defaultValue, setting.controlInfo);
  641.             
  642.         for each (let variable in varsArr)
  643.             this._registerVariable(variable.name, variable.persistent, variable.initialValue);
  644.     },
  645.     
  646.     get prototype() {
  647.         return this._proto;
  648.     },
  649.     
  650.     get host() {
  651.         return this._host;
  652.     },
  653.     
  654.     applySetting: function XBWidgetInstance_applySetting(name, value) {
  655.         this._settingsMap[name].node.setValue(value);
  656.     },
  657.     
  658.     findSetting: function XBWidgetInstance_findSetting(settingName) {
  659.         this.logger.trace("Looking for widget instance setting " + settingName);
  660.         var settingNode = this.base(settingName);
  661.         return settingNode? settingNode: this._proto.findSetting(settingName);
  662.     },
  663.     
  664.     findVariable: function XBWidgetInstance_findVariable(varName) {
  665.         this.logger.trace("Looking for widget instance variable " + varName);
  666.         var varNode = this.base(varName);
  667.         return varNode? varNode: this._proto.findVariable(varName);
  668.     },
  669.     
  670.     finalize: function XBWidgetInstance_finalize() {
  671.         function finalizeNodesInMap(map) {
  672.             for each (let node in map)
  673.                 try {
  674.                     node.finalize();
  675.                 }
  676.                 catch (e) {
  677.                     XB._base.logger.error("Error while finalizing calc node. " + misc.formatError(e));
  678.                     XB._base.logger.debug(e.stack);
  679.                 }
  680.         }
  681.         
  682.         finalizeNodesInMap(this._refsMap);
  683.         finalizeNodesInMap(this._varsMap);
  684.         finalizeNodesInMap(this._dataMap);
  685.         for each (let setting in this._settingsMap) {
  686.             try {
  687.                 setting.node.finalize();
  688.             }
  689.             catch (e) {
  690.                 this.logger.error("Error while finalizing setting node. " + misc.formatError(e));
  691.             }
  692.         }
  693.         
  694.         var proto = this._proto;
  695.         this._proto = null;
  696.         this._host = null;
  697.         
  698.         proto.instanceFinalized(this);
  699.     },
  700.     
  701.     get logger() {
  702.         return this.prototype.logger;
  703.     },
  704.     
  705.     _consts: {
  706.         ERR_PROTO_EXPECTED: "Widget prototype expected"
  707.     },
  708.     _proto: null,
  709.     _wndEngine: null,
  710.     
  711.     _registerSetting: function XBWidgetInstance_registerSetting(settingName, defaultValue, controlInfo) {
  712.         var nodeID = "setting_" + settingName;
  713.         var settingNode = new XB._calcNodes.SettingNode(nodeID, this, settingName, defaultValue);
  714.         this._settingsMap[settingName] = {node: settingNode, controlInfo: controlInfo};
  715.     },
  716.     
  717.     _registerVariable: function XBWidgetInstance_registerVariable(varName, persistent, initialValue) {
  718.         var nodeID = this.id + "_var_" + varName;
  719.         this._varsMap[varName] = persistent ?
  720.             new XB._calcNodes.PersistentVarNode(nodeID, this, varName, initialValue) :
  721.             new XB._calcNodes.VarNode(nodeID, this, initialValue);
  722.     }
  723. });
  724.