Bug 1453540 - Migrate the remaining DTD entries to FTL. r?gijs,flod draft
authorZibi Braniecki <zbraniecki@mozilla.com>
Tue, 17 Apr 2018 13:17:22 -0700
changeset 784490 1ce812e1c6cb7e2767a49f76064493d575f80ddf
parent 783746 5ded36cb383d3ccafd9b6c231c5120dcdae196a2
push id106950
push userbmo:gandalf@aviary.pl
push dateWed, 18 Apr 2018 17:47:14 +0000
reviewersgijs, flod
bugs1453540
milestone61.0a1
Bug 1453540 - Migrate the remaining DTD entries to FTL. r?gijs,flod MozReview-Commit-ID: Aw0a14zPRWk
browser/components/preferences/containers.xul
browser/components/preferences/in-content/main.xul
browser/components/preferences/in-content/preferences.xul
browser/components/preferences/in-content/privacy.xul
browser/components/preferences/in-content/sync.xul
browser/locales/en-US/browser/preferences/preferences.ftl
browser/locales/en-US/chrome/browser/preferences/content.dtd
browser/locales/en-US/chrome/browser/preferences/privacy.dtd
browser/locales/en-US/chrome/browser/preferences/sync.dtd
browser/locales/jar.mn
browser/themes/shared/incontentprefs/preferences.inc.css
python/l10n/fluent_migrations/bug_1453540_preferences_remaining_dtd.py
--- a/browser/components/preferences/containers.xul
+++ b/browser/components/preferences/containers.xul
@@ -12,17 +12,17 @@
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         data-l10n-attrs="title, style"
         onload="gContainersManager.onLoad();"
         onunload="gContainersManager.uninit();"
         persist="screenX screenY width height"
         onkeypress="gContainersManager.onWindowKeyPress(event);">
 
   <link rel="localization" href="browser/preferences/containers.ftl"/>
-  <script type="text/javascript" src="chrome://global/content/l10n.js"></script>
+  <script type="application/javascript" src="chrome://global/content/l10n.js"></script>
 
   <script src="chrome://global/content/treeUtils.js"/>
   <script src="chrome://browser/content/preferences/containers.js"/>
 
   <keyset>
     <key data-l10n-id="containers-window-close" modifiers="accel" oncommand="window.close();"/>
   </keyset>
 
--- a/browser/components/preferences/in-content/main.xul
+++ b/browser/components/preferences/in-content/main.xul
@@ -315,22 +315,21 @@
 
   <hbox id="translationBox" hidden="true">
     <hbox align="center" flex="1">
       <checkbox id="translate" preference="browser.translation.detectLanguage"
                 data-l10n-id="translate-web-pages"
                 onsyncfrompreference="return gMainPane.updateButtons('translateButton',
                                               'browser.translation.detectLanguage');"/>
       <hbox id="bingAttribution" hidden="true" align="center">
-        <label>&translation.options.attribution.beforeLogo;</label>
-        <separator orient="vertical" class="thin"/>
-        <image id="translationAttributionImage" aria-label="Microsoft Translator"
-               src="chrome://browser/content/microsoft-translator-attribution.png"/>
-        <separator orient="vertical" class="thin"/>
-        <label>&translation.options.attribution.afterLogo;</label>
+        <label data-l10n-id="translate-attribution">
+          <html:img id="translationAttributionImage" aria-label="Microsoft Translator"
+            src="chrome://browser/content/microsoft-translator-attribution.png"
+            data-l10n-name="logo"/>
+        </label>
       </hbox>
     </hbox>
     <button id="translateButton"
             class="accessory-button"
             data-l10n-id="translate-exceptions"/>
   </hbox>
   <checkbox id="checkSpelling"
           data-l10n-id="check-user-spelling"
--- a/browser/components/preferences/in-content/preferences.xul
+++ b/browser/components/preferences/in-content/preferences.xul
@@ -13,45 +13,29 @@
   href="chrome://browser/content/preferences/handlers.css"?>
 <?xml-stylesheet href="chrome://browser/skin/preferences/applications.css"?>
 <?xml-stylesheet href="chrome://browser/skin/preferences/in-content/search.css"?>
 <?xml-stylesheet href="chrome://browser/skin/preferences/in-content/containers.css"?>
 <?xml-stylesheet href="chrome://browser/skin/preferences/in-content/privacy.css"?>
 
 <!DOCTYPE page [
 <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
-<!ENTITY % passwordManagerDTD SYSTEM "chrome://passwordmgr/locale/passwordManager.dtd">
 <!ENTITY % historyDTD SYSTEM "chrome://mozapps/locale/update/history.dtd">
 <!ENTITY % certManagerDTD SYSTEM "chrome://pippki/locale/certManager.dtd">
 <!ENTITY % deviceManangerDTD SYSTEM "chrome://pippki/locale/deviceManager.dtd">
-<!ENTITY % privacyDTD SYSTEM "chrome://browser/locale/preferences/privacy.dtd">
-<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd">
-<!ENTITY % syncDTD SYSTEM "chrome://browser/locale/preferences/sync.dtd">
 <!ENTITY % sanitizeDTD SYSTEM "chrome://browser/locale/sanitize.dtd">
-<!ENTITY % aboutHomeDTD SYSTEM "chrome://browser/locale/aboutHome.dtd">
-<!ENTITY % contentDTD SYSTEM "chrome://browser/locale/preferences/content.dtd">
 <!ENTITY % aboutDialogDTD SYSTEM "chrome://browser/locale/aboutDialog.dtd" >
 %aboutDialogDTD;
 %brandDTD;
-%passwordManagerDTD;
 %historyDTD;
 %certManagerDTD;
 %deviceManangerDTD;
-%privacyDTD;
-%syncBrandDTD;
-%syncDTD;
 %sanitizeDTD;
-%aboutHomeDTD;
-%contentDTD;
 ]>
 
-#ifdef XP_WIN
-#define USE_WIN_TITLE_STYLE
-#endif
-
 <page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
       xmlns:html="http://www.w3.org/1999/xhtml"
       disablefastfind="true"
       data-l10n-id="pref-page"
       data-l10n-attrs="title">
 
   <link rel="localization" href="branding/brand.ftl"/>
   <link rel="localization" href="browser/branding/sync-brand.ftl"/>
--- a/browser/components/preferences/in-content/privacy.xul
+++ b/browser/components/preferences/in-content/privacy.xul
@@ -61,40 +61,38 @@
 </groupbox>
 
 <!-- History -->
 <groupbox id="historyGroup" data-category="panePrivacy" hidden="true">
   <caption><label data-l10n-id="history-header"/></caption>
   <hbox align="center">
     <label id="historyModeLabel"
            control="historyMode"
-           accesskey="&historyHeader2.pre.accesskey;">&historyHeader2.pre.label;
-    </label>
+           data-l10n-id="history-remember-label"/>
     <!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
     <hbox>
       <menulist id="historyMode">
         <menupopup>
-          <menuitem label="&historyHeader.remember.label;"
+          <menuitem data-l10n-id="history-remember-option-all"
                     value="remember"
                     search-l10n-ids="history-remember-description"/>
-          <menuitem label="&historyHeader.dontremember.label;"
+          <menuitem data-l10n-id="history-remember-option-never"
                     value="dontremember"
                     search-l10n-ids="history-dontremember-description"/>
-          <menuitem label="&historyHeader.custom.label;"
+          <menuitem data-l10n-id="history-remember-option-custom"
                     value="custom"
                     search-l10n-ids="
                       history-private-browsing-permanent.label,
                       history-remember-option.label,
                       history-remember-search-option.label,
                       history-clear-on-close-option.label,
                       history-clear-on-close-settings.label"/>
         </menupopup>
       </menulist>
     </hbox>
-    <label>&historyHeader.post.label;</label>
   </hbox>
   <hbox>
     <deck id="historyPane" flex="1">
       <vbox id="historyRememberPane">
         <hbox align="center" flex="1">
           <vbox flex="1">
             <description
               class="description-with-side-element"
--- a/browser/components/preferences/in-content/sync.xul
+++ b/browser/components/preferences/in-content/sync.xul
@@ -41,26 +41,33 @@
         </hbox>
         <hbox align="center" flex="1">
           <html:a id="noFxaSignUp"
                   class="openLink"
                   data-l10n-id="sync-signedout-account-create" />
         </hbox>
       </vbox>
     </hbox>
-    <label class="fxaMobilePromo">
-        &mobilePromo3.start;<!-- We put these comments to avoid inserting white spaces
-        --><image class="androidLink"></image><label id="fxaMobilePromo-android"
-                  class="text-link"><!--
-        -->&mobilePromo3.androidLink;</label><!--
-        -->&mobilePromo3.iOSBefore;<!--
-        --><image class="iOSLink"></image><label id="fxaMobilePromo-ios"
-                  class="text-link"><!--
-        -->&mobilePromo3.iOSLink;</label><!--
-        -->&mobilePromo3.end;
+    <label class="fxaMobilePromo" data-l10n-id="sync-mobile-promo">
+      <html:img
+        src="chrome://browser/skin/preferences/in-content/logo-android.svg"
+        data-l10n-name="android-icon"
+        class="androidIcon"/>
+      <html:a
+        id="fxaMobilePromo-android"
+        data-l10n-name="android-link"
+        class="text-link" target="_blank"/>
+      <html:img
+        src="chrome://browser/skin/preferences/in-content/logo-ios.svg"
+        data-l10n-name="ios-icon"
+        class="iOSIcon"/>
+      <html:a
+        id="fxaMobilePromo-ios"
+        data-l10n-name="ios-link"
+        class="text-link" target="_blank"/>
     </label>
   </groupbox>
 
   <vbox id="hasFxaAccount">
     <hbox>
       <vbox id="fxaContentWrapper" flex="1">
         <groupbox id="fxaGroup">
           <caption class="search-header" hidden="true"><label data-l10n-id="pane-sync-title"/></caption>
--- a/browser/locales/en-US/browser/preferences/preferences.ftl
+++ b/browser/locales/en-US/browser/preferences/preferences.ftl
@@ -215,16 +215,20 @@ choose-language-description = Choose you
 choose-button =
     .label = Choose…
     .accesskey = o
 
 translate-web-pages =
     .label = Translate web content
     .accesskey = T
 
+# The <img> element is replaced by the logo of the provider
+# used to provide machine translations for web pages.
+translate-attribution = Translations by <img data-l10n-name="logo"/>
+
 translate-exceptions =
     .label = Exceptions…
     .accesskey = x
 
 check-user-spelling =
     .label = Check your spelling as you type
     .accesskey = t
 
@@ -493,16 +497,26 @@ sync-signedout-description = Synchronize
 sync-signedout-account-title = Connect with a { -fxaccount-brand-name }
 sync-signedout-account-create = Don’t have an account? Get started
     .accesskey = c
 
 sync-signedout-account-signin =
     .label = Sign In…
     .accesskey = I
 
+# This message contains two links and two icon images.
+#   `<img data-l10n-name="android-icon"/>` - Android logo icon
+#   `<a data-l10n-name="android-link">` - Link to Android Download
+#   `<img data-l10n-name="ios-icon">` - iOS logo icon
+#   `<a data-l10n-name="ios-link">` - Link to iOS Download
+#
+# They can be moved within the sentence as needed to adapt
+# to your language, but should not be changed or translated.
+sync-mobile-promo = Download Firefox for <img data-l10n-name="android-icon"/> <a data-l10n-name="android-link">Android</a> or <img data-l10n-name="ios-icon"/> <a data-l10n-name="ios-link">iOS</a> to sync with your mobile device.
+
 ## Sync Section - Signed in
 
 sync-profile-picture =
     .tooltiptext = Change profile picture
 
 sync-disconnect =
     .label = Disconnect…
     .accesskey = D
@@ -614,16 +628,35 @@ forms-master-pw-use =
 forms-master-pw-change =
     .label = Change Master Password
     .accesskey = M
 
 ## Privacy Section - History
 
 history-header = History
 
+# This label is followed, on the same line, by a dropdown list of options
+# (Remember history, etc.).
+# In English it visually creates a full sentence, e.g.
+# "Firefox will" + "Remember history".
+#
+# If this doesn't work for your language, you can translate this message:
+#   - Simply as "Firefox", moving the verb into each option.
+#     This will result in "Firefox" + "Will remember history", etc.
+#   - As a stand-alone message, for example "Firefox history settings:".
+history-remember-label = { -brand-short-name } will
+    .accesskey = w
+
+history-remember-option-all =
+    .label = Remember history
+history-remember-option-never =
+    .label = Never remember history
+history-remember-option-custom =
+    .label = Use custom settings for history
+
 history-remember-description = { -brand-short-name } will remember your browsing, download, form and search history.
 history-dontremember-description = { -brand-short-name } will use the same settings as private browsing, and will not remember any history as you browse the Web.
 
 history-private-browsing-permanent =
     .label = Always use private browsing mode
     .accesskey = p
 
 history-remember-option =
deleted file mode 100644
--- a/browser/locales/en-US/chrome/browser/preferences/content.dtd
+++ /dev/null
@@ -1,13 +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/. -->
-
-<!-- LOCALIZATION NOTE (translation.options.attribution.beforeLogo,
-  -                     translation.options.attribution.afterLogo):
-  -  These 2 strings are displayed before and after a 'Microsoft Translator'
-  -  logo.
-  -  The translations for these strings should match the translations in
-  -  browser/translation.dtd
-  -->
-<!ENTITY translation.options.attribution.beforeLogo "Translations by">
-<!ENTITY translation.options.attribution.afterLogo "">
deleted file mode 100644
--- a/browser/locales/en-US/chrome/browser/preferences/privacy.dtd
+++ /dev/null
@@ -1,10 +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  historyHeader2.pre.label         "&brandShortName; will">
-<!ENTITY  historyHeader2.pre.accesskey     "w">
-<!ENTITY  historyHeader.remember.label     "Remember history">
-<!ENTITY  historyHeader.dontremember.label "Never remember history">
-<!ENTITY  historyHeader.custom.label       "Use custom settings for history">
-<!ENTITY  historyHeader.post.label         "">
deleted file mode 100644
--- a/browser/locales/en-US/chrome/browser/preferences/sync.dtd
+++ /dev/null
@@ -1,19 +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/. -->
-
-<!-- LOCALIZATION NOTE (mobilePromo3.*): the following strings will be used to
-     create a single sentence with active links.
-     The resulting sentence in English is: "Download Firefox for
-     Android or iOS to sync with your mobile device." -->
-
-<!ENTITY mobilePromo3.start            "Download Firefox for ">
-<!-- LOCALIZATION NOTE (mobilePromo3.androidLink): This is a link title that links to https://www.mozilla.org/firefox/android/ -->
-<!ENTITY mobilePromo3.androidLink      "Android">
-
-<!-- LOCALIZATION NOTE (mobilePromo3.iOSBefore): This is text displayed between mobilePromo3.androidLink and mobilePromo3.iosLink -->
-<!ENTITY mobilePromo3.iOSBefore         " or ">
-<!-- LOCALIZATION NOTE (mobilePromo3.iOSLink): This is a link title that links to https://www.mozilla.org/firefox/ios/ -->
-<!ENTITY mobilePromo3.iOSLink          "iOS">
-
-<!ENTITY mobilePromo3.end              " to sync with your mobile device.">
--- a/browser/locales/jar.mn
+++ b/browser/locales/jar.mn
@@ -51,21 +51,18 @@
     locale/browser/safebrowsing/phishing-afterload-warning-message.dtd (%chrome/browser/safebrowsing/phishing-afterload-warning-message.dtd)
     locale/browser/safebrowsing/report-phishing.dtd                    (%chrome/browser/safebrowsing/report-phishing.dtd)
     locale/browser/safebrowsing/safebrowsing.properties   (%chrome/browser/safebrowsing/safebrowsing.properties)
     locale/browser/feeds/subscribe.dtd              (%chrome/browser/feeds/subscribe.dtd)
     locale/browser/feeds/subscribe.properties       (%chrome/browser/feeds/subscribe.properties)
     locale/browser/migration/migration.dtd         (%chrome/browser/migration/migration.dtd)
     locale/browser/migration/migration.properties  (%chrome/browser/migration/migration.properties)
     locale/browser/preferences/clearSiteData.properties     (%chrome/browser/preferences/clearSiteData.properties)
-    locale/browser/preferences/content.dtd            (%chrome/browser/preferences/content.dtd)
     locale/browser/preferences/preferences.properties     (%chrome/browser/preferences/preferences.properties)
-    locale/browser/preferences/privacy.dtd            (%chrome/browser/preferences/privacy.dtd)
     locale/browser/preferences/security.dtd           (%chrome/browser/preferences/security.dtd)
-    locale/browser/preferences/sync.dtd               (%chrome/browser/preferences/sync.dtd)
     locale/browser/syncBrand.dtd                (%chrome/browser/syncBrand.dtd)
     locale/browser/syncSetup.properties         (%chrome/browser/syncSetup.properties)
 #if BUILD_FASTER
     locale/browser/searchplugins/               (searchplugins/*.xml)
     locale/browser/searchplugins/list.json      (search/list.json)
 #else
     locale/browser/searchplugins/               (.deps/generated_@AB_CD@/*.xml)
     locale/browser/searchplugins/list.json      (.deps/generated_@AB_CD@/list.json)
--- a/browser/themes/shared/incontentprefs/preferences.inc.css
+++ b/browser/themes/shared/incontentprefs/preferences.inc.css
@@ -622,26 +622,18 @@ button > hbox > label {
 #fxaSyncEngines > vbox > checkbox {
   max-width: 224px;
 }
 
 .fxaMobilePromo {
   margin-top: 2px !important;
 }
 
-.androidLink {
-  list-style-image: url("chrome://browser/skin/preferences/in-content/logo-android.svg");
-}
-
-.iOSLink {
-  list-style-image: url("chrome://browser/skin/preferences/in-content/logo-ios.svg");
-}
-
-.androidLink,
-.iOSLink {
+.androidIcon,
+.iOSIcon {
   margin-inline-start: 2px;
   margin-inline-end: 4px;
   width: 20px;
   height: 20px;
   vertical-align: text-bottom;
   -moz-context-properties: fill;
   fill: currentColor;
 }
new file mode 100644
--- /dev/null
+++ b/python/l10n/fluent_migrations/bug_1453540_preferences_remaining_dtd.py
@@ -0,0 +1,140 @@
+# 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.transforms import REPLACE
+from fluent.migrate.helpers import MESSAGE_REFERENCE
+from fluent.migrate import COPY, CONCAT
+
+
+# Custom extension of the CONCAT migration tailored to concat
+# two strings separated by a placeable.
+class CONCAT_BEFORE_AFTER(CONCAT):
+    def __call__(self, ctx):
+        assert len(self.elements) == 3
+        pattern_before, middle, pattern_after = self.elements
+        elem_before = pattern_before.elements[0]
+        elem_after = pattern_after.elements[0]
+
+        if isinstance(elem_before, FTL.TextElement) and \
+           len(elem_before.value) > 0 and \
+           elem_before.value[-1] != " ":
+            elem_before.value += " "
+        if isinstance(elem_after, FTL.TextElement) and \
+           len(elem_after.value) > 0 and \
+           elem_after.value[0] != " ":
+            elem_after.value = " " + elem_after.value
+        return super(CONCAT_BEFORE_AFTER, self).__call__(ctx)
+
+def migrate(ctx):
+    """Bug 1453540 - Migrate remaining DTDs in Preferences to Fluent, part {index}."""
+
+    ctx.add_transforms(
+        'browser/browser/preferences/preferences.ftl',
+        'browser/browser/preferences/preferences.ftl',
+        [
+            FTL.Message(
+                id=FTL.Identifier('translate-attribution'),
+                value=CONCAT_BEFORE_AFTER(
+                    COPY(
+                        'browser/chrome/browser/preferences/content.dtd',
+                        'translation.options.attribution.beforeLogo',
+                    ),
+                    FTL.TextElement('<img data-l10n-name="logo"/>'),
+                    COPY(
+                        'browser/chrome/browser/preferences/content.dtd',
+                        'translation.options.attribution.afterLogo',
+                    ),
+                )
+            ),
+            FTL.Message(
+                id=FTL.Identifier('sync-mobile-promo'),
+                value=CONCAT(
+                    COPY(
+                        'browser/chrome/browser/preferences/sync.dtd',
+                        'mobilePromo3.start',
+                    ),
+                    FTL.TextElement('<img data-l10n-name="android-icon"/> <a data-l10n-name="android-link">'),
+                    COPY(
+                        'browser/chrome/browser/preferences/sync.dtd',
+                        'mobilePromo3.androidLink',
+                    ),
+                    FTL.TextElement('</a>'),
+                    COPY(
+                        'browser/chrome/browser/preferences/sync.dtd',
+                        'mobilePromo3.iOSBefore',
+                    ),
+                    FTL.TextElement('<img data-l10n-name="ios-icon"/> <a data-l10n-name="ios-link">'),
+                    COPY(
+                        'browser/chrome/browser/preferences/sync.dtd',
+                        'mobilePromo3.iOSLink',
+                    ),
+                    FTL.TextElement('</a>'),
+                    COPY(
+                        'browser/chrome/browser/preferences/sync.dtd',
+                        'mobilePromo3.end',
+                    ),
+                )
+            ),
+            FTL.Message(
+                id=FTL.Identifier('history-remember-label'),
+                value=REPLACE(
+                    'browser/chrome/browser/preferences/privacy.dtd',
+                    'historyHeader2.pre.label',
+                    {
+                        '&brandShortName;': MESSAGE_REFERENCE(
+                            '-brand-short-name'
+                        )
+                    }
+                ),
+                attributes=[
+                    FTL.Attribute(
+                        FTL.Identifier('accesskey'),
+                        COPY(
+                            'browser/chrome/browser/preferences/privacy.dtd',
+                            'historyHeader2.pre.accesskey',
+                        )
+                    )
+                ]
+            ),
+            FTL.Message(
+                id=FTL.Identifier('history-remember-option-all'),
+                attributes=[
+                    FTL.Attribute(
+                        FTL.Identifier('label'),
+                        COPY(
+                            'browser/chrome/browser/preferences/privacy.dtd',
+                            'historyHeader.remember.label',
+                        )
+                    )
+                ]
+            ),
+            FTL.Message(
+                id=FTL.Identifier('history-remember-option-never'),
+                attributes=[
+                    FTL.Attribute(
+                        FTL.Identifier('label'),
+                        COPY(
+                            'browser/chrome/browser/preferences/privacy.dtd',
+                            'historyHeader.dontremember.label',
+                        )
+                    )
+                ]
+            ),
+            FTL.Message(
+                id=FTL.Identifier('history-remember-option-custom'),
+                attributes=[
+                    FTL.Attribute(
+                        FTL.Identifier('label'),
+                        COPY(
+                            'browser/chrome/browser/preferences/privacy.dtd',
+                            'historyHeader.custom.label',
+                        )
+                    )
+                ]
+            ),
+        ]
+    )