diff options
Diffstat (limited to 'js/src/builtin/intl/IntlObject.js')
-rw-r--r-- | js/src/builtin/intl/IntlObject.js | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/js/src/builtin/intl/IntlObject.js b/js/src/builtin/intl/IntlObject.js new file mode 100644 index 0000000000..2612df9c79 --- /dev/null +++ b/js/src/builtin/intl/IntlObject.js @@ -0,0 +1,216 @@ +/* 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/. */ + +/** + * 8.2.1 Intl.getCanonicalLocales ( locales ) + * + * ES2017 Intl draft rev 947aa9a0c853422824a0c9510d8f09be3eb416b9 + */ +function Intl_getCanonicalLocales(locales) { + // Steps 1-2. + return CanonicalizeLocaleList(locales); +} + +/** + * This function is a custom function in the style of the standard Intl.* + * functions, that isn't part of any spec or proposal yet. + * + * Returns an object with the following properties: + * locale: + * The actual resolved locale. + * + * calendar: + * The default calendar of the resolved locale. + * + * firstDayOfWeek: + * The first day of the week for the resolved locale. + * + * minDays: + * The minimum number of days in a week for the resolved locale. + * + * weekendStart: + * The day considered the beginning of a weekend for the resolved locale. + * + * weekendEnd: + * The day considered the end of a weekend for the resolved locale. + * + * Days are encoded as integers in the range 1=Sunday to 7=Saturday. + */ +function Intl_getCalendarInfo(locales) { + // 1. Let requestLocales be ? CanonicalizeLocaleList(locales). + const requestedLocales = CanonicalizeLocaleList(locales); + + const DateTimeFormat = dateTimeFormatInternalProperties; + + // 2. Let localeData be %DateTimeFormat%.[[localeData]]. + const localeData = DateTimeFormat.localeData; + + // 3. Let localeOpt be a new Record. + const localeOpt = new Record(); + + // 4. Set localeOpt.[[localeMatcher]] to "best fit". + localeOpt.localeMatcher = "best fit"; + + // 5. Let r be ResolveLocale(%DateTimeFormat%.[[availableLocales]], + // requestedLocales, localeOpt, + // %DateTimeFormat%.[[relevantExtensionKeys]], localeData). + const r = ResolveLocale("DateTimeFormat", + requestedLocales, + localeOpt, + DateTimeFormat.relevantExtensionKeys, + localeData); + + // 6. Let result be GetCalendarInfo(r.[[locale]]). + const result = intl_GetCalendarInfo(r.locale); + _DefineDataProperty(result, "calendar", r.ca); + _DefineDataProperty(result, "locale", r.locale); + + // 7. Return result. + return result; +} + +/** + * This function is a custom function in the style of the standard Intl.* + * functions, that isn't part of any spec or proposal yet. + * We want to use it internally to retrieve translated values from CLDR in + * order to ensure they're aligned with what Intl API returns. + * + * This API may one day be a foundation for an ECMA402 API spec proposal. + * + * The function takes two arguments - locales which is a list of locale strings + * and options which is an object with two optional properties: + * + * keys: + * an Array of string values that are paths to individual terms + * + * style: + * a String with a value "long", "short" or "narrow" + * + * It returns an object with properties: + * + * locale: + * a negotiated locale string + * + * style: + * negotiated style + * + * values: + * A key-value pair list of requested keys and corresponding + * translated values + * + */ +function Intl_getDisplayNames(locales, options) { + // 1. Let requestLocales be ? CanonicalizeLocaleList(locales). + const requestedLocales = CanonicalizeLocaleList(locales); + + // 2. If options is undefined, then + if (options === undefined) + // a. Let options be ObjectCreate(null). + options = std_Object_create(null); + // 3. Else, + else + // a. Let options be ? ToObject(options). + options = ToObject(options); + + const DateTimeFormat = dateTimeFormatInternalProperties; + + // 4. Let localeData be %DateTimeFormat%.[[localeData]]. + const localeData = DateTimeFormat.localeData; + + // 5. Let localeOpt be a new Record. + const localeOpt = new Record(); + + // 6. Set localeOpt.[[localeMatcher]] to "best fit". + localeOpt.localeMatcher = "best fit"; + + // 7. Let r be ResolveLocale(%DateTimeFormat%.[[availableLocales]], requestedLocales, localeOpt, + // %DateTimeFormat%.[[relevantExtensionKeys]], localeData). + const r = ResolveLocale("DateTimeFormat", + requestedLocales, + localeOpt, + DateTimeFormat.relevantExtensionKeys, + localeData); + + // 8. Let style be ? GetOption(options, "style", "string", « "long", "short", "narrow" », "long"). + const style = GetOption(options, "style", "string", ["long", "short", "narrow"], "long"); + + // 9. Let keys be ? Get(options, "keys"). + let keys = options.keys; + + // 10. If keys is undefined, + if (keys === undefined) { + // a. Let keys be ArrayCreate(0). + keys = []; + } else if (!IsObject(keys)) { + // 11. Else, + // a. If Type(keys) is not Object, throw a TypeError exception. + ThrowTypeError(JSMSG_INVALID_KEYS_TYPE); + } + + // 12. Let processedKeys be ArrayCreate(0). + // (This really should be a List, but we use an Array here in order that + // |intl_ComputeDisplayNames| may infallibly access the list's length via + // |ArrayObject::length|.) + let processedKeys = []; + + // 13. Let len be ? ToLength(? Get(keys, "length")). + let len = ToLength(keys.length); + + // 14. Let i be 0. + // 15. Repeat, while i < len + for (let i = 0; i < len; i++) { + // a. Let processedKey be ? ToString(? Get(keys, i)). + // b. Perform ? CreateDataPropertyOrThrow(processedKeys, i, processedKey). + _DefineDataProperty(processedKeys, i, ToString(keys[i])); + } + + // 16. Let names be ? ComputeDisplayNames(r.[[locale]], style, processedKeys). + const names = intl_ComputeDisplayNames(r.locale, style, processedKeys); + + // 17. Let values be ObjectCreate(%ObjectPrototype%). + const values = {}; + + // 18. Set i to 0. + // 19. Repeat, while i < len + for (let i = 0; i < len; i++) { + // a. Let key be ? Get(processedKeys, i). + const key = processedKeys[i]; + // b. Let name be ? Get(names, i). + const name = names[i]; + // c. Assert: Type(name) is string. + assert(typeof name === "string", "unexpected non-string value"); + // d. Assert: the length of name is greater than zero. + assert(name.length > 0, "empty string value"); + // e. Perform ? DefinePropertyOrThrow(values, key, name). + _DefineDataProperty(values, key, name); + } + + // 20. Let options be ObjectCreate(%ObjectPrototype%). + // 21. Perform ! DefinePropertyOrThrow(result, "locale", r.[[locale]]). + // 22. Perform ! DefinePropertyOrThrow(result, "style", style). + // 23. Perform ! DefinePropertyOrThrow(result, "values", values). + const result = { locale: r.locale, style, values }; + + // 24. Return result. + return result; +} + +function Intl_getLocaleInfo(locales) { + const requestedLocales = CanonicalizeLocaleList(locales); + + // In the future, we may want to expose uloc_getAvailable and use it here. + const DateTimeFormat = dateTimeFormatInternalProperties; + const localeData = DateTimeFormat.localeData; + + const localeOpt = new Record(); + localeOpt.localeMatcher = "best fit"; + + const r = ResolveLocale("DateTimeFormat", + requestedLocales, + localeOpt, + DateTimeFormat.relevantExtensionKeys, + localeData); + + return intl_GetLocaleInfo(r.locale); +} |