Bug 1246748 - Complete the implementation of chrome.i18n.getUILanguage, r?kmag
Implement chrome.i18n.getUILanguage including tests
Add API to content scripts
MozReview-Commit-ID: IcDlLj8Et73
--- a/toolkit/components/extensions/Extension.jsm
+++ b/toolkit/components/extensions/Extension.jsm
@@ -1177,9 +1177,8 @@ Extension.prototype = extend(Object.crea
hasPermission(perm) {
return this.permissions.has(perm);
},
get name() {
return this.localize(this.manifest.name);
},
});
-
--- a/toolkit/components/extensions/ExtensionContent.jsm
+++ b/toolkit/components/extensions/ExtensionContent.jsm
@@ -113,16 +113,20 @@ var api = context => {
inIncognitoContext: PrivateBrowsingUtils.isContentWindowPrivate(context.contentWindow),
},
i18n: {
getMessage: function(messageName, substitutions) {
return context.extension.localizeMessage(messageName, substitutions);
},
+
+ getUILanguage: function() {
+ return context.extension.localeData.uiLocale;
+ },
},
};
};
// Represents a content script.
function Script(options, deferred = PromiseUtils.defer()) {
this.options = options;
this.run_at = this.options.run_at;
--- a/toolkit/components/extensions/ExtensionUtils.jsm
+++ b/toolkit/components/extensions/ExtensionUtils.jsm
@@ -328,19 +328,17 @@ LocaleData.prototype = {
}
};
return str.replace(/\$(?:([1-9]\d*)|(\$+))/g, replacer);
}
}
// Check for certain pre-defined messages.
if (message == "@@ui_locale") {
- // Return the browser locale, but convert it to a Chrome-style
- // locale code.
- return Locale.getLocale().replace(/-/g, "_");
+ return this.uiLocale;
} else if (message.startsWith("@@bidi_")) {
let registry = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry);
let rtl = registry.isLocaleRTL("global");
if (message == "@@bidi_dir") {
return rtl ? "rtl" : "ltr";
} else if (message == "@@bidi_reversed_dir") {
return rtl ? "ltr" : "rtl";
@@ -421,16 +419,23 @@ LocaleData.prototype = {
// Message names are also case-insensitive, so normalize them to lower-case.
result.set(key.toLowerCase(), value);
}
this.messages.set(locale, result);
return result;
},
+
+ get uiLocale() {
+ // Return the browser locale, but convert it to a Chrome-style
+ // locale code.
+ return Locale.getLocale().replace(/-/g, "_");
+ },
+
};
// This is a generic class for managing event listeners. Example usage:
//
// new EventManager(context, "api.subAPI", fire => {
// let listener = (...) => {
// // Fire any listeners registered with addListener.
// fire(arg1, arg2);
--- a/toolkit/components/extensions/ext-i18n.js
+++ b/toolkit/components/extensions/ext-i18n.js
@@ -1,11 +1,15 @@
"use strict";
extensions.registerSchemaAPI("i18n", null, (extension, context) => {
return {
i18n: {
getMessage: function(messageName, substitutions) {
return extension.localizeMessage(messageName, substitutions);
},
+
+ getUILanguage: function() {
+ return extension.localeData.uiLocale;
+ },
},
};
});
--- a/toolkit/components/extensions/schemas/i18n.json
+++ b/toolkit/components/extensions/schemas/i18n.json
@@ -63,17 +63,16 @@
],
"returns": {
"type": "string",
"description": "Message localized for current locale."
}
},
{
"name": "getUILanguage",
- "unsupported": true,
"type": "function",
"description": "Gets the browser UI language of the browser. This is different from $(ref:i18n.getAcceptLanguages) which returns the preferred user languages.",
"parameters": [],
"returns": {
"type": "string",
"description": "The browser UI language code such as en-US or fr-FR."
}
},
--- a/toolkit/components/extensions/test/mochitest/test_ext_i18n.html
+++ b/toolkit/components/extensions/test/mochitest/test_ext_i18n.html
@@ -9,16 +9,18 @@
<script type="text/javascript" src="head.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="text/javascript">
"use strict";
+SimpleTest.registerCleanupFunction(() => { SpecialPowers.clearUserPref("general.useragent.locale"); });
+
add_task(function* test_i18n() {
function runTests(assertEq) {
let _ = browser.i18n.getMessage.bind(browser.i18n);
let url = browser.runtime.getURL("/");
assertEq(url, `moz-extension://${_("@@extension_id")}/`, "@@extension_id builtin message");
assertEq("Foo.", _("Foo"), "Simple message in selected locale.");
@@ -156,12 +158,91 @@ add_task(function* test_i18n() {
let win = window.open("file_sample.html");
yield extension.awaitMessage("content-script-finished");
win.close();
yield extension.awaitFinish("l10n");
yield extension.unload();
});
+add_task(function* test_get_ui_language() {
+ function getResults() {
+ return {
+ getUILanguage: browser.i18n.getUILanguage(),
+ getMessage: browser.i18n.getMessage("@@ui_locale"),
+ };
+ }
+
+ function background(getResults) {
+ function checkResults(source, results, expected) {
+ browser.test.assertEq(
+ expected,
+ results.getUILanguage,
+ `Got expected getUILanguage result in ${source}`
+ );
+ browser.test.assertEq(
+ expected,
+ results.getMessage,
+ `Got expected getMessage result in ${source}`
+ );
+ }
+
+ let tabId;
+
+ browser.test.onMessage.addListener(([msg, expected]) => {
+ browser.tabs.sendMessage(tabId, "get-results", result => {
+ checkResults("contentScript", result, expected);
+ checkResults("background", getResults(), expected);
+
+ browser.test.sendMessage("done");
+ });
+ });
+
+ browser.tabs.query({currentWindow: true, active: true}, tabs => {
+ tabId = tabs[0].id;
+ browser.test.sendMessage("ready");
+ });
+ }
+
+ function content(getResults) {
+ browser.runtime.onMessage.addListener((msg, sender, respond) => {
+ respond(getResults());
+ });
+ }
+
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ "content_scripts": [{
+ "matches": ["http://mochi.test/*/file_sample.html"],
+ "run_at": "document_start",
+ "js": ["content_script.js"],
+ }],
+ },
+
+ background: `(${background})(${getResults})`,
+
+ files: {
+ "content_script.js": `(${content})(${getResults})`,
+ },
+ });
+
+ let win = window.open("file_sample.html");
+
+ yield extension.startup();
+ yield extension.awaitMessage("ready");
+
+ extension.sendMessage(["expect-results", "en_US"]);
+ yield extension.awaitMessage("done");
+
+ SpecialPowers.setCharPref("general.useragent.locale", "he");
+
+ extension.sendMessage(["expect-results", "he"]);
+ yield extension.awaitMessage("done");
+
+ win.close();
+
+ yield extension.unload();
+});
+
</script>
</body>
</html>