home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2005 October / Gamestar_77_2005-10_dvd.iso / Programy / nsb-install-8-0.exe / chrome / toolkit.jar / content / global / bindings / toolbar.xml < prev    next >
Extensible Markup Language  |  2005-07-29  |  33KB  |  874 lines

  1. <?xml version="1.0"?>
  2.  
  3. <bindings id="toolbarBindings"
  4.           xmlns="http://www.mozilla.org/xbl"
  5.           xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
  6.           xmlns:xbl="http://www.mozilla.org/xbl">
  7.  
  8.   <binding id="toolbar-base">
  9.     <resources>
  10.       <stylesheet src="chrome://global/skin/toolbar.css"/>
  11.     </resources>
  12.     <implementation implements="nsIAccessibleProvider">
  13.       <property name="accessible">
  14.         <getter>
  15.           <![CDATA[
  16.             var accService = Components.classes["@mozilla.org/accessibilityService;1"].getService(Components.interfaces.nsIAccessibilityService);
  17.             if (this.localName == "toolbarseparator")
  18.               return accService.createXULToolbarSeparatorAccessible(this);
  19.             else
  20.               return accService.createXULToolbarAccessible(this);
  21.           ]]>
  22.         </getter>
  23.       </property>
  24.       <constructor>
  25.         <![CDATA[
  26.           this.debug("TOOLBAR-BASE : Constructor, localName : " + this.localName + "\n");
  27.       ]]>
  28.       </constructor>
  29.       <method name="debug">
  30.         <parameter name="aStr"/>
  31.             <body>
  32.              //dump ("MULTIBAR: " + aStr);
  33.             </body>
  34.         </method>
  35.     </implementation>
  36.   </binding>
  37.  
  38.   <binding id="toolbox" extends="chrome://global/content/bindings/toolbar.xml#toolbar-base">
  39.     <implementation name="toolboxImp">
  40.       <field name="palette">
  41.         null
  42.       </field>
  43.  
  44.       <field name="toolbarset">
  45.         null
  46.       </field>
  47.  
  48.       <field name="customToolbarCount">
  49.         0
  50.       </field>
  51.  
  52.       <field name="customMultibarCount">
  53.         0
  54.       </field>
  55.  
  56.       <constructor>
  57.         <![CDATA[
  58.  
  59.           this.debug("TOOLBOX : Constructor, localName : " + this.localName + "\n");
  60.           // Look to see if there is a toolbarset.
  61.           this.toolbarset = this.firstChild;
  62.           while (this.toolbarset && this.toolbarset.localName != "toolbarset")
  63.             this.toolbarset = toolbarset.nextSibling;
  64.  
  65.           if (this.toolbarset) {
  66.             // Create each toolbar described by the toolbarset.
  67.             var index = 0;
  68.             while (toolbarset.hasAttribute("toolbar"+(++index))) {
  69.               var toolbarInfo = toolbarset.getAttribute("toolbar"+index);
  70.               var infoSplit = toolbarInfo.split(":");
  71.               // JMC MERC - Added to handle spui components in custom bars
  72.               var toolbarName = infoSplit.shift();
  73.               var toolbarcontents = infoSplit.join(":");
  74.               toolbar = this.appendCustomToolbar(toolbarName, toolbarcontents, true); // Dont add to set
  75.                 toolbar.setAttribute("iconsize", this.toolbarset.getAttribute("toolbariconsize"+index));
  76.                 toolbar.setAttribute("mode", this.toolbarset.getAttribute("toolbarmode"+index));
  77.             }
  78.  
  79.             index = 0;
  80.             while (toolbarset.hasAttribute("multibar"+(++index))) {
  81.                 this.debug ("Inserting a multibar\n");
  82.               var multibarInfo = toolbarset.getAttribute("multibar"+index);
  83.               if (multibarInfo) {
  84.                 var infoSplit = multibarInfo.split(":");
  85.                 // JMC MERC - Added to handle spui components in custom bars
  86.                 var multibarName = infoSplit.shift();
  87.                 var multibarcontents = infoSplit.join(":");
  88.                 var currentIdx = this.toolbarset.getAttribute("multibarselected"+index);
  89.                 var multibarshowtitle = this.toolbarset.getAttribute("multibarshowtitle"+index);
  90.                 var multibariconsize = this.toolbarset.getAttribute("multibariconsize"+index);
  91.                 var multibarmode = this.toolbarset.getAttribute("multibarmode"+index);
  92.                 var multibar = this.appendCustomMultibar(multibarName, multibarcontents, true); // Dont add to set
  93.                 multibar.setAttribute("currentIndex", currentIdx);
  94.                 multibar.setAttribute("iconsize", multibariconsize);
  95.                 multibar.setAttribute("mode", multibarmode);
  96.                 this.debug ("The multibar will show title : " + multibarshowtitle + "\n");
  97.                 multibar.setAttribute('showtitle', multibarshowtitle);
  98.                }
  99.               }
  100.           }
  101.  
  102.          this.reorderToolbars();
  103.         ]]>
  104.       </constructor>
  105.  
  106.       <method name="removeToolbar">
  107.         <parameter name="aElt"/>
  108.         <body>
  109.           <![CDATA[
  110.           this.debug("TOOLBOX: Gonna delete toolbar called " + aElt.id + "\n");
  111.  
  112.           if (aElt.localName == 'toolbar' || aElt.localName == 'multibar') {
  113.             var orderSplit = this.toolbarset.getAttribute("toolbarorder").split(",");
  114.               var currentIndex = null;
  115.               this.debug(' - orderSplit has '+orderSplit.length+' items:\n');
  116.             for (var i=0; i < orderSplit.length; i++) {
  117.               this.debug('  - ['+i+'] = '+orderSplit[i]+'\n');
  118.               if (orderSplit[i] == aElt.id) {
  119.                 currentIndex = i;
  120.                 break;
  121.               }
  122.               }
  123.               this.debug(' - currentIndex = '+currentIndex+'\n');
  124.  
  125.               if (currentIndex != null) {
  126.               orderSplit.splice(currentIndex,1);
  127.               var newToolbarOrder = orderSplit.join(',');
  128.               this.debug(' - newToolbarOrder = '+newToolbarOrder+'\n');
  129.               this.toolbarset.setAttribute("toolbarorder", newToolbarOrder);
  130.               this.reorderToolbars();
  131.               }
  132.           }
  133.           this.removeChild(aElt);
  134.           ]]>
  135.         </body>
  136.       </method>
  137.       
  138.       <method name="renameToolbar">
  139.        <parameter name="aToolbar"/>
  140.        <parameter name="aName"/>
  141.         <body>
  142.           <![CDATA[
  143.                
  144.             if (aToolbar.localName == 'toolbar' || aToolbar.localName == 'multibar') {
  145.                 var orderSplit = this.toolbarset.getAttribute("toolbarorder").split(",");
  146.                   var currentIndex;
  147.                   for (var i=0; i < orderSplit.length; i++) {
  148.                           if (orderSplit[i] == aToolbar.id) {
  149.                               currentIndex = i;
  150.                               break;
  151.                           }
  152.                   }
  153.                   
  154.                  var oldId = aToolbar.id;
  155.                   
  156.                   // aToolbar.id = '';
  157.                   if (aToolbar.localName == 'toolbar')
  158.                   {
  159.                     if (aToolbar.id != 'nav-bar') {
  160.                         aToolbar.id = "__customToolbar_" + aName.replace(" ", "_");
  161.                        }
  162.                  } else if (aToolbar.id != 'PersonalToolbar') {
  163.                         aToolbar.id = "__customMultibar_" + aName.replace(" ", "_");                 
  164.                  }
  165.                  
  166.                  if (this.toolbarset.getAttribute('showsearch') == oldId) {
  167.                     this.toolbarset.setAttribute('showsearch', aToolbar.id);
  168.                     document.persist(this.toolbarset.id, "showsearch");
  169.                 }
  170.                  
  171.                  aToolbar.setAttribute('toolbarname', aName);
  172.                  orderSplit[currentIndex] = aToolbar.id;
  173.                  this.toolbarset.setAttribute("toolbarorder", orderSplit.join(","));
  174.                     this.reorderToolbars();
  175.              }
  176.                ]]>
  177.           </body>
  178.       </method>
  179.  
  180.       <method name="appendCustomToolbar">
  181.         <parameter name="aName"/>
  182.         <parameter name="aCurrentSet"/>
  183.         <parameter name="bDontAddToSet"/>
  184.         <body>
  185.           <![CDATA[
  186.             var toolbar = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
  187.                                                   "toolbar");
  188.             toolbar.id = "__customToolbar_" + aName.replace(" ", "_");
  189.             toolbar.setAttribute("customizable", "true");
  190.             toolbar.setAttribute("customindex", ++this.customToolbarCount);
  191.             toolbar.setAttribute("toolbarname", aName);
  192.             toolbar.setAttribute("currentset", aCurrentSet);
  193.             toolbar.setAttribute("currentSetAtLoadTime", aCurrentSet);
  194.             toolbar.setAttribute("mode", this.getAttribute("mode"));
  195.             toolbar.setAttribute("iconsize", this.getAttribute("iconsize"));
  196.             toolbar.setAttribute("context", this.toolbarset.getAttribute("context"));
  197.           toolbar.setAttribute("class", "chromeclass-toolbar toolbar-primary");
  198.             toolbar.enableOverflowMenu = true;
  199.  
  200.             this.insertBefore(toolbar, this.toolbarset);
  201.             if (!bDontAddToSet)
  202.                    this.assignOrdinal(toolbar);
  203.             return toolbar;
  204.           ]]>
  205.         </body>
  206.       </method>
  207.  
  208.       <method name="appendCustomMultibar">
  209.         <parameter name="aName"/>
  210.         <parameter name="aCurrentSet"/>
  211.         <parameter name="bDontAddToSet"/>
  212.         <body>
  213.           <![CDATA[
  214.             var toolbar = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
  215.                                                   "multibar");
  216.             // JMC: Ugly custom case hack! Fixme
  217.             if (aName == 'PersonalToolbar') {
  218.                 toolbar.id = aName;
  219.             } else {
  220.                 toolbar.id = "__customMultibar_" + aName.replace(" ", "_");
  221.                }
  222.             toolbar.setAttribute("customizable", "true");
  223.             toolbar.setAttribute("customindex", ++this.customMultibarCount);
  224.             toolbar.setAttribute("toolbarname", aName);
  225.             toolbar.setAttribute("currentset", aCurrentSet); // JMC: Subtle change from above
  226.             toolbar.setAttribute("currentSetAtLoadTime", aCurrentSet);
  227.             toolbar.setAttribute("mode", this.getAttribute("mode"));
  228.             toolbar.setAttribute("iconsize", this.getAttribute("iconsize"));
  229.             toolbar.setAttribute("context", this.toolbarset.getAttribute("context"));
  230.             toolbar.setAttribute("class", "chromeclass-toolbar");
  231.  
  232.             this.insertBefore(toolbar, this.toolbarset);
  233.             if (!bDontAddToSet)
  234.                    this.assignOrdinal(toolbar);
  235.             return toolbar;
  236.           ]]>
  237.         </body>
  238.       </method>
  239.  
  240.       <method name="reorderToolbars">
  241.       <body>
  242.       <![CDATA[
  243.  
  244.         // dump ("Calling reorderToolbars... \n\n");
  245.  
  246.           if (this.toolbarset && this.toolbarset.hasAttribute("toolbarorder")) {
  247.               var thisChild = this.firstChild;
  248.               while (thisChild) {
  249.                   if (thisChild.localName == 'toolbar' ||
  250.                   thisChild.localName == 'multibar') {
  251.                       thisChild.removeAttribute('ordinal');
  252.                   }
  253.                   thisChild = thisChild.nextSibling;
  254.               }
  255.  
  256.  
  257.               var orderSplit = this.toolbarset.getAttribute("toolbarorder").split(",");
  258.               var lowestOrdinal = 0;
  259.               for (var i = 0; i < orderSplit.length; i++) {
  260.                   // dump ("Trying to assign ordinal for toolbar with id of " + orderSplit[i] + "\n\n");
  261.                   var toolbar = document.getElementById(orderSplit[i]);
  262.                   if (toolbar) {
  263.                     toolbar.setAttribute('ordinal', i+1);
  264.                     toolbar.removeAttribute('highestToolbar');
  265.                   // dump ("Set ordinal " + i + " for toolbar with id of " + orderSplit[i] + "\n\n");
  266.                     if (i == lowestOrdinal)
  267.                     {
  268.                         if (toolbar.getAttribute('collapsed') == 'true')
  269.                             lowestOrdinal = lowestOrdinal + 1;
  270.                         else
  271.                              toolbar.setAttribute('highestToolbar','true');
  272.                     } 
  273.                   }
  274.               }
  275.           }
  276.           ]]>
  277.         </body>
  278.       </method>
  279.  
  280.       <method name="assignOrdinal">
  281.             <parameter name="aToolbar"/>
  282.         <body>
  283.           <![CDATA[
  284.  
  285.          // JMC - add it to the ordering in the toolbarset
  286.          if (this.toolbarset) {
  287.                 var barOrder = this.toolbarset.getAttribute("toolbarorder");
  288.                 this.toolbarset.setAttribute("toolbarorder", barOrder + "," + aToolbar.id);
  289.                 document.persist(this.toolbarset.id, "toolbarorder");
  290.             }
  291.          // }
  292.          ]]>
  293.         </body>
  294.        </method>
  295.  
  296.       <method name="moveToolbarUp">
  297.           <parameter name="aToolbar"/>
  298.           <body>
  299.           <![CDATA[
  300.  
  301.           if (aToolbar.localName == 'multibartray') {
  302.               aToolbar.parentNode.moveTrayUp(aToolbar);
  303.               return;
  304.           }
  305.  
  306.           var orderSplit = this.toolbarset.getAttribute("toolbarorder").split(",");
  307.           var currentIndex;
  308.           for (var i=0; i < orderSplit.length; i++) {
  309.                       if (orderSplit[i] == aToolbar.id) {
  310.                       currentIndex = i;
  311.                       break;
  312.                       }
  313.           }
  314.  
  315.           if (currentIndex > 0) {
  316.               var previousToolbarId = orderSplit[currentIndex - 1];
  317.               orderSplit[currentIndex] = previousToolbarId;
  318.               orderSplit[currentIndex - 1] = aToolbar.id;
  319.  
  320.               this.toolbarset.setAttribute("toolbarorder", orderSplit.join(","));
  321.                this.reorderToolbars();
  322.           }
  323.  
  324.           ]]>
  325.           </body>
  326.       </method>
  327.  
  328.  
  329.       <method name="moveToolbarDown">
  330.           <parameter name="aToolbar"/>
  331.           <body>
  332.           <![CDATA[
  333.  
  334.           if (aToolbar.localName == 'multibartray') {
  335.               aToolbar.parentNode.moveTrayDown(aToolbar);
  336.               return;
  337.           }
  338.  
  339.           var orderSplit = this.toolbarset.getAttribute("toolbarorder").split(",");
  340.           var currentIndex;
  341.           for (var i=0; i < orderSplit.length; i++) {
  342.                if (orderSplit[i] == aToolbar.id) {
  343.                    currentIndex = i;
  344.                    break;
  345.                }
  346.           }
  347.  
  348.           if (currentIndex < orderSplit.length - 1) {
  349.               var nextToolbarId = orderSplit[currentIndex + 1];
  350.               orderSplit[currentIndex] = nextToolbarId;
  351.               orderSplit[currentIndex + 1] = aToolbar.id;
  352.  
  353.               this.toolbarset.setAttribute("toolbarorder", orderSplit.join(","));
  354.                this.reorderToolbars();
  355.           }
  356.  
  357.           ]]>
  358.           </body>
  359.       </method>
  360.     </implementation>
  361.   </binding>
  362.  
  363.   <binding id="toolbar" extends="chrome://global/content/bindings/toolbar.xml#toolbar-base">
  364.     <implementation name="toolbarimp">
  365.       <field name="firstPermanentChild">
  366.         null
  367.       </field>
  368.       <field name="lastPermanentChild">
  369.         null
  370.       </field>
  371.  
  372.       <property name="toolbarName"
  373.                 onget="return this.getAttribute('toolbarname');"
  374.                 onset="this.setAttribute('toolbarname', val); return val;"/>
  375.        <property name="joshtemp">
  376.            <getter>
  377.           <![CDATA[
  378.            if (this.hasAttribute('customindex'))
  379.             return this.toolbox.toolbarset.getAttribute('joshtemp' + this.getAttribute('customindex'));
  380.                    ]]>
  381.            </getter>
  382.            <setter>
  383.           <![CDATA[
  384.           if (this.hasAttribute('customindex'))
  385.           {
  386.           this.toolbox.toolbarset.setAttribute('joshtemp' + this.getAttribute('customindex'), val);
  387.           document.persist(this.toolbox.toolbarset.id, 'joshtemp' + this.getAttribute('customindex'));
  388.           } else {
  389.             this.debug('ACK! no customindex attribute.\n');
  390.             this.setAttribute('joshtemp', val);
  391.           }
  392.          return val;
  393.                    ]]>
  394.            </setter>
  395.         </property>
  396.       <constructor>
  397.         <![CDATA[
  398.           this.debug("TOOLBAR : Constructor, localName : " + this.localName + "\n");
  399.            if (this.currentSetAtLoadTime)
  400.             return;
  401.  
  402.           this.firstPermanentChild = this.firstChild;
  403.           this.lastPermanentChild = this.lastChild;
  404.  
  405.  
  406.           // Searching for the toolbox palette in the toolbar binding because
  407.           // toolbars are constructed first.
  408.           if (!this.toolbox || this.toolbox.localName != 'toolbox') {
  409.             if (this.parentNode.localName == 'toolbox')
  410.                this.toolbox = this.parentNode;
  411.             else
  412.               this.toolbox = this.parentNode.parentNode;
  413.           }
  414.  
  415.           if (!this.toolbox.palette) {
  416.             // Look to see if there is a toolbarpalette.
  417.             var node = this.toolbox.firstChild;
  418.             while (node) {
  419.               if (node.localName == "toolbarpalette")
  420.                 break;
  421.               node = node.nextSibling;
  422.             }
  423.  
  424.             if (!node || node.localName != "toolbarpalette")
  425.               return;
  426.  
  427.             // Hold on to the palette but remove it from the document.
  428.             this.toolbox.palette = node;
  429.             this.toolbox.removeChild(node);
  430.           }
  431.  
  432.           // Build up our contents from the palette.
  433.           var currentSet = this.getAttribute("currentset");
  434.           if (!currentSet)
  435.             currentSet = this.getAttribute("defaultset");
  436.           if (currentSet)
  437.             this.currentSet = currentSet;
  438.           // Merc: save the initial value of currentSet for asynchronous SPUI loading
  439.           this.currentSetAtLoadTime = currentSet;
  440.  
  441.           // JMC: All toolbars have overflow by default
  442.           if (this.localName == 'multibartray')
  443.               this.enableOverflowMenu = true;
  444.         ]]>
  445.       </constructor>
  446.  
  447.       <property name="currentSetAtLoadTime"/>
  448.       <property name="toolbox"/>
  449.       <property name="currentSet">
  450.         <getter>
  451.           <![CDATA[
  452.  
  453.           /*
  454.  
  455.           MERC: Need to preserve the instance id (for multiple buttons) in current set,
  456.           so that preferences can be kept for each button instance.
  457.  
  458.           */
  459.  
  460.  
  461.             var node = this.firstChild;
  462.             var currentSet = "";
  463.             while (node) {
  464.               if (node.id &&
  465.                   node.localName == "toolbaritem" ||
  466.                   node.localName == "toolbarbutton" ||
  467.                   node.localName == "toolbarseparator" ||
  468.                   node.localName == "toolbarspring" ||
  469.                   node.localName == "toolbarspacer")
  470.               {
  471.                 if (currentSet)
  472.                   currentSet += ",";
  473.  
  474.                 if (node.localName == "toolbarseparator")
  475.                   currentSet += "separator";
  476.                 else if (node.localName == "toolbarspring")
  477.                   currentSet += "spring";
  478.                 else if (node.localName == "toolbarspacer")
  479.                   currentSet += "spacer";
  480.                 else
  481.                   currentSet += node.id;
  482.               }
  483.               node = node.nextSibling;
  484.             }
  485.  
  486.             return currentSet ? currentSet : "__empty";
  487.           ]]>
  488.         </getter>
  489.  
  490.         <setter>
  491.           <![CDATA[
  492.             // Remove all items before the first permanent child and after the last permanent child.
  493.             while (this.lastChild) {
  494.               if (this.localName != 'multibartray' && (this.lastChild == this.lastPermanentChild ||
  495.                   (this.lastChild.localName == "toolbarpaletteitem" &&
  496.                   this.lastChild.firstChild == this.lastPermanentChild)))
  497.                 break;
  498.               this.removeChild(this.lastChild);
  499.             }
  500.  
  501.             while (this.firstChild) {
  502.               if (this.localName != 'multibartray' && (this.firstChild == this.firstPermanentChild ||
  503.                   (this.firstChild.localName == "toolbarpaletteitem" &&
  504.                   this.firstChild.firstChild == this.firstPermanentChild)))
  505.                 break;
  506.               this.removeChild(this.firstChild);
  507.             }
  508.  
  509.             var firstChildID = this.firstPermanentChild ? this.firstPermanentChild.id : "";
  510.             var lastChildID = this.lastPermanentChild ? this.lastPermanentChild.id : "";
  511.  
  512.             if (val == "__empty")
  513.               return;
  514.  
  515.             if (val) {
  516.            //     dump("TOOLBAR: Setting current set to : " + val + "\n");
  517.               var itemIds = val.split(",");
  518.               var before = true;
  519.               for (var i = 0; i < itemIds.length; i++) {
  520.                 if ((itemIds[i] == firstChildID) || (itemIds[i] == lastChildID)) {
  521.                   before = false;
  522.                      this.insertItem(itemIds[i], null, null, before);
  523.                 }
  524.                 else if (itemIds[i].indexOf("spui:") == -1 || this.toolbox) {
  525.                     // Don't bother inserting spui now
  526.                     // JMC : HACK
  527.                     if (this.localName == 'multibartray')
  528.                         before = false;
  529.                   this.insertItem(itemIds[i], null, null, before);
  530.                 }
  531.               }
  532.             }
  533.           ]]>
  534.         </setter>
  535.       </property>
  536.  
  537.       <method name="reorderItems">
  538.     <body>
  539.     <![CDATA[
  540.  
  541.     if ((this.getAttribute('customindex')
  542.          || this.parentNode.getAttribute('customindex'))
  543.          && this.currentSet != "__empty") {
  544.  
  545.         var thisChild = this.firstChild;
  546.         while (thisChild) {
  547.             thisChild.removeAttribute('ordinal');
  548.             thisChild = thisChild.nextSibling;
  549.         }
  550.  
  551.         var orderSplit = this.currentSet.split(",");
  552.         for (var i = 0; i < orderSplit.length; i++) {
  553.             var toolItem = document.getElementById(orderSplit[i]);
  554.             if (toolItem)
  555.               toolItem.setAttribute('ordinal', i+1);
  556.         }
  557.     }
  558.     ]]>
  559.       </body>
  560.       </method>
  561.  
  562.       <method name="insertItem">
  563.         <parameter name="aId"/>
  564.         <parameter name="aBeforeElt"/>
  565.         <parameter name="aWrapper"/>
  566.         <parameter name="aBeforePermanent"/>
  567.         <body>
  568.           <![CDATA[
  569.           
  570.           // dump("Insert Item named " + aId + "\n");
  571.           
  572.             var newItem = null;
  573.  
  574.             // Create special cases of palette items.
  575.             var uniqueId;
  576.             if (aId == "separator") {
  577.               newItem = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
  578.                                                  "toolbarseparator");
  579.               uniqueId = (new Date()).getTime()+this.childNodes.length;
  580.               newItem.id = "separator" + uniqueId;
  581.             } else if (aId == "spring") {
  582.               newItem = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
  583.                                                  "toolbarspring");
  584.               uniqueId = (new Date()).getTime()+this.childNodes.length;
  585.               newItem.flex = 1;
  586.               newItem.id = "spring" + uniqueId;
  587.             } else if (aId == "spacer") {
  588.               newItem = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
  589.                                                  "toolbarspacer");
  590.               uniqueId = (new Date()).getTime()+this.childNodes.length;
  591.               newItem.id = "spacer" + uniqueId;
  592.             } else {
  593.  
  594.                 var prefix;
  595.                 if (aId.indexOf("|") > -1) // This has a unique id
  596.                {
  597.                         prefix = aId.substring(aId.indexOf("|") + 1,aId.length);
  598.                         aId = aId.substring(0, aId.indexOf("|"));
  599.                }
  600.                // JMC: if this is the second instance, add a unique prefix
  601.                // var bIsDuplicate;
  602.                // var toolbarItem = this.parentNode.
  603.  
  604.                if (!this.toolbox || !this.toolbox.palette.firstChild) {
  605.                    this.debug("++++ Toolbar/multitray bug - no palette available! \n\n");
  606.                    return;
  607.                }
  608.  
  609.               // Attempt to locate an item with a matching id within palette.
  610.               var paletteItem = this.toolbox.palette.firstChild;
  611.               while (paletteItem) {
  612.                 var paletteId = paletteItem.id;
  613.                 // JMC - allow arbitrary id extensions
  614.  
  615.                 if (paletteId == aId) {
  616.                   newItem = paletteItem.cloneNode(true);
  617.                   if (newItem.getAttribute("allowDuplicate")) {
  618.                           // JMC: Try a quick hack - give every button a unique
  619.                            if (!prefix) {
  620.                                prefix = (new Date()).getTime()+this.childNodes.length;
  621.                        }
  622.  
  623.                    }
  624.                   if (prefix) {
  625.                       newItem.id = newItem.id + "|" + prefix;
  626.                       // JMC: Evil Hack - for spui buttons, find the iframe and change that id, too
  627.  
  628.                       if (newItem.id.substring(0,5) == "spui:" ) {
  629.                           var iframe;
  630.                           var itemChild = newItem.firstChild;
  631.                           var bFound;
  632.                           while (itemChild && !bFound) {
  633.                               if (itemChild.localName == "stack") {
  634.                                   var stackChild = itemChild.firstChild;
  635.                                   while (stackChild && !bFound) {
  636.                                       if (stackChild.localName == "vbox") {
  637.                                           var vboxChild = stackChild.firstChild;
  638.                                           while (vboxChild && !bFound) {
  639.                                               if (vboxChild.localName == "iframe") {
  640.                                                   iframe = vboxChild;
  641.                                                   iframe.id = newItem.id + "-iframe";
  642.                                                   bFound = true;
  643.                                               }
  644.                                               vboxChild = vboxChild.nextSibling;
  645.                                           }
  646.                                       }
  647.                                       stackChild = stackChild.nextSibling;
  648.                                   }
  649.                               }
  650.                               itemChild = itemChild.nextSibling;
  651.                           }
  652.                       }
  653.                   }
  654.                   this.debug("inserting toolbar item from palette: "+paletteId+"\n");
  655.                   break;
  656.                 }
  657.                 paletteItem = paletteItem.nextSibling;
  658.               }
  659.               if (!newItem)
  660.                 this.debug("unable to find palette item for: "+aId+"\n");
  661.             }
  662.  
  663.             if (!newItem)
  664.               return false;
  665.  
  666.             var insertItem = newItem;
  667.  
  668.             // Wrap the item in another node if so inclined.
  669.             if (aWrapper) {
  670.               aWrapper.appendChild(newItem);
  671.               insertItem = aWrapper;
  672.             }
  673.  
  674.             if (this.firstPermanentChild)
  675.               this.debug('First permanent child: '+this.firstPermanentChild.id+'\n');
  676.  
  677.             // Insert the palette item into the toolbar.
  678.             if (aBeforeElt)
  679.             {
  680.               this.insertBefore(insertItem, aBeforeElt);
  681.             }
  682.             else if (aBeforePermanent && this.firstPermanentChild)
  683.             {
  684.                 // dump ("TOOLBAR: Insert before permanent, firstpermanent is : " + this.firstPermanentChild + "\n");
  685.                 this.insertBefore(insertItem, this.firstPermanentChild);
  686.             }
  687.             else {
  688.                 this.appendChild(insertItem);
  689.             }
  690.  
  691.             return newItem;
  692.           ]]>
  693.         </body>
  694.       </method>
  695.     </implementation>
  696.   </binding>
  697.  
  698.   <binding id="toolbar-overflow" extends="chrome://global/content/bindings/toolbar.xml#toolbar">
  699.     <implementation>
  700.       <property name="enableOverflowMenu"/>
  701.       <property name="allocating"/>
  702.       <property name="lastWidth"/>
  703.       <method name="allocateItems">
  704.         <parameter name="aForce"/>
  705.         <body>
  706.           <![CDATA[
  707.           // Only do the overflow menu allocation if specifically enabled
  708.           if (!this.enableOverflowMenu) return;
  709.  
  710.           // If the toolbar has not actually changed width, bail out
  711.           // (this helps avoid too-frequent calls)
  712.           if (!aForce && this.boxObject.width == this.lastWidth) return;
  713.           this.lastWidth = this.boxObject.width;
  714.  
  715.           // Function is not re-entrant
  716.           if (this.allocating) return;
  717.           this.allocating = true;
  718.  
  719.           // Clear out the overflow menu
  720.           var oMenu = document.getAnonymousElementByAttribute(this, 'anonid', 'overflow-menu');
  721.           while (oMenu.firstChild) {
  722.             oMenu.removeChild(oMenu.firstChild);
  723.           }
  724.  
  725.           // Iterate through the visible toolbar items
  726.           var node = this.firstChild;
  727.           // var tbRightExtent = this.boxObject.x + this.boxObject.width;
  728.           var tbRightExtent = this.boxObject.screenX + this.boxObject.width;
  729.           var oButton = document.getAnonymousElementByAttribute(this, 'anonid', 'overflow-button');
  730.           var oWidth=oButton.boxObject.width;
  731.           this.debug('  oWidth:'+oWidth+'\n');
  732.           this.debug('  x:'+this.boxObject.screenX+' w:'+this.boxObject.width+' r:'+tbRightExtent+'\n');
  733.           while (node) {
  734.           var nodeRightExtent = node.boxObject.screenX + node.boxObject.width;
  735.             this.debug('    node: #'+node.id+'#  right:'+nodeRightExtent+'\n');
  736.             if (!node.hasAttribute("disableoverflow") && nodeRightExtent > tbRightExtent - oWidth + 2) {
  737.               node.setAttribute('toolbaroverflow','true');
  738.               if (node.localName == 'toolbarbutton' || node.localName == 'toolbaritem') {
  739.                 var newMenuItem = document.createElement('menuitem');
  740.                 var menuLabel = '<no name>';
  741.                 if (node.hasAttribute('label')) {
  742.                   menuLabel = node.getAttribute('label');
  743.                 } else if (node.id) {
  744.                   menuLabel = node.id;
  745.                 }
  746.                 //this.debug('   overflow: '+menuLabel+'\n');
  747.                 newMenuItem.setAttribute('label', menuLabel);
  748.                 newMenuItem.setAttribute('buttonId', node.id);
  749.                 newMenuItem.setAttribute('oncommand', 'OverflowMenuCommand("'+node.id+'");');
  750.                 oMenu.appendChild(newMenuItem);
  751.               }
  752.             } else {
  753.               node.removeAttribute('toolbaroverflow');
  754.             }
  755.             node = node.nextSibling;
  756.           }
  757.  
  758.           // Show or hide overflow button
  759.           var oButton = document.getAnonymousElementByAttribute(this, 'anonid', 'overflow-button');
  760.           if (oMenu.childNodes.length > 0) {
  761.             oButton.hidden = false;
  762.           } else {
  763.             oButton.hidden = true;
  764.           }
  765.  
  766.           this.allocating = false;
  767.           ]]>
  768.         </body>
  769.       </method>
  770.     </implementation>
  771.     <content>
  772.       <xul:hbox flex="1">
  773.         <xul:hbox flex="1" align="center" class="toolbar-inner-container toolbar-left-margin">
  774.           <children/>
  775.         </xul:hbox>
  776.         <xul:toolbarbutton anonid="overflow-button" type="menu"
  777.                            class="toolbar-overflow-button" hidden="true">
  778.           <xul:menupopup anonid="overflow-menu" class="toolbar-overflow-menu"/>
  779.         </xul:toolbarbutton>
  780.       </xul:hbox>
  781.     </content>
  782.     <handlers>
  783.       <handler event="overflow">
  784.         <![CDATA[
  785.         //this.debug('toolbar.xml: toolbar *overflow* event for "'+this.toolbarName+'"\n');
  786.         this.allocateItems();
  787.         ]]>
  788.       </handler>
  789.       <handler event="underflow">
  790.         <![CDATA[
  791.         //this.debug('toolbar.xml: toolbar *underflow* event for "'+this.toolbarName+'"\n');
  792.         this.allocateItems();
  793.         ]]>
  794.       </handler>
  795.     </handlers>
  796.   </binding>
  797.  
  798.   // for now, empty binding to deal with -moz-binding rules from communicator.css
  799.   // (see bug 227993) we may need that binding one day to propagate
  800.   // the text/icons/both state to other windows. If we don't, this binding
  801.   // should be removed after we stop shipping the seamonkey communicator.css skin files.
  802.   <binding id="toolbar-primary" extends="chrome://global/content/bindings/toolbar.xml#toolbar"/>
  803.  
  804.   <binding id="menubar" extends="chrome://global/content/bindings/toolbar.xml#toolbar-base" display="xul:menubar">
  805.     <implementation implements="nsIAccessibleProvider">
  806.       <property name="accessible">
  807.         <getter>
  808.           <![CDATA[
  809.             var accService = Components.classes["@mozilla.org/accessibilityService;1"].getService(Components.interfaces.nsIAccessibilityService);
  810.             return accService.createXULMenubarAccessible(this);
  811.           ]]>
  812.         </getter>
  813.        </property>
  814.        <field name="_active">false</field>
  815.        <field name="_statusbar">null</field>
  816.        <field name="_originalStatusText">null</field>
  817.        <property name="statusbar" onget="return this.getAttribute('statusbar');"
  818.                                   onset="return this.setAttribute('statusbar', val)"/>
  819.        <method name="updateStatusText">
  820.           <parameter name="itemText"/>
  821.           <body>
  822.            <![CDATA[
  823.             if (!this._active)
  824.                 return;
  825.             var newText = itemText ? itemText : this._originalStatusText;
  826.             if (newText != this._statusbar.label)
  827.                 this._statusbar.label = newText;
  828.            ]]>
  829.           </body>
  830.         </method>
  831.     </implementation>
  832.     <handlers>
  833.         <handler event="DOMMenuBarActive">
  834.             if (!this.statusbar) return;
  835.             this._statusbar = document.getElementById(this.statusbar);
  836.             if (!this._statusbar)
  837.                 return;
  838.             this._active = true;
  839.             this._originalStatusText = this._statusbar.label;
  840.         </handler>
  841.         <handler event="DOMMenuBarInactive">
  842.           <![CDATA[
  843.             if (!this._active)
  844.                 return;
  845.             this._active = false;
  846.             this._statusbar.label = this._originalStatusText;
  847.           ]]>
  848.         </handler>
  849.         <handler event="DOMMenuItemActive">this.updateStatusText(event.target.statusText);</handler>
  850.         <handler event="DOMMenuItemInactive">this.updateStatusText("");</handler>
  851.     </handlers>
  852.   </binding>
  853.  
  854.   <binding id="toolbardecoration" extends="chrome://global/content/bindings/toolbar.xml#toolbar-base"/>
  855.  
  856.   <binding id="toolbarpaletteitem" extends="chrome://global/content/bindings/toolbar.xml#toolbar-base" display="xul:button">
  857.     <content>
  858.       <xul:hbox class="toolbarpaletteitem-box" flex="1" xbl:inherits="type,place">
  859.         <children/>
  860.       </xul:hbox>
  861.     </content>
  862.   </binding>
  863.  
  864.   <binding id="toolbarpaletteitem-palette" extends="chrome://global/content/bindings/toolbar.xml#toolbarpaletteitem">
  865.     <content>
  866.       <xul:hbox class="toolbarpaletteitem-box" xbl:inherits="type,place">
  867.         <children/>
  868.       </xul:hbox>
  869.       <xul:label xbl:inherits="value=title"/>
  870.     </content>
  871.   </binding>
  872.  
  873. </bindings>
  874.