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 / filAD05B0A109F558195E5E329CB1E0D08B < prev    next >
Text File  |  2010-07-12  |  57KB  |  1,609 lines

  1. const APP_NAME = "yasearch";
  2.  
  3. const { classes: Cc, interfaces: Ci, utils: Cu, Constructor: CC } = Components;
  4.  
  5. var DOMUtils = {
  6.     evaluateXPath: function DOMUtils_evaluateXPath(aNode, aExpr) {
  7.         function nsResolver(aPrefix) {
  8.             const ns = {
  9.                 "xul": "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
  10.                 "xhtml": "http://www.w3.org/1999/xhtml"
  11.             };
  12.             
  13.             return ns[aPrefix] || null;
  14.         }
  15.         
  16.         let xpEvaluator = Cc["@mozilla.org/dom/xpath-evaluator;1"].getService(Ci.nsIDOMXPathEvaluator);
  17.         let xpathResult = xpEvaluator.evaluate(aExpr, aNode, nsResolver,
  18.                                                Ci.nsIDOMXPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
  19.         let nextElement,
  20.             result = [];
  21.         
  22.         while ((nextElement = xpathResult.iterateNext()))
  23.             result.push(nextElement);
  24.         
  25.         return result;
  26.     }
  27. };
  28.  
  29. var SettingsProxy = {
  30.     _valuesHash: {},
  31.     
  32.     clear: function SettingsProxy_clear() {
  33.         this._valuesHash = {};
  34.     },
  35.     
  36.     remember: function SettingsProxy_remember(settingNode, value) {
  37.         this._valuesHash[settingNode.effectiveID] = {node: settingNode, value: value};
  38.     },
  39.     
  40.     recall: function SettingsProxy_recall(settingNode) {
  41.         var info = this._valuesHash[settingNode.effectiveID];
  42.         if (info)
  43.             return info.value;
  44.     },
  45.     
  46.     recallAll: function SettingsProxy_recallAll() {
  47.         var ret = [];
  48.         for each (let info in this._valuesHash)
  49.             ret.push(info);
  50.         return ret;
  51.     },
  52.     
  53.     resetAll: function SettingsProxy_resetAll() {
  54.         try {
  55.             Preferences.barCore.Preferences.resetBranch(APP_NAME + ".xbwidgets.");
  56.         } catch (ex) {}
  57.     }
  58. };
  59.  
  60. function WidgetProxy(aProtoId) {
  61.     this._id = aProtoId;
  62.     this.isXbWidget = true;
  63.     
  64.     this._init();
  65. }
  66.  
  67. WidgetProxy.prototype = {
  68.     _init: function WidgetProxy__init() {
  69.         if (StaticWidgets.hasWidget(this._id)) {
  70.             let widget = StaticWidgets.getWidget(this._id);
  71.             this.isXbWidget = false;
  72.             this.iconURL = widget.iconURL;
  73.             this.isUnique = widget.isUnique;
  74.             this.isRemovable = false;
  75.             this._id  = widget.protoId;
  76.             this.protoId = widget.protoId;
  77.             this.name = widget.name;
  78.         } else {
  79.             let proto = this.proto;
  80.             this.iconURL = proto.unit.unitPackage.resolvePath(proto.iconPath);
  81.             this.isUnique = proto.isUnique;
  82.             this.isRemovable = !Preferences.barCore.application.isPreinstalledWidget(proto.id);
  83.             this.protoId = proto.id;
  84.             this.name = proto.name;
  85.         }
  86.     },
  87.     
  88.     get proto() {
  89.         return Preferences.barCore.application.widgetLibrary.getWidgetProto(this._id);
  90.     },
  91.     
  92.     get id() {
  93.         return this._id;
  94.     }
  95. };
  96.  
  97. function WidgetInstProxy(aInstanceID) {
  98.     this.isXbWidget = true;
  99.     
  100.     this._id = aInstanceID;
  101.     this._preferenceIDs = [];
  102.     
  103.     this._init();
  104. }
  105.  
  106. WidgetInstProxy.prototype = {
  107.     _init: function WidgetInstProxy__init() {
  108.         if (StaticWidgets.hasWidget(this._id)) {
  109.             let widget = StaticWidgets.getWidget(this._id);
  110.             this.isXbWidget = false;
  111.             this.iconURL = widget.iconURL;
  112.             this.isUnique = widget.isUnique;
  113.             this.isRemovable = false;
  114.             this.protoId = widget.protoId;
  115.             this.instanceID = this._id;
  116.             this.name = widget.name;
  117.             this.xulDocument = widget.xulDocument;
  118.             this._preferenceIDs = widget.preferenceIDs;
  119.         } else {
  120.             let xbWidget = this.xbWidget;
  121.             let proto = xbWidget.prototype;
  122.             this.iconURL = proto.unit.unitPackage.resolvePath(proto.iconPath);
  123.             this.isUnique = proto.isUnique;
  124.             this.isRemovable = false;
  125.             this.protoId = proto.id;
  126.             this.instanceID = this.widgetInfo.instanceID;
  127.             this.name = proto.name;
  128.         }
  129.     },
  130.     
  131.     makeURL: function WidgetInstProxy_makeURL(aSpec) {
  132.         let spec = /^https?:\/\//.test(aSpec) ? aSpec : this.unitPackage.resolvePath(aSpec);
  133.         let uri = spec ? Preferences.barCore.Lib.sysutils.createFixupURIFromString(spec) : null;
  134.         
  135.         if (!(uri && /^(https?|xb)$/.test(uri.scheme) && uri.spec))
  136.             return "";
  137.         
  138.         return uri.spec;
  139.     },
  140.     
  141.     get id() {
  142.         return this._id;
  143.     },
  144.     
  145.     get widgetInfo() {
  146.         return Preferences.overlayProvider.parseWidgetItemId(this._id);
  147.     },
  148.     
  149.     get xbWidget() {
  150.         return Preferences._wndEngine.getWidget(this.widgetInfo.instanceID);
  151.     },
  152.     
  153.     get unitPackage() {
  154.         return this.xbWidget.prototype.unit.unitPackage;
  155.     },
  156.     
  157.     get protoSettings() {
  158.         return this.xbWidget.prototype.settings;
  159.     },
  160.     
  161.     get instSettings() {
  162.         return this.xbWidget.settings;
  163.     },
  164.     
  165.     updatePreferenceNodes: function WidgetInstProxy_updatePreferenceNodes() {
  166.         this._preferenceIDs.forEach(function(aID) {
  167.             let prefNode = document.getElementById(aID);
  168.             if (prefNode)
  169.                 prefNode.updateElements();
  170.         });
  171.     }
  172. };
  173.  
  174. var RegisteredWidgets = {
  175.     _widgets: [],
  176.     
  177.     push: function RegisteredWidgets_push(aProtoID, aBeforeID) {
  178.         let widget = new WidgetProxy(aProtoID);
  179.         this._widgets.push(widget);
  180.         
  181.         return RegisteredWidgetsController.insertItem(widget, aBeforeID);
  182.     },
  183.     
  184.     get: function RegisteredWidgets_get(aProtoID) {
  185.         return this._widgets.filter(function(wp) wp.id == aProtoID)[0];
  186.     },
  187.     
  188.     remove: function RegisteredWidgets_remove(aProtoID) {
  189.         let widgets = this._widgets;
  190.         for (let i = 0, len = widgets.length; i < len; i++) {
  191.             if (widgets[i].id == aProtoID)
  192.                 return widgets.splice(i, 1)[0];
  193.         }
  194.     }
  195. };
  196.  
  197. var ActiveWidgets = {
  198.     _widgets: [],
  199.     
  200.     push: function ActiveWidgets_push(aInstanceID, aBeforeID) {
  201.         let widget = new WidgetInstProxy(aInstanceID);
  202.         this._widgets.push(widget);
  203.         
  204.         return ActiveWidgetsController.insertItem(widget, aBeforeID);
  205.     },
  206.     
  207.     get: function ActiveWidgets_get(aInstanceID) {
  208.         return this._widgets.filter(function(wp) (wp.id == aInstanceID || wp.instanceID == aInstanceID))[0];
  209.     },
  210.     
  211.     remove: function ActiveWidgets_remove(aInstanceID) {
  212.         let widgets = this._widgets;
  213.         for (let i = 0, len = widgets.length; i < len; i++) {
  214.             if (widgets[i].id == aInstanceID)
  215.                 return widgets.splice(i, 1)[0];
  216.         }
  217.     }
  218. };
  219.  
  220. var StaticWidgets = {
  221.     _specialIDs: {
  222.         "proto": ["separator", "spacer", "spring"],
  223.         "localNames": ["toolbarseparator", "toolbarspacer", "toolbarspring"],
  224.         "names": {}
  225.     },
  226.     
  227.     getSpecialID: function(aID) {
  228.         let id = aID.replace(/(\d+)$/, "");
  229.         if (this._specialIDs.proto.indexOf(id) > -1)
  230.             return id;
  231.         
  232.         return null;
  233.     },
  234.     
  235.     clear: function StaticWidgets_clear() {
  236.         this._knowIDs = [];
  237.     },
  238.     
  239.     _getItemFromDocumentOrPalette: function StaticWidgets__getItemFromDocumentOrPalette(aWidgetID) {
  240.         return Preferences.getItemFromDocumentOrPalette(aWidgetID);
  241.     },
  242.     
  243.     init: function StaticWidgets_init() {
  244.         this.clear();
  245.         
  246.         this._specialIDs.proto.forEach(function(name) {
  247.             this[name] = Preferences.getString(name);
  248.         }, this._specialIDs.names);
  249.         
  250.         let infoFile = this._staticDir;
  251.         infoFile.append("info.json");
  252.         
  253.         if (infoFile.exists()) {
  254.             let widgetsInfo = Preferences.barCore.JSON.parse(Preferences.barCore.Lib.sysutils.readTextFile(infoFile));
  255.  
  256.             widgetsInfo.forEach(function(aWidgetID) {
  257.                 if (this._getItemFromDocumentOrPalette(aWidgetID))
  258.                     this._knowIDs.push(aWidgetID);
  259.             }, this);
  260.         }
  261.         
  262.         let toolbarNodes = Array.slice(Preferences._setupWndCtrl._appToolbar.childNodes);
  263.         for (let i = toolbarNodes.length; i-- > 0;) {
  264.             if (this._specialIDs.localNames.indexOf(toolbarNodes[i].localName) > -1) {
  265.                 this._knowIDs.push(toolbarNodes[i].id);
  266.             }
  267.         }
  268.     },
  269.     
  270.     get _staticDir() {
  271.         let staticDir = Preferences.prefDir;
  272.         staticDir.append("static-widgets");
  273.         return staticDir;
  274.     },
  275.     
  276.     _parseXULFile: function StaticWidgets__parseXULFile(aWidgetID) {
  277.         let widgetXULFile = this._staticDir;
  278.         widgetXULFile.append(aWidgetID + ".xul");
  279.         
  280.         let uri = Preferences._ioService.newURI(document.documentURI, null, null);
  281.         let domParser = new Preferences._domParserConstructor(null, uri, uri);
  282.         
  283.         let xulDocument = null;
  284.         try {
  285.             xulDocument = domParser.parseFromString(Preferences.barCore.Lib.sysutils.readTextFile(widgetXULFile), "text/xml");
  286.             if (xulDocument.documentElement.localName != "widget")
  287.                 throw new Error("Wrong static widget structure.");
  288.         } catch (ex) {}
  289.         
  290.         return xulDocument;
  291.     },
  292.     
  293.     _knowIDs: [],
  294.     
  295.     get knownIDs() {
  296.         return this._knowIDs;
  297.     },
  298.     
  299.     get knownProtoIDs() {
  300.         return this._knowIDs
  301.                    .filter(function(id) !this.getSpecialID(id), this)
  302.                    .concat(this._specialIDs.proto);
  303.     },
  304.     
  305.     hasWidget: function StaticWidgets_hasWidget(aWidgetID) {
  306.         return this.getSpecialID(aWidgetID) || (this.knownIDs.indexOf(aWidgetID) != -1);
  307.     },
  308.     
  309.     getWidget: function StaticWidgets_getWidget(aWidgetID) {
  310.         let xulDocument,
  311.             name,
  312.             iconURL = "",
  313.             isUnique = true,
  314.             preferenceIDs = [];
  315.         
  316.         if (this.getSpecialID(aWidgetID)) {
  317.             aWidgetID = this.getSpecialID(aWidgetID);
  318.             name = this._specialIDs.names[aWidgetID] || "widget";
  319.             isUnique = false;
  320.         } else {
  321.             xulDocument = this._parseXULFile(aWidgetID);
  322.             
  323.             let widgetElement = xulDocument.documentElement;
  324.             name = widgetElement.getAttribute("name") || aWidgetID;
  325.             iconURL = widgetElement.getAttribute("icon") || "";
  326.             
  327.             if (iconURL && /^images\//.test(iconURL))
  328.                 iconURL = [Preferences.prefDirChrome, "static-widgets", iconURL].join("/");
  329.             
  330.             if (!iconURL) {
  331.                 let widgetElement = this._getItemFromDocumentOrPalette(aWidgetID);
  332.                 if (widgetElement)
  333.                     iconURL = widgetElement.getAttribute("image") || "";
  334.             }
  335.             
  336.             preferenceIDs = this._createPreferencesNodes(xulDocument);
  337.         }
  338.         
  339.         return {
  340.             protoId: aWidgetID + "-proto",
  341.             iconURL: iconURL,
  342.             isUnique: isUnique,
  343.             name: name,
  344.             xulDocument: xulDocument,
  345.             preferenceIDs: preferenceIDs
  346.         };
  347.     },
  348.     
  349.     _createPreferencesNodes: function StaticWidgets__createPreferencesNodes(aXULDocument) {
  350.         let preferenceIDs = [];
  351.         let docFrag = document.createDocumentFragment();
  352.         
  353.         let prefNodes = aXULDocument.getElementsByTagName("preference");
  354.         for (let i = prefNodes.length; i--;) {
  355.             let id = prefNodes[i].id;
  356.             if (id) {
  357.                 preferenceIDs.push(id);
  358.                 if (!(document.getElementById(id)))
  359.                     docFrag.appendChild(prefNodes[i]);
  360.             }
  361.         }
  362.         
  363.         if (docFrag.childNodes.length)
  364.             document.documentElement.currentPane.getElementsByTagName("preferences")[0].appendChild(docFrag);
  365.         
  366.         return preferenceIDs;
  367.     }
  368. };
  369.  
  370. var Preferences = {
  371.     get JSON() {
  372.         return this.barCore.JSON;
  373.     },
  374.     
  375.     barCore: Cc["@yandex.ru/custombarcore;" + APP_NAME].getService().wrappedJSObject,
  376.     
  377.     _domParserConstructor: new CC("@mozilla.org/xmlextras/domparser;1", "nsIDOMParser", "init"),
  378.     _ioService: Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService),
  379.     
  380.     _setupWndCtrl: null,
  381.     _wndEngine: null,
  382.     
  383.     _restoreInfo: {
  384.         currentset: {},
  385.         collapsed: null
  386.     },
  387.     
  388.     _initPane: function Preferences__initPane(aPaneID) {
  389.         let paneElement = document.getElementById(aPaneID);
  390.         if (!paneElement)
  391.             return;
  392.         
  393.         if (document.documentElement.currentPane != paneElement)
  394.             document.documentElement.showPane(paneElement);
  395.         
  396.         if (paneElement.getAttribute("xb-pane-ready") == "true")
  397.             return;
  398.         
  399.         switch (aPaneID) {
  400.             case "prefpane-customize":
  401.                 setTimeout(function() Preferences._initPrefPane(), 0);
  402.                 
  403.                 break;
  404.             
  405.             case "prefpane-misc":
  406.                 YaSearchPrefs.onPaneLoad();
  407.                 break;
  408.         }
  409.         
  410.         paneElement.setAttribute("xb-pane-ready", "true");
  411.     },
  412.     
  413.     _prefsInited: false,
  414.     
  415.     _initPrefPane: function Preferences__initPrefPane() {
  416.         if (this._prefsInited)
  417.             return;
  418.         
  419.         this._prefsInited = true;
  420.         
  421.         this._logger = this.barCore.Log4Moz.repository.getLogger(APP_NAME + ".Preferences");
  422.         this._logger.trace("Init");
  423.         
  424.         this._setupWndCtrl = this.gBrowser[APP_NAME + "OverlayController"];
  425.         this._wndEngine = this._setupWndCtrl.windowEngine;
  426.         this.overlayProvider = this.barCore.application.overlayProvider;
  427.         
  428.         this._fillWidgetsLists();
  429.         
  430.         StaticHelper.onPaneLoad();
  431.         
  432.         this._rememberToolbarsCurrentSet();
  433.         
  434.         let toolbar = this._setupWndCtrl._appToolbar;
  435.         this._restoreInfo.collapsed = toolbar.collapsed;
  436.         toolbar.collapsed = false;
  437.         toolbar.onToolbarCustomize(true);
  438.         
  439.         document.documentElement.setAttribute("buttondisabledextra2", "false");
  440.     },
  441.     
  442.     selectWidget: function Preferences_selectWidget(aInstanceID) {
  443.         if (this._prefsInited) {
  444.             let widget = ActiveWidgets.get(aInstanceID);
  445.             if (widget)
  446.                 ActiveWidgetsController.selectItem(widget);
  447.             
  448.         } else {
  449.             this._initPane("prefpane-customize");
  450.             
  451.             window.setTimeout(function(me, instanceID) {
  452.                 if (me && me._prefsInited)
  453.                     me.selectWidget(instanceID);
  454.             }, 0, this, aInstanceID);
  455.         }
  456.     },
  457.     
  458.     _fillWidgetsLists: function Preferences__fillWidgetsLists() {
  459.         RegisteredWidgetsController.init();
  460.         ActiveWidgetsController.init();
  461.         StaticWidgets.init();
  462.         
  463.         StaticWidgets.knownProtoIDs.forEach(function(aStaticID)
  464.             RegisteredWidgets.push(aStaticID));
  465.         
  466.         var knownIDs = this.barCore.application.widgetLibrary.getWidgetProtoIDs();
  467.         for each (let protoID in knownIDs) {
  468.             try {
  469.                 RegisteredWidgets.push(protoID);
  470.             }
  471.             catch (e) {
  472.                 this._logger.error("Failed in Preferences__fillWidgetsLists. " + this.barCore.Lib.misc.formatError(e));
  473.                 this._logger.debug(e.stack);
  474.             }
  475.         }
  476.         
  477.         this.getAllWidgetItems().forEach(function(aToolbarItem)
  478.             ActiveWidgets.push(aToolbarItem.id));
  479.     },
  480.     
  481.     _finalize: function Preferences__finalize() {
  482.         this._setupWndCtrl._appToolbar.onToolbarCustomize(false);
  483.         
  484.         this._logger.trace("Finalize");
  485.         
  486.         RegisteredWidgetsController.finalize();
  487.         ActiveWidgetsController.finalize();
  488.         
  489.         this.overlayProvider = null;
  490.         this._wndEngine = null;
  491.         this._setupWndCtrl = null;
  492.         this._logger = null;
  493.         
  494.         this._prefDir = null;
  495.     },
  496.     
  497.     get instantApply() {
  498.         delete this.instantApply;
  499.         return (this.instantApply = document.documentElement.instantApply);
  500.     },
  501.     
  502.     _accepted: false,
  503.     
  504.     beforeAccept: function Preferences_beforeAccept() {
  505.         try {
  506.             if (!this._accepted) {
  507.                 this._apply();
  508.                 this._accepted = true;
  509.             }
  510.         }
  511.         catch (e) {
  512.             this._logger.error("Could not apply changes. " + this.barCore.Lib.misc.formatError(e));
  513.             this._logger.debug(e.stack);
  514.         }
  515.         
  516.         return true;
  517.     },
  518.     
  519.     beforeUnload: function Preferences_beforeUnload() {
  520.         StaticHelper.onWindowBeforeUnload();
  521.         
  522.         try {
  523.             if (this._gBrowser)
  524.                 this._gBrowser.removeEventListener("unload", this, false);
  525.         } catch (ex) {}
  526.         
  527.         if (!this._prefsInited)
  528.             return;
  529.         
  530.         try {
  531.             if (this.instantApply)
  532.                 this.beforeAccept();
  533.             
  534.             if (!this._accepted)
  535.                 this._cancel();
  536.             
  537.             this._finalize();
  538.         }
  539.         catch (e) {
  540.             this._logger.error("Failed in Preferences_beforeUnload. " + this.barCore.Lib.misc.formatError(e));
  541.         }
  542.     },
  543.     
  544.     _apply: function Preferences__apply() {
  545.         YaSearchPrefs.onDialogAccept();
  546.         
  547.         if (!this._prefsInited)
  548.             return;
  549.         
  550.         this._logger.debug("Applying");
  551.         
  552.         this.getAllWidgetItems().forEach(function(aToolbarItem) {
  553.             try {
  554.                 let customizeState = aToolbarItem.getAttribute("xb-customize");
  555.                 if (customizeState) {
  556.                     aToolbarItem.removeAttribute("xb-customize");
  557.                     
  558.                     if (customizeState == "removed") {
  559.                         this.barCore.application.forEachWindow(
  560.                             function(controller) {
  561.                                 try {
  562.                                     controller.removeItemById(aToolbarItem.id, true);
  563.                                 } catch (e) {
  564.                                     this._logger.error(this.barCore.Lib.misc.formatError(e));
  565.                                     this._logger.debug(e.stack);
  566.                                 }
  567.                             }, this);
  568.                     }
  569.                 }
  570.                 
  571.             } catch (ex) {
  572.                 this._logger.error(ex);
  573.             }
  574.             
  575.         }, this);
  576.         
  577.         for each (let info in SettingsProxy.recallAll())
  578.             info.node.setValue(info.value);
  579.         
  580.         SettingsProxy.clear();
  581.         
  582.         if (this._restoreInfo.collapsed) {
  583.             let toolbar = this._setupWndCtrl._appToolbar;
  584.             
  585.             if (this._restoreInfo.currentset[toolbar.id] != toolbar.currentSet) {
  586.                 toolbar.collapsed = false;
  587.                 toolbar.ownerDocument.persist(toolbar.id, "collapsed");
  588.                 this._restoreInfo.collapsed = false;
  589.             } else {
  590.                 toolbar.collapsed = this._restoreInfo.collapsed;
  591.             }
  592.         }
  593.         
  594.         this._persistToolbarsSet();
  595.     },
  596.     
  597.     _cancel: function Preferences__cancel() {
  598.         this._logger.debug("Reverting");
  599.         
  600.         this._restoreToolbarsCurrentSet();
  601.     },
  602.     
  603.     restoreDefault: function Preferences_restoreDefault() {
  604.         if (!this._getUserConfirm(this.getString("PreferencesTitle"), this.getString("RestoreDefaultSet")))
  605.             return;
  606.         
  607.         const UNDEF = undefined;
  608.         let prefNodes = document.getElementsByTagName("preference");
  609.         for (let i = prefNodes.length; i--;) {
  610.             try {
  611.                 prefNodes[i].valueFromPreferences = UNDEF;
  612.             } catch (ex) {}
  613.         }
  614.         
  615.         let items = this.getAllWidgetItems();
  616.         for (let i = items.length; i-- > 0;) {
  617.             let item = items[i];
  618.             
  619.             if (item.hasAttribute("xb-customize"))
  620.                 item.removeAttribute("xb-customize");
  621.             
  622.             this._setupWndCtrl.removeItem(item, true);
  623.         }
  624.         
  625.         SettingsProxy.resetAll();
  626.         
  627.         let toolbar = this._setupWndCtrl._appToolbar;
  628.         let defaultset = toolbar.getAttribute("defaultset");
  629.         toolbar.currentSet = defaultset;
  630.         
  631.         if (toolbar.collapsed) {
  632.             toolbar.collapsed = false;
  633.             toolbar.ownerDocument.persist(toolbar.id, "collapsed");
  634.             this._restoreInfo.collapsed = false;
  635.         }
  636.         
  637.         this._persistToolbarsSet();
  638.         
  639.         SettingsProxy.clear();
  640.         
  641.         StaticHelper.onRestoreDefault();
  642.         
  643.         this._fillWidgetsLists();
  644.         
  645.         this._rememberToolbarsCurrentSet();
  646.     },
  647.     
  648.     _getToolbarsCurrentSet: function Preferences__getToolbarsCurrentSet() {
  649.         let toolbarsCurrentset = {};
  650.         
  651.         let toolbars = this._setupWndCtrl._toolbox.getElementsByTagName("toolbar");
  652.         
  653.         for (let i = toolbars.length; i-- > 0;) {
  654.             let toolbar = toolbars[i];
  655.             let id = toolbar.id;
  656.             if (!id)
  657.                 continue;
  658.             
  659.             toolbarsCurrentset[id] = toolbar.currentSet;
  660.         }
  661.         
  662.         return toolbarsCurrentset;
  663.     },
  664.     
  665.     _rememberToolbarsCurrentSet: function Preferences__rememberToolbarsCurrentSet() {
  666.         this._restoreInfo.currentset = this._getToolbarsCurrentSet();
  667.     },
  668.     
  669.     _restoreToolbarsCurrentSet: function Preferences__restoreToolbarsCurrentSet() {
  670.         this._checkModifiedToolbaritemsOnRestore();
  671.         
  672.         let toolbox = this._setupWndCtrl._toolbox;
  673.         let toolbarsRememberedInfo = this._restoreInfo.currentset;
  674.         
  675.         for (let [toolbarId, toolbarInfo] in Iterator(this._getToolbarsCurrentSet())) {
  676.             let prevCurrenset = toolbarsRememberedInfo[toolbarId];
  677.             if (!prevCurrenset)
  678.                 continue;
  679.             
  680.             let toolbar = toolbox.getElementsByAttribute("id", toolbarId).item(0);
  681.             if (!toolbar)
  682.                 continue;
  683.             
  684.             if (prevCurrenset !== toolbar.currentSet) {
  685.                 let restoredSet = prevCurrenset || toolbar.getAttribute("defaultset") || "";
  686.                 Preferences._logger.trace(["Restored currentset for #" + toolbarId, restoredSet].join("\n"));
  687.                 
  688.                 toolbar.currentSet = restoredSet;
  689.                 toolbar.ownerDocument.persist(toolbarId, "currentset");
  690.             }
  691.         }
  692.         
  693.         this._rememberToolbarsCurrentSet();
  694.     },
  695.     
  696.     _checkModifiedToolbaritemsOnRestore: function Preferences__checkModifiedToolbaritemsOnRestore() {
  697.         let xpathString = ["//xul:*[@xb-customize='removed']",
  698.                            "//xul:*[@xb-customize='added']"]
  699.                            .join("|");
  700.         
  701.         let setupWndCtrl = this._setupWndCtrl;
  702.         
  703.         let items = DOMUtils.evaluateXPath(setupWndCtrl._toolbox, xpathString);
  704.         for (let i = items.length; i-- > 0;) {
  705.             let item = items[i];
  706.             try {
  707.                 if (item.getAttribute("xb-customize") == "added")
  708.                     setupWndCtrl.removeItem(item, true);
  709.                 
  710.                 item.removeAttribute("xb-customize");
  711.             } catch(e) {}
  712.         }
  713.     },
  714.     
  715.     _getSiblingNode: function(aNode, aDirection) {
  716.         let directionProp = aDirection + "Sibling";
  717.         let node = aNode[directionProp];
  718.         
  719.         while (node && node.getAttribute("xb-customize") == "removed")//invisible items
  720.             node = node[directionProp];
  721.         
  722.         return node;
  723.     },
  724.     
  725.     _getChildNode: function(aParent, aType) {
  726.         let node = aType == "first" ? aParent.firstChild : aParent.lastChild;
  727.         
  728.         if (node && node.getAttribute("xb-customize") == "removed")
  729.             node = this._getSiblingNode(node, aType == "first" ? "next" : "previous");
  730.         
  731.         return node;
  732.     },
  733.     
  734.     _getFirstChild: function(aParent) {
  735.         return this._getChildNode(aParent, "first");
  736.     },
  737.     
  738.     _getLastChild: function(aParent) {
  739.         return this._getChildNode(aParent, "last");
  740.     },
  741.     
  742.     _checkControlsTimeout: null,
  743.     
  744.     checkControls: function Preferences_checkControls() {
  745.         if (this._checkControlsTimeout)
  746.             window.clearTimeout(this._checkControlsTimeout);
  747.         
  748.         this._checkControlsTimeout = setTimeout(function(me) {
  749.             if (me && "_checkControls" in me)
  750.                 me._checkControls();
  751.         }, 0, this);
  752.     },
  753.     
  754.     _checkControls: function Preferences__checkControls() {
  755.         let canAddWidgets = !!RegisteredWidgetsController.list.selectedCount;
  756.         document.getElementById("canAddWidgetsBroadcaster").setAttribute("disabled", !canAddWidgets);
  757.         
  758.         let canDeleteWidgets = false;
  759.         
  760.         let focusedElement = document.commandDispatcher.focusedElement;
  761.         
  762.         if (!focusedElement || focusedElement != ActiveWidgetsController.list) {
  763.             let selectedItems = Array.slice(RegisteredWidgetsController.list.selectedItems);
  764.             canDeleteWidgets = !!selectedItems.some(function(aItem) aItem.isRemovable);
  765.         }
  766.         
  767.         document.getElementById("canDeleteWidgetsBroadcaster").setAttribute("disabled", !canDeleteWidgets);
  768.         
  769.         let activeList = ActiveWidgetsController.list;
  770.         
  771.         let canRemoveWidgets = !!activeList.selectedCount;
  772.         document.getElementById("canRemoveWidgetsBroadcaster").setAttribute("disabled", !canRemoveWidgets);
  773.         
  774.         let canMoveUp = canRemoveWidgets,
  775.             canMoveDown = canRemoveWidgets;
  776.         
  777.         if (canRemoveWidgets) {
  778.             let itemCount = activeList.itemCount;
  779.             let selectedCount = activeList.selectedCount;
  780.             let selectedItems = activeList.selectedItemsSorted;
  781.             
  782.             let firstSelectedItem = selectedItems[0];
  783.             let lastSelectedItem = selectedItems[selectedCount-1];
  784.             
  785.             let appToolbar = this._setupWndCtrl._appToolbar;
  786.             
  787.             let firstToolbaritem = this.gDocument.getElementById(firstSelectedItem.id);
  788.             let firstToolbar = firstToolbaritem.parentNode;
  789.             
  790.             if (firstToolbar == appToolbar && firstToolbaritem == this._getFirstChild(firstToolbar)) {
  791.                 canMoveUp = false;
  792.                 
  793.                 let i = 0;
  794.                 let nextToolbaritem = firstToolbaritem;
  795.                 
  796.                 while (++i < selectedCount && (nextToolbaritem = this._getSiblingNode(nextToolbaritem, "next"))) {
  797.                     if (nextToolbaritem.id != selectedItems[i].id) {
  798.                         canMoveUp = true;
  799.                         break;
  800.                     }
  801.                 }
  802.             }
  803.             
  804.             let lastToolbaritem = this.gDocument.getElementById(lastSelectedItem.id);
  805.             let lastToolbar = lastToolbaritem.parentNode;
  806.             
  807.             if (lastToolbar == appToolbar && lastToolbaritem == this._getLastChild(lastToolbar)) {
  808.                 canMoveDown = false;
  809.             
  810.                 let i = selectedCount - 1;
  811.                 let previousToolbaritem = lastToolbaritem;
  812.                 
  813.                 while (--i >= 0 && (previousToolbaritem = this._getSiblingNode(previousToolbaritem, "previous"))) {
  814.                     if (previousToolbaritem.id != selectedItems[i].id) {
  815.                         canMoveDown = true;
  816.                         break;
  817.                     }
  818.                 }
  819.             }
  820.         }
  821.         
  822.         document.getElementById("canMoveWidgetsUpBroadcaster").setAttribute("disabled", !canMoveUp);
  823.         document.getElementById("canMoveWidgetsDownBroadcaster").setAttribute("disabled", !canMoveDown);
  824.     },
  825.     
  826.     selectAll: function Preferences_selectAll() {
  827.         let focusedElement = document.commandDispatcher.focusedElement;
  828.         if (focusedElement && focusedElement.localName == "richlistbox") {
  829.             if ("expandItem" in focusedElement && focusedElement.currentItem)
  830.                 focusedElement.expandItem(null);
  831.             
  832.             focusedElement.selectAll();
  833.         }
  834.     },
  835.     
  836.     addWidgets: function Preferences_addWidgets(aNodeBefore) {
  837.         let selectedItems = Array.slice(RegisteredWidgetsController.list.selectedItems);
  838.         let beforeId = aNodeBefore ? aNodeBefore.id : null;
  839.         
  840.         let addedItems = [];
  841.         for (let i = 0, len = selectedItems.length; i < len; i++) {
  842.             let addedItem = this._addWidget(selectedItems[i], beforeId);
  843.             
  844.             if (addedItem)
  845.                 addedItems.push(addedItem);
  846.         }
  847.         
  848.         let addedLength = addedItems.length;
  849.         if (addedLength) {
  850.             let firstSelectedItem = addedItems[0];
  851.             let lastSelectedItem = addedItems[addedLength-1];
  852.             
  853.             let activeList = ActiveWidgetsController.list;
  854.             activeList.selectItemRange(firstSelectedItem, lastSelectedItem);
  855.             
  856.             if (addedLength == 1) {
  857.                 firstSelectedItem.click();
  858.             } else {
  859.                 activeList.ensureElementIsVisible(lastSelectedItem);
  860.                 activeList.ensureElementIsVisible(firstSelectedItem);
  861.             }
  862.         }
  863.     },
  864.     
  865.     _addWidget: function Preferences__addWidget(aListItem, aBeforeId) {
  866.         let widget = RegisteredWidgets.get(aListItem.id);
  867.         
  868.         let beforeElement = aBeforeId ? this.gDocument.getElementById(aBeforeId) : null;
  869.         
  870.         let toolbaritem;
  871.         let widgetProtoId = widget.protoId;
  872.         
  873.         if (widget.isXbWidget) {
  874.             if (widget.isUnique) {
  875.                 let allWidgetItems = this.getAllWidgetItems();
  876.                 for (let i = allWidgetItems.length; i-- > 0;) {
  877.                     let existToolbaritem = allWidgetItems[i];
  878.                     try {
  879.                         if (existToolbaritem.getAttribute("xb-customize") == "removed" &&
  880.                             existToolbaritem.prototypeID === widgetProtoId)
  881.                         {
  882.                             toolbaritem = existToolbaritem;
  883.                             break;
  884.                         }
  885.                     } catch (ex) {}
  886.                 }
  887.                 
  888.                 if (toolbaritem) {
  889.                     let toolbar = this._setupWndCtrl._appToolbar;
  890.                     toolbaritem = beforeElement ? toolbar.insertBefore(toolbaritem, beforeElement)
  891.                                                 : toolbar.appendChild(toolbaritem);
  892.                 }
  893.             }
  894.             
  895.             toolbaritem = toolbaritem || this._setupWndCtrl.addWidgetItem(widget.protoId, null, beforeElement, null, true);
  896.             
  897.         } else {
  898.             let destToolbar = beforeElement ? beforeElement.parentNode : this._setupWndCtrl._appToolbar;
  899.             toolbaritem = destToolbar.insertItem(widget.protoId.replace(/\-proto/, ""), beforeElement);
  900.         }
  901.         
  902.         if (!toolbaritem)
  903.             return;
  904.         
  905.         toolbaritem.setAttribute("xb-customize", "added");
  906.         
  907.         return ActiveWidgets.push(toolbaritem.id, aBeforeId);
  908.     },
  909.     
  910.     removeWidgets: function Preferences_removeWidgets(aListItems, aRemovePermanently) {
  911.         let itemsToRemove = typeof aListItems == "undefined"
  912.                                 ? Array.slice(ActiveWidgetsController.list.selectedItems)
  913.                                 : aListItems;
  914.         if (!itemsToRemove)
  915.             return;
  916.         
  917.         for (let i = itemsToRemove.length; i-- > 0;)
  918.             this._removeWidget(itemsToRemove[i], aRemovePermanently);
  919.     },
  920.     
  921.     _removeWidget: function Preferences__removeWidget(aListItem, aRemovePermanently) {
  922.         let toolbaritemId = aListItem.id;
  923.         let toolbaritem = this.gDocument.getElementById(toolbaritemId);
  924.         
  925.         if (toolbaritem) {
  926.             if (aRemovePermanently)
  927.                 this._setupWndCtrl.removeItem(toolbaritem, true);
  928.             else
  929.                 toolbaritem.setAttribute("xb-customize", "removed");
  930.         }
  931.         
  932.         ActiveWidgetsController.removeItem(aListItem);
  933.         
  934.         let widget = ActiveWidgets.remove(toolbaritemId);
  935.         RegisteredWidgetsController.checkWidgetUniqueState(widget.protoId, false);
  936.     },
  937.     
  938.     moveWidgets: function Preferences_moveWidgets(aDirection, aRelativeElement) {
  939.         let selectedItems = ActiveWidgetsController.list.selectedItemsSorted;
  940.         if (!selectedItems)
  941.             return;
  942.         
  943.         let placeAfter = !!(aDirection == "down"),
  944.             len = selectedItems.length,
  945.             selectedItem = placeAfter ? selectedItems[len-1] : selectedItems[0];
  946.         
  947.         let toolbaritem = this.gDocument.getElementById(selectedItem.id);
  948.         if (!toolbaritem)
  949.             return;
  950.         
  951.         let relativeElement;
  952.         
  953.         if (aDirection) {
  954.             relativeElement = this._getSiblingNode(toolbaritem, aDirection == "up" ? "previous" : "next") || toolbaritem;
  955.             
  956.             let itemToolbar = toolbaritem.parentNode;
  957.             
  958.             if (toolbaritem == relativeElement || relativeElement == itemToolbar.lastChild) {
  959.                 let appToolbar = this._setupWndCtrl._appToolbar;
  960.                 
  961.                 if (itemToolbar != appToolbar && appToolbar.firstChild) {
  962.                     if ((aDirection == "down" && itemToolbar.lastChild == relativeElement) ||
  963.                         (aDirection == "up" && itemToolbar.firstChild == relativeElement))
  964.                     {
  965.                         relativeElement = aDirection == "down" ? appToolbar.firstChild : appToolbar.lastChild;
  966.                         
  967.                         aDirection = aDirection == "down" ? "up" : "down";
  968.                         placeAfter = !placeAfter;
  969.                     }
  970.                 }
  971.             }
  972.             
  973.         } else if (aRelativeElement) {
  974.             relativeElement = this.gDocument.getElementById(aRelativeElement.id);
  975.         }
  976.         
  977.         ActiveWidgetsController.moveSelectedItems(aDirection, relativeElement ? relativeElement.id : null);
  978.         
  979.         relativeElement = placeAfter ? relativeElement.nextSibling : relativeElement;
  980.         
  981.         let toolbar = relativeElement ? relativeElement.parentNode : this._setupWndCtrl._appToolbar;
  982.         
  983.         let doc = toolbar.ownerDocument;
  984.         let docFrag = doc.createDocumentFragment();
  985.         let next = toolbaritem.nextSibling;
  986.         
  987.         selectedItems.forEach(function(aListItem) {
  988.             let toolbaritem = doc.getElementById(aListItem.id);
  989.             if (toolbaritem) {
  990.                 if (placeAfter && toolbaritem.nextSibling)
  991.                     next = toolbaritem.nextSibling;
  992.                 
  993.                 docFrag.appendChild(toolbaritem);
  994.             }
  995.         });
  996.         
  997.         if (relativeElement == toolbaritem && next)
  998.             relativeElement = next;
  999.         
  1000.         relativeElement ? toolbar.insertBefore(docFrag, relativeElement)
  1001.                         : toolbar.appendChild(docFrag);
  1002.         
  1003.         this.checkControls();
  1004.         
  1005.         let selectedLen = selectedItems.length;
  1006.         let activeList = ActiveWidgetsController.list;
  1007.         
  1008.         if (selectedLen > 1)
  1009.             activeList.ensureElementIsVisible(selectedItems[selectedItems.length-1]);
  1010.         
  1011.         activeList.ensureElementIsVisible(selectedItems[0]);
  1012.     },
  1013.     
  1014.     deleteWidgets: function Preferences_deleteWidgets() {
  1015.         let selectedItems = Array.slice(RegisteredWidgetsController.list.selectedItems);
  1016.         if (!selectedItems.length)
  1017.             return;
  1018.         
  1019.         let removableItems = selectedItems.filter(function(aItem) aItem.isRemovable);
  1020.         if (!removableItems.length)
  1021.             return;
  1022.         
  1023.         const maxWidgetsInTitle = 6;
  1024.         const maxWidgetLabelLength = parseInt(180 / Math.min(removableItems.length, maxWidgetsInTitle), 10);
  1025.         
  1026.         function getShortItemLabel(aItem) {
  1027.             let label = aItem.getAttribute("label");
  1028.             
  1029.             if (label.length > maxWidgetLabelLength) {
  1030.                 label = label.substr(0, maxWidgetLabelLength)
  1031.                              .replace(/(\s+\S{0,5})$/, "") + "...";
  1032.             }
  1033.             
  1034.             return label;
  1035.         }
  1036.         
  1037.         let widgetsLabel = (removableItems.length > maxWidgetsInTitle
  1038.                                 ? removableItems.slice(0, maxWidgetsInTitle - 1)
  1039.                                 : removableItems)
  1040.                                 .map(function(aItem) getShortItemLabel(aItem));
  1041.         
  1042.         let moreText = widgetsLabel.length == removableItems.length ? "" : " " + this.getString("DeleteWidgetsAndOthers");
  1043.         widgetsLabel = "┬½" + widgetsLabel.join("┬╗, ┬½") + "┬╗" + moreText;
  1044.         
  1045.         let confirmTitle = this.getStringPlural("DeleteWidgetsTitle", [removableItems.length]);
  1046.         let confirmText = this.getStringPlural("DeleteWidgetsText", [removableItems.length], [widgetsLabel]);
  1047.         
  1048.         if (!this._getUserConfirm(confirmTitle, confirmText))
  1049.             return;
  1050.         
  1051.         let barApp = this.barCore.application;
  1052.         
  1053.         let widgetsProtoToRemove = [];
  1054.         let checkPackages = { __proto__: null };
  1055.         
  1056.         removableItems.forEach(function(aItem) {
  1057.             let protoId = aItem.getAttribute("id");
  1058.             
  1059.             let activeItems = ActiveWidgetsController.getItemsForProto(protoId);
  1060.             this.removeWidgets(activeItems, true);
  1061.             
  1062.             RegisteredWidgetsController.removeItem(protoId);
  1063.             RegisteredWidgets.remove(protoId);
  1064.             
  1065.             barApp.forEachWindow(function(controller) controller.removeWidgetsOfProto(protoId));
  1066.             
  1067.             let [packageID, ] = barApp.widgetLibrary.parseWidgetProtoID(protoId);
  1068.             checkPackages[packageID] = true;
  1069.             widgetsProtoToRemove.push(protoId);
  1070.         }, this);
  1071.         
  1072.         barApp.widgetLibrary.forgetWidgets(widgetsProtoToRemove);
  1073.         
  1074.         barApp.forEachWindow(function(controller) controller.updatePalette([]));
  1075.         
  1076.         for (let packageID in checkPackages) {
  1077.             this._logger.debug("Checking package " + packageID);
  1078.             if (!barApp.widgetLibrary.getWidgetProtos(packageID).length) {
  1079.                 barApp.packageManager.uninstallPackage(packageID);
  1080.             }
  1081.         }
  1082.     },
  1083.     
  1084.     _persistToolbarsSet: function Preferences__persistToolbarsSet(aToolbox) {
  1085.         if (!window.persistCurrentSets)
  1086.             return;
  1087.         
  1088.         let toolbox = aToolbox || this.gDocument.getElementById("navigator-toolbox");
  1089.         
  1090.         let n = {
  1091.             gToolboxChanged: true,
  1092.             gToolbox: toolbox,
  1093.             gToolboxDocument: toolbox.ownerDocument
  1094.         };
  1095.         
  1096.         let o = {};
  1097.         
  1098.         for (let p in n) {
  1099.             o[p] = window[p];
  1100.             window[p] = n[p];
  1101.         }
  1102.         
  1103.         persistCurrentSets();
  1104.         
  1105.         for (let p in o)
  1106.             window[p] = o[p];
  1107.     },
  1108.     
  1109.     getAllWidgetItems: function() {
  1110.         let toolbarID = this._setupWndCtrl._appToolbar.id;
  1111.         
  1112.         let xpathString = ["//xul:toolbaritem[@xb-app='" + APP_NAME + "']",
  1113.                            "//xul:toolbar[@id='" + toolbarID + "']/xul:toolbarseparator",
  1114.                            "//xul:toolbar[@id='" + toolbarID + "']/xul:toolbarspring",
  1115.                            "//xul:toolbar[@id='" + toolbarID + "']/xul:toolbarspacer"]
  1116.                            .concat(StaticWidgets.knownIDs.map(function(id) "//xul:toolbaritem[@id='" + id + "']"))
  1117.                            .join("|");
  1118.         
  1119.         return DOMUtils.evaluateXPath(this._setupWndCtrl._toolbox, xpathString);
  1120.     },
  1121.     
  1122.     getItemFromDocumentOrPalette: function Preferences_getItemFromDocumentOrPalette(aWidgetID) {
  1123.         return this.gDocument.getElementById(aWidgetID) ||
  1124.                this._setupWndCtrl._toolbox.palette.getElementsByAttribute("id", aWidgetID).item(0);
  1125.     },
  1126.     
  1127.     _gBrowser: null,
  1128.     
  1129.     get gBrowser() {
  1130.         if (!this._gBrowser) {
  1131.             let misc = this.barCore.Lib.misc;
  1132.             
  1133.             let browser = misc.getTopNavigatorWindow();
  1134.             
  1135.             if (!browser) {
  1136.                 window.open("about:blank", "_blank");
  1137.                 browser = misc.getTopNavigatorWindow();
  1138.                 window.focus();
  1139.             }
  1140.             
  1141.             if (!browser)
  1142.                 throw new Error("Can't create browser for preferences window.");
  1143.             
  1144.             browser.addEventListener("unload", this, false);
  1145.             
  1146.             this._gBrowser = browser;
  1147.         }
  1148.         
  1149.         return this._gBrowser;
  1150.     },
  1151.     
  1152.     get gDocument() {
  1153.         return this.gBrowser.document;
  1154.     },
  1155.     
  1156.     _prefDirChrome: null,
  1157.     
  1158.     get prefDirChrome() {
  1159.         if (!this._prefDirChrome)
  1160.             this._prefDirChrome = document.documentURI.split("/preferences.xul")[0];
  1161.         
  1162.         return this._prefDirChrome;
  1163.     },
  1164.     
  1165.     _prefDir: null,
  1166.     
  1167.     get prefDir() {
  1168.         if (!this._prefDir) {
  1169.             const reg = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIChromeRegistry);
  1170.             let chromeURL = this._ioService.newURI(document.documentURI, null, null);
  1171.             let spec = reg.convertChromeURL(chromeURL).spec;
  1172.             
  1173.             let protocolHandler = Cc["@mozilla.org/network/protocol;1?name=file"].createInstance(Ci.nsIFileProtocolHandler);
  1174.             this._prefDir = protocolHandler.getFileFromURLSpec(spec).parent;
  1175.         }
  1176.         
  1177.         return this._prefDir.clone();
  1178.     },
  1179.     
  1180.     getPrefDirFile: function Preferences_getPrefDirFile(aPath) {
  1181.         let prefFile = this.prefDir;
  1182.         aPath.split("/").forEach(function(path) prefFile.append(path));
  1183.         return prefFile;
  1184.     },
  1185.     
  1186.     _transformXML: function Preferences_transformXML(aXML, aStylesheet) {
  1187.         if (!(aXML && aStylesheet))
  1188.             return null;
  1189.         
  1190.         let xsltProcessor = Cc["@mozilla.org/document-transformer;1?type=xslt"].createInstance(Ci.nsIXSLTProcessor);
  1191.         
  1192.         let result = null;
  1193.         
  1194.         try {
  1195.             xsltProcessor.importStylesheet(aStylesheet);
  1196.             let ownerDocument = document.implementation.createDocument("", "xb-prefs", null);
  1197.             result = xsltProcessor.transformToFragment(aXML, ownerDocument);
  1198.         } catch (ex) {
  1199.             this._logger.error("Can't transform XML. " + ex);
  1200.         }
  1201.         
  1202.         if (!result || (result.documentElement && result.documentElement.localName == "parsererror")) {
  1203.             this._logger.trace("Can't transform XML.");
  1204.             result = null;
  1205.         }
  1206.         
  1207.         return result;
  1208.     },
  1209.     
  1210.     get _controlsStylesheet() {
  1211.         let controlsXSLTFile = this.getPrefDirFile("templates/controls.xsl");
  1212.         
  1213.         delete this._controlsStylesheet;
  1214.         return (this._controlsStylesheet = this.barCore.Lib.sysutils.xmlDocFromFile(controlsXSLTFile));
  1215.     },
  1216.     
  1217.     transformControlXML: function Preferences_transformControlXML(aControlXML) {
  1218.         let result = this._transformXML(aControlXML, this._controlsStylesheet);
  1219.         return result ? result.firstChild : null;
  1220.     },
  1221.     
  1222.     transformSourceXMLData: function Preferences_transformSourceXMLData(aInstanceID, aType, aXMLString, aStylesheetString) {
  1223.         if (!aXMLString)
  1224.             return null;
  1225.         
  1226.         let widget = ActiveWidgets.get(aInstanceID);
  1227.         if (!widget)
  1228.             return;
  1229.         
  1230.         var pkgURI = this._ioService.newURI(widget.unitPackage.resolvePath("null"), null, null);
  1231.         let domParser = new this._domParserConstructor(null, pkgURI, pkgURI);
  1232.         
  1233.         let xmlData = null;
  1234.         try {
  1235.             xmlData = domParser.parseFromString(aXMLString, "text/xml");
  1236.         } catch (ex) {}
  1237.         
  1238.         if (!xmlData)
  1239.             return null;
  1240.         
  1241.         let result;
  1242.         
  1243.         if (aStylesheetString) {
  1244.             try {
  1245.                 domParser = new this._domParserConstructor(null, pkgURI, pkgURI);
  1246.                 
  1247.                 let stylesheet = domParser.parseFromString(aStylesheetString, "text/xml");
  1248.                 xmlData = this._transformXML(xmlData, stylesheet);
  1249.             } catch (ex) {
  1250.                 this._logger.error(ex);
  1251.                 xmlData = null;
  1252.             }
  1253.             
  1254.             if (!xmlData)
  1255.                 return null;
  1256.         }
  1257.         
  1258.         try {
  1259.             let type = aType.indexOf("shortcuts") == -1 ? "source" : "shortcuts";
  1260.             let controlsXSLTFile = this.getPrefDirFile("templates/controls-" + type + ".xsl");
  1261.             
  1262.             let stylesheet = this.barCore.Lib.sysutils.xmlDocFromFile(controlsXSLTFile);
  1263.             result = this._transformXML(xmlData, stylesheet);
  1264.             
  1265.         } catch (ex) {
  1266.             this._logger.error(ex);
  1267.         }
  1268.         
  1269.         if (!result) {
  1270.             this._logger.trace("Can't transform XML data for control.");
  1271.             return null;
  1272.         }
  1273.         
  1274.         this._logger.trace("Preferences.transformControlXMLData");
  1275.         
  1276.         return result;
  1277.     },
  1278.     
  1279.     onPrefChange: function Preferences_onPrefChange(aItem, aPrefName, aPrefValue) {
  1280.         let widget = ActiveWidgets.get(aItem.id);
  1281.         
  1282.         if (widget && widget.isXbWidget) {
  1283.             let settingNode = widget.xbWidget.findSetting(aPrefName);
  1284.             
  1285.             if (settingNode) {
  1286.                 if (this.instantApply)
  1287.                   settingNode.setValue(aPrefValue);
  1288.                 else
  1289.                   SettingsProxy.remember(settingNode, aPrefValue);
  1290.             }
  1291.         }
  1292.     },
  1293.     
  1294.     doCommand: function Preferences_doCommand(aCommand, aArguments) {
  1295.         switch (aCommand) {
  1296.             case "cmd_addWidgets":
  1297.                 this.addWidgets(aArguments);
  1298.                 break;
  1299.             
  1300.             case "cmd_removeWidgets":
  1301.                 this.removeWidgets();
  1302.                 break;
  1303.             
  1304.             case "cmd_moveWidgetsUp":
  1305.                 this.moveWidgets("up");
  1306.                 break;
  1307.             
  1308.             case "cmd_moveWidgetsDown":
  1309.                 this.moveWidgets("down");
  1310.                 break;
  1311.             
  1312.             case "cmd_moveWidgets":
  1313.                 this.moveWidgets(null, aArguments);
  1314.                 break;
  1315.             
  1316.             case "cmd_restoreDefault":
  1317.                 this.restoreDefault();
  1318.                 break;
  1319.             
  1320.             case "cmd_selectAll":
  1321.                 this.selectAll();
  1322.                 break;
  1323.             
  1324.             case "cmd_deleteWidgets":
  1325.                 this.deleteWidgets();
  1326.                 break;
  1327.             
  1328.             default:
  1329.                 break;
  1330.         }
  1331.     },
  1332.     
  1333.     handleEvent: function Preferences_handleEvent(aEvent) {
  1334.         switch (aEvent.type) {
  1335.             case "load":
  1336.                 aEvent.currentTarget.removeEventListener("load", arguments.callee, false);
  1337.                 
  1338.                 ["width", "height"].forEach(function(aAttrName) {
  1339.                     if (this.hasAttribute("min" + aAttrName) && this.hasAttribute(aAttrName)) {
  1340.                         let minval = parseInt(this.getAttribute("min" + aAttrName), 10);
  1341.                         let realval = parseInt(this.getAttribute(aAttrName), 10);
  1342.                         
  1343.                         if (realval && minval) {
  1344.                             let val = Math.max(minval, realval);
  1345.                             
  1346.                             if (minval > realval)
  1347.                                 this.setAttribute(aAttrName, val);
  1348.                             
  1349.                             if (aAttrName == "height")
  1350.                                 window.outerHeight = val;
  1351.                             else if (aAttrName == "width")
  1352.                                 window.outerWidth = val;
  1353.                         }
  1354.                     }
  1355.                 }, document.documentElement);
  1356.                 
  1357.                 if ("arguments" in window && window.arguments.length > 1)
  1358.                     this.selectWidget(window.arguments[1]);
  1359.                 
  1360.                 break;
  1361.                 
  1362.             case "paneload":
  1363.                 document.documentElement.__defineGetter__("_shouldAnimate", function() false);
  1364.                 
  1365.                 this._initPane(aEvent.target.id);
  1366.                 
  1367.                 break;
  1368.                 
  1369.             case "unload":
  1370.                 document.documentElement.cancelDialog();
  1371.                 break;
  1372.             
  1373.             default:
  1374.                 break;
  1375.         }
  1376.     },
  1377.     
  1378.     _getUserConfirm: function Preferences__getUserConfirm(aTitle, aText) {
  1379.         return Cc["@mozilla.org/embedcomp/prompt-service;1"]
  1380.                    .getService(Ci.nsIPromptService)
  1381.                    .confirm(window, aTitle, aText);
  1382.     },
  1383.                                    
  1384.     get _stringBundle() {
  1385.         delete this._stringBundle;
  1386.         return this._stringBundle = new Preferences.barCore.Lib.misc.StringBundle("preferences/preferences.properties");
  1387.     },
  1388.     
  1389.     getString: function Preferences_getString(aName, aArgs) {
  1390.         return this._stringBundle.get(aName, aArgs);
  1391.     },
  1392.     
  1393.     getStringPlural: function Preferences_getStringPlural(aName, aArgs, aPluralData) {
  1394.         return this._stringBundle.getPlural(aName, aArgs, aPluralData);
  1395.     }
  1396. };
  1397.  
  1398. var RegisteredWidgetsController = {
  1399.     _inited: false,
  1400.     
  1401.     init: function RWL_init() {
  1402.         this.finalize();
  1403.         this._inited = true;
  1404.     },
  1405.     
  1406.     finalize: function RWL_finalize() {
  1407.         if (this._list) {
  1408.             this.list.clear();
  1409.             this._list = null;
  1410.         }
  1411.         
  1412.         this._inited = false;
  1413.     },
  1414.     
  1415.     _list: null,
  1416.     
  1417.     get list() {
  1418.         return this._list || (this._list = document.getElementById("registered-widgets-list"));
  1419.     },
  1420.     
  1421.     insertItem: function RWL_insertItem(aWidgetProxy, aBeforeID) {
  1422.         return this.list.insertItem(aWidgetProxy.isUnique,
  1423.                                     aWidgetProxy.isRemovable,
  1424.                                     aWidgetProxy.protoId,
  1425.                                     aWidgetProxy.name,
  1426.                                     aWidgetProxy.iconURL,
  1427.                                     aBeforeID);
  1428.     },
  1429.     
  1430.     checkWidgetUniqueState: function RWL_checkWidgetUniqueState(aProtoID, aHide) {
  1431.         let listitem = document.getElementById(aProtoID);
  1432.         
  1433.         if (listitem) {
  1434.             listitem.hidden = aHide;
  1435.             
  1436.             if (aHide)
  1437.                 this.list.removeItemFromSelection(listitem);
  1438.         }
  1439.     },
  1440.     
  1441.     removeItem: function RWL_removeItem(aProtoIdOrListItem) {
  1442.         let listItem = aProtoIdOrListItem;
  1443.         if (typeof listItem == "string")
  1444.             listItem = document.getElementById(aProtoIdOrListItem);
  1445.         
  1446.         if (listItem && listItem.parentNode == this.list) {
  1447.             this.list.removeItemFromSelection(listItem);
  1448.             
  1449.             let indx = this.list.getIndexOfItem(listItem);
  1450.             this.list.removeItemAt(indx);
  1451.         }
  1452.     }
  1453. };
  1454.  
  1455. var ActiveWidgetsController = {
  1456.     init: function AWL_init() {
  1457.         this.finalize();
  1458.         this.list.PreferencesController = Preferences;
  1459.     },
  1460.     
  1461.     finalize: function AWL_finalize() {
  1462.         if (this._list) {
  1463.             this.list.clear();
  1464.             this.list.PreferencesController = null;
  1465.             this._list = null;
  1466.         }
  1467.     },
  1468.     
  1469.     _list: null,
  1470.     
  1471.     get list() {
  1472.         return this._list || (this._list = document.getElementById("active-widgets-list"));
  1473.     },
  1474.     
  1475.     selectItem: function AWL_selectItem(aWidgetProxy) {
  1476.         this.list.selectedItem = document.getElementById(aWidgetProxy.id);
  1477.     },
  1478.     
  1479.     insertItem: function AWL_insertItem(aWidgetProxy, aBeforeID) {
  1480.         if (aWidgetProxy.isUnique)
  1481.             RegisteredWidgetsController.checkWidgetUniqueState(aWidgetProxy.protoId, true);
  1482.         
  1483.         return this.list.insertItem(aWidgetProxy.isUnique,
  1484.                                     aWidgetProxy.isRemovable,
  1485.                                     aWidgetProxy.id,
  1486.                                     aWidgetProxy.name,
  1487.                                     aWidgetProxy.iconURL,
  1488.                                     aBeforeID);
  1489.     },
  1490.     
  1491.     removeItem: function AWL_removeItem(aItem) {
  1492.         if (aItem && aItem.parentNode == this.list) {
  1493.             this.list.removeItemFromSelection(aItem);
  1494.             
  1495.             let indx = this.list.getIndexOfItem(aItem);
  1496.             this.list.removeItemAt(indx);
  1497.         }
  1498.     },
  1499.     
  1500.     moveSelectedItems: function AWL_moveSelectedItems(aDirection, aBeforeElementId) {
  1501.         return this.list.moveSelectedItems(aDirection, aBeforeElementId);
  1502.     },
  1503.     
  1504.     getItemsForProto: function AWL_getItemsForProto(aWidgetProtoID) {
  1505.         return Array.slice(this.list.childNodes)
  1506.                     .filter(function(aItem) {
  1507.                         let widget = ActiveWidgets.get(aItem.id);
  1508.                         return !!(widget && widget.protoId == aWidgetProtoID);
  1509.                     });
  1510.     },
  1511.     
  1512.     _getProxiedSettingValue: function AWL__getProxiedSettingValue(aSettingNode) {
  1513.         let value = SettingsProxy.recall(aSettingNode);
  1514.         
  1515.         if (typeof(value) == "undefined")
  1516.             value = aSettingNode.getValue();
  1517.         
  1518.         return value;
  1519.     },
  1520.     
  1521.     initItemSettings: function AWL_initItemSettings(aItem) {
  1522.         let widget = ActiveWidgets.get(aItem.id);
  1523.         if (!widget)
  1524.             return;
  1525.         
  1526.         if (!widget.isXbWidget) {
  1527.             if (aItem.getAttribute("xb-static-inited") == "true")
  1528.                 return;
  1529.             
  1530.             aItem.setAttribute("xb-static-inited", "true");
  1531.             
  1532.             if (widget.xulDocument) {
  1533.                 let staticGUI = widget.xulDocument.getElementsByTagName("gui");
  1534.                 for (let i = staticGUI.length; i--;) {
  1535.                     let guiNode = staticGUI[i];
  1536.                     
  1537.                     let guiNodes = guiNode.childNodes;
  1538.                     for (let j = 0, len = guiNodes.length; ++j < len;)
  1539.                         aItem.appendChild(document.importNode(guiNodes[j], true));
  1540.                     
  1541.                     if (guiNode.hasAttribute("onload"))
  1542.                         (new Function(guiNode.getAttribute("onload")))();
  1543.                 }
  1544.                 
  1545.                 widget.updatePreferenceNodes();
  1546.             }
  1547.             
  1548.             return;
  1549.         }
  1550.         
  1551.         let settingsContainer = aItem.settingsContainer;
  1552.         
  1553.         let protoSettings = widget.protoSettings;
  1554.         let instSettings = widget.instSettings;
  1555.         
  1556.         for (let [name, setting] in Iterator(instSettings)) {
  1557.             let element = this._createSettingUI(widget, name, setting.controlInfo);
  1558.             
  1559.             if (element) {
  1560.                 let settingNode = setting.node;
  1561.                 element.setAttribute("value", this._getProxiedSettingValue(settingNode));
  1562.                 settingsContainer.appendChild(element);
  1563.             }
  1564.         }
  1565.         
  1566.         for (let [name, setting] in Iterator(protoSettings)) {
  1567.             let element = this._createSettingUI(widget, name, setting.controlInfo);
  1568.             
  1569.             if (element) {
  1570.                 let settingNode = setting.node;
  1571.                 element.setAttribute("value", this._getProxiedSettingValue(settingNode));
  1572.                 element.setAttribute("xb-global-setting-warning", "auto");
  1573.                 element.setAttribute("xb-global-setting-names", widget.name);
  1574.                 settingsContainer.appendChild(element);
  1575.             }
  1576.         }
  1577.     },
  1578.     
  1579.     _createSettingUI: function AWL__createSettingUI(aWidget, aSettingName, aControlInfo) {
  1580.         let control = Preferences.transformControlXML(aControlInfo);
  1581.         
  1582.         if (!control)
  1583.             return null;
  1584.         
  1585.         control.setAttribute("prefName", aSettingName);
  1586.         
  1587.         ["source", "alt-source",
  1588.          "template", "alt-template",
  1589.          "shortcuts-source", "shortcuts-alt-source",
  1590.          "shortcuts-template", "shortcuts-alt-template"
  1591.         ].forEach(function(aAttrName) {
  1592.             if (control.hasAttribute(aAttrName)) {
  1593.                 let url = aWidget.makeURL(control.getAttribute(aAttrName));
  1594.                 
  1595.                 if (url) {
  1596.                     control.setAttribute(aAttrName, url);
  1597.                 } else {
  1598.                     control.removeAttribute(aAttrName);
  1599.                 }
  1600.             }
  1601.         }, this);
  1602.         
  1603.         return control;
  1604.     }
  1605. };
  1606.  
  1607. window.addEventListener("load", Preferences, false);
  1608. window.addEventListener("paneload", Preferences, false);
  1609.