Closed hanguokai closed 3 years ago
I don't think DisplayNames
should be involved in sorting. Alphabetical sorting should be covered by a separate API and include things like groupings (a..c, d...f, etc.).
Currently, for the same code, MS Edge output Example 1, and Google Chrome output Example 2. Why is the output inconsistent by different browser?
I assume one sorts by display name, and another by locale identifier? I'm not sure, but that's in browser UI, and browser UIs often don't use ECMA-402 APIs.
I don't know what is "browser UI" you said.
let languageNames = new Intl.DisplayNames([], {type: 'language', style: 'short'});
console.log(languageNames.of('en-US'));
On Edge, output is English (United States)
.
On Chrome, output is US English
If the output is not uniform, how to sort it?
If the output is not uniform, how to sort it?
I think sorting is not objectively decided here. The application author may want to sort by codes, or by display names. Sorting is handled by Intl.Collator
. I don't think ICU/CLDR or any other intl API provides unified sorting for the locales. This may be even more complex in cases where you may want to have a nested with regions (CA, US, GB) for a single language (en), or locales (en-CA, fr-CA) for a single region (CA).
On Chrome
let languageNames = new Intl.DisplayNames([], {type: 'language', style: 'short'});
let langs = ['en-US', 'en-IN', 'fr-CA', 'fr-FR'];
let names = langs.map(l => languageNames.of(l)); // names is ["US English", "English (India)", "Canadian French", "French (France)"]
names.sort((a,b) => a.localeCompare(b)); // names is ["Canadian French", "English (India)", "French (France)", "US English"]
On Edge
let languageNames = new Intl.DisplayNames([], {type: 'language', style: 'short'});
let langs = ['en-US', 'en-IN', 'fr-CA', 'fr-FR'];
let names = langs.map(l => languageNames.of(l)); // name is ["English (United States)", "English (India)", "French (Canada)", "French (France)"]
names.sort((a,b) => a.localeCompare(b)); // name is ["English (India)", "English (United States)", "French (Canada)", "French (France)"]
Above is my use case. You can imagine a long list of languages. Note, I do not specify locales parameter in the constructor of Intl.DisplayNames. And I use string.localeCompare()
to sort display names. Therefore, I don't know the user's current language, but I hope this code can display the best results for users with various languages. The user will be satisfied with the output of Edge, but the output of Chrome is very confusing.
This is my original intention to create this issue.
And I use string.localeCompare() to sort display names.
This is your choice. You might instead use localeCompare
to compare locale codes. It's up to the user to decide. There's no universal sorting for that.
If I first sort by locales, then get their display names. On Chrome, the result is ["English (India)", "US English", "Canadian French", "French (France)"]
. This is also imperfect.
If there is a long list of languages, how can you quickly find out what you want?
There's no universal sorting for that.
Hope there will be a perfect solution in the future.
If there is a long list of languages, how can you quickly find out what you want?
Language pickers are notoriously hard to build. The recommendation is to always include a search box that filters for matching locale code, language name both in English and in local language.
Sorting is similarly complicated, as the list gets long. Often clustering and nesting per continent, country or language helps. But searchbox for filtering is the most common solution to navigation.
As I understand, it seems not an order issue, but an issue of:
What is short style (or narrow style) mean? It seems diff vendors give a very different style. But people may expect a more stable and consistent output format. Especially consider the common use cases of listing of languages, "Languages (Region)" format is much friendly for fast reading and selecting. So, could we specify short style or narrow style should follow this specific format ? Or could we add a new style (don't know what the style name could be, "human-friendly" ? ) for that?
People should never expect consistent output out of intl APIs. Not just between vendors but between versions, platforms, and user customizations, the output may be different.
I believe what this issue asked is the same as #13 Close it and consider it as a dup.
Thank you @FrankYFTang .
If I understand correctly , now the spec support new Intl.DisplayNames("en", {type: "language", dialectHandling: "standardName"})
to force format output like example 1 in the issue which @hanguokai raised. Am I correct?
Thank you @FrankYFTang .
If I understand correctly , now the spec support
new Intl.DisplayNames("en", {type: "language", dialectHandling: "standardName"})
to force format output like example 1 in the issue which @hanguokai raised. Am I correct?
Yes, if the proposal got approved into Stage 3 and implemented, that will be the case.
From V8 release v9.5, Chrome 95 will support languageDisplay
option, which value could be either “standard” or “dialect”. In my test, languageDisplay: 'standard'
can solve the problem.
let languageNames = new Intl.DisplayNames([], {type: 'language', style: 'short', languageDisplay: 'standard'});
When use "standard", all language names output with "LanguageName (LocaleName)" format.
There is a common use case that show a list of languages for users to select. I need to order all languages by their alphabet order.
Example 1 - alphabet order for the same language with different countries:
Example 2 - not alphabet order(if for all languages not only English) and not the same way for the same language with different countries:
I hope Intl.DisplayNames can give us an option to force format output like example 1.