/* 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/. */ /** * RelativeTimeFormat internal properties. * * Spec: ECMAScript 402 API, RelativeTimeFormat, 1.3.3. */ var relativeTimeFormatInternalProperties = { localeData: relativeTimeFormatLocaleData, relevantExtensionKeys: ["nu"], }; function relativeTimeFormatLocaleData() { return { nu: getNumberingSystems, default: { nu: intl_numberingSystem, }, }; } /** * Compute an internal properties object from |lazyRelativeTimeFormatData|. */ function resolveRelativeTimeFormatInternals(lazyRelativeTimeFormatData) { assert(IsObject(lazyRelativeTimeFormatData), "lazy data not an object?"); var internalProps = std_Object_create(null); var RelativeTimeFormat = relativeTimeFormatInternalProperties; // Steps 10-11. const r = ResolveLocale("RelativeTimeFormat", lazyRelativeTimeFormatData.requestedLocales, lazyRelativeTimeFormatData.opt, RelativeTimeFormat.relevantExtensionKeys, RelativeTimeFormat.localeData); // Steps 12-13. internalProps.locale = r.locale; // Step 14. internalProps.numberingSystem = r.nu; // Step 15 (Not relevant in our implementation). // Step 17. internalProps.style = lazyRelativeTimeFormatData.style; // Step 19. internalProps.numeric = lazyRelativeTimeFormatData.numeric; // Steps 20-24 (Not relevant in our implementation). return internalProps; } /** * Returns an object containing the RelativeTimeFormat internal properties of |obj|. */ function getRelativeTimeFormatInternals(obj) { assert(IsObject(obj), "getRelativeTimeFormatInternals called with non-object"); assert(GuardToRelativeTimeFormat(obj) !== null, "getRelativeTimeFormatInternals called with non-RelativeTimeFormat"); var internals = getIntlObjectInternals(obj); assert(internals.type === "RelativeTimeFormat", "bad type escaped getIntlObjectInternals"); var internalProps = maybeInternalProperties(internals); if (internalProps) return internalProps; internalProps = resolveRelativeTimeFormatInternals(internals.lazyData); setInternalProperties(internals, internalProps); return internalProps; } /** * Initializes an object as a RelativeTimeFormat. * * This method is complicated a moderate bit by its implementing initialization * as a *lazy* concept. Everything that must happen now, does -- but we defer * all the work we can until the object is actually used as a RelativeTimeFormat. * This later work occurs in |resolveRelativeTimeFormatInternals|; steps not noted * here occur there. * * Spec: ECMAScript 402 API, RelativeTimeFormat, 1.1.1. */ function InitializeRelativeTimeFormat(relativeTimeFormat, locales, options) { assert(IsObject(relativeTimeFormat), "InitializeRelativeimeFormat called with non-object"); assert(GuardToRelativeTimeFormat(relativeTimeFormat) !== null, "InitializeRelativeTimeFormat called with non-RelativeTimeFormat"); // Lazy RelativeTimeFormat data has the following structure: // // { // requestedLocales: List of locales, // style: "long" / "short" / "narrow", // numeric: "always" / "auto", // // opt: // opt object computed in InitializeRelativeTimeFormat // { // localeMatcher: "lookup" / "best fit", // } // } // // Note that lazy data is only installed as a final step of initialization, // so every RelativeTimeFormat lazy data object has *all* these properties, never a // subset of them. const lazyRelativeTimeFormatData = std_Object_create(null); // Step 1. let requestedLocales = CanonicalizeLocaleList(locales); lazyRelativeTimeFormatData.requestedLocales = requestedLocales; // Steps 2-3. if (options === undefined) options = std_Object_create(null); else options = ToObject(options); // Step 4. let opt = new Record(); // Steps 5-6. let matcher = GetOption(options, "localeMatcher", "string", ["lookup", "best fit"], "best fit"); opt.localeMatcher = matcher; // Steps 7-9. let numberingSystem = GetOption(options, "numberingSystem", "string", undefined, undefined); if (numberingSystem !== undefined) { numberingSystem = intl_ValidateAndCanonicalizeUnicodeExtensionType(numberingSystem, "numberingSystem", "nu"); } opt.nu = numberingSystem; lazyRelativeTimeFormatData.opt = opt; // Steps 16-17. const style = GetOption(options, "style", "string", ["long", "short", "narrow"], "long"); lazyRelativeTimeFormatData.style = style; // Steps 18-19. const numeric = GetOption(options, "numeric", "string", ["always", "auto"], "always"); lazyRelativeTimeFormatData.numeric = numeric; initializeIntlObject(relativeTimeFormat, "RelativeTimeFormat", lazyRelativeTimeFormatData); } /** * Returns the subset of the given locale list for which this locale list has a * matching (possibly fallback) locale. Locales appear in the same order in the * returned list as in the input list. * * Spec: ECMAScript 402 API, RelativeTimeFormat, 1.3.2. */ function Intl_RelativeTimeFormat_supportedLocalesOf(locales /*, options*/) { var options = arguments.length > 1 ? arguments[1] : undefined; // Step 1. var availableLocales = "RelativeTimeFormat"; // Step 2. let requestedLocales = CanonicalizeLocaleList(locales); // Step 3. return SupportedLocales(availableLocales, requestedLocales, options); } /** * Returns a String value representing the written form of a relative date * formatted according to the effective locale and the formatting options * of this RelativeTimeFormat object. * * Spec: ECMAScript 402 API, RelativeTImeFormat, 1.4.3. */ function Intl_RelativeTimeFormat_format(value, unit) { // Step 1. let relativeTimeFormat = this; // Step 2. if (!IsObject(relativeTimeFormat) || (relativeTimeFormat = GuardToRelativeTimeFormat(relativeTimeFormat)) === null) { return callFunction(CallRelativeTimeFormatMethodIfWrapped, this, value, unit, "Intl_RelativeTimeFormat_format"); } // Step 3. let t = ToNumber(value); // Step 4. let u = ToString(unit); // Ensure the RelativeTimeFormat internals are resolved. var internals = getRelativeTimeFormatInternals(relativeTimeFormat); // Step 5. return intl_FormatRelativeTime(relativeTimeFormat, t, u, internals.numeric, false); } /** * Returns an Array composed of the components of a relative date formatted * according to the effective locale and the formatting options of this * RelativeTimeFormat object. * * Spec: ECMAScript 402 API, RelativeTImeFormat, 1.4.4. */ function Intl_RelativeTimeFormat_formatToParts(value, unit) { // Step 1. let relativeTimeFormat = this; // Step 2. if (!IsObject(relativeTimeFormat) || (relativeTimeFormat = GuardToRelativeTimeFormat(relativeTimeFormat)) === null) { return callFunction(CallRelativeTimeFormatMethodIfWrapped, this, value, unit, "Intl_RelativeTimeFormat_formatToParts"); } // Step 3. let t = ToNumber(value); // Step 4. let u = ToString(unit); // Ensure the RelativeTimeFormat internals are resolved. var internals = getRelativeTimeFormatInternals(relativeTimeFormat); // Step 5. return intl_FormatRelativeTime(relativeTimeFormat, t, u, internals.numeric, true); } /** * Returns the resolved options for a RelativeTimeFormat object. * * Spec: ECMAScript 402 API, RelativeTimeFormat, 1.4.5. */ function Intl_RelativeTimeFormat_resolvedOptions() { // Step 1. var relativeTimeFormat = this; // Steps 2-3. if (!IsObject(relativeTimeFormat) || (relativeTimeFormat = GuardToRelativeTimeFormat(relativeTimeFormat)) === null) { return callFunction(CallRelativeTimeFormatMethodIfWrapped, this, "Intl_RelativeTimeFormat_resolvedOptions"); } var internals = getRelativeTimeFormatInternals(relativeTimeFormat); // Steps 4-5. var result = { locale: internals.locale, style: internals.style, numeric: internals.numeric, numberingSystem: internals.numberingSystem, }; // Step 6. return result; }