/* 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/. */
#ifdef DEBUG
#define JS_CONCAT2(x, y) x##y
#define JS_CONCAT(x, y) JS_CONCAT2(x, y)
#define assertIsValidAndCanonicalLanguageTag(locale, desc) \ do { \ var JS_CONCAT(canonical, __LINE__) = intl_TryValidateAndCanonicalizeLanguageTag(locale); \ assert(JS_CONCAT(canonical, __LINE__) !== null, \
`${desc} is a structurally valid language tag`); \ assert(JS_CONCAT(canonical, __LINE__) === locale, \
`${desc} is a canonicalized language tag`); \
} while (false)
#else
#define assertIsValidAndCanonicalLanguageTag(locale, desc) ; // Elided assertion.
#endif
/** * Returns the start index of a "Unicode locale extension sequence", which the * specification defines as: "any substring of a language tag that starts with * a separator '-' and the singleton 'u' and includes the maximum sequence of * following non-singleton subtags and their preceding '-' separators." * * Alternatively, this may be defined as: the components of a language tag that * match the `unicode_locale_extensions` production in UTS 35. * * Spec: ECMAScript Internationalization API Specification, 6.2.1.
*/ function startOfUnicodeExtensions(locale) { assert(typeof locale === "string", "locale is a string");
// Search for "-u-" marking the start of a Unicode extension sequence. var start = callFunction(std_String_indexOf, locale, "-u-"); if (start < 0) { return -1;
}
// And search for "-x-" marking the start of any privateuse component to // handle the case when "-u-" was only found within a privateuse subtag. var privateExt = callFunction(std_String_indexOf, locale, "-x-"); if (privateExt >= 0 && privateExt < start) { return -1;
}
return start;
}
/** * Returns the end index of a Unicode locale extension sequence.
*/ function endOfUnicodeExtensions(locale, start) { assert(typeof locale === "string", "locale is a string"); assert(0 <= start && start < locale.length, "start is an index into locale"); assert(
Substring(locale, start, 3) === "-u-", "start points to Unicode extension sequence"
);
// Search for the start of the next singleton or privateuse subtag. // // Begin searching after the smallest possible Unicode locale extension // sequence, namely |"-u-" 2alphanum|. End searching once the remaining // characters can't fit the smallest possible singleton or privateuse // subtag, namely |"-x-" alphanum|. Note the reduced end-limit means // indexing inside the loop is always in-range. for (var i = start + 5, end = locale.length - 4; i <= end; i++) { if (locale[i] !== "-") { continue;
} if (locale[i + 2] === "-") { return i;
}
// Skip over (i + 1) and (i + 2) because we've just verified they // aren't "-", so the next possible delimiter can only be at (i + 3).
i += 2;
}
// If no singleton or privateuse subtag was found, the Unicode extension // sequence extends until the end of the string. return locale.length;
}
/** * Removes Unicode locale extension sequences from the given language tag.
*/ function removeUnicodeExtensions(locale) {
assertIsValidAndCanonicalLanguageTag(
locale, "locale with possible Unicode extension"
);
var start = startOfUnicodeExtensions(locale); if (start < 0) { return locale;
}
var end = endOfUnicodeExtensions(locale, start);
var left = Substring(locale, 0, start); var right = Substring(locale, end, locale.length - end); var combined = left + right;
assertIsValidAndCanonicalLanguageTag(combined, "the recombined locale"); assert(
startOfUnicodeExtensions(combined) < 0, "recombination failed to remove all Unicode locale extension sequences"
);
return combined;
}
/** * Returns Unicode locale extension sequences from the given language tag.
*/ function getUnicodeExtensions(locale) {
assertIsValidAndCanonicalLanguageTag(locale, "locale with Unicode extension");
var start = startOfUnicodeExtensions(locale); assert(start >= 0, "start of Unicode extension sequence not found"); var end = endOfUnicodeExtensions(locale, start);
return Substring(locale, start, end - start);
}
/** * Returns true if the input contains only ASCII alphabetical characters.
*/ function IsASCIIAlphaString(s) { assert(typeof s === "string", "IsASCIIAlphaString");
for (var i = 0; i < s.length; i++) { var c = callFunction(std_String_charCodeAt, s, i); if (!((0x41 <= c && c <= 0x5a) || (0x61 <= c && c <= 0x7a))) { returnfalse;
}
} returntrue;
}
var localeCache = {
runtimeDefaultLocale: undefined,
defaultLocale: undefined,
};
/** * Returns the BCP 47 language tag for the host environment's current locale. * * Spec: ECMAScript Internationalization API Specification, 6.2.4.
*/ function DefaultLocale() { if (intl_IsRuntimeDefaultLocale(localeCache.runtimeDefaultLocale)) { return localeCache.defaultLocale;
}
// If we didn't have a cache hit, compute the candidate default locale. var runtimeDefaultLocale = intl_RuntimeDefaultLocale(); var locale = intl_supportedLocaleOrFallback(runtimeDefaultLocale);
assertIsValidAndCanonicalLanguageTag(locale, "the computed default locale"); assert(
startOfUnicodeExtensions(locale) < 0, "the computed default locale must not contain a Unicode extension sequence"
);
// Cache the computed locale until the runtime default locale changes.
localeCache.defaultLocale = locale;
localeCache.runtimeDefaultLocale = runtimeDefaultLocale;
return locale;
}
/** * Canonicalizes a locale list. * * Spec: ECMAScript Internationalization API Specification, 9.2.1.
*/ function CanonicalizeLocaleList(locales) { // Step 1. if (locales === undefined) { return [];
}
// Step 3 (and the remaining steps). var tag = intl_ValidateAndCanonicalizeLanguageTag(locales, false); if (tag !== null) { assert( typeof tag === "string", "intl_ValidateAndCanonicalizeLanguageTag returns a string value"
); return [tag];
}
// Step 2. var seen = [];
// Step 4. var O = ToObject(locales);
// Step 5. var len = ToLength(O.length);
// Step 6. var k = 0;
// Step 7. while (k < len) { // Steps 7.a-c. if (k in O) { // Step 7.c.i. var kValue = O[k];
// Steps 7.c.iii-iv. var tag = intl_ValidateAndCanonicalizeLanguageTag(kValue, true); assert( typeof tag === "string", "ValidateAndCanonicalizeLanguageTag returns a string value"
);
/** * Compares a BCP 47 language tag against the locales in availableLocales * and returns the best available match. Uses the fallback * mechanism of RFC 4647, section 3.4. * * Spec: ECMAScript Internationalization API Specification, 9.2.2. * Spec: RFC 4647, section 3.4.
*/ function BestAvailableLocale(availableLocales, locale) { return intl_BestAvailableLocale(availableLocales, locale, DefaultLocale());
}
/** * Identical to BestAvailableLocale, but does not consider the default locale * during computation.
*/ function BestAvailableLocaleIgnoringDefault(availableLocales, locale) { return intl_BestAvailableLocale(availableLocales, locale, null);
}
/** * Compares a BCP 47 language priority list against the set of locales in * availableLocales and determines the best available language to meet the * request. Options specified through Unicode extension subsequences are * ignored in the lookup, but information about such subsequences is returned * separately. * * This variant is based on the Lookup algorithm of RFC 4647 section 3.4. * * Spec: ECMAScript Internationalization API Specification, 9.2.3. * Spec: RFC 4647, section 3.4.
*/ function LookupMatcher(availableLocales, requestedLocales) { // Step 1. var result = new_Record();
// Step 2. for (var i = 0; i < requestedLocales.length; i++) { var locale = requestedLocales[i];
// Step 2.a. var noExtensionsLocale = removeUnicodeExtensions(locale);
// Step 2.b. var availableLocale = BestAvailableLocale(
availableLocales,
noExtensionsLocale
);
/** * Compares a BCP 47 language priority list against the set of locales in * availableLocales and determines the best available language to meet the * request. Options specified through Unicode extension subsequences are * ignored in the lookup, but information about such subsequences is returned * separately. * * Spec: ECMAScript Internationalization API Specification, 9.2.4.
*/ function BestFitMatcher(availableLocales, requestedLocales) { // this implementation doesn't have anything better return LookupMatcher(availableLocales, requestedLocales);
}
/** * Returns the Unicode extension value subtags for the requested key subtag. * * Spec: ECMAScript Internationalization API Specification, 9.2.5.
*/ function UnicodeExtensionValue(extension, key) { assert(typeof extension === "string", "extension is a string value"); assert(
callFunction(std_String_startsWith, extension, "-u-") &&
getUnicodeExtensions("und" + extension) === extension, "extension is a Unicode extension subtag"
); assert(typeof key === "string", "key is a string value");
// Step 1. assert(key.length === 2, "key is a Unicode extension key subtag");
// Step 2. var size = extension.length;
// Step 3. var searchValue = "-" + key + "-";
// Step 4. var pos = callFunction(std_String_indexOf, extension, searchValue);
// Step 5. if (pos !== -1) { // Step 5.a. var start = pos + 4;
// Step 5.b. var end = start;
// Step 5.c. var k = start;
// Steps 5.d-e. while (true) { // Step 5.e.i. var e = callFunction(std_String_indexOf, extension, "-", k);
// Step 5.e.ii. var len = e === -1 ? size - k : e - k;
// Step 5.e.iii. if (len === 2) { break;
}
// Step 5.e.iv. if (e === -1) {
end = size; break;
}
// Steps 7-8. if (callFunction(std_String_endsWith, extension, searchValue)) { return"";
}
// Step 9 (implicit).
}
/** * Compares a BCP 47 language priority list against availableLocales and * determines the best available language to meet the request. Options specified * through Unicode extension subsequences are negotiated separately, taking the * caller's relevant extensions and locale data as well as client-provided * options into consideration. * * Spec: ECMAScript Internationalization API Specification, 9.2.6.
*/ function ResolveLocale(
availableLocales,
requestedLocales,
options,
relevantExtensionKeys,
localeData
) { // Steps 1-3. var matcher = options.localeMatcher; var r =
matcher === "lookup"
? LookupMatcher(availableLocales, requestedLocales)
: BestFitMatcher(availableLocales, requestedLocales);
// Step 4. var foundLocale = r.locale; var extension = r.extension;
// Step 5. var result = new_Record();
// Step 6.
result.dataLocale = foundLocale;
// Step 7. var supportedExtension = "-u";
// In this implementation, localeData is a function, not an object. var localeDataProvider = localeData();
// Step 8. for (var i = 0; i < relevantExtensionKeys.length; i++) { var key = relevantExtensionKeys[i];
// Steps 8.a-h (The locale data is only computed when needed). var keyLocaleData = undefined; var value = undefined;
// Locale tag may override.
// Step 8.g. var supportedExtensionAddition = "";
// Step 8.h. if (extension !== undefined) { // Step 8.h.i. var requestedValue = UnicodeExtensionValue(extension, key);
// According to the LDML spec, if there's no type value, // and true is an allowed value, it's used. if (callFunction(std_Array_indexOf, keyLocaleData, "true") !== -1) {
value = "true";
supportedExtensionAddition = "-" + key;
}
}
}
}
// Steps 9.d-e (Step 9.e is not required in this implementation, because we don't canonicalize // Unicode extension subtags).
assertIsValidAndCanonicalLanguageTag(locale, "locale after concatenation");
return locale;
}
/** * Returns the subset of requestedLocales for which availableLocales has a * matching (possibly fallback) locale. Locales appear in the same order in the * returned list as in the input list. * * Spec: ECMAScript Internationalization API Specification, 9.2.7.
*/ function LookupSupportedLocales(availableLocales, requestedLocales) { // Step 1. var subset = [];
// Step 2. for (var i = 0; i < requestedLocales.length; i++) { var locale = requestedLocales[i];
// Step 2.a. var noExtensionsLocale = removeUnicodeExtensions(locale);
// Step 2.b. var availableLocale = BestAvailableLocale(
availableLocales,
noExtensionsLocale
);
/** * Returns the subset of requestedLocales for which availableLocales has a * matching (possibly fallback) locale. Locales appear in the same order in the * returned list as in the input list. * * Spec: ECMAScript Internationalization API Specification, 9.2.8.
*/ function BestFitSupportedLocales(availableLocales, requestedLocales) { // don't have anything better return LookupSupportedLocales(availableLocales, requestedLocales);
}
/** * Returns the subset of requestedLocales for which availableLocales has a * matching (possibly fallback) locale. Locales appear in the same order in the * returned list as in the input list. * * Spec: ECMAScript Internationalization API Specification, 9.2.9.
*/ function SupportedLocales(availableLocales, requestedLocales, options) { // Step 1. var matcher; if (options !== undefined) { // Step 1.a.
options = ToObject(options);
/** * Extracts a property value from the provided options object, converts it to * the required type, checks whether it is one of a list of allowed values, * and fills in a fallback value if necessary. * * Spec: ECMAScript Internationalization API Specification, 9.2.10.
*/ function GetOption(options, property, type, values, fallback) { // Step 1. var value = options[property];
// Step 2. if (value !== undefined) { // Steps 2.a-c. if (type === "boolean") {
value = ToBoolean(value);
} elseif (type === "string") {
value = ToString(value);
} else { assert(false, "GetOption");
}
/** * Extracts a property value from the provided options object, converts it to * a boolean or string, checks whether it is one of a list of allowed values, * and fills in a fallback value if necessary.
*/ function GetStringOrBooleanOption(
options,
property,
stringValues,
fallback
) { assert(IsObject(stringValues), "GetStringOrBooleanOption");
// Step 3. if (Number_isNaN(value) || value < minimum || value > maximum) {
ThrowRangeError(JSMSG_INVALID_DIGITS_VALUE, value);
}
// Step 4. // Apply bitwise-or to convert -0 to +0 per ES2017, 5.2 and to ensure the // result is an int32 value. return std_Math_floor(value) | 0;
}
/** * Extracts a property value from the provided options object, converts it to a * Number value, checks whether it is in the allowed range, and fills in a * fallback value if necessary. * * Spec: ECMAScript Internationalization API Specification, 9.2.12.
*/ function GetNumberOption(options, property, minimum, maximum, fallback) { // Steps 1-2. return DefaultNumberOption(options[property], minimum, maximum, fallback);
}
// Symbols in the self-hosting compartment can't be cloned, use a separate // object to hold the actual symbol value. // TODO: Can we add support to clone symbols? var intlFallbackSymbolHolder = { value: undefined };
/** * The [[FallbackSymbol]] symbol of the %Intl% intrinsic object. * * This symbol is used to implement the legacy constructor semantics for * Intl.DateTimeFormat and Intl.NumberFormat.
*/ function intlFallbackSymbol() { var fallbackSymbol = intlFallbackSymbolHolder.value; if (!fallbackSymbol) { var Symbol = GetBuiltinConstructor("Symbol");
fallbackSymbol = Symbol("IntlLegacyConstructedSymbol");
intlFallbackSymbolHolder.value = fallbackSymbol;
} return fallbackSymbol;
}
// The meaning of an internals object for an object |obj| is as follows. // // The .type property indicates the type of Intl object that |obj| is. It // must be one of: // - Collator // - DateTimeFormat // - DisplayNames // - DurationFormat // - ListFormat // - NumberFormat // - PluralRules // - RelativeTimeFormat // - Segmenter // // The .lazyData property stores information needed to compute -- without // observable side effects -- the actual internal Intl properties of // |obj|. If it is non-null, then the actual internal properties haven't // been computed, and .lazyData must be processed by // |setInternalProperties| before internal Intl property values are // available. If it is null, then the .internalProps property contains an // object whose properties are the internal Intl properties of |obj|.
/** * Set the internal properties object for an |internals| object previously * associated with lazy data.
*/ function setInternalProperties(internals, internalProps) { assert(IsObject(internals.lazyData), "lazy data must exist already"); assert(IsObject(internalProps), "internalProps argument should be an object");
// Set in reverse order so that the .lazyData nulling is a barrier.
internals.internalProps = internalProps;
internals.lazyData = null;
}
/** * Get the existing internal properties out of a non-newborn |internals|, or * null if none have been computed.
*/ function maybeInternalProperties(internals) { assert(IsObject(internals), "non-object passed to maybeInternalProperties"); var lazyData = internals.lazyData; if (lazyData) { returnnull;
} assert(
IsObject(internals.internalProps), "missing lazy data and computed internals"
); return internals.internalProps;
}
/** * Return |obj|'s internals object (*not* the object holding its internal * properties!), with structure specified above. * * Spec: ECMAScript Internationalization API Specification, 10.3. * Spec: ECMAScript Internationalization API Specification, 11.3. * Spec: ECMAScript Internationalization API Specification, 12.3.
*/ function getIntlObjectInternals(obj) { assert(IsObject(obj), "getIntlObjectInternals called with non-Object"); assert(
intl_GuardToCollator(obj) !== null ||
intl_GuardToDateTimeFormat(obj) !== null ||
intl_GuardToDisplayNames(obj) !== null ||
intl_GuardToDurationFormat(obj) !== null ||
intl_GuardToListFormat(obj) !== null ||
intl_GuardToNumberFormat(obj) !== null ||
intl_GuardToPluralRules(obj) !== null ||
intl_GuardToRelativeTimeFormat(obj) !== null ||
intl_GuardToSegmenter(obj) !== null, "getIntlObjectInternals called with non-Intl object"
);
var internals = UnsafeGetReservedSlot(obj, INTL_INTERNALS_OBJECT_SLOT);
/** * Get the internal properties of known-Intl object |obj|. For use only by * C++ code that knows what it's doing!
*/ function getInternals(obj) { var internals = getIntlObjectInternals(obj);
// If internal properties have already been computed, use them. var internalProps = maybeInternalProperties(internals); if (internalProps) { return internalProps;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.