diff --git a/build/commands/lib/chromiumRebaseL10n.js b/build/commands/lib/chromiumRebaseL10n.js
index 50f1ff3169ea..bc3e0a5b2c9f 100644
--- a/build/commands/lib/chromiumRebaseL10n.js
+++ b/build/commands/lib/chromiumRebaseL10n.js
@@ -4,10 +4,15 @@
const config = require('../lib/config')
const util = require('../lib/util')
-const {rebaseBraveStringFilesOnChromiumL10nFiles} = require('./l10nUtil')
+const {rebaseBraveStringFilesOnChromiumL10nFiles, braveAutoGeneratedPaths} = require('./l10nUtil')
const chromiumRebaseL10n = (options) => {
rebaseBraveStringFilesOnChromiumL10nFiles()
+ braveAutoGeneratedPaths.forEach((sourceStringPath) => {
+ const cmdOptions = config.defaultOptions
+ cmdOptions.cwd = config.projects['brave-core'].dir
+ util.run('python', ['script/chromium-rebase-l10n.py', '--source_string_path', sourceStringPath], cmdOptions)
+ })
}
module.exports = chromiumRebaseL10n
diff --git a/build/commands/lib/l10nUtil.js b/build/commands/lib/l10nUtil.js
index 72b05a05b312..45b3e9fc324e 100644
--- a/build/commands/lib/l10nUtil.js
+++ b/build/commands/lib/l10nUtil.js
@@ -2,91 +2,121 @@
* 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 manages the following:
+ * - Lists of files needed to be translated (Which is all top level GRD and JSON files)
+ * - All mappings for auto-generated Brave files from the associated Chromium files.
+ * - Top level global string replacements, such as replacing Chromium with Brave
+ */
+
const path = require('path')
const fs = require('fs')
const srcDir = path.resolve(path.join(__dirname, '..', 'src'))
-// Brave string paths
+// chromium_strings.grd and any of its parts files that we track localization for in transifex
+// These map to brave/app/resources/chromium_strings*.xtb
+const chromiumStringsPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'chromium_strings.grd'))
const braveStringsPath = path.resolve(path.join(srcDir, 'brave', 'app', 'brave_strings.grd'))
+const chromiumSettingsPartPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'settings_chromium_strings.grdp'))
const braveSettingsPartPath = path.resolve(path.join(srcDir, 'brave', 'app', 'settings_brave_strings.grdp'))
+
+// component_chromium_strings.grd and any of its parts files that we track localization for in transifex
+// These map to brave/app/strings/components_chromium_strings*.xtb
+const chromiumComponentsStringsPath = path.resolve(path.join(srcDir, 'components', 'components_chromium_strings.grd'))
const braveComponentsStringsPath = path.resolve(path.join(srcDir, 'brave', 'app', 'components_brave_strings.grd'))
-const braveExtensionMessagesPath = path.resolve(path.join(srcDir, 'brave', 'vendor', 'brave-extension', 'app', '_locales', 'en_US', 'messages.json'))
-const braveSpecificGeneratedResourcesPath = path.resolve(path.join(srcDir, 'brave', 'app', 'brave_generated_resources.grd'))
-const braveComponentsResourcesPath = path.resolve(path.join(srcDir, 'brave', 'components', 'resources', 'brave_components_resources.grd'))
+// generated_resources.grd and any of its parts files that we track localization for in transifex
+// There is also chromeos_strings.grdp but we don't need to track it here
+// These map to brave/app/resources/generated_resoruces*.xtb
+const chromiumGeneratedResourcesPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'generated_resources.grd'))
const braveGeneratedResourcesPath = path.resolve(path.join(srcDir, 'brave', 'app', 'generated_resources.grd'))
+const chromiumBookmarksPartPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'bookmarks_strings.grdp'))
const braveBookmarksPartPath = path.resolve(path.join(srcDir, 'brave', 'app', 'bookmarks_strings.grdp'))
+const chromiumMediaRouterPartPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'media_router_strings.grdp'))
const braveMediaRouterPartPath = path.resolve(path.join(srcDir, 'brave', 'app', 'media_router_strings.grdp'))
+const chromiumSettingsStringsPartPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'settings_strings.grdp'))
const braveSettingsStringsPartPath = path.resolve(path.join(srcDir, 'brave', 'app', 'settings_strings.grdp'))
+const chromiumMdExtensionsPartPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'md_extensions_strings.grdp'))
const braveMdExtensionsPartPath = path.resolve(path.join(srcDir, 'brave', 'app', 'md_extensions_strings.grdp'))
+const chromiumPrintingStringsPartPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'printing_strings.grdp'))
const bravePrintingStringsPartPath = path.resolve(path.join(srcDir, 'brave', 'app', 'printing_strings.grdp'))
+// extensions_resources.grd and any of its parts files that we track localization for in transifex
+// There are no XTB files for this.
+const chromiumExtensionsResourcesPath = path.resolve(path.join(srcDir, 'chrome', 'browser', 'resources', 'md_extensions', 'extensions_resources.grd'))
const braveExtensionsResourcesPath = path.resolve(path.join(srcDir, 'brave', 'browser', 'resources', 'md_extensions', 'extensions_resources.grd'))
+
+// settings_resources.grd and any of its parts files that we track localization for in transifex
+// There are no XTB files for this.
+const chromiumSettingsResourcesPath = path.resolve(path.join(srcDir, 'chrome', 'browser', 'resources', 'settings', 'settings_resources.grd'))
const braveSettingsResourcesPath = path.resolve(path.join(srcDir, 'brave', 'browser', 'resources', 'settings', 'settings_resources.grd'))
-const braveBrowserResourcesPath = path.resolve(path.join(srcDir, 'brave', 'browser', 'browser_resources.grd'))
-// Chromium string paths
-const chromiumStringsPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'chromium_strings.grd'))
-const chroimumSettingsPartPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'settings_chromium_strings.grdp'))
-const chromiumComponentsStringsPath = path.resolve(path.join(srcDir, 'components', 'components_chromium_strings.grd'))
+// browser_resources.grd and any of its parts files that we track localization for in transifex
+// We currently do not need to track media_router_resources.grdp
+// There are no XTB files for this.
+const chromiumBrowserResourcesPath = path.resolve(path.join(srcDir, 'chrome', 'browser', 'browser_resources.grd'))
+const braveBrowserResourcesPath = path.resolve(path.join(srcDir, 'brave', 'browser', 'browser_resources.grd'))
-const chromiumGeneratedResourcesPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'generated_resources.grd'))
-const chromiumBookmarksPartPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'bookmarks_strings.grdp'))
-const chromiumMediaRouterPartPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'media_router_strings.grdp'))
-const chromiumSettingsStringsPartPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'settings_strings.grdp'))
-const chromiumMdExtensionsPartPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'md_extensions_strings.grdp'))
-const chromePrintingStringsPartPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'printing_strings.grdp'))
+// The following are not generated files but still need to be tracked so they get sent to transifex
+// These xtb files don't need to be copied anywhere.
+// brave_generated_resources.grd maps to brave/app/resources/brave_generated_resources*.xtb,
+// brave_component_resources.grd maps to brave/components/resources/strings/brave_components_resources*.xtb
+// messages.json localization is handled inside of brave-extension.
+const braveSpecificGeneratedResourcesPath = path.resolve(path.join(srcDir, 'brave', 'app', 'brave_generated_resources.grd'))
+const braveComponentsResourcesPath = path.resolve(path.join(srcDir, 'brave', 'components', 'resources', 'brave_components_resources.grd'))
+const braveExtensionMessagesPath = path.resolve(path.join(srcDir, 'brave', 'vendor', 'brave-extension', 'app', '_locales', 'en_US', 'messages.json'))
-const chromiumExtensionsResourcesPath = path.resolve(path.join(srcDir, 'chrome', 'browser', 'resources', 'md_extensions', 'extensions_resources.grd'))
-const chromiumSettingsResourcesPath = path.resolve(path.join(srcDir, 'chrome', 'browser', 'resources', 'settings', 'settings_resources.grd'))
-const chromiumBrowserResourcesPath = path.resolve(path.join(srcDir, 'chrome', 'browser', 'browser_resources.grd'))
+// When adding new grd or grd files, never add a grdp part path without a parent grd path.
+// Group them with a leading and trailing newline to keep this file organized.
-const autoGeneratedWarning = ''
-
-const pageVisibility = ' \n'
-
-module.exports.getSourceStringPaths = () => {
- return [
- braveStringsPath,
- braveComponentsStringsPath,
- braveExtensionMessagesPath,
- braveSpecificGeneratedResourcesPath,
- braveComponentsResourcesPath,
- braveGeneratedResourcesPath,
- // No strings for now, uncomment if strings are added
- // path.resolve(path.join(srcDir, 'brave', 'browser', 'resources', 'brave_extension.grd')),
- // path.resolve(path.join(srcDir, 'brave', 'common', 'extensions', 'api', 'brave_api_resources.grd')),
- ]
+// Add all mappings here whether it is a GRD or a GRDP.
+// Brave specific only grd and grdp files should not be added here.
+const chromiumToAutoGeneratedBraveMapping = {
+ [chromiumStringsPath]: braveStringsPath,
+ [chromiumSettingsPartPath]: braveSettingsPartPath,
+ [chromiumComponentsStringsPath]: braveComponentsStringsPath,
+ [chromiumGeneratedResourcesPath]: braveGeneratedResourcesPath,
+ [chromiumBookmarksPartPath]: braveBookmarksPartPath,
+ [chromiumMediaRouterPartPath]: braveMediaRouterPartPath,
+ [chromiumSettingsStringsPartPath]: braveSettingsStringsPartPath,
+ [chromiumMdExtensionsPartPath]: braveMdExtensionsPartPath,
+ [chromiumPrintingStringsPartPath]: bravePrintingStringsPartPath,
+ [chromiumExtensionsResourcesPath]: braveExtensionsResourcesPath,
+ [chromiumSettingsResourcesPath]: braveSettingsResourcesPath,
+ [chromiumBrowserResourcesPath]: braveBrowserResourcesPath
}
+// Same as with chromiumToAutoGeneratedBraveMapping but maps in the opposite direction
+module.exports.autoGeneratedBraveToChromiumMapping = Object.keys(chromiumToAutoGeneratedBraveMapping)
+ .reduce((obj, key) => ({ ...obj, [chromiumToAutoGeneratedBraveMapping[key]]: key }), {})
+
+// All paths which are not generated
+module.exports.braveNonGeneratedPaths = [
+ //braveSpecificGeneratedResourcesPath, braveComponentsResourcesPath, braveExtensionMessagesPath
+]
+// All paths which are generated
+module.exports.braveAutoGeneratedPaths = Object.values(chromiumToAutoGeneratedBraveMapping)
+
+// Brave specific strings and Chromium mapped Brave strings will be here.
+// But you only need to add the Brave specific strings manually here.
+module.exports.allBravePaths = module.exports.braveNonGeneratedPaths.concat(module.exports.braveAutoGeneratedPaths)
+
+// Get all GRD and JSON paths whether they are generatd or not
+// Push and pull scripts for l10n use this.
+// Transifex manages files per grd and not per grd or grdp.
+// This is because only 1 xtb is created per grd per locale even if it has multiple grdp files.
+module.exports.braveTopLevelPaths = module.exports.allBravePaths.filter((x) => ['grd', 'json'].includes(x.split('.').pop()))
+
+// This simply reads Chromium files that are passed to it and replaces branding strings
+// with Brave specific branding strings.
+// Do not use this for filtering XML, instead use chromium-rebase-l10n.py.
+// Only add idempotent replacements here (i.e. don't append replace A with AX here)
module.exports.rebaseBraveStringFilesOnChromiumL10nFiles = (path) =>
- Object.entries({
- [chromiumStringsPath]: braveStringsPath,
- [chroimumSettingsPartPath]: braveSettingsPartPath,
- [chromiumComponentsStringsPath]: braveComponentsStringsPath,
- [chromiumGeneratedResourcesPath]: braveGeneratedResourcesPath,
- [chromiumBookmarksPartPath]: braveBookmarksPartPath,
- [chromiumMediaRouterPartPath]: braveMediaRouterPartPath,
- [chromiumSettingsStringsPartPath]: braveSettingsStringsPartPath,
- [chromiumMdExtensionsPartPath]: braveMdExtensionsPartPath,
- [chromePrintingStringsPartPath]: bravePrintingStringsPartPath,
- [chromiumExtensionsResourcesPath]: braveExtensionsResourcesPath,
- [chromiumSettingsResourcesPath]: braveSettingsResourcesPath,
- [chromiumBrowserResourcesPath]: braveBrowserResourcesPath
- }).forEach(([sourcePath, destPath]) =>
+ Object.entries(chromiumToAutoGeneratedBraveMapping).forEach(([sourcePath, destPath]) =>
fs.writeFileSync(destPath,
fs.readFileSync(sourcePath, 'utf8')
- .replace(/<\?xml version="1.0" encoding="utf-8"\?>/i, '\n' + autoGeneratedWarning)
- .replace(' {
- getSourceStringPaths().forEach((sourceStringPath) => {
+ braveTopLevelPaths.forEach((sourceStringPath) => {
const cmdOptions = config.defaultOptions
cmdOptions.cwd = config.projects['brave-core'].dir
util.run('python', ['script/pull-l10n.py', '--source_string_path', sourceStringPath], cmdOptions)
diff --git a/build/commands/lib/pushL10n.js b/build/commands/lib/pushL10n.js
index 67b6a1b6f9de..6c573c81de8f 100644
--- a/build/commands/lib/pushL10n.js
+++ b/build/commands/lib/pushL10n.js
@@ -1,16 +1,16 @@
const config = require('../lib/config')
const util = require('../lib/util')
-const {getSourceStringPaths} = require('./l10nUtil')
+const {braveTopLevelPaths} = require('./l10nUtil')
const pushL10n = (options) => {
// Get rid of local copied xtb and grd changes
const runOptions = { cwd: config.projects.chrome.dir }
let args = ['checkout', '--', '*.xtb']
util.run('git', args, runOptions)
- args = ['checkout', '--', '*.grd']
+ args = ['checkout', '--', '*.grd*']
util.run('git', args, runOptions)
- getSourceStringPaths().forEach((sourceStringPath) => {
+ braveTopLevelPaths.forEach((sourceStringPath) => {
const cmdOptions = config.defaultOptions
cmdOptions.cwd = config.projects['brave-core'].dir
util.run('python', ['script/push-l10n.py', '--source_string_path', sourceStringPath], cmdOptions)
diff --git a/build/commands/lib/util.js b/build/commands/lib/util.js
index 8a660bc94cca..563d4318c1a3 100644
--- a/build/commands/lib/util.js
+++ b/build/commands/lib/util.js
@@ -2,6 +2,7 @@ const path = require('path')
const spawnSync = require('child_process').spawnSync
const config = require('./config')
const fs = require('fs-extra')
+const autoGeneratedBraveToChromiumMapping = Object.assign({}, require('./l10nUtil').autoGeneratedBraveToChromiumMapping)
const runGClient = (args, options = {}) => {
if (config.gClientVerbose) args.push('--verbose')
@@ -65,18 +66,22 @@ const util = {
const braveBrowserDir = path.join(config.projects['brave-core'].dir, 'browser')
const braveAppVectorIconsDir = path.join(config.projects['brave-core'].dir, 'vector_icons', 'chrome', 'app')
- fs.copySync(path.join(braveAppDir, 'brave_strings.grd'), path.join(chromeAppDir, 'brave_strings.grd'))
- fs.copySync(path.join(braveAppDir, 'settings_brave_strings.grdp'), path.join(chromeAppDir, 'settings_brave_strings.grdp'))
- fs.copySync(path.join(braveAppDir, 'generated_resources.grd'), path.join(chromeAppDir, 'generated_resources.grd'))
- fs.copySync(path.join(braveAppDir, 'bookmarks_strings.grdp'), path.join(chromeAppDir, 'bookmarks_strings.grdp'))
- fs.copySync(path.join(braveAppDir, 'media_router_strings.grdp'), path.join(chromeAppDir, 'media_router_strings.grdp'))
-
- fs.copySync(path.join(braveAppDir, 'settings_strings.grdp'), path.join(chromeAppDir, 'settings_strings.grdp'))
- fs.copySync(path.join(braveAppDir, 'md_extensions_strings.grdp'), path.join(chromeAppDir, 'md_extensions_strings.grdp'))
- fs.copySync(path.join(braveResourcesDir, 'md_extensions', 'extensions_resources.grd'), path.join(chromeResourcesDir, 'md_extensions', 'extensions_resources.grd'))
- fs.copySync(path.join(braveResourcesDir, 'settings', 'settings_resources.grd'), path.join(chromeResourcesDir, 'settings', 'settings_resources.grd'))
- fs.copySync(path.join(braveBrowserDir, 'browser_resources.grd'), path.join(chromeBrowserDir, 'browser_resources.grd'))
- fs.copySync(path.join(braveAppDir, 'components_brave_strings.grd'), path.join(config.srcDir, 'components', 'components_brave_strings.grd'))
+ // The following 3 entries we map to the same name, not the chromium equivalent name for copying back
+ autoGeneratedBraveToChromiumMapping[path.join(braveAppDir, 'brave_strings.grd')] = path.join(chromeAppDir, 'brave_strings.grd')
+ autoGeneratedBraveToChromiumMapping[path.join(braveAppDir, 'settings_brave_strings.grdp')] = path.join(chromeAppDir, 'settings_brave_strings.grdp')
+ autoGeneratedBraveToChromiumMapping[path.join(braveAppDir, 'components_brave_strings.grd')] = path.join(config.srcDir, 'components', 'components_brave_strings.grd')
+
+ // Copy each grd back to Chromium src dir
+ Object.entries(autoGeneratedBraveToChromiumMapping).forEach(([bravePath, chromiumPath]) =>
+ fs.copySync(bravePath, chromiumPath))
+
+ // Copy xtb files for:
+ // brave/app/resources/chromium_strings*.xtb
+ // brave/app/strings/components_chromium_strings*.xtb
+ // brave/app/resources/generated_resoruces*.xtb
+ fs.copySync(path.join(braveAppDir, 'resources'), path.join(chromeAppDir, 'resources'))
+ fs.copySync(path.join(braveAppDir, 'strings'), path.join(chromeComponentsDir, 'strings'))
+
fs.copySync(path.join(braveAppDir, 'theme', 'brave'), path.join(chromeAppDir, 'theme', 'brave'))
fs.copySync(path.join(braveAppDir, 'theme', 'default_100_percent', 'brave'), path.join(chromeAppDir, 'theme', 'default_100_percent', 'brave'))
fs.copySync(path.join(braveAppDir, 'theme', 'default_200_percent', 'brave'), path.join(chromeAppDir, 'theme', 'default_200_percent', 'brave'))
@@ -87,10 +92,6 @@ const util = {
fs.copySync(path.join(braveComponentsDir, 'resources', 'default_100_percent', 'brave'), path.join(chromeComponentsDir, 'resources', 'default_100_percent', 'chromium'))
fs.copySync(path.join(braveComponentsDir, 'resources', 'default_200_percent', 'brave'), path.join(chromeComponentsDir, 'resources', 'default_200_percent', 'chromium'))
fs.copySync(path.join(braveAppVectorIconsDir, 'vector_icons', 'brave'), path.join(chromeAppDir, 'vector_icons', 'brave'))
- // Copy XTB files for app/brave_strings.grd => chromium_strings.grd
- fs.copySync(path.join(braveAppDir, 'resources'), path.join(chromeAppDir, 'resources'))
- // Copy XTB files for brave/app/components_brave_strings.grd => components/components_chromium_strings.grd
- fs.copySync(path.join(braveAppDir, 'strings'), path.join(chromeComponentsDir, 'strings'))
fs.copySync(path.join(braveResourcesDir, 'settings', 'brave_page_visibility.js'), path.join(chromeResourcesDir, 'settings', 'brave_page_visibility.js'))
},