-
Notifications
You must be signed in to change notification settings - Fork 107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Intl.Locale minimize/maximize extension keys #409
Comments
Dup of #390? |
I think it's safe to say that this issue is pending a resolution to #416. |
Do you have a use case in mind that wouldn't be met by an idiom like |
How do you propose handling user preferences that aren't covered by any particular Intl API, such as the first day of the week (among others; that's just one example)? |
@sffc Ah, good question. Maybe we should/could add these to |
Oh, heh, I rejected the resolvedOptions approach in #6 (comment) years ago :) |
A suggestion: Rather than framing this necessarily in terms of extension keys (which would only be able to explain a fraction of what's in CLDR), what if we added methods to |
I think the key question here is: how do we agree on the set of preferences that we want to make accessible? @litherum brought up an example of a hypothetical user preference, whether you prefer cats or dogs. Does TC39-TG2 want to own the decision of making a value judgement on whether a certain setting is worth adding? Unicode has already gone through the process of vetting the set of user preferences to include in the form of extension tags, and that schema is well-specified and understood around the industry. Why reinvent the wheel when Unicode already went through the trouble of solving this problem for us? |
How does this relate to user preferences? I thought the minimize/maximize API was about querying standard locale data, and we'd cordon off all user preferences to |
My understanding from a discussion with @aphillips was that the BCP 47 tags don't form a list of all the user preferences we might care about, and it might not make sense to extend them to this. (I'm not enough of an expert in this area to evaluate that myself, though, and it's possible I misunderstood him.) I'm also wondering if there's further data that CLDR has about locales that we might want to expose, which isn't even considered a "user preference". |
That's one of the problems: how do we go about deciding what user preferences to include? The list @zbraniecki posted in #6 (comment) is the closest I've seen of a cohesive list of exactly what preferences we want:
Basically, the policy I would propose is that we build on top of the closest thing there is to an industry standard on user preferences, and defer to that spec for not only the list of preferences, but also the schema and identifiers associated with them. If we standardize a list of valid user preferences (and the choices for those preferences) in ECMA-402, then we become the de-facto standard that others might cite, and this isn't something that I truly think should be out of scope for us. If there's a setting we think is legitimate and worthwhile including as a Locale extension keyword, we bring that to CLDR and let them decide. I think in most cases, if the request is legitimate, they will be happy to accept it.
Yes. Here are some examples:
I see these as fundamentally different from user preferences. First, there is usually only one right answer at a given point in time. Second, these preferences are often represented by more complex structures, like a set of Unicode code points (exemplar characters) or a DAG (region containment), not a string enumeration like is the case with user preferences. Third, these are more similar to Unicode properties (https://github.com/srl295/es-unicode-properties) and Display Names (https://github.com/tc39/proposal-intl-displaynames) than user preferences. I think if we wanted to add APIs to get at any of this supplemental CLDR data, we could add them on a case-by-case basis, and that decision doesn't influence what we do with user preferences. |
I'm still confused about where these are supposed to come from. Are they implied by the locale? Are they preferences indicated in the OS? A mix of them? I'm in favor of adding APIs for both needs (exposing locale data and exposing OS/user preferences). I'm proposing that we use different APIs for them (e.g., Can we agree that any OS/user preferences aren't exposed from calls to the |
Note that the separation of This is why I'm opposed to some kind of |
I'm not intending to conflate What I'm proposing is that if there are any user preferences, they show up in In other words, in a world with both of these features, if you wanted to get the user's preferred calendar, the fundamental operations (which we could sugar up if necessary) would be: // Step 1: get the user's locale (TODO: pick one based on your site's l10n support)
let contentLocale = navigator.locales[0];
// Step 2: populate the `-u-ca-` subtag if it isn't already present
contentLocale = contentLocale.maximize(["calendar"]);
// Step 3: get the calendar identifier
return contentLocale.calendar; There are two cases here: Case 1: Case 2: Does that help clarify? |
Yes, seems like our understanding of the separation between Now, to bikeshed: do we want to have a general I think getters for each thing that we want to maximize would be more ergonomic. It would also permit feature testing (though arguably that's not a requirement, as this could be considered a sort of a best effort API). Are there any reasons, ergonomic or otherwise, to prefer the array-of-properties approach to getters per thing to query? (These getters would also leave the door open for exposing data that is not expressed in BCP 47, as I mentioned in #409 (comment), though I think the initial set of things to include would be from BCP 47 (a subset of things that are in BCP 47 seems highest priority), and it's not clear whether we'd ever expand outside of that set.) |
That does indeed have nicer ergonomics: return navigator.locales[0].preferredCalendar; If you wanted to save the result for later, you could do, let maximized = navigator.locales[0];
maximized.calendar = maximized.preferredCalendar;
The
I'm not sure if Intl.Locale is the right place to think about adding these other getters, but we can talk about that in the future. |
Locales are immutable; I guess we'd do something like this: maximized = new Intl.Locale(maximized, {calendar: maximized.preferredCalendar}) I hope that that's good enough ergonomics, but if you have ideas for improving it, let's discuss them.
This topic of making things async seems really important, but I see it as a large and complicated separate issue. I think the data for this will be rather small, but supporting a larger set of locales, or strings in Intl.DisplayNames than would be practical to ship in engines (Emoji descriptions anyone??) could be really useful. Maybe we should discuss this separately.
Yes, I share this uncertainty, and agree that we can put off this discussion. Actually, this uncertainty is a big reason that we've held off on |
Let's follow up on async Intl APIs in #434 . |
How about, navigator.locales[0].getLikelyCalendar()
navigator.locales[0].getLikelyNumberingSystem()
navigator.locales[0].getLikelyHourCycle() where Intl.Locale.prototype.getLikelyCalendar = function() {
if (this.calendar) {
return this.calendar;
} else {
// return best-guess calendar from locale data
}
} |
@sffc I'm with you on semantics, but why |
Because of what I said earlier about these methods being more "heavyweight" and accessing locale data. It's weird for a getter to do potentially a lot of work. |
Oh sorry, I see you wrote:
I think some data-dependency is fine here. These are pretty small data tables. In general, I think these getters qualify as "acting as data properties", as described in the W3C design principles doc. We're not necessarily bound by that doc in TC39, but it's a nice point of reference IMO. Anyway, I think accessor vs method is a small bikeshedding question that we could resolve between Stage 2 and 3 (or the equivalent for this as a PR). Seems like we're zeroing in on an API here. Should we pursue this as a staged proposal, or a PR? Does someone want to be a "champion" for this effort, writing a document with the consolidated motivation and spec text? |
The ability to get at user preferences is an old, recurring feature request (#6, #38, #68, tc39/proposal-intl-locale#3). It's also a feature that will be important in a Temporal world, when we start to give developers more tools for building custom calendar apps.
I was wondering if we can do this with the maximize() function. Currently, that function only fills in language, script, and region. Is there a reason it can't fill in extension keys, too? It would be slow to fill in everything, but maybe you could request which extension keys you want:
The pattern to get the default calendar in a browser environment then becomes:
Slightly shorter, but could cause extra work to maximize subtags you don't need:
Maybe in addition, we can add a flag to populate this in the option bag:
@zbraniecki @littledan
The text was updated successfully, but these errors were encountered: