summaryrefslogtreecommitdiffstats
path: root/js/src/builtin/intl/ListFormat.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /js/src/builtin/intl/ListFormat.js
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/builtin/intl/ListFormat.js')
-rw-r--r--js/src/builtin/intl/ListFormat.js276
1 files changed, 276 insertions, 0 deletions
diff --git a/js/src/builtin/intl/ListFormat.js b/js/src/builtin/intl/ListFormat.js
new file mode 100644
index 0000000000..ddb1c0e084
--- /dev/null
+++ b/js/src/builtin/intl/ListFormat.js
@@ -0,0 +1,276 @@
+/* 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/. */
+
+/**
+ * ListFormat internal properties.
+ */
+var listFormatInternalProperties = {
+ localeData: function() // eslint-disable-line object-shorthand
+ {
+ // ListFormat don't support any extension keys.
+ return {};
+ },
+ relevantExtensionKeys: []
+};
+
+/**
+ * Intl.ListFormat ( [ locales [ , options ] ] )
+ *
+ * Compute an internal properties object from |lazyListFormatData|.
+ */
+function resolveListFormatInternals(lazyListFormatData) {
+ assert(IsObject(lazyListFormatData), "lazy data not an object?");
+
+ var internalProps = std_Object_create(null);
+
+ var ListFormat = listFormatInternalProperties;
+
+ // Compute effective locale.
+
+ // Step 9.
+ var localeData = ListFormat.localeData;
+
+ // Step 10.
+ var r = ResolveLocale("ListFormat",
+ lazyListFormatData.requestedLocales,
+ lazyListFormatData.opt,
+ ListFormat.relevantExtensionKeys,
+ localeData);
+
+ // Step 11.
+ internalProps.locale = r.locale;
+
+ // Step 13.
+ internalProps.type = lazyListFormatData.type;
+
+ // Step 15.
+ internalProps.style = lazyListFormatData.style;
+
+ // Steps 16-23 (not applicable in our implementation).
+
+ // The caller is responsible for associating |internalProps| with the right
+ // object using |setInternalProperties|.
+ return internalProps;
+}
+
+/**
+ * Returns an object containing the ListFormat internal properties of |obj|.
+ */
+function getListFormatInternals(obj) {
+ assert(IsObject(obj), "getListFormatInternals called with non-object");
+ assert(GuardToListFormat(obj) !== null, "getListFormatInternals called with non-ListFormat");
+
+ var internals = getIntlObjectInternals(obj);
+ assert(internals.type === "ListFormat", "bad type escaped getIntlObjectInternals");
+
+ // If internal properties have already been computed, use them.
+ var internalProps = maybeInternalProperties(internals);
+ if (internalProps)
+ return internalProps;
+
+ // Otherwise it's time to fully create them.
+ internalProps = resolveListFormatInternals(internals.lazyData);
+ setInternalProperties(internals, internalProps);
+ return internalProps;
+}
+
+/**
+ * Intl.ListFormat ( [ locales [ , options ] ] )
+ *
+ * Initializes an object as a ListFormat.
+ *
+ * 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 ListFormat.
+ * This later work occurs in |resolveListFormatInternals|; steps not noted
+ * here occur there.
+ */
+function InitializeListFormat(listFormat, locales, options, supportsTypeAndStyle) {
+ assert(IsObject(listFormat), "InitializeListFormat called with non-object");
+ assert(GuardToListFormat(listFormat) !== null, "InitializeListFormat called with non-ListFormat");
+
+ // Lazy ListFormat data has the following structure:
+ //
+ // {
+ // requestedLocales: List of locales,
+ // type: "conjunction" / "disjunction" / "unit",
+ // style: "long" / "short" / "narrow",
+ //
+ // opt: // opt object computed in InitializeListFormat
+ // {
+ // localeMatcher: "lookup" / "best fit",
+ // }
+ // }
+ //
+ // Note that lazy data is only installed as a final step of initialization,
+ // so every ListFormat lazy data object has *all* these properties, never a
+ // subset of them.
+ var lazyListFormatData = std_Object_create(null);
+
+ // Step 3.
+ var requestedLocales = CanonicalizeLocaleList(locales);
+ lazyListFormatData.requestedLocales = requestedLocales;
+
+ // Steps 4-5.
+ if (options === undefined)
+ options = std_Object_create(null);
+ else
+ options = ToObject(options);
+
+ // Step 6.
+ var opt = new Record();
+ lazyListFormatData.opt = opt;
+
+ // Steps 7-8.
+ let matcher = GetOption(options, "localeMatcher", "string", ["lookup", "best fit"], "best fit");
+ opt.localeMatcher = matcher;
+
+ // Compute formatting options.
+
+ // Supporting all "type" and "style" options requires draft APIs in ICU 67,
+ // which may not be available when compiling against a system ICU.
+
+ // Steps 12-13.
+ var type = GetOption(options, "type", "string",
+ supportsTypeAndStyle ? ["conjunction", "disjunction", "unit"] : ["conjunction"],
+ "conjunction");
+ lazyListFormatData.type = type;
+
+ // Steps 14-15.
+ var style = GetOption(options, "style", "string",
+ supportsTypeAndStyle ? ["long", "short", "narrow"] : ["long"],
+ "long");
+ lazyListFormatData.style = style;
+
+ // We've done everything that must be done now: mark the lazy data as fully
+ // computed and install it.
+ initializeIntlObject(listFormat, "ListFormat", lazyListFormatData);
+}
+
+/**
+ * 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.
+ */
+function Intl_ListFormat_supportedLocalesOf(locales /*, options*/) {
+ var options = arguments.length > 1 ? arguments[1] : undefined;
+
+ // Step 1.
+ var availableLocales = "ListFormat";
+
+ // Step 2.
+ var requestedLocales = CanonicalizeLocaleList(locales);
+
+ // Step 3.
+ return SupportedLocales(availableLocales, requestedLocales, options);
+}
+
+/**
+ * StringListFromIterable ( iterable )
+ */
+function StringListFromIterable(iterable, methodName) {
+ // Step 1.
+ if (iterable === undefined) {
+ return [];
+ }
+
+ // Step 3.
+ var list = [];
+
+ // Steps 2, 4-5.
+ for (var element of allowContentIter(iterable)) {
+ // Step 5.b.ii.
+ if (typeof element !== "string") {
+ ThrowTypeError(JSMSG_NOT_EXPECTED_TYPE, methodName, "string", typeof element);
+ }
+
+ // Step 5.b.iii.
+ _DefineDataProperty(list, list.length, element);
+ }
+
+ // Step 6.
+ return list;
+}
+
+/**
+ * Intl.ListFormat.prototype.format ( list )
+ */
+function Intl_ListFormat_format(list) {
+ // Step 1.
+ var listFormat = this;
+
+ // Steps 2-3.
+ if (!IsObject(listFormat) || (listFormat = GuardToListFormat(listFormat)) === null) {
+ return callFunction(CallListFormatMethodIfWrapped, this, list,
+ "Intl_ListFormat_format");
+ }
+
+ // Step 4.
+ var stringList = StringListFromIterable(list, "format");
+
+ // We can directly return if |stringList| contains less than two elements.
+ if (stringList.length < 2) {
+ return stringList.length === 0 ? "" : stringList[0];
+ }
+
+ // Ensure the ListFormat internals are resolved.
+ getListFormatInternals(listFormat);
+
+ // Step 5.
+ return intl_FormatList(listFormat, stringList, /* formatToParts = */ false);
+}
+
+/**
+ * Intl.ListFormat.prototype.formatToParts ( list )
+ */
+function Intl_ListFormat_formatToParts(list) {
+ // Step 1.
+ var listFormat = this;
+
+ // Steps 2-3.
+ if (!IsObject(listFormat) || (listFormat = GuardToListFormat(listFormat)) === null) {
+ return callFunction(CallListFormatMethodIfWrapped, this, list,
+ "Intl_ListFormat_formatToParts");
+ }
+
+ // Step 4.
+ var stringList = StringListFromIterable(list, "formatToParts");
+
+ // We can directly return if |stringList| contains less than two elements.
+ if (stringList.length < 2) {
+ return stringList.length === 0 ? [] : [{type: "element", value: stringList[0]}];
+ }
+
+ // Ensure the ListFormat internals are resolved.
+ getListFormatInternals(listFormat);
+
+ // Step 5.
+ return intl_FormatList(listFormat, stringList, /* formatToParts = */ true);
+}
+
+/**
+ * Returns the resolved options for a ListFormat object.
+ */
+function Intl_ListFormat_resolvedOptions() {
+ // Step 1.
+ var listFormat = this;
+
+ // Steps 2-3.
+ if (!IsObject(listFormat) || (listFormat = GuardToListFormat(listFormat)) === null) {
+ return callFunction(CallListFormatMethodIfWrapped, this,
+ "Intl_ListFormat_resolvedOptions");
+ }
+
+ var internals = getListFormatInternals(listFormat);
+
+ // Steps 4-5.
+ var result = {
+ locale: internals.locale,
+ type: internals.type,
+ style: internals.style,
+ };
+
+ // Step 6.
+ return result;
+}