Negotiates the languages between the list of requested locales against
a list of available locales.
The algorithm is based on the BCP4647 3.3.2 Extended Filtering algorithm,
with several modifications:
available locales are treated as ranges
This change allows us to match a more specific request against
more generic available locale.
For example, if the available locale list provides locale en,
and the requested locale is en-US, we treat the available locale as
a locale that matches all possible english requests.
This means that we expect available locale ID to be as precize as
the matches they want to cover.
For example, if there is only sr available, it's ok to list
it in available locales. But once the available locales has both,
Cyrl and Latn variants, the locale IDs should be sr-Cyrl and sr-Latn
to avoid any sr-* request to match against whole sr range.
What it does ([requested] * [available] = [supported]):
['en-US'] * ['en'] = ['en']
likely subtags from LDML 4.3 Likely Subtags has been added
The most obvious likely subtag that can be computed is a duplication
of the language field onto region field (fr => fr-FR).
On top of that, likely subtags may use a list of mappings, that
allow the algorithm to handle non-obvious matches.
For example, making sure that we match en to en-US or sr to
sr-Cyrl, while sr-RU to sr-Latn-RU.
This list can be taken directly from CLDR Supplemental Data.
What it does ([requested] * [available] = [supported]):
Lastly, the last form of check is against the requested locale ID
but with the variant/region field replaced with a * range.
The rationale here laid out in LDML 4.4 Language Matching:
"(...) normally the fall-off between the user's languages is
substantially greated than regional variants."
In other words, if we can't match for the given region, maybe
we can match for the same language/script but other region, and
it will in most cases be preferred over falling back on the next
language.
What it does ([requested] * [available] = [supported]):
It works similarly to getParentLocales algo, except that we stop
after matching against variant/region ranges and don't try to match
ignoring script ranges. That means that sr-Cyrl will never match
against sr-Latn.
Negotiates the languages between the list of requested locales against a list of available locales.
The algorithm is based on the BCP4647 3.3.2 Extended Filtering algorithm, with several modifications:
This change allows us to match a more specific request against more generic available locale.
For example, if the available locale list provides locale
en
, and the requested locale isen-US
, we treat the available locale as a locale that matches all possible english requests.This means that we expect available locale ID to be as precize as the matches they want to cover.
For example, if there is only
sr
available, it's ok to list it in available locales. But once the available locales has both, Cyrl and Latn variants, the locale IDs should besr-Cyrl
andsr-Latn
to avoid anysr-*
request to match against wholesr
range.What it does ([requested] * [available] = [supported]):
['en-US'] * ['en'] = ['en']
The most obvious likely subtag that can be computed is a duplication of the language field onto region field (
fr
=>fr-FR
).On top of that, likely subtags may use a list of mappings, that allow the algorithm to handle non-obvious matches. For example, making sure that we match
en
toen-US
orsr
tosr-Cyrl
, whilesr-RU
tosr-Latn-RU
.This list can be taken directly from CLDR Supplemental Data.
What it does ([requested] * [available] = [supported]):
['fr'] * ['fr-FR'] = ['fr-FR'] ['en'] * ['en-US'] = ['en-US'] ['sr'] * ['sr-Latn', 'sr-Cyrl'] = ['sr-Cyrl']
Lastly, the last form of check is against the requested locale ID but with the variant/region field replaced with a
*
range.The rationale here laid out in LDML 4.4 Language Matching: "(...) normally the fall-off between the user's languages is substantially greated than regional variants."
In other words, if we can't match for the given region, maybe we can match for the same language/script but other region, and it will in most cases be preferred over falling back on the next language.
What it does ([requested] * [available] = [supported]):
['en-AU'] * ['en-US'] = ['en-US'] ['sr-RU'] * ['sr-Latn-RO'] = ['sr-Latn-RO'] // sr-RU -> sr-Latn-RU
It works similarly to getParentLocales algo, except that we stop after matching against variant/region ranges and don't try to match ignoring script ranges. That means that
sr-Cyrl
will never match againstsr-Latn
.