Backed out changeset 16d82f57e0fb (bug 1602808) for bc failures on browser_privatebrowsing_windowtitle.js . CLOSED TREE
authorNarcis Beleuzu <nbeleuzu@mozilla.com>
Wed, 01 Apr 2020 10:24:08 +0300
changeset 521530 205d1b4e8f6946fa8ef35c86febdd338c1159715
parent 521529 01880a4c9ec8ed25d8a8961fa55833435ed47eae
child 521531 38bf1856442127f04c282babf9abfb082b790664
push id111692
push usernbeleuzu@mozilla.com
push dateWed, 01 Apr 2020 07:24:59 +0000
treeherderautoland@205d1b4e8f69 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1602808
milestone76.0a1
backs out16d82f57e0fb2b21d0709baebc89379f9d9aab1a
first release with
nightly linux32
205d1b4e8f69 / 76.0a1 / 20200401095134 / files
nightly linux64
205d1b4e8f69 / 76.0a1 / 20200401095134 / files
nightly mac
205d1b4e8f69 / 76.0a1 / 20200401095134 / files
nightly win32
205d1b4e8f69 / 76.0a1 / 20200401095134 / files
nightly win64
205d1b4e8f69 / 76.0a1 / 20200401095134 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset 16d82f57e0fb (bug 1602808) for bc failures on browser_privatebrowsing_windowtitle.js . CLOSED TREE
browser/base/content/browser.js
browser/base/content/browser.xhtml
browser/base/content/tabbrowser.js
browser/components/extensions/parent/ext-browser.js
browser/components/extensions/parent/ext-windows.js
browser/locales/en-US/browser/browser.ftl
browser/locales/en-US/chrome/browser/browser.dtd
browser/modules/WindowsPreviewPerTab.jsm
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -8364,23 +8364,16 @@ var gPrivateBrowsingUI = {
     document.getElementById("Tools:Sanitize").setAttribute("disabled", "true");
 
     if (window.location.href != AppConstants.BROWSER_CHROME_URL) {
       return;
     }
 
     // Adjust the window's title
     let docElement = document.documentElement;
-    if (!PrivateBrowsingUtils.permanentPrivateBrowsing) {
-      docElement.title = docElement.getAttribute("title_privatebrowsing");
-      docElement.setAttribute(
-        "titlemodifier",
-        docElement.getAttribute("titlemodifier_privatebrowsing")
-      );
-    }
     docElement.setAttribute(
       "privatebrowsingmode",
       PrivateBrowsingUtils.permanentPrivateBrowsing ? "permanent" : "temporary"
     );
     gBrowser.updateTitlebar();
 
     if (PrivateBrowsingUtils.permanentPrivateBrowsing) {
       // Adjust the New Window menu entries
--- a/browser/base/content/browser.xhtml
+++ b/browser/base/content/browser.xhtml
@@ -35,36 +35,22 @@
 <!DOCTYPE window [
 #include browser-doctype.inc
 ]>
 
 <html id="main-window"
         xmlns:html="http://www.w3.org/1999/xhtml"
         xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         xmlns="http://www.w3.org/1999/xhtml"
-        title_normal="&mainWindow.title;"
-#ifdef XP_MACOSX
-        title_privatebrowsing="&mainWindow.title;&mainWindow.titlemodifiermenuseparator;&mainWindow.titlePrivateBrowsingSuffix;"
-        titledefault="&mainWindow.title;"
-        titlemodifier=""
-        titlemodifier_normal=""
-        titlemodifier_privatebrowsing="&mainWindow.titlePrivateBrowsingSuffix;"
-#else
-        title_privatebrowsing="&mainWindow.titlemodifier; &mainWindow.titlePrivateBrowsingSuffix;"
-        titlemodifier="&mainWindow.titlemodifier;"
-        titlemodifier_normal="&mainWindow.titlemodifier;"
-        titlemodifier_privatebrowsing="&mainWindow.titlemodifier; &mainWindow.titlePrivateBrowsingSuffix;"
-#endif
 #ifdef XP_WIN
         chromemargin="0,2,2,2"
 #else
         chromemargin="0,-1,-1,-1"
 #endif
         tabsintitlebar="true"
-        titlemenuseparator="&mainWindow.titlemodifiermenuseparator;"
         windowtype="navigator:browser"
         macanimationtype="document"
         screenX="4" screenY="4"
         fullscreenbutton="true"
         sizemode="normal"
         retargetdocumentfocus="urlbar-input"
         scrolling="false"
         persist="screenX screenY width height sizemode"
@@ -78,17 +64,19 @@
   <link rel="localization" href="browser/browserContext.ftl"/>
   <link rel="localization" href="browser/browserSets.ftl"/>
   <link rel="localization" href="browser/menubar.ftl"/>
   <link rel="localization" href="browser/protectionsPanel.ftl"/>
   <link rel="localization" href="browser/appmenu.ftl"/>
   <link rel="localization" href="preview/interventions.ftl"/>
   <link rel="localization" href="browser/sidebarMenu.ftl"/>
 
-  <title>&mainWindow.title;</title>
+  <title
+    data-l10n-id="browser-main-window-title"
+    data-l10n-args='{"mode": "default"}'></title>
 
 # All JS files which are needed by browser.xhtml and other top level windows to
 # support MacOS specific features *must* go into the global-scripts.inc file so
 # that they can be shared with macWindow.inc.xhtml.
 #include global-scripts.inc
 
 <script>
   /* eslint-env mozilla/browser-window */
--- a/browser/base/content/tabbrowser.js
+++ b/browser/base/content/tabbrowser.js
@@ -203,16 +203,23 @@
     _multiSelectChangeSelected: false,
 
     /**
      * Tab close requests are ignored if the window is closing anyway,
      * e.g. when holding Ctrl+W.
      */
     _windowIsClosing: false,
 
+    /**
+     * We'll use this to cache the accessor to the title element.
+     * It's important that the defualt is `undefined`, so that it
+     * can be set to `null` by the `querySelector`.
+     */
+    _titleElement: undefined,
+
     preloadedBrowser: null,
 
     /**
      * This defines a proxy which allows us to access browsers by
      * index without actually creating a full array of browsers.
      */
     browsers: new Proxy([], {
       has: (target, name) => {
@@ -908,73 +915,89 @@
           description: aDescription,
           previewImageURL: aPreviewImage,
         };
         PlacesUtils.history.update(pageInfo).catch(Cu.reportError);
       }
     },
 
     getWindowTitleForBrowser(aBrowser) {
-      var newTitle = "";
-      var docElement = document.documentElement;
-      var sep = docElement.getAttribute("titlemenuseparator");
-      let tab = this.getTabForBrowser(aBrowser);
-      let docTitle;
-
-      if (tab._labelIsContentTitle) {
-        // Strip out any null bytes in the content title, since the
-        // underlying widget implementations of nsWindow::SetTitle pass
-        // null-terminated strings to system APIs.
-        docTitle = tab.getAttribute("label").replace(/\0/g, "");
-      }
-
-      if (!docTitle) {
-        docTitle = docElement.getAttribute("titledefault");
-      }
-
-      var modifier = docElement.getAttribute("titlemodifier");
-      if (docTitle) {
-        newTitle += docElement.getAttribute("titlepreface") || "";
-        newTitle += docTitle;
-        if (modifier) {
-          newTitle += sep;
-        }
-      }
-      newTitle += modifier;
+      let title = "";
+
+      let docElement = document.documentElement;
 
       // If location bar is hidden and the URL type supports a host,
       // add the scheme and host to the title to prevent spoofing.
       // XXX https://bugzilla.mozilla.org/show_bug.cgi?id=22183#c239
       try {
         if (docElement.getAttribute("chromehidden").includes("location")) {
           const uri = Services.io.createExposableURI(aBrowser.currentURI);
-          if (uri.scheme === "about") {
-            newTitle = `${uri.spec}${sep}${newTitle}`;
-          } else if (uri.scheme === "moz-extension") {
+          let prefix = uri.prePath;
+          if (uri.scheme == "about") {
+            prefix = uri.spec;
+          } else if (uri.scheme == "moz-extension") {
             const ext = WebExtensionPolicy.getByHostname(uri.host);
             if (ext && ext.name) {
-              const prefix = document.querySelector("#urlbar-label-extension")
-                .value;
-              newTitle = `${prefix} (${ext.name})${sep}${newTitle}`;
-            } else {
-              newTitle = `${uri.prePath}${sep}${newTitle}`;
+              let extensionLabel = document.getElementById(
+                "urlbar-label-extension"
+              );
+              prefix = `${extensionLabel.value} (${ext.name})`;
             }
-          } else {
-            newTitle = `${uri.prePath}${sep}${newTitle}`;
           }
+          title = prefix + " - ";
         }
       } catch (e) {
         // ignored
       }
 
-      return newTitle;
-    },
-
-    updateTitlebar() {
-      document.title = this.getWindowTitleForBrowser(this.selectedBrowser);
+      if (docElement.hasAttribute("titlepreface")) {
+        title += docElement.getAttribute("titlepreface");
+      }
+
+      let tab = this.getTabForBrowser(aBrowser);
+
+      if (tab._labelIsContentTitle) {
+        // Strip out any null bytes in the content title, since the
+        // underlying widget implementations of nsWindow::SetTitle pass
+        // null-terminated strings to system APIs.
+        title += tab.getAttribute("label").replace(/\0/g, "");
+      }
+
+      let mode =
+        docElement.getAttribute("privatebrowsingmode") == "temporary"
+          ? "private"
+          : "default";
+
+      if (title) {
+        return {
+          id:
+            mode == "private"
+              ? "browser-main-window-content-title-private"
+              : "browser-main-window-content-title-default",
+          args: {
+            title,
+          },
+        };
+      }
+      return {
+        id: "browser-main-window-title",
+        args: {
+          mode,
+        },
+      };
+    },
+
+    async updateTitlebar() {
+      if (!this._titleElement) {
+        this._titleElement = document.documentElement.querySelector("title");
+      }
+
+      let { id, args } = this.getWindowTitleForBrowser(this.selectedBrowser);
+      document.l10n.setAttributes(this._titleElement, id, args);
+      await document.l10n.translateElements([this._titleElement]);
     },
 
     updateCurrentBrowser(aForceUpdate) {
       let newBrowser = this.getBrowserAtIndex(this.tabContainer.selectedIndex);
       if (this.selectedBrowser == newBrowser && !aForceUpdate) {
         return;
       }
 
--- a/browser/components/extensions/parent/ext-browser.js
+++ b/browser/components/extensions/parent/ext-browser.js
@@ -999,20 +999,24 @@ class Window extends WindowBase {
     }
   }
 
   get _title() {
     return this.window.document.title;
   }
 
   setTitlePreface(titlePreface) {
-    this.window.document.documentElement.setAttribute(
-      "titlepreface",
-      titlePreface
-    );
+    if (!titlePreface) {
+      this.window.document.documentElement.removeAttribute("titlepreface");
+    } else {
+      this.window.document.documentElement.setAttribute(
+        "titlepreface",
+        titlePreface
+      );
+    }
   }
 
   get focused() {
     return this.window.document.hasFocus();
   }
 
   get top() {
     return this.window.screenY;
--- a/browser/components/extensions/parent/ext-windows.js
+++ b/browser/components/extensions/parent/ext-windows.js
@@ -373,17 +373,17 @@ this.windows = class extends ExtensionAP
             }
             if (createData.titlePreface !== null) {
               win.setTitlePreface(createData.titlePreface);
             }
             return win.convert({ populate: true });
           });
         },
 
-        update: function(windowId, updateInfo) {
+        update: async function(windowId, updateInfo) {
           if (updateInfo.state !== null && updateInfo.state != "normal") {
             if (
               updateInfo.left !== null ||
               updateInfo.top !== null ||
               updateInfo.width !== null ||
               updateInfo.height !== null
             ) {
               return Promise.reject({
@@ -410,22 +410,22 @@ this.windows = class extends ExtensionAP
             // Bug 1257497 - Firefox can't cancel attention actions.
             win.window.getAttention();
           }
 
           win.updateGeometry(updateInfo);
 
           if (updateInfo.titlePreface !== null) {
             win.setTitlePreface(updateInfo.titlePreface);
-            win.window.gBrowser.updateTitlebar();
+            await win.window.gBrowser.updateTitlebar();
           }
 
           // TODO: All the other properties, focused=false...
 
-          return Promise.resolve(win.convert());
+          return win.convert();
         },
 
         remove: function(windowId) {
           let window = windowTracker.getWindow(windowId, context);
           if (!context.canAccessWindow(window)) {
             return Promise.reject({
               message: `Invalid window ID: ${windowId}`,
             });
--- a/browser/locales/en-US/browser/browser.ftl
+++ b/browser/locales/en-US/browser/browser.ftl
@@ -1,13 +1,55 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 
+# This is the default window title in case there is no content
+# title to be displayed.
+#
+# Depending on the $mode, the string will look like this (in en-US):
+#
+# "default" - "Mozilla Firefox"
+# "private" - "Mozilla Firefox (Private Browsing)"
+#
+# Variables
+#   $mode (String) - "private" in case of a private browsing mode, "default" otherwise.
+browser-main-window-title = { $mode ->
+        [private] { -brand-full-name } (Private Browsing)
+       *[default] { -brand-full-name }
+    }
+
+## This is the default window title in case there is content
+## title to be displayed.
+##
+## On macOS the title doesn't include the brand name, on all other
+## platforms it does.
+##
+## For example, in private mode on Windows, the title will be:
+## "Example Title - Mozilla Firefox (Private Browsing)"
+##
+## while on macOS in default mode it will be:
+## "Example Title"
+##
+## Variables
+##   $title (String) - Content title string.
+
+browser-main-window-content-title-default = { PLATFORM() ->
+    [macos] { $title }
+   *[other] { $title } - { -brand-full-name }
+}
+
+browser-main-window-content-title-private = { PLATFORM() ->
+    [macos] { $title } - (Private Browsing)
+   *[other] { $title } - { -brand-full-name } (Private Browsing)
+}
+
+##
+
 urlbar-identity-button =
     .aria-label = View site information
 
 ## Tooltips for images appearing in the address bar
 
 urlbar-services-notification-anchor =
     .tooltiptext = Open install message panel
 urlbar-web-notification-anchor =
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -1,25 +1,15 @@
 <!-- This Source Code Form is subject to the terms of the Mozilla Public
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
 <!-- LOCALIZATION NOTE : FILE This file contains the browser main menu items -->
 <!-- LOCALIZATION NOTE : FILE Do not translate commandkeys -->
 
-<!-- LOCALIZATION NOTE (mainWindow.title): DONT_TRANSLATE -->
-<!ENTITY mainWindow.title "&brandFullName;">
-<!-- LOCALIZATION NOTE (mainWindow.titlemodifier) : DONT_TRANSLATE -->
-<!ENTITY mainWindow.titlemodifier "&brandFullName;">
-<!-- LOCALIZATION NOTE (mainWindow.titlemodifiermenuseparator): DONT_TRANSLATE -->
-<!ENTITY mainWindow.titlemodifiermenuseparator " - ">
-<!-- LOCALIZATION NOTE (mainWindow.titlePrivateBrowsingSuffix): This will be appended to the window's title
-                                                                inside the private browsing mode -->
-<!ENTITY mainWindow.titlePrivateBrowsingSuffix "(Private Browsing)">
-
 <!ENTITY appmenu.tooltip                     "Open menu">
 <!ENTITY navbarOverflow.label                "More tools…">
 
 <!-- Tab context menu -->
 
 <!-- LOCALIZATION NOTE (pinTab.label, unpinTab.label): "Pin" is being
 used as a metaphor for expressing the fact that these tabs are "pinned" to the
 left edge of the tabstrip. Really we just want the string to express the idea
--- a/browser/modules/WindowsPreviewPerTab.jsm
+++ b/browser/modules/WindowsPreviewPerTab.jsm
@@ -242,22 +242,29 @@ PreviewController.prototype = {
     AeroPeek.resetCacheTimer();
     return PageThumbs.captureToCanvas(this.linkedBrowser, this.canvasPreview, {
       fullScale: aFullScale,
     }).catch(e => Cu.reportError(e));
     // If we're updating the canvas, then we're in the middle of a peek so
     // don't discard the cache of previews.
   },
 
-  updateTitleAndTooltip() {
-    let title = this.win.tabbrowser.getWindowTitleForBrowser(
+  async updateTitleAndTooltip() {
+    let { id, args } = this.win.tabbrowser.getWindowTitleForBrowser(
       this.linkedBrowser
     );
-    this.preview.title = title;
-    this.preview.tooltip = title;
+    let title = await this.win.tabbrowser.ownerDocument.l10n.formatValue(
+      id,
+      args
+    );
+    // Since the previous call is async, the `this.preview` may become empty.
+    if (this.preview) {
+      this.preview.title = title;
+      this.preview.tooltip = title;
+    }
   },
 
   // nsITaskbarPreviewController
 
   // window width and height, not browser
   get width() {
     return this.win.width;
   },