/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* 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
/** *Returnsthestartindexofa"Unicodelocaleextensionsequence",whichthe *specificationdefinesas:"anysubstringofalanguagetagthatstartswith *aseparator'-'andthesingleton'u'andincludesthemaximumsequenceof *followingnon-singletonsubtagsandtheirpreceding'-'separators." * *Alternatively,thismaybedefinedas:thecomponentsofalanguagetagthat *matchthe`unicode_locale_extensions`productioninUTS35. * *Spec:ECMAScriptInternationalizationAPISpecification,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;
}
/** *ReturnstheendindexofaUnicodelocaleextensionsequence.
*/ 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;
}
/** *RemovesUnicodelocaleextensionsequencesfromthegivenlanguagetag.
*/ 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;
}
/** *ReturnsUnicodelocaleextensionsequencesfromthegivenlanguagetag.
*/ 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);
}
/** *ReturnstrueiftheinputcontainsonlyASCIIalphabeticalcharacters.
*/ 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,
};
/** *ReturnstheBCP47languagetagforthehostenvironment'scurrentlocale. * *Spec:ECMAScriptInternationalizationAPISpecification,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;
}
/** *Canonicalizesalocalelist. * *Spec:ECMAScriptInternationalizationAPISpecification,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"
);
// 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;
}
/** *ReturnsthesubsetofrequestedLocalesforwhichavailableLocaleshasa *matching(possiblyfallback)locale.Localesappearinthesameorderinthe *returnedlistasintheinputlist. * *Spec:ECMAScriptInternationalizationAPISpecification,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
);
// 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]]symbolofthe%Intl%intrinsicobject. * *Thissymbolisusedtoimplementthelegacyconstructorsemanticsfor *Intl.DateTimeFormatandIntl.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|.
/** *Settheinternalpropertiesobjectforan|internals|objectpreviously *associatedwithlazydata.
*/ 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;
}
/** *Gettheexistinginternalpropertiesoutofanon-newborn|internals|,or *nullifnonehavebeencomputed.
*/ 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;
}
/** *Gettheinternalpropertiesofknown-Intlobject|obj|.Foruseonlyby *C++codethatknowswhatit'sdoing!
*/ 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.