If I'm reading (and implementing) BestAvailableLocale() correctly, there seems to be an off-by-one error with regard to step 2(d): "pos-1" should be "pos".
This is the code I'm using, and it's chopping too much off the end of the candidate:
BestAvailableLocale: function(availableLocales, locale) {
if (!this.IsStructurallyValidLanguageTag(locale)) {
return undefined;
}
let candidate = this.CanonicalizeLanguageTag(locale);
while (candidate.length > 0) {
if (availableLocales.indexOf(candidate) !== -1) {
return candidate;
}
let pos = candidate.lastIndexOf('-');
if (pos === -1) {
return undefined;
}
if (pos >= 2 && candidate[pos - 2] === '-' ) {
pos -= 2;
}
candidate = candidate.substring(0, pos - 1);
}
},
Am I missing something? Or is the spec wrong?
In a call to substring, it has to be just pos. Where the spec said "substring of candidate from position 0 to position pos-1", it meant to include the characters in both positions.
To make things clearer, I changed the spec to say "position 0, inclusive, to position pos, exclusive".