76c5f5cc8a
In the GN build, libchromiumcontent is no longer a distinct library, but merely a container for a set of scripts and patches. Maintaining those patches in a separate repository is tedious and error-prone, so merge them into the main repo. Once this is merged and GN is the default way to build Electron, the libchromiumcontent repository can be archived.
300 lines
11 KiB
Diff
300 lines
11 KiB
Diff
diff --git a/src/js/intl.js b/src/js/intl.js
|
|
index 53fbe1f947..3c7112716c 100644
|
|
--- a/src/js/intl.js
|
|
+++ b/src/js/intl.js
|
|
@@ -152,18 +152,11 @@ var AVAILABLE_LOCALES = {
|
|
*/
|
|
var DEFAULT_ICU_LOCALE = UNDEFINED;
|
|
|
|
-function GetDefaultICULocaleJS(service) {
|
|
+function GetDefaultICULocaleJS() {
|
|
if (IS_UNDEFINED(DEFAULT_ICU_LOCALE)) {
|
|
DEFAULT_ICU_LOCALE = %GetDefaultICULocale();
|
|
}
|
|
- // Check that this is a valid default for this service,
|
|
- // otherwise fall back to "und"
|
|
- // TODO(littledan,jshin): AvailableLocalesOf sometimes excludes locales
|
|
- // which don't require tailoring, but work fine with root data. Look into
|
|
- // exposing this fact in ICU or the way Chrome bundles data.
|
|
- return (IS_UNDEFINED(service) ||
|
|
- HAS_OWN_PROPERTY(getAvailableLocalesOf(service), DEFAULT_ICU_LOCALE))
|
|
- ? DEFAULT_ICU_LOCALE : "und";
|
|
+ return DEFAULT_ICU_LOCALE;
|
|
}
|
|
|
|
/**
|
|
@@ -434,6 +427,48 @@ function resolveLocale(service, requestedLocales, options) {
|
|
}
|
|
|
|
|
|
+/**
|
|
+ * Look up the longest non-empty prefix of |locale| that is an element of
|
|
+ * |availableLocales|. Returns undefined when the |locale| is completely
|
|
+ * unsupported by |availableLocales|.
|
|
+ */
|
|
+function bestAvailableLocale(availableLocales, locale) {
|
|
+ do {
|
|
+ if (!IS_UNDEFINED(availableLocales[locale])) {
|
|
+ return locale;
|
|
+ }
|
|
+ // Truncate locale if possible.
|
|
+ var pos = %StringLastIndexOf(locale, '-');
|
|
+ if (pos === -1) {
|
|
+ break;
|
|
+ }
|
|
+ locale = %_Call(StringSubstring, locale, 0, pos);
|
|
+ } while (true);
|
|
+
|
|
+ return UNDEFINED;
|
|
+}
|
|
+
|
|
+
|
|
+/**
|
|
+ * Try to match any mutation of |requestedLocale| against |availableLocales|.
|
|
+ */
|
|
+function attemptSingleLookup(availableLocales, requestedLocale) {
|
|
+ // Remove all extensions.
|
|
+ var noExtensionsLocale = %RegExpInternalReplace(
|
|
+ GetAnyExtensionRE(), requestedLocale, '');
|
|
+ var availableLocale = bestAvailableLocale(
|
|
+ availableLocales, requestedLocale);
|
|
+ if (!IS_UNDEFINED(availableLocale)) {
|
|
+ // Return the resolved locale and extension.
|
|
+ var extensionMatch = %regexp_internal_match(
|
|
+ GetUnicodeExtensionRE(), requestedLocale);
|
|
+ var extension = IS_NULL(extensionMatch) ? '' : extensionMatch[0];
|
|
+ return {locale: availableLocale, extension: extension};
|
|
+ }
|
|
+ return UNDEFINED;
|
|
+}
|
|
+
|
|
+
|
|
/**
|
|
* Returns best matched supported locale and extension info using basic
|
|
* lookup algorithm.
|
|
@@ -446,31 +481,25 @@ function lookupMatcher(service, requestedLocales) {
|
|
var availableLocales = getAvailableLocalesOf(service);
|
|
|
|
for (var i = 0; i < requestedLocales.length; ++i) {
|
|
- // Remove all extensions.
|
|
- var locale = %RegExpInternalReplace(
|
|
- GetAnyExtensionRE(), requestedLocales[i], '');
|
|
- do {
|
|
- if (!IS_UNDEFINED(availableLocales[locale])) {
|
|
- // Return the resolved locale and extension.
|
|
- var extensionMatch = %regexp_internal_match(
|
|
- GetUnicodeExtensionRE(), requestedLocales[i]);
|
|
- var extension = IS_NULL(extensionMatch) ? '' : extensionMatch[0];
|
|
- return {locale: locale, extension: extension, position: i};
|
|
- }
|
|
- // Truncate locale if possible.
|
|
- var pos = %StringLastIndexOf(locale, '-');
|
|
- if (pos === -1) {
|
|
- break;
|
|
- }
|
|
- locale = %_Call(StringSubstring, locale, 0, pos);
|
|
- } while (true);
|
|
+ var result = attemptSingleLookup(availableLocales, requestedLocales[i]);
|
|
+ if (!IS_UNDEFINED(result)) {
|
|
+ return result;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ var defLocale = GetDefaultICULocaleJS();
|
|
+
|
|
+ // While ECMA-402 returns defLocale directly, we have to check if it is
|
|
+ // supported, as such support is not guaranteed.
|
|
+ var result = attemptSingleLookup(availableLocales, defLocale);
|
|
+ if (!IS_UNDEFINED(result)) {
|
|
+ return result;
|
|
}
|
|
|
|
// Didn't find a match, return default.
|
|
return {
|
|
- locale: GetDefaultICULocaleJS(service),
|
|
- extension: '',
|
|
- position: -1
|
|
+ locale: 'und',
|
|
+ extension: ''
|
|
};
|
|
}
|
|
|
|
diff --git a/test/intl/assert.js b/test/intl/assert.js
|
|
index d8cc85849f..c11e7c0bbf 100644
|
|
--- a/test/intl/assert.js
|
|
+++ b/test/intl/assert.js
|
|
@@ -132,6 +132,16 @@ function assertFalse(value, user_message = '') {
|
|
}
|
|
|
|
|
|
+/**
|
|
+ * Throws if value is null.
|
|
+ */
|
|
+function assertNotNull(value, user_message = '') {
|
|
+ if (value === null) {
|
|
+ fail("not null", value, user_message);
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
/**
|
|
* Runs code() and asserts that it throws the specified exception.
|
|
*/
|
|
@@ -189,3 +199,34 @@ function assertInstanceof(obj, type) {
|
|
(actualTypeName ? ' but of < ' + actualTypeName + '>' : ''));
|
|
}
|
|
}
|
|
+
|
|
+
|
|
+/**
|
|
+ * Split a BCP 47 language tag into locale and extension.
|
|
+ */
|
|
+function splitLanguageTag(tag) {
|
|
+ var extRe = /(-[0-9A-Za-z](-[0-9A-Za-z]{2,8})+)+$/;
|
|
+ var match = %regexp_internal_match(extRe, tag);
|
|
+ if (match) {
|
|
+ return { locale: tag.slice(0, match.index), extension: match[0] };
|
|
+ }
|
|
+
|
|
+ return { locale: tag, extension: '' };
|
|
+}
|
|
+
|
|
+
|
|
+/**
|
|
+ * Throw if |parent| is not a more general language tag of |child|, nor |child|
|
|
+ * itself, per BCP 47 rules.
|
|
+ */
|
|
+function assertLanguageTag(child, parent) {
|
|
+ var childSplit = splitLanguageTag(child);
|
|
+ var parentSplit = splitLanguageTag(parent);
|
|
+
|
|
+ // Do not compare extensions at this moment, as %GetDefaultICULocale()
|
|
+ // doesn't always output something we support.
|
|
+ if (childSplit.locale !== parentSplit.locale &&
|
|
+ !childSplit.locale.startsWith(parentSplit.locale + '-')) {
|
|
+ fail(child, parent, 'language tag comparison');
|
|
+ }
|
|
+}
|
|
diff --git a/test/intl/break-iterator/default-locale.js b/test/intl/break-iterator/default-locale.js
|
|
index d8d5aeadb2..e1a42a100a 100644
|
|
--- a/test/intl/break-iterator/default-locale.js
|
|
+++ b/test/intl/break-iterator/default-locale.js
|
|
@@ -37,8 +37,8 @@ assertFalse(options.locale === 'und');
|
|
assertFalse(options.locale === '');
|
|
assertFalse(options.locale === undefined);
|
|
|
|
-// Then check for equality.
|
|
-assertEquals(options.locale, %GetDefaultICULocale());
|
|
+// Then check for legitimacy.
|
|
+assertLanguageTag(%GetDefaultICULocale(), options.locale);
|
|
|
|
var iteratorNone = new Intl.v8BreakIterator();
|
|
assertEquals(options.locale, iteratorNone.resolvedOptions().locale);
|
|
diff --git a/test/intl/break-iterator/wellformed-unsupported-locale.js b/test/intl/break-iterator/wellformed-unsupported-locale.js
|
|
index 5ac8fbcd41..ffa44aef08 100644
|
|
--- a/test/intl/break-iterator/wellformed-unsupported-locale.js
|
|
+++ b/test/intl/break-iterator/wellformed-unsupported-locale.js
|
|
@@ -29,4 +29,4 @@
|
|
|
|
var iterator = Intl.v8BreakIterator(['xx']);
|
|
|
|
-assertEquals(iterator.resolvedOptions().locale, %GetDefaultICULocale());
|
|
+assertLanguageTag(%GetDefaultICULocale(), iterator.resolvedOptions().locale);
|
|
diff --git a/test/intl/collator/default-locale.js b/test/intl/collator/default-locale.js
|
|
index db9b1e7330..5fc6ff4665 100644
|
|
--- a/test/intl/collator/default-locale.js
|
|
+++ b/test/intl/collator/default-locale.js
|
|
@@ -37,8 +37,8 @@ assertFalse(options.locale === 'und');
|
|
assertFalse(options.locale === '');
|
|
assertFalse(options.locale === undefined);
|
|
|
|
-// Then check for equality.
|
|
-assertEquals(options.locale, %GetDefaultICULocale());
|
|
+// Then check for legitimacy.
|
|
+assertLanguageTag(%GetDefaultICULocale(), options.locale);
|
|
|
|
var collatorNone = new Intl.Collator();
|
|
assertEquals(options.locale, collatorNone.resolvedOptions().locale);
|
|
@@ -48,5 +48,8 @@ var collatorBraket = new Intl.Collator({});
|
|
assertEquals(options.locale, collatorBraket.resolvedOptions().locale);
|
|
|
|
var collatorWithOptions = new Intl.Collator(undefined, {usage: 'search'});
|
|
-assertEquals(%GetDefaultICULocale() + '-u-co-search',
|
|
- collatorWithOptions.resolvedOptions().locale);
|
|
+assertLanguageTag(%GetDefaultICULocale(),
|
|
+ collatorWithOptions.resolvedOptions().locale);
|
|
+assertNotNull(
|
|
+ %regexp_internal_match(/-u(-[a-zA-Z]+-[a-zA-Z]+)*-co-search/,
|
|
+ collatorWithOptions.resolvedOptions().locale));
|
|
diff --git a/test/intl/collator/wellformed-unsupported-locale.js b/test/intl/collator/wellformed-unsupported-locale.js
|
|
index 3963d47a61..ad89e3e220 100644
|
|
--- a/test/intl/collator/wellformed-unsupported-locale.js
|
|
+++ b/test/intl/collator/wellformed-unsupported-locale.js
|
|
@@ -29,4 +29,4 @@
|
|
|
|
var collator = Intl.Collator(['xx']);
|
|
|
|
-assertEquals(collator.resolvedOptions().locale, %GetDefaultICULocale());
|
|
+assertLanguageTag(%GetDefaultICULocale(), collator.resolvedOptions().locale);
|
|
diff --git a/test/intl/date-format/default-locale.js b/test/intl/date-format/default-locale.js
|
|
index 8e9b7fcec3..2d79e895b5 100644
|
|
--- a/test/intl/date-format/default-locale.js
|
|
+++ b/test/intl/date-format/default-locale.js
|
|
@@ -37,8 +37,8 @@ assertFalse(options.locale === 'und');
|
|
assertFalse(options.locale === '');
|
|
assertFalse(options.locale === undefined);
|
|
|
|
-// Then check for equality.
|
|
-assertEquals(options.locale, %GetDefaultICULocale());
|
|
+// Then check for legitimacy.
|
|
+assertLanguageTag(%GetDefaultICULocale(), options.locale);
|
|
|
|
var dtfNone = new Intl.DateTimeFormat();
|
|
assertEquals(options.locale, dtfNone.resolvedOptions().locale);
|
|
diff --git a/test/intl/date-format/wellformed-unsupported-locale.js b/test/intl/date-format/wellformed-unsupported-locale.js
|
|
index 6f063abbd1..b812164832 100644
|
|
--- a/test/intl/date-format/wellformed-unsupported-locale.js
|
|
+++ b/test/intl/date-format/wellformed-unsupported-locale.js
|
|
@@ -29,4 +29,4 @@
|
|
|
|
var dtf = Intl.DateTimeFormat(['xx']);
|
|
|
|
-assertEquals(dtf.resolvedOptions().locale, %GetDefaultICULocale());
|
|
+assertLanguageTag(%GetDefaultICULocale(), dtf.resolvedOptions().locale);
|
|
diff --git a/test/intl/number-format/default-locale.js b/test/intl/number-format/default-locale.js
|
|
index cd67ba724f..a24aec2333 100644
|
|
--- a/test/intl/number-format/default-locale.js
|
|
+++ b/test/intl/number-format/default-locale.js
|
|
@@ -37,8 +37,8 @@ assertFalse(options.locale === 'und');
|
|
assertFalse(options.locale === '');
|
|
assertFalse(options.locale === undefined);
|
|
|
|
-// Then check for equality.
|
|
-assertEquals(options.locale, %GetDefaultICULocale());
|
|
+// Then check for legitimacy.
|
|
+assertLanguageTag(%GetDefaultICULocale(), options.locale);
|
|
|
|
var nfNone = new Intl.NumberFormat();
|
|
assertEquals(options.locale, nfNone.resolvedOptions().locale);
|
|
diff --git a/test/intl/number-format/wellformed-unsupported-locale.js b/test/intl/number-format/wellformed-unsupported-locale.js
|
|
index 195eba4c19..c51753928e 100644
|
|
--- a/test/intl/number-format/wellformed-unsupported-locale.js
|
|
+++ b/test/intl/number-format/wellformed-unsupported-locale.js
|
|
@@ -29,4 +29,4 @@
|
|
|
|
var nf = Intl.NumberFormat(['xx']);
|
|
|
|
-assertEquals(nf.resolvedOptions().locale, %GetDefaultICULocale());
|
|
+assertLanguageTag(%GetDefaultICULocale(), nf.resolvedOptions().locale);
|
|
diff --git a/test/mjsunit/regress/regress-6288.js b/test/mjsunit/regress/regress-6288.js
|
|
index 337af54c1a..5f550c31c8 100644
|
|
--- a/test/mjsunit/regress/regress-6288.js
|
|
+++ b/test/mjsunit/regress/regress-6288.js
|
|
@@ -8,6 +8,6 @@
|
|
// DateTimeFormat but not Collation
|
|
|
|
if (this.Intl) {
|
|
- assertEquals('und', Intl.Collator().resolvedOptions().locale);
|
|
+ assertEquals('pt', Intl.Collator().resolvedOptions().locale);
|
|
assertEquals('pt-BR', Intl.DateTimeFormat().resolvedOptions().locale);
|
|
}
|