Bug 1362774 - Reduce flickering of the tab title when opening tabs and loading pages. r?florian draft
authorZibi Braniecki <zbraniecki@mozilla.com>
Thu, 14 Sep 2017 23:14:03 -0700
changeset 665309 b3795cbd3d6c4c2d8c39015af32df4444e201de6
parent 665308 cf182c4734e12850fe0f645e316cbab6628f78ad
child 731732 f8e4ffc1511abcc0d2e2605a5e1007a4e4fdcdd5
push id80011
push userbmo:gandalf@aviary.pl
push dateFri, 15 Sep 2017 08:39:27 +0000
reviewersflorian
bugs1362774
milestone57.0a1
Bug 1362774 - Reduce flickering of the tab title when opening tabs and loading pages. r?florian MozReview-Commit-ID: LkQd7dwDfC6
browser/base/content/tabbrowser.xml
browser/components/sessionstore/SessionStore.jsm
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -870,17 +870,23 @@
                   let findBar = this.mTabBrowser.getFindBar(this.mTab);
 
                   // Close the Find toolbar if we're in old-style TAF mode
                   if (findBar.findMode != findBar.FIND_NORMAL) {
                     findBar.close();
                   }
                 }
 
-                this.mTabBrowser.setTabTitle(this.mTab);
+                // This sets the tab title to the url we are loading;
+                // We don't want to set the title to an URL for `about:`
+                // pages. Since they're local, they'll load quickly and
+                // showing the URL will filcker or not be shown at all.
+                if (!aLocation.schemeIs("about")) {
+                  this.mTabBrowser.setTabTitle(this.mTab);
+                }
 
                 // Don't clear the favicon if this tab is in the pending
                 // state, as SessionStore will have set the icon for us even
                 // though we're pointed at an about:blank. Also don't clear it
                 // if onLocationChange was triggered by a pushState or a
                 // replaceState (bug 550565) or a hash change (bug 408415).
                 if (!this.mTab.hasAttribute("pending") &&
                     aWebProgress.isLoadingDocument &&
@@ -1520,22 +1526,23 @@
           }
           this._tabAttrModified(tab, ["sharing"]);
 
           if (aBrowser == this.mCurrentBrowser)
             gIdentityHandler.updateSharingIndicator();
         ]]></body>
       </method>
 
-
-      <!-- TODO: remove after 57, once we know add-ons can no longer use it. -->
-      <method name="setTabTitleLoading">
+      <method name="setAboutBlankTabTitle">
         <parameter name="aTab"/>
-        <body/>
-      </method>
+        <body><![CDATA[
+          aTab.setAttribute("label", this.mStringBundle.getString("tabs.emptyTabTitle"));
+        ]]></body>
+      </method>
+
 
       <method name="setInitialTabTitle">
         <parameter name="aTab"/>
         <parameter name="aTitle"/>
         <parameter name="aOptions"/>
         <body><![CDATA[
           if (aTitle) {
             if (!aTab.getAttribute("label")) {
@@ -1559,47 +1566,47 @@
             if (aTab._labelIsInitialTitle) {
               if (!title) {
                 return false;
               }
               delete aTab._labelIsInitialTitle;
             }
 
             let isContentTitle = false;
-            if (title) {
-              isContentTitle = true;
-            } else if (aTab.hasAttribute("customizemode")) {
+            let currentURI = browser.currentURI;
+
+            if (aTab.hasAttribute("customizemode")) {
               let brandBundle = document.getElementById("bundle_brand");
               let brandShortName = brandBundle.getString("brandShortName");
               title = gNavigatorBundle.getFormattedString("customizeMode.tabTitle",
                                                           [ brandShortName ]);
+            } else if (title) {
               isContentTitle = true;
+            } else if (currentURI.spec === "about:blank") {
+              title = this.mStringBundle.getString("tabs.emptyTabTitle");
+            } else if (currentURI.schemeIs("about")) {
+              return false;
             } else {
-              if (browser.currentURI.displaySpec) {
-                try {
-                  title = this.mURIFixup.createExposableURI(browser.currentURI).displaySpec;
-                } catch (ex) {
-                  title = browser.currentURI.displaySpec;
-                }
-              }
-
-              if (title && !isBlankPageURL(title)) {
-                // At this point, we now have a URI.
-                // Let's try to unescape it using a character set
-                // in case the URI is not ASCII.
-                try {
-                  var characterSet = browser.characterSet;
-                  const textToSubURI = Components.classes["@mozilla.org/intl/texttosuburi;1"]
-                                                 .getService(Components.interfaces.nsITextToSubURI);
-                  title = textToSubURI.unEscapeNonAsciiURI(characterSet, title);
-                } catch (ex) { /* Do nothing. */ }
-              } else {
-                // Still no title? Fall back to our untitled string.
-                title = this.mStringBundle.getString("tabs.emptyTabTitle");
-              }
+              let readableURI;
+              try {
+                readableURI = this.mURIFixup.createExposableURI(currentURI).displaySpec;
+              } catch (ex) {
+                readableURI = currentURI.displaySpec;
+              }
+              // At this point, we now have a URI.
+              // Let's try to unescape it using a character set
+              // in case the URI is not ASCII.
+              try {
+                var characterSet = browser.characterSet;
+                const textToSubURI = Components.classes["@mozilla.org/intl/texttosuburi;1"]
+                                               .getService(Components.interfaces.nsITextToSubURI);
+                readableURI = textToSubURI.unEscapeNonAsciiURI(characterSet, readableURI);
+              } catch (ex) { /* Do nothing. */ }
+
+              title = readableURI;
             }
 
             return this._setTabLabel(aTab, title, { isContentTitle });
           ]]>
         </body>
       </method>
 
       <method name="_setTabLabel">
@@ -2621,18 +2628,18 @@
             if (aCreateLazyBrowser && aURI != "about:blank") {
               lazyBrowserURI = aURIObject;
               aURI = "about:blank";
             }
 
             var uriIsAboutBlank = aURI == "about:blank";
 
             if (!aNoInitialLabel) {
-              if (isBlankPageURL(aURI)) {
-                t.setAttribute("label", this.mStringBundle.getString("tabs.emptyTabTitle"));
+              if (["about:blank", "about:newtab"].includes(aURI)) {
+                this.setAboutBlankTabTitle(t);
               } else {
                 // Set URL as label so that the tab isn't empty initially.
                 this.setInitialTabTitle(t, aURI, { beforeTabOpen: true });
               }
             }
 
             if (aIsPrerendered) {
               t.setAttribute("hidden", "true");
@@ -6264,17 +6271,26 @@
       <constructor>
         <![CDATA[
           this.mTabClipWidth = Services.prefs.getIntPref("browser.tabs.tabClipWidth");
 
           let { restoreTabsButton } = this;
           restoreTabsButton.setAttribute("label", this.tabbrowser.mStringBundle.getString("tabs.restoreLastTabs"));
 
           var tab = this.firstChild;
-          tab.label = this.tabbrowser.mStringBundle.getString("tabs.emptyTabTitle");
+          // If the first tab of the new window is going to be
+          // about:blank or about:newtab, set its title immediately to
+          // improve the perceived performance.
+          if (window.arguments && typeof window.arguments[0] == "string") {
+            const firstStartPage = window.arguments[0].split("|")[0].trim();
+            if (["about:blank", "about:newtab"].includes(firstStartPage)) {
+              this.tabbrowser.setAboutBlankTabTitle(tab);
+            }
+          }
+
           tab.setAttribute("onerror", "this.removeAttribute('image');");
 
           window.addEventListener("resize", this);
           window.addEventListener("load", this);
 
           Services.prefs.addObserver("privacy.userContext", this);
           this.observe(null, "nsPref:changed", "privacy.userContext.enabled");
 
--- a/browser/components/sessionstore/SessionStore.jsm
+++ b/browser/components/sessionstore/SessionStore.jsm
@@ -2700,16 +2700,18 @@ var SessionStoreInternal = {
 
     // If the page has a title, set it.
     if (activePageData) {
       if (activePageData.title &&
           activePageData.title != activePageData.url) {
         win.gBrowser.setInitialTabTitle(tab, activePageData.title, { isContentTitle: true });
       } else if (activePageData.url != "about:blank") {
         win.gBrowser.setInitialTabTitle(tab, activePageData.url);
+      } else {
+        win.gBrowser.setAboutBlankTabTitle(tab);
       }
     }
 
     // Restore the tab icon.
     if ("image" in tabData) {
       // Use the serialized contentPrincipal with the new icon load.
       let loadingPrincipal = Utils.deserializePrincipal(tabData.iconLoadingPrincipal);
       win.gBrowser.setIcon(tab, tabData.image, loadingPrincipal);