It looks like the existing implementation of this feature was pretty
well thought out and correct, the problem was that a compareArray
function was used which was comparing arrays in a rather bizzare
fashion that was not in line with what a "normal person" would expect.
So now the array comparator is correct, and the logic works properly.
The logic works as follows -- the next locale is picked and tried as-is.
If that fails, the code normally tries to chop the last bit (normally
the country designation) and try again. However, if the next array
element has the same or longer prefix as the one to be tried, the
iteration continues. So for example if the array has the sequence
"AA-BB", "AA-CC", "XX-YY"
then first "AA-BB" is tried, then a naive solution would try "AA", but
this one instead checks to see that "AA-CC" is actually more concrete
than "AA", so it tries "AA-CC" next, and only after it fails (if it
fails) it tries "AA", because "XX-YY" does not have "AA" as prefix. So
in the end the following locales are tried in this order (assuming all
fail so the next one is tried):
"AA-BB", "AA-CC", "AA", "XX-YY", "XX"
Fixes #4780
import isArray from '../utils/is-array';
import isUndefined from '../utils/is-undefined';
-import compareArrays from '../utils/compare-arrays';
import { deprecateSimple } from '../utils/deprecate';
import { mergeConfigs } from './set';
import { Locale } from './constructor';
var localeFamilies = {};
var globalLocale;
+function commonPrefix(arr1, arr2) {
+ var i, minl = Math.min(arr1.length, arr2.length);
+ for (i = 0; i < minl; i += 1) {
+ if (arr1[i] !== arr2[i]) {
+ return i;
+ }
+ }
+ return minl;
+}
+
function normalizeLocale(key) {
return key ? key.toLowerCase().replace('_', '-') : key;
}
if (locale) {
return locale;
}
- if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
+ if (next && next.length >= j && commonPrefix(split, next) >= j - 1) {
//the next array item is better than a shallower substring of this one
break;
}