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 / tabbrowser.xml < prev    next >
Extensible Markup Language  |  2005-07-29  |  126KB  |  3,244 lines

  1. <?xml version="1.0"?>
  2.  
  3. <!--
  4.    - The contents of this file are subject to the Mozilla Public
  5.    - License Version 1.1 (the "License"); you may not use this file
  6.    - except in compliance with the License. You may obtain a copy of
  7.    - the License at http://www.mozilla.org/MPL/
  8.    -
  9.    - Software distributed under the License is distributed on an "AS
  10.    - IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  11.    - implied. See the License for the specific language governing
  12.    - rights and limitations under the License.
  13.    -
  14.    - The Original Code is this file as it was released on
  15.    - March 28, 2001.
  16.    -
  17.    - The Initial Developer of the Original Code is David Hyatt
  18.    - Portions created by David Hyatt are Copyright (C) 2001
  19.    - David Hyatt.  All Rights Reserved.
  20.    -
  21.    - Contributor(s):
  22.    -   David Hyatt <hyatt@netscape.com> (Original Author of <tabbrowser>)
  23.    -
  24.    - Alternatively, the contents of this file may be used under the
  25.    - terms of the GNU General Public License Version 2 or later (the
  26.    - "GPL"), in which case the provisions of the GPL are applicable
  27.    - instead of those above.  If you wish to allow use of your
  28.    - version of this file only under the terms of the GPL and not to
  29.    - allow others to use your version of this file under the MPL,
  30.    - indicate your decision by deleting the provisions above and
  31.    - replace them with the notice and other provisions required by
  32.    - the GPL.  If you do not delete the provisions above, a recipient
  33.    - may use your version of this file under either the MPL or the
  34.    - GPL.
  35.   -->
  36.  
  37. <!DOCTYPE bindings [
  38. <!ENTITY % tabBrowserDTD SYSTEM "chrome://global/locale/tabbrowser.dtd" >
  39. %tabBrowserDTD;
  40. ]>
  41.  
  42. <bindings id="tabBrowserBindings"
  43.           xmlns="http://www.mozilla.org/xbl"
  44.           xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
  45.           xmlns:xbl="http://www.mozilla.org/xbl">
  46.  
  47.   <binding id="tabbrowser">
  48.     <resources>
  49.       <stylesheet src="chrome://global/skin/browser.css"/>
  50.     </resources>
  51.  
  52.     <content>
  53.       <xul:stringbundle src="chrome://global/locale/tabbrowser.properties"/>
  54.       <xul:tabbox flex="1" eventnode="document" xbl:inherits="handleCtrlPageUpDown"
  55.                   onselect="if (!('updateCurrentBrowser' in this.parentNode) || event.target.localName != 'tabpanels') return; this.parentNode.updateCurrentBrowser();">
  56.         <xul:hbox class="tabbrowser-strip chromeclass-toolbar" collapsed="true" tooltip="_child" context="_child">
  57.           <xul:tooltip onpopupshowing="event.preventBubble();"/>
  58.           <xul:menupopup anonid="tabContextMenu"
  59.                          onpopupshowing="var tabbrowser = this.parentNode.parentNode.parentNode;
  60.                                          tabbrowser.updateTabContextMenu();">
  61.             <xul:menuitem anonid="sitecontrolmenuContainer" label="Show Site Controls"
  62.                           oncommand="var x=this.parentNode.boxObject.screenX;var y=this.parentNode.boxObject.screenY;dump('x='+x+', y='+y+'\n');setTimeout('showSiteControlsPopup('+x+','+y+');',100);"/>
  63.             <xul:menuseparator anonid="activemenuSeparator"/>
  64.  
  65.             <xul:menuitem label="&closeTab.label;" accesskey="&closeTab.accesskey;"
  66.                           tbattr="tabbrowser-multiple"
  67.                           oncommand="var tabbrowser = this.parentNode.parentNode.parentNode.parentNode;
  68.                                      tabbrowser.removeTab(tabbrowser.mContextTab);"/>
  69.             <xul:menu anonid="activemenuContainer" label="&tab-closebutton.closeother.label;">
  70.               <xul:menupopup anonid="activemenu"
  71.                               onpopupshowing="tabbrowser = this.parentNode;
  72.                                      while (tabbrowser.localName != 'tabbrowser')
  73.                                         tabbrowser = tabbrowser.parentNode;
  74.                                      tabbrowser.updateTabPopupMenu(this, tabbrowser.mContextTab);">
  75.                 <xul:menuitem label="&tab-closebutton.closeallother.label;"
  76.                               oncommand="BrowserDelayRemoveAllTabsBut();"/>
  77.                 <xul:menuitem label="&tab-closebutton.closeallfromsite.label;"
  78.                               oncommand="DelayCloseAllTabsFromSameSite();"/>
  79.                 <xul:menuitem label="&tab-closebutton.closeallnotfromsite.label;"
  80.                               oncommand="DelayCloseAllTabsExceptFromSameSite();"/>
  81.               </xul:menupopup>
  82.             </xul:menu>
  83.             <xul:menuseparator/>
  84.             <xul:menuitem label="&newTab.label;" accesskey="&newTab.accesskey;"
  85.                           xbl:inherits="oncommand=onnewpreftab"/>
  86.             <xul:menuitem label="&bookmarkThisPage.label;" accesskey="&bookmarkThisPage.accesskey;"
  87.                           xbl:inherits="oncommand=onbookmarkpage"/>
  88.             <xul:menuitem label="&bookmarkThisGroupOfTabs.label;" accesskey="&bookmarkThisGroupOfTabs.accesskey;"
  89.                           anonid="bookmarkGroupMenuItem"
  90.                           tbattr="tabbrowser-multiple"
  91.                           xbl:inherits="oncommand=onbookmarktabs"/>
  92.             <xul:menuitem label="&appendTabToHomePage.label;" accesskey="&appendTabToHomePage.accesskey;"
  93.                           oncommand="var tabbrowser = this.parentNode.parentNode.parentNode.parentNode;
  94.                                      tabbrowser.appendTabToHomePage(tabbrowser.mContextTab);"/>
  95.             <xul:menuseparator/>
  96.             <xul:menuitem label="&aboutTabbedBrowsing.label;" accesskey="&aboutTabbedBrowsing.accesskey;"
  97.                           oncommand="AboutTabBrowsing();"/>
  98.             <!-- /MERC -->
  99.           </xul:menupopup>
  100.  
  101.           <xul:tabs id="browsertabs" class="tabbrowser-tabs" closebutton="true" flex="1"
  102.                     browsertabs="true"
  103.                     setfocus="false"
  104.                     onclick="this.parentNode.parentNode.parentNode.onTabClick(event);"
  105.                     onmousedown="this.parentNode.parentNode.parentNode.updateContextTab(event);"
  106.                     ondragover="nsDragAndDrop.dragOver(event, this.parentNode.parentNode.parentNode);
  107.                                 event.stopPropagation();"
  108.                     ondragdrop="nsDragAndDrop.drop(event, this.parentNode.parentNode.parentNode);
  109.                                 event.stopPropagation();"
  110.                     xbl:inherits="onnewtab,tabs-newdropdown,onhometab,onnewcurrenttab,onnetscapetab,onnewpreftab,onbookmarkpage,onbookmarktabs"
  111.                     ondblclick="if (event.originalTarget.localName != 'tab') {
  112.                                   if (event.button == 0) {
  113.                                     if (this.parentNode.parentNode.parentNode
  114.                                             .mPrefs.getBoolPref('browser.tabs.doubleClickTabBarToOpen'))
  115.                                     {
  116.                                       this.parentNode.parentNode.parentNode.selectedTab =
  117.                                         this.parentNode.parentNode.parentNode.addPrefTab();
  118.                                     }
  119.                                   }
  120.                                 }"
  121.                     onclosetab="var node = this.parentNode;
  122.                                 while (node.localName != 'tabbrowser')
  123.                                   node = node.parentNode;
  124.                                 node.removeCurrentTab();">
  125.             <xul:tab validate="never" 
  126.                      onerror="this.parentNode.parentNode.parentNode.parentNode.addToMissedIconCache(this.getAttribute('image'));
  127.                               this.removeAttribute('image');"
  128.                      maxwidth="250" width="0" minwidth="50" flex="100"
  129.                      xbl:inherits="onnewpreftab"
  130.                      class="tabbrowser-tab" label="&untitledTab;" crop="end"/>
  131.           </xul:tabs>
  132.         </xul:hbox>
  133.         <xul:tabpanels flex="1" class="plain">
  134.           <xul:vbox flex="1">
  135.             <xul:browsermessage hidden="true" type="top"/>
  136.             <xul:browser flex="1" type="content-primary" message="true" disablehistory="true" xbl:inherits="tooltip=contenttooltip,contextmenu=contentcontextmenu,autocompletepopup"/>
  137.             <xul:browsermessage hidden="true" type="bottom"/>
  138.           </xul:vbox>
  139.         </xul:tabpanels>
  140.       </xul:tabbox>
  141.       <children/>
  142.     </content>
  143.     <implementation>
  144.       <field name="mPrefs" readonly="true">
  145.         Components.classes['@mozilla.org/preferences-service;1']
  146.                   .getService(Components.interfaces.nsIPrefService)
  147.                   .getBranch(null);
  148.       </field>
  149.       <field name="mTabBox">
  150.         document.getAnonymousNodes(this)[1]
  151.       </field>
  152.       <field name="mStrip">
  153.         this.mTabBox.firstChild
  154.       </field>
  155.       <field name="mTabContainer">
  156.         this.mStrip.childNodes[2]
  157.       </field>
  158.       <field name="mPanelContainer">
  159.         this.mTabBox.childNodes[1]
  160.       </field>
  161.       <field name="mStringBundle">
  162.         document.getAnonymousNodes(this)[0]
  163.       </field>
  164.       <field name="mCurrentTab">
  165.         null
  166.       </field>
  167.       <field name="mCurrentBrowser">
  168.         null
  169.       </field>
  170.       <field name="mProgressListeners">
  171.         null
  172.       </field>
  173.       <field name="mTabListeners">
  174.         new Array()
  175.       </field>
  176.       <field name="mTabFilters">
  177.         new Array()
  178.       </field>
  179.       <field name="mTabbedMode">
  180.         false
  181.       </field>
  182.       <field name="mIsBusy">
  183.         false
  184.       </field>
  185.       <field name="mMissedIconCache">
  186.         null
  187.       </field>
  188.       <field name="mContextTab">
  189.         null
  190.       </field>
  191.       <field name="mModalDialogShowing">
  192.         false
  193.       </field>
  194.       
  195.       <method name="getBrowserAtIndex">
  196.         <parameter name="aIndex"/>
  197.         <body>
  198.           <![CDATA[
  199.             return this.mPanelContainer.childNodes[aIndex].firstChild.nextSibling;
  200.           ]]>
  201.         </body>
  202.       </method>
  203.  
  204.       <method name="getBrowserIndexForDocument">
  205.         <parameter name="aDocument"/>
  206.         <body>
  207.           <![CDATA[
  208.             for (var i = 0; i < this.mPanelContainer.childNodes.length; i++) {
  209.               if (this.getBrowserAtIndex(i).contentDocument == aDocument) {
  210.                 return i;
  211.               }
  212.             }
  213.             return -1;
  214.           ]]>
  215.         </body>
  216.       </method>
  217.         
  218.       <method name="getMessageForBrowser">
  219.         <parameter name="aBrowser"/>
  220.         <parameter name="aTopBottom"/>
  221.         <body>
  222.           <![CDATA[
  223.             return aBrowser[aTopBottom == "top" ? "previousSibling" : "nextSibling"];
  224.           ]]>
  225.         </body>
  226.       </method>
  227.       
  228.       <method name="showMessage">
  229.         <parameter name="aBrowser"/>
  230.         <parameter name="aIconURL"/>
  231.         <parameter name="aMessage"/>
  232.         <parameter name="aButtonLabel"/>
  233.         <parameter name="aDocShell"/>
  234.         <parameter name="aSource"/>
  235.         <parameter name="aPopup"/>
  236.         <parameter name="aTopBottom"/>
  237.         <parameter name="aShowCloseButton"/>
  238.         <parameter name="aDeckPick"/>
  239.         <body>
  240.           <![CDATA[
  241.             if (aDeckPick == null) aDeckPick = 0;
  242.  
  243.             var message = this.getMessageForBrowser(aBrowser, aTopBottom);
  244.  
  245.             if (aDeckPick > -1 && aDeckPick <= 6) {
  246.                 var theDeck = document.getAnonymousElementByAttribute(message, 'anonid', 'browsermessageDeck');
  247.                 theDeck.selectedIndex = aDeckPick;
  248.                 if (aDeckPick == 1) {
  249.                     var pcCheckbox = document.getAnonymousElementByAttribute(message, 'anonid', 'messagePasscardCheckBox');
  250.                     var menu = document.getAnonymousElementByAttribute(message, 'anonid', 'messagePasscardList');
  251.                     menu.removeAllItems();
  252.  
  253.                     // keep track of number of passcards found for the specific realm
  254.                     var passcardCount = 0;
  255.                     var passcardIndex = -1;
  256.  
  257.                     var foundSitePasscards = false;
  258.                     var addDefaultPasscard = false;
  259.                     var defaultName = "";
  260.                     var defaultUniqueID = -1;
  261.  
  262.                     // MERC - JCH: Make sure checkbox is set correctly.
  263.                     // msgBarVal = 0  show notification bar.
  264.                     // msgBarVal = 3  don't show notification bar.
  265.                     var msgBarVal = null; 
  266.  
  267.                     try {
  268.                         var passwordManager =
  269.                             Components.classes["@mozilla.org/passwordmanager;1"]
  270.                                       .getService(Components.interfaces.nsIPasswordManager);
  271.                         var enumerator = passwordManager.enumerator;
  272.                         while (enumerator.hasMoreElements()) {
  273.                             var nextPasscard = enumerator.getNext();
  274.                             nextPasscard = nextPasscard.QueryInterface(Components.interfaces.nsIPassword);
  275.  
  276.                             // get all info for the passcard
  277.                             if (this.currentURI.asciiHost.indexOf(nextPasscard.host) > -1) {
  278.                                 var uniqueID = nextPasscard.uniqueID;
  279.                                 var passcard = nextPasscard.passcard;
  280.                                 var lastUsed = nextPasscard.lastUsed;
  281.  
  282.                                 //dump("***Passcard -- passcard: " + passcard +
  283.                                   //     " uniqueID: " + uniqueID + " lastUsed: " + lastUsed + "\n");
  284.  
  285.                                 // find the default passcard for realm
  286.                                 if (eval(lastUsed)) {
  287.                                     passcardIndex = passcardCount;
  288.                                 }
  289.  
  290.                                 msgBarVal = nextPasscard.autologin; 
  291.  
  292.                                 menu.appendItem(passcard,uniqueID);
  293.                                 passcardCount++;
  294.                                 foundSitePasscards = true;
  295.  
  296.             
  297.                             }
  298.                             else if ("DefaultPasscard" == nextPasscard.host) {
  299.                                 //dump("***Passcard -- passcard: " + nextPasscard.host + "\n");
  300.                                 defaultName = nextPasscard.passcard;
  301.                                 defaultUniqueID = nextPasscard.uniqueID;
  302.  
  303.                                 // if it is protected, we will assume that the user has a valid Default Passcard
  304.                                 if (nextPasscard.protect == 0 &&
  305.                                     (nextPasscard.user.length < 1 || nextPasscard.password.length < 1))
  306.                                 {
  307.                                     addDefaultPasscard = false;
  308.                                 }
  309.                                 else {
  310.                                     addDefaultPasscard = true;
  311.                                 }
  312.                                 
  313.                                 msgBarVal = nextPasscard.autologin;
  314.                             }
  315.                         } // while
  316.                     } catch(e) {
  317.                         dump ("PASSCARD Notify exception : " + e + "\n");
  318.                     }
  319.  
  320.                     if (addDefaultPasscard && !foundSitePasscards &&
  321.                         defaultName.length > 0 && defaultUniqueID != -1)
  322.                     {
  323.                         //dump("***Default Passcard -- passcard: " + defaultName +
  324.                           //     " uniqueID: " + defaultUniqueID + "\n");
  325.                         menu.appendItem(defaultName, defaultUniqueID);
  326.                         passcardIndex = 0;
  327.                     }
  328.  
  329.                     menu.selectedIndex = passcardIndex;
  330.  
  331.                     // Set the "Don't Show Again" checkbox
  332.                     if (msgBarVal == 0) {
  333.                         pcCheckbox.checked = false;
  334.                     } else {
  335.                         pcCheckbox.checked = true;
  336.                     }
  337.  
  338.                     if (passcardCount < 1 && !addDefaultPasscard)
  339.                         return;
  340.  
  341.                 } else if (aDeckPick == 2) {
  342.                     // See if the datacard message bar should be suppressed
  343.                     if (gPrefService.getPrefType('datacard.messagebar.enable') &&
  344.                         !gPrefService.getBoolPref('datacard.messagebar.enable'))
  345.                     {
  346.                         return;
  347.                     }
  348.  
  349.                     document.getAnonymousElementByAttribute(message, 'anonid', 'datacardDoNotShow').checked = false;
  350.  
  351.                     // HACK: init the Datacard menulist
  352.                     var menulist = document.getAnonymousElementByAttribute(message, 'anonid', 'datacardList');
  353.                     menulist.removeAllItems();
  354.                     var datacards = datacardUtils.GetDatacardList();
  355.                     var defaultDatacard = datacardUtils.GetDefaultDatacard();
  356.  
  357.                     // Bail out if there are not datacards
  358.                     if (!datacards.length) return;
  359.  
  360.                     var cardForSite = datacardUtils.FindDatacardForURI(this.currentURI);
  361.                     for (var i = 0; i < datacards.length; i++) {
  362.                         var item = menulist.appendItem(datacards[i], datacards[i]);
  363.                         if (datacards[i] == defaultDatacard)
  364.                             item.setAttribute('defaultDatacard','true');
  365.                         if (datacards[i] == cardForSite)
  366.                             menulist.selectedIndex = i;
  367.                     }
  368.  
  369.                     // final sanity
  370.                     if (menulist.menupopup.childNodes.length < 1)
  371.                         return;
  372.  
  373.                 } else if (aDeckPick == 3) {
  374.                     message.phishText = aMessage;
  375.                     // Phishing site warning
  376.                     dump('>> Showing Phishing site warning messagebar.\n')
  377.                 } else if (aDeckPick == 4) {
  378.                     message.spywareText = aMessage;
  379.                     // Spyware site warning
  380.                     dump('>> Showing Spyware site warning messagebar.\n')
  381.                 } else if (aDeckPick == 5) {
  382.                     // Webmail message
  383.                     message.webmailImage = aIconURL;
  384.                     message.webmailText = aMessage;
  385.                 } else if (aDeckPick == 6) {
  386.                     // See if the popups message bar should be suppressed
  387.                     if (gPrefService.getPrefType('popups.messagebar.enable') &&
  388.                         !gPrefService.getBoolPref('popups.messagebar.enable'))
  389.                     {
  390.                         return;
  391.                     }
  392.                     // Popup blocker message
  393.                     message.popupblockerText = aMessage;
  394.                 }
  395.             }
  396.             // dump('tabbrowser.xml: ShowMessage, about to show message : ' + aMessage + '\n');
  397.  
  398.             message.image = aIconURL;
  399.             message.text = aMessage;
  400.             message.buttonText = aButtonLabel;
  401.             message.hidden = false;
  402.             if (aSource) {
  403.               message.source = aSource;
  404.               message.popup = null;
  405.             }
  406.             else if (aPopup) {
  407.               message.popup = aPopup;
  408.               message.source = null;
  409.             }
  410.             message.docShell = aDocShell;
  411.             message.closeButton = aShowCloseButton;
  412.             aBrowser.isShowingMessage = true;
  413.           ]]>
  414.         </body>
  415.       </method>
  416.             
  417.       <method name="hideMessage">
  418.         <parameter name="aBrowser"/>
  419.         <parameter name="aTopBottom"/>
  420.         <body>
  421.           <![CDATA[
  422.             if (aTopBottom != "both")
  423.               this.getMessageForBrowser(aBrowser, aTopBottom).hidden = true;
  424.             else {
  425.               this.getMessageForBrowser(aBrowser, "top").hidden = true;
  426.               this.getMessageForBrowser(aBrowser, "bottom").hidden = true;
  427.             }
  428.           ]]>
  429.         </body>
  430.       </method>
  431.  
  432.       <!-- A web progress listener object definition for a given tab. -->
  433.       <method name="mTabProgressListener">
  434.         <parameter name="aTab"/>
  435.         <parameter name="aBrowser"/>
  436.         <parameter name="aStartsBlank"/>
  437.         <body>
  438.         <![CDATA[
  439.           return ({
  440.             mTabBrowser: this,
  441.             mTab: aTab,
  442.             mBrowser: aBrowser,
  443.             mBlank: aStartsBlank,
  444.             mIcon: null,
  445.             mLastURI: null,
  446.  
  447.             onProgressChange : function (aWebProgress, aRequest,
  448.                                          aCurSelfProgress, aMaxSelfProgress,
  449.                                          aCurTotalProgress, aMaxTotalProgress)
  450.             {
  451.               if (!this.mBlank && this.mTabBrowser.mCurrentTab == this.mTab) {
  452.                 for (var i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
  453.                   var p = this.mTabBrowser.mProgressListeners[i];
  454.                   if (p)
  455.                     p.onProgressChange(aWebProgress, aRequest,
  456.                                        aCurSelfProgress, aMaxSelfProgress,
  457.                                        aCurTotalProgress, aMaxTotalProgress);
  458.                 }
  459.               }
  460.             },
  461.  
  462.             onStateChange : function(aWebProgress, aRequest, aStateFlags, aStatus)
  463.             {
  464.               if (!aRequest)
  465.                 return;
  466.  
  467.               var oldBlank = this.mBlank;
  468.  
  469.               const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
  470.               const nsIChannel = Components.interfaces.nsIChannel;
  471.  
  472.               if (aStateFlags & nsIWebProgressListener.STATE_START)
  473.                   this.mBrowser.mFavIconURL = null;
  474.  
  475.               if (aStateFlags & nsIWebProgressListener.STATE_START && 
  476.                   aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK) {
  477.                 // It's okay to clear what the user typed when we start
  478.                 // loading a document. If the user types, this flag gets
  479.                 // set to false, if the document load ends without an
  480.                 // onLocationChange, this flag also gets set to false
  481.                 // (so we keep it while switching tabs after failed load
  482.                 if (aWebProgress.DOMWindow == this.mBrowser.contentWindow)
  483.                   this.mBrowser.userTypedClear = true;
  484.  
  485.                 if (!this.mBlank) {
  486.                   this.mTab.setAttribute("busy", "true");
  487.                   this.mTab.label = this.mTabBrowser.mStringBundle.getString("tabs.loading");
  488.                   this.mTab.removeAttribute("image"); 
  489.                   this.mIcon = null;
  490.  
  491.                   if (this.mTabBrowser.mCurrentTab == this.mTab)
  492.                     this.mTabBrowser.mIsBusy = true;
  493.                 }
  494.               }
  495.               else if (aStateFlags & nsIWebProgressListener.STATE_STOP &&
  496.                        aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK) {
  497.                 // The document is done loading, it's okay to clear
  498.                 // the value again.
  499.                 if (aWebProgress.DOMWindow == this.mBrowser.contentWindow)
  500.                   this.mBrowser.userTypedClear = false;
  501.  
  502.                 if (this.mBlank)
  503.                   this.mBlank = false;
  504.  
  505.                 this.mTab.removeAttribute("busy");
  506.  
  507.                 var location = aRequest.QueryInterface(nsIChannel).URI;
  508.  
  509.                 // For keyword URIs clear the user typed value since they will be changed into real URIs
  510.                 if (location.scheme == "keyword")
  511.                   this.mBrowser.userTypedValue = null;
  512.  
  513.                 if (this.mTabBrowser.shouldLoadFavIcon(location)) {
  514.                     if (this.mIcon)
  515.                       this.mTab.setAttribute("image", this.mIcon);
  516.                     else
  517.                       this.mTabBrowser.loadFavIcon(location, "image", this.mTab);
  518.                     this.mBrowser.mFavIconURL = this.mTab.getAttribute("image");
  519.                     this.mIcon = this.mTab.getAttribute("image");
  520.                     SetPageProxyState( "valid", location );
  521.                 }
  522.  
  523.                 if (this.mTab.label == this.mTabBrowser.mStringBundle.getString("tabs.loading"))
  524.                   this.mTabBrowser.setTabTitle(this.mTab);
  525.  
  526.                 if (this.mTabBrowser.mCurrentTab == this.mTab)
  527.                   this.mTabBrowser.mIsBusy = false;
  528.               }
  529.  
  530.               if (!oldBlank && this.mTabBrowser.mCurrentTab == this.mTab) {
  531.                 for (var i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
  532.                   var p = this.mTabBrowser.mProgressListeners[i];
  533.                   if (p)
  534.                     p.onStateChange(aWebProgress, aRequest, aStateFlags, aStatus);
  535.                 }
  536.               }
  537.  
  538.               // MERC - JCH: Set the title and icon of the non-user-initiated tab
  539.               if (this.mTab.isNonUserInitPopupTab)
  540.               {
  541.                   this.mTab.label = "POP-UPS";
  542.                   this.mTab.setAttribute("image", "chrome://browser/skin/icons/popuponsm_n.png");
  543.               }
  544.  
  545.             },
  546.  
  547.             onLocationChange : function(aWebProgress, aRequest, aLocation) {
  548.               // The document loaded correctly, clear the value if we should
  549.               if (this.mBrowser.userTypedClear)
  550.                 this.mBrowser.userTypedValue = null;
  551.  
  552.               if (!this.mBlank && this.mTabBrowser.mCurrentTab == this.mTab) {
  553.                 for (var i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
  554.                   var p = this.mTabBrowser.mProgressListeners[i];
  555.                   if (p)
  556.                     p.onLocationChange(aWebProgress, aRequest, aLocation);
  557.                 }
  558.               }
  559.               // MERC (DP): update icon to match security level AND engine.
  560.               // function is defined in browser.js since we need to call it
  561.               // as well when the browser reloads on Trident side.
  562.               UpdateSiteControlIcon(this.mTab);
  563.             },
  564.  
  565.             onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage) {
  566.               if (this.mBlank)
  567.                 return;
  568.  
  569.               if (this.mTabBrowser.mCurrentTab == this.mTab) {
  570.                 for (var i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
  571.                   var p = this.mTabBrowser.mProgressListeners[i];
  572.                   if (p)
  573.                     p.onStatusChange(aWebProgress, aRequest, aStatus, aMessage);
  574.                 }
  575.               }
  576.             },
  577.  
  578.             onSecurityChange : function(aWebProgress, aRequest, aState)
  579.             {
  580.               if (this.mTabBrowser.mCurrentTab == this.mTab) {
  581.                 for (var i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
  582.                   var p = this.mTabBrowser.mProgressListeners[i];
  583.                   if (p)
  584.                     p.onSecurityChange(aWebProgress, aRequest, aState);
  585.                 }
  586.               }
  587.             },
  588.  
  589.             QueryInterface : function(aIID)
  590.             {
  591.               if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
  592.                   aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
  593.                   aIID.equals(Components.interfaces.nsISupports))
  594.                 return this;
  595.               throw Components.results.NS_NOINTERFACE;
  596.             }
  597.                   
  598.             });
  599.         ]]>
  600.         </body>
  601.       </method>
  602.       
  603.       <method name="buildFavIconString">
  604.         <parameter name="aURI"/>
  605.         <body>
  606.           <![CDATA[
  607.             var end = (aURI.port == -1) ? "/favicon.ico" : (":" + aURI.port + "/favicon.ico");
  608.             return aURI.scheme + "://" + aURI.host + end;
  609.           ]]>
  610.         </body>
  611.       </method>
  612.  
  613.       <method name="shouldLoadFavIcon">
  614.         <parameter name="aURI"/>
  615.         <body>
  616.           <![CDATA[
  617.             return (aURI && this.mPrefs.getBoolPref("browser.chrome.site_icons") &&
  618.                     this.mPrefs.getBoolPref("browser.chrome.favicons") &&
  619.                     ("schemeIs" in aURI) && (aURI.schemeIs("http") || aURI.schemeIs("https")));
  620.           ]]>
  621.         </body>
  622.       </method>
  623.  
  624.       <method name="loadFavIcon">
  625.         <parameter name="aURI"/>
  626.         <parameter name="aAttr"/>
  627.         <parameter name="aElt"/>
  628.         <body>
  629.           <![CDATA[
  630.             var iconURL = this.buildFavIconString(aURI);
  631.             if (!this.isFavIconKnownMissing(iconURL)) {
  632.               aElt.setAttribute(aAttr, iconURL);
  633.             }
  634.  
  635.             // MERC - JCH: Set icon of the non-user-initiated popup tab
  636.             if (aElt.isNonUserInitPopupTab)    {
  637.                 aElt.setAttribute("image", "chrome://browser/skin/icons/popuponsm_n.png");
  638.             }
  639.  
  640.           ]]>
  641.         </body>
  642.       </method>
  643.  
  644.       <method name="addToMissedIconCache">
  645.         <parameter name="aURI"/>
  646.         <body>
  647.           <![CDATA[
  648.             var entry = this.openCacheEntry(aURI, Components.interfaces.nsICache.ACCESS_READ_WRITE);
  649.             if (!entry)
  650.               return;
  651.  
  652.             if (entry.accessGranted == Components.interfaces.nsICache.ACCESS_WRITE)
  653.               // It's a new entry.  Just write a bit of metadata in to the entry.
  654.               entry.setMetaDataElement("Icon", "Missed");
  655.             entry.markValid();
  656.             entry.close();
  657.           ]]>
  658.         </body>
  659.       </method>
  660.  
  661.       <method name="openCacheEntry">
  662.         <parameter name="key"/>
  663.         <parameter name="access"/>
  664.         <body>
  665.           <![CDATA[
  666.             try {
  667.               if (!this.mMissedIconCache) {
  668.                 var cacheService = Components.classes['@mozilla.org/network/cache-service;1'].getService(Components.interfaces.nsICacheService);
  669.                 this.mMissedIconCache = cacheService.createSession("MissedIconCache", Components.interfaces.nsICache.STORE_ANYWHERE, true);
  670.                 if (!this.mMissedIconCache)
  671.                   return null;
  672.               }
  673.               return this.mMissedIconCache.openCacheEntry(key, access, true);
  674.             }
  675.             catch (e) {
  676.               return null;
  677.             }
  678.           ]]>
  679.         </body>
  680.       </method>
  681.  
  682.       <method name="isFavIconKnownMissing">
  683.         <parameter name="key"/>
  684.         <body>
  685.           <![CDATA[
  686.             var e = this.openCacheEntry(key, Components.interfaces.nsICache.ACCESS_READ);
  687.             if (e) {
  688.                 e.close();
  689.                 return true;
  690.             }
  691.             return false;
  692.           ]]>
  693.         </body>
  694.       </method>
  695.  
  696.       <method name="updateTitlebar">
  697.         <body>
  698.           <![CDATA[
  699.             var newTitle = "";
  700.             var docTitle;
  701.             var docElement = this.ownerDocument.documentElement;
  702.             if (this.docShell.contentViewer)
  703.               docTitle = this.contentTitle;
  704.  
  705.             if (!docTitle)
  706.               docTitle = docElement.getAttribute("titledefault");
  707.  
  708.             var modifier = docElement.getAttribute("titlemodifier");
  709.             var sep = docElement.getAttribute("titlemenuseparator");
  710.             if (docTitle) {
  711.               newTitle += docElement.getAttribute("titlepreface");
  712.               newTitle += docTitle;
  713.               if (modifier)
  714.                 newTitle += sep;
  715.             }
  716.             newTitle += modifier;
  717.  
  718.             // if location bar is hidden and the URL type supports a host
  719.             // then add the scheme and host to the title to prevent spoofing
  720.             try {
  721.               if (docElement.getAttribute("chromehidden").indexOf("location") != -1) {
  722.                 var host = this.mURIFixup.createExposableURI(
  723.                              this.mCurrentBrowser.currentURI).prePath;
  724.                 if (host)
  725.                   newTitle = host + sep + newTitle;
  726.               }
  727.             } catch (e) {}
  728.  
  729.             window.title = newTitle;
  730.           ]]>
  731.         </body>
  732.       </method>
  733.  
  734.       <method name="updateContextTab">
  735.         <parameter name="aEvent"/>
  736.         <body>
  737.           <![CDATA[
  738.             if (aEvent.originalTarget.localName == "tab")
  739.               this.mContextTab = aEvent.originalTarget;
  740.             else
  741.               this.mContextTab = this.mCurrentTab;
  742.               //this.mContextTab = document.popupNode;
  743.           ]]>
  744.         </body>
  745.       </method>
  746.  
  747.       <!-- MERC (DP): update the site controls tab menu when the icon is visible -->
  748.       <method name="updateSiteControlsSubmenu">
  749.         <body>
  750.           <![CDATA[
  751.             //dump('tabbrowser.xml: updateSiteControlsSubmenu()\n');
  752.  
  753.             var currentEngine = this.mCurrentBrowser.webNavigation.browserEngine;
  754.             var url = this.getBrowserForTab(this.mCurrentTab).currentURI.spec;
  755.             var scMenu = document.getAnonymousElementByAttribute(this.mCurrentTab, 'anonid', 'menu');
  756.             var sc = sitecontrols.SCSVC;
  757.  
  758.             if (!sc.isControllableURI(url)) {
  759.  
  760.               // This is not a controllable URI, so we will disable most menu items
  761.               var menuitem;
  762.               for (var j = 0; j < scMenu.childNodes.length; j++) {
  763.                 menuitem = scMenu.childNodes[j];
  764.                 // disable all menu items
  765.                 if (menuitem.localName == 'menuitem' || menuitem.localName == 'menu') {
  766.                   menuitem.setAttribute('disabled', 'true');
  767.                 }
  768.               }
  769.  
  770.               // make sure 'openSiteControls' menu item is enabled
  771.               var openSiteControls =
  772.                 document.getAnonymousElementByAttribute(this.mCurrentTab, 'anonid', 'openSiteControls');
  773.               openSiteControls.removeAttribute('disabled');
  774.  
  775.               // Update 'displayEngine' menu item label
  776.               var displayEngineItem =
  777.                 document.getAnonymousElementByAttribute(this.mCurrentTab, 'anonid', 'displayEngine');
  778.               // if about:blank page, let user toggle engine
  779.               if (url == 'about:blank') {
  780.                 displayEngineItem.removeAttribute('disabled');
  781.               }
  782.  
  783.               if (currentEngine == 'Trident') {
  784.                 displayEngineItem.setAttribute('label', 'Display like Netscape');
  785.               } else {
  786.                 displayEngineItem.setAttribute('label', 'Display like Internet Explorer');
  787.               }
  788.  
  789.             } else {
  790.  
  791.               // This *is* a controllable URI, so we enable most menu items
  792.               var menuitem;
  793.               for (var j = 0; j < scMenu.childNodes.length; j++) {
  794.                 menuitem = scMenu.childNodes[j];
  795.                 // enable all menu items
  796.                 if (menuitem.localName == 'menuitem' || menuitem.localName == 'menu') {
  797.                   menuitem.removeAttribute('disabled');
  798.                 }
  799.               }
  800.  
  801.               var site = sc.getResourceForURI(url);
  802.               var displayEngine = sc.readSiteControlResource(site, 'displayEngine');
  803.               var allowPopups = sc.readSiteControlResource(site, 'allowPopups');
  804.               var requestedPopupsInTab = sc.readSiteControlResource(site, 'requestedPopupsInTab');
  805.               var enableActiveX = sc.readSiteControlResource(site, 'enableActiveX');
  806.               var enableJava = sc.readSiteControlResource(site, 'enableJava');
  807.               var enableJavaScript = sc.readSiteControlResource(site, 'enableJavaScript');
  808.               var allowCookies = sc.readSiteControlResource(site, 'allowCookies');
  809.               var securityLevel = sc.readSiteControlResource(site, 'securityLevel');
  810.  
  811.               // Update 'allowPopups' menu item
  812.               var allowPopupsItem =
  813.                 document.getAnonymousElementByAttribute(this.mCurrentTab, 'anonid', 'allowPopups');
  814.               allowPopupsItem.setAttribute('checked',allowPopups);
  815.  
  816.               // Update 'requestedPopupsInTab' menu item
  817.               var requestedPopupsInTabItem =
  818.                 document.getAnonymousElementByAttribute(this.mCurrentTab, 'anonid', 'requestedPopupsInTab');
  819.               if(allowPopups == 'true') {
  820.                 requestedPopupsInTabItem.setAttribute('checked',requestedPopupsInTab);
  821.                 requestedPopupsInTabItem.removeAttribute('disabled');
  822.               } else {
  823.                 requestedPopupsInTabItem.setAttribute('checked', 'false');
  824.                 requestedPopupsInTabItem.setAttribute('disabled', 'true');
  825.               }
  826.  
  827.               // Update 'allowCookies' menu item
  828.               var allowCookiesItem =
  829.                 document.getAnonymousElementByAttribute(this.mCurrentTab, 'anonid', 'allowCookies');
  830.               allowCookiesItem.setAttribute('checked',allowCookies);
  831.  
  832.               // Update 'allowJavascript' menu item
  833.               var enableJavaScriptItem =
  834.                 document.getAnonymousElementByAttribute(this.mCurrentTab, 'anonid', 'enableJavaScript');
  835.               enableJavaScriptItem.setAttribute('checked', enableJavaScript);
  836.  
  837.               // Update 'allowJava' menu item
  838.               var enableJavaItem =
  839.                 document.getAnonymousElementByAttribute(this.mCurrentTab, 'anonid', 'enableJava');
  840.               enableJavaItem.setAttribute('checked', enableJava);
  841.  
  842.               var enableActiveXItem =
  843.                 document.getAnonymousElementByAttribute(this.mCurrentTab, 'anonid', 'enableActiveX');
  844.               var displayEngineItem =
  845.                 document.getAnonymousElementByAttribute(this.mCurrentTab, 'anonid', 'displayEngine');
  846.               if (currentEngine == 'Trident') {
  847.                 // Update 'allowActiveX' menu item
  848.                 enableActiveXItem.removeAttribute('disabled');
  849.                 enableActiveXItem.setAttribute('checked', enableActiveX);
  850.  
  851.                 // Update 'displayEngine' menu item label
  852.                 displayEngineItem.setAttribute('label', 'Display like Netscape');
  853.               } else {
  854.                 // Update 'allowActiveX' menu item
  855.                 enableActiveXItem.setAttribute('checked', 'false');
  856.                 enableActiveXItem.setAttribute('disabled', 'true');
  857.  
  858.                 // Update 'displayEngine' menu item label
  859.                 displayEngineItem.setAttribute('label', 'Display like Internet Explorer');
  860.               }
  861.  
  862.               // check mark the appropriate security level menu item
  863.               var lowSecurityMenuItem =
  864.                 document.getAnonymousElementByAttribute(this.mCurrentTab, 'anonid', 'displaySecurityLow');
  865.               var mediumSecurityMenuItem =
  866.                 document.getAnonymousElementByAttribute(this.mCurrentTab, 'anonid', 'displaySecurityMedium');
  867.               var highSecurityMenuItem =
  868.                 document.getAnonymousElementByAttribute(this.mCurrentTab, 'anonid', 'displaySecurityHigh');
  869.               lowSecurityMenuItem.setAttribute('checked', 'false');
  870.               mediumSecurityMenuItem.setAttribute('checked', 'false');
  871.               highSecurityMenuItem.setAttribute('checked', 'false');
  872.  
  873.               switch(securityLevel) {
  874.                 case 'Low':
  875.                   lowSecurityMenuItem.setAttribute('checked', 'true');
  876.                   break;
  877.                 case 'Medium':
  878.                   mediumSecurityMenuItem.setAttribute('checked', 'true');
  879.                   break;
  880.                 case 'High':
  881.                   highSecurityMenuItem.setAttribute('checked', 'true');
  882.                   break;
  883.                 default:
  884.                   break;
  885.               }
  886.             }
  887.           ]]>
  888.         </body>
  889.       </method>
  890.  
  891.       <!-- MERC (DP): called to update site control menu when SC icon is hidden and the SC menu
  892.            is displayed in the tab context menu
  893.       -->
  894.       <method name="updateSiteControlsSubmenu2">
  895.         <parameter name="aPopupMenu"/>
  896.         <body>
  897.           <![CDATA[
  898.             //dump('tabbrowser.xml: updateSiteControlsSubmenu2()\n');
  899.  
  900.             var contextBrowser = this.getBrowserForTab(this.mContextTab);
  901.             var currentEngine = contextBrowser.webNavigation.browserEngine;
  902.             var url = this.getBrowserForTab(this.mContextTab).currentURI.spec;
  903.             //var scMenu = document.getAnonymousElementByAttribute(this.mContextTab, 'anonid', 'sitecontrolTabMenu');
  904.             var scMenu = aPopupMenu;
  905.             var sc = sitecontrols.SCSVC;
  906.  
  907.             if (!sc.isControllableURI(url)) {
  908.  
  909.               // This is not a controllable URI, so we will disable most menu items
  910.               var menuitem;
  911.               for (var j = 0; j < scMenu.childNodes.length; j++) {
  912.                 menuitem = scMenu.childNodes[j];
  913.                 // disable all menu items
  914.                 if (menuitem.localName == 'menuitem' || menuitem.localName == 'menu') {
  915.                   menuitem.setAttribute('disabled', 'true');
  916.                 }
  917.               }
  918.  
  919.               // make sure 'openSiteControls' menu item is enabled
  920.               var openSiteControls = scMenu.getElementsByAttribute("anonid", "openSiteControls");
  921.               openSiteControls = openSiteControls[0];
  922.               openSiteControls.removeAttribute('disabled');
  923.  
  924.               // Update 'displayEngine' menu item label
  925.               var displayEngineItem = scMenu.getElementsByAttribute("anonid", "displayEngine");
  926.               displayEngineItem = displayEngineItem[0];
  927.  
  928.               // if about:blank page, let user toggle engine
  929.               if (url == 'about:blank') {
  930.                 displayEngineItem.removeAttribute('disabled');
  931.               }
  932.  
  933.               if (currentEngine == 'Trident') {
  934.                 displayEngineItem.setAttribute('label', 'Display like Netscape');
  935.               } else {
  936.                 displayEngineItem.setAttribute('label', 'Display like Internet Explorer');
  937.               }
  938.  
  939.             } else {
  940.  
  941.               // This *is* a controllable URI, so we enable most menu items
  942.               var menuitem;
  943.               for (var j = 0; j < scMenu.childNodes.length; j++) {
  944.                 menuitem = scMenu.childNodes[j];
  945.                 // enable all menu items
  946.                 if (menuitem.localName == 'menuitem' || menuitem.localName == 'menu') {
  947.                   menuitem.removeAttribute('disabled');
  948.                 }
  949.               }
  950.  
  951.               var site = sc.getResourceForURI(url);
  952.               var displayEngine = sc.readSiteControlResource(site, 'displayEngine');
  953.               var allowPopups = sc.readSiteControlResource(site, 'allowPopups');
  954.               var requestedPopupsInTab = sc.readSiteControlResource(site, 'requestedPopupsInTab');
  955.               var enableActiveX = sc.readSiteControlResource(site, 'enableActiveX');
  956.               var enableJava = sc.readSiteControlResource(site, 'enableJava');
  957.               var enableJavaScript = sc.readSiteControlResource(site, 'enableJavaScript');
  958.               var allowCookies = sc.readSiteControlResource(site, 'allowCookies');
  959.               var securityLevel = sc.readSiteControlResource(site, 'securityLevel');
  960.  
  961.               // Update 'allowPopups' menu item
  962.               //var allowPopupsItem =
  963.               //  document.getAnonymousElementByAttribute(this.mContextTab, 'anonid', 'allowPopups');
  964.               //allowPopupsItem.setAttribute('checked',allowPopups);
  965.               var allowPopupsItem = scMenu.getElementsByAttribute("anonid", "allowPopups");
  966.               allowPopupsItem = allowPopupsItem[0];
  967.               allowPopupsItem.setAttribute('checked',allowPopups);
  968.  
  969.               // Update 'requestedPopupsInTab' menu item
  970.               //var requestedPopupsInTabItem =
  971.               //  document.getAnonymousElementByAttribute(this.mContextTab, 'anonid', 'requestedPopupsInTab');
  972.               //requestedPopupsInTabItem.setAttribute('checked',requestedPopupsInTab);
  973.               var requestedPopupsInTabItem = scMenu.getElementsByAttribute("anonid", "requestedPopupsInTab");
  974.               requestedPopupsInTabItem = requestedPopupsInTabItem[0];
  975.               if(allowPopups == 'true') {
  976.                 requestedPopupsInTabItem.setAttribute('checked',requestedPopupsInTab);
  977.                 requestedPopupsInTabItem.removeAttribute('disabled');
  978.               } else {
  979.                 requestedPopupsInTabItem.setAttribute('checked', 'false');
  980.                 requestedPopupsInTabItem.setAttribute('disabled', 'true');
  981.               }
  982.  
  983.               // Update 'allowCookies' menu item
  984.               var allowCookiesItem = scMenu.getElementsByAttribute("anonid", "allowCookies");
  985.               allowCookiesItem = allowCookiesItem[0];
  986.               allowCookiesItem.setAttribute('checked',allowCookies);
  987.  
  988.               // Update 'allowJavascript' menu item
  989.               var enableJavaScriptItem = scMenu.getElementsByAttribute("anonid", "enableJavaScript");
  990.               enableJavaScriptItem = enableJavaScriptItem[0];
  991.               enableJavaScriptItem.setAttribute('checked', enableJavaScript);
  992.  
  993.               // Update 'allowJava' menu item
  994.               var enableJavaItem = scMenu.getElementsByAttribute("anonid", "enableJava");
  995.               enableJavaItem = enableJavaItem[0];
  996.               enableJavaItem.setAttribute('checked', enableJava);
  997.  
  998.               var enableActiveXItem = scMenu.getElementsByAttribute("anonid", "enableActiveX");
  999.               enableActiveXItem = enableActiveXItem[0];
  1000.  
  1001.               var displayEngineItem =
  1002.                 scMenu.getElementsByAttribute("anonid", "displayEngine");
  1003.               displayEngineItem = displayEngineItem[0];
  1004.  
  1005.               if (currentEngine == 'Trident') {
  1006.                 // Update 'allowActiveX' menu item
  1007.                 enableActiveXItem.removeAttribute('disabled');
  1008.                 enableActiveXItem.setAttribute('checked', enableActiveX);
  1009.  
  1010.                 // Update 'displayEngine' menu item label
  1011.                 displayEngineItem.setAttribute('label', 'Display like Netscape');
  1012.               } else {
  1013.                 // Update 'allowActiveX' menu item
  1014.                 enableActiveXItem.setAttribute('checked', 'false');
  1015.                 enableActiveXItem.setAttribute('disabled', 'true');
  1016.  
  1017.                 // Update 'displayEngine' menu item label
  1018.                 displayEngineItem.setAttribute('label', 'Display like Internet Explorer');
  1019.               }
  1020.  
  1021.               // check mark the appropriate security level menu item
  1022.               var lowSecurityMenuItem = scMenu.getElementsByAttribute("anonid", "displaySecurityLow");
  1023.               lowSecurityMenuItem = lowSecurityMenuItem[0];
  1024.  
  1025.               var mediumSecurityMenuItem = scMenu.getElementsByAttribute("anonid", "displaySecurityMedium");
  1026.               mediumSecurityMenuItem = mediumSecurityMenuItem[0];
  1027.  
  1028.               var highSecurityMenuItem = scMenu.getElementsByAttribute("anonid", "displaySecurityHigh");
  1029.               highSecurityMenuItem = highSecurityMenuItem[0];
  1030.  
  1031.               lowSecurityMenuItem.setAttribute('checked', 'false');
  1032.               mediumSecurityMenuItem.setAttribute('checked', 'false');
  1033.               highSecurityMenuItem.setAttribute('checked', 'false');
  1034.  
  1035.               switch(securityLevel) {
  1036.                 case 'Low':
  1037.                   lowSecurityMenuItem.setAttribute('checked', 'true');
  1038.                   break;
  1039.                 case 'Medium':
  1040.                   mediumSecurityMenuItem.setAttribute('checked', 'true');
  1041.                   break;
  1042.                 case 'High':
  1043.                   highSecurityMenuItem.setAttribute('checked', 'true');
  1044.                   break;
  1045.                 default:
  1046.                   break;
  1047.               }
  1048.             }
  1049.           ]]>
  1050.         </body>
  1051.       </method>
  1052.  
  1053.       <!-- MERC (DP): update the context tab menu -->
  1054.       <method name="updatePopupMenu">
  1055.         <parameter name="aPopupMenu"/>
  1056.         <parameter name="aTab"/>
  1057.         <body>
  1058.           <![CDATA[
  1059.             if (aTab.localName != "tab") {
  1060.               aTab = this.mCurrentTab;
  1061.             }
  1062.             var disabled = this.mPanelContainer.childNodes.length == 1;
  1063.             var menuItems = aPopupMenu.getElementsByAttribute("tbattr", "tabbrowser-multiple");
  1064.             for (var i = 0; i < menuItems.length; i++)
  1065.               menuItems[i].setAttribute("disabled", disabled);
  1066.  
  1067.             // if there is only 1 tab, disable activemenu in the context menu
  1068.             var menuContainer = aPopupMenu.getElementsByAttribute("anonid", "activemenuContainer");
  1069.             if(disabled)
  1070.               menuContainer[0].setAttribute("disabled", "true");
  1071.             else
  1072.               menuContainer[0].removeAttribute("disabled");
  1073.  
  1074.             // if we are hiding the site control button, show the site control menu as part of the tab context menu
  1075.             // on the active tab only
  1076.             menuContainer = aPopupMenu.getElementsByAttribute("anonid", "sitecontrolmenuContainer");
  1077.             var menuSeparator = aPopupMenu.getElementsByAttribute("anonid", "activemenuSeparator");
  1078.             if(this.mPrefs.getBoolPref("browser.tabs.showSiteControlButtonOnTab")) {
  1079.               menuContainer[0].setAttribute("hidden", "true");
  1080.               menuSeparator[0].setAttribute("hidden", "true");
  1081.             } else {
  1082.               if(this.mContextTab == this.mCurrentTab) {
  1083.                 menuContainer[0].removeAttribute("hidden");
  1084.                 menuSeparator[0].removeAttribute("hidden");
  1085.               } else {
  1086.                 menuContainer[0].setAttribute("hidden", "true");
  1087.                 menuSeparator[0].setAttribute("hidden", "true");
  1088.               }
  1089.             }
  1090.           ]]>
  1091.         </body>
  1092.       </method>
  1093.  
  1094.       <!-- MERC (DP): update the tab context menu -->
  1095.       <method name="updateTabContextMenu">
  1096.         <body>
  1097.           <![CDATA[
  1098.               var closeOtherMenuItem = document.getAnonymousElementByAttribute(this, 'anonid', 'activemenuContainer');
  1099.               var bookmarkGroupMenuItem = document.getAnonymousElementByAttribute(this, 'anonid', 'bookmarkGroupMenuItem');
  1100.             var numTabs = this.mTabContainer.childNodes.length;
  1101.             if(numTabs < 2) {
  1102.                 closeOtherMenuItem.setAttribute('disabled', 'true');
  1103.                 bookmarkGroupMenuItem.setAttribute('disabled', 'true');
  1104.             } else {
  1105.                 closeOtherMenuItem.removeAttribute('disabled');
  1106.                 bookmarkGroupMenuItem.removeAttribute('disabled');
  1107.             }
  1108.  
  1109.             // MERC - JCH: Addresses BLT# 156478. Make sure that the site controls dialog option is
  1110.             // disabled in the right-click context menu when the tab is a blank tab.
  1111.             var scDialogMenuItem = document.getAnonymousElementByAttribute(this, 'anonid', 'sitecontrolmenuContainer');
  1112.             if (this.mCurrentTab.label == "(Untitled)") {
  1113.                 scDialogMenuItem.setAttribute('disabled', 'true');
  1114.             } else {
  1115.                 scDialogMenuItem.setAttribute('disabled', 'false');
  1116.             }
  1117.  
  1118.           ]]>
  1119.         </body>
  1120.       </method>
  1121.  
  1122.       <!-- MERC (DP): update the right tab menu -->
  1123.       <method name="updateTabPopupMenu">
  1124.         <parameter name="aPopupMenu"/>
  1125.         <parameter name="aTab"/>
  1126.         <body>
  1127.           <![CDATA[
  1128.             if (aTab.localName != "tab") {
  1129.               aTab = this.mCurrentTab;
  1130.             }
  1131.  
  1132.             /*
  1133.             var disabled = this.mPanelContainer.childNodes.length == 1;
  1134.  
  1135.             // get the elements to disable
  1136.             // *** we have to pass in the parent of the menu popup object (toolbarbutton) - not sure why?!
  1137.             leftItem = document.getAnonymousElementByAttribute(aPopupMenu.parentNode, "anonid", "closeAllTabsToLeftMenuItem");
  1138.             rightItem = document.getAnonymousElementByAttribute(aPopupMenu.parentNode, "anonid", "closeAllTabsToRightMenuItem");
  1139.             clearBlankItem = document.getAnonymousElementByAttribute(aPopupMenu.parentNode, "anonid", "closeAllBlankTabsMenuItem");
  1140.  
  1141.             // disable menu items if clicked on first or last tab
  1142.             if(disabled) {
  1143.               leftItem.setAttribute("disabled", true);
  1144.               rightItem.setAttribute("disabled", true);
  1145.             } else {
  1146.               if(this.mTabContainer.childNodes[0] == aTab) {
  1147.                 leftItem.setAttribute("disabled", true);
  1148.               } else {
  1149.                 leftItem.removeAttribute("disabled");
  1150.               }
  1151.  
  1152.               if(this.mTabContainer.childNodes[this.mPanelContainer.childNodes.length - 1] == aTab) {
  1153.                 rightItem.setAttribute("disabled", true);
  1154.               } else {
  1155.                 rightItem.removeAttribute("disabled");
  1156.               }
  1157.             }
  1158.  
  1159.             // ***
  1160.             // disable clear all blank tabs menu item if there are no blanks tabs
  1161.             // ***
  1162.             var browsers = this.mPanelContainer.childNodes
  1163.             var found = 0;
  1164.             for(var j = 0; j < browsers.length; j++) {
  1165.               if(this.getBrowserAtIndex(j).currentURI.spec == "about:blank") {
  1166.                 found = 1;
  1167.                 break;
  1168.               }
  1169.             }
  1170.  
  1171.             if(found) {
  1172.               clearBlankItem.removeAttribute("disabled");
  1173.             } else {
  1174.               clearBlankItem.setAttribute("disabled", true);
  1175.             }
  1176.             */
  1177.           ]]>
  1178.         </body>
  1179.       </method>
  1180.  
  1181.       <!-- MERC (DP): update the right tab list menu -->
  1182.       <method name="updateTabListMenu">
  1183.         <parameter name="aPopupMenu"/>
  1184.         <body>
  1185.           <![CDATA[
  1186.             // clear old menuitems
  1187.             var children = aPopupMenu.childNodes;
  1188.             while(children.length) {
  1189.               aPopupMenu.removeChild(children[0]);
  1190.               children = aPopupMenu.childNodes;
  1191.             }
  1192.  
  1193.             // go thru list of tabs and add a menu item for each one
  1194.             var menuitem;
  1195.             var string;
  1196.             var tab;
  1197.             var favicon;
  1198.             for(var j = 0; j < this.mTabContainer.childNodes.length; j++) {
  1199.               tab = this.mTabContainer.childNodes[j];
  1200.               if(this.mTabListeners[j].mIcon) {
  1201.                   favicon = this.mTabListeners[j].mIcon;
  1202.               } else {
  1203.                   favicon = "chrome://global/skin/icons/default-favicon.png";
  1204.               }
  1205.               menuitem = document.createElement("menuitem");
  1206.               menuitem.setAttribute('label', tab.label);
  1207.               menuitem.setAttribute('type', 'checkbox');
  1208.               menuitem.setAttribute('favsrc', favicon);
  1209.               string = "var tabs = this; while(tabs.localName != 'tabs') tabs = tabs.parentNode; tabs.selectTabByIndex(" + j + ");"
  1210.               menuitem.setAttribute('oncommand', string);
  1211.               if(tab == this.mCurrentTab)
  1212.                 menuitem.setAttribute('checked', 'true');
  1213.               aPopupMenu.appendChild(menuitem);
  1214.             }
  1215.           ]]>
  1216.         </body>
  1217.       </method>
  1218.  
  1219.       <method name="updateCurrentBrowser">
  1220.       <parameter name="forceUpdate"/>
  1221.         <body>
  1222.           <![CDATA[
  1223.             var newBrowser = this.getBrowserAtIndex(this.mPanelContainer.selectedIndex);
  1224.               dump ("UpdateCurrentBrowser to index " + this.mPanelContainer.selectedIndex + "\n");
  1225.             if (this.mCurrentBrowser == newBrowser && !forceUpdate) {
  1226.               // MERC (DP): update tab chrome
  1227.               this.updateChromeWhenLastTab();
  1228.               // MERC
  1229.               UpdateStatusbarPartnerIcons();
  1230.               return;
  1231.             }
  1232.  
  1233.             if (this.mCurrentBrowser) {
  1234.               this.mCurrentBrowser.focusedWindow = document.commandDispatcher.focusedWindow;
  1235.               this.mCurrentBrowser.focusedElement = document.commandDispatcher.focusedElement;
  1236.                this.mCurrentBrowser.setAttribute("type", "content");
  1237.             }
  1238.  
  1239.             newBrowser.setAttribute("type", "content-primary");
  1240.             this.mCurrentBrowser = newBrowser;
  1241.             this.mCurrentTab = this.selectedTab;
  1242.  
  1243.             // Update the URL bar.
  1244.             var loc = this.mCurrentBrowser.currentURI;
  1245.             if (!loc)
  1246.               loc = ({ spec: "" });
  1247.  
  1248.             var webProgress = this.mCurrentBrowser.webProgress;
  1249.             var securityUI = this.mCurrentBrowser.securityUI;
  1250.             // Remember the current clear state, then set it to false
  1251.             // so we don't clear the userTypedValue when just switching
  1252.             // tabs. Set it back to its old state after we're done.
  1253.             var userTypedClear = this.mCurrentBrowser.userTypedClear;
  1254.             this.mCurrentBrowser.userTypedClear = false;
  1255.             var i, p;
  1256.             for (i = 0; i < this.mProgressListeners.length; i++) {
  1257.               p = this.mProgressListeners[i];
  1258.               if (p) {
  1259.                 p.onLocationChange(webProgress, null, loc);
  1260.                 if (securityUI)
  1261.                   p.onSecurityChange(webProgress, null, securityUI.state);
  1262.                 var listener = this.mTabListeners[this.mPanelContainer.selectedIndex];
  1263.                 if (listener.mIcon) {
  1264.                   if (this.isFavIconKnownMissing(listener.mIcon))
  1265.                     listener.mIcon = null;
  1266.                   else
  1267.                     p.onLinkIconAvailable(newBrowser, listener.mIcon);
  1268.                 }
  1269.               }
  1270.             }
  1271.             this.mCurrentBrowser.userTypedClear = userTypedClear;
  1272.  
  1273.             this._fastFind.setDocShell(this.mCurrentBrowser.docShell);
  1274.  
  1275.             // Update the window title.
  1276.             this.updateTitlebar();
  1277.  
  1278.             // If the new tab is busy, and our current state is not busy, then
  1279.             // we need to fire a start to all progress listeners.
  1280.             const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
  1281.             if (this.mCurrentTab.hasAttribute("busy") && !this.mIsBusy) {
  1282.               this.mIsBusy = true;
  1283.               webProgress = this.mCurrentBrowser.webProgress;
  1284.               for (i = 0; i < this.mProgressListeners.length; i++) {
  1285.                 p = this.mProgressListeners[i];
  1286.                 if (p)
  1287.                   p.onStateChange(webProgress, null, nsIWebProgressListener.STATE_START | nsIWebProgressListener.STATE_IS_NETWORK, 0);
  1288.               }
  1289.             }
  1290.  
  1291.             // If the new tab is not busy, and our current state is busy, then
  1292.             // we need to fire a stop to all progress listeners.
  1293.             if (!this.mCurrentTab.hasAttribute("busy") && this.mIsBusy) {
  1294.               this.mIsBusy = false;
  1295.               webProgress = this.mCurrentBrowser.webProgress;
  1296.               for (i = 0; i < this.mProgressListeners.length; i++) {
  1297.                 p = this.mProgressListeners[i];
  1298.                 if (p)
  1299.                   p.onStateChange(webProgress, null, nsIWebProgressListener.STATE_STOP | nsIWebProgressListener.STATE_IS_NETWORK, 0);
  1300.               }
  1301.             }
  1302.                                                      
  1303.                         if (!this.mCurrentTab.hasAttribute("busy")) {
  1304.                             window.XULBrowserWindow.onStateChange(webProgress, null, nsIWebProgressListener.STATE_STOP | nsIWebProgressListener.STATE_IS_NETWORK, 0);                    
  1305.                         } else {
  1306.                             window.XULBrowserWindow.onStateChange(webProgress, null, nsIWebProgressListener.STATE_START | nsIWebProgressListener.STATE_IS_NETWORK, 0);
  1307.                         }
  1308.                         
  1309.             function setFocus(element) {
  1310.                 // dump ("In tabbrowser.xml, using setFocus with " + element + ", id of " + element.id + "\t\t\t");
  1311.                 // showStack();
  1312.               Components.lookupMethod(element, "focus").call(element);
  1313.             }
  1314.  
  1315.             // Focus the previously focused element or window
  1316.             document.commandDispatcher.suppressFocusScroll = true;
  1317.             if (newBrowser.focusedElement) {
  1318.               try {
  1319.                 setFocus(newBrowser.focusedElement);
  1320.               } catch (e) {
  1321.                 setFocus(newBrowser.focusedWindow);
  1322.               }
  1323.             }
  1324.             else if (newBrowser.focusedWindow)
  1325.               setFocus(newBrowser.focusedWindow);
  1326.             else // new tab, focus our new content area
  1327.             {
  1328.               // setTimeout(setFocus, 0, window.content);
  1329.               dump ("JMC: Just set focus to window.content, within tabbrowser.xml\n");    
  1330.             }
  1331.             document.commandDispatcher.suppressFocusScroll = false;
  1332.             // MERC (DP): switch to the right toggle engine icon
  1333.             var currentEngine = this.mCurrentBrowser.webNavigation.browserEngine;
  1334.             var button = document.getElementById('enginetoggle-button');
  1335.             if(button) {
  1336.               if (currentEngine == 'Trident') {
  1337.                 button.style.listStyleImage = "url(chrome://browser/skin/Engine-Trident.png)";
  1338.               } else {
  1339.                 button.style.listStyleImage = "url(chrome://browser/skin/Engine-Gecko.png)";
  1340.               }
  1341.             }
  1342.  
  1343.             // update tab chrome
  1344.             this.updateChromeWhenLastTab();
  1345.             // MERC
  1346.             UpdateStatusbarPartnerIcons();       
  1347.             
  1348.             // MERC (rpaul) updating the statusbar engine icon for the current tab
  1349.                UpdateStatusBarEngineIcon(); 
  1350.             
  1351.           ]]>
  1352.         </body>
  1353.       </method>
  1354.  
  1355.       <method name="onTabClick">
  1356.         <parameter name="event"/>
  1357.         <body>
  1358.           <![CDATA[
  1359.             if (event.button > 1) return;  // Ignore right-clicks
  1360.                         
  1361.             // MERC (rpaul) click handler for new tab drop down popup menu
  1362.             var tabsNewDropDown = document.getElementById('tabs-newdropdown');
  1363.  
  1364.             if ((tabsNewDropDown.boxObject.screenX <= event.screenX)
  1365.               && (event.screenX - tabsNewDropDown.boxObject.screenX <= tabsNewDropDown.boxObject.width)
  1366.               && (tabsNewDropDown.boxObject.screenY <= event.screenY)
  1367.               && (event.screenY - tabsNewDropDown.boxObject.screenY <= tabsNewDropDown.boxObject.height))
  1368.              {
  1369.                 //anchor the new tab popup menu to the new tab button
  1370.                 var newTabButton = document.getElementById('tabNewButton');
  1371.                 var newTabButtonPopup = document.getElementById('tabsNewButtonPopup');
  1372.                 newTabButtonPopup.showPopup(newTabButton, -1, -1, "popup", "bottomleft", "topleft");
  1373.             }
  1374.  
  1375.             if (event.button != 1 || event.target.localName != 'tab' ||
  1376.                 this.mPrefs.getBoolPref("middlemouse.contentLoadURL"))
  1377.               return;
  1378.  
  1379.             this.removeTab(event.target);
  1380.             event.stopPropagation();
  1381.           ]]>
  1382.         </body>
  1383.       </method>
  1384.  
  1385.       <method name="onLinkAdded">
  1386.         <parameter name="event"/>
  1387.         <body>
  1388.           <![CDATA[
  1389.             if (!event.isTrusted)
  1390.               return;
  1391.  
  1392.             // mechanism for reading properties of the underlying XPCOM object
  1393.             // (ignoring potential getters/setters added by malicious content)
  1394.             var safeGetProperty = function(obj, propname) {
  1395.               return Components.lookupMethod(obj, propname).call(obj);
  1396.             };
  1397.  
  1398.             var tabBrowser = this.parentNode.parentNode;
  1399.             if (!tabBrowser.mPrefs.getBoolPref("browser.chrome.site_icons"))
  1400.               return;
  1401.  
  1402.             if (!event.target.rel.match((/(?:^|\s)icon(?:\s|$)/i)))
  1403.               return;
  1404.  
  1405.             // We have an icon.
  1406.             var href = event.target.href;
  1407.             if (!href)
  1408.               return;
  1409.  
  1410.             const nsIContentPolicy = Components.interfaces.nsIContentPolicy;
  1411.             try {
  1412.               var contentPolicy =
  1413.                 Components.classes['@mozilla.org/layout/content-policy;1']
  1414.                           .getService(nsIContentPolicy);
  1415.             } catch(e) {
  1416.               return; // Refuse to load if we can't do a security check.
  1417.             }
  1418.  
  1419.             // Verify that the load of this icon is legal.
  1420.             // We check first with the security manager
  1421.             const secMan =
  1422.               Components.classes["@mozilla.org/scriptsecuritymanager;1"]
  1423.                         .getService(Components.interfaces.nsIScriptSecurityManager);
  1424.  
  1425.             // Get the IOService so we can make URIs
  1426.             const ioService =
  1427.               Components.classes["@mozilla.org/network/io-service;1"]
  1428.                         .getService(Components.interfaces.nsIIOService);
  1429.  
  1430.             const targetDoc = safeGetProperty(event.target, "ownerDocument");
  1431.             // Make a URI out of our href.
  1432.             var docCharset = safeGetProperty(targetDoc, "characterSet");
  1433.             var uri = ioService.newURI(href, docCharset, null);
  1434.  
  1435.             var origURIStr = safeGetProperty(targetDoc, "documentURI");
  1436.             var origURI = ioService.newURI(origURIStr, docCharset, null);
  1437.  
  1438.             const nsIScriptSecMan =
  1439.               Components.interfaces.nsIScriptSecurityManager;
  1440.  
  1441.             try {
  1442.               secMan.checkLoadURI(origURI, uri,
  1443.                                   nsIScriptSecMan.DISALLOW_SCRIPT);
  1444.             } catch(e) {
  1445.               return;
  1446.             }
  1447.  
  1448.             // Security says okay, now ask content policy
  1449.             if (contentPolicy.shouldLoad(nsIContentPolicy.TYPE_IMAGE,
  1450.                                          uri, origURI, event.target,
  1451.                                          safeGetProperty(event.target, "type"),
  1452.                                          null) != nsIContentPolicy.ACCEPT)
  1453.               return;
  1454.  
  1455.             var browserIndex = tabBrowser.getBrowserIndexForDocument(targetDoc);
  1456.             // no browser? no favicon.
  1457.             if (browserIndex == -1)
  1458.               return;
  1459.  
  1460.             var listener = tabBrowser.mTabListeners[browserIndex];
  1461.             // there's no tab listener for non-tabbed mode browser 0
  1462.  
  1463.             if (tabBrowser.isFavIconKnownMissing(href)) {
  1464.               if (listener)
  1465.                 listener.mIcon = null;
  1466.               return;
  1467.             }
  1468.  
  1469.             if (listener)
  1470.               listener.mIcon = href;
  1471.  
  1472.             if (tabBrowser.mProgressListeners) {
  1473.               var targetBrowser = tabBrowser.getBrowserAtIndex(browserIndex);
  1474.               for (i = 0; i < tabBrowser.mProgressListeners.length; i++) {
  1475.                 var p = tabBrowser.mProgressListeners[i];
  1476.                 if (p)
  1477.                   p.onLinkIconAvailable(targetBrowser, href);
  1478.               }
  1479.             }
  1480.           ]]>
  1481.         </body>
  1482.       </method>
  1483.  
  1484.       <method name="onTitleChanged">
  1485.         <parameter name="evt"/>
  1486.         <body>
  1487.           <![CDATA[
  1488.             if (evt.target != this.contentDocument)
  1489.               return;
  1490.  
  1491.             var i = 0;
  1492.             for ( ; i < this.parentNode.parentNode.childNodes.length; i++) {
  1493.               if (this.parentNode.parentNode.childNodes[i].firstChild.nextSibling == this)
  1494.                 break;
  1495.             }
  1496.             
  1497.             var tabBrowser = this.parentNode.parentNode.parentNode.parentNode;
  1498.  
  1499.             var tab = tabBrowser.mTabContainer.childNodes[i];
  1500.             tabBrowser.setTabTitle(tab);
  1501.  
  1502.             if (tab == tabBrowser.mCurrentTab)
  1503.               tabBrowser.updateTitlebar();
  1504.           ]]>
  1505.         </body>
  1506.       </method>
  1507.  
  1508.       <method name="setTabTitle">
  1509.         <parameter name="aTab"/>
  1510.         <body>
  1511.           <![CDATA[
  1512.           
  1513. //          dump ("setTabTitle called\t\t\t");
  1514. //          showStack();
  1515.           
  1516.             var browser = this.getBrowserForTab(aTab);
  1517.             var crop = "end";
  1518.             var title = browser.contentTitle;
  1519.             
  1520.             if (!title) {
  1521.               if (browser.currentURI.spec) {
  1522.                 try {
  1523.                   title = this.mURIFixup.createExposableURI(browser.currentURI).spec;
  1524.                 } catch(ex) {
  1525.                   title = browser.currentURI.spec;
  1526.                 }
  1527.               }
  1528.  
  1529.               if (title && title != "about:blank") {
  1530.                 // At this point, we now have a URI.
  1531.                 // Let's try to unescape it using a character set
  1532.                 // in case the URI is not ASCII.
  1533.                 try {
  1534.                   var characterSet = Components.lookupMethod(browser.contentDocument, 'characterSet')
  1535.                                                .call(browser.contentDocument);
  1536.                   const textToSubURI = Components.classes["@mozilla.org/intl/texttosuburi;1"]
  1537.                                                  .getService(Components.interfaces.nsITextToSubURI);
  1538.                   title = textToSubURI.unEscapeNonAsciiURI(characterSet, title);
  1539.                 } catch(ex) { /* Do nothing. */ }
  1540.  
  1541.                 crop = "center";
  1542.  
  1543.               } else // Still no title?  Fall back to our untitled string.
  1544.                 title = this.mStringBundle.getString("tabs.untitled");
  1545.             }
  1546.  
  1547.             aTab.label = title;
  1548.             aTab.setAttribute("crop", crop);
  1549.  
  1550.             // MERC - JCH: Set special title and icon if tab is the non-user-initiated tab
  1551.             if (aTab.isNonUserInitPopupTab)
  1552.             {
  1553.                 aTab.label = "POP-UPS";
  1554.                 aTab.setAttribute("image", "chrome://browser/skin/icons/popuponsm_n.png");
  1555.             }
  1556.  
  1557.             //JA
  1558.             for (var i = 0; i < this.mTabContainer.childNodes.length; i++) {
  1559.                     if (this.mTabContainer.childNodes[i] == aTab)
  1560.                     {
  1561.                         window.onTabAction(3,i,title);//notify about title change on tab
  1562.                         break;
  1563.                     }
  1564.             }
  1565.             //end JA
  1566.           ]]>
  1567.         </body>
  1568.       </method>
  1569.  
  1570.       // MERC - JCH: Get the tab that holds the non-user-initiated popups tab if
  1571.       // it exists. If it doesn't, create a new tab and return it.
  1572.       <method name="getNonUserInitPopupTab">
  1573.         <parameter name="aURI"/>
  1574.         <parameter name="aReferrerURI"/>
  1575.         <parameter name="aCharset"/>
  1576.         <body>
  1577.         <![CDATA[
  1578.  
  1579.             var tab;
  1580.             var found = false;
  1581.             var childCount = this.mTabContainer.childNodes.length;
  1582.  
  1583.  
  1584.             // Search the tabs for the non-user-initiated-popups tab
  1585.             for (var i=0; i < childCount; i++)
  1586.             {
  1587.                 tab = this.mTabContainer.childNodes[i];
  1588.                 if (tab && tab.isNonUserInitPopupTab)//JA true if tab not
  1589.                 {
  1590.                     //dump("\n\n\n~~~~~~~~~~~isNonUserInitPopupTab = "+i);
  1591.                     found = true;
  1592.                     break;
  1593.                 }
  1594.             }
  1595.  
  1596.             // If the non-user-initiated popups tab is found, load it with current pop-up
  1597.             // page, otherwise create a new tab and init isNonUserInitPopupTab to true.
  1598.             if (found) {
  1599.  
  1600.                 var browser = this.getBrowserForTab(tab);
  1601.                 //dump("\n~~~~~~~~~~~browser = "+browser+"tab = "+tab+"\n\n\n");
  1602.                 browser.loadURI(aURI,aReferrerURI,aCharset);
  1603.  
  1604.             // This is the first non-user-initiated popup so create a tab and
  1605.             // set property isNonUserInitPopupTab to true
  1606.             } else {
  1607.  
  1608.                 tab = this.addTab(aURI,aReferrerURI,aCharset,null);
  1609.                 tab.isNonUserInitPopupTab = true;
  1610.             }
  1611.  
  1612.             return tab;
  1613.         ]]>
  1614.         </body>
  1615.       </method>
  1616.  
  1617.  
  1618.       // MERC - JCH: Check if non-user-initiated popups tab exists
  1619.       <method name="nonUserInitPopupTabExists">
  1620.         <body>
  1621.         <![CDATA[
  1622.             var found = false;
  1623.             var childCount = this.mTabContainer.childNodes.length;
  1624.  
  1625.             // Search the tabs for the non-user-initiated-popups tab
  1626.             for (var i=0; i < childCount; i++) {
  1627.  
  1628.                 if (this.mTabContainer.childNodes[i].isNonUserInitPopupTab) {
  1629.  
  1630.                     found = true;
  1631.                     break;
  1632.                 }
  1633.             }
  1634.  
  1635.             return found;
  1636.         ]]>
  1637.         </body>
  1638.       </method>
  1639.  
  1640.       <method name="setStripVisibilityTo">
  1641.         <parameter name="aShow"/>
  1642.         <body>
  1643.         <![CDATA[
  1644.           this.mStrip.collapsed = !aShow;
  1645.           if (aShow) {
  1646.             // XXXdwh temporary unclean dependency on specific menu items in navigator.xul
  1647.             document.getElementById("menu_closeWindow").hidden = false;
  1648.             document.getElementById("menu_close").setAttribute("label", this.mStringBundle.getString("tabs.closeTab"));
  1649.             if (!this.mTabbedMode)
  1650.               this.enterTabbedMode();
  1651.           }
  1652.           else {
  1653.             // XXXdwh temporary unclean dependency on specific menu items in navigator.xul
  1654.             document.getElementById("menu_closeWindow").hidden = true;
  1655.             document.getElementById("menu_close").setAttribute("label", this.mStringBundle.getString("tabs.close"));
  1656.           }
  1657.         ]]>
  1658.         </body>
  1659.       </method>
  1660.  
  1661.       <method name="getStripVisibility">
  1662.         <body>
  1663.           return !this.mStrip.collapsed;
  1664.         </body>
  1665.       </method>
  1666.  
  1667.       <method name="enterTabbedMode">
  1668.         <body>
  1669.           <![CDATA[
  1670.             this.mTabbedMode = true; // Welcome to multi-tabbed mode.
  1671.  
  1672.             // Get the first tab all hooked up with a title listener and popup blocking listener.
  1673.             this.mCurrentBrowser.addEventListener("DOMTitleChanged", this.onTitleChanged, false);
  1674.  
  1675.             this.setTabTitle(this.mCurrentTab);
  1676.  
  1677.             // Hook up our favicon.
  1678.             var uri = this.mCurrentBrowser.currentURI;
  1679.             if (this.shouldLoadFavIcon(uri))
  1680.               this.loadFavIcon(uri, "image", this.mCurrentTab);
  1681.  
  1682.             var filter;
  1683.             if (this.mTabFilters.length > 0) {
  1684.               // Use the filter hooked up in our addProgressListener
  1685.               filter = this.mTabFilters[0];
  1686.             } else {
  1687.               // create a filter and hook it up to our first browser
  1688.               filter = Components.classes["@mozilla.org/appshell/component/browser-status-filter;1"]
  1689.                                  .createInstance(Components.interfaces.nsIWebProgress);
  1690.               this.mTabFilters[0] = filter;
  1691.               this.mCurrentBrowser.webProgress.addProgressListener(filter, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
  1692.             }
  1693.  
  1694.             // Remove all our progress listeners from the active browser's filter.
  1695.             if (this.mProgressListeners) {
  1696.               for (var i = 0; i < this.mProgressListeners.length; i++) {
  1697.                 var p = this.mProgressListeners[i];
  1698.                 if (p)
  1699.                   filter.removeProgressListener(p);
  1700.               }
  1701.             }
  1702.  
  1703.             // Wire up a progress listener to our filter.
  1704.             const listener = this.mTabProgressListener(this.mCurrentTab, this.mCurrentBrowser, false);
  1705.             filter.addProgressListener(listener, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
  1706.             this.mTabListeners[0] = listener;
  1707.           ]]>
  1708.         </body>
  1709.       </method>
  1710.  
  1711.       <method name="_createMessage">
  1712.         <parameter name="aType"/>
  1713.         <body>
  1714.           <![CDATA[
  1715.             var message = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
  1716.                                                    "browsermessage");
  1717.             message.hidden = true;
  1718.             message.setAttribute("type", aType);
  1719.             return message;
  1720.           ]]>
  1721.         </body>
  1722.       </method>
  1723.  
  1724.       <method name="addTab">
  1725.         <parameter name="aURI"/>
  1726.         <parameter name="aReferrerURI"/>
  1727.         <parameter name="aCharset"/>
  1728.         <parameter name="aPostData"/>
  1729.         <body>
  1730.           <![CDATA[
  1731.             var blank = (aURI == "about:blank");
  1732.  
  1733.             if (!this.mTabbedMode)
  1734.               this.enterTabbedMode();
  1735.  
  1736.             var b = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
  1737.                                              "browser");
  1738.             var t = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
  1739.                                              "tab");
  1740.  
  1741.             if (blank)
  1742.               t.setAttribute("label", this.mStringBundle.getString("tabs.untitled"));
  1743.             else
  1744.               t.setAttribute("label", aURI);
  1745.  
  1746.             t.setAttribute("crop", "end");
  1747.             t.maxWidth = 250;
  1748.             t.minWidth = 50;
  1749.             t.width = 0;
  1750.             t.setAttribute("flex", "100");
  1751.             t.setAttribute("validate", "never");
  1752.             t.setAttribute("onerror", "this.parentNode.parentNode.parentNode.parentNode.addToMissedIconCache(this.getAttribute('image')); this.removeAttribute('image');");
  1753.             // MERC (DP) ***********
  1754.             t.setAttribute("onnewpreftab", "BrowserOpenPrefTab();");
  1755.             // *********************
  1756.  
  1757.             // MERC - JCH: If the nuip tab exists then add new tab to the left of this
  1758.             // otherwise just add to far right
  1759.  
  1760.             if (this.nonUserInitPopupTabExists()) {
  1761.  
  1762.                 this.mTabContainer.insertBefore(t, this.mTabContainer.childNodes[this.mPanelContainer.childNodes.length-1]);
  1763.             } else {
  1764.  
  1765.                 this.mTabContainer.appendChild(t);
  1766.             }
  1767.  
  1768.             b.setAttribute("type", "content");
  1769.             b.setAttribute("message", "true");
  1770.             b.setAttribute("contextmenu", this.getAttribute("contentcontextmenu"));
  1771.             b.setAttribute("tooltip", this.getAttribute("contenttooltip"));
  1772.             b.setAttribute("autocompletepopup", this.getAttribute("autocompletepopup"));
  1773.  
  1774.             // Add the Message and the Browser to the box
  1775.             var vbox = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
  1776.                                                 "vbox");
  1777.             vbox.setAttribute("flex", "1");
  1778.             vbox.appendChild(this._createMessage("top"));
  1779.             vbox.appendChild(b);
  1780.             vbox.appendChild(this._createMessage("bottom"));
  1781.             b.setAttribute("flex", "1");
  1782.             // this.mPanelContainer.appendChild(vbox);
  1783.  
  1784.             // MERC - JCH: If the nuip tab exists then add new tab to the left of this
  1785.             // otherwise just add to far right
  1786.             if (this.nonUserInitPopupTabExists()) {
  1787.               this.mPanelContainer.insertBefore(vbox, this.mPanelContainer.childNodes[this.mPanelContainer.childNodes.length-1]);
  1788.             } else {
  1789.               this.mPanelContainer.appendChild(vbox);
  1790.             }
  1791.  
  1792.             b.addEventListener("DOMTitleChanged", this.onTitleChanged, false);
  1793.  
  1794.             if (this.mStrip.collapsed)
  1795.               this.setStripVisibilityTo(true);
  1796.  
  1797.             this.mPrefs.setBoolPref("browser.tabs.forceHide", false);
  1798.  
  1799.             // wire up a progress listener for the new browser object.
  1800.             var tabListener = this.mTabProgressListener(t, b, blank);
  1801.             
  1802.             // JMC - Note: this causes the currently selected tab to refresh it's title and favicon,
  1803.             // In the case where we're loading a new tab into the background
  1804.             
  1805.             const filter = Components.classes["@mozilla.org/appshell/component/browser-status-filter;1"]
  1806.                                      .createInstance(Components.interfaces.nsIWebProgress);
  1807.             filter.addProgressListener(tabListener, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
  1808.             b.webProgress.addProgressListener(filter, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
  1809.  
  1810.             var position;
  1811.  
  1812.             // MERC - JCH: If the nuip tab exists, then position the
  1813.             // listeners and filters correctly
  1814.             if (this.nonUserInitPopupTabExists()) {
  1815.               position = this.mTabContainer.childNodes.length-2;
  1816.               this.mTabListeners.splice(position, 0, tabListener);
  1817.               this.mTabFilters.splice(position, 0, filter);
  1818.             } else {
  1819.               position = this.mTabContainer.childNodes.length-1;
  1820.               this.mTabListeners[position] = tabListener;
  1821.               this.mTabFilters[position] = filter;
  1822.             }
  1823.  
  1824.             b._fastFind = this.fastFind;
  1825.  
  1826.             if (!blank) {
  1827.               // pretend the user typed this so it'll be available till
  1828.               // the document successfully loads
  1829.               b.userTypedValue = aURI;
  1830.  
  1831.               if (aPostData === undefined)
  1832.                 aPostData = null;
  1833.               try {
  1834.                 b.loadURIWithFlags(aURI, nsIWebNavigation.LOAD_FLAGS_NONE,
  1835.                                  aReferrerURI, aPostData, null);
  1836.               } catch( e ) {
  1837.                 // Clean up for bad scheme exception thrown by loadURIWithFlags().
  1838.                 b.userTypedValue = "";
  1839.                 t.setAttribute("label", this.mStringBundle.getString("tabs.untitled"));
  1840.               }
  1841.             }
  1842.  
  1843.             this.updateCurrentBrowser();
  1844.  
  1845.             window.onTabAction(0,position,null);//JA
  1846.  
  1847.             return t;
  1848.           ]]>
  1849.         </body>
  1850.       </method>
  1851.  
  1852.       <method name="addTabAt">
  1853.         <parameter name="aURI"/>
  1854.         <parameter name="atPref"/> <!-- set to undefined to read pref: browser.tabs.newTabLocation -->
  1855.         <parameter name="aReferrerURI"/>
  1856.         <parameter name="aCharset"/>
  1857.         <parameter name="aPostData"/>
  1858.         <body>
  1859.           <![CDATA[
  1860.           return this.addTabAtWithFlag(1, aURI, atPref, aReferrerURI, aCharset, aPostData);
  1861.       ]]>
  1862.       </body>
  1863.       </method>
  1864.  
  1865.       <method name="addTabAtWithFlag">
  1866.         <parameter name="aAddSessionHistory"/>
  1867.         <parameter name="aURI"/>
  1868.         <parameter name="atPref"/> <!-- set to undefined to read pref: browser.tabs.newTabLocation -->
  1869.         <parameter name="aReferrerURI"/>
  1870.         <parameter name="aCharset"/>
  1871.         <parameter name="aPostData"/>
  1872.         <body>
  1873.           <![CDATA[
  1874.             var blank = (aURI == "about:blank");
  1875.  
  1876.             if (!this.mTabbedMode)
  1877.               this.enterTabbedMode();
  1878.             
  1879.             var forceUpdate;
  1880.             
  1881.             var b = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
  1882.                                              "browser");
  1883.             var t = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
  1884.                                              "tab");
  1885.  
  1886.             if (blank)
  1887.               t.setAttribute("label", this.mStringBundle.getString("tabs.untitled"));
  1888.             else
  1889.               t.setAttribute("label", aURI);
  1890.  
  1891.             t.setAttribute("crop", "end");
  1892.             t.maxWidth = 250;
  1893.             t.minWidth = 50;
  1894.             t.width = 0;
  1895.             t.setAttribute("flex", "100");
  1896.             t.setAttribute("validate", "never");
  1897.             t.setAttribute("onerror", "this.parentNode.parentNode.parentNode.parentNode.addToMissedIconCache(this.getAttribute('image')); this.removeAttribute('image');");
  1898.             // MERC (DP) ***********
  1899.             t.setAttribute("onnewpreftab", "BrowserOpenPrefTab();");
  1900.             // *********************
  1901.  
  1902.             // this pref determines where a new tab is openned
  1903.             // choices are: left, right, farleft, farright.
  1904.             // if the pref is passed in, use it. otherwise get the user pref
  1905.             var newTabLocation;
  1906.             if(atPref === undefined) {
  1907.               newTabLocation = this.mPrefs.getCharPref("browser.tabs.newTabLocation");
  1908.             } else {
  1909.               newTabLocation = atPref;
  1910.             }
  1911.  
  1912.             switch(newTabLocation) {
  1913.                 case 'left':
  1914.                     this.mTabContainer.insertBefore(t, this.mCurrentTab);
  1915.                     forceUpdate = true;
  1916.                     break;
  1917.                 case 'right':
  1918.                     // MERC - JCH: If the nuip tab exists then new tab is placed to its left
  1919.                     if (this.nonUserInitPopupTabExists()) {
  1920.                         this.mTabContainer.insertBefore(t, this.mTabContainer.childNodes[this.mPanelContainer.childNodes.length-1]);
  1921.                         break;
  1922.                     }
  1923.  
  1924.                     // if the current tab is the last tab
  1925.                     if(this.mPanelContainer.selectedIndex == this.mPanelContainer.childNodes.length) {
  1926.                         this.mTabContainer.appendChild(t);
  1927.                     } else {
  1928.                         this.mTabContainer.insertBefore(t, this.mTabContainer.childNodes[this.mPanelContainer.selectedIndex + 1]);
  1929.                     }
  1930.                     break;
  1931.                 case 'farleft':
  1932.                     this.mTabContainer.insertBefore(t, this.mTabContainer.childNodes[0]);
  1933.                     break;
  1934.                 case 'farright':
  1935.                 // MERC - JCH: If the nuip tab exists then new tab is placed to its left
  1936.                 if (this.nonUserInitPopupTabExists()) {
  1937.                     this.mTabContainer.insertBefore(t, this.mTabContainer.childNodes[this.mPanelContainer.childNodes.length-1]);
  1938.                     break;
  1939.                 }
  1940.                default:
  1941.                     this.mTabContainer.appendChild(t);
  1942.                     break;
  1943.             }
  1944.  
  1945.             b.setAttribute("type", "content");
  1946.             b.setAttribute("message", "true");
  1947.             b.setAttribute("contextmenu", this.getAttribute("contentcontextmenu"));
  1948.             b.setAttribute("tooltip", this.getAttribute("contenttooltip"));
  1949.             b.setAttribute("autocompletepopup", this.getAttribute("autocompletepopup"));
  1950.  
  1951.             // To avoid unnecessary string compares on pageload in <browser>, only set the
  1952.             // autocomplete attribute if autocomplete is actually enabled, so we can
  1953.             // just test with |hasAttribute| in <browser>'s load handler.
  1954.             if (this.getAttribute("autocompleteenabled") == "true")
  1955.               b.setAttribute("autocompleteenabled", "true");
  1956.  
  1957.             // Add the Message and the Browser to the box
  1958.             var vbox = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
  1959.                                                 "vbox");
  1960.             vbox.setAttribute("flex", "1");
  1961.             vbox.appendChild(this._createMessage("top"));
  1962.             vbox.appendChild(b);
  1963.             vbox.appendChild(this._createMessage("bottom"));
  1964.             b.setAttribute("flex", "1");
  1965.  
  1966.             switch(newTabLocation) {
  1967.               case 'left':
  1968.                     //this.mPanelContainer.insertBefore(vbox, this.getBrowserForTab(this.mCurrentTab));
  1969.                     this.mPanelContainer.insertBefore(vbox, this.mPanelContainer.childNodes[this.mPanelContainer.selectedIndex]);
  1970.                     break;
  1971.                 case 'right':
  1972.                     // MERC - JCH: If the nuip tab exists then new tab is placed to its left
  1973.                     if (this.nonUserInitPopupTabExists()) {
  1974.                         this.mPanelContainer.insertBefore(vbox, this.mPanelContainer.childNodes[this.mPanelContainer.childNodes.length-1]);
  1975.                         break;
  1976.                     }
  1977.  
  1978.                 // if the current tab is the last tab
  1979.                 if(this.mPanelContainer.selectedIndex == this.mPanelContainer.childNodes.length) {
  1980.                     this.mPanelContainer.appendChild(vbox);
  1981.                 } else {
  1982.                     this.mPanelContainer.insertBefore(vbox, this.mPanelContainer.childNodes[this.mPanelContainer.selectedIndex + 1]);
  1983.                 }
  1984.                 break;
  1985.                 case 'farleft':
  1986.                     this.mPanelContainer.insertBefore(vbox, this.mPanelContainer.childNodes[0]);
  1987.                 break;
  1988.                 case 'farright':
  1989.                 // MERC - JCH: If the nuip tab exists then new tab is placed to its left
  1990.                 if (this.nonUserInitPopupTabExists()) {
  1991.                     this.mPanelContainer.insertBefore(vbox, this.mPanelContainer.childNodes[this.mPanelContainer.childNodes.length-1]);
  1992.                     break;
  1993.                 }
  1994.  
  1995.                 default:
  1996.                 this.mPanelContainer.appendChild(vbox);
  1997.                 break;
  1998.             }
  1999.  
  2000.             b.addEventListener("DOMTitleChanged", this.onTitleChanged, false);
  2001.  
  2002.             if (this.mStrip.collapsed)
  2003.               this.setStripVisibilityTo(true);
  2004.  
  2005.             this.mPrefs.setBoolPref("browser.tabs.forceHide", false);
  2006.  
  2007.             // wire up a progress listener for the new browser object.
  2008.             var tabListener = this.mTabProgressListener(t, b, blank);
  2009.             const filter = Components.classes["@mozilla.org/appshell/component/browser-status-filter;1"]
  2010.                                      .createInstance(Components.interfaces.nsIWebProgress);
  2011.             filter.addProgressListener(tabListener, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
  2012.             b.webProgress.addProgressListener(filter, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
  2013.  
  2014.             var position;
  2015.             switch(newTabLocation) {
  2016.                 case 'left':
  2017.                     position = this.mPanelContainer.selectedIndex;
  2018.                     this.mTabListeners.splice(position, 0, tabListener);
  2019.                     this.mTabFilters.splice(position, 0, filter);
  2020.                     break;
  2021.                 case 'right':
  2022.                     // MERC - JCH: If the nuip tab exists, position the listeners and filters
  2023.                     // correctly for the new tab
  2024.                     if (this.nonUserInitPopupTabExists()) {
  2025.                         position = this.mTabContainer.childNodes.length-2;
  2026.                         this.mTabListeners.splice(position, 0, tabListener);
  2027.                         this.mTabFilters.splice(position, 0, filter);
  2028.                         break;
  2029.                     }
  2030.  
  2031.                     // if the current tab is the last tab
  2032.                     if(this.mPanelContainer.selectedIndex == this.mPanelContainer.childNodes.length) {
  2033.                         position = this.mTabContainer.childNodes.length-1;
  2034.                         this.mTabListeners[position] = tabListener;
  2035.                         this.mTabFilters[position] = filter;
  2036.                     } else {
  2037.                         position = this.mPanelContainer.selectedIndex + 1;
  2038.                         this.mTabListeners.splice(position, 0, tabListener);
  2039.                         this.mTabFilters.splice(position, 0, filter);
  2040.                     }
  2041.                     break;
  2042.                 case 'farleft':
  2043.                   position = 0;
  2044.                   this.mTabListeners.splice(position, 0, tabListener);
  2045.                   this.mTabFilters.splice(position, 0, filter);
  2046.                   break;
  2047.                 case 'farright':
  2048.                     // MERC - JCH: If the nuip tab exists, position the listeners and filters
  2049.                     // correctly for the new tab
  2050.                     if (this.nonUserInitPopupTabExists()) {
  2051.                         position = this.mTabContainer.childNodes.length-2;
  2052.                         this.mTabListeners.splice(position, 0, tabListener);
  2053.                         this.mTabFilters.splice(position, 0, filter);
  2054.                         break;
  2055.                     }
  2056.                 default:
  2057.                     position = this.mTabContainer.childNodes.length-1;
  2058.                     this.mTabListeners[position] = tabListener;
  2059.                     this.mTabFilters[position] = filter;
  2060.                     break;
  2061.             }
  2062.  
  2063.             if (!blank) {
  2064.               if (aPostData === undefined)
  2065.                 aPostData = null;
  2066.               // Full back/forward history already duplicated; do not clobber with current URI.
  2067.               var wnLoadType = nsIWebNavigation.LOAD_FLAGS_NONE;
  2068.               if (aAddSessionHistory) {
  2069.                 wnLoadType = nsIWebNavigation.LOAD_FLAGS_NONE;
  2070.               } else {
  2071.                 wnLoadType = nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY;
  2072.               }
  2073.               try {
  2074.                 b.loadURIWithFlags(aURI, wnLoadType, aReferrerURI, aPostData, null);
  2075.               } catch( e ) {
  2076.                 t.setAttribute("label", this.mStringBundle.getString("tabs.untitled"));
  2077.               }
  2078.             }
  2079.             // if (!forceUpdate)
  2080.             // {
  2081.                 // dump ("Calling update Current Browser");
  2082.                 // this.updateCurrentBrowser();
  2083.             // }
  2084.             window.onTabAction(0,position,null);//JA
  2085.             return t;
  2086.           ]]>
  2087.         </body>
  2088.       </method>
  2089.  
  2090.       <method name="addPrefTab">
  2091.         <body>
  2092.           <![CDATA[
  2093.             // 4 cases:
  2094.             // a) 'blank' - open a new blank tab
  2095.             // b) 'homepage' - open new tabs with home page entries
  2096.             // c) 'current' - open a new tab with the current site loaded
  2097.             // d) 'netscape' - open a new tab with netscape.com
  2098.             var newTabPref;
  2099.             try {
  2100.               newTabPref = this.mPrefs.getCharPref("browser.tabs.newTabChoice");
  2101.             } catch(e) {
  2102.               newTabPref = 'blank';
  2103.             }
  2104.  
  2105.             var addedTab;
  2106.             switch(newTabPref) {
  2107.               case 'homepage':
  2108.                 BrowserHome(true);
  2109.                 addedTab = this.mCurrentTab;
  2110.                 break;
  2111.               case 'current':
  2112.                 currentTab = this.mCurrentTab;
  2113.                 var curTabBrowser=this.getBrowserForTab(currentTab);
  2114.                 var sHistory=curTabBrowser.sessionHistory;
  2115.                 addedTab = this.addTabAtWithFlag(0,this.getBrowserForTab(this.mCurrentTab).currentURI.spec);
  2116.                 var newTabBrowser=this.getBrowserForTab(addedTab);
  2117.                 newTabBrowser.sessionHistory.appendFrom(sHistory);
  2118.                 break;
  2119.               case 'netscape':
  2120.                 var url;
  2121.                 try {
  2122.                   url = gPrefService.getComplexValue("browser.netscape.homepage",
  2123.                                             Components.interfaces.nsIPrefLocalizedString).data;
  2124.                 } catch (e) {
  2125.                 }
  2126.                 addedTab = this.addTabAt(url);
  2127.                 break;
  2128.               case 'blank':
  2129.               default:
  2130.                 addedTab = this.addTabAt("about:blank");
  2131.                 break;
  2132.             }
  2133.  
  2134.             return addedTab;
  2135.           ]]>
  2136.         </body>
  2137.       </method>
  2138.  
  2139.       <method name="warnAboutClosingTabs">
  2140.       <parameter name="aAll"/>
  2141.       <body>
  2142.         <![CDATA[
  2143.           var numTabs = this.mTabContainer.childNodes.length;
  2144.           var reallyClose = true;
  2145.           if (numTabs <= 1)
  2146.             return reallyClose;
  2147.  
  2148.           const pref = "browser.tabs.warnOnClose";
  2149.           var shouldPrompt = this.mPrefs.getBoolPref(pref);
  2150.           var reallyClose = true;
  2151.  
  2152.           if (shouldPrompt) {
  2153.             var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
  2154.                                           .getService(Components.interfaces.nsIPromptService);
  2155.  
  2156.             //default to true: if it were false, we wouldn't get this far
  2157.             var warnOnClose = { value:true };
  2158.             var bundle = this.mStringBundle;
  2159.             var tabsToClose = numTabs;  //number of tabs to be removed
  2160.             if (!aAll)
  2161.               --tabsToClose;
  2162.  
  2163.             var messageKey = (tabsToClose == 1) ? "tabs.closeWarningOne" : "tabs.closeWarningMultiple";
  2164.             var closeKey = (tabsToClose == 1) ? "tabs.closeButtonOne" : "tabs.closeButtonMultiple";
  2165.             var buttonPressed = promptService.confirmEx(window,
  2166.                                                         bundle.getString('tabs.closeWarningTitle'),
  2167.                                                         bundle.getFormattedString(messageKey, [tabsToClose]),
  2168.                                                         (promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_0)
  2169.                                                         + (promptService.BUTTON_TITLE_CANCEL * promptService.BUTTON_POS_1),
  2170.                                                         bundle.getString(closeKey),
  2171.                                                         null, null,
  2172.                                                         bundle.getString('tabs.closeWarningPromptMe'),
  2173.                                                         warnOnClose);
  2174.             reallyClose = (buttonPressed == 0);
  2175.             // don't set the pref unless they press OK and it's false
  2176.             if (reallyClose && !warnOnClose.value)
  2177.               this.mPrefs.setBoolPref(pref, false);
  2178.           }
  2179.           return reallyClose;
  2180.         ]]>
  2181.       </body>
  2182.       </method>
  2183.  
  2184.       <method name="removeAllTabsBut">
  2185.         <parameter name="aTab"/>
  2186.         <body>
  2187.           <![CDATA[
  2188.               if (this.warnAboutClosingTabs(false)) {
  2189.                 if (aTab.localName != "tab")
  2190.                   aTab = this.mCurrentTab;
  2191.                 else
  2192.                   this.mTabContainer.selectedItem = aTab;
  2193.  
  2194.                 var childNodes = this.mTabContainer.childNodes;
  2195.  
  2196.                 for (var i = childNodes.length - 1; i >= 0; --i) {
  2197.                   if (childNodes[i] != aTab)
  2198.                     this.removeTab(childNodes[i]);
  2199.                 }
  2200.               }
  2201.             }
  2202.           ]]>
  2203.         </body>
  2204.       </method>
  2205.  
  2206.       <method name="removeCurrentTab">
  2207.         <body>
  2208.           <![CDATA[
  2209.               // MERC (DP): hide site control popup for the case when tab is closed on dbl click
  2210.               document.getElementById('SiteControlsPopup').hidePopup();
  2211.             return this.removeTab(this.mCurrentTab);
  2212.           ]]>
  2213.         </body>
  2214.       </method>
  2215.  
  2216.       <method name="removeTab">
  2217.         <parameter name="aTab"/>
  2218.         <body>
  2219.           <![CDATA[
  2220.             if (aTab.localName != "tab")
  2221.               aTab = this.mCurrentTab;
  2222.             // if we are deleting the tab associated to lastSelectedTab, set lastSelectedTab = null;
  2223.             if(this.mTabContainer.lastSelectedTab != null && aTab == this.mTabContainer.lastSelectedTab) {
  2224.               this.mTabContainer.lastSelectedTab = null;
  2225.             }
  2226.             var l = this.mTabContainer.childNodes.length;
  2227.             if (l == 1) {
  2228.  
  2229.               if (aTab.isNonUserInitPopupTab)
  2230.                 aTab.isNonUserInitPopupTab = false;
  2231.  
  2232.               if (!this.mPrefs.getBoolPref("browser.tabs.autoHide")) {
  2233.                 // blank the tab
  2234.                 this.loadURI("about:blank");
  2235.                 return;
  2236.               }
  2237.               // hide the tab bar
  2238.               /* MERC (DP): never allow the case when there are zero tabs open
  2239.                             i.e. there must always be at least one tab
  2240.               this.mPrefs.setBoolPref("browser.tabs.forceHide", true);
  2241.               this.setStripVisibilityTo(false);
  2242.               */
  2243.               return;
  2244.             }
  2245.             var ds = this.getBrowserForTab(aTab).docShell;
  2246.  
  2247.             if (ds.contentViewer && !ds.contentViewer.permitUnload())
  2248.               return;
  2249.  
  2250.             if (l == 2) {
  2251.               var autohide = this.mPrefs.getBoolPref("browser.tabs.autoHide");
  2252.               if (autohide)
  2253.                 this.setStripVisibilityTo(false);
  2254.             }
  2255.  
  2256.             var index = -1;
  2257.             if (this.mCurrentTab == aTab)
  2258.               index = this.mPanelContainer.selectedIndex;
  2259.             else {
  2260.               // Find and locate the tab in our list.
  2261.               for (var i = 0; i < l; i++)
  2262.                 if (this.mTabContainer.childNodes[i] == aTab)
  2263.                   index = i;
  2264.             }
  2265.  
  2266.             // Remove the tab's filter and progress listener.
  2267.             const filter = this.mTabFilters[index];
  2268.             var oldBrowser = this.getBrowserAtIndex(index);
  2269.             oldBrowser.webProgress.removeProgressListener(filter);
  2270.             filter.removeProgressListener(this.mTabListeners[index]);
  2271.             this.mTabFilters.splice(index, 1);
  2272.             this.mTabListeners.splice(index, 1);
  2273.  
  2274.             // Remove our title change and blocking listeners
  2275.             oldBrowser.removeEventListener("DOMTitleChanged", this.onTitleChanged, false);
  2276.  
  2277.             // We are no longer the primary content area.
  2278.             oldBrowser.setAttribute("type", "content");
  2279.  
  2280.             // get the preference that determines which tab is focused after removal
  2281.             var focusAfterRemoval = this.mPrefs.getCharPref("browser.tabs.focusAfterRemoval");
  2282.             // Now select the new tab before nuking the old one.
  2283.             var currentIndex = this.mPanelContainer.selectedIndex;
  2284.  
  2285.             var bUseLastTab = false;
  2286.             var newIndex = -1;
  2287.             if (currentIndex > index) {
  2288.               newIndex = currentIndex-1;
  2289.             } else if (currentIndex < index) {
  2290.               newIndex = currentIndex;
  2291.             } else {
  2292.               switch(focusAfterRemoval) {
  2293.                 case 'right':
  2294.                   newIndex = currentIndex;
  2295.                   break;
  2296.                 case 'lastSelected':
  2297.                   if(this.mTabContainer.lastSelectedTab == null) {
  2298.                     // if there is no last selected tab, we focus the tab to the left
  2299.                     newIndex = currentIndex - 1;
  2300.                   } else {
  2301.                     bUseLastTab = true;
  2302.                   }
  2303.                   break;
  2304.                 case 'left':
  2305.                 default:
  2306.                   newIndex = currentIndex - 1;
  2307.                   break;
  2308.               }
  2309.             }
  2310.  
  2311.             var newLength = l - 2;
  2312.             if(newIndex < 0) {
  2313.               newIndex = 0;
  2314.             }
  2315.             if(newIndex > newLength) {
  2316.               newIndex = newLength;
  2317.             }
  2318.             var oldTab = aTab;
  2319.             // clean up the before/afterselected attributes before removing the tab
  2320.             oldTab.selected = false;
  2321.             // XXX browser's destructor isn't always called, so we force a cleanup ourselves
  2322.             oldBrowser.destroy();
  2323.             window.onTabAction(1,index,null);//JA
  2324.  
  2325.             this.mTabContainer.removeChild(oldTab);
  2326.                         this.mPanelContainer.removeChild(this.mPanelContainer.childNodes[index]);
  2327.             if(bUseLastTab) {
  2328.               for (var i = 0; i < l; i++) {
  2329.                   if (this.mTabContainer.childNodes[i] == this.mTabContainer.lastSelectedTab) {
  2330.                     newIndex = i;
  2331.                   }
  2332.               }
  2333.             }
  2334.             this.selectedTab = this.mTabContainer.childNodes[newIndex];
  2335.             this.mPanelContainer.selectedIndex = newIndex;
  2336.             this.updateCurrentBrowser();
  2337.  
  2338.             }
  2339.  
  2340.  
  2341.           ]]>
  2342.         </body>
  2343.       </method>
  2344.  
  2345.       <method name="reloadAllTabs">
  2346.         <body>
  2347.           <![CDATA[
  2348.             var l = this.mPanelContainer.childNodes.length;
  2349.             for (var i = 0; i < l; i++) {
  2350.               try {
  2351.                 this.getBrowserAtIndex(i).reload();
  2352.               } catch (e) {
  2353.                 // ignore failure to reload so others will be reloaded
  2354.               }
  2355.             }
  2356.           ]]>
  2357.         </body>
  2358.       </method>
  2359.  
  2360.       <method name="reloadTab">
  2361.         <parameter name="aTab"/>
  2362.         <body>
  2363.           <![CDATA[
  2364.             if (aTab.localName != "tab")
  2365.               aTab = this.mCurrentTab;
  2366.  
  2367.             this.getBrowserForTab(aTab).reload();
  2368.           ]]>
  2369.         </body>
  2370.       </method>
  2371.  
  2372.       // MERC (DP)
  2373.       <method name="closeAllTabsToLeft">
  2374.         <parameter name="aTab"/>
  2375.         <body>
  2376.           <![CDATA[
  2377.             if (aTab.localName != "tab") {
  2378.               aTab = this.mCurrentTab;
  2379.             }
  2380.  
  2381.             // get the number of tabs
  2382.             var l = this.mTabContainer.childNodes.length;
  2383.  
  2384.             // find the index of the context tab (not necessarily the selected tab)
  2385.             var index = -1;
  2386.             if (this.mCurrentTab == aTab) {
  2387.               index = this.mPanelContainer.selectedIndex;
  2388.             } else {
  2389.               // Find and locate the tab in our list.
  2390.               for (var i = 0; i < l; i++) {
  2391.                 if (this.mTabContainer.childNodes[i] == aTab) {
  2392.                   index = i;
  2393.                   break;
  2394.                 } // if
  2395.               } // for
  2396.             } // if
  2397.  
  2398.             for(var j = 0; j < index; j++) {
  2399.               // remove the first tab
  2400.               this.removeTab(this.mTabContainer.childNodes[0]);
  2401.             }
  2402.           ]]>
  2403.         </body>
  2404.       </method>
  2405.  
  2406.       <method name="closeAllTabsToRight">
  2407.         <parameter name="aTab"/>
  2408.         <body>
  2409.           <![CDATA[
  2410.             if (aTab.localName != "tab") {
  2411.               aTab = this.mCurrentTab;
  2412.             }
  2413.  
  2414.             // get the number of tabs
  2415.             var l = this.mTabContainer.childNodes.length;
  2416.  
  2417.             // find the index of the context tab (not necessarily the selected tab)
  2418.             var index = -1;
  2419.             if (this.mCurrentTab == aTab) {
  2420.               index = this.mPanelContainer.selectedIndex;
  2421.             } else {
  2422.               // Find and locate the tab in our list.
  2423.               for (var i = 0; i < l; i++) {
  2424.                 if (this.mTabContainer.childNodes[i] == aTab) {
  2425.                   index = i;
  2426.                   break;
  2427.                 } // if
  2428.               } // for
  2429.             } // if
  2430.  
  2431.             for(var j = 0; j < l - index - 1; j++) {
  2432.               // remove the last tab
  2433.               this.removeTab(this.mTabContainer.childNodes[this.mTabContainer.childNodes.length - 1]);
  2434.             }
  2435.           ]]>
  2436.         </body>
  2437.       </method>
  2438.       // MERC (DP)
  2439.  
  2440.  
  2441.         <!--
  2442.             Will return true if the host string of the first URI param is a direct subdomain
  2443.             of the second URI param
  2444.             e.g. www.google.com , mail.google.com => true
  2445.                  slashdot.org/main.html , news.slashdot.org/index.html => true
  2446.                  foobar.asdf.com , hello.asdf.com => false
  2447.         -->
  2448.       <method name="compareURISubdomain">
  2449.         <parameter name="aURI1"/>
  2450.         <parameter name="aURI2"/>
  2451.         <body>
  2452.           <![CDATA[
  2453.             var host1;
  2454.             var host2;
  2455.  
  2456.             try {
  2457.               host1 = aURI1.host;
  2458.             } catch(e) {
  2459.               host1 = aURI1.spec;
  2460.             }
  2461.  
  2462.                         // strip 'www.' from the first host, if present
  2463.                         if(host1.match(/^www\./)) {
  2464.                             host1 = host1.substring(4);
  2465.                         }
  2466.  
  2467.             try {
  2468.               host2 = aURI2.host;
  2469.             } catch(e) {
  2470.               host2 = aURI2.spec;
  2471.             }
  2472.  
  2473.                         var dotHost1 = '.' + host1;
  2474.                         var dotHost2 = '.' + host2;
  2475.             if(dotHost2.indexOf(dotHost1) > -1) {
  2476.               return true;
  2477.             } else {
  2478.               return false;
  2479.             }
  2480.           ]]>
  2481.         </body>
  2482.       </method>
  2483.  
  2484.       <!--
  2485.         Will return true if the host string of the URIs are the same
  2486.         e.g. www.foobar.com/index.html == www.foobar.com/help.html
  2487.       -->
  2488.       <method name="compareURI">
  2489.         <parameter name="aURI1"/>
  2490.         <parameter name="aURI2"/>
  2491.         <body>
  2492.           <![CDATA[
  2493.             var host1;
  2494.             var host2;
  2495.  
  2496.             try {
  2497.               host1 = aURI1.host;
  2498.             } catch(e) {
  2499.               host1 = aURI1.spec;
  2500.             }
  2501.  
  2502.             try {
  2503.               host2 = aURI2.host;
  2504.             } catch(e) {
  2505.               host2 = aURI2.spec;
  2506.             }
  2507.  
  2508.             if(host1 == host2) {
  2509.               return true;
  2510.             } else {
  2511.               return false;
  2512.             }
  2513.           ]]>
  2514.         </body>
  2515.       </method>
  2516.  
  2517.       <method name="closeAllTabsFromSameSite">
  2518.         <parameter name="aTab"/>
  2519.         <body>
  2520.           <![CDATA[
  2521.             if (aTab.localName != "tab") {
  2522.               aTab = this.mCurrentTab;
  2523.             }
  2524.  
  2525.             var contextBrowser = this.getBrowserForTab(aTab);
  2526.             var browserPanels = this.mPanelContainer.childNodes;
  2527.             var tabs = this.mTabContainer.childNodes;
  2528.  
  2529.             for(var i = tabs.length - 1; i >= 0; --i) {
  2530.               // don't remove the context tab until the very end. otherwise you get error
  2531.               if( (this.compareURISubdomain(contextBrowser.currentURI, this.getBrowserAtIndex(i).currentURI)) && (tabs[i] != aTab) ) {
  2532.                 this.removeTab(tabs[i]);
  2533.               }
  2534.             }
  2535.  
  2536.             // remove context tab
  2537.             this.removeTab(aTab);  // remove this line for now as it seems to crash when u select from dropdown menu
  2538.           ]]>
  2539.         </body>
  2540.       </method>
  2541.  
  2542.       <method name="closeAllTabsExceptFromSameSite">
  2543.         <parameter name="aTab"/>
  2544.         <body>
  2545.           <![CDATA[
  2546.             if (aTab.localName != "tab") {
  2547.               aTab = this.mCurrentTab;
  2548.             }
  2549.  
  2550.             var contextBrowser = this.getBrowserForTab(aTab);
  2551.             var browserPanels = this.mPanelContainer.childNodes;
  2552.             var tabs = this.mTabContainer.childNodes;
  2553.  
  2554.             for(var i = tabs.length - 1; i >= 0; --i) {
  2555.               if(!this.compareURISubdomain(contextBrowser.currentURI, this.getBrowserAtIndex(i).currentURI)) {
  2556.                 this.removeTab(tabs[i]);
  2557.               }
  2558.             }
  2559.           ]]>
  2560.         </body>
  2561.       </method>
  2562.  
  2563.       <method name="closeAllBlankTabs">
  2564.         <body>
  2565.           <![CDATA[
  2566.             var tabs = this.mTabContainer.childNodes;
  2567.  
  2568.             for(var i = tabs.length - 1; i >= 0; --i) {
  2569.               if(this.getBrowserForTab(tabs[i]).currentURI.spec == "about:blank") {
  2570.                 this.removeTab(tabs[i]);
  2571.               }
  2572.             }
  2573.           ]]>
  2574.         </body>
  2575.       </method>
  2576.  
  2577.       <method name="appendTabToHomePage">
  2578.         <parameter name="aTab"/>
  2579.         <body>
  2580.           <![CDATA[
  2581.             if (aTab.localName != "tab") {
  2582.               aTab = this.mCurrentTab;
  2583.             }
  2584.  
  2585.             this.mTabContainer.selectedItem = aTab;
  2586.  
  2587.             var homePage = this.mPrefs.getComplexValue("browser.startup.homepage", Components.interfaces.nsIPrefLocalizedString).data;
  2588.             if(homePage) {
  2589.               newHomePage = homePage + "|" + this.getBrowserForTab(aTab).currentURI.spec;
  2590.             } else {
  2591.               newHomePage = this.getBrowserForTab(aTab).currentURI.spec;
  2592.             }
  2593.             this.mPrefs.setCharPref("browser.startup.homepage", newHomePage);
  2594.           ]]>
  2595.         </body>
  2596.       </method>
  2597.  
  2598.       <method name="setTabAsHomePage">
  2599.         <parameter name="aTab"/>
  2600.         <body>
  2601.           <![CDATA[
  2602.             if (aTab.localName != "tab") {
  2603.               aTab = this.mCurrentTab;
  2604.             }
  2605.  
  2606.             this.mTabContainer.selectedItem = aTab;
  2607.  
  2608.             this.mPrefs.setCharPref("browser.startup.homepage", this.getBrowserForTab(aTab).currentURI.spec);
  2609.           ]]>
  2610.         </body>
  2611.       </method>
  2612.  
  2613.       <method name="setAllTabsAsHomePage">
  2614.         <parameter name="aTab"/>
  2615.         <body>
  2616.           <![CDATA[
  2617.             if (aTab.localName != "tab") {
  2618.               aTab = this.mCurrentTab;
  2619.             }
  2620.  
  2621.             var newHPValue = "";
  2622.             var tabs = this.mTabContainer.childNodes;
  2623.             var browsers = this.mPanelContainer.childNodes;
  2624.  
  2625.             this.mTabContainer.selectedItem = aTab;
  2626.  
  2627.             for (var i = 0; i < tabs.length; i++) {
  2628.               if (i) {
  2629.                 newHPValue += '|';
  2630.               }
  2631.               newHPValue += this.getBrowserAtIndex(i).currentURI.spec;
  2632.             }
  2633.             this.mPrefs.setCharPref("browser.startup.homepage", newHPValue);
  2634.           ]]>
  2635.         </body>
  2636.       </method>
  2637.  
  2638.       <method name="onTabBarDblClick">
  2639.         <parameter name="aEvent"/>
  2640.         <body>
  2641.           <![CDATA[
  2642.             if (aEvent.originalTarget.localName != 'tab' && aEvent.button == 0)
  2643.               this.selectedTab = this.addTab();
  2644.           ]]>
  2645.         </body>
  2646.       </method>
  2647.  
  2648.       // we need to call this function whenever tabs are added and remove and
  2649.       // on startup. if there is only one tab, we hide:
  2650.       // tab close button, tabs dropdown menu, tabs close all button
  2651.       <method name="updateChromeWhenLastTab">
  2652.         <body>
  2653.           <![CDATA[
  2654.             var tabs = this.mTabContainer.childNodes;
  2655.             if(tabs.length == 1) {
  2656.               var closebutton = document.getAnonymousElementByAttribute(tabs[0],'anonid','closebutton-box');
  2657.               /*var activemenubutton = document.getAnonymousElementByAttribute(tabs[0],'anonid','activemenubutton');*/
  2658.               if (!closebutton.hasAttribute("hidden")) {
  2659.                 closebutton.setAttribute("hidden", true);
  2660.               }
  2661.               /*if (!activemenubutton.hasAttribute("hidden")) {
  2662.                 activemenubutton.setAttribute("hidden", true);
  2663.               }*/
  2664.               //document.getElementById('cmd_close').setAttribute('disabled', 'true');
  2665.  
  2666.               //document.getAnonymousElementByAttribute(this.mTabContainer,'anonid','tabs-dropdown').setAttribute("hidden", true);
  2667.               //document.getAnonymousElementByAttribute(this.mTabContainer,'anonid','tabs-closeall').setAttribute("hidden", true);
  2668.             } else {
  2669.               var closebutton;
  2670.               var activemenubutton;
  2671.               for (var k = 0; k < tabs.length; k++) {
  2672.                 closebutton = document.getAnonymousElementByAttribute(tabs[k],'anonid','closebutton-box');
  2673.                 /*activemenubutton = document.getAnonymousElementByAttribute(tabs[k],'anonid','activemenubutton');*/
  2674.                 closebutton.removeAttribute("hidden");
  2675.                 /*activemenubutton.removeAttribute("hidden");*/
  2676.               }
  2677.               //document.getElementById('cmd_close').removeAttribute('disabled');
  2678.  
  2679.               //document.getAnonymousElementByAttribute(this.mTabContainer,'anonid','tabs-dropdown').removeAttribute("hidden");
  2680.               //document.getAnonymousElementByAttribute(this.mTabContainer,'anonid','tabs-closeall').removeAttribute("hidden");
  2681.             }
  2682.           ]]>
  2683.         </body>
  2684.       </method>
  2685.       // MERC
  2686.  
  2687.       <method name="addProgressListener">
  2688.         <parameter name="aListener"/>
  2689.         <parameter name="aMask"/>
  2690.         <body>
  2691.           <![CDATA[
  2692.             if (!this.mProgressListeners) {
  2693.               this.mProgressListeners = [];
  2694.               const autoHide = this.mPrefs.getBoolPref("browser.tabs.autoHide");
  2695.               const forceHide = this.mPrefs.getBoolPref("browser.tabs.forceHide");
  2696.               if (!autoHide && !forceHide)
  2697.                 this.setStripVisibilityTo(true);
  2698.  
  2699.               // Hook up a listener for <link>s.
  2700.               this.mPanelContainer.addEventListener("DOMLinkAdded", this.onLinkAdded, false);
  2701.             }
  2702.  
  2703.             if (!this.mTabbedMode && this.mProgressListeners.length == 1) {
  2704.               // If we are adding a 2nd progress listener, we need to enter tabbed mode
  2705.               // because the browser status filter can only handle one progress listener.
  2706.               // In tabbed mode, mTabProgressListener is used which will iterate over all listeners.
  2707.               this.enterTabbedMode();
  2708.             }
  2709.  
  2710.             this.mProgressListeners.push(aListener);
  2711.  
  2712.             if (!this.mTabbedMode) {
  2713.               // If someone does this:
  2714.               // addProgressListener, removeProgressListener, addProgressListener
  2715.               // don't create a new filter; reuse the existing filter.
  2716.               if (this.mTabFilters.length == 0) {
  2717.                 // hook a filter up to our first browser
  2718.                 const filter = Components.classes["@mozilla.org/appshell/component/browser-status-filter;1"]
  2719.                                          .createInstance(Components.interfaces.nsIWebProgress);
  2720.                 this.mTabFilters[0] = filter;
  2721.                 this.mCurrentBrowser.webProgress.addProgressListener(filter, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
  2722.               }
  2723.  
  2724.               // Directly hook the listener up to the filter for better performance
  2725.               this.mTabFilters[0].addProgressListener(aListener, aMask);
  2726.             }
  2727.           ]]>
  2728.         </body>
  2729.       </method>
  2730.  
  2731.       <method name="removeProgressListener">
  2732.         <parameter name="aListener"/>
  2733.         <body>
  2734.           <![CDATA[
  2735.             if (!this.mProgressListeners) return;
  2736.             for (var i = 0; i < this.mProgressListeners.length; i++) {
  2737.               if (this.mProgressListeners[i] == aListener) {
  2738.                 this.mProgressListeners[i] = null;
  2739.                 break;
  2740.               }
  2741.             }
  2742.  
  2743.             if (!this.mTabbedMode)
  2744.               // Don't forget to remove it from the filter we hooked it up to
  2745.               this.mTabFilters[0].removeProgressListener(aListener);
  2746.          ]]>
  2747.         </body>
  2748.       </method>
  2749.  
  2750.       <method name="getBrowserForTab">
  2751.         <parameter name="aTab"/>
  2752.         <body>
  2753.         <![CDATA[
  2754.           if (this.mCurrentTab == aTab)
  2755.             return this.mCurrentBrowser;
  2756.  
  2757.           for (var i = 0; i < this.mTabContainer.childNodes.length; i++) {
  2758.             if (this.mTabContainer.childNodes[i] == aTab) {
  2759.               return this.getBrowserAtIndex(i);
  2760.             }
  2761.           }
  2762.  
  2763.           return null;
  2764.         ]]>
  2765.         </body>
  2766.       </method>
  2767.  
  2768.       <property name="tabContainer">
  2769.         <getter>
  2770.           return this.mTabContainer;
  2771.         </getter>
  2772.       </property>
  2773.  
  2774.       <property name="selectedTab">
  2775.         <getter>
  2776.           return this.mTabBox.selectedTab;
  2777.         </getter>
  2778.         <setter>
  2779.           <![CDATA[
  2780.           // Update the tab
  2781.           this.mTabBox.selectedTab = val;
  2782.           return val;
  2783.           ]]>
  2784.         </setter>
  2785.       </property>
  2786.  
  2787.       <property name="selectedBrowser"
  2788.                 onget="return this.mCurrentBrowser;"
  2789.                 readonly="true"/>
  2790.  
  2791.  
  2792.       <property name="browsers"
  2793.                 onget="return this.mPanelContainer.getElementsByTagName('browser');"
  2794.                 readonly="true"/>
  2795.  
  2796.       <!-- Drag and drop observer API -->
  2797.       <!--<method name="onDragStart">
  2798.         <parameter name="aEvent"/>
  2799.         <parameter name="aXferData"/>
  2800.         <parameter name="aDragAction"/>
  2801.         <body/>
  2802.       </method>-->
  2803.  
  2804.       <method name="onDragOver">
  2805.         <parameter name="aEvent"/>
  2806.         <parameter name="aFlavour"/>
  2807.         <parameter name="aDragSession"/>
  2808.         <body>
  2809.         <![CDATA[
  2810.           return; // Just having this makes our feedback correct.
  2811.         ]]>
  2812.         </body>
  2813.       </method>
  2814.  
  2815.       <method name="onDrop">
  2816.         <parameter name="aEvent"/>
  2817.         <parameter name="aXferData"/>
  2818.         <parameter name="aDragSession"/>
  2819.         <body>
  2820.           <![CDATA[
  2821.             var url = transferUtils.retrieveURLFromData(aXferData.data, aXferData.flavour.contentType);
  2822.  
  2823.             // valid urls don't contain spaces ' '; if we have a space it isn't a valid url.
  2824.             // Also disallow dropping javascript: or data: urls--bail out
  2825.             if (!url || !url.length || url.indexOf(" ", 0) != -1 ||
  2826.                 /^\s*(javascript|data):/.test(url))
  2827.               return;
  2828.  
  2829.             this.dragDropSecurityCheck(aEvent, aDragSession, url);
  2830.  
  2831.             var bgLoad = this.mPrefs.getBoolPref("browser.tabs.loadInBackground");
  2832.  
  2833.             var tab = null;
  2834.             if (aEvent.originalTarget.localName != "tab") {
  2835.               // We're adding a new tab.
  2836.               tab = this.addTabAt(getShortcutOrURI(url));
  2837.             }
  2838.             else {
  2839.               // Load in an existing tab.
  2840.               tab = aEvent.originalTarget;
  2841.               this.getBrowserForTab(tab).loadURI(getShortcutOrURI(url));
  2842.             }
  2843.             if (this.mCurrentTab != tab && !bgLoad)
  2844.               this.selectedTab = tab;
  2845.           ]]>
  2846.         </body>
  2847.       </method>
  2848.  
  2849.       <method name="getSupportedFlavours">
  2850.         <body>
  2851.         <![CDATA[
  2852.           var flavourSet = new FlavourSet();
  2853.           flavourSet.appendFlavour("text/x-moz-url");
  2854.           flavourSet.appendFlavour("text/unicode");
  2855.           flavourSet.appendFlavour("application/x-moz-file", "nsIFile");
  2856.           return flavourSet;
  2857.         ]]>
  2858.         </body>
  2859.       </method>
  2860.                                                                
  2861.       <!-- BEGIN FORWARDED BROWSER PROPERTIES.  IF YOU ADD A PROPERTY TO THE BROWSER ELEMENT
  2862.            MAKE SURE TO ADD IT HERE AS WELL. -->
  2863.       <property name="canGoBack"
  2864.                 onget="return this.mCurrentBrowser.canGoBack;"
  2865.                 readonly="true"/>
  2866.  
  2867.       <property name="canGoForward"
  2868.                 onget="return this.mCurrentBrowser.canGoForward;"
  2869.                 readonly="true"/>
  2870.  
  2871.       <method name="goBack">
  2872.         <body>
  2873.           <![CDATA[
  2874.             return this.mCurrentBrowser.goBack();
  2875.           ]]>
  2876.         </body>
  2877.       </method>
  2878.  
  2879.       <method name="goForward">
  2880.         <body>
  2881.           <![CDATA[
  2882.             return this.mCurrentBrowser.goForward();
  2883.           ]]>
  2884.         </body>
  2885.       </method>
  2886.  
  2887.       <method name="reload">
  2888.         <body>
  2889.           <![CDATA[
  2890.             return this.mCurrentBrowser.reload();
  2891.           ]]>
  2892.         </body>
  2893.       </method>
  2894.  
  2895.       <method name="reloadWithFlags">
  2896.         <parameter name="aFlags"/>
  2897.         <body>
  2898.           <![CDATA[
  2899.             return this.mCurrentBrowser.reloadWithFlags(aFlags);
  2900.           ]]>
  2901.         </body>
  2902.       </method>
  2903.  
  2904.       <method name="stop">
  2905.         <body>
  2906.           <![CDATA[
  2907.             return this.mCurrentBrowser.stop();
  2908.           ]]>
  2909.         </body>
  2910.       </method>
  2911.  
  2912.       <!-- throws exception for unknown schemes -->
  2913.       <method name="loadURI">
  2914.         <parameter name="aURI"/>
  2915.         <parameter name="aReferrerURI"/>
  2916.         <parameter name="aCharset"/>
  2917.         <body>
  2918.           <![CDATA[
  2919.             return this.mCurrentBrowser.loadURI(aURI, aReferrerURI, aCharset);
  2920.           ]]>
  2921.         </body>
  2922.       </method>
  2923.  
  2924.       <!-- throws exception for unknown schemes -->
  2925.       <method name="loadURIWithFlags">
  2926.         <parameter name="aURI"/>
  2927.         <parameter name="aFlags"/>
  2928.         <parameter name="aReferrerURI"/>
  2929.         <parameter name="aCharset"/>
  2930.         <body>
  2931.           <![CDATA[
  2932.             return this.mCurrentBrowser.loadURIWithFlags(aURI, aFlags, aReferrerURI, aCharset);
  2933.           ]]>
  2934.         </body>
  2935.       </method>
  2936.  
  2937.       <method name="goHome">
  2938.         <body>
  2939.           <![CDATA[
  2940.             return this.mCurrentBrowser.goHome();
  2941.           ]]>
  2942.         </body>
  2943.       </method>
  2944.  
  2945.       <property name="homePage">
  2946.         <getter>
  2947.           <![CDATA[
  2948.             return this.mCurrentBrowser.homePage;
  2949.           ]]>
  2950.         </getter>
  2951.         <setter>
  2952.           <![CDATA[
  2953.             this.mCurrentBrowser.homePage = val;
  2954.             return val;
  2955.           ]]>
  2956.         </setter>
  2957.       </property>
  2958.  
  2959.       <method name="gotoIndex">
  2960.         <parameter name="aIndex"/>
  2961.         <body>
  2962.           <![CDATA[
  2963.             return this.mCurrentBrowser.gotoIndex(aIndex);
  2964.           ]]>
  2965.         </body>
  2966.       </method>
  2967.       
  2968.       <method name="attachFormFill">
  2969.         <body><![CDATA[
  2970.           for (var i = 0; i < this.mPanelContainer.childNodes.length; ++i) {
  2971.             var cb = this.getBrowserAtIndex(i);
  2972.             cb.attachFormFill();
  2973.           }
  2974.         ]]></body>
  2975.       </method>
  2976.  
  2977.       <method name="detachFormFill">
  2978.         <body><![CDATA[
  2979.           for (var i = 0; i < this.mPanelContainer.childNodes.length; ++i) {
  2980.             var cb = this.getBrowserAtIndex(i);
  2981.             cb.detachFormFill();
  2982.           }
  2983.         ]]></body>
  2984.       </method>
  2985.  
  2986.       <property name="pageReport"
  2987.                 onget="return this.mCurrentBrowser.pageReport;"
  2988.                 readonly="true"/>
  2989.  
  2990.       <property name="currentURI"
  2991.                 onget="return this.mCurrentBrowser.currentURI;"
  2992.                 readonly="true"/>
  2993.  
  2994.       <field name="_fastFind">null</field>
  2995.       <property name="fastFind"
  2996.                 readonly="true">
  2997.         <getter>
  2998.         <![CDATA[
  2999.           if (!this._fastFind) {
  3000.             this._fastFind = Components.classes["@mozilla.org/typeaheadfind;1"]
  3001.                                        .createInstance(Components.interfaces.nsITypeAheadFind);                                
  3002.             this._fastFind.init(this.docShell);
  3003.           }
  3004.           return this._fastFind;
  3005.         ]]>
  3006.         </getter>
  3007.       </property>
  3008.                       
  3009.       <property name="findString"
  3010.                 onget="return this.mCurrentBrowser.findString;"
  3011.                 readonly="true"/>
  3012.                 
  3013.       <property name="docShell"
  3014.                 onget="return this.mCurrentBrowser.docShell"
  3015.                 readonly="true"/>
  3016.  
  3017.       <property name="webNavigation"
  3018.                 onget="return this.mCurrentBrowser.webNavigation"
  3019.                 readonly="true"/>
  3020.  
  3021.       <property name="webBrowserFind"
  3022.                 readonly="true"
  3023.                 onget="return this.mCurrentBrowser.webBrowserFind"/>
  3024.  
  3025.       <property name="webProgress"
  3026.                 readonly="true"
  3027.                 onget="return this.mCurrentBrowser.webProgress"/>
  3028.  
  3029.       <property name="contentWindow"
  3030.                 readonly="true"
  3031.                 onget="return this.mCurrentBrowser.contentWindow"/>
  3032.  
  3033.       <property name="sessionHistory"
  3034.                 onget="return this.mCurrentBrowser.sessionHistory;"
  3035.                 readonly="true"/>
  3036.  
  3037.       <property name="markupDocumentViewer"
  3038.                 onget="return this.mCurrentBrowser.markupDocumentViewer;"
  3039.                 readonly="true"/>
  3040.  
  3041.       <property name="contentViewerEdit"
  3042.                 onget="return this.mCurrentBrowser.contentViewerEdit;"
  3043.                 readonly="true"/>
  3044.  
  3045.       <property name="contentViewerFile"
  3046.                 onget="return this.mCurrentBrowser.contentViewerFile;"
  3047.                 readonly="true"/>
  3048.  
  3049.       <property name="documentCharsetInfo"
  3050.                 onget="return this.mCurrentBrowser.documentCharsetInfo;"
  3051.                 readonly="true"/>
  3052.  
  3053.       <property name="contentDocument"
  3054.                 onget="return this.mCurrentBrowser.contentDocument;"
  3055.                 readonly="true"/>
  3056.  
  3057.       <property name="contentTitle"
  3058.                 onget="return this.mCurrentBrowser.contentTitle;"
  3059.                 readonly="true"/>
  3060.  
  3061.       <property name="securityUI"
  3062.                 onget="return this.mCurrentBrowser.securityUI;"
  3063.                 readonly="true"/>
  3064.  
  3065.       <method name="find">
  3066.         <body>
  3067.           <![CDATA[
  3068.             return this.mCurrentBrowser.find();
  3069.           ]]>
  3070.         </body>
  3071.       </method>
  3072.  
  3073.       <method name="findAgain">
  3074.         <body>
  3075.           <![CDATA[
  3076.             return this.mCurrentBrowser.findAgain();
  3077.           ]]>
  3078.         </body>
  3079.       </method>
  3080.  
  3081.       <method name="findPrevious">
  3082.         <body>
  3083.           <![CDATA[
  3084.             return this.mCurrentBrowser.findPrevious();
  3085.           ]]>
  3086.         </body>
  3087.       </method>
  3088.  
  3089.       <method name="dragDropSecurityCheck">
  3090.         <parameter name="aEvent"/>
  3091.         <parameter name="aDragSession"/>
  3092.         <parameter name="aUrl"/>
  3093.         <body>
  3094.           <![CDATA[
  3095.             // Do a security check for drag n' drop. Make sure the
  3096.             // source document can load the dragged link.
  3097.             var sourceDoc = aDragSession.sourceDocument;
  3098.  
  3099.             if (sourceDoc) {
  3100.               var sourceURI = sourceDoc.documentURI;
  3101.  
  3102.               const nsIScriptSecurityManager =
  3103.                 Components.interfaces.nsIScriptSecurityManager;
  3104.               var secMan =
  3105.                 Components.classes["@mozilla.org/scriptsecuritymanager;1"]
  3106.                 .getService(nsIScriptSecurityManager);
  3107.  
  3108.               try {
  3109.                 secMan.checkLoadURIStr(sourceURI, aUrl,
  3110.                                        nsIScriptSecurityManager.STANDARD);
  3111.               } catch (e) {
  3112.                 // Stop even propagation right here.
  3113.                 aEvent.stopPropagation();
  3114.  
  3115.                 throw "Drop of " + aUrl + " denied.";
  3116.               }
  3117.             }
  3118.           ]]>
  3119.         </body>
  3120.       </method>
  3121.  
  3122.       <field name="_keyEventHandler" readonly="true">
  3123.       <![CDATA[({
  3124.         tabbrowser: this,
  3125.         handleEvent: function handleEvent(aEvent) {
  3126.       if (!aEvent.isTrusted) {
  3127.         // Don't let untrusted events mess with tabs.
  3128.         return;
  3129.       }
  3130.  
  3131.           if (aEvent.ctrlKey && aEvent.keyCode == KeyEvent.DOM_VK_F4 &&
  3132.                             this.tabbrowser.mTabBox.handleCtrlPageUpDown)
  3133.             this.tabbrowser.removeCurrentTab();
  3134.         }
  3135.       })]]>
  3136.       </field>
  3137.  
  3138.       <property name="canFindAgain"
  3139.                 onget="return this.mCurrentBrowser.canFindAgain;"
  3140.                 readonly="true"/>
  3141.  
  3142.       <property name="userTypedClear"
  3143.                 onget="return this.mCurrentBrowser.userTypedClear;"
  3144.                 onset="return this.mCurrentBrowser.userTypedClear = val;"/>
  3145.  
  3146.       <property name="userTypedValue"
  3147.                 onget="return this.mCurrentBrowser.userTypedValue;"
  3148.                 onset="return this.mCurrentBrowser.userTypedValue = val;"/>
  3149.  
  3150.       <property name="forceSyncURLBarUpdate"
  3151.                 onget="return this.mModalDialogShowing;"/>
  3152.  
  3153.       <!-- MERC - JCH : needed for counting blocked popups -->
  3154.       <property name="numberBlocked"
  3155.                 onget="return this.getAttribute('numberBlocked');"
  3156.                 onset="this.setAttribute('numberBlocked', val); return val;"/>
  3157.  
  3158.       <constructor>
  3159.         <![CDATA[
  3160.           this.mCurrentBrowser = this.getBrowserAtIndex(0);
  3161.           this.mCurrentTab = this.mTabContainer.firstChild;
  3162.           this.setAttribute("numberBlocked", "0");
  3163.           document.addEventListener("keypress", this._keyEventHandler, false);
  3164.         ]]>
  3165.       </constructor>
  3166.  
  3167.       <destructor>
  3168.         <![CDATA[
  3169.           for (var i = 0; i < this.mTabListeners.length; ++i) {
  3170.             this.getBrowserAtIndex(i).webProgress.removeProgressListener(this.mTabFilters[i]);
  3171.             this.mTabFilters[i].removeProgressListener(this.mTabListeners[i]);
  3172.             this.mTabFilters[i] = null;
  3173.             this.mTabListeners[i] = null;
  3174.             this.getBrowserAtIndex(i).removeEventListener("DOMTitleChanged", this.onTitleChanged, false);
  3175.           }
  3176.           this.mPanelContainer.removeEventListener("DOMLinkAdded", this.onLinkAdded, false);
  3177.           document.removeEventListener("keypress", this._keyEventHandler, false);
  3178.         ]]>
  3179.       </destructor>
  3180.     </implementation>
  3181.  
  3182.     <handlers>
  3183.       <handler event="DOMWindowClose">
  3184.         <![CDATA[
  3185.           if (!event.isTrusted)
  3186.             return;
  3187.  
  3188.           const browsers = this.mPanelContainer.childNodes;
  3189.           if (browsers.length == 1) {
  3190.             // There's only one browser left. If a window is being
  3191.             // closed and the window is *not* the window in the
  3192.             // browser that's still around, prevent the event's default
  3193.             // action to prevent closing a window that's being closed
  3194.             // already.
  3195.             if (this.getBrowserAtIndex(0).contentWindow != event.target)
  3196.               event.preventDefault();
  3197.  
  3198.             return;
  3199.           }
  3200.  
  3201.           for (var i = 0; i < browsers.length; ++i) {
  3202.             if (this.getBrowserAtIndex(i).contentWindow == event.target) {
  3203.               this.removeTab(this.mTabContainer.childNodes[i]);
  3204.               //JA event.preventDefault();
  3205.               break;
  3206.             }
  3207.           }
  3208.  
  3209.           // JA tmp fix for bug 403: always prevent .close() from script if
  3210.           // target window was not found : as it happens when tab gets
  3211.           // removed by clicking on [x] or dblclick
  3212.           event.preventDefault();
  3213.         ]]>
  3214.       </handler>
  3215.       <handler event="DOMWillOpenModalDialog">
  3216.         <![CDATA[
  3217.           if (!event.isTrusted)
  3218.             return;
  3219.  
  3220.           // We're about to open a modal dialog, make sure the opening
  3221.           // tab is brought to the front.
  3222.  
  3223.           for (var i = 0; i < browsers.length; ++i) {
  3224.             if (this.getBrowserAtIndex(i).contentWindow == event.target) {
  3225.               this.mModalDialogShowing = true;
  3226.               this.selectedTab = this.mTabContainer.childNodes[i];
  3227.  
  3228.               break;
  3229.             }
  3230.           }
  3231.         ]]>
  3232.       </handler>
  3233.       <handler event="DOMModalDialogClosed">
  3234.         <![CDATA[
  3235.           if (!event.isTrusted)
  3236.             return;
  3237.  
  3238.           this.mModalDialogShowing = false;
  3239.         ]]>
  3240.       </handler>
  3241.     </handlers>
  3242.   </binding>
  3243.  
  3244. </bindings>