Bug 1374768 - Location bar not focused immediately with remote/content about:newtab page. r=mconley draft
authorEd Lee <edilee@mozilla.com>
Tue, 20 Jun 2017 12:56:35 -0700
changeset 604970 9def21f6e89e5f616ef4fa3a6eff8cdeac6ffc0b
parent 604348 ed438053201937afc04589ca66417bb1644c09a0
child 636357 6d5b1c426d09339db4402e7da667efa9d7e31321
push id67260
push userbmo:edilee@mozilla.com
push dateThu, 06 Jul 2017 21:04:45 +0000
reviewersmconley
bugs1374768
milestone56.0a1
Bug 1374768 - Location bar not focused immediately with remote/content about:newtab page. r=mconley Share logic for checking for local-resource about: URIs with tabProgressListener and the switcher. MozReview-Commit-ID: KnWkQN2fWdl
browser/base/content/tabbrowser.xml
browser/base/content/test/tabs/browser.ini
browser/base/content/test/tabs/browser_isLocalAboutURI.js
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -511,16 +511,43 @@
 
             callListeners(this.mTabsProgressListeners, aArguments);
           }
 
           return rv;
         ]]></body>
       </method>
 
+      <!-- Determine if a URI is an about: page pointing to a local resource. -->
+      <method name="_isLocalAboutURI">
+        <parameter name="aURI"/>
+        <parameter name="aResolvedURI"/>
+        <body><![CDATA[
+          if (!aURI.schemeIs("about")) {
+            return false;
+          }
+
+          // Specially handle about:blank as local
+          if (aURI.path === "blank") {
+            return true;
+          }
+
+          // Use the passed in resolvedURI if we have one
+          const resolvedURI = aResolvedURI || Services.io.newChannelFromURI2(
+            aURI,
+            null, // loadingNode
+            Services.scriptSecurityManager.getSystemPrincipal(), // loadingPrincipal
+            null, // triggeringPrincipal
+            Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, // securityFlags
+            Ci.nsIContentPolicy.TYPE_OTHER // contentPolicyType
+          ).URI;
+          return resolvedURI.schemeIs("jar") || resolvedURI.schemeIs("file");
+        ]]></body>
+      </method>
+
       <!-- A web progress listener object definition for a given tab. -->
       <method name="mTabProgressListener">
         <parameter name="aTab"/>
         <parameter name="aBrowser"/>
         <parameter name="aStartsBlank"/>
         <parameter name="aWasPreloadedBrowser"/>
         <parameter name="aOrigStateFlags"/>
         <body>
@@ -564,19 +591,19 @@
 
             _shouldShowProgress(aRequest) {
               if (this.mBlank)
                 return false;
 
               // Don't show progress indicators in tabs for about: URIs
               // pointing to local resources.
               if ((aRequest instanceof Ci.nsIChannel) &&
-                  aRequest.originalURI.schemeIs("about") &&
-                  (aRequest.URI.schemeIs("jar") || aRequest.URI.schemeIs("file")))
+                  this.mTabBrowser._isLocalAboutURI(aRequest.originalURI, aRequest.URI)) {
                 return false;
+              }
 
               return true;
             },
 
             _isForInitialAboutBlank(aWebProgress, aStateFlags, aLocation) {
               if (!this.mBlank || !aWebProgress.isTopLevel) {
                 return false;
               }
@@ -4186,23 +4213,24 @@
               let shouldBeBlank = false;
               if (requestedBrowser.isRemoteBrowser) {
                 // If a tab is remote and the window is not minimized, we can show a
                 // blank tab instead of a spinner in the following cases:
                 //
                 // 1. The tab has just crashed, and we haven't started showing the
                 //    tab crashed page yet (in this case, the TabParent is null)
                 // 2. The tab has never presented, and has not finished loading
-                //    a non-blank page.
+                //    a non-local-about: page.
                 //
-                // For (2), "finished loading a non-blank page" is determined by
-                // looking at the loaded URI and the busy state on the tab element.
+                // For (2), "finished loading a non-local-about: page" is
+                // determined by the busy state on the tab element and checking
+                // if the loaded URI is local.
                 let hasSufficientlyLoaded =
                   !this.requestedTab.hasAttribute("busy") &&
-                  requestedBrowser.currentURI.spec != "about:blank";
+                  !this.tabbrowser._isLocalAboutURI(requestedBrowser.currentURI);
 
                 let fl = requestedBrowser.frameLoader;
                 shouldBeBlank = !this.minimizedOrFullyOccluded &&
                                 (!fl.tabParent ||
                                  (!hasSufficientlyLoaded && !fl.tabParent.hasPresented));
               }
 
               this.log("Tab should be blank: " + shouldBeBlank);
--- a/browser/base/content/test/tabs/browser.ini
+++ b/browser/base/content/test/tabs/browser.ini
@@ -1,16 +1,17 @@
 [DEFAULT]
 support-files =
   dummy_page.html
   test_bug1358314.html
 
 [browser_abandonment_telemetry.js]
 [browser_allow_process_switches_despite_related_browser.js]
 [browser_contextmenu_openlink_after_tabnavigated.js]
+[browser_isLocalAboutURI.js]
 [browser_tabCloseProbes.js]
 [browser_tabSpinnerProbe.js]
 skip-if = !e10s # Tab spinner is e10s only.
 [browser_tabSwitchPrintPreview.js]
 skip-if = os == 'mac'
 [browser_navigatePinnedTab.js]
 [browser_new_web_tab_in_file_process_pref.js]
 skip-if = !e10s # Pref and test only relevant for e10s.
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/tabs/browser_isLocalAboutURI.js
@@ -0,0 +1,41 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+/**
+ * Unit tests for tabbrowser._isLocalAboutURI to make sure it returns the
+ * appropriate values for various URIs as well as optional resolved URI.
+ */
+
+add_task(function test_URI() {
+  const check = (spec, expect, description) => {
+    const URI = Services.io.newURI(spec);
+    is(gBrowser._isLocalAboutURI(URI), expect, description);
+  };
+  check("https://www.mozilla.org/", false, "https is not about");
+  check("http://www.mozilla.org/", false, "http is not about");
+  check("about:blank", true, "about:blank is local");
+  check("about:about", true, "about:about is local");
+  check("about:newtab", true, "about:newtab is local");
+});
+
+add_task(function test_URI_with_resolved() {
+  const check = (spec, resolvedSpec, expect, description) => {
+    const URI = Services.io.newURI(spec);
+    const resolvedURI = Services.io.newURI(resolvedSpec);
+    is(gBrowser._isLocalAboutURI(URI, resolvedURI), expect, description);
+  };
+  check("about:newtab",
+    "jar:file:///Applications/Firefox.app/Contents/Resources/browser/features/activity-stream@mozilla.org.xpi!/chrome/content/data/content/activity-stream.html",
+    true,
+    "about:newtab with jar is local");
+  check("about:newtab",
+    "file:///mozilla-central/browser/base/content/newtab/newTab.xhtml",
+    true,
+    "about:newtab with file is local");
+  check("about:newtab",
+    "https://www.mozilla.org/newtab",
+    false,
+    "about:newtab with https is not local");
+});