home *** CD-ROM | disk | FTP | other *** search
/ ftp.swcp.com / ftp.swcp.com.zip / ftp.swcp.com / mac / mozilla-macos9-1.3.1.sea.bin / Mozilla1.3.1 / Chrome / comm.jar / content / navigator / navigator.js < prev    next >
Text File  |  2003-06-08  |  71KB  |  2,181 lines

  1. /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* ***** BEGIN LICENSE BLOCK *****
  3.  * Version: NPL 1.1/GPL 2.0/LGPL 2.1
  4.  *
  5.  * The contents of this file are subject to the Netscape Public License
  6.  * Version 1.1 (the "License"); you may not use this file except in
  7.  * compliance with the License. You may obtain a copy of the License at
  8.  * http://www.mozilla.org/NPL/
  9.  *
  10.  * Software distributed under the License is distributed on an "AS IS" basis,
  11.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12.  * for the specific language governing rights and limitations under the
  13.  * License.
  14.  *
  15.  * The Original Code is mozilla.org code.
  16.  *
  17.  * The Initial Developer of the Original Code is 
  18.  * Netscape Communications Corporation.
  19.  * Portions created by the Initial Developer are Copyright (C) 1998
  20.  * the Initial Developer. All Rights Reserved.
  21.  *
  22.  * Contributor(s):
  23.  *   Blake Ross <blakeross@telocity.com>
  24.  *   Peter Annema <disttsc@bart.nl>
  25.  *   Dean Tessman <dean_tessman@hotmail.com>
  26.  *
  27.  * Alternatively, the contents of this file may be used under the terms of
  28.  * either the GNU General Public License Version 2 or later (the "GPL"), or 
  29.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  30.  * in which case the provisions of the GPL or the LGPL are applicable instead
  31.  * of those above. If you wish to allow use of your version of this file only
  32.  * under the terms of either the GPL or the LGPL, and not to allow others to
  33.  * use your version of this file under the terms of the NPL, indicate your
  34.  * decision by deleting the provisions above and replace them with the notice
  35.  * and other provisions required by the GPL or the LGPL. If you do not delete
  36.  * the provisions above, a recipient may use your version of this file under
  37.  * the terms of any one of the NPL, the GPL or the LGPL.
  38.  *
  39.  * ***** END LICENSE BLOCK ***** */
  40.  
  41. const XREMOTESERVICE_CONTRACTID = "@mozilla.org/browser/xremoteservice;1";
  42. var gURLBar = null;
  43. var gProxyButton = null;
  44. var gProxyFavIcon = null;
  45. var gProxyDeck = null;
  46. var gBookmarksService = null;
  47. var gSearchService = null;
  48. var gNavigatorBundle;
  49. var gBrandBundle;
  50. var gNavigatorRegionBundle;
  51. var gBrandRegionBundle;
  52. var gLastValidURLStr = "";
  53. var gLastValidURL = null;
  54. var gHaveUpdatedToolbarState = false;
  55. var gClickSelectsAll = false;
  56. var gIgnoreFocus = false;
  57. var gIgnoreClick = false;
  58. var gURIFixup = null;
  59.  
  60. var pref = null;
  61.  
  62. var appCore = null;
  63.  
  64. //cached elements
  65. var gBrowser = null;
  66.  
  67. // focused frame URL
  68. var gFocusedURL = null;
  69. var gFocusedDocument = null;
  70.  
  71. // Pref listener constants
  72. const gButtonPrefListener =
  73. {
  74.   domain: "browser.toolbars.showbutton",
  75.   observe: function(subject, topic, prefName)
  76.   {
  77.     // verify that we're changing a button pref
  78.     if (topic != "nsPref:changed")
  79.       return;
  80.  
  81.     var buttonName = prefName.substr(this.domain.length+1);
  82.     var buttonId = buttonName + "-button";
  83.     var button = document.getElementById(buttonId);
  84.  
  85.     // We need to explicitly set "hidden" to "false"
  86.     // in order for persistence to work correctly
  87.     var show = pref.getBoolPref(prefName);
  88.     if (show)
  89.       button.setAttribute("hidden","false");
  90.     else
  91.       button.setAttribute("hidden", "true");
  92.  
  93.     // If all buttons before the separator are hidden, also hide the separator
  94.     if (allLeftButtonsAreHidden())
  95.       document.getElementById("home-bm-separator").setAttribute("hidden", "true");
  96.     else
  97.       document.getElementById("home-bm-separator").removeAttribute("hidden");
  98.   }
  99. };
  100.  
  101. const gTabStripPrefListener =
  102. {
  103.   domain: "browser.tabs.autoHide",
  104.   observe: function(subject, topic, prefName)
  105.   {
  106.     // verify that we're changing the tab browser strip auto hide pref
  107.     if (topic != "nsPref:changed")
  108.       return;
  109.  
  110.     var stripVisibility = !pref.getBoolPref(prefName);
  111.     if (gBrowser.mTabContainer.childNodes.length == 1) {
  112.       gBrowser.setStripVisibilityTo(stripVisibility);
  113.       pref.setBoolPref("browser.tabs.forceHide", false);
  114.     }
  115.   }
  116. };
  117.  
  118. const gHomepagePrefListener =
  119. {
  120.   domain: "browser.startup.homepage",
  121.   observe: function(subject, topic, prefName)
  122.   {
  123.     // verify that we're changing the home page pref
  124.     if (topic != "nsPref:changed")
  125.       return;
  126.  
  127.     updateHomeButtonTooltip();
  128.   }
  129. };
  130.  
  131. // popup window permission change listener
  132. const gPopupPermListener = {
  133.  
  134.   observe: function(subject, topic, data) {
  135.     if (topic == "popup-perm-close") {
  136.       // close the window if we're a popup and our opener's URI matches
  137.       // the URI in the notification
  138.       var popupOpenerURI = maybeInitPopupContext();
  139.       if (popupOpenerURI) {
  140.         const IOS = Components.classes["@mozilla.org/network/io-service;1"]
  141.                     .getService(Components.interfaces.nsIIOService);
  142.         closeURI = IOS.newURI(data, null, null);
  143.         if (closeURI.host == popupOpenerURI.host)
  144.           window.close();
  145.       }
  146.     }
  147.   }
  148. };
  149.  
  150. const POPUP_TYPE = 2;
  151. const gPopupPrefListener =
  152. {
  153.   domain: "dom.disable_open_during_load",
  154.   observe: function(subject, topic, prefName)
  155.   {        
  156.     if (topic != "nsPref:changed" || prefName != this.domain)
  157.       return;
  158.  
  159.     var browsers = getBrowser().browsers;
  160.     var policy = pref.getBoolPref(prefName);
  161.  
  162.     var hosts = [];
  163.  
  164.     var popupManager = Components.classes["@mozilla.org/PopupWindowManager;1"]
  165.                                  .getService(Components.interfaces.nsIPopupWindowManager);
  166.     
  167.     var enumerator = popupManager.getEnumerator();
  168.     var count=0;
  169.     while (enumerator.hasMoreElements()) {
  170.       var permission = enumerator.getNext()
  171.                                  .QueryInterface(Components.interfaces.nsIPermission);
  172.       if (permission.capability == policy)
  173.         hosts[permission.host] = permission.host;
  174.     }
  175.  
  176.     var popupIcon = document.getElementById("popupIcon");
  177.     
  178.     if (!policy) { // blacklist
  179.       for (var i = 0; i < browsers.length; i++) {
  180.         if (browsers[i].popupDomain in hosts)
  181.           break;
  182.         browsers[i].popupDomain = null;
  183.         popupIcon.hidden = true;
  184.       }
  185.     } else { // whitelist
  186.       for (var i = 0; i < browsers.length; i++) {
  187.         if (browsers[i].popupDomain in hosts) {
  188.           browsers[i].popupDomain = null;
  189.           popupIcon.hidden = true;
  190.         }
  191.       }
  192.     }
  193.   }
  194. };
  195.  
  196. /**
  197. * Pref listener handler functions.
  198. * Both functions assume that observer.domain is set to 
  199. * the pref domain we want to start/stop listening to.
  200. */
  201. function addPrefListener(observer)
  202. {
  203.   try {
  204.     var pbi = pref.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
  205.     pbi.addObserver(observer.domain, observer, false);
  206.   } catch(ex) {
  207.     dump("Failed to observe prefs: " + ex + "\n");
  208.   }
  209. }
  210.  
  211. function removePrefListener(observer)
  212. {
  213.   try {
  214.     var pbi = pref.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
  215.     pbi.removeObserver(observer.domain, observer);
  216.   } catch(ex) {
  217.     dump("Failed to remove pref observer: " + ex + "\n");
  218.   }
  219. }
  220.  
  221. function addPopupPermListener(observer)
  222. {
  223.   const OS = Components.classes["@mozilla.org/observer-service;1"]
  224.              .getService(Components.interfaces.nsIObserverService);
  225.   OS.addObserver(observer, "popup-perm-close", false);
  226. }
  227.  
  228. function removePopupPermListener(observer)
  229. {
  230.   const OS = Components.classes["@mozilla.org/observer-service;1"]
  231.              .getService(Components.interfaces.nsIObserverService);
  232.   OS.removeObserver(observer, "popup-perm-close");
  233. }
  234.  
  235. /**
  236. * We can avoid adding multiple load event listeners and save some time by adding
  237. * one listener that calls all real handlers.
  238. */
  239.  
  240. function loadEventHandlers(event)
  241. {
  242.   // Filter out events that are not about the document load we are interested in
  243.   if (event.originalTarget == _content.document) {
  244.     UpdateBookmarksLastVisitedDate(event);
  245.     UpdateInternetSearchResults(event);
  246.     checkForDirectoryListing();
  247.     postURLToNativeWidget();
  248.   }
  249. }
  250.  
  251. /**
  252.  * Determine whether or not the content area is displaying a page with frames,
  253.  * and if so, toggle the display of the 'save frame as' menu item.
  254.  **/
  255. function getContentAreaFrameCount()
  256. {
  257.   var saveFrameItem = document.getElementById("savepage");
  258.   if (!content || !content.frames.length || !isContentFrame(document.commandDispatcher.focusedWindow))
  259.     saveFrameItem.setAttribute("hidden", "true");
  260.   else
  261.     saveFrameItem.removeAttribute("hidden");
  262. }
  263.  
  264. // When a content area frame is focused, update the focused frame URL
  265. function contentAreaFrameFocus()
  266. {
  267.   var focusedWindow = document.commandDispatcher.focusedWindow;
  268.   if (isContentFrame(focusedWindow)) {
  269.     gFocusedURL = Components.lookupMethod(focusedWindow, 'location').call(focusedWindow).href;
  270.     gFocusedDocument = focusedWindow.document;
  271.   }
  272. }
  273.  
  274. function updateHomeButtonTooltip()
  275. {
  276.   const XUL_NAMESPACE = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
  277.   var homePage = getHomePage();
  278.   var tooltip = document.getElementById("home-button-tooltip-inner");
  279.  
  280.   while (tooltip.firstChild)
  281.     tooltip.removeChild(tooltip.firstChild);
  282.  
  283.   for (var i in homePage) {
  284.     var label = document.createElementNS(XUL_NAMESPACE, "label");
  285.     label.setAttribute("value", homePage[i]);
  286.     tooltip.appendChild(label);
  287.   }
  288. }
  289.  
  290. //////////////////////////////// BOOKMARKS ////////////////////////////////////
  291.  
  292. function UpdateBookmarksLastVisitedDate(event)
  293. {
  294.   var url = getWebNavigation().currentURI.spec;
  295.   if (url) {
  296.     // if the URL is bookmarked, update its "Last Visited" date
  297.     if (!gBookmarksService)
  298.       gBookmarksService = Components.classes["@mozilla.org/browser/bookmarks-service;1"]
  299.                                     .getService(Components.interfaces.nsIBookmarksService);
  300.  
  301.     gBookmarksService.updateLastVisitedDate(url, _content.document.characterSet);
  302.   }
  303. }
  304.  
  305. function HandleBookmarkIcon(iconURL, addFlag)
  306. {
  307.   var url = getWebNavigation().currentURI.spec
  308.   if (url) {
  309.     // update URL with new icon reference
  310.     if (!gBookmarksService)
  311.       gBookmarksService = Components.classes["@mozilla.org/browser/bookmarks-service;1"]
  312.                                     .getService(Components.interfaces.nsIBookmarksService);
  313.     if (addFlag)    gBookmarksService.updateBookmarkIcon(url, iconURL);
  314.     else            gBookmarksService.removeBookmarkIcon(url, iconURL);
  315.   }
  316. }
  317.  
  318. function UpdateInternetSearchResults(event)
  319. {
  320.   var url = getWebNavigation().currentURI.spec;
  321.   if (url) {
  322.     try {
  323.       var autoOpenSearchPanel = 
  324.         pref.getBoolPref("browser.search.opensidebarsearchpanel");
  325.  
  326.       if (autoOpenSearchPanel || isSearchPanelOpen())
  327.       {
  328.         if (!gSearchService)
  329.           gSearchService = Components.classes["@mozilla.org/rdf/datasource;1?name=internetsearch"]
  330.                                          .getService(Components.interfaces.nsIInternetSearchService);
  331.  
  332.         var searchInProgressFlag = gSearchService.FindInternetSearchResults(url);
  333.  
  334.         if (searchInProgressFlag) {
  335.           if (autoOpenSearchPanel)
  336.             RevealSearchPanel();
  337.         }
  338.       }
  339.     } catch (ex) {
  340.     }
  341.   }
  342. }
  343.  
  344. function getBrowser()
  345. {
  346.   if (!gBrowser)
  347.     gBrowser = document.getElementById("content");
  348.   return gBrowser;
  349. }
  350.  
  351. function getHomePage()
  352. {
  353.   var URIs = [];
  354.   try {
  355.     URIs[0] = pref.getComplexValue("browser.startup.homepage",
  356.                                    Components.interfaces.nsIPrefLocalizedString).data;
  357.     var count = pref.getIntPref("browser.startup.homepage.count");
  358.     for (var i = 1; i < count; ++i) {
  359.       URIs[i] = pref.getComplexValue("browser.startup.homepage."+i,
  360.                                      Components.interfaces.nsIPrefLocalizedString).data;
  361.     }
  362.   } catch(e) {
  363.   }
  364.  
  365.   return URIs;
  366. }
  367.  
  368. function UpdateBackForwardButtons()
  369. {
  370.   var backBroadcaster = document.getElementById("canGoBack");
  371.   var forwardBroadcaster = document.getElementById("canGoForward");
  372.   var webNavigation = getWebNavigation();
  373.  
  374.   // Avoid setting attributes on broadcasters if the value hasn't changed!
  375.   // Remember, guys, setting attributes on elements is expensive!  They
  376.   // get inherited into anonymous content, broadcast to other widgets, etc.!
  377.   // Don't do it if the value hasn't changed! - dwh
  378.  
  379.   var backDisabled = backBroadcaster.hasAttribute("disabled");
  380.   var forwardDisabled = forwardBroadcaster.hasAttribute("disabled");
  381.   if (backDisabled == webNavigation.canGoBack) {
  382.     if (backDisabled)
  383.       backBroadcaster.removeAttribute("disabled");
  384.     else
  385.       backBroadcaster.setAttribute("disabled", true);
  386.   }
  387.   if (forwardDisabled == webNavigation.canGoForward) {
  388.     if (forwardDisabled)
  389.       forwardBroadcaster.removeAttribute("disabled");
  390.     else
  391.       forwardBroadcaster.setAttribute("disabled", true);
  392.   }
  393. }
  394.  
  395. // Function allLeftButtonsAreHidden
  396. // Returns true if all the buttons left of the separator in the personal
  397. // toolbar are hidden, false otherwise.
  398. // Used by nsButtonPrefListener to hide the separator if needed
  399. function allLeftButtonsAreHidden()
  400. {
  401.   var buttonNode = document.getElementById("home-bm-separator").previousSibling;
  402.   while (buttonNode) {
  403.     if (buttonNode.localName != "tooltip" && !buttonNode.hidden)
  404.       return false;
  405.     buttonNode = buttonNode.previousSibling;
  406.   }
  407.   return true;
  408. }
  409.  
  410. function RegisterTabOpenObserver()
  411. {
  412.   const observer = {
  413.     observe: function(subject, topic, data)
  414.     {
  415.       if (topic != "open-new-tab-request" || subject != window)
  416.         return;
  417.  
  418.       delayedOpenTab(data);
  419.     }
  420.   };
  421.  
  422.   var service = Components.classes["@mozilla.org/observer-service;1"]
  423.     .getService(Components.interfaces.nsIObserverService);
  424.   service.addObserver(observer, "open-new-tab-request", false);
  425.   // Null out service variable so the closure of the observer doesn't
  426.   // own the service and create a cycle (bug 170022).
  427.   service = null;
  428. }
  429.  
  430. function Startup()
  431. {
  432.   // init globals
  433.   gNavigatorBundle = document.getElementById("bundle_navigator");
  434.   gBrandBundle = document.getElementById("bundle_brand");
  435.   gNavigatorRegionBundle = document.getElementById("bundle_navigator_region");
  436.   gBrandRegionBundle = document.getElementById("bundle_brand_region");
  437.  
  438.   gBrowser = document.getElementById("content");
  439.   gURLBar = document.getElementById("urlbar");
  440.   
  441.   SetPageProxyState("invalid", null);
  442.  
  443.   var webNavigation;
  444.   try {
  445.     // Create the browser instance component.
  446.     appCore = Components.classes["@mozilla.org/appshell/component/browser/instance;1"]
  447.                         .createInstance(Components.interfaces.nsIBrowserInstance);
  448.     if (!appCore)
  449.       throw "couldn't create a browser instance";
  450.  
  451.     // Get the preferences service
  452.     var prefService = Components.classes["@mozilla.org/preferences-service;1"]
  453.                                 .getService(Components.interfaces.nsIPrefService);
  454.     pref = prefService.getBranch(null);
  455.  
  456.     webNavigation = getWebNavigation();
  457.     if (!webNavigation)
  458.       throw "no XBL binding for browser";
  459.   } catch (e) {
  460.     alert("Error launching browser window:" + e);
  461.     window.close(); // Give up.
  462.     return;
  463.   }
  464.  
  465.   // Do all UI building here:
  466.  
  467.   // set home button tooltip text
  468.   updateHomeButtonTooltip();
  469.  
  470.   // initialize observers and listeners
  471.   window.XULBrowserWindow = new nsBrowserStatusHandler();
  472.  
  473.   addPrefListener(gButtonPrefListener); 
  474.   addPrefListener(gTabStripPrefListener);
  475.   addPrefListener(gHomepagePrefListener);
  476.   addPopupPermListener(gPopupPermListener);
  477.   addPrefListener(gPopupPrefListener);
  478.  
  479.   window.browserContentListener =
  480.     new nsBrowserContentListener(window, getBrowser());
  481.   
  482.   // Initialize browser instance..
  483.   appCore.setWebShellWindow(window);
  484.  
  485.   // Add a capturing event listener to the content area
  486.   // (rjc note: not the entire window, otherwise we'll get sidebar pane loads too!)
  487.   //  so we'll be notified when onloads complete.
  488.   var contentArea = document.getElementById("appcontent");
  489.   contentArea.addEventListener("load", loadEventHandlers, true);
  490.   contentArea.addEventListener("focus", contentAreaFrameFocus, true);
  491.  
  492.   var turboMode = false;
  493.   // set default character set if provided
  494.   if ("arguments" in window && window.arguments.length > 1 && window.arguments[1]) {
  495.     if (window.arguments[1].indexOf("charset=") != -1) {
  496.       var arrayArgComponents = window.arguments[1].split("=");
  497.       if (arrayArgComponents) {
  498.         //we should "inherit" the charset menu setting in a new window
  499.         getMarkupDocumentViewer().defaultCharacterSet = arrayArgComponents[1];
  500.       }
  501.     } else if (window.arguments[1].indexOf("turbo=yes") != -1) {
  502.       turboMode = true;
  503.     }
  504.   }
  505.  
  506.   //initConsoleListener();
  507.  
  508.   // XXXjag work-around for bug 113076
  509.   // there's another bug where we throw an exception when getting
  510.   // sessionHistory if it is null, which I'm exploiting here to
  511.   // detect the situation described in bug 113076.
  512.   // The same problem caused bug 139522, also worked around below.
  513.   try {
  514.     getBrowser().sessionHistory;
  515.   } catch (e) {
  516.     // sessionHistory wasn't set from the browser's constructor
  517.     // so we'll just have to set it here.
  518.  
  519.     // Wire up session and global history before any possible
  520.     // progress notifications for back/forward button updating
  521.     webNavigation.sessionHistory = Components.classes["@mozilla.org/browser/shistory;1"]
  522.                                              .createInstance(Components.interfaces.nsISHistory);
  523.  
  524.     // wire up global history.  the same applies here.
  525.     var globalHistory = Components.classes["@mozilla.org/browser/global-history;1"]
  526.                                   .getService(Components.interfaces.nsIGlobalHistory);
  527.     getBrowser().docShell.QueryInterface(Components.interfaces.nsIDocShellHistory).globalHistory = globalHistory;
  528.  
  529.     const selectedBrowser = getBrowser().selectedBrowser;
  530.     if (selectedBrowser.securityUI)
  531.       selectedBrowser.securityUI.init(selectedBrowser.contentWindow);
  532.   }
  533.  
  534.   // hook up UI through progress listener
  535.   getBrowser().addProgressListener(window.XULBrowserWindow, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
  536.  
  537.   // load appropriate initial page from commandline
  538.   var isPageCycling = false;
  539.  
  540.   // page cycling for tinderbox tests
  541.   if (!appCore.cmdLineURLUsed)
  542.     isPageCycling = appCore.startPageCycler();
  543.  
  544.   // only load url passed in when we're not page cycling
  545.   if (!isPageCycling) {
  546.     var uriToLoad;
  547.  
  548.     // Check for window.arguments[0]. If present, use that for uriToLoad.
  549.     if ("arguments" in window && window.arguments.length >= 1 && window.arguments[0]) {
  550.       var uriArray = window.arguments[0].toString().split('\n'); // stringify and split
  551.       uriToLoad = uriArray.splice(0, 1)[0];
  552.       if (uriArray.length > 0)
  553.         window.setTimeout(function(arg) { for (var i in arg) gBrowser.addTab(arg[i]); }, 0, uriArray);
  554.     }
  555.     
  556.     if (uriToLoad && uriToLoad != "about:blank") {
  557.       gURLBar.value = uriToLoad;
  558.       if ("arguments" in window && window.arguments.length >= 3) {
  559.         loadURI(uriToLoad, window.arguments[2]);
  560.       } else {
  561.         loadURI(uriToLoad);
  562.       }
  563.     }
  564.  
  565.     // Close the window now, if it's for turbo mode startup.
  566.     if ( turboMode ) {
  567.         // Set "command line used" flag.  If we don't do this, then when a cmd line url
  568.         // for a "real* invocation comes in, we will override it with the "cmd line url"
  569.         // from the turbo-mode process (i.e., the home page).
  570.         appCore.cmdLineURLUsed = true;
  571.         // For some reason, window.close() directly doesn't work, so do it in the future.
  572.         window.setTimeout( "window.close()", 100 );
  573.         return;
  574.     }
  575.  
  576.     // Focus the content area unless we're loading a blank page
  577.     var navBar = document.getElementById("nav-bar");
  578.     if (uriToLoad == "about:blank" && !navBar.hidden && window.locationbar.visible)
  579.       setTimeout(WindowFocusTimerCallback, 0, gURLBar);
  580.     else
  581.       setTimeout(WindowFocusTimerCallback, 0, _content);
  582.  
  583.     // Perform default browser checking (after window opens).
  584.     setTimeout( checkForDefaultBrowser, 0 );
  585.  
  586.     // hook up remote support
  587.     if (XREMOTESERVICE_CONTRACTID in Components.classes) {
  588.       var remoteService;
  589.       remoteService = Components.classes[XREMOTESERVICE_CONTRACTID]
  590.                                 .getService(Components.interfaces.nsIXRemoteService);
  591.       remoteService.addBrowserInstance(window);
  592.  
  593.       RegisterTabOpenObserver();
  594.     }
  595.   }
  596.   
  597.   // called when we go into full screen, even if it is 
  598.   // initiated by a web page script
  599.   addEventListener("fullscreen", onFullScreen, false);
  600.  
  601.   addEventListener("DOMPopupBlocked", onPopupBlocked, false);
  602.  
  603.   // does clicking on the urlbar select its contents?
  604.   gClickSelectsAll = pref.getBoolPref("browser.urlbar.clickSelectsAll");
  605.  
  606.   // now load bookmarks after a delay
  607.   setTimeout(LoadBookmarksCallback, 0);
  608. }
  609.  
  610. function LoadBookmarksCallback()
  611. {
  612.   try {
  613.     if (!gBookmarksService)
  614.       gBookmarksService = Components.classes["@mozilla.org/browser/bookmarks-service;1"]
  615.                                     .getService(Components.interfaces.nsIBookmarksService);
  616.     gBookmarksService.ReadBookmarks();
  617.     // tickle personal toolbar to load personal toolbar items
  618.     var personalToolbar = document.getElementById("NC:PersonalToolbarFolder");
  619.     personalToolbar.builder.rebuild();
  620.   } catch (e) {
  621.   }
  622. }
  623.  
  624. function WindowFocusTimerCallback(element)
  625. {
  626.   // This fuction is a redo of the fix for jag bug 91884
  627.   var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
  628.                      .getService(Components.interfaces.nsIWindowWatcher);
  629.   if (window == ww.activeWindow) {
  630.     element.focus();
  631.   } else {
  632.     // set the element in command dispatcher so focus will restore properly
  633.     // when the window does become active
  634.     if (element instanceof Components.interfaces.nsIDOMElement)
  635.       document.commandDispatcher.focusedElement = element;
  636.     else if (element instanceof Components.interfaces.nsIDOMWindow)
  637.       document.commandDispatcher.focusedWindow = element;
  638.   }
  639. }
  640.  
  641. function BrowserFlushBookmarksAndHistory()
  642. {
  643.   // Flush bookmarks and history (used when window closes or is cached).
  644.   try {
  645.     // If bookmarks are dirty, flush 'em to disk
  646.     var bmks = Components.classes["@mozilla.org/browser/bookmarks-service;1"]
  647.                          .getService(Components.interfaces.nsIRDFRemoteDataSource);
  648.     bmks.Flush();
  649.  
  650.     // give history a chance at flushing to disk also
  651.     var history = Components.classes["@mozilla.org/browser/global-history;1"]
  652.                             .getService(Components.interfaces.nsIRDFRemoteDataSource);
  653.     history.Flush();
  654.   } catch(ex) {
  655.   }
  656. }
  657.  
  658. function Shutdown()
  659. {
  660.   // remove remote support
  661.   if (XREMOTESERVICE_CONTRACTID in Components.classes) {
  662.     var remoteService;
  663.     remoteService = Components.classes[XREMOTESERVICE_CONTRACTID]
  664.                               .getService(Components.interfaces.nsIXRemoteService);
  665.     remoteService.removeBrowserInstance(window);
  666.   }
  667.  
  668.   try {
  669.     getBrowser().removeProgressListener(window.XULBrowserWindow);
  670.   } catch (ex) {
  671.   }
  672.  
  673.   window.XULBrowserWindow.destroy();
  674.   window.XULBrowserWindow = null;
  675.  
  676.   BrowserFlushBookmarksAndHistory();
  677.  
  678.   // unregister us as a pref listener
  679.   removePrefListener(gButtonPrefListener);
  680.   removePrefListener(gTabStripPrefListener);
  681.   removePrefListener(gHomepagePrefListener);
  682.   removePopupPermListener(gPopupPermListener);
  683.   removePrefListener(gPopupPrefListener);
  684.  
  685.   window.browserContentListener.close();
  686.   // Close the app core.
  687.   if (appCore)
  688.     appCore.close();
  689. }
  690.  
  691. function Translate()
  692. {
  693.   var service = pref.getCharPref("browser.translation.service");
  694.   var serviceDomain = pref.getCharPref("browser.translation.serviceDomain");
  695.   var targetURI = getWebNavigation().currentURI.spec;
  696.  
  697.   // if we're already viewing a translated page, then just reload
  698.   if (targetURI.indexOf(serviceDomain) >= 0)
  699.     BrowserReload();
  700.   else {
  701.     loadURI(service + escape(targetURI));
  702.   }
  703. }
  704.  
  705. function gotoHistoryIndex(aEvent)
  706. {
  707.   var index = aEvent.target.getAttribute("index");
  708.   if (!index)
  709.     return false;
  710.   try {
  711.     getWebNavigation().gotoIndex(index);
  712.   }
  713.   catch(ex) {
  714.     return false;
  715.   }
  716.   return true;
  717.  
  718. }
  719.  
  720. function BrowserBack()
  721. {
  722.   try {
  723.     getWebNavigation().goBack();
  724.   }
  725.   catch(ex) {
  726.   }
  727. }
  728.  
  729. function BrowserForward()
  730. {
  731.   try {
  732.     getWebNavigation().goForward();
  733.   }
  734.   catch(ex) {
  735.   }
  736. }
  737.  
  738. function BrowserBackMenu(event)
  739. {
  740.   return FillHistoryMenu(event.target, "back");
  741. }
  742.  
  743. function BrowserForwardMenu(event)
  744. {
  745.   return FillHistoryMenu(event.target, "forward");
  746. }
  747.  
  748. function BrowserStop()
  749. {
  750.   try {
  751.     const stopFlags = nsIWebNavigation.STOP_ALL;
  752.     getWebNavigation().stop(stopFlags);
  753.   }
  754.   catch(ex) {
  755.   }
  756. }
  757.  
  758. function BrowserReload()
  759. {
  760.   const reloadFlags = nsIWebNavigation.LOAD_FLAGS_NONE;
  761.   return BrowserReloadWithFlags(reloadFlags);
  762. }
  763.  
  764. function BrowserReloadSkipCache()
  765. {
  766.   // Bypass proxy and cache.
  767.   const reloadFlags = nsIWebNavigation.LOAD_FLAGS_BYPASS_PROXY | nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE;
  768.   return BrowserReloadWithFlags(reloadFlags);
  769. }
  770.  
  771. function BrowserHome()
  772. {
  773.   var homePage = getHomePage();
  774.   if (homePage.length == 1) {
  775.     loadURI(homePage[0]);
  776.   } else {
  777.     for (var i in homePage)
  778.       gBrowser.addTab(homePage[i]);
  779.   }
  780. }
  781.  
  782. function OpenBookmarkGroup(element, datasource)
  783. {
  784.   if (!datasource)
  785.     return;
  786.     
  787.   var id = element.getAttribute("id");
  788.   var rdf = Components.classes["@mozilla.org/rdf/rdf-service;1"]
  789.                           .getService(Components.interfaces.nsIRDFService);
  790.   var resource = rdf.GetResource(id, true);
  791.   OpenBookmarkGroupFromResource(resource, datasource, rdf);
  792. }
  793.  
  794. function OpenBookmarkGroupFromResource(resource, datasource, rdf) {
  795.   var urlResource = rdf.GetResource("http://home.netscape.com/NC-rdf#URL");
  796.   var rdfContainer = Components.classes["@mozilla.org/rdf/container;1"].getService(Components.interfaces.nsIRDFContainer);
  797.   rdfContainer.Init(datasource, resource);
  798.   var containerChildren = rdfContainer.GetElements();
  799.   var tabPanels = gBrowser.mPanelContainer.childNodes;
  800.   var tabCount = tabPanels.length;
  801.   var index = 0;
  802.   for (; containerChildren.hasMoreElements(); ++index) {
  803.     var res = containerChildren.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
  804.     var target = datasource.GetTarget(res, urlResource, true);
  805.     if (target) {
  806.       var uri = target.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
  807.       gBrowser.addTab(uri);
  808.     }
  809.   }  
  810.   
  811.   if (index == 0)
  812.     return; // If the bookmark group was completely invalid, just bail.
  813.      
  814.   // Select the first tab in the group if we aren't loading in the background.
  815.   if (!pref.getBoolPref("browser.tabs.loadInBackground")) {
  816.     var tabs = gBrowser.mTabContainer.childNodes;
  817.     gBrowser.selectedTab = tabs[tabCount];
  818.   }
  819. }
  820.  
  821. function OpenBookmarkURL(node, datasources)
  822. {
  823.   if (node.getAttribute("group") == "true")
  824.     OpenBookmarkGroup(node, datasources);
  825.     
  826.   if (node.getAttribute("container") == "true")
  827.     return;
  828.  
  829.   var url = node.getAttribute("id");
  830.   if (!url) // if empty url (most likely a normal menu item like "Manage Bookmarks",
  831.     return; // don't bother loading it
  832.   try {
  833.     // add support for IE favorites under Win32, and NetPositive URLs under BeOS
  834.     if (datasources) {
  835.       var rdf = Components.classes["@mozilla.org/rdf/rdf-service;1"]
  836.                           .getService(Components.interfaces.nsIRDFService);
  837.       var src = rdf.GetResource(url, true);
  838.       var prop = rdf.GetResource("http://home.netscape.com/NC-rdf#URL", true);
  839.       var target = datasources.GetTarget(src, prop, true);
  840.       if (target) {
  841.         target = target.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
  842.         if (target)
  843.           url = target;
  844.       }
  845.     }
  846.   } catch (ex) {
  847.     return;
  848.   }
  849.  
  850.   // Ignore "NC:" urls.
  851.   if (url.substring(0, 3) == "NC:")
  852.     return;
  853.  
  854.   // Check if we have a browser window
  855.   if (_content) {
  856.     loadURI(url);
  857.     _content.focus();
  858.   }
  859.   else
  860.     openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no", url);
  861. }
  862.  
  863. function addBookmarkAs()
  864. {
  865.   const browsers = gBrowser.browsers;
  866.   if (browsers.length > 1)
  867.     BookmarksUtils.addBookmarkForTabBrowser(gBrowser);
  868.   else
  869.     BookmarksUtils.addBookmarkForBrowser(gBrowser.webNavigation, true);
  870. }
  871.  
  872. function addGroupmarkAs()
  873. {
  874.   BookmarksUtils.addBookmarkForTabBrowser(gBrowser, true);
  875. }
  876.  
  877. function updateGroupmarkMenuitem(id)
  878. {
  879.   const disabled = gBrowser.browsers.length == 1;
  880.   document.getElementById(id).setAttribute("disabled", disabled);
  881. }
  882.  
  883. function readRDFString(aDS,aRes,aProp)
  884. {
  885.   var n = aDS.GetTarget(aRes, aProp, true);
  886.   return n ? n.QueryInterface(Components.interfaces.nsIRDFLiteral).Value : "";
  887. }
  888.  
  889.  
  890. function ensureDefaultEnginePrefs(aRDF,aDS) 
  891. {
  892.   var mPrefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
  893.   var defaultName = mPrefs.getComplexValue("browser.search.defaultenginename", Components.interfaces.nsIPrefLocalizedString).data;
  894.   var kNC_Root = aRDF.GetResource("NC:SearchEngineRoot");
  895.   var kNC_child = aRDF.GetResource("http://home.netscape.com/NC-rdf#child");
  896.   var kNC_Name = aRDF.GetResource("http://home.netscape.com/NC-rdf#Name");
  897.           
  898.   var arcs = aDS.GetTargets(kNC_Root, kNC_child, true);
  899.   while (arcs.hasMoreElements()) {
  900.     var engineRes = arcs.getNext().QueryInterface(Components.interfaces.nsIRDFResource);       
  901.     var name = readRDFString(aDS, engineRes, kNC_Name);
  902.     if (name == defaultName)
  903.       mPrefs.setCharPref("browser.search.defaultengine", engineRes.Value);
  904.   }
  905. }
  906.  
  907. function ensureSearchPref()
  908. {
  909.   var rdf = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
  910.   var ds = rdf.GetDataSource("rdf:internetsearch");
  911.   var mPrefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
  912.   var kNC_Name = rdf.GetResource("http://home.netscape.com/NC-rdf#Name");
  913.   var defaultEngine;
  914.   try {
  915.     defaultEngine = mPrefs.getCharPref("browser.search.defaultengine");
  916.   } catch(ex) {
  917.     ensureDefaultEnginePrefs(rdf, ds);
  918.     defaultEngine = mPrefs.getCharPref("browser.search.defaultengine");
  919.   }
  920. }
  921.  
  922. function getSearchUrl(attr)
  923. {
  924.   var rdf = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService); 
  925.   var ds = rdf.GetDataSource("rdf:internetsearch"); 
  926.   var kNC_Root = rdf.GetResource("NC:SearchEngineRoot");
  927.   var mPrefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
  928.   var defaultEngine = mPrefs.getCharPref("browser.search.defaultengine");
  929.   var engineRes = rdf.GetResource(defaultEngine);
  930.   var prop = "http://home.netscape.com/NC-rdf#" + attr;
  931.   var kNC_attr = rdf.GetResource(prop);
  932.   var searchURL = readRDFString(ds, engineRes, kNC_attr);
  933.   return searchURL;
  934. }
  935.  
  936. function QualifySearchTerm()
  937. {
  938.   // If the text in the URL bar is the same as the currently loaded
  939.   // page's URL then treat this as an empty search term.  This way
  940.   // the user is taken to the search page where s/he can enter a term.
  941.   if (window.XULBrowserWindow.userTyped.value)
  942.     return document.getElementById("urlbar").value;
  943.   return "";
  944. }
  945.  
  946. function OpenSearch(tabName, forceDialogFlag, searchStr, newWindowFlag)
  947. {
  948.   //This function needs to be split up someday.
  949.  
  950.   var autoOpenSearchPanel = false;
  951.   var defaultSearchURL = null;
  952.   var fallbackDefaultSearchURL = gNavigatorRegionBundle.getString("fallbackDefaultSearchURL");
  953.   ensureSearchPref()
  954.   //Check to see if search string contains "://" or "ftp." or white space.
  955.   //If it does treat as url and match for pattern
  956.   
  957.   var urlmatch= /(:\/\/|^ftp\.)[^ \S]+$/ 
  958.   var forceAsURL = urlmatch.test(searchStr);
  959.  
  960.   try {
  961.     autoOpenSearchPanel = pref.getBoolPref("browser.search.opensidebarsearchpanel");
  962.     defaultSearchURL = pref.getComplexValue("browser.search.defaulturl",
  963.                                             Components.interfaces.nsIPrefLocalizedString).data;
  964.   } catch (ex) {
  965.   }
  966.  
  967.   // Fallback to a default url (one that we can get sidebar search results for)
  968.   if (!defaultSearchURL)
  969.     defaultSearchURL = fallbackDefaultSearchURL;
  970.  
  971.   if (!searchStr) {
  972.     BrowserSearchInternet();
  973.   } else {
  974.  
  975.     //Check to see if location bar field is a url
  976.     //If it is a url go to URL.  A Url is "://" or "." as commented above
  977.     //Otherwise search on entry
  978.     if (forceAsURL) {
  979.        BrowserLoadURL()
  980.     } else {
  981.       var searchMode = 0;
  982.       try {
  983.         searchMode = pref.getIntPref("browser.search.powermode");
  984.       } catch(ex) {
  985.       }
  986.  
  987.       if (forceDialogFlag || searchMode == 1) {
  988.         // Use a single search dialog
  989.         var windowManager = Components.classes["@mozilla.org/appshell/window-mediator;1"]
  990.                                       .getService(Components.interfaces.nsIWindowMediator);
  991.  
  992.         var searchWindow = windowManager.getMostRecentWindow("search:window");
  993.         if (!searchWindow) {
  994.           openDialog("chrome://communicator/content/search/search.xul", "SearchWindow", "dialog=no,close,chrome,resizable", tabName, searchStr);
  995.         } else {
  996.           // Already had one, focus it and load the page
  997.           searchWindow.focus();
  998.  
  999.           if ("loadPage" in searchWindow)
  1000.             searchWindow.loadPage(tabName, searchStr);
  1001.         }
  1002.       } else {
  1003.         if (searchStr) {
  1004.           var escapedSearchStr = escape(searchStr);
  1005.           defaultSearchURL += escapedSearchStr;
  1006.           var searchDS = Components.classes["@mozilla.org/rdf/datasource;1?name=internetsearch"]
  1007.                                    .getService(Components.interfaces.nsIInternetSearchService);
  1008.  
  1009.           searchDS.RememberLastSearchText(escapedSearchStr);
  1010.           try {
  1011.             var searchEngineURI = pref.getCharPref("browser.search.defaultengine");
  1012.             if (searchEngineURI) {          
  1013.               var searchURL = getSearchUrl("actionButton");
  1014.               if (searchURL) {
  1015.                 defaultSearchURL = searchURL + escapedSearchStr; 
  1016.               } else {
  1017.                 searchURL = searchDS.GetInternetSearchURL(searchEngineURI, escapedSearchStr, 0, 0, {value:0});
  1018.                 if (searchURL)
  1019.                   defaultSearchURL = searchURL;
  1020.               }
  1021.             }
  1022.           } catch (ex) {
  1023.           }
  1024.  
  1025.           if (!newWindowFlag)
  1026.             loadURI(defaultSearchURL);
  1027.           else
  1028.             window.open(defaultSearchURL, "_blank");
  1029.         }
  1030.       }
  1031.     }
  1032.   }
  1033.  
  1034.   // should we try and open up the sidebar to show the "Search Results" panel?
  1035.   if (autoOpenSearchPanel)
  1036.     RevealSearchPanel();
  1037. }
  1038.  
  1039. function RevealSearchPanel()
  1040. {
  1041.   var searchPanel = document.getElementById("urn:sidebar:panel:search");
  1042.   if (searchPanel)
  1043.     SidebarSelectPanel(searchPanel, true, true); // lives in sidebarOverlay.js
  1044. }
  1045.  
  1046. function isSearchPanelOpen()
  1047. {
  1048.   return ( !sidebar_is_hidden()    && 
  1049.            !sidebar_is_collapsed() && 
  1050.            SidebarGetLastSelectedPanel() == "urn:sidebar:panel:search"
  1051.          );
  1052. }
  1053.  
  1054. function BrowserSearchInternet()
  1055. {
  1056.   try {
  1057.     var searchEngineURI = pref.getCharPref("browser.search.defaultengine");
  1058.     if (searchEngineURI) {          
  1059.       var searchRoot = getSearchUrl("searchForm");
  1060.       if (searchRoot) {
  1061.         loadURI(searchRoot);
  1062.         return;
  1063.       } else {
  1064.         // Get a search URL and guess that the front page of the site has a search form.
  1065.         var searchDS = Components.classes["@mozilla.org/rdf/datasource;1?name=internetsearch"]
  1066.                                  .getService(Components.interfaces.nsIInternetSearchService);
  1067.         searchURL = searchDS.GetInternetSearchURL(searchEngineURI, "ABC", 0, 0, {value:0});
  1068.         if (searchURL) {
  1069.           searchRoot = searchURL.match(/[a-z]+:\/\/[a-z.-]+/);
  1070.           if (searchRoot) {
  1071.             loadURI(searchRoot + "/");
  1072.             return;
  1073.           }
  1074.         }
  1075.       }
  1076.     }
  1077.   } catch (ex) {
  1078.   }
  1079.  
  1080.   // Fallback if the stuff above fails: use the hard-coded search engine
  1081.   loadURI(gNavigatorRegionBundle.getString("otherSearchURL"));
  1082. }
  1083.  
  1084.  
  1085. //Note: BrowserNewEditorWindow() was moved to globalOverlay.xul and renamed to NewEditorWindow()
  1086.  
  1087. function BrowserOpenWindow()
  1088. {
  1089.   //opens a window where users can select a web location to open
  1090.   openDialog("chrome://communicator/content/openLocation.xul", "_blank", "chrome,modal,titlebar", window);
  1091. }
  1092.  
  1093. function BrowserOpenTab()
  1094. {
  1095.   if (!gInPrintPreviewMode) {
  1096.     gBrowser.selectedTab = gBrowser.addTab('about:blank');
  1097.     setTimeout("gURLBar.focus();", 0); 
  1098.   }
  1099. }
  1100.  
  1101. /* Called from the openLocation dialog. This allows that dialog to instruct
  1102.    its opener to open a new window and then step completely out of the way.
  1103.    Anything less byzantine is causing horrible crashes, rather believably,
  1104.    though oddly only on Linux. */
  1105. function delayedOpenWindow(chrome,flags,url)
  1106. {
  1107.   setTimeout("openDialog('"+chrome+"','_blank','"+flags+"','"+url+"')", 10);
  1108. }
  1109.  
  1110. /* Required because the tab needs time to set up its content viewers and get the load of
  1111.    the URI kicked off before becoming the active content area. */
  1112. function delayedOpenTab(url)
  1113. {
  1114.   setTimeout(function(aTabElt) { getBrowser().selectedTab = aTabElt; }, 0, getBrowser().addTab(url));
  1115. }
  1116.  
  1117. function BrowserOpenFileWindow()
  1118. {
  1119.   // Get filepicker component.
  1120.   try {
  1121.     const nsIFilePicker = Components.interfaces.nsIFilePicker;
  1122.     var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
  1123.     fp.init(window, gNavigatorBundle.getString("openFile"), nsIFilePicker.modeOpen);
  1124.     fp.appendFilters(nsIFilePicker.filterAll | nsIFilePicker.filterText | nsIFilePicker.filterImages |
  1125.                      nsIFilePicker.filterXML | nsIFilePicker.filterHTML);
  1126.  
  1127.     if (fp.show() == nsIFilePicker.returnOK)
  1128.       openTopWin(fp.fileURL.spec);
  1129.   } catch (ex) {
  1130.   }
  1131. }
  1132.  
  1133. // Set up a lame hack to avoid opening two bookmarks.
  1134. // Could otherwise happen with two Ctrl-B's in a row.
  1135. var gDisableBookmarks = false;
  1136. function enableBookmarks()
  1137. {
  1138.   gDisableBookmarks = false;
  1139. }
  1140.  
  1141. function BrowserEditBookmarks()
  1142. {
  1143.   // Use a single sidebar bookmarks dialog
  1144.   var windowManager = Components.classes["@mozilla.org/appshell/window-mediator;1"]
  1145.                                 .getService(Components.interfaces.nsIWindowMediator);
  1146.  
  1147.   var bookmarksWindow = windowManager.getMostRecentWindow("bookmarks:manager");
  1148.  
  1149.   if (bookmarksWindow) {
  1150.     bookmarksWindow.focus();
  1151.   } else {
  1152.     // while disabled, don't open new bookmarks window
  1153.     if (!gDisableBookmarks) {
  1154.       gDisableBookmarks = true;
  1155.  
  1156.       open("chrome://communicator/content/bookmarks/bookmarks.xul", "_blank",
  1157.         "chrome,extrachrome,menubar,resizable,scrollbars,status,toolbar");
  1158.       setTimeout(enableBookmarks, 2000);
  1159.     }
  1160.   }
  1161. }
  1162.  
  1163. function updateCloseItems()
  1164. {
  1165.   var browser = getBrowser();
  1166.   if (browser && browser.localName == 'tabbrowser' && browser.getStripVisibility()) {
  1167.     document.getElementById('menu_close').setAttribute('label', gNavigatorBundle.getString('tabs.closeTab'));
  1168.     document.getElementById('menu_closeWindow').hidden = false;
  1169.     document.getElementById('menu_closeOtherTabs').hidden = false;
  1170.     if (browser.mTabContainer.childNodes.length > 1)
  1171.       document.getElementById('cmd_closeOtherTabs').removeAttribute('disabled');
  1172.     else
  1173.       document.getElementById('cmd_closeOtherTabs').setAttribute('disabled', 'true');
  1174.   } else {
  1175.     document.getElementById('menu_close').setAttribute('label', gNavigatorBundle.getString('tabs.close'));
  1176.     document.getElementById('menu_closeWindow').hidden = true;
  1177.     document.getElementById('menu_closeOtherTabs').hidden = true;
  1178.   }
  1179. }
  1180.  
  1181. function BrowserCloseOtherTabs()
  1182. {
  1183.   var browser = getBrowser();
  1184.   browser.removeAllTabsBut(browser.mCurrentTab);
  1185. }
  1186.  
  1187. function BrowserCloseTabOrWindow()
  1188. {
  1189.   var browser = getBrowser();
  1190.   if (browser && browser.localName == 'tabbrowser' && browser.mTabContainer.childNodes.length > 1) {
  1191.     // Just close up a tab.
  1192.     browser.removeCurrentTab();
  1193.     return;
  1194.   }
  1195.  
  1196.   BrowserCloseWindow();
  1197. }
  1198.  
  1199. function BrowserCloseWindow() 
  1200. {
  1201.   // This code replicates stuff in Shutdown().  It is here because
  1202.   // window.screenX and window.screenY have real values.  We need
  1203.   // to fix this eventually but by replicating the code here, we
  1204.   // provide a means of saving position (it just requires that the
  1205.   // user close the window via File->Close (vs. close box).
  1206.   
  1207.   // Get the current window position/size.
  1208.   var x = window.screenX;
  1209.   var y = window.screenY;
  1210.   var h = window.outerHeight;
  1211.   var w = window.outerWidth;
  1212.  
  1213.   // Store these into the window attributes (for persistence).
  1214.   var win = document.getElementById( "main-window" );
  1215.   win.setAttribute( "x", x );
  1216.   win.setAttribute( "y", y );
  1217.   win.setAttribute( "height", h );
  1218.   win.setAttribute( "width", w );
  1219.  
  1220.   window.close();
  1221. }
  1222.  
  1223. function loadURI(uri, referrer)
  1224. {
  1225.   try {
  1226.     getWebNavigation().loadURI(uri, nsIWebNavigation.LOAD_FLAGS_NONE, referrer, null, null);
  1227.   } catch (e) {
  1228.   }
  1229. }
  1230.  
  1231. function BrowserLoadURL(aTriggeringEvent)
  1232. {
  1233.   var url = gURLBar.value;
  1234.   if (url.match(/^view-source:/)) {
  1235.     BrowserViewSourceOfURL(url.replace(/^view-source:/, ""), null, null);
  1236.   } else {
  1237.     // Check the pressed modifiers: (also see bug 97123)
  1238.     // Modifier Mac | Modifier PC | Action
  1239.     // -------------+-------------+-----------
  1240.     // Command      | Control     | New Window/Tab
  1241.     // Shift+Cmd    | Shift+Ctrl  | New Window/Tab behind current one
  1242.     // Option       | Shift       | Save URL (show Filepicker)
  1243.  
  1244.     // If false, the save modifier is Alt, which is Option on Mac.
  1245.     var modifierIsShift = true;
  1246.     try {
  1247.       modifierIsShift = pref.getBoolPref("ui.key.saveLink.shift");
  1248.     }
  1249.     catch (ex) {}
  1250.  
  1251.     var shiftPressed = false;
  1252.     var saveModifier = false; // if the save modifier was pressed
  1253.     if (aTriggeringEvent && 'shiftKey' in aTriggeringEvent &&
  1254.         'altKey' in aTriggeringEvent) {
  1255.       saveModifier = modifierIsShift ? aTriggeringEvent.shiftKey
  1256.                      : aTriggeringEvent.altKey;
  1257.       shiftPressed = aTriggeringEvent.shiftKey;
  1258.     }
  1259.  
  1260.     url = getShortcutOrURI(url);
  1261.     // Accept both Control and Meta (=Command) as New-Window-Modifiers
  1262.     if (aTriggeringEvent &&
  1263.         (('ctrlKey' in aTriggeringEvent && aTriggeringEvent.ctrlKey) ||
  1264.          ('metaKey' in aTriggeringEvent && aTriggeringEvent.metaKey))) {
  1265.       // Check if user requests Tabs instead of windows
  1266.       var openTab = false;
  1267.       try {
  1268.         openTab = pref.getBoolPref("browser.tabs.opentabfor.urlbar");
  1269.       }
  1270.       catch (ex) {}
  1271.  
  1272.       if (openTab && getBrowser().localName == "tabbrowser") {
  1273.         // Open link in new tab
  1274.         var t = getBrowser().addTab(url);
  1275.         // Focus new tab unless shift is pressed
  1276.         if (!shiftPressed)
  1277.           getBrowser().selectedTab = t;
  1278.       }
  1279.       else {
  1280.         // Open a new window with the URL
  1281.         var newWin = openDialog(getBrowserURL(), "_blank", "all,dialog=no", url);
  1282.         // Reset url in the urlbar, copied from handleURLBarRevert()
  1283.         var oldURL = getWebNavigation().currentURI.spec;
  1284.         if (oldURL != "about:blank") {
  1285.           gURLBar.value = oldURL;
  1286.           SetPageProxyState("valid", null);
  1287.         }
  1288.         else
  1289.           gURLBar.value = "";
  1290.  
  1291.         // Focus old window if shift was pressed, as there's no
  1292.         // way to open a new window in the background
  1293.         // XXX this doesn't seem to work
  1294.         if (shiftPressed) {
  1295.           //newWin.blur();
  1296.           content.focus();
  1297.         }
  1298.       }
  1299.     }
  1300.     else if (saveModifier) {
  1301.       try {
  1302.         // Firstly, fixup the url so that (e.g.) "www.foo.com" works
  1303.         const nsIURIFixup = Components.interfaces.nsIURIFixup;
  1304.         if (!gURIFixup)
  1305.           gURIFixup = Components.classes["@mozilla.org/docshell/urifixup;1"]
  1306.                                 .getService(nsIURIFixup);
  1307.         url = gURIFixup.createFixupURI(url, nsIURIFixup.FIXUP_FLAGS_MAKE_ALTERNATE_URI).spec;
  1308.         // Open filepicker to save the url
  1309.         saveURL(url, "");
  1310.       }
  1311.       catch(ex) {
  1312.         // XXX Do nothing for now.
  1313.         // Do we want to put up an alert in the future?  Mmm, l10n...
  1314.       }
  1315.     }
  1316.     else {
  1317.       // No modifier was pressed, load the URL normally and
  1318.       // focus the content area
  1319.       loadURI(url);
  1320.       content.focus();
  1321.     }
  1322.   }
  1323. }
  1324.  
  1325. function getShortcutOrURI(url)
  1326. {
  1327.   // rjc: added support for URL shortcuts (3/30/1999)
  1328.   try {
  1329.     if (!gBookmarksService)
  1330.       gBookmarksService = Components.classes["@mozilla.org/browser/bookmarks-service;1"]
  1331.                                     .getService(Components.interfaces.nsIBookmarksService);
  1332.  
  1333.     var shortcutURL = gBookmarksService.resolveKeyword(url);
  1334.     if (!shortcutURL) {
  1335.       // rjc: add support for string substitution with shortcuts (4/4/2000)
  1336.       //      (see bug # 29871 for details)
  1337.       var aOffset = url.indexOf(" ");
  1338.       if (aOffset > 0) {
  1339.         var cmd = url.substr(0, aOffset);
  1340.         var text = url.substr(aOffset+1);
  1341.         shortcutURL = gBookmarksService.resolveKeyword(cmd);
  1342.         if (shortcutURL && text) {
  1343.           aOffset = shortcutURL.indexOf("%s");
  1344.           if (aOffset >= 0)
  1345.             shortcutURL = shortcutURL.substr(0, aOffset) + text + shortcutURL.substr(aOffset+2);
  1346.           else
  1347.             shortcutURL = null;
  1348.         }
  1349.       }
  1350.     }
  1351.  
  1352.     if (shortcutURL)
  1353.       url = shortcutURL;
  1354.  
  1355.   } catch (ex) {
  1356.   }
  1357.   return url;
  1358. }
  1359.  
  1360. function readFromClipboard()
  1361. {
  1362.   var url;
  1363.  
  1364.   try {
  1365.     // Get clipboard.
  1366.     var clipboard = Components.classes["@mozilla.org/widget/clipboard;1"]
  1367.                               .getService(Components.interfaces.nsIClipboard);
  1368.  
  1369.     // Create tranferable that will transfer the text.
  1370.     var trans = Components.classes["@mozilla.org/widget/transferable;1"]
  1371.                           .createInstance(Components.interfaces.nsITransferable);
  1372.  
  1373.     trans.addDataFlavor("text/unicode");
  1374.     clipboard.getData(trans, clipboard.kSelectionClipboard);
  1375.  
  1376.     var data = {};
  1377.     var dataLen = {};
  1378.     trans.getTransferData("text/unicode", data, dataLen);
  1379.  
  1380.     if (data) {
  1381.       data = data.value.QueryInterface(Components.interfaces.nsISupportsString);
  1382.       url = data.data.substring(0, dataLen.value / 2);
  1383.     }
  1384.   } catch (ex) {
  1385.   }
  1386.  
  1387.   return url;
  1388. }
  1389.  
  1390. function OpenMessenger()
  1391. {
  1392.   open("chrome://messenger/content/messenger.xul", "_blank",
  1393.     "chrome,extrachrome,menubar,resizable,status,toolbar");
  1394. }
  1395.  
  1396. function OpenAddressbook()
  1397. {
  1398.   open("chrome://messenger/content/addressbook/addressbook.xul", "_blank",
  1399.     "chrome,extrachrome,menubar,resizable,status,toolbar");
  1400. }
  1401.  
  1402. function BrowserViewSourceOfDocument(aDocument)
  1403. {
  1404.   var docCharset;
  1405.   var pageCookie;
  1406.   var webNav;
  1407.  
  1408.   // Get the document charset
  1409.   docCharset = "charset=" + aDocument.characterSet;
  1410.  
  1411.   // Get the nsIWebNavigation associated with the document
  1412.   try {
  1413.       var win;
  1414.       var ifRequestor;
  1415.  
  1416.       // Get the DOMWindow for the requested document.  If the DOMWindow
  1417.       // cannot be found, then just use the _content window...
  1418.       //
  1419.       // XXX:  This is a bit of a hack...
  1420.       win = aDocument.defaultView;
  1421.       if (win == window) {
  1422.         win = _content;
  1423.       }
  1424.       ifRequestor = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
  1425.  
  1426.       webNav = ifRequestor.getInterface(Components.interfaces.nsIWebNavigation);
  1427.   } catch(err) {
  1428.       // If nsIWebNavigation cannot be found, just get the one for the whole
  1429.       // window...
  1430.       webNav = getWebNavigation();
  1431.   }
  1432.   //
  1433.   // Get the 'PageDescriptor' for the current document. This allows the
  1434.   // view-source to access the cached copy of the content rather than
  1435.   // refetching it from the network...
  1436.   //
  1437.   try{
  1438.     var PageLoader = webNav.QueryInterface(Components.interfaces.nsIWebPageDescriptor);
  1439.  
  1440.     pageCookie = PageLoader.currentDescriptor;
  1441.   } catch(err) {
  1442.     // If no page descriptor is available, just use the view-source URL...
  1443.   }
  1444.  
  1445.   BrowserViewSourceOfURL(webNav.currentURI.spec, docCharset, pageCookie);
  1446. }
  1447.  
  1448. function BrowserViewSourceOfURL(url, charset, pageCookie)
  1449. {
  1450.   // try to open a view-source window while inheriting the charset (if any)
  1451.   openDialog("chrome://navigator/content/viewSource.xul",
  1452.              "_blank",
  1453.              "scrollbars,resizable,chrome,dialog=no",
  1454.              url, charset, pageCookie);
  1455. }
  1456.  
  1457. // doc=null for regular page info, doc=owner document for frame info.
  1458. function BrowserPageInfo(doc, tab)
  1459. {
  1460.   window.openDialog("chrome://navigator/content/pageInfo.xul",
  1461.                     "_blank",
  1462.                     "chrome,dialog=no",
  1463.                     doc,
  1464.                     tab);
  1465. }
  1466.  
  1467. function hiddenWindowStartup()
  1468. {
  1469.   // focus the hidden window
  1470.   window.focus();
  1471.  
  1472.   // Disable menus which are not appropriate
  1473.   var disabledItems = ['cmd_close', 'Browser:SendPage', 'Browser:EditPage', 'Browser:PrintSetup', /*'Browser:PrintPreview',*/
  1474.                        'Browser:Print', 'canGoBack', 'canGoForward', 'Browser:Home', 'Browser:AddBookmark', 'cmd_undo',
  1475.                        'cmd_redo', 'cmd_cut', 'cmd_copy','cmd_paste', 'cmd_delete', 'cmd_selectAll', 'menu_textZoom'];
  1476.   for (var id in disabledItems) {
  1477.     var broadcaster = document.getElementById(disabledItems[id]);
  1478.     if (broadcaster)
  1479.       broadcaster.setAttribute("disabled", "true");
  1480.   }
  1481. }
  1482.  
  1483. // Initialize the LeakDetector class.
  1484. function LeakDetector(verbose)
  1485. {
  1486.   this.verbose = verbose;
  1487. }
  1488.  
  1489. const NS_LEAKDETECTOR_CONTRACTID = "@mozilla.org/xpcom/leakdetector;1";
  1490.  
  1491. if (NS_LEAKDETECTOR_CONTRACTID in Components.classes) {
  1492.   try {
  1493.     LeakDetector.prototype = Components.classes[NS_LEAKDETECTOR_CONTRACTID]
  1494.                                        .createInstance(Components.interfaces.nsILeakDetector);
  1495.   } catch (err) {
  1496.     LeakDetector.prototype = Object.prototype;
  1497.   }
  1498. } else {
  1499.   LeakDetector.prototype = Object.prototype;
  1500. }
  1501.  
  1502. var leakDetector = new LeakDetector(false);
  1503.  
  1504. // Dumps current set of memory leaks.
  1505. function dumpMemoryLeaks()
  1506. {
  1507.   leakDetector.dumpLeaks();
  1508. }
  1509.  
  1510. // Traces all objects reachable from the chrome document.
  1511. function traceChrome()
  1512. {
  1513.   leakDetector.traceObject(document, leakDetector.verbose);
  1514. }
  1515.  
  1516. // Traces all objects reachable from the content document.
  1517. function traceDocument()
  1518. {
  1519.   // keep the chrome document out of the dump.
  1520.   leakDetector.markObject(document, true);
  1521.   leakDetector.traceObject(_content, leakDetector.verbose);
  1522.   leakDetector.markObject(document, false);
  1523. }
  1524.  
  1525. // Controls whether or not we do verbose tracing.
  1526. function traceVerbose(verbose)
  1527. {
  1528.   leakDetector.verbose = (verbose == "true");
  1529. }
  1530.  
  1531. var consoleListener = {
  1532.   observe: function (aMsgObject)
  1533.   {
  1534.     const nsIScriptError = Components.interfaces.nsIScriptError;
  1535.     var scriptError = aMsgObject.QueryInterface(nsIScriptError);
  1536.     var isWarning = scriptError.flags & nsIScriptError.warningFlag != 0;
  1537.     if (!isWarning) {
  1538.       var statusbarDisplay = document.getElementById("statusbar-display");
  1539.       statusbarDisplay.setAttribute("error", "true");
  1540.       statusbarDisplay.addEventListener("click", loadErrorConsole, true);
  1541.       statusbarDisplay.label = gNavigatorBundle.getString("jserror");
  1542.       this.isShowingError = true;
  1543.     }
  1544.   },
  1545.  
  1546.   // whether or not an error alert is being displayed
  1547.   isShowingError: false
  1548. };
  1549.  
  1550. function initConsoleListener()
  1551. {
  1552.   /**
  1553.    * XXX - console launch hookup requires some work that I'm not sure
  1554.    * how to do.
  1555.    *
  1556.    *       1) ideally, the notification would disappear when the
  1557.    *       document that had the error was flushed. how do I know when
  1558.    *       this happens? All the nsIScriptError object I get tells me
  1559.    *       is the URL. Where is it located in the content area?
  1560.    *       2) the notification service should not display chrome
  1561.    *       script errors.  web developers and users are not interested
  1562.    *       in the failings of our shitty, exception unsafe js. One
  1563.    *       could argue that this should also extend to the console by
  1564.    *       default (although toggle-able via setting for chrome
  1565.    *       authors) At any rate, no status indication should be given
  1566.    *       for chrome script errors.
  1567.    *
  1568.    *       As a result I am commenting out this for the moment.
  1569.    *
  1570.  
  1571.   var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
  1572.                                  .getService(Components.interfaces.nsIConsoleService);
  1573.  
  1574.   if (consoleService)
  1575.     consoleService.registerListener(consoleListener);
  1576.   */
  1577. }
  1578.  
  1579. function loadErrorConsole(aEvent)
  1580. {
  1581.   if (aEvent.detail == 2)
  1582.     toJavaScriptConsole();
  1583. }
  1584.  
  1585. function clearErrorNotification()
  1586. {
  1587.   var statusbarDisplay = document.getElementById("statusbar-display");
  1588.   statusbarDisplay.removeAttribute("error");
  1589.   statusbarDisplay.removeEventListener("click", loadErrorConsole, true);
  1590.   consoleListener.isShowingError = false;
  1591. }
  1592.  
  1593. const NS_URLWIDGET_CONTRACTID = "@mozilla.org/urlwidget;1";
  1594. var urlWidgetService = null;
  1595. if (NS_URLWIDGET_CONTRACTID in Components.classes) {
  1596.   urlWidgetService = Components.classes[NS_URLWIDGET_CONTRACTID]
  1597.                                .getService(Components.interfaces.nsIUrlWidget);
  1598. }
  1599.  
  1600. //Posts the currently displayed url to a native widget so third-party apps can observe it.
  1601. function postURLToNativeWidget()
  1602. {
  1603.   if (urlWidgetService) {
  1604.     var url = getWebNavigation().currentURI.spec;
  1605.     try {
  1606.       urlWidgetService.SetURLToHiddenControl(url, window);
  1607.     } catch(ex) {
  1608.     }
  1609.   }
  1610. }
  1611.  
  1612. function checkForDirectoryListing()
  1613. {
  1614.   if ( "HTTPIndex" in _content &&
  1615.        _content.HTTPIndex instanceof Components.interfaces.nsIHTTPIndex ) {
  1616.     _content.defaultCharacterset = getMarkupDocumentViewer().defaultCharacterSet;
  1617.   }
  1618. }
  1619.  
  1620. /**
  1621.  * Use Stylesheet functions.
  1622.  *     Written by Tim Hill (bug 6782)
  1623.  *     Frameset handling by Neil Rashbrook <neil@parkwaycc.co.uk>
  1624.  **/
  1625. function getStyleSheetArray(frame)
  1626. {
  1627.   var styleSheets = frame.document.styleSheets;
  1628.   var styleSheetsArray = new Array(styleSheets.length);
  1629.   for (var i = 0; i < styleSheets.length; i++) {
  1630.     styleSheetsArray[i] = styleSheets[i];
  1631.   }
  1632.   return styleSheetsArray;
  1633. }
  1634.  
  1635. function getAllStyleSheets(frameset)
  1636. {
  1637.   var styleSheetsArray = getStyleSheetArray(frameset);
  1638.   for (var i = 0; i < frameset.frames.length; i++) {
  1639.     var frameSheets = getAllStyleSheets(frameset.frames[i]);
  1640.     styleSheetsArray = styleSheetsArray.concat(frameSheets);
  1641.   }
  1642.   return styleSheetsArray;
  1643. }
  1644.  
  1645. function stylesheetFillPopup(menuPopup)
  1646. {
  1647.   var itemNoOptStyles = menuPopup.firstChild;
  1648.   while (itemNoOptStyles.nextSibling)
  1649.     menuPopup.removeChild(itemNoOptStyles.nextSibling);
  1650.  
  1651.   var noOptionalStyles = true;
  1652.   var styleSheets = getAllStyleSheets(window._content);
  1653.   var currentStyleSheets = [];
  1654.  
  1655.   for (var i = 0; i < styleSheets.length; ++i) {
  1656.     var currentStyleSheet = styleSheets[i];
  1657.  
  1658.     if (currentStyleSheet.title) {
  1659.       if (!currentStyleSheet.disabled)
  1660.         noOptionalStyles = false;
  1661.  
  1662.       var lastWithSameTitle = null;
  1663.       if (currentStyleSheet.title in currentStyleSheets)
  1664.         lastWithSameTitle = currentStyleSheets[currentStyleSheet.title];
  1665.  
  1666.       if (!lastWithSameTitle) {
  1667.         var menuItem = document.createElement("menuitem");
  1668.         menuItem.setAttribute("type", "radio");
  1669.         menuItem.setAttribute("label", currentStyleSheet.title);
  1670.         menuItem.setAttribute("data", currentStyleSheet.title);
  1671.         menuItem.setAttribute("checked", !currentStyleSheet.disabled);
  1672.         menuPopup.appendChild(menuItem);
  1673.         currentStyleSheets[currentStyleSheet.title] = menuItem;
  1674.       } else {
  1675.         if (currentStyleSheet.disabled)
  1676.           lastWithSameTitle.removeAttribute("checked");
  1677.       }
  1678.     }
  1679.   }
  1680.   itemNoOptStyles.setAttribute("checked", noOptionalStyles);
  1681. }
  1682.  
  1683. function stylesheetInFrame(frame, title) {
  1684.   var docStyleSheets = frame.document.styleSheets;
  1685.  
  1686.   for (var i = 0; i < docStyleSheets.length; ++i) {
  1687.     if (docStyleSheets[i].title == title)
  1688.       return true;
  1689.   }
  1690.   return false;
  1691. }
  1692.  
  1693. function stylesheetSwitchFrame(frame, title) {
  1694.   var docStyleSheets = frame.document.styleSheets;
  1695.  
  1696.   for (var i = 0; i < docStyleSheets.length; ++i) {
  1697.     var docStyleSheet = docStyleSheets[i];
  1698.  
  1699.     if (docStyleSheet.title)
  1700.       docStyleSheet.disabled = (docStyleSheet.title != title);
  1701.     else if (docStyleSheet.disabled)
  1702.       docStyleSheet.disabled = false;
  1703.   }
  1704. }
  1705.  
  1706. function stylesheetSwitchAll(frameset, title) {
  1707.   if (!title || stylesheetInFrame(frameset, title)) {
  1708.     stylesheetSwitchFrame(frameset, title);
  1709.   }
  1710.   for (var i = 0; i < frameset.frames.length; i++) {
  1711.     stylesheetSwitchAll(frameset.frames[i], title);
  1712.   }
  1713. }
  1714.  
  1715. function applyTheme(themeName)
  1716. {
  1717.   var id = themeName.getAttribute('id'); 
  1718.   var name=id.substring('urn:mozilla.skin.'.length, id.length);
  1719.   if (!name)
  1720.     return;
  1721.  
  1722.   var chromeRegistry = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
  1723.     .getService(Components.interfaces.nsIXULChromeRegistry);
  1724.  
  1725.   var oldTheme = false;
  1726.   try {
  1727.     oldTheme = !chromeRegistry.checkThemeVersion(name);
  1728.   }
  1729.   catch(e) {
  1730.   }
  1731.  
  1732.   var str = Components.classes["@mozilla.org/supports-string;1"]
  1733.                       .createInstance(Components.interfaces.nsISupportsString);
  1734.  
  1735.   var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
  1736.   if (oldTheme) {
  1737.     var title = gNavigatorBundle.getString("oldthemetitle");
  1738.     var message = gNavigatorBundle.getString("oldTheme");
  1739.  
  1740.     message = message.replace(/%theme_name%/, themeName.getAttribute("displayName"));
  1741.     message = message.replace(/%brand%/g, gBrandBundle.getString("brandShortName"));
  1742.  
  1743.     if (promptService.confirm(window, title, message)){
  1744.       var inUse = chromeRegistry.isSkinSelected(name, true);
  1745.  
  1746.       chromeRegistry.uninstallSkin( name, true );
  1747.       // XXX - this sucks and should only be temporary.
  1748.  
  1749.       str.data = true;
  1750.       pref.setComplexValue("general.skins.removelist." + name,
  1751.                            Components.interfaces.nsISupportsString, str);
  1752.       
  1753.       if (inUse)
  1754.         chromeRegistry.refreshSkins();
  1755.     }
  1756.  
  1757.     return;
  1758.   }
  1759.  
  1760.  // XXX XXX BAD BAD BAD BAD !! XXX XXX                                         
  1761.  // we STILL haven't fixed editor skin switch problems                         
  1762.  // hacking around it yet again                                                
  1763.  
  1764.  str.data = name;
  1765.  pref.setComplexValue("general.skins.selectedSkin", Components.interfaces.nsISupportsString, str);
  1766.  
  1767.  // shut down quicklaunch so the next launch will have the new skin
  1768.  var appShell = Components.classes['@mozilla.org/appshell/appShellService;1'].getService();
  1769.  appShell = appShell.QueryInterface(Components.interfaces.nsIAppShellService);
  1770.  try {
  1771.    appShell.nativeAppSupport.isServerMode = false;
  1772.  }
  1773.  catch(ex) {
  1774.  }
  1775.  
  1776.  if (promptService) {                                                          
  1777.    var dialogTitle = gNavigatorBundle.getString("switchskinstitle");           
  1778.    var brandName = gBrandBundle.getString("brandShortName");                   
  1779.    var msg = gNavigatorBundle.getFormattedString("switchskins", [brandName]);  
  1780.    promptService.alert(window, dialogTitle, msg);                              
  1781.  }                                                                             
  1782. }
  1783.  
  1784. function getNewThemes()
  1785. {
  1786.   loadURI(gBrandRegionBundle.getString("getNewThemesURL"));
  1787. }
  1788.  
  1789. function URLBarFocusHandler(aEvent)
  1790. {
  1791.   if (gIgnoreFocus)
  1792.     gIgnoreFocus = false;
  1793.   else if (gClickSelectsAll)
  1794.     gURLBar.select();
  1795. }
  1796.  
  1797. function URLBarMouseDownHandler(aEvent)
  1798. {
  1799.   if (gURLBar.hasAttribute("focused")) {
  1800.     gIgnoreClick = true;
  1801.   } else {
  1802.     gIgnoreFocus = true;
  1803.     gIgnoreClick = false;
  1804.     gURLBar.setSelectionRange(0, 0);
  1805.   }
  1806. }
  1807.  
  1808. function URLBarClickHandler(aEvent)
  1809. {
  1810.   if (!gIgnoreClick && gClickSelectsAll && gURLBar.selectionStart == gURLBar.selectionEnd && gURLBar.selectionStart < gURLBar.value.length)
  1811.     gURLBar.select();
  1812. }
  1813.  
  1814. // This function gets the "windows hooks" service and has it check its setting
  1815. // This will do nothing on platforms other than Windows.
  1816. function checkForDefaultBrowser()
  1817. {
  1818.   const NS_WINHOOKS_CONTRACTID = "@mozilla.org/winhooks;1";
  1819.   var dialogShown = false;
  1820.   if (NS_WINHOOKS_CONTRACTID in Components.classes) {
  1821.     try {
  1822.       dialogShown = Components.classes[NS_WINHOOKS_CONTRACTID]
  1823.                       .getService(Components.interfaces.nsIWindowsHooks)
  1824.                       .checkSettings(window);
  1825.     } catch(e) {
  1826.     }
  1827.  
  1828.     if (dialogShown)  
  1829.     {
  1830.       // Force the sidebar to build since the windows 
  1831.       // integration dialog may have come up.
  1832.       SidebarRebuild();
  1833.     }
  1834.   }
  1835. }
  1836.  
  1837. function ShowAndSelectContentsOfURLBar()
  1838. {
  1839.   var navBar = document.getElementById("nav-bar");
  1840.   
  1841.   // If it's hidden, show it.
  1842.   if (navBar.getAttribute("hidden") == "true")
  1843.     goToggleToolbar('nav-bar','cmd_viewnavbar');
  1844.  
  1845.   if (gURLBar.value)
  1846.     gURLBar.select();
  1847.   else
  1848.     gURLBar.focus();
  1849. }
  1850.  
  1851. // If "ESC" is pressed in the url bar, we replace the urlbar's value with the url of the page
  1852. // and highlight it, unless it is about:blank, where we reset it to "".
  1853. function handleURLBarRevert()
  1854. {
  1855.   var url = getWebNavigation().currentURI.spec;
  1856.   var throbberElement = document.getElementById("navigator-throbber");
  1857.  
  1858.   var isScrolling = gURLBar.userAction == "scrolling";
  1859.   
  1860.   // don't revert to last valid url unless page is NOT loading
  1861.   // and user is NOT key-scrolling through autocomplete list
  1862.   if (!throbberElement.hasAttribute("busy") && !isScrolling) {
  1863.     if (url != "about:blank") { 
  1864.       gURLBar.value = url;
  1865.       gURLBar.select();
  1866.       SetPageProxyState("valid", null); // XXX Build a URI and pass it in here.
  1867.     } else { //if about:blank, urlbar becomes ""
  1868.       gURLBar.value = "";
  1869.     }
  1870.   }
  1871.  
  1872.   // tell widget to revert to last typed text only if the user
  1873.   // was scrolling when they hit escape
  1874.   return isScrolling; 
  1875. }
  1876.  
  1877. function handleURLBarCommand(aUserAction, aTriggeringEvent)
  1878. {
  1879.   try { 
  1880.     addToUrlbarHistory();
  1881.   } catch (ex) {
  1882.     // Things may go wrong when adding url to session history,
  1883.     // but don't let that interfere with the loading of the url.
  1884.   }
  1885.   
  1886.   BrowserLoadURL(aTriggeringEvent); 
  1887. }
  1888.  
  1889. function UpdatePageProxyState()
  1890. {
  1891.   if (gURLBar.value != gLastValidURLStr)
  1892.     SetPageProxyState("invalid", null);
  1893. }
  1894.  
  1895. function SetPageProxyState(aState, aURI)
  1896. {
  1897.   if (!gProxyButton)
  1898.     gProxyButton = document.getElementById("page-proxy-button");
  1899.   if (!gProxyFavIcon)
  1900.     gProxyFavIcon = document.getElementById("page-proxy-favicon");
  1901.   if (!gProxyDeck)
  1902.     gProxyDeck = document.getElementById("page-proxy-deck");
  1903.  
  1904.   gProxyButton.setAttribute("pageproxystate", aState);
  1905.  
  1906.   if (aState == "valid") {
  1907.     gLastValidURLStr = gURLBar.value;
  1908.     gURLBar.addEventListener("input", UpdatePageProxyState, false);
  1909.     if (gBrowser.shouldLoadFavIcon(aURI)) {
  1910.       var favStr = gBrowser.buildFavIconString(aURI);
  1911.       if (favStr != gProxyFavIcon.src) {
  1912.         gBrowser.loadFavIcon(aURI, "src", gProxyFavIcon);
  1913.         gProxyDeck.selectedIndex = 0;
  1914.       }
  1915.       else gProxyDeck.selectedIndex = 1;
  1916.     }
  1917.     else {
  1918.       gProxyDeck.selectedIndex = 0;
  1919.       gProxyFavIcon.removeAttribute("src");
  1920.     }
  1921.   } else if (aState == "invalid") {
  1922.     gURLBar.removeEventListener("input", UpdatePageProxyState, false);
  1923.     gProxyDeck.selectedIndex = 0;
  1924.   }
  1925. }
  1926.  
  1927. function PageProxyDragGesture(aEvent)
  1928. {
  1929.   if (gProxyButton.getAttribute("pageproxystate") == "valid") {
  1930.     nsDragAndDrop.startDrag(aEvent, proxyIconDNDObserver);
  1931.     return true;
  1932.   }
  1933.   return false;
  1934. }
  1935.  
  1936. function updateComponentBarBroadcaster()
  1937.   var compBarBroadcaster = document.getElementById('cmd_viewcomponentbar');
  1938.   var taskBarBroadcaster = document.getElementById('cmd_viewtaskbar');
  1939.   var compBar = document.getElementById('component-bar');
  1940.   if (taskBarBroadcaster.getAttribute('checked') == 'true') {
  1941.     compBarBroadcaster.removeAttribute('disabled');
  1942.     if (compBar.getAttribute('hidden') != 'true')
  1943.       compBarBroadcaster.setAttribute('checked', 'true');
  1944.   }
  1945.   else {
  1946.     compBarBroadcaster.setAttribute('disabled', 'true');
  1947.     compBarBroadcaster.removeAttribute('checked');
  1948.   }
  1949. }
  1950.  
  1951. function updateToolbarStates(toolbarMenuElt)
  1952. {
  1953.   if (!gHaveUpdatedToolbarState) {
  1954.     var mainWindow = document.getElementById("main-window");
  1955.     if (mainWindow.hasAttribute("chromehidden")) {
  1956.       gHaveUpdatedToolbarState = true;
  1957.       var i;
  1958.       for (i = 0; i < toolbarMenuElt.childNodes.length; ++i)
  1959.         document.getElementById(toolbarMenuElt.childNodes[i].getAttribute("observes")).removeAttribute("checked");
  1960.       var toolbars = document.getElementsByTagName("toolbar");
  1961.       for (i = 0; i < toolbars.length; ++i) {
  1962.         if (toolbars[i].getAttribute("class").indexOf("chromeclass") != -1)
  1963.           toolbars[i].setAttribute("hidden", "true");
  1964.       }
  1965.       var statusbars = document.getElementsByTagName("statusbar");
  1966.       for (i = 0; i < statusbars.length; ++i) {
  1967.         if (statusbars[i].getAttribute("class").indexOf("chromeclass") != -1)
  1968.           statusbars[i].setAttribute("hidden", "true");
  1969.       }
  1970.       mainWindow.removeAttribute("chromehidden");
  1971.     }
  1972.   }
  1973.   updateComponentBarBroadcaster();
  1974.  
  1975.   const tabbarMenuItem = document.getElementById("menuitem_showhide_tabbar");
  1976.   // Make show/hide menu item reflect current state
  1977.   const visibility = gBrowser.getStripVisibility();
  1978.   tabbarMenuItem.setAttribute("checked", visibility);
  1979.  
  1980.   // Don't allow the tab bar to be shown/hidden when more than one tab is open
  1981.   // or when we have 1 tab and the autoHide pref is set
  1982.   const disabled = gBrowser.browsers.length > 1 ||
  1983.                    pref.getBoolPref("browser.tabs.autoHide");
  1984.   tabbarMenuItem.setAttribute("disabled", disabled);
  1985. }
  1986.  
  1987. function showHideTabbar()
  1988. {
  1989.   const visibility = gBrowser.getStripVisibility();
  1990.   pref.setBoolPref("browser.tabs.forceHide", visibility);
  1991.   gBrowser.setStripVisibilityTo(!visibility);
  1992. }
  1993.  
  1994. // Fill in tooltips for personal toolbar
  1995. function FillInPTTooltip(tipElement)
  1996. {
  1997.  
  1998.   var title = tipElement.label;
  1999.   var url = tipElement.statusText;
  2000.  
  2001.   if (!title && !url) {
  2002.     // bail out early if there is nothing to show
  2003.     return false;
  2004.   }
  2005.  
  2006.   var tooltipTitle = document.getElementById("ptTitleText");
  2007.   var tooltipUrl = document.getElementById("ptUrlText"); 
  2008.  
  2009.   if (title && title != url) {
  2010.     tooltipTitle.removeAttribute("hidden");
  2011.     tooltipTitle.setAttribute("value", title);
  2012.   } else  {
  2013.     tooltipTitle.setAttribute("hidden", "true");
  2014.   }
  2015.  
  2016.   if (url) {
  2017.     tooltipUrl.removeAttribute("hidden");
  2018.     tooltipUrl.setAttribute("value", url);
  2019.   } else {
  2020.     tooltipUrl.setAttribute("hidden", "true");
  2021.   }
  2022.  
  2023.   return true; // show tooltip
  2024. }
  2025.  
  2026. function BrowserFullScreen()
  2027. {
  2028.   window.fullScreen = !window.fullScreen;
  2029. }
  2030.  
  2031. function onFullScreen()
  2032. {
  2033.   FullScreen.toggle();
  2034. }
  2035.  
  2036.  
  2037. function onPopupBlocked(aEvent) {
  2038.   var playSound = pref.getBoolPref("privacy.popups.sound_enabled");
  2039.  
  2040.   if (playSound) {
  2041.     var sound = Components.classes["@mozilla.org/sound;1"]
  2042.                           .createInstance(Components.interfaces.nsISound);
  2043.  
  2044.     var soundUrlSpec = pref.getCharPref("privacy.popups.sound_url");
  2045.  
  2046.     //beep if no sound file specified
  2047.     if (!soundUrlSpec)
  2048.       sound.beep();
  2049.  
  2050.     if (soundUrlSpec.substr(0, 7) == "file://") {
  2051.       var soundUrl = Components.classes["@mozilla.org/network/standard-url;1"]
  2052.                                .createInstance(Components.interfaces.nsIFileURL);
  2053.       soundUrl.spec = soundUrlSpec;
  2054.       var file = soundUrl.file;
  2055.       if (file.exists)
  2056.         sound.play(soundUrl);
  2057.     } 
  2058.     else {
  2059.       sound.playSystemSound(soundUrlSpec);
  2060.     }
  2061.   }
  2062.  
  2063.   var showIcon = pref.getBoolPref("privacy.popups.statusbar_icon_enabled");
  2064.   if (showIcon) {
  2065.     var doc = aEvent.target;
  2066.     var browsers = getBrowser().browsers;
  2067.     for (var i = 0; i < browsers.length; i++) {
  2068.       if (browsers[i].contentDocument == doc) {
  2069.         var hostPort = browsers[i].currentURI.hostPort;
  2070.         browsers[i].popupDomain = hostPort;
  2071.         if (browsers[i] == getBrowser().selectedBrowser) {
  2072.           var popupIcon = document.getElementById("popupIcon");
  2073.           popupIcon.hidden = false;
  2074.         }
  2075.       }
  2076.     }
  2077.   }
  2078. }
  2079.  
  2080. function StatusbarViewPopupManager() {
  2081.   var policy = pref.getBoolPref("dom.disable_open_during_load");
  2082.   
  2083.   var hostPort = "";
  2084.   try {
  2085.     hostPort = getBrowser().selectedBrowser.currentURI.hostPort;
  2086.   }
  2087.   catch(ex) { }
  2088.   
  2089.   //open blacklist or whitelist with web site prefilled to unblock
  2090.   window.openDialog("chrome://communicator/content/popupManager.xul", "",
  2091.                       "chrome,resizable=yes", policy, hostPort, false);
  2092. }
  2093.  
  2094. // Set up a lame hack to avoid opening two bookmarks.
  2095. // Could otherwise happen with two Ctrl-B's in a row.
  2096. var gDisableHistory = false;
  2097. function enableHistory() {
  2098.   gDisableHistory = false;
  2099. }
  2100.  
  2101. function toHistory()
  2102. {
  2103.   // Use a single sidebar history dialog
  2104.  
  2105.   var cwindowManager = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService();
  2106.   var iwindowManager = Components.interfaces.nsIWindowMediator;
  2107.   var windowManager  = cwindowManager.QueryInterface(iwindowManager);
  2108.  
  2109.   var historyWindow = windowManager.getMostRecentWindow('history:manager');
  2110.  
  2111.   if (historyWindow) {
  2112.     //debug("Reuse existing history window");
  2113.     historyWindow.focus();
  2114.   } else {
  2115.     //debug("Open a new history dialog");
  2116.  
  2117.     if (true == gDisableHistory) {
  2118.       //debug("Recently opened one. Wait a little bit.");
  2119.       return;
  2120.     }
  2121.     gDisableHistory = true;
  2122.  
  2123.     window.open( "chrome://communicator/content/history/history.xul", "_blank",
  2124.         "chrome,extrachrome,menubar,resizable,scrollbars,status,toolbar" );
  2125.     setTimeout(enableHistory, 2000);
  2126.   }
  2127.  
  2128. }
  2129.  
  2130. function checkTheme()
  2131. {
  2132.   var theSkinKids = document.getElementById("theme");
  2133.   var chromeRegistry = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
  2134.     .getService(Components.interfaces.nsIXULChromeRegistry);
  2135.   for (var i = 0; i < theSkinKids.childNodes.length; ++i) {
  2136.     var child = theSkinKids.childNodes[i];
  2137.     var id=child.getAttribute("id");
  2138.     if (id.length > 0) {
  2139.       var themeName = id.substring('urn:mozilla:skin:'.length, id.length);       
  2140.       var selected = chromeRegistry.isSkinSelected(themeName, true);
  2141.       if (selected == Components.interfaces.nsIChromeRegistry.FULL) {
  2142.         var menuitem=document.getElementById(id);
  2143.         menuitem.setAttribute("checked", true);
  2144.         break;
  2145.       }
  2146.     }
  2147.   } 
  2148. }
  2149.  
  2150. // opener may not have been initialized by load time (chrome windows only)
  2151. // so call this function some time later.
  2152. function maybeInitPopupContext()
  2153. {
  2154.   // it's not a popup with no opener
  2155.   if (!window.content.opener)
  2156.     return null;
  2157.  
  2158.   try {
  2159.     // are we a popup window?
  2160.     const CI = Components.interfaces;
  2161.     var xulwin = window
  2162.                  .QueryInterface(CI.nsIInterfaceRequestor)
  2163.                  .getInterface(CI.nsIWebNavigation)
  2164.                  .QueryInterface(CI.nsIDocShellTreeItem).treeOwner
  2165.                  .QueryInterface(CI.nsIInterfaceRequestor)
  2166.                  .getInterface(CI.nsIXULWindow);
  2167.     if (xulwin.contextFlags &
  2168.         CI.nsIWindowCreator2.PARENT_IS_LOADING_OR_RUNNING_TIMEOUT) {
  2169.       // return our opener's URI
  2170.       const IOS = Components.classes["@mozilla.org/network/io-service;1"]
  2171.                   .getService(CI.nsIIOService);
  2172.       var spec = Components.lookupMethod(window.content.opener, "location")
  2173.                  .call();
  2174.       return IOS.newURI(spec, null, null);
  2175.     }
  2176.   } catch(e) {
  2177.   }
  2178.   return null;
  2179. }
  2180.