Function filterMatches

  • 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:

    1. 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']

    1. 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]):

    ['fr'] * ['fr-FR'] = ['fr-FR'] ['en'] * ['en-US'] = ['en-US'] ['sr'] * ['sr-Latn', 'sr-Cyrl'] = ['sr-Cyrl']

    1. variant/region range check has been added

    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 against sr-Latn.

    Parameters

    • requestedLocales: string[]
    • availableLocales: string[]
    • strategy: string

    Returns string[]