Bug 593782 - cleanup command line handling [r=mfinkle, r=fabrice]
authorFabrice Desré <fabrice@mozilla.com>
Mon, 06 Sep 2010 06:46:00 -0400
changeset 66540 67481a81241375fb29805c4a9632095c58f56f5a
parent 66539 d6712406d5fbf7ec393a53313cd313f76c5668f2
child 66541 582f22ba322cc4b0ce4a19a644385367197de4d5
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmfinkle, fabrice
bugs593782
Bug 593782 - cleanup command line handling [r=mfinkle, r=fabrice]
mobile/chrome/content/Util.js
mobile/chrome/content/browser.js
mobile/components/BrowserCLH.js
mobile/components/Makefile.in
--- a/mobile/chrome/content/Util.js
+++ b/mobile/chrome/content/Util.js
@@ -131,44 +131,16 @@ let Util = {
     let dontShare = /^(chrome|about|file|javascript|resource)$/;
     return (aProtocol && !dontShare.test(aProtocol));
   },
 
   clamp: function(num, min, max) {
     return Math.max(min, Math.min(max, num));
   },
 
-  /**
-   * Determines whether a home page override is needed.
-   * Returns:
-   *  "new profile" if this is the first run with a new profile.
-   *  "new version" if this is the first run with a build with a different
-   *                      Gecko milestone (i.e. right after an upgrade).
-   *  "none" otherwise.
-   */
-  needHomepageOverride: function needHomepageOverride() {
-    let savedmstone = null;
-    try {
-      savedmstone = Services.prefs.getCharPref("browser.startup.homepage_override.mstone");
-    } catch (e) {}
-
-    if (savedmstone == "ignore")
-      return "none";
-
-#expand    let ourmstone = "__MOZ_APP_VERSION__";
-
-    if (ourmstone != savedmstone) {
-      Services.prefs.setCharPref("browser.startup.homepage_override.mstone", ourmstone);
-
-      return (savedmstone ? "new version" : "new profile");
-    }
-
-    return "none";
-  },
-
   /** Don't display anything in the urlbar for these special URIs. */
   isURLEmpty: function isURLEmpty(aURL) {
     return (!aURL || aURL == "about:blank" || aURL == "about:empty" || aURL == "about:home");
   },
 
   /** Recursively find all documents, including root document. */
   getAllDocuments: function getAllDocuments(doc, resultSoFar) {
     resultSoFar = resultSoFar || [doc];
--- a/mobile/chrome/content/browser.js
+++ b/mobile/chrome/content/browser.js
@@ -358,20 +358,16 @@ var Browser = {
       messageManager.loadFrameScript("chrome://browser/content/Util.js", true);
       messageManager.loadFrameScript("chrome://browser/content/forms.js", true);
       messageManager.loadFrameScript("chrome://browser/content/content.js", true);
     } catch (e) {
       // XXX whatever is calling startup needs to dump errors!
       dump("###########" + e + "\n");
     }
 
-    let needOverride = Util.needHomepageOverride();
-    if (needOverride == "new profile")
-      this.initNewProfile();
-
     let container = document.getElementById("tile-container");
     let bv = this._browserView = new BrowserView(container, Browser.getVisibleRect);
 
     /* handles dispatching clicks on tiles into clicks in content or zooms */
     container.customClicker = new ContentCustomClicker(bv);
     container.customKeySender = new ContentCustomKeySender(bv);
 
     /* scrolling box that contains tiles */
@@ -502,55 +498,23 @@ var Browser = {
 
     // Login Manager and Form History initialization
     Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
     Cc["@mozilla.org/satchel/form-history;1"].getService(Ci.nsIFormHistory2);
 
     // Make sure we're online before attempting to load
     Util.forceOnline();
 
-    // Command line arguments/initial homepage
-    let whereURI = this.getHomePage();
-    if (needOverride == "new profile")
-        whereURI = "about:firstrun";
-
-    // If this is an intial window launch (was a nsICommandLine passed via window params)
-    // we execute some logic to load the initial launch page
-    if (window.arguments && window.arguments[0]) {
-      if (window.arguments[0] instanceof Ci.nsICommandLine) {
-        try {
-          var cmdLine = window.arguments[0];
-
-          // Check for and use a single commandline parameter
-          if (cmdLine.length == 1) {
-            // Assume the first arg is a URI if it is not a flag
-            var uri = cmdLine.getArgument(0);
-            if (uri != "" && uri[0] != '-') {
-              whereURI = cmdLine.resolveURI(uri);
-              if (whereURI)
-                whereURI = whereURI.spec;
-            }
-          }
-
-          // Check for the "url" flag
-          var uriFlag = cmdLine.handleFlagWithParam("url", false);
-          if (uriFlag) {
-            whereURI = cmdLine.resolveURI(uriFlag);
-            if (whereURI)
-              whereURI = whereURI.spec;
-          }
-        } catch (e) {}
-      }
-      else {
-        // This window could have been opened by nsIBrowserDOMWindow.openURI
-        whereURI = window.arguments[0];
-      }
-    } 
-
-    this.addTab(whereURI, true);
+    // If this is an intial window launch the commandline handler passes us the default
+    // page as an argument
+    let defaultURL = this.getHomePage();
+    if (window.arguments && window.arguments[0])
+      defaultURL = window.arguments[0];
+
+    this.addTab(defaultURL, true);
 
     // JavaScript Error Console
     if (Services.prefs.getBoolPref("browser.console.showInPanel")){
       let button = document.getElementById("tool-console");
       button.hidden = false;
     }
 
     bv.commitBatchOperation();
@@ -651,19 +615,16 @@ var Browser = {
     os.removeObserver(gSessionHistoryObserver, "browser:purge-session-history");
     os.removeObserver(MemoryObserver, "memory-pressure");
     os.removeObserver(BrowserSearch, "browser-search-engine-modified");
 
     window.controllers.removeController(this);
     window.controllers.removeController(BrowserUI);
   },
 
-  initNewProfile: function initNewProfile() {
-  },
-
   getHomePage: function () {
     let url = "about:home";
     try {
       url = Services.prefs.getComplexValue("browser.startup.homepage", Ci.nsIPrefLocalizedString).data;
     } catch (e) { }
 
     return url;
   },
--- a/mobile/components/BrowserCLH.js
+++ b/mobile/components/BrowserCLH.js
@@ -37,18 +37,24 @@
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
-function openWindow(aParent, aURL, aTarget, aFeatures) {
-  return Services.ww.openWindow(aParent, aURL, aTarget, aFeatures, null);
+function openWindow(aParent, aURL, aTarget, aFeatures, aArgs) {
+  let argString = null;
+  if (aArgs) {
+    argString = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
+    argString.data = aArgs;
+  }
+  
+  return Services.ww.openWindow(aParent, aURL, aTarget, aFeatures, argString);
 }
 
 function resolveURIInternal(aCmdLine, aArgument) {
   let uri = aCmdLine.resolveURI(aArgument);
 
   if (!(uri instanceof Ci.nsIFileURL))
     return uri;
 
@@ -66,16 +72,53 @@ function resolveURIInternal(aCmdLine, aA
   }
   catch (e) {
     Cu.reportError(e);
   }
 
   return uri;
 }
 
+/**
+ * Determines whether a home page override is needed.
+ * Returns:
+ *  "new profile" if this is the first run with a new profile.
+ *  "new version" if this is the first run with a build with a different
+ *                      Gecko milestone (i.e. right after an upgrade).
+ *  "none" otherwise.
+ */
+function needHomepageOverride() {
+  let savedmstone = null;
+  try {
+    savedmstone = Services.prefs.getCharPref("browser.startup.homepage_override.mstone");
+  } catch (e) {}
+
+  if (savedmstone == "ignore")
+    return "none";
+
+#expand    let ourmstone = "__MOZ_APP_VERSION__";
+
+  if (ourmstone != savedmstone) {
+    Services.prefs.setCharPref("browser.startup.homepage_override.mstone", ourmstone);
+
+    return (savedmstone ? "new version" : "new profile");
+  }
+
+  return "none";
+}
+
+function getHomePage() {
+  let url = "about:home";
+  try {
+    url = Services.prefs.getComplexValue("browser.startup.homepage", Ci.nsIPrefLocalizedString).data;
+  } catch (e) { }
+
+  return url;
+}
+
 
 function BrowserCLH() { }
 
 BrowserCLH.prototype = {
   //
   // nsICommandLineHandler
   //
   handle: function fs_handle(aCmdLine) {
@@ -90,51 +133,90 @@ BrowserCLH.prototype = {
       let autoComplete = Cc["@mozilla.org/autocomplete/search;1?name=history"].
                          getService(Ci.nsIAutoCompleteSearch);
     }
 
     // Handle chrome windows loaded via commandline
     let chromeParam = aCmdLine.handleFlagWithParam("chrome", false);
     if (chromeParam) {
       try {
-        // only load URIs which do not inherit chrome privs
+        // Only load URIs which do not inherit chrome privs
         let features = "chrome,dialog=no,all";
         let uri = resolveURIInternal(aCmdLine, chromeParam);
         let netutil = Cc["@mozilla.org/network/util;1"].getService(Ci.nsINetUtil);
         if (!netutil.URIChainHasFlags(uri, Ci.nsIHttpProtocolHandler.URI_INHERITS_SECURITY_CONTEXT)) {
-          openWindow(null, uri.spec, "_blank", features);
+          openWindow(null, uri.spec, "_blank", features, null);
+
+          // Stop the normal commandline processing from continuing
           aCmdLine.preventDefault = true;
         }
       }
       catch (e) {
         Cu.reportError(e);
       }
     }
 
-    let win;
-    try {
-      win = Services.wm.getMostRecentWindow("navigator:browser");
-      if (!win)
-        return;
+    // Keep an array of possible URL arguments
+    let uris = [];
 
-      win.focus();
-      aCmdLine.preventDefault = true;
-    } catch (e) { }
+    // Check for the "url" flag
+    let uriFlag = aCmdLine.handleFlagWithParam("url", false);
+    if (uriFlag) {
+      let uri = resolveURIInternal(aCmdLine, uriFlag);
+      if (uri)
+        uris.push(uri);
+    }
 
-    // Assumption:  All CLH arguments we've received have been sent remotely,
-    // or we wouldn't already have a window.  Therefore: open 'em all!
     for (let i = 0; i < aCmdLine.length; i++) {
       let arg = aCmdLine.getArgument(i);
       if (!arg || arg[0] == '-')
         continue;
 
       let uri = resolveURIInternal(aCmdLine, arg);
       if (uri)
-        win.browserDOMWindow.openURI(uri, null, Ci.nsIBrowserDOMWindow.OPEN_NEWTAB, null);
+        uris.push(uri);
     }
+
+    // Open the main browser window, if we don't already have one
+    let win;
+    try {
+      win = Services.wm.getMostRecentWindow("navigator:browser");
+      if (!win) {
+        // Default to the saved homepage
+        let defaultURL = getHomePage();
+  
+        // Override the default if we have a new profile
+        if (needHomepageOverride() == "new profile")
+            defaultURL = "about:firstrun";
+  
+        // Override the default if we have a URL passed on command line
+        if (uris.length > 0) {
+          defaultURL = uris[0].spec;
+          uris = uris.slice(1);
+        }
+
+        win = openWindow(null, "chrome://browser/content/browser.xul", "_blank", "chrome,dialog=no,all", defaultURL);
+      }
+
+      win.focus();
+
+      // Stop the normal commandline processing from continuing. We just opened the main browser window
+      aCmdLine.preventDefault = true;
+    } catch (e) { }
+
+    // Assumption: All remaining command line arguments have been sent remotely (browser is already running)
+    // Action: Open any URLs we find into an existing browser window
+
+    // First, get a browserDOMWindow object
+    while (!win.browserDOMWindow)
+      Services.tm.currentThread.processNextEvent(true);
+
+    // Open any URIs into new tabs
+    for (let i = 0; i < uris.length; i++)
+      win.browserDOMWindow.openURI(uris[i], null, Ci.nsIBrowserDOMWindow.OPEN_NEWTAB, null);
   },
 
   // QI
   QueryInterface: XPCOMUtils.generateQI([Ci.nsICommandLineHandler]),
 
   // XPCOMUtils factory
   classID: Components.ID("{be623d20-d305-11de-8a39-0800200c9a66}"),
 };
--- a/mobile/components/Makefile.in
+++ b/mobile/components/Makefile.in
@@ -47,30 +47,30 @@ MODULE = MobileComponents
 XPIDL_MODULE = MobileComponents
 
 XPIDLSRCS = \
         SessionStore.idl \
         $(NULL)
 
 EXTRA_PP_COMPONENTS = \
         AboutRedirector.js \
+        BrowserCLH.js \
         DirectoryProvider.js\
         Sidebar.js \
         SessionStore.js \
         $(NULL)
 
 EXTRA_COMPONENTS = \
         MobileComponents.manifest \
         BrowserStartup.js \
         GeolocationPrompt.js \
         XPIDialogService.js \
         DownloadManagerUI.js \
         HelperAppDialog.js \
         PromptService.js \
-        BrowserCLH.js \
         ContentDispatchChooser.js \
         AutoCompleteCache.js \
         AddonUpdateService.js \
         FormAutoComplete.js \
         LoginManager.js \
         BlocklistPrompt.js \
 	$(NULL)