author | Zibi Braniecki <gandalf@mozilla.com> |
Wed, 01 Mar 2017 16:58:11 -0800 | |
changeset 345591 | afd35703e5b01482e48fca74bfb29da982af5ec5 |
parent 345590 | 8f70ae357674bb83a2c73d2a918e6477f6673c5d |
child 345592 | 077b849d2beb99a92dc9ec8caa8d2023b170dcbc |
push id | 38235 |
push user | zbraniecki@mozilla.com |
push date | Thu, 02 Mar 2017 19:52:03 +0000 |
treeherder | autoland@afd35703e5b0 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | smaug |
bugs | 1339892 |
milestone | 54.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
|
--- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -545,16 +545,21 @@ @RESPATH@/components/PresentationDeviceInfoManager.manifest @RESPATH@/components/PresentationDeviceInfoManager.js @RESPATH@/components/BuiltinProviders.manifest @RESPATH@/components/PresentationControlService.js @RESPATH@/components/PresentationDataChannelSessionTransport.js @RESPATH@/components/PresentationDataChannelSessionTransport.manifest +#ifdef ENABLE_INTL_API +@RESPATH@/components/mozIntl.manifest +@RESPATH@/components/mozIntl.js +#endif + #if defined(ENABLE_TESTS) && defined(MOZ_DEBUG) @RESPATH@/components/TestInterfaceJS.js @RESPATH@/components/TestInterfaceJS.manifest @RESPATH@/components/TestInterfaceJSMaplike.js #endif ; [Extensions] @RESPATH@/components/extensions-toolkit.manifest
--- a/mobile/android/installer/package-manifest.in +++ b/mobile/android/installer/package-manifest.in @@ -393,16 +393,21 @@ @BINPATH@/components/PresentationDataChannelSessionTransport.js @BINPATH@/components/PresentationDataChannelSessionTransport.manifest @BINPATH@/components/AndroidCastDeviceProvider.manifest @BINPATH@/components/AndroidCastDeviceProvider.js @BINPATH@/components/TVSimulatorService.js @BINPATH@/components/TVSimulatorService.manifest +#ifdef ENABLE_INTL_API +@BINPATH@/components/mozIntl.manifest +@BINPATH@/components/mozIntl.js +#endif + ; Modules @BINPATH@/modules/* ; Safe Browsing @BINPATH@/components/nsURLClassifier.manifest @BINPATH@/components/nsUrlClassifierHashCompleter.js @BINPATH@/components/nsUrlClassifierListManager.js @BINPATH@/components/nsUrlClassifierLib.js
rename from toolkit/components/mozintl/MozIntl.cpp rename to toolkit/components/mozintl/MozIntlHelper.cpp --- a/toolkit/components/mozintl/MozIntl.cpp +++ b/toolkit/components/mozintl/MozIntlHelper.cpp @@ -1,27 +1,27 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode:nil; c-basic-offset: 2 -*- */ /* 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/. */ -#include "MozIntl.h" +#include "MozIntlHelper.h" #include "jswrapper.h" #include "mozilla/ModuleUtils.h" -#define MOZ_MOZINTL_CID \ - { 0x83f8f991, 0x6b81, 0x4dd8, { 0xa0, 0x93, 0x72, 0x0b, 0xfb, 0x67, 0x4d, 0x38 } } +#define MOZ_MOZINTLHELPER_CID \ + { 0xb43c96be, 0x2b3a, 0x4dc4, { 0x90, 0xe9, 0xb0, 0x6d, 0x34, 0x21, 0x9b, 0x68 } } using namespace mozilla; -NS_IMPL_ISUPPORTS(MozIntl, mozIMozIntl) +NS_IMPL_ISUPPORTS(MozIntlHelper, mozIMozIntlHelper) -MozIntl::MozIntl() = default; +MozIntlHelper::MozIntlHelper() = default; -MozIntl::~MozIntl() = default; +MozIntlHelper::~MozIntlHelper() = default; static nsresult AddFunctions(JSContext* cx, JS::Handle<JS::Value> val, const JSFunctionSpec* funcs) { if (!val.isObject()) { return NS_ERROR_INVALID_ARG; } @@ -35,39 +35,39 @@ AddFunctions(JSContext* cx, JS::Handle<J if (!JS_DefineFunctions(cx, realIntlObj, funcs)) { return NS_ERROR_FAILURE; } return NS_OK; } NS_IMETHODIMP -MozIntl::AddGetCalendarInfo(JS::Handle<JS::Value> val, JSContext* cx) +MozIntlHelper::AddGetCalendarInfo(JS::Handle<JS::Value> val, JSContext* cx) { static const JSFunctionSpec funcs[] = { JS_SELF_HOSTED_FN("getCalendarInfo", "Intl_getCalendarInfo", 1, 0), JS_FS_END }; return AddFunctions(cx, val, funcs); } NS_IMETHODIMP -MozIntl::AddGetDisplayNames(JS::Handle<JS::Value> val, JSContext* cx) +MozIntlHelper::AddGetDisplayNames(JS::Handle<JS::Value> val, JSContext* cx) { static const JSFunctionSpec funcs[] = { JS_SELF_HOSTED_FN("getDisplayNames", "Intl_getDisplayNames", 2, 0), JS_FS_END }; return AddFunctions(cx, val, funcs); } NS_IMETHODIMP -MozIntl::AddPluralRulesConstructor(JS::Handle<JS::Value> val, JSContext* cx) +MozIntlHelper::AddPluralRulesConstructor(JS::Handle<JS::Value> val, JSContext* cx) { if (!val.isObject()) { return NS_ERROR_INVALID_ARG; } JS::Rooted<JSObject*> realIntlObj(cx, js::CheckedUnwrap(&val.toObject())); if (!realIntlObj) { return NS_ERROR_INVALID_ARG; @@ -78,42 +78,42 @@ MozIntl::AddPluralRulesConstructor(JS::H if (!js::AddPluralRulesConstructor(cx, realIntlObj)) { return NS_ERROR_FAILURE; } return NS_OK; } NS_IMETHODIMP -MozIntl::AddGetLocaleInfo(JS::Handle<JS::Value> val, JSContext* cx) +MozIntlHelper::AddGetLocaleInfo(JS::Handle<JS::Value> val, JSContext* cx) { static const JSFunctionSpec funcs[] = { JS_SELF_HOSTED_FN("getLocaleInfo", "Intl_getLocaleInfo", 1, 0), JS_FS_END }; return AddFunctions(cx, val, funcs); } -NS_GENERIC_FACTORY_CONSTRUCTOR(MozIntl) -NS_DEFINE_NAMED_CID(MOZ_MOZINTL_CID); +NS_GENERIC_FACTORY_CONSTRUCTOR(MozIntlHelper) +NS_DEFINE_NAMED_CID(MOZ_MOZINTLHELPER_CID); -static const Module::CIDEntry kMozIntlCIDs[] = { - { &kMOZ_MOZINTL_CID, false, nullptr, MozIntlConstructor }, +static const Module::CIDEntry kMozIntlHelperCIDs[] = { + { &kMOZ_MOZINTLHELPER_CID, false, nullptr, MozIntlHelperConstructor }, { nullptr } }; -static const mozilla::Module::ContractIDEntry kMozIntlContracts[] = { - { "@mozilla.org/mozintl;1", &kMOZ_MOZINTL_CID }, +static const mozilla::Module::ContractIDEntry kMozIntlHelperContracts[] = { + { "@mozilla.org/mozintlhelper;1", &kMOZ_MOZINTLHELPER_CID }, { nullptr } }; -static const mozilla::Module kMozIntlModule = { +static const mozilla::Module kMozIntlHelperModule = { mozilla::Module::kVersion, - kMozIntlCIDs, - kMozIntlContracts, + kMozIntlHelperCIDs, + kMozIntlHelperContracts, nullptr, nullptr, nullptr, nullptr }; -NSMODULE_DEFN(mozMozIntlModule) = &kMozIntlModule; +NSMODULE_DEFN(mozMozIntlHelperModule) = &kMozIntlHelperModule;
rename from toolkit/components/mozintl/MozIntl.h rename to toolkit/components/mozintl/MozIntlHelper.h --- a/toolkit/components/mozintl/MozIntl.h +++ b/toolkit/components/mozintl/MozIntlHelper.h @@ -1,22 +1,22 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode:nil; c-basic-offset: 2 -*- */ /* 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/. */ -#include "mozIMozIntl.h" +#include "mozIMozIntlHelper.h" namespace mozilla { -class MozIntl final : public mozIMozIntl +class MozIntlHelper final : public mozIMozIntlHelper { public: NS_DECL_ISUPPORTS - NS_DECL_MOZIMOZINTL + NS_DECL_MOZIMOZINTLHELPER - MozIntl(); + MozIntlHelper(); private: - ~MozIntl(); + ~MozIntlHelper(); }; } // namespace mozilla
--- a/toolkit/components/mozintl/moz.build +++ b/toolkit/components/mozintl/moz.build @@ -3,17 +3,23 @@ # 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/. XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell.ini'] XPIDL_SOURCES += [ 'mozIMozIntl.idl', + 'mozIMozIntlHelper.idl', ] XPIDL_MODULE = 'mozintl' SOURCES += [ - 'MozIntl.cpp', + 'MozIntlHelper.cpp', +] + +EXTRA_COMPONENTS += [ + 'mozIntl.js', + 'mozIntl.manifest', ] FINAL_LIBRARY = 'xul'
--- a/toolkit/components/mozintl/mozIMozIntl.idl +++ b/toolkit/components/mozintl/mozIMozIntl.idl @@ -1,21 +1,45 @@ /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* 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/. */ #include "nsISupports.idl" -[scriptable, uuid(9f9bc42e-54f4-11e6-9aed-4b1429ac0ba0)] +/** + * This is a set of APIs that are of general usefulness for user interface + * internationalization. + * + * They're all in various stages of the standardization process through + * ECMA402, so they are exposed to privileged content only but are written + * in the way to allow for easy migration to standard Intl object once + * the appropriate stage of the ECMA402 is achieved. + * + * The exact structure of the code is a little bit complex because of that: + * + * 1) The core is in SpiderMonkey together with other Intl APIs + * + * This allows us to write the code once, stick to the spec language + * of the proposal, reuse our ICU bindings in Spidermonkey and use + * the code to inform us on refining the spec proposal for the given API itself. + * + * 2) The MozIntlHelper API exposes the SpiderMonkey APIs + * + * This helper API allows attaching the new APIs on any regular object. + * + * 3) The MozIntl API provides the access to those APIs + * + * This API exposes the actual functionality and wraps around the MozIntlHelper + * lazily retrieving and setting the accessors. + * On top of that, the API also binds additional functionality like using + * current application locale by default, and fetching OS regional preferences + * for date time format. + */ +[scriptable, uuid(7f63279a-1a29-4ae6-9e7a-dc9684a23530)] interface mozIMozIntl : nsISupports { - [implicit_jscontext] void addGetCalendarInfo(in jsval intlObject); - [implicit_jscontext] void addGetDisplayNames(in jsval intlObject); - [implicit_jscontext] void addGetLocaleInfo(in jsval intlObject); + jsval getCalendarInfo([optional] in jsval locales); + jsval getDisplayNames([optional] in jsval locales, [optional] in jsval options); + jsval getLocaleInfo([optional] in jsval locales); - /** - * Adds a PluralRules constructor to the given object. This function may only - * be called once within a realm/global object: calling it multiple times will - * throw. - */ - [implicit_jscontext] void addPluralRulesConstructor(in jsval intlObject); + jsval createPluralRules([optional] in jsval locales, [optional] in jsval options); };
copy from toolkit/components/mozintl/mozIMozIntl.idl copy to toolkit/components/mozintl/mozIMozIntlHelper.idl --- a/toolkit/components/mozintl/mozIMozIntl.idl +++ b/toolkit/components/mozintl/mozIMozIntlHelper.idl @@ -1,17 +1,25 @@ /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* 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/. */ #include "nsISupports.idl" -[scriptable, uuid(9f9bc42e-54f4-11e6-9aed-4b1429ac0ba0)] -interface mozIMozIntl : nsISupports +/** + * This is an internal helper for mozIMozIntl API. There should be virtually + * no reason for you to call this API except from mozIMozIntl implementation. + * + * This API helps accessing the SpiderMonkey Intl APIs, but it is mozIMozIntl + * that exposes the thin wrapper around them that binds the functionality + * to Gecko. + */ +[scriptable, uuid(189eaa7d-b29a-43a9-b1fb-7658990df940)] +interface mozIMozIntlHelper : nsISupports { [implicit_jscontext] void addGetCalendarInfo(in jsval intlObject); [implicit_jscontext] void addGetDisplayNames(in jsval intlObject); [implicit_jscontext] void addGetLocaleInfo(in jsval intlObject); /** * Adds a PluralRules constructor to the given object. This function may only * be called once within a realm/global object: calling it multiple times will
new file mode 100644 --- /dev/null +++ b/toolkit/components/mozintl/mozIntl.js @@ -0,0 +1,69 @@ +/* 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/. */ + +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); + +const Cc = Components.classes; +const Ci = Components.interfaces; + +const mozIntlHelper = + Cc["@mozilla.org/mozintlhelper;1"].getService(Ci.mozIMozIntlHelper); +const localeSvc = + Cc["@mozilla.org/intl/localeservice;1"].getService(Ci.mozILocaleService); + +/** + * This helper function retrives currently used app locales, allowing + * all mozIntl APIs to use the current app locales unless called with + * explicitly listed locales. + */ +function getLocales(locales) { + if (!locales) { + return localeSvc.getAppLocales(); + } + return locales; +} + +class MozIntl { + constructor() { + this._cache = {}; + } + + getCalendarInfo(locales, ...args) { + if (!this._cache.hasOwnProperty("getCalendarInfo")) { + mozIntlHelper.addGetCalendarInfo(this._cache); + } + + return this._cache.getCalendarInfo(getLocales(locales), ...args); + } + + getDisplayNames(locales, ...args) { + if (!this._cache.hasOwnProperty("getDisplayNames")) { + mozIntlHelper.addGetDisplayNames(this._cache); + } + + return this._cache.getDisplayNames(getLocales(locales), ...args); + } + + getLocaleInfo(locales, ...args) { + if (!this._cache.hasOwnProperty("getLocaleInfo")) { + mozIntlHelper.addGetLocaleInfo(this._cache); + } + + return this._cache.getLocaleInfo(getLocales(locales), ...args); + } + + createPluralRules(locales, ...args) { + if (!this._cache.hasOwnProperty("PluralRules")) { + mozIntlHelper.addPluralRulesConstructor(this._cache); + } + + return new this._cache.PluralRules(getLocales(locales), ...args); + } +} + +MozIntl.prototype.classID = Components.ID("{35ec195a-e8d0-4300-83af-c8a2cc84b4a3}"); +MozIntl.prototype.QueryInterface = XPCOMUtils.generateQI([Ci.mozIMozIntl, Ci.nsISupports]); + +var components = [MozIntl]; +this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
new file mode 100644 --- /dev/null +++ b/toolkit/components/mozintl/mozIntl.manifest @@ -0,0 +1,2 @@ +component {35ec195a-e8d0-4300-83af-c8a2cc84b4a3} mozIntl.js +contract @mozilla.org/mozintl;1 {35ec195a-e8d0-4300-83af-c8a2cc84b4a3}
--- a/toolkit/components/mozintl/test/test_mozintl.js +++ b/toolkit/components/mozintl/test/test_mozintl.js @@ -1,50 +1,27 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ function run_test() { const mozIntl = Components.classes["@mozilla.org/mozintl;1"] .getService(Components.interfaces.mozIMozIntl); - test_this_global(mozIntl); - test_cross_global(mozIntl); test_methods_presence(mozIntl); + test_methods_calling(mozIntl); ok(true); } -function test_this_global(mozIntl) { - let x = {}; - - mozIntl.addGetCalendarInfo(x); - equal(x.getCalendarInfo instanceof Function, true); - equal(x.getCalendarInfo() instanceof Object, true); +function test_methods_presence(mozIntl) { + equal(mozIntl.getCalendarInfo instanceof Function, true); + equal(mozIntl.getDisplayNames instanceof Function, true); + equal(mozIntl.getLocaleInfo instanceof Function, true); + equal(mozIntl.createPluralRules instanceof Function, true); } -function test_cross_global(mozIntl) { - var global = new Components.utils.Sandbox("https://example.com/"); - var x = global.Object(); - - mozIntl.addGetCalendarInfo(x); - var waivedX = Components.utils.waiveXrays(x); - equal(waivedX.getCalendarInfo instanceof Function, false); - equal(waivedX.getCalendarInfo instanceof global.Function, true); - equal(waivedX.getCalendarInfo() instanceof Object, false); - equal(waivedX.getCalendarInfo() instanceof global.Object, true); +function test_methods_calling(mozIntl) { + let ci = mozIntl.getCalendarInfo('pl'); + let dn = mozIntl.getDisplayNames('ar'); + let li = mozIntl.getLocaleInfo('de'); + let pr = mozIntl.createPluralRules('fr'); + ok(true); } - -function test_methods_presence(mozIntl) { - equal(mozIntl.addGetCalendarInfo instanceof Function, true); - equal(mozIntl.addGetDisplayNames instanceof Function, true); - equal(mozIntl.addGetLocaleInfo instanceof Function, true); - - let x = {}; - - mozIntl.addGetCalendarInfo(x); - equal(x.getCalendarInfo instanceof Function, true); - - mozIntl.addGetDisplayNames(x); - equal(x.getDisplayNames instanceof Function, true); - - mozIntl.addGetLocaleInfo(x); - equal(x.getLocaleInfo instanceof Function, true); -}
new file mode 100644 --- /dev/null +++ b/toolkit/components/mozintl/test/test_mozintlhelper.js @@ -0,0 +1,50 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +function run_test() { + const miHelper = Components.classes["@mozilla.org/mozintlhelper;1"] + .getService(Components.interfaces.mozIMozIntlHelper); + + test_this_global(miHelper); + test_cross_global(miHelper); + test_methods_presence(miHelper); + + ok(true); +} + +function test_this_global(miHelper) { + let x = {}; + + miHelper.addGetCalendarInfo(x); + equal(x.getCalendarInfo instanceof Function, true); + equal(x.getCalendarInfo() instanceof Object, true); +} + +function test_cross_global(miHelper) { + var global = new Components.utils.Sandbox("https://example.com/"); + var x = global.Object(); + + miHelper.addGetCalendarInfo(x); + var waivedX = Components.utils.waiveXrays(x); + equal(waivedX.getCalendarInfo instanceof Function, false); + equal(waivedX.getCalendarInfo instanceof global.Function, true); + equal(waivedX.getCalendarInfo() instanceof Object, false); + equal(waivedX.getCalendarInfo() instanceof global.Object, true); +} + +function test_methods_presence(miHelper) { + equal(miHelper.addGetCalendarInfo instanceof Function, true); + equal(miHelper.addGetDisplayNames instanceof Function, true); + equal(miHelper.addGetLocaleInfo instanceof Function, true); + + let x = {}; + + miHelper.addGetCalendarInfo(x); + equal(x.getCalendarInfo instanceof Function, true); + + miHelper.addGetDisplayNames(x); + equal(x.getDisplayNames instanceof Function, true); + + miHelper.addGetLocaleInfo(x); + equal(x.getLocaleInfo instanceof Function, true); +}
--- a/toolkit/components/mozintl/test/xpcshell.ini +++ b/toolkit/components/mozintl/test/xpcshell.ini @@ -1,4 +1,5 @@ [DEFAULT] head = [test_mozintl.js] +[test_mozintlhelper.js]
--- a/toolkit/content/widgets/datetimepopup.xml +++ b/toolkit/content/widgets/datetimepopup.xml @@ -18,21 +18,18 @@ <field name="dateTimePopupFrame"> this.querySelector("#dateTimePopupFrame"); </field> <field name="TIME_PICKER_WIDTH" readonly="true">"12em"</field> <field name="TIME_PICKER_HEIGHT" readonly="true">"21em"</field> <field name="DATE_PICKER_WIDTH" readonly="true">"23.1em"</field> <field name="DATE_PICKER_HEIGHT" readonly="true">"20.7em"</field> <constructor><![CDATA[ - this.l10n = {}; - const mozIntl = Components.classes["@mozilla.org/mozintl;1"] - .getService(Components.interfaces.mozIMozIntl); - mozIntl.addGetCalendarInfo(this.l10n); - mozIntl.addGetDisplayNames(this.l10n); + this.mozIntl = Components.classes["@mozilla.org/mozintl;1"] + .getService(Components.interfaces.mozIMozIntl); ]]></constructor> <method name="loadPicker"> <parameter name="type"/> <parameter name="detail"/> <body><![CDATA[ this.hidden = false; this.type = type; this.pickerState = {}; @@ -221,17 +218,17 @@ break; } } ]]></body> </method> <method name="getCalendarInfo"> <parameter name="locale"/> <body><![CDATA[ - const calendarInfo = this.l10n.getCalendarInfo(locale); + const calendarInfo = this.mozIntl.getCalendarInfo(locale); // Day of week from calendarInfo starts from 1 as Sunday to 7 as Saturday, // so they need to be mapped to JavaScript convention with 0 as Sunday // and 6 as Saturday let firstDayOfWeek = calendarInfo.firstDayOfWeek - 1, weekendStart = calendarInfo.weekendStart - 1, weekendEnd = calendarInfo.weekendEnd - 1; @@ -254,17 +251,17 @@ } ]]></body> </method> <method name="getDisplayNames"> <parameter name="locale"/> <parameter name="keys"/> <parameter name="style"/> <body><![CDATA[ - const displayNames = this.l10n.getDisplayNames(locale, {keys, style}); + const displayNames = this.mozIntl.getDisplayNames(locale, {keys, style}); return keys.map(key => displayNames.values[key]); ]]></body> </method> <method name="handleEvent"> <parameter name="aEvent"/> <body><![CDATA[ switch (aEvent.type) { case "load": {