Bug 1517529 - Migrate safeMode dialog to Fluent for localization, r=Gijs,flod
authorcowlesni <cowlesni@msu.edu>
Mon, 21 Jan 2019 21:51:10 +0000
changeset 514753 5858163628554673e899f663747c81c9fbbfef27
parent 514752 85f4a4a750613b8693046f6d34c0f31e72406746
child 514754 8a49f013e0d0641b0eb187892bad82e17be26278
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersGijs, flod
bugs1517529
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1517529 - Migrate safeMode dialog to Fluent for localization, r=Gijs,flod Differential Revision: https://phabricator.services.mozilla.com/D16987
browser/base/content/safeMode.js
browser/base/content/safeMode.xul
browser/components/nsBrowserGlue.js
browser/locales/en-US/browser/safeMode.ftl
browser/locales/en-US/chrome/browser/safeMode.dtd
browser/locales/jar.mn
python/l10n/fluent_migrations/bug_1517529_safemode.py
toolkit/content/widgets/dialog.xml
--- a/browser/base/content/safeMode.js
+++ b/browser/base/content/safeMode.js
@@ -72,9 +72,11 @@ function onLoad() {
       // Hide the reset button is it's not supported.
       document.documentElement.getButton("extra1").hidden = true;
     }
   } else if (!ResetProfile.resetSupported()) {
     // Hide the reset button and text if it's not supported.
     document.documentElement.getButton("extra1").hidden = true;
     document.getElementById("resetProfileInstead").hidden = true;
   }
+  document.l10n.translateElements(document.querySelectorAll("label, description")).then(
+    () => window.sizeToContent());
 }
--- a/browser/base/content/safeMode.xul
+++ b/browser/base/content/safeMode.xul
@@ -1,50 +1,47 @@
 <?xml version="1.0"?>
 
 <!-- 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/. -->
 
-<!DOCTYPE prefwindow [
-<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
-%brandDTD;
-<!ENTITY % safeModeDTD SYSTEM "chrome://browser/locale/safeMode.dtd" >
-%safeModeDTD;
-<!ENTITY % resetProfileDTD SYSTEM "chrome://global/locale/resetProfile.dtd" >
-%resetProfileDTD;
-]>
-
 <?xml-stylesheet href="chrome://global/skin/"?>
 <?xml-stylesheet href="chrome://browser/content/safeMode.css"?>
 
 <dialog id="safeModeDialog"
             xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-            title="&safeModeDialog.title;"
+            data-l10n-id="safe-mode-window"
+            data-l10n-attrs="title,style"
             buttons="accept,extra1"
-            buttonlabelaccept="&startSafeMode.label;"
-            buttonlabelextra1="&refreshProfile.label;"
-            maxwidth="&window.maxWidth;"
+            buttonidaccept="start-safe-mode"
+            buttonidextra1="refresh-profile"
             ondialogaccept="return onDefaultButton()"
             ondialogcancel="onCancel();"
             ondialogextra1="return onExtra1()"
             onload="onLoad()">
 
+  <linkset>
+    <link rel="localization" href="branding/brand.ftl"/>
+    <link rel="localization" href="browser/safeMode.ftl"/>
+  </linkset>
+
   <script type="application/javascript" src="chrome://browser/content/safeMode.js"/>
 
+
   <vbox id="autoSafeMode" hidden="true">
-    <description>&autoSafeModeDescription3.label;</description>
+    <description data-l10n-id="auto-safe-mode-description"/>
   </vbox>
 
   <vbox id="safeMode">
-    <label>&safeModeDescription3.label;</label>
+    <label data-l10n-id="safe-mode-description" />
     <separator class="thin"/>
-    <label>&safeModeDescription5.label;</label>
+    <label data-l10n-id="safe-mode-description-details" />
     <separator class="thin"/>
-    <label id="resetProfileInstead">&refreshProfileInstead.label;</label>
+    <label id="resetProfileInstead" data-l10n-id="refresh-profile-instead"/>
   </vbox>
 
   <vbox id="resetProfile" hidden="true">
-    <label id="resetProfileInstead">&refreshProfileInstead.label;</label>
+    <label data-l10n-id="refresh-profile-instead" />
   </vbox>
 
   <separator class="thin"/>
 </dialog>
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -1002,16 +1002,24 @@ BrowserGlue.prototype = {
     if (Services.prefs.prefHasUserValue(PREF_PDFJS_ENABLED_CACHE_STATE)) {
       Services.ppmm.sharedData.set(
         "pdfjs.enabled",
         Services.prefs.getBoolPref(PREF_PDFJS_ENABLED_CACHE_STATE));
     } else {
       PdfJs.earlyInit();
     }
 
+    // Initialize the default l10n resource sources for L10nRegistry.
+    let locales = Services.locale.packagedLocales;
+    const greSource = new FileSource("toolkit", locales, "resource://gre/localization/{locale}/");
+    L10nRegistry.registerSource(greSource);
+
+    const appSource = new FileSource("app", locales, "resource://app/localization/{locale}/");
+    L10nRegistry.registerSource(appSource);
+
     // check if we're in safe mode
     if (Services.appinfo.inSafeMode) {
       Services.ww.openWindow(null, "chrome://browser/content/safeMode.xul",
                              "_blank", "chrome,centerscreen,modal,resizable=no", null);
     }
 
     // apply distribution customizations
     this._distributionCustomizer.applyCustomizations();
@@ -1068,24 +1076,16 @@ BrowserGlue.prototype = {
       sidebar_border: "rgba(255, 255, 255, 0.1)",
       author: vendorShortName,
     }, {
       useInDarkMode: true,
     });
 
     Normandy.init();
 
-    // Initialize the default l10n resource sources for L10nRegistry.
-    let locales = Services.locale.packagedLocales;
-    const greSource = new FileSource("toolkit", locales, "resource://gre/localization/{locale}/");
-    L10nRegistry.registerSource(greSource);
-
-    const appSource = new FileSource("app", locales, "resource://app/localization/{locale}/");
-    L10nRegistry.registerSource(appSource);
-
     SaveToPocket.init();
     Services.obs.notifyObservers(null, "browser-ui-startup-complete");
   },
 
   _checkForOldBuildUpdates() {
     // check for update if our build is old
     if (AppConstants.MOZ_UPDATER &&
         Services.prefs.getBoolPref("app.update.checkInstallTime")) {
new file mode 100644
--- /dev/null
+++ b/browser/locales/en-US/browser/safeMode.ftl
@@ -0,0 +1,16 @@
+# 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/.
+
+safe-mode-window =
+    .title = { -brand-short-name } Safe Mode
+    .style = max-width: 400px
+start-safe-mode =
+    .label = Start in Safe Mode
+refresh-profile =
+    .label = Refresh { -brand-short-name }
+safe-mode-description = Safe Mode is a special mode of { -brand-short-name } that can be used to troubleshoot issues.
+safe-mode-description-details = Your add-ons and custom settings will be temporarily disabled, and { -brand-short-name } features may not perform as they currently do.
+refresh-profile-instead = You can also skip troubleshooting and try refreshing { -brand-short-name }.
+# Shown on the safe mode dialog after multiple startup crashes. 
+auto-safe-mode-description = { -brand-short-name } closed unexpectedly while starting. This might be caused by add-ons or other problems. You can try to resolve the problem by troubleshooting in Safe Mode.
deleted file mode 100644
--- a/browser/locales/en-US/chrome/browser/safeMode.dtd
+++ /dev/null
@@ -1,17 +0,0 @@
-<!-- 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/. -->
-
-<!ENTITY safeModeDialog.title         "&brandShortName; Safe Mode">
-<!ENTITY window.maxWidth              "400">
-
-<!ENTITY startSafeMode.label          "Start in Safe Mode">
-<!ENTITY refreshProfile.label         "Refresh &brandShortName;">
-
-<!ENTITY safeModeDescription3.label   "Safe Mode is a special mode of &brandShortName; that can be used to troubleshoot issues.">
-<!ENTITY safeModeDescription5.label   "Your add-ons and custom settings will be temporarily disabled, and &brandShortName; features may not perform as they currently do.">
-
-<!ENTITY refreshProfileInstead.label  "You can also skip troubleshooting and try refreshing &brandShortName;.">
-
-<!-- LOCALIZATION NOTE (autoSafeModeDescription3.label): Shown on the safe mode dialog after multiple startup crashes. See also chrome/global/resetProfile.dtd -->
-<!ENTITY autoSafeModeDescription3.label "&brandShortName; closed unexpectedly while starting. This might be caused by add-ons or other problems. You can try to resolve the problem by troubleshooting in Safe Mode.">
--- a/browser/locales/jar.mn
+++ b/browser/locales/jar.mn
@@ -22,17 +22,16 @@
     locale/browser/baseMenuOverlay.dtd             (%chrome/browser/baseMenuOverlay.dtd)
     locale/browser/browser.properties              (%chrome/browser/browser.properties)
     locale/browser/customizableui/customizableWidgets.properties (%chrome/browser/customizableui/customizableWidgets.properties)
     locale/browser/lightweightThemes.properties    (%chrome/browser/lightweightThemes.properties)
     locale/browser/uiDensity.properties            (%chrome/browser/uiDensity.properties)
     locale/browser/pageInfo.dtd                    (%chrome/browser/pageInfo.dtd)
     locale/browser/pageInfo.properties             (%chrome/browser/pageInfo.properties)
     locale/browser/pocket.properties               (%chrome/browser/pocket.properties)
-    locale/browser/safeMode.dtd                    (%chrome/browser/safeMode.dtd)
     locale/browser/search.properties               (%chrome/browser/search.properties)
     locale/browser/siteData.properties             (%chrome/browser/siteData.properties)
     locale/browser/sitePermissions.properties      (%chrome/browser/sitePermissions.properties)
     locale/browser/setDesktopBackground.dtd        (%chrome/browser/setDesktopBackground.dtd)
     locale/browser/shellservice.properties         (%chrome/browser/shellservice.properties)
     locale/browser/tabbrowser.properties           (%chrome/browser/tabbrowser.properties)
     locale/browser/taskbar.properties              (%chrome/browser/taskbar.properties)
     locale/browser/translation.dtd                 (%chrome/browser/translation.dtd)
new file mode 100644
--- /dev/null
+++ b/python/l10n/fluent_migrations/bug_1517529_safemode.py
@@ -0,0 +1,117 @@
+# coding=utf8
+
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+from __future__ import absolute_import
+import fluent.syntax.ast as FTL
+from fluent.migrate.helpers import transforms_from
+from fluent.migrate.helpers import MESSAGE_REFERENCE, TERM_REFERENCE
+from fluent.migrate import COPY, CONCAT, REPLACE
+
+def migrate(ctx):
+    """Bug 1517529 - Migrate safeMode from DTD to Fluent, part {index}."""
+
+    ctx.add_transforms(
+        'browser/browser/safeMode.ftl',
+        'browser/browser/safeMode.ftl',
+        [
+            FTL.Message(
+                id=FTL.Identifier('safe-mode-window'),
+                attributes=[
+                    FTL.Attribute(
+                        FTL.Identifier('title'),
+                        value=REPLACE(
+                            'browser/chrome/browser/safeMode.dtd',
+                            'safeModeDialog.title',
+                            {
+                                "&brandShortName;": TERM_REFERENCE("brand-short-name")
+                            }
+                        )
+                    ),
+                    FTL.Attribute(
+                        FTL.Identifier('style'),
+                        value=CONCAT(
+                            FTL.TextElement('max-width: '),
+                            COPY(
+                                'browser/chrome/browser/safeMode.dtd',
+                                'window.maxWidth'
+                            ),
+                            FTL.TextElement('px')
+                        )
+                    )
+                ]
+            ),
+        ]
+    ),
+    ctx.add_transforms(
+        'browser/browser/safeMode.ftl',
+        'browser/browser/safeMode.ftl',
+        transforms_from(
+"""
+start-safe-mode = 
+    .label = { COPY("browser/chrome/browser/safeMode.dtd", "startSafeMode.label") }
+"""
+        )
+    ),
+    ctx.add_transforms(
+        'browser/browser/safeMode.ftl',
+        'browser/browser/safeMode.ftl',
+        [
+            FTL.Message(
+                id=FTL.Identifier('refresh-profile'),
+                attributes=[
+                    FTL.Attribute(
+                        FTL.Identifier('label'),
+                        value=REPLACE(
+                            'browser/chrome/browser/safeMode.dtd',
+                            'refreshProfile.label',
+                            {
+                                "&brandShortName;": TERM_REFERENCE("brand-short-name")
+                            }
+                        )
+                    )
+                ]
+            ),
+            FTL.Message(
+                id=FTL.Identifier('safe-mode-description'),
+                value=REPLACE(
+                    'browser/chrome/browser/safeMode.dtd',
+                    'safeModeDescription3.label',
+                    {
+                        "&brandShortName;": TERM_REFERENCE("brand-short-name")
+                    }
+                )
+            ),
+            FTL.Message(
+                id=FTL.Identifier('safe-mode-description-details'),
+                value=REPLACE(
+                    'browser/chrome/browser/safeMode.dtd',
+                    'safeModeDescription5.label',
+                    {
+                        "&brandShortName;": TERM_REFERENCE("brand-short-name")
+                    }
+                )
+            ),
+            FTL.Message(
+                id=FTL.Identifier('refresh-profile-instead'),
+                value=REPLACE(
+                    'browser/chrome/browser/safeMode.dtd',
+                    'refreshProfileInstead.label',
+                    {
+                        "&brandShortName;": TERM_REFERENCE("brand-short-name")
+                    }
+                )
+            ),
+            FTL.Message(
+                id=FTL.Identifier('auto-safe-mode-description'),
+                value=REPLACE(
+                    'browser/chrome/browser/safeMode.dtd',
+                    'autoSafeModeDescription3.label',
+                    {
+                        "&brandShortName;": TERM_REFERENCE("brand-short-name")
+                    }
+                )
+            )
+        ]
+    )
--- a/toolkit/content/widgets/dialog.xml
+++ b/toolkit/content/widgets/dialog.xml
@@ -279,23 +279,23 @@
 
             // don't override custom labels with pre-defined labels on explicit buttons
             if (!button.hasAttribute("label")) {
               // dialog attributes override the default labels in dialog.properties
               if (this.hasAttribute("buttonlabel" + dlgtype)) {
                 button.setAttribute("label", this.getAttribute("buttonlabel" + dlgtype));
                 if (this.hasAttribute("buttonaccesskey" + dlgtype))
                   button.setAttribute("accesskey", this.getAttribute("buttonaccesskey" + dlgtype));
+              } else if (this.hasAttribute("buttonid" + dlgtype)) {
+                document.l10n.setAttributes(button, this.getAttribute("buttonid" + dlgtype));
               } else if (dlgtype != "extra1" && dlgtype != "extra2") {
                 button.setAttribute("label", this.mStrBundle.GetStringFromName("button-" + dlgtype));
                 var accessKey = this.mStrBundle.GetStringFromName("accesskey-" + dlgtype);
                 if (accessKey)
                   button.setAttribute("accesskey", accessKey);
-              } else if (this.hasAttribute("buttonid" + dlgtype)) {
-                document.l10n.setAttributes(button, this.getAttribute("buttonid" + dlgtype));
               }
             }
             // allow specifying alternate icons in the dialog header
             if (!button.hasAttribute("icon")) {
               // if there's an icon specified, use that
               if (this.hasAttribute("buttonicon" + dlgtype))
                 button.setAttribute("icon", this.getAttribute("buttonicon" + dlgtype));
               // otherwise set defaults