From 98a644b4c889866d55eb4a7a45c79df99d9331b8 Mon Sep 17 00:00:00 2001 From: Nick Alexander Date: Wed, 19 Jan 2022 17:02:26 +0000 Subject: [PATCH] Bug 1749435 - Use Fluent to localize `bookmarks.html` at run-time rather than build-time. r=flod,mak,fluent-reviewers This modernizes an old part of the build system to not require build-time localization at all. That's generally preferable. The most significant changes to the in-product functionality is to make import localize HTML so that we can use Fluent's `data-l10n-id`. The locale used is the user's current locale. This is different than the existing approach, which always uses the build-time (repack) locale. I believe this is a strictly superior user experience and it may lead to future improvements where-in the default bookmarks become truly dynamic and vary with the user's chosen locale rather than being point-in-time decisions. I tried to restrict these changes to only applen when we import the default bookmarks, but I think the various layers of flags no longer achieve this restriction in practice and the formatting and localization will apply to all imported `bookmarks.html` files. Since we don't anticipate (nor ourselves write) these new things in (respectively, to) `bookmarks.html`, and the file is already user-controlled, I don't think this exposes any meaningful change in functionality (or in security surface). Some notes: 1) There's no migration of `.inc` -> `.ftl` because this is the lone `.inc` file. 2) I elected to prefix all strings with `default-bookmarks-`, since the existing names were very short and likely to collide (now or in the future). 3) I elected to change the HTML file name for easier searching. 4) Since the `default-bookmarks.html` file is product-specific and the existing tests are in `toolkit/`, I elected to not test the file directly in automation. 5) We removed the explicit locale (or equivalent `%LOCALE%`) since Mozilla properties will redirect to the appropriate language automatically. Differential Revision: https://phabricator.services.mozilla.com/D135816 --- .../content/default-bookmarks.html} | 62 ++++++++++------- browser/base/jar.mn | 1 + browser/components/BrowserGlue.jsm | 5 +- .../components/migration/MigrationUtils.jsm | 2 +- .../browser/profile/default-bookmarks.ftl | 52 ++++++++++++++ browser/locales/en-US/profile/bookmarks.inc | 68 ------------------- browser/locales/generate_bookmarks.py | 45 ------------ browser/locales/jar.mn | 3 - browser/locales/moz.build | 10 --- .../components/places/BookmarkHTMLUtils.jsm | 19 ++++++ .../tests/unit/bookmarks_html_localized.html | 21 ++++++ .../unit/test_bookmarks_html_localized.js | 51 ++++++++++++++ .../components/places/tests/unit/xpcshell.ini | 2 + 13 files changed, 186 insertions(+), 155 deletions(-) rename browser/{locales/generic/profile/bookmarks.html.in => base/content/default-bookmarks.html} (69%) create mode 100644 browser/locales/en-US/browser/profile/default-bookmarks.ftl delete mode 100644 browser/locales/en-US/profile/bookmarks.inc delete mode 100644 browser/locales/generate_bookmarks.py create mode 100644 toolkit/components/places/tests/unit/bookmarks_html_localized.html create mode 100644 toolkit/components/places/tests/unit/test_bookmarks_html_localized.js diff --git a/browser/locales/generic/profile/bookmarks.html.in b/browser/base/content/default-bookmarks.html similarity index 69% rename from browser/locales/generic/profile/bookmarks.html.in rename to browser/base/content/default-bookmarks.html index c5ac0b45d9c25..b2d18d309866c 100644 --- a/browser/locales/generic/profile/bookmarks.html.in +++ b/browser/base/content/default-bookmarks.html @@ -1,5 +1,4 @@ #filter substitution -#include @BOOKMARKS_INCLUDE_PATH@ #define mozilla_icon data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E %3Cpath d='M0 0h16v16H0z'/%3E %3Cpath d='M13.994 10.356H15V12h-3.171V7.741c0-1.308-.435-1.81-1.29-1.81-1.04 0-1.46.737-1.46 1.8v2.63h1.006V12H6.918V7.741c0-1.308-.435-1.81-1.291-1.81-1.039 0-1.459.737-1.459 1.8v2.63h1.441V12H1v-1.644h1.006V6.079H1V4.435h3.168v1.139a2.507 2.507 0 0 1 2.3-1.29A2.452 2.452 0 0 1 8.931 5.91 2.535 2.535 0 0 1 11.4 4.284 2.448 2.448 0 0 1 14 6.9v3.458z' fill='%23fff'/%3E %3C/svg%3E @@ -14,36 +13,47 @@ - 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/. --> - -@bookmarks_title@ -

@bookmarks_heading@

+ + + + + + + default-bookmarks-title + + +

default-bookmarks-heading

-

@bookmarks_toolbarfolder@

-
@bookmarks_toolbarfolder_description@ +

default-bookmarks-toolbarfolder

+
default-bookmarks-toolbarfolder-description
#ifndef NIGHTLY_BUILD -
-

@getting_started@
-
-

@firefox_heading@

-

@firefox_get_help@ -
@firefox_customize@ -
@firefox_community@ -
@firefox_about@ -
+
default-bookmarks-getting-started
+

+

default-bookmarks-firefox-heading

+

+

default-bookmarks-firefox-get-help
+
default-bookmarks-firefox-customize
+
default-bookmarks-firefox-community
+
default-bookmarks-firefox-about
+

#else -

-

@firefox_community@ -
-

@nightly_heading@

-

@nightly_blog@ -
@bugzilla@ -
@mdn@ -
@nightly_tester_tools@ -
@crashes@ -
@planet@ -
+
default-bookmarks-firefox-community
+

+

default-bookmarks-nightly-heading

+

+

default-bookmarks-nightly-blog
+
default-bookmarks-bugzilla
+
default-bookmarks-mdn
+
default-bookmarks-nightly-tester-tools
+
default-bookmarks-crashes
+
default-bookmarks-planet
+

#endif + + diff --git a/browser/base/jar.mn b/browser/base/jar.mn index 345c42f811678..739cbc2a56639 100644 --- a/browser/base/jar.mn +++ b/browser/base/jar.mn @@ -106,6 +106,7 @@ browser.jar: content/browser/upgradeDialog.js (content/upgradeDialog.js) content/browser/spotlight.html (content/spotlight.html) content/browser/spotlight.js (content/spotlight.js) +* content/browser/default-bookmarks.html (content/default-bookmarks.html) % override chrome://global/content/netError.xhtml chrome://browser/content/certerror/aboutNetError.xhtml diff --git a/browser/components/BrowserGlue.jsm b/browser/components/BrowserGlue.jsm index 64341a86f8223..f1219b4899c21 100644 --- a/browser/components/BrowserGlue.jsm +++ b/browser/components/BrowserGlue.jsm @@ -3223,8 +3223,9 @@ BrowserGlue.prototype = { // An import operation is about to run. let bookmarksUrl = null; if (restoreDefaultBookmarks) { - // User wants to restore bookmarks.html file from default profile folder - bookmarksUrl = "chrome://browser/locale/bookmarks.html"; + // User wants to restore the default set of bookmarks shipped with the + // browser, those that new profiles start with. + bookmarksUrl = "chrome://browser/content/default-bookmarks.html"; } else if (await IOUtils.exists(BookmarkHTMLUtils.defaultPath)) { bookmarksUrl = PathUtils.toFileURI(BookmarkHTMLUtils.defaultPath); } diff --git a/browser/components/migration/MigrationUtils.jsm b/browser/components/migration/MigrationUtils.jsm index 05ea4471d350d..0faa02786e38b 100644 --- a/browser/components/migration/MigrationUtils.jsm +++ b/browser/components/migration/MigrationUtils.jsm @@ -456,7 +456,7 @@ var MigratorPrototype = { // Import the default bookmarks. We ignore whether or not we succeed. await BookmarkHTMLUtils.importFromURL( - "chrome://browser/locale/bookmarks.html", + "chrome://browser/content/default-bookmarks.html", { replace: true, source: PlacesUtils.bookmarks.SOURCES.RESTORE_ON_STARTUP, diff --git a/browser/locales/en-US/browser/profile/default-bookmarks.ftl b/browser/locales/en-US/browser/profile/default-bookmarks.ftl new file mode 100644 index 0000000000000..e70e221d92ed3 --- /dev/null +++ b/browser/locales/en-US/browser/profile/default-bookmarks.ftl @@ -0,0 +1,52 @@ +# 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 file intentionally uses hard-coded brand names instead of Fluent terms. +# This approach minimizes issues across multiple release channels and rebranded +# versions. + +default-bookmarks-title = Bookmarks +default-bookmarks-heading = Bookmarks + +default-bookmarks-toolbarfolder = Bookmarks Toolbar Folder +default-bookmarks-toolbarfolder-description = Add bookmarks to this folder to see them displayed on the Bookmarks Toolbar + +# link title for https://www.mozilla.org/firefox/central/ +default-bookmarks-getting-started = Getting Started + +# Firefox links folder name +default-bookmarks-firefox-heading = Mozilla Firefox + +# link title for https://www.mozilla.org/firefox/help/ +default-bookmarks-firefox-get-help = Get Help + +# link title for https://www.mozilla.org/firefox/customize/ +default-bookmarks-firefox-customize = Customize Firefox + +# link title for https://www.mozilla.org/contribute/ +default-bookmarks-firefox-community = Get Involved + +# link title for https://www.mozilla.org/about/ +default-bookmarks-firefox-about = About Us + +# Firefox Nightly links folder name +default-bookmarks-nightly-heading = Firefox Nightly Resources + +# Nightly builds only, link title for https://blog.nightly.mozilla.org/ +default-bookmarks-nightly-blog = Firefox Nightly blog + +# Nightly builds only, link title for https://bugzilla.mozilla.org/ +default-bookmarks-bugzilla = Mozilla Bug Tracker + +# Nightly builds only, link title for https://developer.mozilla.org/ +default-bookmarks-mdn = Mozilla Developer Network + +# Nightly builds only, link title for https://addons.mozilla.org/firefox/addon/nightly-tester-tools/ +default-bookmarks-nightly-tester-tools = Nightly Tester Tools + +# Nightly builds only, link title for about:crashes +default-bookmarks-crashes = All your crashes + +# Nightly builds only, link title for https://planet.mozilla.org/ +default-bookmarks-planet = Planet Mozilla diff --git a/browser/locales/en-US/profile/bookmarks.inc b/browser/locales/en-US/profile/bookmarks.inc deleted file mode 100644 index 578eac05a32ad..0000000000000 --- a/browser/locales/en-US/profile/bookmarks.inc +++ /dev/null @@ -1,68 +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/. -#filter emptyLines - -# LOCALIZATION NOTE: The 'en-US' strings in the URLs will be replaced with -# your locale code, and link to your translated pages as soon as they're -# live. - -#define bookmarks_title Bookmarks -#define bookmarks_heading Bookmarks - -#define bookmarks_toolbarfolder Bookmarks Toolbar Folder -#define bookmarks_toolbarfolder_description Add bookmarks to this folder to see them displayed on the Bookmarks Toolbar - -# LOCALIZATION NOTE (getting_started): -# link title for https://www.mozilla.org/en-US/firefox/central/ -#define getting_started Getting Started - -# LOCALIZATION NOTE (firefox_heading): -# Firefox links folder name -#define firefox_heading Mozilla Firefox - -# LOCALIZATION NOTE (firefox_get_help): -# link title for https://www.mozilla.org/en-US/firefox/help/ -#define firefox_get_help Get Help - -# LOCALIZATION NOTE (firefox_customize): -# link title for https://www.mozilla.org/en-US/firefox/customize/ -#define firefox_customize Customize Firefox - -# LOCALIZATION NOTE (firefox_community): -# link title for https://www.mozilla.org/en-US/contribute/ -#define firefox_community Get Involved - -# LOCALIZATION NOTE (firefox_about): -# link title for https://www.mozilla.org/en-US/about/ -#define firefox_about About Us - -# LOCALIZATION NOTE (nightly_heading): -# Firefox Nightly links folder name -#define nightly_heading Firefox Nightly Resources - -# LOCALIZATION NOTE (nightly_blog): -# Nightly builds only, link title for https://blog.nightly.mozilla.org/ -#define nightly_blog Firefox Nightly blog - -# LOCALIZATION NOTE (bugzilla): -# Nightly builds only, link title for https://bugzilla.mozilla.org/ -#define bugzilla Mozilla Bug Tracker - -# LOCALIZATION NOTE (mdn): -# Nightly builds only, link title for https://developer.mozilla.org/ -#define mdn Mozilla Developer Network - -# LOCALIZATION NOTE (nightly_tester_tools): -# Nightly builds only, link title for https://addons.mozilla.org/en-US/firefox/addon/nightly-tester-tools/ -#define nightly_tester_tools Nightly Tester Tools - -# LOCALIZATION NOTE (crashes): -# Nightly builds only, link title for about:crashes -#define crashes All your crashes - -# LOCALIZATION NOTE (planet): -# Nightly builds only, link title for https://planet.mozilla.org/ -#define planet Planet Mozilla - -#unfilter emptyLines diff --git a/browser/locales/generate_bookmarks.py b/browser/locales/generate_bookmarks.py deleted file mode 100644 index 1b2002fcf9ca0..0000000000000 --- a/browser/locales/generate_bookmarks.py +++ /dev/null @@ -1,45 +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/. - -# Generate bookmarks.html by interpolating the included (localized) -# `bookmarks.inc` file into the given (unlocalized) `bookmarks.html.in` input. - -from __future__ import absolute_import, unicode_literals, print_function - -import buildconfig -import sys - -from mozbuild import preprocessor - - -def main(output, bookmarks_html_in, bookmarks_inc, locale=None): - if not locale: - raise ValueError("locale must be specified!") - - CONFIG = buildconfig.substs - - # Based on - # https://searchfox.org/l10n-central/search?q=path%3Abookmarks.inc+%23if&redirect=true, - # no localized input uses the preprocessor conditional #if (really, - # anything but #define), so it's safe to restrict the set of defines to - # what's used in mozilla-central directly. - defines = {} - defines["AB_CD"] = locale - if defines["AB_CD"] == "ja-JP-mac": - defines["AB_CD"] = "ja" - - defines["BOOKMARKS_INCLUDE_PATH"] = bookmarks_inc - - for var in ("NIGHTLY_BUILD",): - if var in CONFIG: - defines[var] = CONFIG[var] - - includes = preprocessor.preprocess( - includes=[bookmarks_html_in], defines=defines, output=output - ) - return includes - - -if __name__ == "__main__": - main(sys.argv[1:]) diff --git a/browser/locales/jar.mn b/browser/locales/jar.mn index b6a606e3328d3..0c48d4ef81f75 100644 --- a/browser/locales/jar.mn +++ b/browser/locales/jar.mn @@ -16,9 +16,6 @@ @AB_CD@.jar: % locale browser @AB_CD@ %locale/browser/ -# bookmarks.html is produced by LOCALIZED_GENERATED_FILES. - locale/browser/bookmarks.html (bookmarks.html) - locale/browser/accounts.properties (%chrome/browser/accounts.properties) locale/browser/browser.properties (%chrome/browser/browser.properties) locale/browser/customizableui/customizableWidgets.properties (%chrome/browser/customizableui/customizableWidgets.properties) diff --git a/browser/locales/moz.build b/browser/locales/moz.build index e1c27c75499d0..53e3ac361f245 100644 --- a/browser/locales/moz.build +++ b/browser/locales/moz.build @@ -25,16 +25,6 @@ if CONFIG["MOZ_UPDATER"]: # work. LOCALIZED_FILES[".."] += ["!updater.ini"] -LOCALIZED_GENERATED_FILES += ["bookmarks.html"] -bookmarks = LOCALIZED_GENERATED_FILES["bookmarks.html"] -bookmarks.script = "generate_bookmarks.py" -bookmarks.inputs = [ - # This input will not be considered for localization. - "generic/profile/bookmarks.html.in", - # The `locales/en-US/` will be rewritten to the locale-specific path. - "en-US/profile/bookmarks.inc", -] - with Files("**"): BUG_COMPONENT = ("Firefox Build System", "General") diff --git a/toolkit/components/places/BookmarkHTMLUtils.jsm b/toolkit/components/places/BookmarkHTMLUtils.jsm index ce1afe97e5025..0047af283b275 100644 --- a/toolkit/components/places/BookmarkHTMLUtils.jsm +++ b/toolkit/components/places/BookmarkHTMLUtils.jsm @@ -840,6 +840,25 @@ BookmarkImporter.prototype = { */ async importFromURL(href) { let data = await fetchData(href); + + if (this._isImportDefaults && data) { + // Localize default bookmarks. Find rel="localization" links and manually + // localize using them. + let hrefs = []; + let links = data.head.querySelectorAll("link[rel='localization']"); + for (let link of links) { + if (link.getAttribute("href")) { + // We need the text, not the fully qualified URL, so we use `getAttribute`. + hrefs.push(link.getAttribute("href")); + } + } + + if (hrefs.length) { + let domLoc = new DOMLocalization(hrefs); + await domLoc.translateFragment(data.body); + } + } + this._walkTreeForImport(data); await this._importBookmarks(); }, diff --git a/toolkit/components/places/tests/unit/bookmarks_html_localized.html b/toolkit/components/places/tests/unit/bookmarks_html_localized.html new file mode 100644 index 0000000000000..bc3bacc54dfa5 --- /dev/null +++ b/toolkit/components/places/tests/unit/bookmarks_html_localized.html @@ -0,0 +1,21 @@ + + + + + +Bookmarks + + + +

Bookmarks

+ +

+

bookmarks-html-localized-folder

+

+

bookmarks-html-localized-bookmark +

+

+ + diff --git a/toolkit/components/places/tests/unit/test_bookmarks_html_localized.js b/toolkit/components/places/tests/unit/test_bookmarks_html_localized.js new file mode 100644 index 0000000000000..8be9bb3d718cf --- /dev/null +++ b/toolkit/components/places/tests/unit/test_bookmarks_html_localized.js @@ -0,0 +1,51 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et: */ +/* 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/. */ + +const { BookmarkHTMLUtils } = ChromeUtils.import( + "resource://gre/modules/BookmarkHTMLUtils.jsm" +); + +add_task(async function setup_l10n() { + // A single localized string. + const mockSource = L10nFileSource.createMock( + "test", + "app", + ["en-US"], + "/localization/{locale}/", + [ + { + path: "/localization/en-US/bookmarks_html_localized.ftl", + source: ` +bookmarks-html-localized-folder = Localized Folder +bookmarks-html-localized-bookmark = Localized Bookmark +`, + }, + ] + ); + + L10nRegistry.getInstance().registerSources([mockSource]); +}); + +add_task(async function test_bookmarks_html_localized() { + let bookmarksFile = OS.Path.join( + do_get_cwd().path, + "bookmarks_html_localized.html" + ); + await BookmarkHTMLUtils.importFromFile(bookmarksFile, { replace: true }); + + let root = PlacesUtils.getFolderContents(PlacesUtils.bookmarks.menuGuid).root; + Assert.equal(root.childCount, 1); + let folder = root.getChild(0); + PlacesUtils.asContainer(folder).containerOpen = true; + // Folder title is localized. + Assert.equal(folder.title, "Localized Folder"); + Assert.equal(folder.childCount, 1); + let bookmark = folder.getChild(0); + Assert.equal(bookmark.uri, "http://www.mozilla.com/firefox/help/"); + // Bookmark title is localized. + Assert.equal(bookmark.title, "Localized Bookmark"); + folder.containerOpen = false; +}); diff --git a/toolkit/components/places/tests/unit/xpcshell.ini b/toolkit/components/places/tests/unit/xpcshell.ini index d17172d4d02e5..1ab0dd32c8767 100644 --- a/toolkit/components/places/tests/unit/xpcshell.ini +++ b/toolkit/components/places/tests/unit/xpcshell.ini @@ -6,6 +6,7 @@ support-files = bookmarks.json bookmarks_corrupt.json bookmarks.preplaces.html + bookmarks_html_localized.html bookmarks_html_singleframe.html mobile_bookmarks_folder_import.json mobile_bookmarks_folder_merge.json @@ -46,6 +47,7 @@ skip-if = os == "linux" # Bug 821781 [test_bookmarks_html_corrupt.js] [test_bookmarks_html_escape_entities.js] [test_bookmarks_html_import_tags.js] +[test_bookmarks_html_localized.js] [test_bookmarks_html_singleframe.js] [test_bookmarks_restore_notification.js] [test_broken_folderShortcut_result.js]