home *** CD-ROM | disk | FTP | other *** search
/ Chip 2008 June / CHIP-2008-06.iso / bonus / +10SecurityTips / files / xB-Browser_2.0.0.12b.exe / App / Browser / firefox / components / nsBrowserContentHandler.js < prev    next >
Encoding:
Text File  |  2008-02-02  |  32.0 KB  |  913 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3.  *
  4.  * The contents of this file are subject to the Mozilla Public License Version
  5.  * 1.1 (the "License"); you may not use this file except in compliance with
  6.  * the License. You may obtain a copy of the License at
  7.  * http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the
  12.  * License.
  13.  *
  14.  * The Original Code is the Mozilla Firefox browser.
  15.  *
  16.  * The Initial Developer of the Original Code is
  17.  * Benjamin Smedberg <benjamin@smedbergs.us>
  18.  *
  19.  * Portions created by the Initial Developer are Copyright (C) 2004
  20.  * the Initial Developer. All Rights Reserved.
  21.  *
  22.  * Contributor(s):
  23.  *
  24.  * Alternatively, the contents of this file may be used under the terms of
  25.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  26.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  27.  * in which case the provisions of the GPL or the LGPL are applicable instead
  28.  * of those above. If you wish to allow use of your version of this file only
  29.  * under the terms of either the GPL or the LGPL, and not to allow others to
  30.  * use your version of this file under the terms of the MPL, indicate your
  31.  * decision by deleting the provisions above and replace them with the notice
  32.  * and other provisions required by the GPL or the LGPL. If you do not delete
  33.  * the provisions above, a recipient may use your version of this file under
  34.  * the terms of any one of the MPL, the GPL or the LGPL.
  35.  *
  36.  * ***** END LICENSE BLOCK ***** */
  37.  
  38. const nsISupports            = Components.interfaces.nsISupports;
  39.  
  40. const nsIBrowserDOMWindow    = Components.interfaces.nsIBrowserDOMWindow;
  41. const nsIBrowserHandler      = Components.interfaces.nsIBrowserHandler;
  42. const nsIBrowserHistory      = Components.interfaces.nsIBrowserHistory;
  43. const nsIChannel             = Components.interfaces.nsIChannel;
  44. const nsICommandLine         = Components.interfaces.nsICommandLine;
  45. const nsICommandLineHandler  = Components.interfaces.nsICommandLineHandler;
  46. const nsIContentHandler      = Components.interfaces.nsIContentHandler;
  47. const nsIDocShellTreeItem    = Components.interfaces.nsIDocShellTreeItem;
  48. const nsIDOMChromeWindow     = Components.interfaces.nsIDOMChromeWindow;
  49. const nsIDOMWindow           = Components.interfaces.nsIDOMWindow;
  50. const nsIFactory             = Components.interfaces.nsIFactory;
  51. const nsIFileURL             = Components.interfaces.nsIFileURL;
  52. const nsIJARURI              = Components.interfaces.nsIJARURI;
  53. const nsIHttpProtocolHandler = Components.interfaces.nsIHttpProtocolHandler;
  54. const nsIInterfaceRequestor  = Components.interfaces.nsIInterfaceRequestor;
  55. const nsIPrefBranch          = Components.interfaces.nsIPrefBranch;
  56. const nsIPrefLocalizedString = Components.interfaces.nsIPrefLocalizedString;
  57. const nsISupportsString      = Components.interfaces.nsISupportsString;
  58. const nsIURIFixup            = Components.interfaces.nsIURIFixup;
  59. const nsIWebNavigation       = Components.interfaces.nsIWebNavigation;
  60. const nsIWindowMediator      = Components.interfaces.nsIWindowMediator;
  61. const nsIWindowWatcher       = Components.interfaces.nsIWindowWatcher;
  62. const nsICategoryManager     = Components.interfaces.nsICategoryManager;
  63. const nsIWebNavigationInfo   = Components.interfaces.nsIWebNavigationInfo;
  64. const nsIBrowserSearchService = Components.interfaces.nsIBrowserSearchService;
  65. const nsICommandLineValidator = Components.interfaces.nsICommandLineValidator;
  66.  
  67. const NS_BINDING_ABORTED = 0x804b0002;
  68. const NS_ERROR_WONT_HANDLE_CONTENT = 0x805d0001;
  69. const NS_ERROR_ABORT = Components.results.NS_ERROR_ABORT;
  70.  
  71. function shouldLoadURI(aURI) {
  72.   if (aURI && !aURI.schemeIs("chrome"))
  73.     return true;
  74.  
  75.   dump("*** Preventing external load of chrome: URI into browser window\n");
  76.   dump("    Use -chrome <uri> instead\n");
  77.   return false;
  78. }
  79.  
  80. function resolveURIInternal(aCmdLine, aArgument) {
  81.   var uri = aCmdLine.resolveURI(aArgument);
  82.  
  83.   if (!(uri instanceof nsIFileURL)) {
  84.     return uri;
  85.   }
  86.  
  87.   try {
  88.     if (uri.file.exists())
  89.       return uri;
  90.   }
  91.   catch (e) {
  92.     Components.utils.reportError(e);
  93.   }
  94.  
  95.   // We have interpreted the argument as a relative file URI, but the file
  96.   // doesn't exist. Try URI fixup heuristics: see bug 290782.
  97.  
  98.   try {
  99.     var urifixup = Components.classes["@mozilla.org/docshell/urifixup;1"]
  100.                              .getService(nsIURIFixup);
  101.  
  102.     uri = urifixup.createFixupURI(aArgument, 0);
  103.   }
  104.   catch (e) {
  105.     Components.utils.reportError(e);
  106.   }
  107.  
  108.   return uri;
  109. }
  110.  
  111. const OVERRIDE_NONE        = 0;
  112. const OVERRIDE_NEW_PROFILE = 1;
  113. const OVERRIDE_NEW_MSTONE  = 2;
  114. /**
  115.  * Determines whether a home page override is needed.
  116.  * Returns:
  117.  *  OVERRIDE_NEW_PROFILE if this is the first run with a new profile.
  118.  *  OVERRIDE_NEW_MSTONE if this is the first run with a build with a different
  119.  *                      Gecko milestone (i.e. right after an upgrade).
  120.  *  OVERRIDE_NONE otherwise.
  121.  */
  122. function needHomepageOverride(prefb) {
  123.   var savedmstone = null;
  124.   try {
  125.     savedmstone = prefb.getCharPref("browser.startup.homepage_override.mstone");
  126.   } catch (e) {}
  127.  
  128.   if (savedmstone == "ignore")
  129.     return OVERRIDE_NONE;
  130.  
  131.   var mstone = Components.classes["@mozilla.org/network/protocol;1?name=http"]
  132.                          .getService(nsIHttpProtocolHandler).misc;
  133.  
  134.   if (mstone != savedmstone) {
  135.     prefb.setCharPref("browser.startup.homepage_override.mstone", mstone);
  136.     return (savedmstone ? OVERRIDE_NEW_MSTONE : OVERRIDE_NEW_PROFILE);
  137.   }
  138.  
  139.   return OVERRIDE_NONE;
  140. }
  141.  
  142. // Copies a pref override file into the user's profile pref-override folder,
  143. // and then tells the pref service to reload it's default prefs.
  144. function copyPrefOverride() {
  145.   try {
  146.     var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"]
  147.                                 .getService(Components.interfaces.nsIProperties);
  148.     const NS_APP_EXISTING_PREF_OVERRIDE = "ExistingPrefOverride";
  149.     var prefOverride = fileLocator.get(NS_APP_EXISTING_PREF_OVERRIDE,
  150.                                        Components.interfaces.nsIFile);
  151.     if (!prefOverride.exists())
  152.       return; // nothing to do
  153.  
  154.     const NS_APP_PREFS_OVERRIDE_DIR     = "PrefDOverride";
  155.     var prefOverridesDir = fileLocator.get(NS_APP_PREFS_OVERRIDE_DIR,
  156.                                            Components.interfaces.nsIFile);
  157.  
  158.     // Check for any existing pref overrides, and remove them if present
  159.     var existingPrefOverridesFile = prefOverridesDir.clone();
  160.     existingPrefOverridesFile.append(prefOverride.leafName);
  161.     if (existingPrefOverridesFile.exists())
  162.       existingPrefOverridesFile.remove(false);
  163.  
  164.     prefOverride.copyTo(prefOverridesDir, null);
  165.  
  166.     // Now that we've installed the new-profile pref override file,
  167.     // re-read the default prefs.
  168.     var prefSvcObs = Components.classes["@mozilla.org/preferences-service;1"]
  169.                                .getService(Components.interfaces.nsIObserver);
  170.     prefSvcObs.observe(null, "reload-default-prefs", null);
  171.   } catch (ex) {
  172.     Components.utils.reportError(ex);
  173.   }
  174. }
  175.  
  176. function openWindow(parent, url, target, features, args) {
  177.   var wwatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
  178.                          .getService(nsIWindowWatcher);
  179.  
  180.   var argstring;
  181.   if (args) {
  182.     argstring = Components.classes["@mozilla.org/supports-string;1"]
  183.                             .createInstance(nsISupportsString);
  184.     argstring.data = args;
  185.   }
  186.   return wwatch.openWindow(parent, url, target, features, argstring);
  187. }
  188.  
  189. function openPreferences() {
  190.   var features = "chrome,titlebar,toolbar,centerscreen,dialog=no";
  191.   var url = "chrome://browser/content/preferences/preferences.xul";
  192.  
  193.   var win = getMostRecentWindow("Browser:Preferences");
  194.   if (win) {
  195.     win.focus();
  196.   } else {
  197.     openWindow(null, url, "_blank", features);
  198.   }
  199. }
  200.  
  201. function getMostRecentWindow(aType) {
  202.   var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
  203.                      .getService(nsIWindowMediator);
  204.   return wm.getMostRecentWindow(aType);
  205. }
  206.  
  207. //@line 215 "/cygdrive/c/builds/tinderbox/Fx-Mozilla1.8-Release/WINNT_5.2_Depend/mozilla/browser/components/nsBrowserContentHandler.js"
  208.  
  209. // this returns the most recent non-popup browser window
  210. function getMostRecentBrowserWindow() {
  211.   var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
  212.                      .getService(Components.interfaces.nsIWindowMediator);
  213.  
  214. //@line 235 "/cygdrive/c/builds/tinderbox/Fx-Mozilla1.8-Release/WINNT_5.2_Depend/mozilla/browser/components/nsBrowserContentHandler.js"
  215.   var windowList = wm.getZOrderDOMWindowEnumerator("navigator:browser", true);
  216.   if (!windowList.hasMoreElements())
  217.     return null;
  218.  
  219.   var win = windowList.getNext();
  220.   while (!win.toolbar.visible) {
  221.     if (!windowList.hasMoreElements()) 
  222.       return null;
  223.  
  224.     win = windowList.getNext();
  225.   }
  226. //@line 247 "/cygdrive/c/builds/tinderbox/Fx-Mozilla1.8-Release/WINNT_5.2_Depend/mozilla/browser/components/nsBrowserContentHandler.js"
  227.  
  228.   return win;
  229. }
  230.  
  231. function doSearch(searchTerm, cmdLine) {
  232.   var ss = Components.classes["@mozilla.org/browser/search-service;1"]
  233.                      .getService(nsIBrowserSearchService);
  234.  
  235.   var submission = ss.defaultEngine.getSubmission(searchTerm, null);
  236.  
  237.   // fill our nsISupportsArray with uri-as-wstring, null, null, postData
  238.   var sa = Components.classes["@mozilla.org/supports-array;1"]
  239.                      .createInstance(Components.interfaces.nsISupportsArray);
  240.  
  241.   var wuri = Components.classes["@mozilla.org/supports-string;1"]
  242.                        .createInstance(Components.interfaces.nsISupportsString);
  243.   wuri.data = submission.uri.spec;
  244.  
  245.   sa.AppendElement(wuri);
  246.   sa.AppendElement(null);
  247.   sa.AppendElement(null);
  248.   sa.AppendElement(submission.postData);
  249.  
  250.   // XXXbsmedberg: use handURIToExistingBrowser to obey tabbed-browsing
  251.   // preferences, but need nsIBrowserDOMWindow extensions
  252.  
  253.   var wwatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
  254.                          .getService(nsIWindowWatcher);
  255.  
  256.   return wwatch.openWindow(null, nsBrowserContentHandler.chromeURL,
  257.                            "_blank",
  258.                            "chrome,dialog=no,all" +
  259.                              nsBrowserContentHandler.getFeatures(cmdLine),
  260.                            sa);
  261. }
  262.  
  263. var nsBrowserContentHandler = {
  264.   /* helper functions */
  265.  
  266.   mChromeURL : null,
  267.  
  268.   get chromeURL() {
  269.     if (this.mChromeURL) {
  270.       return this.mChromeURL;
  271.     }
  272.  
  273.     var prefb = Components.classes["@mozilla.org/preferences-service;1"]
  274.                           .getService(nsIPrefBranch);
  275.     this.mChromeURL = prefb.getCharPref("browser.chromeURL");
  276.  
  277.     return this.mChromeURL;
  278.   },
  279.  
  280.   /* nsISupports */
  281.   QueryInterface : function bch_QI(iid) {
  282.     if (!iid.equals(nsISupports) &&
  283.         !iid.equals(nsICommandLineHandler) &&
  284.         !iid.equals(nsIBrowserHandler) &&
  285.         !iid.equals(nsIContentHandler) &&
  286.         !iid.equals(nsICommandLineValidator) &&
  287.         !iid.equals(nsIFactory))
  288.       throw Components.errors.NS_ERROR_NO_INTERFACE;
  289.  
  290.     return this;
  291.   },
  292.  
  293.   /* nsICommandLineHandler */
  294.   handle : function bch_handle(cmdLine) {
  295.     if (cmdLine.handleFlag("browser", false)) {
  296.       openWindow(null, this.chromeURL, "_blank",
  297.                  "chrome,dialog=no,all" + this.getFeatures(cmdLine),
  298.                  this.defaultArgs);
  299.       cmdLine.preventDefault = true;
  300.     }
  301.  
  302.     try {
  303.       var remoteCommand = cmdLine.handleFlagWithParam("remote", true);
  304.     }
  305.     catch (e) {
  306.       throw NS_ERROR_ABORT;
  307.     }
  308.  
  309.     if (remoteCommand != null) {
  310.       try {
  311.         var a = /^\s*(\w+)\(([^\)]*)\)\s*$/.exec(remoteCommand);
  312.         var remoteVerb;
  313.         if (a) {
  314.           remoteVerb = a[1].toLowerCase();
  315.           var remoteParams = [];
  316.           var sepIndex = a[2].lastIndexOf(",");
  317.           if (sepIndex == -1)
  318.             remoteParams[0] = a[2];
  319.           else {
  320.             remoteParams[0] = a[2].substring(0, sepIndex);
  321.             remoteParams[1] = a[2].substring(sepIndex + 1);
  322.           }
  323.         }
  324.  
  325.         switch (remoteVerb) {
  326.         case "openurl":
  327.         case "openfile":
  328.           // openURL(<url>)
  329.           // openURL(<url>,new-window)
  330.           // openURL(<url>,new-tab)
  331.  
  332.           // First param is the URL, second param (if present) is the "target"
  333.           // (tab, window)
  334.           var url = remoteParams[0];
  335.           var target = nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW;
  336.           if (remoteParams[1]) {
  337.             var targetParam = remoteParams[1].toLowerCase()
  338.                                              .replace(/^\s*|\s*$/g, "");
  339.             if (targetParam == "new-tab")
  340.               target = nsIBrowserDOMWindow.OPEN_NEWTAB;
  341.             else if (targetParam == "new-window")
  342.               target = nsIBrowserDOMWindow.OPEN_NEWWINDOW;
  343.             else {
  344.               // The "target" param isn't one of our supported values, so
  345.               // assume it's part of a URL that contains commas.
  346.               url += "," + remoteParams[1];
  347.             }
  348.           }
  349.  
  350.           var uri = resolveURIInternal(cmdLine, url);
  351.           handURIToExistingBrowser(uri, target, cmdLine);
  352.           break;
  353.  
  354.         case "xfedocommand":
  355.           // xfeDoCommand(openBrowser)
  356.           if (remoteParams[0].toLowerCase() != "openbrowser")
  357.             throw NS_ERROR_ABORT;
  358.  
  359.           openWindow(null, this.chromeURL, "_blank",
  360.                      "chrome,dialog=no,all" + this.getFeatures(cmdLine),
  361.                      this.defaultArgs);
  362.           break;
  363.  
  364.         default:
  365.           // Somebody sent us a remote command we don't know how to process:
  366.           // just abort.
  367.           throw "Unknown remote command.";
  368.         }
  369.  
  370.         cmdLine.preventDefault = true;
  371.       }
  372.       catch (e) {
  373.         Components.utils.reportError(e);
  374.         // If we had a -remote flag but failed to process it, throw
  375.         // NS_ERROR_ABORT so that the xremote code knows to return a failure
  376.         // back to the handling code.
  377.         throw NS_ERROR_ABORT;
  378.       }
  379.     }
  380.  
  381.     var uriparam;
  382.     try {
  383.       while ((uriparam = cmdLine.handleFlagWithParam("new-window", false))) {
  384.         var uri = resolveURIInternal(cmdLine, uriparam);
  385.         if (!shouldLoadURI(uri))
  386.           continue;
  387.         openWindow(null, this.chromeURL, "_blank",
  388.                    "chrome,dialog=no,all" + this.getFeatures(cmdLine),
  389.                    uri.spec);
  390.         cmdLine.preventDefault = true;
  391.       }
  392.     }
  393.     catch (e) {
  394.       Components.utils.reportError(e);
  395.     }
  396.  
  397.     try {
  398.       while ((uriparam = cmdLine.handleFlagWithParam("new-tab", false))) {
  399.         var uri = resolveURIInternal(cmdLine, uriparam);
  400.         handURIToExistingBrowser(uri, nsIBrowserDOMWindow.OPEN_NEWTAB, cmdLine);
  401.         cmdLine.preventDefault = true;
  402.       }
  403.     }
  404.     catch (e) {
  405.       Components.utils.reportError(e);
  406.     }
  407.  
  408.     var chromeParam = cmdLine.handleFlagWithParam("chrome", false);
  409.     if (chromeParam) {
  410.  
  411.       // Handle the old preference dialog URL separately (bug 285416)
  412.       if (chromeParam == "chrome://browser/content/pref/pref.xul") {
  413.         openPreferences();
  414.         cmdLine.preventDefault = true;
  415.       } else try {
  416.         // only load URIs which do not inherit chrome privs.
  417.  
  418.         // normally would call checkLoadURI(..., DISALLOW_SCRIPT_OR_DATA)
  419.         // for this, but in this context we crash when the security manager
  420.         // tries to throw an exception (no window object here). On the branch
  421.         // we need to simulate the important bits
  422.         var uri = resolveURIInternal(cmdLine, chromeParam);
  423.         while (uri instanceof nsIJARURI) {
  424.           // unpack to find the real scheme
  425.           uri = uri.JARFile;
  426.         }
  427.         if (!uri.schemeIs("javascript") && !uri.schemeIs("data")) {
  428.           var features = "chrome,dialog=no,all" + this.getFeatures(cmdLine);
  429.           openWindow(null, uri.spec, "_blank", features, "");
  430.           cmdLine.preventDefault = true;
  431.         }
  432.       }
  433.       catch (e) {
  434.         Components.utils.reportError(e);
  435.       }
  436.     }
  437.     if (cmdLine.handleFlag("preferences", false)) {
  438.       openPreferences();
  439.       cmdLine.preventDefault = true;
  440.     }
  441.     if (cmdLine.handleFlag("silent", false))
  442.       cmdLine.preventDefault = true;
  443.  
  444.     var searchParam = cmdLine.handleFlagWithParam("search", false);
  445.     if (searchParam) {
  446.       doSearch(searchParam, cmdLine);
  447.       cmdLine.preventDefault = true;
  448.     }
  449.  
  450. //@line 471 "/cygdrive/c/builds/tinderbox/Fx-Mozilla1.8-Release/WINNT_5.2_Depend/mozilla/browser/components/nsBrowserContentHandler.js"
  451.     // Handle "? searchterm" for Windows Vista start menu integration
  452.     for (var i = cmdLine.length - 1; i >= 0; --i) {
  453.       var param = cmdLine.getArgument(i);
  454.       if (param.match(/^\? /)) {
  455.         cmdLine.removeArguments(i, i);
  456.         cmdLine.preventDefault = true;
  457.  
  458.         searchParam = param.substr(2);
  459.         doSearch(searchParam, cmdLine);
  460.       }
  461.     }
  462. //@line 483 "/cygdrive/c/builds/tinderbox/Fx-Mozilla1.8-Release/WINNT_5.2_Depend/mozilla/browser/components/nsBrowserContentHandler.js"
  463.   },
  464.  
  465.   helpInfo : "  -browser            Open a browser window.\n",
  466.  
  467.   /* nsIBrowserHandler */
  468.  
  469.   get defaultArgs() {
  470.     var prefb = Components.classes["@mozilla.org/preferences-service;1"]
  471.                           .getService(nsIPrefBranch);
  472.     var formatter = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
  473.                               .getService(Components.interfaces.nsIURLFormatter);
  474.  
  475.     var overridePage = "";
  476.     var haveUpdateSession = false;
  477.     try {
  478.       switch (needHomepageOverride(prefb)) {
  479.         case OVERRIDE_NEW_PROFILE:
  480.           // New profile.
  481.           overridePage = formatter.formatURLPref("startup.homepage_welcome_url");
  482.           break;
  483.         case OVERRIDE_NEW_MSTONE:
  484.           // Existing profile.
  485.           copyPrefOverride();
  486.  
  487.           // Check whether we have a session to restore. If we do, we assume
  488.           // that this is an "update" session.
  489.           var ss = Components.classes["@mozilla.org/browser/sessionstartup;1"]
  490.                              .getService(Components.interfaces.nsISessionStartup);
  491.           haveUpdateSession = ss.doRestore();
  492.           overridePage = formatter.formatURLPref("startup.homepage_override_url");
  493.           break;
  494.       }
  495.     } catch (e) {}
  496.  
  497.     // formatURLPref might return "about:blank" if getting the pref fails
  498.     if (overridePage == "about:blank")
  499.       overridePage = "";
  500.  
  501.     var startPage = "";
  502.     try {
  503.       var choice = prefb.getIntPref("browser.startup.page");
  504.       if (choice == 1)
  505.         startPage = this.startPage;
  506.  
  507.       if (choice == 2)
  508.         startPage = Components.classes["@mozilla.org/browser/global-history;2"]
  509.                               .getService(nsIBrowserHistory).lastPageVisited;
  510.     } catch (e) {
  511.       Components.utils.reportError(e);
  512.     }
  513.  
  514.     if (startPage == "about:blank")
  515.       startPage = "";
  516.  
  517.     // Only show the startPage if we're not restoring an update session.
  518.     if (overridePage && startPage && !haveUpdateSession)
  519.       return overridePage + "|" + startPage;
  520.  
  521.     return overridePage || startPage || "about:blank";
  522.   },
  523.  
  524.   get startPage() {
  525.     var prefb = Components.classes["@mozilla.org/preferences-service;1"]
  526.                           .getService(nsIPrefBranch);
  527.  
  528.     var uri = prefb.getComplexValue("browser.startup.homepage",
  529.                                     nsIPrefLocalizedString).data;
  530.  
  531.     if (!uri) {
  532.       prefb.clearUserPref("browser.startup.homepage");
  533.       uri = prefb.getComplexValue("browser.startup.homepage",
  534.                                   nsIPrefLocalizedString).data;
  535.     }
  536.                                 
  537.     var count;
  538.     try {
  539.       count = prefb.getIntPref("browser.startup.homepage.count");
  540.     }
  541.     catch (e) {
  542.       return uri;
  543.     }
  544.  
  545.     for (var i = 1; i < count; ++i) {
  546.       try {
  547.         var page = prefb.getComplexValue("browser.startup.homepage." + i,
  548.                                          nsIPrefLocalizedString).data;
  549.         uri += "\n" + page;
  550.       }
  551.       catch (e) {
  552.       }
  553.     }
  554.  
  555.     return uri;
  556.   },
  557.  
  558.   mFeatures : null,
  559.  
  560.   getFeatures : function bch_features(cmdLine) {
  561.     if (this.mFeatures === null) {
  562.       this.mFeatures = "";
  563.  
  564.       try {
  565.         var width = cmdLine.handleFlagWithParam("width", false);
  566.         var height = cmdLine.handleFlagWithParam("height", false);
  567.  
  568.         if (width)
  569.           this.mFeatures += ",width=" + width;
  570.         if (height)
  571.           this.mFeatures += ",height=" + height;
  572.       }
  573.       catch (e) {
  574.       }
  575.     }
  576.  
  577.     return this.mFeatures;
  578.   },
  579.  
  580.   /* nsIContentHandler */
  581.  
  582.   handleContent : function bch_handleContent(contentType, context, request) {
  583.     try {
  584.       var webNavInfo = Components.classes["@mozilla.org/webnavigation-info;1"]
  585.                                  .getService(nsIWebNavigationInfo);
  586.       if (!webNavInfo.isTypeSupported(contentType, null)) {
  587.         throw NS_ERROR_WONT_HANDLE_CONTENT;
  588.       }
  589.     } catch (e) {
  590.       throw NS_ERROR_WONT_HANDLE_CONTENT;
  591.     }
  592.  
  593.     var parentWin;
  594.     try {
  595.       parentWin = context.getInterface(nsIDOMWindow);
  596.     }
  597.     catch (e) {
  598.     }
  599.  
  600.     request.QueryInterface(nsIChannel);
  601.     
  602.     openWindow(parentWin, request.URI, "_blank", null, null);
  603.     request.cancel(NS_BINDING_ABORTED);
  604.   },
  605.  
  606.   /* nsICommandLineValidator */
  607.   validate : function bch_validate(cmdLine) {
  608.     // Other handlers may use osint so only handle the osint flag if the url
  609.     // flag is also present and the command line is valid.
  610.     var osintFlagIdx = cmdLine.findFlag("osint", false);
  611.     var urlFlagIdx = cmdLine.findFlag("url", false);
  612.     if (urlFlagIdx > -1 && (osintFlagIdx > -1 ||
  613.         cmdLine.state == nsICommandLine.STATE_REMOTE_EXPLICIT)) {
  614.       var urlParam = cmdLine.getArgument(urlFlagIdx + 1);
  615.       if (cmdLine.length != urlFlagIdx + 2 || /firefoxurl:/.test(urlParam))
  616.         throw NS_ERROR_ABORT;
  617.       cmdLine.handleFlag("osint", false)
  618.     }
  619.   },
  620.  
  621.   /* nsIFactory */
  622.   createInstance: function bch_CI(outer, iid) {
  623.     if (outer != null)
  624.       throw Components.results.NS_ERROR_NO_AGGREGATION;
  625.  
  626.     return this.QueryInterface(iid);
  627.   },
  628.     
  629.   lockFactory : function bch_lock(lock) {
  630.     /* no-op */
  631.   }
  632. };
  633.  
  634. const bch_contractID = "@mozilla.org/browser/clh;1";
  635. const bch_CID = Components.ID("{5d0ce354-df01-421a-83fb-7ead0990c24e}");
  636. const CONTRACTID_PREFIX = "@mozilla.org/uriloader/content-handler;1?type=";
  637.  
  638. function handURIToExistingBrowser(uri, location, cmdLine)
  639. {
  640.   if (!shouldLoadURI(uri))
  641.     return;
  642.  
  643.   var navWin = getMostRecentBrowserWindow();
  644.   if (!navWin) {
  645.     // if we couldn't load it in an existing window, open a new one
  646.     openWindow(null, nsBrowserContentHandler.chromeURL, "_blank",
  647.                "chrome,dialog=no,all" + nsBrowserContentHandler.getFeatures(cmdLine),
  648.                uri.spec);
  649.     return;
  650.   }
  651.  
  652.   var navNav = navWin.QueryInterface(nsIInterfaceRequestor)
  653.                      .getInterface(nsIWebNavigation);
  654.   var rootItem = navNav.QueryInterface(nsIDocShellTreeItem).rootTreeItem;
  655.   var rootWin = rootItem.QueryInterface(nsIInterfaceRequestor)
  656.                         .getInterface(nsIDOMWindow);
  657.   var bwin = rootWin.QueryInterface(nsIDOMChromeWindow).browserDOMWindow;
  658.   bwin.openURI(uri, null, location,
  659.                nsIBrowserDOMWindow.OPEN_EXTERNAL);
  660. }
  661.  
  662.  
  663. var nsDefaultCommandLineHandler = {
  664.   /* nsISupports */
  665.   QueryInterface : function dch_QI(iid) {
  666.     if (!iid.equals(nsISupports) &&
  667.         !iid.equals(nsICommandLineHandler) &&
  668.         !iid.equals(nsIFactory))
  669.       throw Components.errors.NS_ERROR_NO_INTERFACE;
  670.  
  671.     return this;
  672.   },
  673.  
  674.   // List of uri's that were passed via the command line without the app
  675.   // running and have already been handled. This is compared against uri's
  676.   // opened using DDE on Win32 so we only open one of the requests.
  677.   _handledURIs: [ ],
  678. //@line 699 "/cygdrive/c/builds/tinderbox/Fx-Mozilla1.8-Release/WINNT_5.2_Depend/mozilla/browser/components/nsBrowserContentHandler.js"
  679.   _haveProfile: false,
  680. //@line 701 "/cygdrive/c/builds/tinderbox/Fx-Mozilla1.8-Release/WINNT_5.2_Depend/mozilla/browser/components/nsBrowserContentHandler.js"
  681.  
  682.   /* nsICommandLineHandler */
  683.   handle : function dch_handle(cmdLine) {
  684.     var urilist = [];
  685.  
  686. //@line 707 "/cygdrive/c/builds/tinderbox/Fx-Mozilla1.8-Release/WINNT_5.2_Depend/mozilla/browser/components/nsBrowserContentHandler.js"
  687.     // If we don't have a profile selected yet (e.g. the Profile Manager is
  688.     // displayed) we will crash if we open an url and then select a profile. To
  689.     // prevent this handle all url command line flags and set the command line's
  690.     // preventDefault to true to prevent the display of the ui. The initial
  691.     // command line will be retained when nsAppRunner calls LaunchChild though
  692.     // urls launched after the initial launch will be lost.
  693.     if (!this._haveProfile) {
  694.       try {
  695.         // This will throw when a profile has not been selected.
  696.         var fl = Components.classes["@mozilla.org/file/directory_service;1"]
  697.                            .getService(Components.interfaces.nsIProperties);
  698.         var dir = fl.get("ProfD", Components.interfaces.nsILocalFile);
  699.         this._haveProfile = true;
  700.       }
  701.       catch (e) {
  702.         while ((ar = cmdLine.handleFlagWithParam("url", false))) { }
  703.         cmdLine.preventDefault = true;
  704.       }
  705.     }
  706. //@line 727 "/cygdrive/c/builds/tinderbox/Fx-Mozilla1.8-Release/WINNT_5.2_Depend/mozilla/browser/components/nsBrowserContentHandler.js"
  707.  
  708.     try {
  709.       var ar;
  710.       while ((ar = cmdLine.handleFlagWithParam("url", false))) {
  711.         var found = false;
  712.         var uri = resolveURIInternal(cmdLine, ar);
  713.         // count will never be greater than zero except on Win32.
  714.         var count = this._handledURIs.length;
  715.         for (var i = 0; i < count; ++i) {
  716.           if (this._handledURIs[i].spec == uri.spec) {
  717.             this._handledURIs.splice(i, 1);
  718.             found = true;
  719.             cmdLine.preventDefault = true;
  720.             break;
  721.           }
  722.         }
  723.         if (!found) {
  724.           urilist.push(uri);
  725.           // The requestpending command line flag is only used on Win32.
  726.           if (cmdLine.handleFlag("requestpending", false) &&
  727.               cmdLine.state == nsICommandLine.STATE_INITIAL_LAUNCH)
  728.             this._handledURIs.push(uri)
  729.         }
  730.       }
  731.     }
  732.     catch (e) {
  733.       Components.utils.reportError(e);
  734.     }
  735.  
  736.     count = cmdLine.length;
  737.  
  738.     for (i = 0; i < count; ++i) {
  739.       var curarg = cmdLine.getArgument(i);
  740.       if (curarg.match(/^-/)) {
  741.         Components.utils.reportError("Warning: unrecognized command line flag " + curarg + "\n");
  742.         // To emulate the pre-nsICommandLine behavior, we ignore
  743.         // the argument after an unrecognized flag.
  744.         ++i;
  745.       } else {
  746.         try {
  747.           urilist.push(resolveURIInternal(cmdLine, curarg));
  748.         }
  749.         catch (e) {
  750.           Components.utils.reportError("Error opening URI '" + curarg + "' from the command line: " + e + "\n");
  751.         }
  752.       }
  753.     }
  754.  
  755.     if (urilist.length) {
  756.       if (cmdLine.state != nsICommandLine.STATE_INITIAL_LAUNCH &&
  757.           urilist.length == 1) {
  758.         // Try to find an existing window and load our URI into the
  759.         // current tab, new tab, or new window as prefs determine.
  760.         try {
  761.           handURIToExistingBrowser(urilist[0], nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW, cmdLine);
  762.           return;
  763.         }
  764.         catch (e) {
  765.         }
  766.       }
  767.  
  768.       var speclist = [];
  769.       for (uri in urilist) {
  770.         if (shouldLoadURI(urilist[uri]))
  771.           speclist.push(urilist[uri].spec);
  772.       }
  773.  
  774.       if (speclist.length) {
  775.         openWindow(null, nsBrowserContentHandler.chromeURL, "_blank",
  776.                    "chrome,dialog=no,all" + nsBrowserContentHandler.getFeatures(cmdLine),
  777.                    speclist.join("|"));
  778.       }
  779.  
  780.     }
  781.     else if (!cmdLine.preventDefault) {
  782.       openWindow(null, nsBrowserContentHandler.chromeURL, "_blank",
  783.                  "chrome,dialog=no,all" + nsBrowserContentHandler.getFeatures(cmdLine),
  784.                  nsBrowserContentHandler.defaultArgs);
  785.     }
  786.   },
  787.  
  788.   // XXX localize me... how?
  789.   helpInfo : "Usage: firefox [-flags] [<url>]\n",
  790.  
  791.   /* nsIFactory */
  792.   createInstance: function dch_CI(outer, iid) {
  793.     if (outer != null)
  794.       throw Components.results.NS_ERROR_NO_AGGREGATION;
  795.  
  796.     return this.QueryInterface(iid);
  797.   },
  798.     
  799.   lockFactory : function dch_lock(lock) {
  800.     /* no-op */
  801.   }
  802. };
  803.  
  804. const dch_contractID = "@mozilla.org/browser/final-clh;1";
  805. const dch_CID = Components.ID("{47cd0651-b1be-4a0f-b5c4-10e5a573ef71}");
  806.  
  807. var Module = {
  808.   /* nsISupports */
  809.   QueryInterface: function mod_QI(iid) {
  810.     if (iid.equals(Components.interfaces.nsIModule) ||
  811.         iid.equals(Components.interfaces.nsISupports))
  812.       return this;
  813.  
  814.     throw Components.results.NS_ERROR_NO_INTERFACE;
  815.   },
  816.  
  817.   /* nsIModule */
  818.   getClassObject: function mod_getco(compMgr, cid, iid) {
  819.     if (cid.equals(bch_CID))
  820.       return nsBrowserContentHandler.QueryInterface(iid);
  821.  
  822.     if (cid.equals(dch_CID))
  823.       return nsDefaultCommandLineHandler.QueryInterface(iid);
  824.  
  825.     throw Components.results.NS_ERROR_NO_INTERFACE;
  826.   },
  827.     
  828.   registerSelf: function mod_regself(compMgr, fileSpec, location, type) {
  829.     var compReg =
  830.       compMgr.QueryInterface( Components.interfaces.nsIComponentRegistrar );
  831.  
  832.     compReg.registerFactoryLocation( bch_CID,
  833.                                      "nsBrowserContentHandler",
  834.                                      bch_contractID,
  835.                                      fileSpec,
  836.                                      location,
  837.                                      type );
  838.     compReg.registerFactoryLocation( dch_CID,
  839.                                      "nsDefaultCommandLineHandler",
  840.                                      dch_contractID,
  841.                                      fileSpec,
  842.                                      location,
  843.                                      type );
  844.  
  845.     function registerType(contentType) {
  846.       compReg.registerFactoryLocation( bch_CID,
  847.                                        "Browser Cmdline Handler",
  848.                                        CONTRACTID_PREFIX + contentType,
  849.                                        fileSpec,
  850.                                        location,
  851.                                        type );
  852.     }
  853.  
  854.     registerType("text/html");
  855.     registerType("application/vnd.mozilla.xul+xml");
  856. //@line 877 "/cygdrive/c/builds/tinderbox/Fx-Mozilla1.8-Release/WINNT_5.2_Depend/mozilla/browser/components/nsBrowserContentHandler.js"
  857.     registerType("image/svg+xml");
  858. //@line 879 "/cygdrive/c/builds/tinderbox/Fx-Mozilla1.8-Release/WINNT_5.2_Depend/mozilla/browser/components/nsBrowserContentHandler.js"
  859.     registerType("text/rdf");
  860.     registerType("text/xml");
  861.     registerType("application/xhtml+xml");
  862.     registerType("text/css");
  863.     registerType("text/plain");
  864.     registerType("image/gif");
  865.     registerType("image/jpeg");
  866.     registerType("image/jpg");
  867.     registerType("image/png");
  868.     registerType("image/bmp");
  869.     registerType("image/x-icon");
  870.     registerType("image/vnd.microsoft.icon");
  871.     registerType("image/x-xbitmap");
  872.     registerType("application/http-index-format");
  873.  
  874.     var catMan = Components.classes["@mozilla.org/categorymanager;1"]
  875.                            .getService(nsICategoryManager);
  876.  
  877.     catMan.addCategoryEntry("command-line-handler",
  878.                             "m-browser",
  879.                             bch_contractID, true, true);
  880.     catMan.addCategoryEntry("command-line-handler",
  881.                             "x-default",
  882.                             dch_contractID, true, true);
  883.     catMan.addCategoryEntry("command-line-validator",
  884.                             "b-browser",
  885.                             bch_contractID, true, true);
  886.   },
  887.     
  888.   unregisterSelf : function mod_unregself(compMgr, location, type) {
  889.     var compReg = compMgr.QueryInterface(nsIComponentRegistrar);
  890.     compReg.unregisterFactoryLocation(bch_CID, location);
  891.     compReg.unregisterFactoryLocation(dch_CID, location);
  892.  
  893.     var catMan = Components.classes["@mozilla.org/categorymanager;1"]
  894.                            .getService(nsICategoryManager);
  895.  
  896.     catMan.deleteCategoryEntry("command-line-handler",
  897.                                "m-browser", true);
  898.     catMan.deleteCategoryEntry("command-line-handler",
  899.                                "x-default", true);
  900.     catMan.deleteCategoryEntry("command-line-validator",
  901.                                "b-browser", true);
  902.   },
  903.  
  904.   canUnload: function(compMgr) {
  905.     return true;
  906.   }
  907. };
  908.  
  909. // NSGetModule: Return the nsIModule object.
  910. function NSGetModule(compMgr, fileSpec) {
  911.   return Module;
  912. }
  913.