home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2009 March / ME_03_2009.iso / Software / Internet / Firefox 3.0.8.dmg / Firefox.app / Contents / MacOS / components / nsBrowserContentHandler.js < prev    next >
Encoding:
JavaScript  |  2009-03-26  |  31.0 KB  |  890 lines

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