diff --git a/img/ecma-header.svg b/img/ecma-header.svg new file mode 100644 index 00000000..5eaffa9d --- /dev/null +++ b/img/ecma-header.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/meetings/notes-2024-05-23.md b/meetings/notes-2024-05-23.md new file mode 100644 index 00000000..4cc6b630 --- /dev/null +++ b/meetings/notes-2024-05-23.md @@ -0,0 +1,208 @@ +# 2024-05-23 ECMA-402 Meeting + +## Logistics + +### Attendees + +- Ben Allen - Igalia (BAN) +- Eemeli Aro - Mozilla (EAO) +- Chris de Almeida - IBM (CDA) +- Henri Sivonen - Mozilla (HJS) +- Louis-Aimé de Fouquières - Invited Expert (LAF) +- Richard Gibson - OpenJS Foundation (RGN) +- Sean Burke - Mozilla (SBE) +- Shane Carr - Google i18n (SFC), Co-Moderator +- Yusuke Suzuki - Apple (YSZ) + +### Standing items + +- [Discussion Board](https://github.com/tc39/ecma402/projects/2) +- [Status Wiki](https://github.com/tc39/ecma402/wiki/Proposal-and-PR-Progress-Tracking) -- please update! +- [Abbreviations](https://github.com/tc39/notes/blob/master/delegates.txt) +- [MDN Tracking](https://github.com/tc39/ecma402-mdn) +- [Meeting Calendar](https://calendar.google.com/calendar/embed?src=unicode.org_nubvqveeeol570uuu7kri513vc%40group.calendar.google.com) +- [Matrix](https://matrix.to/#/#tc39-ecma402:matrix.org) + +## Status Updates + +### Updates from the Editors + +BAN: Several editorial PRs fixing long standing issues have been merged. + +RGN: I'm happy with the editorial cleanup mode we're in. + +BAN: We have two PRs from Anba from last summer, #826 and #827. They are really good but really big. I would like to put up a new PR with those changes. + +### Updates from the MessageFormat Working Group + +EAO: We're thinking about changing the verbiage around error handling. A strict reading of the spec is that APIs must always return lists of errors. But we're considering making that requirement a bit more loose. Rather than having .format() and .formatToParts() that can return an Object/tuple of some sort for errors. Alternately: four AOs, .formatFallback() and .formatToPartsFallback(). Discussion ongoing. + +### Updates from the W3C i18n Group + +BAN: I was hoping that we could bring the MF2 discussion to the W3C i18n WG. + + +## Proposals and Discussion Topics + +https://github.com/tc39/ecma402/projects/2 + +### I18N objections to reducing accept-language #10 + +https://github.com/Tanych/accept-language/issues/10 + +YSZ: I discussed this with Apple i18n and privacy folks. We don't have a formal definitive position, but right now we're thinking that reducing A-L into a single item to one is not the right approach. For example, myself, I probably want to have 2 items in the list. Web sites that have Han/Kanji need to know whether I prefer Japanese or Chinese for rendering to be correct. We favor limiting fingerprinting but this is a big tradeoff. Limiting to only 1 is probably too problematic in real-world use cases. We are continually discussing these things; it’s possible that we could have a proposal with ideas, but right now we’re not agreeing with the direct proposal. + +HJS: Previously when this has come up, it's been noted that APple can take a llonger list of prefs but make it shorter. It's not public in WebKit but something in the OS. It would be useful for this discussion if that mechanism could be publicly described. + +YSZ: Right now, my understanding is that this Accept-Language handling is done in a CXNetwork framework. Basically we are sending up to two languages right now, the most preferred language and the system display language. It’s possible that we could change something, but at least my understanding is that this is the current behaviour. + +HJS: I was previously under the impression that there were APple internal experts that developed an allowlist of combinations. + +YSZ: This is much more about a definition of locale itself, this is Accept-Language sending what language we’d like to send. + +For example, the system itself allows us to specify Arabic or Latin number. But this is not strictly tied to the Arabic locale itself, because we need to pass that as a Unicode extension. So we are bucketing these sets of configurations. That is different than Accept-Language. + +HJS: It would be great on these threads to have a description of what's going on in Safari. + +SFC: Thank you. We’ll continue having these discussions. If there are major updates, I’ll bring them back to the agenda. Mike wanted the feedback from the l10n groups, and I think we've done that now. + +### Smart Unit Preferences + +https://notes.igalia.com/p/5wv2lK6Fp#/ + +BAN: (presents slides) + +EAO: I have two separate thoughts. 1, I think unit conversion should be a 262 matter… I can imagine cases where the converted value would be valuable outside of formatting. Baking this capability into NumberFormat would make working with this clumsy. The other aspect is that through working with MessageFormat and other contexts and quite influenced by things that SFC has mentioned, I have come to understand and agree that the unit of a number is not a formatting option, but a quantity of a value that’s being formatted, and a more general solution that could help us with building an appropriate API is bringing in some sort of support for a “measured unit” as a compound that could be acceptable to NumberFormat + +HJS: Do you have quantification of how much data this is, when the data is arranged in a way that a reasonable programmer would do? + +SFC: There are several types of data that go into this, but most of the data is included in units.xml in CLDR. + +HJS: If you wrote an ICU4X transform for this, how much would the ICU4X data. + +SFC: Younis has been working on the ICU4X implementation, he already has a data structure for the conversion factors. We can look up exactly how big that is. + +HJS: From seeing what you’ve showed, it is a bad case of the US region overriding all of these. + +SFC: It looks like the unit conversion factors are about 8 kB; see here. + +SFC: We got two types of feedback here and at TG1: is 402 the right place, and is the ‘en-US’ problem unsolvable? Having a way to pull some other variable than browser locale would be ideal. Fingerprinting challenges. + +BAN: I wouldn't expect that this wouldn't split into too many buckets. + +HJS: When TG1 was asking if 402 was the right place, was it presupposed that some JS place that’s appropriate for this, or HTML/CSS issue? + +SFC: If I understand correctly, there is generally a feeling that a unit conversion API should be put in a library / blessed library, but also definitely a l10n concern. That requires deep integration with Intl API, not something userland library can provide. They can do conversions, but not formatting. + +HJS: Was the topic of doing it somewhere other than JavaScript discussed at TG1? + +BAN: It wasn't a topic I saw in the TG1 notes. + +SFC: One thing that we should discuss as a group and get a position on two axes: the user preferences thing, and the unit conversion thing. We might find it useful to have a more clear message to send regarding this topic. This formatting is a 402 concern, but conversion is not, and it’s also not a 262 concern. Resolving this can let us make a clearer recommendation. + +EAO: I'd say that one way in which we could assist solution would be to define something like a CompoundValue API that would be supported by NumberFormat and others, so you could have for example an object with a value property that's a number and a unit property, or a currency property, and this value could be directly formatted with NumberFormat accordingly if defined in the options bag and the input value. By defining the API, we’d be giving an output target for libraries for conversions to use to produce. We could get the whole experience, and a part of it would be done – the localization aspect – could be done in 402, and the rest in userland. + +SFC: My thoughts on unit conversion is that we’re not in the business, particularly with the lack of a decimal type, we’re not in the businesses of giving scientific conversions in ECMAScript, because we don’t have a scientific type. The only risk is that when we add this feature, we in effect do have unit conversion in the platform, it’s just not wrapped in a unit conversion API. So what people will do is what people do with time zones, where people have all these weird hacks that parse output from DateTimeFormat. This causes a lot of problems, and what stable formatting tries to solve. A principle is that if there’s any functionality embedded in an Intl API that’s useful outside of Intl, we should do that outside of Intl. Another solution we should do in more places is we should have more expressivity around the formatted value. We currently have formatToParts, which solves a lot of these problems, but we could do better. In ICU4X/C things return formatted values with additional getters. Perhaps we could eventually return an object, keep value and unit in a machine-readable form, or we could just rely on StableFormatting to do that – if you StableFormat using the null locale, this could give you a machine-readable form that you can utilize. When formatting for human display, we’re not doing a highly accurate conversion. Example: When we’re talking about social distancing during COVID, the CDC said you need to have six feet of separation to be safe. When you display that in Germany, what’s happening is there are sources that say “you need 1.83 meters of separation”, which doesn’t really get the spirit. They probably should have said 2 meters. But this is the type of thing where these localized outputs aren’t designed to be accurate scientific conversions. I think that’s okay. If we do provide APIs to get to these formatted values, that’s the disclaimer that comes with them: it’s not meant to be a scientific unit conversion, _but_ if you want the outputs you can get them this way, since we don’t want you to parse strings. + +HJS: So the assumption is that a conversion API would need to be very scientific, and double-precision floating point would not be good enough. This context here, that CLDR has, are things like person-height, floor-area, surely double-precision floating point numbers are precise enough for that. It seems weird to refer to have an outright conversion API out of fear of not having a decimal type. On that point, what about currency? Money stuff seems higher-stakes than person-height. I assumed that currency formatting is high enough stakes that it’s not used, then I look at the HTTP Archive and it seems to be one of the most popular things that people do with Intl APIs. When there is currency formatting in the API, it seems overprudent not to have a unit conversion API with lengths and areas. I’m not saying we should have that API, but that the Decimal reason doesn’t seem like a good reason not to have it. + +SFC: It’s a matter of when people think of measurement units, they come with this presumption that things are going to be accurate. By having everything you can do inside Intl, we indicate that this is l10n, rather than precision. Not actually scientific – by doing it we’re saying this is an approximation. + +LAF: The accuracy is itself a characteristic of the output. + +SFC: The only place currency could come in is something like “dollars per mile”, that would be a legal conversion, but we’re not going to ever convert currencies. + +EAO: Just reiterating that I don’t think unit conversion belongs in 402. What could belong is 402 is getting information for which measurement system is used in this locale for which object. Actually doing the conversion doesn’t belong in 402. + +SFC: Definitely a valid perspective. In general there are two directions: we provide a black box that does everything. The other is to provide building blocks, and the building blocks that are needed. One is to get the unit preferences for a locale and a preference. One is encapsulating mixed unit lists. And then defer to 3rd party library for conversions. That can be done, but isn’t necessarily the most important thing. CLDR has the conversion data and the conversion utilities. There’s a lot more than just unit preference lists. If it says “here’s a region, here’s the usage”, if you look at the xml file, it depends on how big the unit is. You get a list of units for big, medium, and small. You also get data around how to round units. Road distance example: different rounding for different distances. There’s a lot of detail in unit preferences that needs to be exposed, and a lot of glue code. If it’s a black box, it’s easier to do the right thing and harder to do the wrong thing. By giving the building blocks, we’re setting up programmers to do the wrong thing. My position is that it seems intuitive that we should give the building blocks, but it’s better to give the black box. + +EAO: My main concern with a black box is that there are real user desires for using the value of a unit conversion, rather than just the formatted result. What it sounds like you’re proposing is an API that could expand the scope of how people misuse Intl interfaces to get at the value, or proposing something novel in 402, which is providing a value use that could and should be used as such. It would be interesting to see the shape of what that looks like. Potentially this sounds like a thing that is maybe a 402 thing, but not an Intl object thing. I don’t know where it’d go or what it would look like, but it would be interesting to see. + +BAN: The reason the black box idea works for me is that all the data is already in CLDR. The idea of it being a 402 thing but not an Intl object is intriguing. + +SFC: We’re not solving the problem of doing unit conversions to the web platform, but we have learned the lesson that if people will use Intl APIs for things that they shouldn’t be used for. People will definitely use this for unit conversion, even though it’s not what it’s for. What we can do is acknowledge that they will do it, and provide data in a way that won’t break, without fully endorsing that this is a unit conversion API. + +EAO: If we ever provide an API that does unit conversion and provides output, that will be a unit conversion API for the web platform, even if that’s not how it’s intended. + +HJS: I agree, we should take into account what programmers will do and not just say that it’s not designed for that. + +SFC: Sounds like we’re in agreement – that’s something we’ve learned the hard way. Maybe we could take these points, make slides, and get ahead of questions, so that TG1 discussion isn’t a rehash of earlier ones. + +SBE: One takeaway is that actual unit conversion… there are too many different ways that people might want to use that. Some of those ways are things that we really don’t want them to be doing with an i18n API, which suggests what EAO proposed – notating what units are, not providing the conversion. Actually including conversions opens up several cans of worms that we don’t necessarily want to address in Intl. + +SFC: It’s safe to say that we don’t have a TG2 recommendation for building blocks vs black box approach. Gathering the pros and cons are acceptable at this point. When we get to the point where we’re asking for stage 2, we’ll need a TG2 recommendation, but we don’t need it right now. + +SFC: One sub-proposal is doing formatting of mixed units, which is something that’s motivated on its own. You can already do it by gluing NumberFormats and ListFormats together, but do we want to support that as a unit we can support in NumberFormat itself. Another less controversial sub-proposal would be the thing that CDA proposed before, notation: compact with a unit. See how that fits into the picture. That’s not the smart units proposal, but it’s one we could maybe move on. It would be nice to align on what we want the end goal to be, since there’s lots of sub-proposals to do to work towards that end goal. We should ask for 45 to 60 minutes for a discussion of this at TG1. Goal of that meeting is to get more clear guidance on what direction we want to take / black box vs building blocks, and the shape in general of unit formatting. If we say we want the black box / to do things the right way, we could also do something to fix the problem that CDA found with the compact notation bytes formatting. + +EAO: I think putting building blocks and black box as opposition to each other is not necessarily the way this can go. I think the concerns about how the value results of conversion can get used will lead us to a situation where we provide some solution – something like building blocks will need to be provided – the question is whether we end up with black box and building blocks. If we provide just the black box, it’s going to get abused. + +### Please remove onError parameter from format/formatToParts + +https://github.com/tc39/proposal-intl-messageformat/issues/58 + + +EAO: Discussion about this is happening in the MessageFormatV2 and the ICU TG. The question we’re asking is what is an appropriate set of requirements or suggestions that that spec should offer for how MessageFormat2 messages should be formatted if they fail, either a little bit or a lot. If they’re calling a custom function that fails, if they’re using invalid data, or they’re formatting a message that requires a variable that’s not passed in, etc. The text that has been in the MessageFormat2 spec is quite strict about how an API should behave, and it is possible that the text of the spec that we end up with will be looser about requiring the formatting behaviour to be the same across implementations. The question that’s interesting for us to consider here is what we think the most appropriate thing for JS, is that appropriate thing for JS something that is enabled/allowed by the MessageFormat2 proposal, so that we can take that feedback to the MessageFormat2 working group. Or should we find something that’s more appropriate than the current way. My personal take is that I very much value the strictness that is currently in the spec, and I do think that the current proposal for the format methods with their own error callbacks is the most JavaScriptey way of handling this, and a valid way of fulfilling all the requirements we have here. + +SFC: I think that it’s an important behaviour to have. Not only is it required by the current specification, but it’s also useful to clients to access and iterate over these errors. However, I do think that there’s room to think about what’s the most JavaScriptey way to give this information to users, and I’m not convinced that onError is the most JavaScriptey approach. This is not something I’ve necessarily seen done in JS languages. JavaScript supports exceptions – not every language does, but JavaScript does – and try/catch is a pattern I’ve seen. We can also populate fields – it’s very JavaScriptey to return bags of data. Possibly return an upgraded type like FormattedMessage, with getters on it to get the errors out. Regex.match returns an object that has getters on it – it’s consistent in JS to do something like that here. Having an error callback – maybe EAO can describe why this is the most JavaScriptey approach. + +EAO: My background in this API design is working with Fluent, which has a similar sort of approach, in that the Fluent JavaScript formatting call returns a tuple with the value and list of errors, for the same set of purposes as in MessageFormat2. The sources of the error are various, that the user will have a use for both a message that is possibly formatted with some fallback values, as well as the errors themselves that they may deal with as appropriate. The practical experience as a user of the Fluent library in JavaScript made that pattern strange and clunky to use. It also requires the construction of the list of errors within the formatting, and its population, and then including in the output. Whereas the pattern that is here, is a sort of pattern, which I think USA linked to examples of, to me this seems from a userland point of view a much more common pattern to be used in interfaces, and it makes for a much cleaner UX when the formatted result is always the formatted result, and the errors that you might need to deal with (but only rarely can with this sort of API) is handled by a side-channel. The least-worst option here, in particular because it avoids the wrapper object creation that would be required by any sort of compound value, given the feedback that this proposal has already received is the number of objects that we come up with here. + +SFC: To return to the object count concern, we’re not introducing too many objects. We’ve been hearing a lot about object cost in Temporal, but Temporal is basically two orders of magnitude more than this. I think that there’s potentially a very big benefit to having MessageFormat return a formatted message. Not only for error handling, but also for the expressiveness of the .formatToParts(), something like that. If it turns out that error handling is the only reason to return upgraded type we can have that discussion about adding more types, and this use case may not be enough justification for adding a new type, but my instinct is that it’s not the only use case. + +EAO: That’s where the API started from. The call for that was called resultMessage, since I figured all the format calls currently return a string, so returning something other from a string would seem weird and not fit with the rest of the API design. Earlier in the life of this proposal the way to do it would be to call [?] that would have toString and toParts, to get the string value and the parts value, and provided you access to some of the more internal values of the message, which allowed you to take one formatted message and more cleanly and clearly include it as an input value to another MessageFormatter, in cases like we needed to include one message in another. There is a sense from TG1 that this is not the right thing to do. The sense I got when presenting that API was a strong desire for this to be more normal, more aligned with the format and formatToParts methods in other Intl objects, so that’s the direction we’ve taken. It sounds like this complex message value return could be explored, but there’s also concerns that have been previously made about that, and an explicit move away from that to our current design. I am not sure that error handling was specifically discussed in a clear way during all of that. + +SFC: It sounds to me that this is probably a topic that’s worthwhile discussing again with TG1. I know that the previous discussion we had with TG1 was a little while ago, I don’t have a clear recollection. If the question is just about API shape, it is worthwhile to put this on the agenda so that we can discuss it with TG1. + +EAO: I don’t have the bandwidth for doing that for Helsinki. + +SFC: It would be an appropriate venue, if we have the resources to put such a thing on the agenda. + +EAO: I don’t mind other people putting MessageFormat on the TG1 agenda and talking about it, but since I’m effectively hosting the meeting I don’t have the bandwidth for doing it myself. + +SFC: I may put this on the agenda for myself. + +### Add locale sensitive substring matching functions to Intl.Collator + +https://github.com/tc39/ecma402/issues/506 + + + + + + + +HJS: There exists, not in 402 but in ICU4C, a notion of collator-based search. To have the notion of case-insensitive search that takes in account accents and (for example) the Turkish i. There are accents from the English-world point of view are accents, but are from the Finnish point of view (for example) are considered as a base letter in their own right. If you have a checkbox to allow/disallow accent, if you have an é you would ignore it, but you wouldn’t ignore [a with 2 dots] + +So we need to know what accents are ignored and what accents are not ignored. It seems like we can get this information “for free” by using a collator, but “for free” may not be free. For example, if you want to search instead of just sort, there’s a need to correlate the collation units back to the text, which is complexity. The mapping is complexity, and then it turns out the whole design space for why collation data is arranged the way it is is because the point is to have culturally relevant less than / greater than relationships, but for search you just need equals, and less than/greater than is wasted complexity for search. Implementing search, since there is this need to correlate the collation units back to the text being searched, it’s a non-trivial effort to take a collator that does sorting and extend it to search. On the other hand if you have unicode database data and add special cases for (example) the Turkish i, and the kind of pre-baked data where you can take a character and have it mapped to its base character without accents, even without going to normalization. You could do accent-insensitive search and some kind of exception data that’s much simpler than collation data. What this is asking for is an accent- and case-insensitive search, and asking for a particular mechanism, and that mechanism is excessively complex. Even if we think the use case is reasonable, should there be a different mechanism than collation-based search for it. There are additional complications required to tie Arabic script and Hangul in CLDR. Another reason why this doesn’t come for free is that, since there is the collation data for Finnish or Swedish, you can use that for search, but you can’t: the implementation only allows the root and one tailoring later. We end up with as many copies as the search tailorings to the root as there are locales that have this locale-specific tailoring, and we duplicating the locale-specific tailoring. It ends up being very much not for free. So why do we have this search root layer? Well, the equals sign should not match not equals. We have one character that’s special everywhere. Then it takes the position that ignoring the tie, that for some reason ignoring that should be analogous to ignoring accents or case. That’s fine, but it could be special-cased with much less complexity than this. Similarly, there is data that, Arabic hamza, ignoring that is considered equivalent to ignoring accents in search, but there’s no user story of why you’d want this for Arabic, other than “we need to do this, let’s do this” without any background explanation of whether this is what users want. I’m not saying they don’t want it, I’m saying it’s problematic when the motivation isn’t visible. And for Hangul, it seems what the search collations try to accomplish is, say you’re producing archaic symbols, you want to approximate that with a modern IME, is it necessary? Firefox doesn’t do that – we don’t get complaints, but I don’t know if that’s a good signal. There’s a lot of complexity and it would be good to see to what extent users actually care. + +What Firefox does is based on this precomputed fold case and precomputed base letter thing. I think if we want accent-insensitive search in a way that’s locale-sensitive about what accents to not ignore, we should first think about whether it’s a problem that really needs solving, and we should have a special-purpose solution for that instead of supposing that collation data gets it for free when how much it costs to get the collation database to do the search is a lot. + +SFC: I think the use case here is definitely something that a lot of developers want to do, and as with all these Intl APIs there’s a lot of gnarly corners of everything we do – date time, number formatting, regular collation, there’s a lot of weird corners – but this seems like a use case that comes up a lot. I have a string, I want to search for substrings, get the boundaries, that seems like an operation that seems useful. I do agree, though, that there’s a lot of people in this thread who are saying in one way or another that I want to get at the building blocks. This is a good example where the building blocks are so messy and easy to use incorrectly that doing the building blocks is not the right solution. What’s the very basic fundamental that we might be able to agree on? Intl.Collator has the compare function that returns equal, less than, greater than, so one fundamental is, let’s say we took a string of text, took out every substring, and ran Collator.compare(). We could have a function that’s the ranges in this text that are Collator.compare() equal. Is that a thing that we think could be useful and motivated if we shape it in that form? Separate from the idea of exposing the Intl.Collator search? + +HJS: Markus is noting in the thread that it’s more complex than that. Even though it’d be quadratic to look at each of the substrings, even if it’s extremely inefficient to take the current primitive and build search out of that primitive, there’s cases where it wouldn’t work. The way stuff works is even more difficult than it seems. What could go wrong? There’s the issue that in Thai they put certain characters not in logical order in the storage, and then the collation layer, when it’s used for sorting, in the process of mapping to collation elements undoes that presentational ordering. Then the search root suppresses those contractions, so that the search operates on how the user who’s used to the way the Thai keyboard works and Thai storage works matches those substrings. + +Multiple characters in the storage can form one collation unit, but there can be issues if the prefix search lands in the middle of that sort of thing. Even if you do the silly quadratic approach, you still can’t get reliable results. And then how do you correlate that back to the input? Once you’ve run a match on the collation units, the collation units are 64 bits. If a browser has UTF-16 and you could run a search on UTF-16 and have a handful of special cases for case- and accent-sensitivity, and mappings on those units, UTF-16 units to UTF-16 units, you get this other set of 64 bit units that don’t correspond to one thing. There are so many simpler ways to accomplish the use case, but they need data that CLDR doesn’t currently have. Opening the collation data up in one window and have [] for accent-sensitive search, looking for the collation definitions and picking out the interesting things and developing this other data would be much less of an undertaking than implementing a search function on Intl.Collator. Searching the ICU4X collator vs doing all the work of reviewing collations in CLDR and adopting the current firefox approach based on new exception data is something I’d rather have, rather than the software project of adding collation-based search to the ICU4X collator. It’s better to look at the data and put them in a form that’s optimized for search, rather than taking the collation data and using Intl.Collator for search. + +SFC: Maybe this isn’t a 402 issue – maybe if it came from Unicode or CLDR, we then could look at it? – but it seems hard to implement in 402. This seems to be a really simple problem where people have found a solution – firefox has its own, that it uses internally – but that can’t be the only solution for this problem. + +HJS: For non-locale sensitive, the search that would correspond to the root locale without the Thai and Arabic things, that works on modern Korean and the sort of scripts that have accents that are really accents, in the sense that Latin and Greek scripts have them, and not hamzas, Firefox has an implementation of that but doesn’t have locale-specific exceptions. The only complaint about that is from a Finnish colleague. We’re not getting reports from throughout the world about not having collator-based search. If you have a large enough web page, like the HTML spec, even on a modern computer that’s super fast with an optimized build of a browser, you can see the difference in performance between collator-based search and what Firefox does. + +SFC: In order to do this correctly, this is not a small thing. We want to collect the data to make sure it’s implementable in ICU4X, and it sounds like the solution that’s currently implemented in ICU4C we don’t want to implement in ICU4X. Could you clarify – if Safari and Chrome are already using the ICU4C approach – why… + +HJS: It’s a needlessly complex approach. Firefox takes 16 bit units and converts them to 16 bit units on a character-by-character basis, so that you don’t get lost in the haystack. + +SFC: So you’re saying that the Firefox approach is technically superior to the ICU4C implementation? + +HJS: It's faster, less complex, has fewer edge cases, doesn't need to correlate back to the original representation. It runs directly on the UTF that you have, instead of first transforming into this many-to-many 64 bit space and then having to search on that end and correlate back, so it doesn’t have that issue, and as a matter of efficiently, because the collator data is designed so that > and < are culturally sensitive, we have needlessly complex data design for what we need. If we don’t, for collation for sorting purposes, we need only root and one level of tailoring, and that’s currently the way it is in both ICU4C and ICU4X. For search we logically need three layers: sorting root, search root overlaid, then we need the locale-specific overlay. Unless we do three layers of lookup in the collator itself, we end up with the data situation as you see in ICU4C, where we have this duplication and duplication of data that’s supposed to be for free, but the search root layer gets duplicated as many time as there’s search locale, and the locale-specific data is duplicated for every locale that has locale-specific search. And what the data is designed for is inefficient for our purposes. + +SFC: One of the reasons I put this on here is because there’s a large number of upvotes. It does seem like a use case that has uses – I can even see google docs wanting to use this sort of API, I can see Google clients wanting to use this API if it’s available, so it seems intuitive that this is the kind of thing we want to work toward. I am convinced that there’s a use case, but I see what HJS is saying about the problems with using collator for that. Since Firefox has its own implementation, I wonder if someone from Mozilla can upstream this into ICU4X, and then eventually 402. + +HJS: The thing is, we don’t have the locale-specific rules, we have what correlates to the root locale, so we don’t have the locale-specific exceptions. Maybe there are users who are unhappy about it, but the only one who has filed a bug is one of my colleagues in Finland. + +SFC: Adding locale overrides is part of the picture – if we can get agreement from the different committees about whether this is the direction we want to go in, we could ask that question at that time. + +HJS: We have [missed], and a logically equivalent operation computed from the Unicode database for removing accents. We could have a codepoint trie for ICU4X, seems like the sensible thing. + +SFC: Next month: Sequence unit formatting, how do we support formatting of foot-and-inch, meter-and-centimeter, we can have a discussion about whether we want people to rely on ListFormat or if we want people to have a more cohesive solution. + +The other item is the ‘und’ locale – it turns out we don’t support this in the Web platform. I thought we did, but I looked more closely and we don’t. Do we want to add the ‘und’ locale? Is this a solution we can employ for the StableFormatting proposal? That’s a discussion we can also have next month. I’ll post my conclusion on 506 based on these notes. And again, my conclusion that this is a thing that we can’t solve in ECMAScript until we solve it in Unicode, and solving it in Unicode requires in the next few years to see if we can take pieces from the Mozilla solution and bring it into ICU4X, and then after that bring it in to 402. diff --git a/meetings/notes-2024-06-20.md b/meetings/notes-2024-06-20.md new file mode 100644 index 00000000..306f1862 --- /dev/null +++ b/meetings/notes-2024-06-20.md @@ -0,0 +1,75 @@ +# 2024-06-20 ECMA-402 Meeting + +## Logistics + +### Attendees + +- Shane Carr - Google i18n (SFC), Co-Moderator +- Louis-Aimé de Fouquières - Invited Expert (LAF) +- Ujjwal Sharma - Igalia (USA), Co-Moderator +- Yusuke Suzuki - Apple (YSZ) + +### Standing items + +- [Discussion Board](https://github.com/tc39/ecma402/projects/2) +- [Status Wiki](https://github.com/tc39/ecma402/wiki/Proposal-and-PR-Progress-Tracking) -- please update! +- [Abbreviations](https://github.com/tc39/notes/blob/master/delegates.txt) +- [MDN Tracking](https://github.com/tc39/ecma402-mdn) +- [Meeting Calendar](https://calendar.google.com/calendar/embed?src=unicode.org_nubvqveeeol570uuu7kri513vc%40group.calendar.google.com) +- [Matrix](https://matrix.to/#/#tc39-ecma402:matrix.org) + +## Status Updates + +### Updates from the Editors + +USA: There's a lot of work recently on the editorial side. It won't make it into ES 2024 but will be coming up. We would be glad to receive more editorial suggestions and comments. We should thinking ahead about what we can do to further improve the spec for readers, implementers, and other groups. + +SFC: Where do we stand on landing the big PR from Anba last summer that Ben updated? + +USA: Looks like they are merged + +### Updates from the MessageFormat Working Group + +USA: The plan at the moment is to expand the set of stakeholders in MF by inviting more people. + +SFC: There's an open issue with TG5. Is there anything we can do to accelerate the MF study in TG5? + +USA: Yeah I can take an action about that. + +### Updates from Implementers + +https://github.com/tc39/ecma402/wiki/Proposal-and-PR-Progress-Tracking + +(none) + +### Updates from the W3C i18n Group + +(no liaison present) + +## Proposals and Discussion Topics + +https://github.com/tc39/ecma402/projects/2 + +### eraDisplay Action Items + +https://github.com/tc39/proposal-intl-eradisplay/issues/9 + +LAF: The present state is that we've discussed making the CLDR drive the process of displaying the era. I think it's a good idea as of now. But should other people be in the loop to move forward? Until now, it was only a question of analyzing whenever there was an error field in the date to be displayed and now we’ve to consider something that could be in CLDR and say “if we’re in this situation we have to … and in another situation we have to cancel it”. Should we make a sort of mock-up to see how things should work? + +SFC: Of the CLDR data? + +LAF: Yes. + +SFC: Goes through #9. + +LAF: In some calendars, eras can be implied. In some cases, in order for the date to be understandable for people, you have to mention the era. This is the case for the ordinary gregorian calendar. There are many situations where within the same locale, you might have to change the reckoning rules. Maybe we shouldn’t mix up the two IDs. What happens today is that most people say that we need only one reckoning system to set the date in a rather precise and straightforward way, thanks to ISO 8601. But in many historic applications, you’ll find people saying that they want to express historical dates in a modern way. + +SFC: what is a sub-era? + +LAF: a sub-era is when you don’t change the reckoning rules but you change the way you write the date. For instance, if you mention a date in the 30s, it could be misunderstood and therefore you would probably have to include additional information. It’s not a new era, it’s just expressed like that to avoid the ambiguity. + +SFC: So Spain and Italy have the same change date. Would there be a difference in whether the era code gets displayed between languages/regions, or is it only dependent on the calendar system? + +LAF: It is mainly for users speaking other languages in a region. For example, a Spanish reader interacting with English dates would want to know whether they are in old or new system. + +SFC: Spanish readers living contemporaneously with the change date might have needed this disambiguation, but Spanish readers living today probably are roughly equivalent with English readers with regard to the context in which they need the disambiguation. diff --git a/meetings/notes-2024-07-18.md b/meetings/notes-2024-07-18.md new file mode 100644 index 00000000..1d23f0f7 --- /dev/null +++ b/meetings/notes-2024-07-18.md @@ -0,0 +1,310 @@ +# 2024-07-18 ECMA-402 Meeting + +## Logistics + +### Attendees + +- Shane Carr - Google i18n (SFC), Co-Moderator +- Louis-Aimé de Fouquières - Invited Expert (LAF) +- Ujjwal Sharma - Igalia (USA), Co-Moderator +- Yusuke Suzuki - Apple (YSZ) +- Ben Allen - Igalia (BAN) +- Henri Sivonen - Mozilla (HJS) +- Eemeli Aro - Mozilla (EAO) +- Frank Yung-Fong Tang - Google i18n, V8 (FYT) +- Jesse Alama - Igalia (JMN) +- Richard Gibson - OpenJS Foundation (RGN) + +### Standing items + +- [Discussion Board](https://github.com/tc39/ecma402/projects/2) +- [Status Wiki](https://github.com/tc39/ecma402/wiki/Proposal-and-PR-Progress-Tracking) -- please update! +- [Abbreviations](https://github.com/tc39/notes/blob/master/delegates.txt) +- [MDN Tracking](https://github.com/tc39/ecma402-mdn) +- [Meeting Calendar](https://calendar.google.com/calendar/embed?src=unicode.org_nubvqveeeol570uuu7kri513vc%40group.calendar.google.com) +- [Matrix](https://matrix.to/#/#tc39-ecma402:matrix.org) + +## Status Updates + +### Updates from the Editors + +BAN: It's been slow. Most merges have been related to Temporal syncing. + +USA: ECMA-402 11th edition is approved! + +https://402.ecma-international.org/11.0/index.html + +USA: I feel BAN has been working as an editor for some time. I think Ben should officially join as a co-editor. + +SFC: Ben has been an apprentice editor for 1 year, so this is a great time to give Ben the promotion! + +USA: We'll formalize it in the next TG1 Plenary. + +### Updates from the MessageFormat Working Group + +EAO: It has been relatively quiet. The most active thing is the open ballot in the working group about normative requirements involving error handling and fallbacking: whether to require these at all, and what are the specifics for what's happening. This impacts what we do in Intl.MessageFormat about error handling, following up from the discussion from the Helsinki discussion in June. + +Voting thread: https://github.com/unicode-org/message-format-wg/issues/830 + +Discussion thread: https://github.com/unicode-org/message-format-wg/issues/831 + +EAO: The other thing is, Addison Phillips and I have been discussing what Bi-Di marks to allow for, or strongly recommend. For right-to-left content to appear without difficulty in the overall left-to-right syntax. I'm not familiar with this being implemented in other programming languages. + +This is not necessarily appropriate for JavaScript, but it’s an interesting discussion in the MessageFormat working group. It’s not concluded yet, but is not controversial in any way. + +SFC: Have you considered whether UTS 55 applies? + +https://www.unicode.org/reports/tr55/ + +EAO: We're looking at it, but UTS 55 is not an all-in-one solution. + +SFC: Bi-di is a key thing, and problems related to it are something that MessageFormat can leverage. One thing is making sure that the MessageFormat syntax are compatible with the constraints in UTS 55, which tries to indicate what’s an identifier character, what’s a syntax character. + +EAO: We should be UTS 55 compatible. + +### Updates from Implementers + +FYT: I synced V8 to the latest DurationFormat spec. Some LocaleInfo changes needed, basically bug fixing. Currently staging DurationFormat to Chrome 128, which will be available generally to the public in end of August, and planning to ask for shipping DurationFormat for 129. Haven’t done it yet, but upcoming in September. Updating LocaleInfo to match current spec, removing getters in a separate cycle later. + +BAN: Does that mean it's plausible to move to DurationFormat Stage 4 in Tokyo in October? + +FYT: It's possible but a little early to talk about it. + +SFC: It sounds like it will still be in time for ES 2025 / 12th edition. + +SFC: HJS, did you have any updates? + +HJS: Pending patch for non-ISO calendars in Temporal, done by Anba. + +SFC: I believe Anba is using ICU4X calendars for that + +HJS: Yes + +SFC: That’s a very good development – I’m glad to see that. + +YSZ: In JSC side we are updating Intl.DurationFormat and right now we’re working on the recently updated spec (?) + +SFC: That’s wonderful. + +YSZ: The good thing is that it is updated by the contributor who is working on this thing as an open-source project. + +SFC: I’m happy to hear that, because I was slightly concerned that since we made that API change, was that going to be in JSC vs. V8. It sounds like they’ll be interoperable, so that we can go to stage 4. + +### Updates from the W3C i18n Group + +BAN: The thing that's been most active is they have new working drafts for scripts. They have docs describing the diffs for Urdu, etc. There hasn't been any discussion of MessageFormat on that side from what I can see. + +SFC: Question for W3C – TPAC meeting in Anaheim coming up soon, do you believe it will be productive for + +EAO: My expectation for MessageFormat for W3C right now is relatively low, since there isn’t a W3C or WHATWG proposal activating at the moment. That’s essentially blocked by us not knowing when we can get Intl.MessageFormat to stage 2, so it doesn’t make sense to go ahead of things on W3C. I don’t have any expectation of this being considered there. Second point is that I am at least going to be at TPAC, and would be interested in any of us who will be around here. + +USA: The ones of us who live in California will find it quite convenient. + +SFC: One reason I brought this up is that we haven’t had an in-person TG2 meeting for four and half years. So I was also considering whether this would be something that we’d consider doing, if a lot of folks will be around at TPAC. There’s also UTW, the Unicode-specific meeting in Sunnyvale in October, so logistically that would be quite easy for me to set up an in-person TG2 meeting on a Thursday in October. But I want to see which event is likely to draw the most delegates. + +EAO: Would be interested to get a determination of when an in-person thing could be happening as soon as possible, since I will be making transatlantic travel plans around it and will appreciate doing so as soon as possible. + +SFC: I agree that we should figure this out soon. It could be the case that for our official meeting we continue to do on video, but also have an informal working meeting that’s not necessarily an official TG2 meeting. + +USA: I don't think I'll be traveling to either event. + +EAO: I’ll be at TPAC, I may be able to make UTW and possibly a TG2 meeting in association with that, but that’s dependent on other travel timings. TPAC, I am definitely coming. + +HJS: I have plans that conflict with both of these, so unfortunately I won’t be attending either. + +SFC: I certainly think UTW is a valuable event if you’re in the i18n space. ECMAScript is a huge part of this, but also in keyboards, localization, CLDR, ICU4X, talks about integrations, globalization, the business side of things.There’s basically everything in this space. It seems like EAO is the person I should be talking to about scheduling, because it doesn’t seem that others are considering traveling. + +## Proposals and Discussion Topics + +### Decimal & Intl topic for the July Ecma 402 monthly call + +https://github.com/tc39/ecma402/issues/906 + +JMN: I can present briefly. This is my chance to rejoin this group, I discussed Decimal here a few months ago. Since then Intl has disappeared from my own radar, so to speak – I’ve been focusing on getting the spec right. As we get ready for plenary I wanted to push the turbo button on getting this ready. I’ve prepared a PR just yesterday – there’s nothing final there, but I can present it if you like. But my open question is whether I’m barking up the right tree here, or if I’m missing the ball. I can’t verify for myself that I’m doing the right thing. Consider this a grand ping that Decimal is still going. If there are things that I’m getting badly wrong, or things I’m completely missing – pieces of the contact surface between Decimal and Intl that I don’t know. The main contacts points are PluralRules, which is fairly small, and then the larger one is NumberFormat. I’m not asking for a live review, simply bringing the topic back to the table. + +EAO: Sort of a side topic: what you said reminded me of the fact that Intl.PluralRules supports Number but not BigInt, whereas Intl.NumberFormat supports both. As you work through the Intl.PluralRules spec, the updates required to that to make it work with Decimal, it might be interesting to keep in mind that we’ll be adding a third type of input to PluralRules at some point, and then this is a bit of a question: if we were to add BigInt to PluralRules, would that be a fully qualified proposal, or could we do it as a smaller change in order to get that through. Or is there a specific reason that I’m not aware of that PluralRules isn’t and shouldn’t be supporting BigInt + +JMN: When I initially got started with Decimal, Intl wasn’t on my radar – it came up on my radar late. The main thing on my mind is just implementer concerns about this stuff. Very good question. I don’t think it would be difficult, though, to add that support. + +SFC: Two things: First, on EAO’s side topic, I thought I recalled that we had discussed this a few years ago and that it had already been resolved that we should have it. If we did do that it may have just gotten lost in the tracker. We should support the same shape of input in NumberFormat as in PluralRules. The second is about Decimal specifically. The other comment about Decimal is going back to JMN’s topic – I’ve reviewed your PR and left some feedback on it, and it looks like you commented during the nighttime in my timezone, and I haven’t seen it yet. + +JMN: Yes, because of the time zone differences I didn’t expect you to look at it. Mostly I just want a sense check that I’m heading in the right direction, and whether we’re miles away from a solution or getting close. + +SFC: The reason I asked this question is because it’s a little bit – well, I serve two roles reviewing this spec. One is to check if it’s correct. My other role is determining whether it achieves what we want it to achieve. As of right now, or as of yesterday when I reviewed the code, 173 does not achieve what we wanted to achieve with Intl integration with Decimal. If the goal of the PR is “I’m changing around data types to make another PR later”, that’s fine, but I want to be clear on what I’m actually reviewing. + +JMN: There’s a lot of cleanup I’m doing in response to feedback we’ve gotten recently. My hope is that it’s a lot cleaner. I would say it’s not necessarily the final thing yet, but I guess it’s an honest effort to fix those open gaps that were identified a couple of months ago, as well as to see what is needed for PluralRules. My sense is that not that much is needed for PluralRules, since PluralRules for the things I’m doing just delegates a lot of the work to NumberFormat – not entirely, but largely – and so I’ve fallen back to polishing up the NumberFormat part. One task for me would be to take a look at some of these cases that you’ve given me, and see if I can convince myself that they go through. I can ping you separately to see if it’s ready. But also if there’s other big things for me to know, that would be helpful. + +EAO: One thing that I believe I’ve mentioned previously is that in parallel to the discussion on Decimal and Decimal integration into NumberFormat, there is a discussion that at least I’ve seen SFC pushing for in the MessageFormat context, which is making more consideration for formatting values that contain not just a numerical value, but also additional things around that, so such as in the case of Decimal the information about fractional digits and how many of them there are, but also currencies, the currency units, and other units as well, where the question is what is this a unit of? This makes it interesting for us to consider whether the PluralRules integration of Decimal should be its own thing, or if we should instead design a protocol for input into NumberFormat and PluralRules be able to effectively encode not just a value but which we currently require as options to do the work – such as currency, minimum/maximumFractionDigits, and units. Is there interest, other than just my interest, in considering the design of what this protocol would look like that would also work for Decimal, and that Decimal could use to work with NumberFormat. Or should we consider Decimal specifically, how does this type of information get integrated with NumberFormat. The solutions we’re encountering might be very similar to each other, and we shouldn’t have multiple similar solutions that could be unified. + +JMN: That sounds cool to me. If I recall correctly, BAN and a few other people discussed Decimal and units. Discussing numbers and scales, labeled numbers, also makes sense. TBD, but thank you for the insight. + +USA: I want to second what SFC said earlier, and after that I agree that the PR you made, JMN, is a step in the right direction, but I slightly disagree – I hope this isn’t the last time we’re seeing you – it’s going to be a long time before we standardize all of Decimal. So I want to say it’s good enough in terms of being good enough. I’m wondering if what we have is sufficient for stage 2, which I think it is, and after stage 2 there’s a couple more stages, so we’ll have to keep iterating through the details. It’s the most crucial stage for most proposals in terms of solidifying the API and the options. If we go for something near-perfect right now, that near-perfect thing is going to be going through a lot of iterations anyway. + +SFC: I have responses to these things. First to EAO’s comment, I think that Decimal is a numeric type, and Decimal is a type that should be formattable by Intl.NumberFormat. And that’s enough motivation for having it accepted in NumberFormat.prototype.format. I think there’s going to be an interesting discussion about currencies and other things, but I don’t think that discussion conflicts with just being able to format a Decimal in an Intl.NumberFormat. The second comment was about the trailing zeros and things, I’ve made the case for a long time that this is a justification for an integration of Decimal with NumberFormat and PluralRules. The third thing is that when I do look at the spec, one reason I find JMN’s PR a little hard to review is because I’m not clear on what they’re actually trying to do, and it’s hard for me to review it in terms of “does it do what it’s trying to do.” With code, if I send a PR just to refactor things, that’s fine. But with spec, when you refactor things, it’s a little hard to, out of context, understand the motivation. What anba does is stack normative commits on top of editorial commits, so that I can see what the motivation is for the editorial changes. When you refactor code, it’s mostly harmless, but when you refactor spec it’s not exactly free, because polyfills and such follow along line by line. So editorial changes should have some motivation, in terms of “this makes the normative change easier to make.” something you could consider doing is finish writing the normative change, and that would give me and other reviewers more context when reviewing it. + +JMN: That’s just the feedback I’m looking for. I appreciate the comparison with normal code PRs, that’s very helpful. + +EAO: A bit of procedural clarifying questions. One is that what I asked earlier, about adding BigInt support to PluralRules, is that something that needs to go through the whole staging process or is that something that could be PRed into the spec? It wasn’t clear to me at the beginning which way we’d go with that. + +USA: I think that some people have – basically everyone has their own understanding of what that line is. So size might be one consideration, but for me personally I believe that the decision is mostly about the nature of arguments and discussions that we’re looking forward to. Given the nature of this, that it’s simply a question of completion and symmetry, and it’s fairly straightforward what needs to be done here, I think there’s a way we can get it through. There is a possibility though that if you put in a big normative PR, people will say they have concerns. But in this case I’d say we should do the “ask for forgiveness instead of permission” thing, because if we ask in advance we will absolutely end up with a proposal. + +SFC: I agree with USA. The thing that’s worked the best has been to set the line based on the amount of controversy we expect, since one of the reasons for the staging process is to resolve conflicts/controversies. This is something that we should start as a pull request and bring both to TG1 and TG2, and if there are concerns that people bring up, we’ll then make it a proposal. The other reason is if it’s a large or intricate change, and we need more scrutiny in terms of looking at the corners of the spec. For example, JGT recent work on time zones I encouraged him to make a proposal out of it, even though it’s a fairly small PR. I would say with PluralRules BigInt it’s likely a pull request, but first we should file an issue as step one. + +EAO: As you’re working on almost exactly this but for Decimal, would you be interested in a PR on fixing PluralRules for BigInt, or do you think it’s something someone else should take on? + +JMN: I’m definitely interested, it seems to be a fairly small change, and I’ve been heads-down in this spec for some time. + +EAO: Let’s sync about this offline, I’m very interested because it makes stuff in MessageFormat very complicated, because it’s handling NumberFormat and PluralRules behind a single number function. The other thing is if there’s interest in figuring out if there’s a common protocol we should be designing for, when numbers are coming to NumberFormat as a value rather than an option. Should I set up a call, or does anyone have a better thought for how to take this forward. It seems like it will be a proposal-scale thing. + +SFC: I feel like there’s several items that may be bigger items that may be helpful to jam on together, to figure out what the shape of the proposal would be. StableFormatting’s another one, which has been stalled. And I’d put Intl.MessageFormat in the same bucket with that. That might be a good topic for an in-person TG2 meeting. Alternatively if someone wants to bring a proposal forward at this meeting, well, we mostly discuss proposals and []. I do meet with BAN about once a quarter, in terms of backlog issues and that sort of thing, but I’d like to do it more with other proposals as well. + +JMN: I think I got what I came for. Thanks, everyone! + +### What is the use case of resolvedOptions().functions ? #54 + +https://github.com/tc39/proposal-intl-messageformat/issues/54 + +EAO: I added this to the agenda, so I figured I can present on it. In MessageFormat, we end up with a lot of functions for formatting numbers. [several things that call several other things]. But we’re going to lay out other [?]. And essentially we’re going to have an alternative formatting for calling these, because it’s important that we make these functions somehow available in JavaScript code so that people extending the core set of functions for formatting with their own [?] that may require calling our own formatters. Making the built-in formatters available makes the lives of extension implementers easier. Currently they’re available through creating a MessageFormat object, and then in the resolvedOptions of that there’s an object that you can use. But as FYT quite rightly pointed out, this API is too well-hidden, that it should be readily available. And my preference on this is to add static functions like MessageFormat.number and MessageFormat.dateTime, corresponding to each of the message formatting functions we provide. I wanted to highlight this, and get a discussion around it, and ask this group if this is a sensible way to proceed, or if there is some reason we should be more active in hiding these functions, because of caching or other concerns, that would make it such that we should provide a different interface for accessing these functions. + +FYT: I think we should look at the thing as three different aspects. The first is that MessageFormat have the ability to pass in a custom function to formatters, which I think we is an ability we already have. I’m okay with having a function to override or customize the formatting, I’m okay with that. But the second thing, that I think EAO pointed out, in order for the caller to provide that function it would be easier if there’s a way to get the default implementation as a function and then do some preprocessing or post-processing to write that custom function, instead of the custom functions having to write everything from scratch. It is currently in the spec text, you create a MessageFormat first and then you do something else to get it. I think if you’re doing that, it’s better to define some static class function to hold onto it. I do have some concerns about the naming of the function, which we can discuss later. We need to name it very clearly as a formatting function, which we can talk about, but it needs to be attached to the class. The third thing is whether this thing should be returned by resolvedOptions, because resolveFunction in Intl objects is used to return when we have some complicated resolution of the locale and localedata. In this particular case, where we’re passing a function and returning it, in either case the caller has all the information, and I don’t want the MessageFormat object itself to be able to remember those. But in order to always have in the resolvedOptions some way to expose that, I have concerns. I don’t want resolvedOptions to return that item, that implementations don’t need to carry for an object base. It should be a static function on the class, that’s my opinion. + +USA: I just wanted to say on the first topic, well, not on the first topic, but on the topic of the built-ins and the extensible built-ins, I can understand that it’s an interesting use case, but I didn’t feel very compelled about it already because I couldn’t use it like that so far. But I somewhat agree, and I think that in terms of this being a stage 1 proposal my understanding is that FYT and EAO’s opinions are in the same direction, they’re close enough for a stage 1 proposal to be considered, we have a degree of direction for what we’re doing here. In the case of resolvedOptions, in the 262 side of things we love talking about invariants. And I think in this group we talk about the various invariants in 402, we see resolvedOptions is a way to recreate the constructor (?) – being able to get the resolvedOptions and put them back into the constructor and create exactly the same thing.. If this is going to violate that… + +EAO: Apologies if my signal is bad. So I was going to say the same thing that USA effectively said, about resolvedOptions, in that there is an expectation that you can take what you get from resolvedOptions and plug that back into the input of a format and get something that behaves the same. There are two ways we can handle this. 1) we could return the exact value that the user provided for the functions, compare in exactly the same way as the built-in functions. The way we currently do it, it has the user provided stuff as well as the built in stuff, and if you feed that into another MessageFormat constructor it works. But something I wanted to say that the resolvedOptions that provide the options for cformatting it, and two methods – toString and toParts, and possibly selectKeys that are used when formatting this, as a placeholder in MessageFormat, or selecting one of the options based on it when it is used as a selector in MessageFormat. I don’t think we should have a static message on the MessageFormat class itself that gets the function, rather than having a static function directly on the MessageFormat class (?) + +FYT: For the last part we just have a misunderstanding, I’m not opposed to what you’re saying. + +USA: I have a curiosity, I believe FYT may be able to answer this, or other implementers. If the spec says that it should return the same function that is provided by the user, does it have to have any weight, it doesn’t have to be a clone of the function on the implementation side, but can just be a pointer to the same function? Or am I understanding incorrectly? + +FYT: I’m not that deep into understanding the thing so far, but I can say a couple of things. First, in the past, I don’t think any of the Intl objects take a function in the options bag. We never ever return a function from resolvedOptions, and I think in our implementation those default functions internally are implemented in C++, and so for me to return a resolvedOptions as a function I have to be able go through all the hoops to wrap (?) into a function. So I’m wondering whether that thing should be passed into the constructor or not. That we could discuss. +The other thing, I think I’m a little more questioning, my understanding is that we take an Intl.MessageFormat and we have some options and the options may have various (?). Is that customization per type, or per variable? + +EAO: The current spec requires a Message to explicitly call a function in order for that to be customizable from the outside. There is in the spec currently built-in behavior for Numbers and Strings using the built-in number and string methods, same for DateObject and BigInts as well. There is no way right now to add in new handlers. You can’t add in a custom function and somehow through that definition make it so that if you pass in a variable of a specific type then it gets special handing in MessageFormat, unless the MessageFormat syntax itself explicitly calls what you’re providing as a custom function. + +FYT: Well, let’s say I have two numbers, one called frank, one called tang. Both are numbers. Can you format the default one using the customized one? + +EAO: In the MessageFormat syntax, if they don’t have annotations they get handled the same way. + +FYT: But one with, one without? + +EAO: In the message syntax, yes, this is possible. + +FYT: So you could have differing customizations for different variables, right? + +EAO: So long as the customizations are overloading the [three functions] + +FYT: My question is that is customization binding to a type, or is it binding to a variable? Because the way it seems in the current spec is that you’re binding to the type. + +EAO: the binding is to a name of a function, and then there are types that end up calling functions of a specific range. + +USA: But to clarify, the default ones cannot be written over and customized. + +FYT: My question is if your message has two or three variables for the same type, if you only provide one would that solve that issue? There are ten data types, but three different variables. Would each one of those be able to customize differently? : No – name indicated type of name-indicated variable? + +EAO: We might not be talking about the same thing, and I’d be interested in continuing this, but it seems like it’s a different discussion than where we started. + +FYT: Well the resolvedOptions returns functions, and [?]. Are the key and the value tied to the type, or to the variable. Suppose you return a resolvedOptions that you can pass into the constructor to reconstruct everything. But I wonder if what you already put in the options is already powerful enough for you to that same thing. Because if you’re binding to a particular variable, you might not be able to do that in the current spec. If your passed-in thing is bound to a data type, you might not be able to do this. + +SFC: One concern I have here is that returning functions from resolvedOptions – well, everything we return from resolvedOptions is a primitive, basically. Let’s say you’re returning a non-primitive, a function can change that behaviour, and that’s something we should not be comfortable with. If we really must return functions, we have to isolate it so that you can’t change it and change its behavior. That’s one of the concerns we have with returning a non-primitive with resolvedOptions. I understand the desire to have the same behavior when you pass the options back into the constructor, so we’re not completely consistent on this front. I think that – I can see the argument for why we should put the function there, but I also see the argument that this is an awkward way to access it. There’s a second question, we could add an additional function, either in the way that FYT proposed or how EAO proposed, having a static function. Another question is do we also return them on the resolvedOptions? I need to think about this for a little more before I can be confident in my recommendation one way or another. + +USA: I’ll be super fast. FYT, relating to the playground that we set up fairly recently, it might be useful but it doesn’t support functions yet. But for now at least you can see how it’s doing with these and use the built-in number and date-time functions that could be illustrative of how these things are being used. + +EAO: For me the important thing is finding an ergonomic way to make the function available, so that we can have a richer and more localized format experience for everyone. One thing we could consider – given all the other stuff we’ve done – we could simply remove resolvedOptions altogether. We only have two remaining. If functions are a problem, and we have access to the function otherwise, I’d be comfortable with removing resolvedOptions altogether. + +SFC: That’s an interesting thought. There are good things to consider there. + +### WeekInfoOfLocale need to convert loc.[[FirstDayOfWeek]] to number before return + +https://github.com/tc39/proposal-intl-locale-info/issues/82 + +FYT: The history of this is that Intl.LocaleInfo, we’re getting the first day of the week from an option, but also from -fw. We wanted it to be a string, but then a number, and we discovered that it’s possible for people to construct a locale with a random string. For the locale purpose we could construct and return a string. The problem is that after that there’s a bug in the thing that we store the value of the first day of the week in, and internally we have to access it to be able to use that information to impact the value in the getWeekInfo. And that part, I think the last time we had the PR, we missed that, and somehow it’s reading a string but should return a number, but the spec didn’t do the conversion part. So that’s the first issue, issue 82, we do need to do the conversion. Beside that, in PR 83 it includes that, but in the meantime it also necessarily there’s a different request made by anba earlier on, which is what’s the effect of having a calendar option that’s not ISO, the first day of the week should be Monday, except -fw should have priority. I’ve added that to this PR, but then other people pointed out during the review that we should have the, whenever we get the value we should only look at the language part to get information, because we currently do not handle u-rg regional override. Therefore, we should look only at the locale identifier part, so it will not respect -rg, and we can add it later because currently we don’t support it. Those are three changes related to how the weekInfo of Locale should return. One is [?], and 3rd is to make it tighter and not respect -rg until later we can add it. So we should get agreement on that so that we can take it to TC39. Any questions. + +SFC: My recollection is that the date fields return an integer, and that firstDayOfWeek returns a string. So… what’s the problem? It’s a spec bug, is it hard to fix the spec bug? + +FYT: It’s not, this is the PR to fix the spec bug. It combines three things: it has the spec bug fix, and also anba has mentioned the desire to make the impact of the calendar more explicitly. Initially I think, well, we look at a locale, 8601 has that information. And then he also wanted to make sure that -rg is explicitly not to be impacting this. + +SFC: I’m looking at the PR and I’m a little confused why we do the thing with ISO 8601. So this is fixing an additional issue, not just the string/integer thing. + +FYT: Yes, initially the spec says “I have a locale, I’ll just return a value. If it has ISO 8601, it’ll just return 1.” Anba wanted to make that explicit. + +SFC: At what point does it say that it’s an ILD behavior? The line you’re removing doesn’t say anything about it being implementation and locale dependent. + +FYT: Here, it’s in A. So we did have it as locale-dependent behavior. + +SFC: This is a question for the editors, but: usually when we have this we explicitly say the word “ILD”. Now I understand what it’s doing. + +RGN: One of the things I’d like to do is make it a definition so that the link is explicit. Implementation and locale defined, meaning this is not something where we specify deterministic behavior. + +FYT: Where? + +RGN: It’s literally the phrase “implementation and locale defined” + +FYT: This is the first time I’ve noticed it. What should I do? Something I do in the spec, or something done later on? + +SFC: It’s an editorial thing. + +FYT: Originally what I have in mind is that I don’t need to make things explicit here, but Anba said that we need to make it explicit, so that’s why we’re adding these several lines, to make it explicit. + +LAF: Let me be sure I understand. In ISO 8601 calendar, there is no choice, normally. The first day of week is monday, and the first week is the one with Thursday, something like that. It is defined by ISO, but together with you in several regions the week may begin on another day, and the first week of the year may be different. This is where you want to apply this. So is it linked to a calendar, or? I’m not sure I understand this perfectly. + +FYT: UTS 35 already fixed this, so there is a priority. If nothing got specified in the locale, then the language, region, and script determines what is the first day of week, and what is the minimal day. If somehow there’s a calendar specified, and the calendar is explicitly saying it’s ISO 8601, we set it to Sunday regardless of the region code, and the minimum days for the first week need to be four days. And if the locale also has an -fw parameter, then it overrides that. So let’s say I say the first day of week is Wednesday, and it will always be Wednesday regardless of whether it’s UTS 35 (ISO 8601?) Then if there’s somehow a region override, -rg, then we have a priority somewhere, I forget the order, but we currently don’t have support for -rg. So that’s what this is. change is about. If a locale explicitly has -ca, and -fw, and iso8601, what do we do? Anba wanted to make this very explicitly. + +SFC: I think that if we, I think what’s written is correct. I just opened the issue about using ILD more consistently. I think it works for what LAF said, and it’s not a normative change. + +FYT: It’s arguable whether it’s a normative change, because anba could say “hey, originally it may not be that way.” Whenever you change something from implicitly defined it becomes normative. + +SFC: Right now it says with values based on locale, we change that to “implemented in locale-defined values” + +FYT: Arguably this is normative, because we have an explicit statement of ISO8601. + +SFC: Technically this doesn’t allow locales to vary what they return, which is odd. I think we should decouple these. Actually – why did you change it to be based on language_id instead of locale? + +FYT: That’s Anba’s patch – if I do that, then it will listen to -rg. + +SFC: We want it to listen to -rg, but also -ca? + +FYT: We don’t want it to listen to -rg until -rg is supported. It does listen to -ca + +SFC: It doesn’t, though. If you have en-u-ca-hebrew, that doesn’t change that. I think LAF’s argument is that the calendar system can definitely have an effect on first day of week. + +FYT: Does it? Which one? + +LAF: Oh yes, ISO 8601 does, and Hebrew does. In Hebrew the first day of the week is Sunday. The way you express, Hebrew you express the first day as Sunday. + +SFC: Even if you’re in a region, say France, and you have a gregorian calendar hanging on your wall it starts Monday, but if you have a Hebrew one it starts on Sunday. + +LAF: And there can be some changes in the culture. Essentially the week may be defined with the calendar, in fact the week is not defined with the Gregorian calendar – but with ISO 8601 it is! + +FYT: I currently do not believe – well, here’s another complication – I don’t think ICU’s implementation will change if you have ‘fr-u-ca-hebrew’. + +SFC: It could be the case that ICU is buggy, but that doesn’t mean we should forbid it in the spec. + +FYT: So we need to probably put this on hold if that is the case. + +SFC: I think, FYT, you can, I think you should put on the TG1 agenda the version of the PR that doesn’t do the additional Anba change. + +FYT: Let me do this: I will not change these several lines, I will only change the conversion lines. + +SFC: And you can do the ISO 8601 check. There’s three changes in these seven lines of code: the fix about returning an integer, that’s good, there’s the fix about hard-coding ISO 8601, and then there’s the fix that we can only rely on language_id when determining the first day of week. But you can keep the ISO 8601 section. + +FYT: I got it! Okay! So I’ll revert that last part. + +### TG1 Agenda Review + +BAN to add https://github.com/tc39/ecma402/pull/780 + +BAN has added https://github.com/tc39/ecma402/pull/908 + +BAN to update https://github.com/tc39/ecma402/pull/839 to be a note + +BAN to double-check if https://github.com/tc39/proposal-intl-duration-format/pull/207 needs to be added + +BAN has verified: https://github.com/tc39/proposal-intl-duration-format/pull/198 was approved in June + +FYT to add https://github.com/tc39/proposal-intl-locale-info/pull/83 after it is updated + +### Data-driven approach + +https://github.com/tc39/proposal-intl-eradisplay/issues/9 + +(after meeting deep dive) diff --git a/package-lock.json b/package-lock.json index 25992679..251dee13 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,8 @@ "version": "9.0.0", "license": "SEE LICENSE IN https://tc39.es/ecma402/#sec-copyright-and-software-license", "dependencies": { - "@tc39/ecma262-biblio": "2.1.2678", - "ecmarkup": "^18.1.2" + "@tc39/ecma262-biblio": "2.1.2742", + "ecmarkup": "^19.0.0" } }, "node_modules/@babel/code-frame": { @@ -99,80 +99,38 @@ } }, "node_modules/@esfx/async-canceltoken": { - "version": "1.0.0-pre.30", - "resolved": "https://registry.npmjs.org/@esfx/async-canceltoken/-/async-canceltoken-1.0.0-pre.30.tgz", - "integrity": "sha512-4he0W+ZKH4OO4RvGfmATIibO5JzGLQqwm4Dp3X15bWnguDTmmOFt3Qt169Doij/gXxn2aPpZvxUaYIEebi8Xig==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@esfx/async-canceltoken/-/async-canceltoken-1.0.0.tgz", + "integrity": "sha512-3Ps/4NPd7qFltmHL+CYXCjZtNXcQGV9BZmpzu8Rt3/0SZMtbQve0gtX0uJDJGvAWa6w3IB4HrKVP12VPoFONmA==", "dependencies": { - "@esfx/cancelable": "^1.0.0-pre.30", - "@esfx/collections-linkedlist": "^1.0.0-pre.24", - "@esfx/disposable": "^1.0.0-pre.30", - "@esfx/internal-guards": "^1.0.0-pre.23", - "@esfx/internal-tag": "^1.0.0-pre.19", - "tslib": "^2.1.0" + "@esfx/cancelable": "^1.0.0", + "@esfx/canceltoken": "^1.0.0", + "@esfx/disposable": "^1.0.0", + "tslib": "^2.4.0" } }, "node_modules/@esfx/cancelable": { - "version": "1.0.0-pre.30", - "resolved": "https://registry.npmjs.org/@esfx/cancelable/-/cancelable-1.0.0-pre.30.tgz", - "integrity": "sha512-fo0+/D3tEcSOHdZ8HiCR7qOKl5Tkk6Nw6QJNNXSQ0ejlpP3HU4S2i0rb/tjHQ1EkUcWZfB3g2jzfL0ioQSEgGg==", - "dependencies": { - "@esfx/disposable": "^1.0.0-pre.30", - "@esfx/internal-deprecate": "^1.0.0-pre.24", - "@esfx/internal-guards": "^1.0.0-pre.23", - "@esfx/internal-tag": "^1.0.0-pre.19" - } - }, - "node_modules/@esfx/collection-core": { - "version": "1.0.0-pre.24", - "resolved": "https://registry.npmjs.org/@esfx/collection-core/-/collection-core-1.0.0-pre.24.tgz", - "integrity": "sha512-OIgMS91JmjSoRWD7u/DfnDzo8vDggeTeUPRi1p5WhyboY0+IwmetEqgeHZb8bpka/SsmtYX5qxqEjeqNXqh+pA==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@esfx/cancelable/-/cancelable-1.0.0.tgz", + "integrity": "sha512-2dry/TuOT9ydpw86f396v09cyi/gLeGPIZSH4Gx+V/qKQaS/OXCRurCY+Cn8zkBfTAgFsjk9NE15d+LPo2kt9A==", "dependencies": { - "@esfx/internal-deprecate": "^1.0.0-pre.24", - "@esfx/internal-guards": "^1.0.0-pre.23" + "@esfx/disposable": "^1.0.0" } }, - "node_modules/@esfx/collections-linkedlist": { - "version": "1.0.0-pre.24", - "resolved": "https://registry.npmjs.org/@esfx/collections-linkedlist/-/collections-linkedlist-1.0.0-pre.24.tgz", - "integrity": "sha512-Maya8jXH0xvzyfeSH88/j2b5gavO/mluslgIC2Ttdz8rh6+3o8/pVYriceH/Jinn4pgTEzDhO6Rn/aruZG0+Ug==", + "node_modules/@esfx/canceltoken": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@esfx/canceltoken/-/canceltoken-1.0.0.tgz", + "integrity": "sha512-/TgdzC5O89w5v0TgwE2wcdtampWNAFOxzurCtb4RxYVr3m72yk3Bg82vMdznx+H9nnf28zVDR0PtpZO9FxmOkw==", "dependencies": { - "@esfx/collection-core": "^1.0.0-pre.24", - "@esfx/equatable": "^1.0.0-pre.19", - "@esfx/internal-guards": "^1.0.0-pre.23" + "@esfx/cancelable": "^1.0.0", + "@esfx/disposable": "^1.0.0", + "tslib": "^2.4.0" } }, "node_modules/@esfx/disposable": { - "version": "1.0.0-pre.30", - "resolved": "https://registry.npmjs.org/@esfx/disposable/-/disposable-1.0.0-pre.30.tgz", - "integrity": "sha512-njBGIQO+HW+lMqqMjURC+MWn+55ufulgebPLXzlxbwVSz5hZkoCsv6n9sIBQbnvg/PYQmWK5Dk6gDSmFfihTUg==" - }, - "node_modules/@esfx/equatable": { - "version": "1.0.0-pre.19", - "resolved": "https://registry.npmjs.org/@esfx/equatable/-/equatable-1.0.0-pre.19.tgz", - "integrity": "sha512-+f6Xm6GOigyGx7t0D0IyG9Z0AuYDhNWjwV49vs5uNG/+0VQAOSYjmnpSzTZRYcYwxW52DmWJWFYNY8bvCDD2ag==" - }, - "node_modules/@esfx/internal-deprecate": { - "version": "1.0.0-pre.24", - "resolved": "https://registry.npmjs.org/@esfx/internal-deprecate/-/internal-deprecate-1.0.0-pre.24.tgz", - "integrity": "sha512-TSU5k04+nuVQdyfYhaVXxyskdiwYQHgwN20J3cbyRrm/YFi2dOoFSLFvkMNh7LNOPGWSOg6pfAm3kd23ISR3Ow==" - }, - "node_modules/@esfx/internal-guards": { - "version": "1.0.0-pre.23", - "resolved": "https://registry.npmjs.org/@esfx/internal-guards/-/internal-guards-1.0.0-pre.23.tgz", - "integrity": "sha512-y2svuwRERA2eKF1T/Stq+O8kPjicFQcUTob5je3L6iloOHnOD0sX6aQLvheWmTXXS7hAnjlyMeSN/ec84BRyHg==", - "dependencies": { - "@esfx/type-model": "^1.0.0-pre.23" - } - }, - "node_modules/@esfx/internal-tag": { - "version": "1.0.0-pre.19", - "resolved": "https://registry.npmjs.org/@esfx/internal-tag/-/internal-tag-1.0.0-pre.19.tgz", - "integrity": "sha512-/v1D5LfvBnbvHzL22Vh6yobrOTVCBhsW/l9M+/GRA51eqCN27yTmWGaYUSd1QXp2vxHwNr0sfckVoNtTzeaIqQ==" - }, - "node_modules/@esfx/type-model": { - "version": "1.0.0-pre.23", - "resolved": "https://registry.npmjs.org/@esfx/type-model/-/type-model-1.0.0-pre.23.tgz", - "integrity": "sha512-jwcSY9pqEmGoDNhfT+0LUmSTyk6zXF/pbgKb7KU7mTfCrWfVCT/ve61cD1CreerDRBSat/s55se0lJXwDSjhuA==" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@esfx/disposable/-/disposable-1.0.0.tgz", + "integrity": "sha512-hu7EI+YxlEWEKrb2himbS13HNaq5mlUePASf99KeQqkiNeqiAZbKqG4w59uDcLZs8JrV3qJqS/NYib5ZMhbfTQ==" }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", @@ -207,9 +165,9 @@ } }, "node_modules/@tc39/ecma262-biblio": { - "version": "2.1.2678", - "resolved": "https://registry.npmjs.org/@tc39/ecma262-biblio/-/ecma262-biblio-2.1.2678.tgz", - "integrity": "sha512-3I6m+wpNSHuQsJjeH3UgfqUaet1aM/9ReeWJH8H1H+DKLHfQafWK+OHQLgUbpd5ruJveC2AbyKuUVsXrtMV3Bw==" + "version": "2.1.2742", + "resolved": "https://registry.npmjs.org/@tc39/ecma262-biblio/-/ecma262-biblio-2.1.2742.tgz", + "integrity": "sha512-nWPDshWKzcEMXpNNzhBud9X39KzP2PLhIoENAIhQsfmXc+jAFzWIY4Z1B3+oChU1U5X46yHcyYd8PZY/pro2BA==" }, "node_modules/@tootallnate/once": { "version": "2.0.0", @@ -500,9 +458,9 @@ } }, "node_modules/ecmarkup": { - "version": "18.1.2", - "resolved": "https://registry.npmjs.org/ecmarkup/-/ecmarkup-18.1.2.tgz", - "integrity": "sha512-HqQXcUlmz66D2dGKEFcfApAftzTQfjjHrScccGmbFjuDjf82HQVBCX4vVwUnWpkVki2ioTDZUIvG8AVvRZg31g==", + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/ecmarkup/-/ecmarkup-19.0.0.tgz", + "integrity": "sha512-ncn5LXs46jPqcQSO/XdJCOOsdAvC8xT/Yebxted4qgpYWLisY4AEdOdZ4OXKgmPXGgWBqAgCSoV0obvEBEz8Hg==", "dependencies": { "chalk": "^4.1.2", "command-line-args": "^5.2.0", @@ -511,7 +469,7 @@ "ecmarkdown": "^8.1.0", "eslint-formatter-codeframe": "^7.32.1", "fast-glob": "^3.2.7", - "grammarkdown": "^3.2.0", + "grammarkdown": "^3.3.2", "highlight.js": "11.0.1", "html-escape": "^1.0.2", "js-yaml": "^3.13.1", @@ -938,12 +896,13 @@ } }, "node_modules/grammarkdown": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/grammarkdown/-/grammarkdown-3.2.0.tgz", - "integrity": "sha512-pEVUvG2Kxv/PwM3Dm3kFEU1/GHRkNcFWmk/zkqN/y0uoQtPaZ+5VaBacMQAaFOIL9WGYjHXtqpkT5YRvySsISQ==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/grammarkdown/-/grammarkdown-3.3.2.tgz", + "integrity": "sha512-inNbeEotDr7MENqoZlms3x4gBzvK73wR2NGpNVnw4oEZcsq2METUbAh0J3VWtEqd9t2+U3poEqiJ9CDgBXr5Tg==", "dependencies": { "@esfx/async-canceltoken": "^1.0.0-pre.13", - "@esfx/cancelable": "^1.0.0-pre.13" + "@esfx/cancelable": "^1.0.0-pre.13", + "@esfx/disposable": "^1.0.0-pre.13" }, "bin": { "grammarkdown": "bin/grammarkdown" @@ -1312,9 +1271,9 @@ } }, "node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/type-check": { "version": "0.3.2", @@ -1456,80 +1415,38 @@ } }, "@esfx/async-canceltoken": { - "version": "1.0.0-pre.30", - "resolved": "https://registry.npmjs.org/@esfx/async-canceltoken/-/async-canceltoken-1.0.0-pre.30.tgz", - "integrity": "sha512-4he0W+ZKH4OO4RvGfmATIibO5JzGLQqwm4Dp3X15bWnguDTmmOFt3Qt169Doij/gXxn2aPpZvxUaYIEebi8Xig==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@esfx/async-canceltoken/-/async-canceltoken-1.0.0.tgz", + "integrity": "sha512-3Ps/4NPd7qFltmHL+CYXCjZtNXcQGV9BZmpzu8Rt3/0SZMtbQve0gtX0uJDJGvAWa6w3IB4HrKVP12VPoFONmA==", "requires": { - "@esfx/cancelable": "^1.0.0-pre.30", - "@esfx/collections-linkedlist": "^1.0.0-pre.24", - "@esfx/disposable": "^1.0.0-pre.30", - "@esfx/internal-guards": "^1.0.0-pre.23", - "@esfx/internal-tag": "^1.0.0-pre.19", - "tslib": "^2.1.0" + "@esfx/cancelable": "^1.0.0", + "@esfx/canceltoken": "^1.0.0", + "@esfx/disposable": "^1.0.0", + "tslib": "^2.4.0" } }, "@esfx/cancelable": { - "version": "1.0.0-pre.30", - "resolved": "https://registry.npmjs.org/@esfx/cancelable/-/cancelable-1.0.0-pre.30.tgz", - "integrity": "sha512-fo0+/D3tEcSOHdZ8HiCR7qOKl5Tkk6Nw6QJNNXSQ0ejlpP3HU4S2i0rb/tjHQ1EkUcWZfB3g2jzfL0ioQSEgGg==", - "requires": { - "@esfx/disposable": "^1.0.0-pre.30", - "@esfx/internal-deprecate": "^1.0.0-pre.24", - "@esfx/internal-guards": "^1.0.0-pre.23", - "@esfx/internal-tag": "^1.0.0-pre.19" - } - }, - "@esfx/collection-core": { - "version": "1.0.0-pre.24", - "resolved": "https://registry.npmjs.org/@esfx/collection-core/-/collection-core-1.0.0-pre.24.tgz", - "integrity": "sha512-OIgMS91JmjSoRWD7u/DfnDzo8vDggeTeUPRi1p5WhyboY0+IwmetEqgeHZb8bpka/SsmtYX5qxqEjeqNXqh+pA==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@esfx/cancelable/-/cancelable-1.0.0.tgz", + "integrity": "sha512-2dry/TuOT9ydpw86f396v09cyi/gLeGPIZSH4Gx+V/qKQaS/OXCRurCY+Cn8zkBfTAgFsjk9NE15d+LPo2kt9A==", "requires": { - "@esfx/internal-deprecate": "^1.0.0-pre.24", - "@esfx/internal-guards": "^1.0.0-pre.23" + "@esfx/disposable": "^1.0.0" } }, - "@esfx/collections-linkedlist": { - "version": "1.0.0-pre.24", - "resolved": "https://registry.npmjs.org/@esfx/collections-linkedlist/-/collections-linkedlist-1.0.0-pre.24.tgz", - "integrity": "sha512-Maya8jXH0xvzyfeSH88/j2b5gavO/mluslgIC2Ttdz8rh6+3o8/pVYriceH/Jinn4pgTEzDhO6Rn/aruZG0+Ug==", + "@esfx/canceltoken": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@esfx/canceltoken/-/canceltoken-1.0.0.tgz", + "integrity": "sha512-/TgdzC5O89w5v0TgwE2wcdtampWNAFOxzurCtb4RxYVr3m72yk3Bg82vMdznx+H9nnf28zVDR0PtpZO9FxmOkw==", "requires": { - "@esfx/collection-core": "^1.0.0-pre.24", - "@esfx/equatable": "^1.0.0-pre.19", - "@esfx/internal-guards": "^1.0.0-pre.23" + "@esfx/cancelable": "^1.0.0", + "@esfx/disposable": "^1.0.0", + "tslib": "^2.4.0" } }, "@esfx/disposable": { - "version": "1.0.0-pre.30", - "resolved": "https://registry.npmjs.org/@esfx/disposable/-/disposable-1.0.0-pre.30.tgz", - "integrity": "sha512-njBGIQO+HW+lMqqMjURC+MWn+55ufulgebPLXzlxbwVSz5hZkoCsv6n9sIBQbnvg/PYQmWK5Dk6gDSmFfihTUg==" - }, - "@esfx/equatable": { - "version": "1.0.0-pre.19", - "resolved": "https://registry.npmjs.org/@esfx/equatable/-/equatable-1.0.0-pre.19.tgz", - "integrity": "sha512-+f6Xm6GOigyGx7t0D0IyG9Z0AuYDhNWjwV49vs5uNG/+0VQAOSYjmnpSzTZRYcYwxW52DmWJWFYNY8bvCDD2ag==" - }, - "@esfx/internal-deprecate": { - "version": "1.0.0-pre.24", - "resolved": "https://registry.npmjs.org/@esfx/internal-deprecate/-/internal-deprecate-1.0.0-pre.24.tgz", - "integrity": "sha512-TSU5k04+nuVQdyfYhaVXxyskdiwYQHgwN20J3cbyRrm/YFi2dOoFSLFvkMNh7LNOPGWSOg6pfAm3kd23ISR3Ow==" - }, - "@esfx/internal-guards": { - "version": "1.0.0-pre.23", - "resolved": "https://registry.npmjs.org/@esfx/internal-guards/-/internal-guards-1.0.0-pre.23.tgz", - "integrity": "sha512-y2svuwRERA2eKF1T/Stq+O8kPjicFQcUTob5je3L6iloOHnOD0sX6aQLvheWmTXXS7hAnjlyMeSN/ec84BRyHg==", - "requires": { - "@esfx/type-model": "^1.0.0-pre.23" - } - }, - "@esfx/internal-tag": { - "version": "1.0.0-pre.19", - "resolved": "https://registry.npmjs.org/@esfx/internal-tag/-/internal-tag-1.0.0-pre.19.tgz", - "integrity": "sha512-/v1D5LfvBnbvHzL22Vh6yobrOTVCBhsW/l9M+/GRA51eqCN27yTmWGaYUSd1QXp2vxHwNr0sfckVoNtTzeaIqQ==" - }, - "@esfx/type-model": { - "version": "1.0.0-pre.23", - "resolved": "https://registry.npmjs.org/@esfx/type-model/-/type-model-1.0.0-pre.23.tgz", - "integrity": "sha512-jwcSY9pqEmGoDNhfT+0LUmSTyk6zXF/pbgKb7KU7mTfCrWfVCT/ve61cD1CreerDRBSat/s55se0lJXwDSjhuA==" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@esfx/disposable/-/disposable-1.0.0.tgz", + "integrity": "sha512-hu7EI+YxlEWEKrb2himbS13HNaq5mlUePASf99KeQqkiNeqiAZbKqG4w59uDcLZs8JrV3qJqS/NYib5ZMhbfTQ==" }, "@nodelib/fs.scandir": { "version": "2.1.5", @@ -1555,9 +1472,9 @@ } }, "@tc39/ecma262-biblio": { - "version": "2.1.2678", - "resolved": "https://registry.npmjs.org/@tc39/ecma262-biblio/-/ecma262-biblio-2.1.2678.tgz", - "integrity": "sha512-3I6m+wpNSHuQsJjeH3UgfqUaet1aM/9ReeWJH8H1H+DKLHfQafWK+OHQLgUbpd5ruJveC2AbyKuUVsXrtMV3Bw==" + "version": "2.1.2742", + "resolved": "https://registry.npmjs.org/@tc39/ecma262-biblio/-/ecma262-biblio-2.1.2742.tgz", + "integrity": "sha512-nWPDshWKzcEMXpNNzhBud9X39KzP2PLhIoENAIhQsfmXc+jAFzWIY4Z1B3+oChU1U5X46yHcyYd8PZY/pro2BA==" }, "@tootallnate/once": { "version": "2.0.0", @@ -1781,9 +1698,9 @@ } }, "ecmarkup": { - "version": "18.1.2", - "resolved": "https://registry.npmjs.org/ecmarkup/-/ecmarkup-18.1.2.tgz", - "integrity": "sha512-HqQXcUlmz66D2dGKEFcfApAftzTQfjjHrScccGmbFjuDjf82HQVBCX4vVwUnWpkVki2ioTDZUIvG8AVvRZg31g==", + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/ecmarkup/-/ecmarkup-19.0.0.tgz", + "integrity": "sha512-ncn5LXs46jPqcQSO/XdJCOOsdAvC8xT/Yebxted4qgpYWLisY4AEdOdZ4OXKgmPXGgWBqAgCSoV0obvEBEz8Hg==", "requires": { "chalk": "^4.1.2", "command-line-args": "^5.2.0", @@ -1792,7 +1709,7 @@ "ecmarkdown": "^8.1.0", "eslint-formatter-codeframe": "^7.32.1", "fast-glob": "^3.2.7", - "grammarkdown": "^3.2.0", + "grammarkdown": "^3.3.2", "highlight.js": "11.0.1", "html-escape": "^1.0.2", "js-yaml": "^3.13.1", @@ -2093,12 +2010,13 @@ } }, "grammarkdown": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/grammarkdown/-/grammarkdown-3.2.0.tgz", - "integrity": "sha512-pEVUvG2Kxv/PwM3Dm3kFEU1/GHRkNcFWmk/zkqN/y0uoQtPaZ+5VaBacMQAaFOIL9WGYjHXtqpkT5YRvySsISQ==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/grammarkdown/-/grammarkdown-3.3.2.tgz", + "integrity": "sha512-inNbeEotDr7MENqoZlms3x4gBzvK73wR2NGpNVnw4oEZcsq2METUbAh0J3VWtEqd9t2+U3poEqiJ9CDgBXr5Tg==", "requires": { "@esfx/async-canceltoken": "^1.0.0-pre.13", - "@esfx/cancelable": "^1.0.0-pre.13" + "@esfx/cancelable": "^1.0.0-pre.13", + "@esfx/disposable": "^1.0.0-pre.13" } }, "has-flag": { @@ -2359,9 +2277,9 @@ } }, "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "type-check": { "version": "0.3.2", diff --git a/package.json b/package.json index ba8c825b..b9b516e5 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "license": "SEE LICENSE IN https://tc39.es/ecma402/#sec-copyright-and-software-license", "homepage": "https://tc39.es/ecma402/", "dependencies": { - "ecmarkup": "^18.1.2", - "@tc39/ecma262-biblio": "2.1.2678" + "ecmarkup": "^19.0.0", + "@tc39/ecma262-biblio": "2.1.2742" } } diff --git a/spec/annexes.html b/spec/annexes.html index 4aab6077..e23ab569 100644 --- a/spec/annexes.html +++ b/spec/annexes.html @@ -27,7 +27,7 @@

Implementation Dependent Behaviour

In Collator: + +

DateTime Format Records

+ +

+ Each DateTime Format Record has the fields defined in . +

+ + DateTime Format Record + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameValue TypeDescription
[[weekday]][[Weekday]] values in the Values column of Optional field. Present if [[pattern]] contains the substring *"{weekday}"*.
[[era]][[Era]] values in the Values column of Optional field. Present if [[pattern]] contains the substring *"{era}"*.
[[year]][[Year]] values in the Values column of Optional field. Present if [[pattern]] contains at least one of the substrings *"{year}"*, *"{yearName}"*, or *"{relatedYear}"*.
[[month]][[Month]] values in the Values column of Optional field. Present if [[pattern]] contains the substring *"{month}"*.
[[day]][[Day]] values in the Values column of Optional field. Present if [[pattern]] contains the substring *"{day}"*.
[[dayPeriod]][[DayPeriod]] values in the Values column of Optional field. Present if [[pattern]] contains the substring *"{dayPeriod}"*.
[[hour]][[Hour]] values in the Values column of Optional field. Present if [[pattern]] contains the substring *"{hour}"*.
[[minute]][[Minute]] values in the Values column of Optional field. Present if [[pattern]] contains the substring *"{minute}"*.
[[second]][[Second]] values in the Values column of Optional field. Present if [[pattern]] contains the substring *"{second}"*.
[[fractionalSecondDigits]][[FractionalSecondDigits]] values in the Values column of Optional field. Present if [[pattern]] contains the substring *"{fractionalSecondDigits}"*.
[[timeZoneName]][[TimeZoneName]] values in the Values column of Optional field. Present if [[pattern]] contains the substring *"{timeZoneName}"*.
[[pattern]]a Pattern StringContains for each of the date and time format component fields of the record a substring starting with *"{"*, followed by the name of the field, followed by *"}"*. If the record has a [[year]] field, the string may contain the substrings *"{yearName}"* and *"{relatedYear}"*.
[[pattern12]]a Pattern StringOptional field. Present if the [[hour]] field is present. In addition to the substrings of the [[pattern]] field, contains at least one of the substrings *"{ampm}"* or *"{dayPeriod}"*.
[[rangePatterns]]a DateTime Range Pattern RecordPattern strings in this field are similar to [[pattern]].
[[rangePatterns12]]a DateTime Range Pattern RecordOptional field. Present if the [[hour]] field is present. Pattern strings in this field are similar to [[pattern12]].
+
+
+ + +

DateTime Range Pattern Records

+ +

+ Each DateTime Range Pattern Record has the fields defined in . +

+ + DateTime Range Pattern Record + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameValue TypeDescription
[[Default]]a DateTime Range Pattern Format RecordIt contains the default range pattern used when a more specific range pattern is not available.
[[Era]]a DateTime Range Pattern Format RecordOptional field. Used when era is the largest calendar element that is different between the start and end dates.
[[Year]]a DateTime Range Pattern Format RecordOptional field. Used when year is the largest calendar element that is different between the start and end dates.
[[Month]]a DateTime Range Pattern Format RecordOptional field. Used when month is the largest calendar element that is different between the start and end dates.
[[Day]]a DateTime Range Pattern Format RecordOptional field. Used when day is the largest calendar element that is different between the start and end dates.
[[AmPm]]a DateTime Range Pattern Format RecordOptional field. Used when ante or post meridiem is the largest calendar element that is different between the start and end dates.
[[DayPeriod]]a DateTime Range Pattern Format RecordOptional field. Used when day period is the largest calendar element that is different between the start and end dates.
[[Hour]]a DateTime Range Pattern Format RecordOptional field. Used when hour is the largest calendar element that is different between the start and end dates.
[[Minute]]a DateTime Range Pattern Format RecordOptional field. Used when minute is the largest calendar element that is different between the start and end dates.
[[Second]]a DateTime Range Pattern Format RecordOptional field. Used when second is the largest calendar element that is different between the start and end dates.
[[FractionalSecondDigits]]a DateTime Range Pattern Format RecordOptional field. Used when fractional seconds are the largest calendar element that is different between the start and end dates.
+
+
+ + +

DateTime Range Pattern Format Records

+ +

+ Each DateTime Range Pattern Format Record has the fields defined in . +

+ + DateTime Range Pattern Format Record + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameValue TypeDescription
[[weekday]][[Weekday]] values in the Values column of Optional field. Present if a Pattern String in [[PatternParts]] contains the substring *"{weekday}"*.
[[era]][[Era]] values in the Values column of Optional field. Present if a Pattern String in [[PatternParts]] contains the substring *"{era}"*.
[[year]][[Year]] values in the Values column of Optional field. Present if a Pattern String in [[PatternParts]] contains at least one of the substrings *"{year}"*, *"{yearName}"*, or *"{relatedYear}"*.
[[month]][[Month]] values in the Values column of Optional field. Present if a Pattern String in [[PatternParts]] contains the substring *"{month}"*.
[[day]][[Day]] values in the Values column of Optional field. Present if a Pattern String in [[PatternParts]] contains the substring *"{day}"*.
[[dayPeriod]][[DayPeriod]] values in the Values column of Optional field. Present if a Pattern String in [[PatternParts]] contains the substring *"{dayPeriod}"*.
[[hour]][[Hour]] values in the Values column of Optional field. Present if a Pattern String in [[PatternParts]] contains the substring *"{hour}"*.
[[minute]][[Minute]] values in the Values column of Optional field. Present if a Pattern String in [[PatternParts]] contains the substring *"{minute}"*.
[[second]][[Second]] values in the Values column of Optional field. Present if a Pattern String in [[PatternParts]] contains the substring *"{second}"*.
[[fractionalSecondDigits]][[FractionalSecondDigits]] values in the Values column of Optional field. Present if a Pattern String in [[PatternParts]] contains the substring *"{fractionalSecondDigits}"*.
[[timeZoneName]][[TimeZoneName]] values in the Values column of Optional field. Present if a Pattern String in [[PatternParts]] contains the substring *"{timeZoneName}"*.
[[PatternParts]]a List of DateTime Range Pattern Part RecordsEach record represents a part of the range pattern.
+
+
+ + +

DateTime Range Pattern Part Records

+ +

+ Each DateTime Range Pattern Part Record has the fields defined in . +

+ + DateTime Range Pattern Part Record + + + + + + + + + + + + + + + + + + +
Field NameValue TypeDescription
[[Source]]*"shared"*, *"startRange"*, or *"endRange"*It indicates which of the range's dates should be formatted using the value of the [[Pattern]] field.
[[Pattern]]a Pattern StringA String of the same format as the regular date pattern String.
+
+
+ + +

DateTime Styles Records

+ +

+ Each DateTime Styles Record has the fields defined in . +

+ + DateTime Styles Record + + + + + + + + + + + + + + + + + + + + + + + +
Field NameValue Type
[[Date]]a DateTime Style Record
[[Time]]a DateTime Style Record
[[Connector]]a DateTime Connector Record
[[DateTimeRangeFormat]]a DateTime Date Range Record
+
+
+ + +

DateTime Style Records

+ +

+ Each DateTime Style Record has the fields defined in . +

+ + DateTime Style Record + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameValue TypeDescription
[[full]]a DateTime Format RecordFormat record for the *"full"* style.
[[long]]a DateTime Format RecordFormat record for the *"long"* style.
[[medium]]a DateTime Format RecordFormat record for the *"medium"* style.
[[short]]a DateTime Format RecordFormat record for the *"short"* style.
+
+
+ + +

DateTime Connector Records

+ +

+ Each DateTime Connector Record has the fields defined in . All connector pattern strings must contain the strings *"{0}"* and *"{1}"*. +

+ + DateTime Connector Record + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameValue TypeDescription
[[full]]a Pattern StringConnector pattern when the date style is *"full"*.
[[long]]a Pattern StringConnector pattern when the date style is *"long"*.
[[medium]]a Pattern StringConnector pattern when the date style is *"medium"*.
[[short]]a Pattern StringConnector pattern when the date style is *"short"*.
+
+
+ + +

DateTime Date Range Records

+ +

+ Each DateTime Date Range Record has the fields defined in . +

+ + DateTime Date Range Record + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameValue TypeDescription
[[full]]a DateTime Time Range RecordUsed when date style is *"full"*.
[[long]]a DateTime Time Range RecordUsed when date style is *"long"*.
[[medium]]a DateTime Time Range RecordUsed when date style is *"medium"*.
[[short]]a DateTime Time Range RecordUsed when date style is *"short"*.
+
+
+ + +

DateTime Time Range Records

+ +

+ Each DateTime Time Range Record has the fields defined in . +

+ + DateTime Time Range Record + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameValue TypeDescription
[[full]]a DateTime Style Range RecordUsed when time style is *"full"*.
[[long]]a DateTime Style Range RecordUsed when time style is *"long"*.
[[medium]]a DateTime Style Range RecordUsed when time style is *"medium"*.
[[short]]a DateTime Style Range RecordUsed when time style is *"short"*.
+
+
+ + +

DateTime Style Range Records

+ +

+ Each DateTime Style Range Record has the fields defined in . +

+ + DateTime Style Range Record + + + + + + + + + + + + + + + + + + +
Field NameValue TypeDescription
[[rangePatterns]]a DateTime Range Pattern RecordRange patterns to combine date and time styles.
[[rangePatterns12]]a DateTime Range Pattern RecordOptional Field. Range patterns to combine date and time styles for 12-hour formats.
+
+
+ - For example, an implementation might include the following record as part of its English locale data: + For example, an implementation might include the following Record as part of its English locale data: @@ -408,60 +876,6 @@

Internal slots

It is recommended that implementations use the locale data provided by the Common Locale Data Repository (available at https://cldr.unicode.org/). - - - Range pattern fields - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Range Pattern FieldPattern String Field
[[Era]]*"era"*
[[Year]]*"year"*
[[Month]]*"month"*
[[Day]]*"day"*
[[AmPm]]*"ampm"*
[[DayPeriod]]*"dayPeriod"*
[[Hour]]*"hour"*
[[Minute]]*"minute"*
[[Second]]*"second"*
[[FractionalSecondDigits]]*"fractionalSecondDigits"*
- -
@@ -480,11 +894,11 @@

Intl.DateTimeFormat.prototype.constructor

- -

Intl.DateTimeFormat.prototype [ @@toStringTag ]

+ +

Intl.DateTimeFormat.prototype [ %Symbol.toStringTag% ]

- The initial value of the @@toStringTag property is the String value *"Intl.DateTimeFormat"*. + The initial value of the %Symbol.toStringTag% property is the String value *"Intl.DateTimeFormat"*.

@@ -583,11 +997,15 @@

Intl.DateTimeFormat.prototype.resolvedOptions ( )

1. Perform ? RequireInternalSlot(_dtf_, [[InitializedDateTimeFormat]]). 1. Let _options_ be OrdinaryObjectCreate(%Object.prototype%). 1. For each row of , except the header row, in table order, do - 1. Let _v_ be the value of _dtf_'s internal slot whose name is the Internal Slot value of the current row. 1. Let _p_ be the Property value of the current row. - 1. If the Internal Slot value of the current row is an Internal Slot value in , then - 1. If _dtf_.[[DateStyle]] is not *undefined* or _dtf_.[[TimeStyle]] is not *undefined*, then - 1. Set _v_ to *undefined*. + 1. If there is an Internal Slot value in the current row, then + 1. Let _v_ be the value of _dtf_'s internal slot whose name is the Internal Slot value of the current row. + 1. Else, + 1. Let _format_ be _dtf_.[[DateTimeFormat]]. + 1. If _format_ has a field [[<_p_>]] and _dtf_.[[DateStyle]] is *undefined* and _dtf_.[[TimeStyle]] is *undefined*, then + 1. Let _v_ be _format_.[[<_p_>]]. + 1. Else, + 1. Let _v_ be *undefined*. 1. If _v_ is not *undefined*, then 1. If there is a Conversion value in the current row, then 1. Let _conversion_ be the Conversion value of the current row. @@ -641,57 +1059,57 @@

Intl.DateTimeFormat.prototype.resolvedOptions ( )

~hour12~ - [[Weekday]] + *"weekday"* - [[Era]] + *"era"* - [[Year]] + *"year"* - [[Month]] + *"month"* - [[Day]] + *"day"* - [[DayPeriod]] + *"dayPeriod"* - [[Hour]] + *"hour"* - [[Minute]] + *"minute"* - [[Second]] + *"second"* - [[FractionalSecondDigits]] + *"fractionalSecondDigits"* ~number~ - [[TimeZoneName]] + *"timeZoneName"* @@ -742,12 +1160,9 @@

Properties of Intl.DateTimeFormat Instances

  • [[Calendar]] is a String value representing the Unicode Calendar Identifier used for formatting.
  • [[NumberingSystem]] is a String value representing the Unicode Number System Identifier used for formatting.
  • [[TimeZone]] is a String value used for formatting that is either a time zone identifier from the IANA Time Zone Database or a UTC offset in ISO 8601 extended format.
  • -
  • [[Weekday]], [[Era]], [[Year]], [[Month]], [[Day]], [[DayPeriod]], [[Hour]], [[Minute]], [[Second]], [[TimeZoneName]] are each either *undefined*, indicating that the component is not used for formatting, or one of the String values given in , indicating how the component should be presented in the formatted output.
  • -
  • [[FractionalSecondDigits]] is either *undefined* or a positive, non-zero integer indicating the fraction digits to be used for fractional seconds. Numbers will be rounded or padded with trailing zeroes if necessary.
  • -
  • [[HourCycle]] is a String value indicating whether the 12-hour format (*"h11"*, *"h12"*) or the 24-hour format (*"h23"*, *"h24"*) should be used. *"h11"* and *"h23"* start with hour 0 and go up to 11 and 23 respectively. *"h12"* and *"h24"* start with hour 1 and go up to 12 and 24. [[HourCycle]] is only used when [[Hour]] is not *undefined*.
  • +
  • [[HourCycle]] is a String value indicating whether the 12-hour format (*"h11"*, *"h12"*) or the 24-hour format (*"h23"*, *"h24"*) should be used. *"h11"* and *"h23"* start with hour 0 and go up to 11 and 23 respectively. *"h12"* and *"h24"* start with hour 1 and go up to 12 and 24. [[HourCycle]] is only used when [[DateTimeFormat]] has an [[hour]] field.
  • [[DateStyle]], [[TimeStyle]] are each either *undefined*, or a String value with values *"full"*, *"long"*, *"medium"*, or *"short"*.
  • -
  • [[Pattern]] is a String value as described in .
  • -
  • [[RangePatterns]] is a Record as described in .
  • +
  • [[DateTimeFormat]] is a DateTime Format Record.
  • @@ -767,7 +1182,7 @@

    Abstract Operations for DateTimeFormat Objects

    - + @@ -835,26 +1250,26 @@

    DateTimeStyleFormat ( _dateStyle_: *"full"*, *"long"*, *"medium"*, *"short"*, or *undefined*, _timeStyle_: *"full"*, *"long"*, *"medium"*, *"short"*, or *undefined*, - _styles_: a Record, - ): a Record + _styles_: a DateTime Styles Record, + ): a DateTime Format Record

    description
    -
    _styles_ is a record from %Intl.DateTimeFormat%.[[LocaleData]].[[<_locale_>]].[[styles]].[[<_calendar_>]] for some locale _locale_ and calendar _calendar_. It returns the appropriate format record for date time formatting based on the parameters.
    +
    _styles_ is a Record from %Intl.DateTimeFormat%.[[LocaleData]].[[<_locale_>]].[[styles]].[[<_calendar_>]] for some locale _locale_ and calendar _calendar_. It returns the appropriate format Record for date time formatting based on the parameters.
    1. Assert: _dateStyle_ is not *undefined* or _timeStyle_ is not *undefined*. 1. If _timeStyle_ is not *undefined*, then 1. Assert: _timeStyle_ is one of *"full"*, *"long"*, *"medium"*, or *"short"*. - 1. Let _timeFormat_ be _styles_.[[TimeFormat]].[[<_timeStyle_>]]. + 1. Let _timeFormat_ be _styles_.[[Time]].[[<_timeStyle_>]]. 1. If _dateStyle_ is not *undefined*, then 1. Assert: _dateStyle_ is one of *"full"*, *"long"*, *"medium"*, or *"short"*. - 1. Let _dateFormat_ be _styles_.[[DateFormat]].[[<_dateStyle_>]]. + 1. Let _dateFormat_ be _styles_.[[Date]].[[<_dateStyle_>]]. 1. If _dateStyle_ is not *undefined* and _timeStyle_ is not *undefined*, then - 1. Let _format_ be a new Record. + 1. Let _format_ be a new DateTime Format Record. 1. Add to _format_ all fields from _dateFormat_ except [[pattern]] and [[rangePatterns]]. 1. Add to _format_ all fields from _timeFormat_ except [[pattern]], [[rangePatterns]], [[pattern12]], and [[rangePatterns12]], if present. - 1. Let _connector_ be _styles_.[[DateTimeFormat]].[[<_dateStyle_>]]. + 1. Let _connector_ be _styles_.[[Connector]].[[<_dateStyle_>]]. 1. Let _pattern_ be the string _connector_ with the substring *"{0}"* replaced with _timeFormat_.[[pattern]] and the substring *"{1}"* replaced with _dateFormat_.[[pattern]]. 1. Set _format_.[[pattern]] to _pattern_. 1. If _timeFormat_ has a [[pattern12]] field, then @@ -876,8 +1291,8 @@

    BasicFormatMatcher ( _options_: a Record, - _formats_: a List of Records, - ): a Record + _formats_: a List of DateTime Format Records, + ): a DateTime Format Record

    @@ -891,7 +1306,6 @@

    1. Let _offsetPenalty_ be 1. 1. Let _bestScore_ be -∞. 1. Let _bestFormat_ be *undefined*. - 1. Assert: Type(_formats_) is List. 1. For each element _format_ of _formats_, do 1. Let _score_ be 0. 1. For each row of , except the header row, in table order, do @@ -944,8 +1358,8 @@

    BestFitFormatMatcher ( _options_: a Record, - _formats_: a List of Records, - ): a Record + _formats_: a List of DateTime Format Records, + ): a DateTime Format Record

    description
    @@ -961,7 +1375,7 @@

    DateTime Format Functions

    1. Let _dtf_ be _F_.[[DateTimeFormat]]. - 1. Assert: Type(_dtf_) is Object and _dtf_ has an [[InitializedDateTimeFormat]] internal slot. + 1. Assert: _dtf_ is an Object and _dtf_ has an [[InitializedDateTimeFormat]] internal slot. 1. If _date_ is not provided or is *undefined*, then 1. Let _x_ be ! Call(%Date.now%, *undefined*). 1. Else, @@ -978,18 +1392,16 @@

    DateTime Format Functions

    FormatDateTimePattern ( _dateTimeFormat_: an Intl.DateTimeFormat, - _patternParts_: a List of Records as returned by PartitionPattern, - _x_: a Number, - _rangeFormatOptions_: a range pattern Record as used in [[rangePattern]], or *undefined*, - ): either a normal completion containing a List of Records with fields [[Type]] (a String) and [[Value]] (a String), or a throw completion + _format_: a DateTime Format Record or a DateTime Range Pattern Format Record, + _pattern_: a Pattern String, + _epochNanoseconds_: a BigInt, + ): a List of Records with fields [[Type]] (a String) and [[Value]] (a String)

    description
    -
    It interprets _x_ as a time value as specified in es2024, , and creates the corresponding parts according _pattern_ and to the effective locale and the formatting options of _dateTimeFormat_ and _rangeFormatOptions_.
    +
    It creates the corresponding parts for the epoch time _epochNanoseconds_ according to _pattern_ and to the effective locale and the formatting options of _dateTimeFormat_ and _format_.
    - 1. Let _x_ be TimeClip(_x_). - 1. If _x_ is *NaN*, throw a *RangeError* exception. 1. Let _locale_ be _dateTimeFormat_.[[Locale]]. 1. Let _nfOptions_ be OrdinaryObjectCreate(*null*). 1. Perform ! CreateDataPropertyOrThrow(_nfOptions_, *"useGrouping"*, *false*). @@ -998,36 +1410,39 @@

    1. Perform ! CreateDataPropertyOrThrow(_nf2Options_, *"minimumIntegerDigits"*, *2*𝔽). 1. Perform ! CreateDataPropertyOrThrow(_nf2Options_, *"useGrouping"*, *false*). 1. Let _nf2_ be ! Construct(%Intl.NumberFormat%, « _locale_, _nf2Options_ »). - 1. Let _fractionalSecondDigits_ be _dateTimeFormat_.[[FractionalSecondDigits]]. - 1. If _fractionalSecondDigits_ is not *undefined*, then + 1. If _format_ has a field [[fractionalSecondDigits]], then + 1. Let _fractionalSecondDigits_ be _format_.[[fractionalSecondDigits]]. 1. Let _nf3Options_ be OrdinaryObjectCreate(*null*). 1. Perform ! CreateDataPropertyOrThrow(_nf3Options_, *"minimumIntegerDigits"*, 𝔽(_fractionalSecondDigits_)). 1. Perform ! CreateDataPropertyOrThrow(_nf3Options_, *"useGrouping"*, *false*). 1. Let _nf3_ be ! Construct(%Intl.NumberFormat%, « _locale_, _nf3Options_ »). - 1. Let _tm_ be ToLocalTime(ℤ(ℝ(_x_) × 106), _dateTimeFormat_.[[Calendar]], _dateTimeFormat_.[[TimeZone]]). + 1. Let _tm_ be ToLocalTime(_epochNanoseconds_, _dateTimeFormat_.[[Calendar]], _dateTimeFormat_.[[TimeZone]]). + 1. Let _patternParts_ be PartitionPattern(_pattern_). 1. Let _result_ be a new empty List. 1. For each Record { [[Type]], [[Value]] } _patternPart_ of _patternParts_, do 1. Let _p_ be _patternPart_.[[Type]]. 1. If _p_ is *"literal"*, then 1. Append the Record { [[Type]]: *"literal"*, [[Value]]: _patternPart_.[[Value]] } to _result_. 1. Else if _p_ is *"fractionalSecondDigits"*, then - 1. Assert: _fractionalSecondDigits_ is not *undefined*. + 1. Assert: _format_ has a field [[fractionalSecondDigits]]. 1. Let _v_ be _tm_.[[Millisecond]]. 1. Set _v_ to floor(_v_ × 10( _fractionalSecondDigits_ - 3 )). 1. Let _fv_ be FormatNumeric(_nf3_, _v_). 1. Append the Record { [[Type]]: *"fractionalSecond"*, [[Value]]: _fv_ } to _result_. 1. Else if _p_ is *"dayPeriod"*, then - 1. Let _f_ be _dateTimeFormat_.[[DayPeriod]]. + 1. Assert: _format_ has a field [[dayPeriod]]. + 1. Let _f_ be _format_.[[dayPeriod]]. 1. Let _fv_ be a String value representing the day period of _tm_ in the form given by _f_; the String value depends upon the implementation and the effective locale of _dateTimeFormat_. 1. Append the Record { [[Type]]: _p_, [[Value]]: _fv_ } to _result_. 1. Else if _p_ is *"timeZoneName"*, then - 1. Let _f_ be _dateTimeFormat_.[[TimeZoneName]]. + 1. Assert: _format_ has a field [[timeZoneName]]. + 1. Let _f_ be _format_.[[timeZoneName]]. 1. Let _v_ be _dateTimeFormat_.[[TimeZone]]. - 1. Let _fv_ be a String value representing _v_ in the form given by _f_; the String value depends upon the implementation and the effective locale of _dateTimeFormat_. The String value may also depend on the value of the [[InDST]] field of _tm_ if _f_ is *"short"*, *"long"*, *"shortOffset"*, or *"longOffset"*. If the implementation does not have such a localized representation of _v_, then use the String value of _v_ itself. + 1. Let _fv_ be a String value representing _v_ in the form given by _f_; the String value depends upon the implementation and the effective locale of _dateTimeFormat_. The String value may also depend on the value of the [[InDST]] field of _tm_ if _f_ is *"short"*, *"long"*, *"shortOffset"*, or *"longOffset"*. If the implementation does not have such a localized representation of _f_, then use the String value of _v_ itself. 1. Append the Record { [[Type]]: _p_, [[Value]]: _fv_ } to _result_. - 1. Else if _p_ matches one of the values in the Property column of , then - 1. If _rangeFormatOptions_ is not *undefined*, let _f_ be the value of _rangeFormatOptions_'s field whose name matches _p_. - 1. Else, let _f_ be the value of _dateTimeFormat_'s internal slot whose name matches the value in the Internal Slot column of the matching row. + 1. Else if _p_ matches a Property column of the row in , then + 1. Assert: _format_ has a field [[<_p_>]]. + 1. Let _f_ be _format_.[[<_p_>]]. 1. Let _v_ be the value of _tm_'s field whose name is the Internal Slot column of the matching row. 1. If _p_ is *"year"* and _v_ ≤ 0, set _v_ to 1 - _v_. 1. If _p_ is *"month"*, set _v_ to _v_ + 1. @@ -1040,9 +1455,14 @@

    1. Let _fv_ be FormatNumeric(_nf_, _v_). 1. Else if _f_ is *"2-digit"*, then 1. Let _fv_ be FormatNumeric(_nf2_, _v_). - 1. If the *"length"* property of _fv_ is greater than 2, set _fv_ to the substring of _fv_ containing the last two characters. + 1. Let _codePoints_ be StringToCodePoints(_fv_). + 1. Let _count_ be the number of elements in _codePoints_. + 1. If _count_ > 2, then + 1. Let _tens_ be _codePoints_[_count_ - 2]. + 1. Let _ones_ be _codePoints_[_count_ - 1]. + 1. Set _fv_ to CodePointsToString(« _tens_, _ones_ »). 1. Else if _f_ is *"narrow"*, *"short"*, or *"long"*, then - 1. Let _fv_ be a String value representing _v_ in the form given by _f_; the String value depends upon the implementation and the effective locale and calendar of _dateTimeFormat_. If _p_ is *"month"* and _rangeFormatOptions_ is *undefined*, then the String value may also depend on whether _dateTimeFormat_.[[Day]] is *undefined*. If _p_ is *"month"* and _rangeFormatOptions_ is not *undefined*, then the String value may also depend on whether _rangeFormatOptions_.[[day]] is *undefined*. If _p_ is *"era"* and _rangeFormatOptions_ is *undefined*, then the String value may also depend on whether _dateTimeFormat_.[[Era]] is *undefined*. If _p_ is *"era"* and _rangeFormatOptions_ is not *undefined*, then the String value may also depend on whether _rangeFormatOptions_.[[era]] is *undefined*. If the implementation does not have such a localized representation of _v_, then use ! ToString(_v_). + 1. Let _fv_ be a String value representing _v_ in the form given by _f_; the String value depends upon the implementation and the effective locale and calendar of _dateTimeFormat_. If _p_ is *"month"*, then the String value may also depend on whether _format_.[[day]] is present. If the implementation does not have a localized representation of _f_, then use the String value of _v_ itself. 1. Append the Record { [[Type]]: _p_, [[Value]]: _fv_ } to _result_. 1. Else if _p_ is *"ampm"*, then 1. Let _v_ be _tm_.[[Hour]]. @@ -1060,7 +1480,7 @@

    1. Let _fv_ be an implementation and locale dependent String value representing _v_. 1. Append the Record { [[Type]]: *"yearName"*, [[Value]]: _fv_ } to _result_. 1. Else, - 1. Let _unknown_ be an implementation-, locale-, and numbering system-dependent String based on _x_ and _p_. + 1. Let _unknown_ be an implementation-, locale-, and numbering system-dependent String based on _epochNanoseconds_ and _p_. 1. Append the Record { [[Type]]: *"unknown"*, [[Value]]: _unknown_ } to _result_. 1. Return _result_. @@ -1082,8 +1502,15 @@

    It interprets _x_ as a time value as specified in es2024, , and creates the corresponding parts according to the effective locale and the formatting options of _dateTimeFormat_.

    - 1. Let _patternParts_ be PartitionPattern(_dateTimeFormat_.[[Pattern]]). - 1. Let _result_ be ? FormatDateTimePattern(_dateTimeFormat_, _patternParts_, _x_, *undefined*). + 1. Let _x_ be TimeClip(_x_). + 1. If _x_ is *NaN*, throw a *RangeError* exception. + 1. Let _epochNanoseconds_ be ℤ(ℝ(_x_) × 106). + 1. Let _format_ be _dateTimeFormat_.[[DateTimeFormat]]. + 1. If _dateTimeFormat_.[[HourCycle]] is *"h11"* or *"h12"*, then + 1. Let _pattern_ be _format_.[[pattern12]]. + 1. Else, + 1. Let _pattern_ be _format_.[[pattern]]. + 1. Let _result_ be FormatDateTimePattern(_dateTimeFormat_, _format_, _pattern_, _epochNanoseconds_). 1. Return _result_. @@ -1146,19 +1573,27 @@

    1. If _x_ is *NaN*, throw a *RangeError* exception. 1. Set _y_ to TimeClip(_y_). 1. If _y_ is *NaN*, throw a *RangeError* exception. - 1. Let _tm1_ be ToLocalTime(ℤ(ℝ(_x_) × 106), _dateTimeFormat_.[[Calendar]], _dateTimeFormat_.[[TimeZone]]). - 1. Let _tm2_ be ToLocalTime(ℤ(ℝ(_y_) × 106), _dateTimeFormat_.[[Calendar]], _dateTimeFormat_.[[TimeZone]]). - 1. Let _rangePatterns_ be _dateTimeFormat_.[[RangePatterns]]. + 1. Let _xEpochNanoseconds_ be ℤ(ℝ(_x_) × 106). + 1. Let _yEpochNanoseconds_ be ℤ(ℝ(_y_) × 106). + 1. Let _tm1_ be ToLocalTime(_xEpochNanoseconds_, _dateTimeFormat_.[[Calendar]], _dateTimeFormat_.[[TimeZone]]). + 1. Let _tm2_ be ToLocalTime(_yEpochNanoseconds_, _dateTimeFormat_.[[Calendar]], _dateTimeFormat_.[[TimeZone]]). + 1. Let _format_ be _dateTimeFormat_.[[DateTimeFormat]]. + 1. If _dateTimeFormat_.[[HourCycle]] is *"h11"* or *"h12"*, then + 1. Let _pattern_ be _format_.[[pattern12]]. + 1. Let _rangePatterns_ be _format_.[[rangePatterns12]]. + 1. Else, + 1. Let _pattern_ be _format_.[[pattern]]. + 1. Let _rangePatterns_ be _format_.[[rangePatterns]]. 1. Let _selectedRangePattern_ be *undefined*. 1. Let _relevantFieldsEqual_ be *true*. 1. Let _checkMoreFields_ be *true*. - 1. For each row of , except the header row, in table order, do - 1. Let _fieldName_ be the name given in the Range Pattern Field column of the current row. - 1. If _rangePatterns_ has a field [[<_fieldName_>]], let _rangePattern_ be _rangePatterns_.[[<_fieldName_>]]; else let _rangePattern_ be *undefined*. + 1. For each row of , except the header row, in table order, do + 1. Let _fieldName_ be the name given in the Field Name column of the row. + 1. If _rangePatterns_ has a field whose name is _fieldName_, let _rangePattern_ be _rangePatterns_' field whose name is _fieldName_; else let _rangePattern_ be *undefined*. 1. If _selectedRangePattern_ is not *undefined* and _rangePattern_ is *undefined*, then 1. NOTE: Because there is no range pattern for differences at or below this field, no further checks will be performed. 1. Set _checkMoreFields_ to *false*. - 1. If _relevantFieldsEqual_ is *true* and _checkMoreFields_ is *true*, then + 1. If _fieldName_ is not equal to [[Default]] and _relevantFieldsEqual_ is *true* and _checkMoreFields_ is *true*, then 1. Set _selectedRangePattern_ to _rangePattern_. 1. If _fieldName_ is [[AmPm]], then 1. If _tm1_.[[Hour]] is less than 12, let _v1_ be *"am"*; else let _v1_ be *"pm"*. @@ -1167,22 +1602,21 @@

    1. Let _v1_ be a String value representing the day period of _tm1_; the String value depends upon the implementation and the effective locale of _dateTimeFormat_. 1. Let _v2_ be a String value representing the day period of _tm2_; the String value depends upon the implementation and the effective locale of _dateTimeFormat_. 1. Else if _fieldName_ is [[FractionalSecondDigits]], then - 1. Let _fractionalSecondDigits_ be _dateTimeFormat_.[[FractionalSecondDigits]]. - 1. If _fractionalSecondDigits_ is *undefined*, then - 1. Set _fractionalSecondDigits_ to 3. + 1. If _format_ has a [[fractionalSecondDigits]] field, then + 1. Let _fractionalSecondDigits_ be _format_.[[fractionalSecondDigits]]. + 1. Else, + 1. Let _fractionalSecondDigits_ be 3. 1. Let _exp_ be _fractionalSecondDigits_ - 3. 1. Let _v1_ be floor(_tm1_.[[Millisecond]] × 10_exp_). 1. Let _v2_ be floor(_tm2_.[[Millisecond]] × 10_exp_). 1. Else, - 1. Let _v1_ be _tm1_.[[<_fieldName_>]]. - 1. Let _v2_ be _tm2_.[[<_fieldName_>]]. - 1. If _v1_ is not _v2_, then + 1. Let _v1_ be _tm1_'s field whose name is _fieldName_. + 1. Let _v2_ be _tm2_'s field whose name is _fieldName_. + 1. If _v1_ is not equal to _v2_, then 1. Set _relevantFieldsEqual_ to *false*. 1. If _relevantFieldsEqual_ is *true*, then 1. Let _collapsedResult_ be a new empty List. - 1. Let _pattern_ be _dateTimeFormat_.[[Pattern]]. - 1. Let _patternParts_ be PartitionPattern(_pattern_). - 1. Let _resultParts_ be ! FormatDateTimePattern(_dateTimeFormat_, _patternParts_, _x_, *undefined*). + 1. Let _resultParts_ be FormatDateTimePattern(_dateTimeFormat_, _format_, _pattern_, _xEpochNanoseconds_). 1. For each Record { [[Type]], [[Value]] } _r_ of _resultParts_, do 1. Append the Record { [[Type]]: _r_.[[Type]], [[Value]]: _r_.[[Value]], [[Source]]: *"shared"* } to _collapsedResult_. 1. Return _collapsedResult_. @@ -1193,11 +1627,10 @@

    1. Let _pattern_ be _rangePatternPart_.[[Pattern]]. 1. Let _source_ be _rangePatternPart_.[[Source]]. 1. If _source_ is *"startRange"* or *"shared"*, then - 1. Let _z_ be _x_. + 1. Let _z_ be _xEpochNanoseconds_. 1. Else, - 1. Let _z_ be _y_. - 1. Let _patternParts_ be PartitionPattern(_pattern_). - 1. Let _resultParts_ be ! FormatDateTimePattern(_dateTimeFormat_, _patternParts_, _z_, _selectedRangePattern_). + 1. Let _z_ be _yEpochNanoseconds_. + 1. Let _resultParts_ be FormatDateTimePattern(_dateTimeFormat_, _selectedRangePattern_, _pattern_, _z_). 1. For each Record { [[Type]], [[Value]] } _r_ of _resultParts_, do 1. Append the Record { [[Type]]: _r_.[[Type]], [[Value]]: _r_.[[Value]], [[Source]]: _source_ } to _rangeResult_. 1. Return _rangeResult_. @@ -1371,7 +1804,7 @@

    - 1. If Type(_dtf_) is not Object, throw a *TypeError* exception. + 1. If _dtf_ is not an Object, throw a *TypeError* exception. 1. If _dtf_ does not have an [[InitializedDateTimeFormat]] internal slot and ? OrdinaryHasInstance(%Intl.DateTimeFormat%, _dtf_) is *true*, then 1. Return ? Get(_dtf_, %Intl%.[[FallbackSymbol]]). 1. Return _dtf_. diff --git a/spec/displaynames.html b/spec/displaynames.html index 27614738..a6782f41 100644 --- a/spec/displaynames.html +++ b/spec/displaynames.html @@ -132,11 +132,11 @@

    Intl.DisplayNames.prototype.constructor

    - -

    Intl.DisplayNames.prototype[ @@toStringTag ]

    + +

    Intl.DisplayNames.prototype [ %Symbol.toStringTag% ]

    - The initial value of the @@toStringTag property is the String value *"Intl.DisplayNames"*. + The initial value of the %Symbol.toStringTag% property is the String value *"Intl.DisplayNames"*.

    This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }. diff --git a/spec/index.html b/spec/index.html index 23f17bbf..6a0b77c4 100644 --- a/spec/index.html +++ b/spec/index.html @@ -9,30 +9,6 @@ }

    Internal SlotField Name Property Values