This repository has been archived by the owner on Jan 25, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathspec.html
590 lines (532 loc) · 34.6 KB
/
spec.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
<!doctype html>
<meta charset="utf8">
<pre class=metadata>
title: Intl.Locale
stage: 3
contributors: Mozilla, Ecma International
</pre>
<emu-biblio href="./biblio.json"></emu-biblio>
<emu-clause id="locale-objects">
<h1>Locale Objects</h1>
<emu-clause id="sec-intl-locale-constructor">
<h1>The Intl.Locale Constructor</h1>
<p>
The Locale constructor is a standard built-in property of the Intl object.
</p>
<emu-clause id="sec-apply-options-to-tag" aoid=ApplyOptionsToTag>
<h1>ApplyOptionsToTag( _tag_, _options_ )</h1>
<p>
The following algorithm refers to <a href="https://www.unicode.org/reports/tr35/#Identifiers">UTS 35's Unicode Language and Locale Identifiers grammar</a>.
</p>
<emu-alg>
1. Assert: Type(_tag_) is String.
1. If IsStructurallyValidLanguageTag(_tag_) is *false*, throw a *RangeError* exception.
1. Let _language_ be ? GetOption(_options_, `"language"`, `"string"`, *undefined*, *undefined*).
1. If _language_ is not *undefined*, then
1. If _language_ does not match the `unicode_language_subtag` production, throw a *RangeError* exception.
1. Let _script_ be ? GetOption(_options_, `"script"`, `"string"`, *undefined*, *undefined*).
1. If _script_ is not *undefined*, then
1. If _script_ does not match the `unicode_script_subtag`, throw a *RangeError* exception.
1. Let _region_ be ? GetOption(_options_, `"region"`, `"string"`, *undefined*, *undefined*).
1. If _region_ is not *undefined*, then
1. If _region_ does not match the `unicode_region_subtag`, throw a *RangeError* exception.
1. Set _tag_ to CanonicalizeUnicodeLocaleId(_tag_).
1. If _language_ is not *undefined*,
1. Assert: _tag_ matches the `unicode_locale_id` production.
1. Set _tag_ to _tag_ with the substring corresponding to the `unicode_language_subtag` production of the `unicode_language_id` replaced by the string _language_.
1. If _script_ is not *undefined*, then
1. If _tag_ does not contain a `unicode_script_subtag` production of the `unicode_language_id`, then
1. Set _tag_ to the concatenation of the `unicode_language_subtag` production of the `unicode_languge_id` of _tag_, `"-"`, _script_, and the rest of _tag_.
1. Else,
1. Set _tag_ to _tag_ with the substring corresponding to the `unicode_script_subtag` production of the `unicode_language_id` replaced by the string _script_.
1. If _region_ is not *undefined*, then
1. If _tag_ does not contain a `unicode_region_subtag` production of the `unicode_language_id`, then
1. Set _tag_ to the concatenation of the `unicode_language_subtag` production of the `unicode_language_id` of _tag_, the substring corresponding to the `"-" unicode_script_subtag` production of the `unicode_language_id` if present, `"-"`, _region_, and the rest of _tag_.
1. Else,
1. Set _tag_ to _tag_ with the substring corresponding to the `unicode_region_subtag` production of the `unicode_language_id` replaced by the string _region_.
1. Return CanonicalizeUnicodeLocaleId(_tag_).
</emu-alg>
</emu-clause>
<emu-clause id="sec-apply-unicode-extension-to-tag" aoid=ApplyUnicodeExtensionToTag>
<h1>ApplyUnicodeExtensionToTag( _tag_, _options_, _relevantExtensionKeys_ )</h1>
<p>
The following algorithm refers to <a href="https://www.unicode.org/reports/tr35/#Identifiers">UTS 35's Unicode Language and Locale Identifiers grammar</a>.
</p>
<emu-alg>
1. Assert: Type(_tag_) is String.
1. Assert: _tag_ matches the `unicode_locale_id` production.
1. If _tag_ contains a substring that is a Unicode locale extension sequence, then
1. Let _extension_ be the String value consisting of the first substring of _tag_ that is a Unicode locale extension sequence.
1. Let _components_ be ! UnicodeExtensionComponents(_extension_).
1. Let _attributes_ be _components_.[[Attributes]].
1. Let _keywords_ be _components_.[[Keywords]].
1. Else,
1. Let _attributes_ be the empty List.
1. Let _keywords_ be the empty List.
1. Let _result_ be a new Record.
1. Repeat for each element _key_ of _relevantExtensionKeys_ in List order,
1. Let _value_ be *undefined*.
1. If _keywords_ contains an element whose [[Key]] is the same as _key_, then
1. Let _entry_ be the element of _keywords_ whose [[Key]] is the same as _key_.
1. Let _value_ be _entry_.[[Value]].
1. Else
1. Let _entry_ be ~empty~.
1. Assert: _options_ has a field [[<_key_>]].
1. Let _optionsValue_ be _options_.[[<_key_>]].
1. If _optionsValue_ is not *undefined*, then
1. Assert: Type(_optionsValue_) is String.
1. Let _value_ be _optionsValue_.
1. If _entry_ is not ~empty~, then
1. Set _entry_.[[Value]] to _value_.
1. Else,
1. Append the Record{[[Key]]: _key_, [[Value]]: _value_} to _keywords_.
1. Set _result_.[[<_key_>]] to _value_.
1. Let _locale_ be the String value that is _tag_ with all Unicode locale extension sequences removed.
1. Let _newExtension_ be a Unicode BCP 47 U Extension based on _attributes_ and _keywords_.
1. If _newExtension_ is not the empty String, then
1. Let _locale_ be ! InsertUnicodeExtensionAndCanonicalize(_locale_, _newExtension_).
1. Set _result_.[[locale]] to _locale_.
1. Return _result_.
</emu-alg>
</emu-clause>
<emu-clause id="sec-unicode-extension-components" aoid=UnicodeExtensionComponents>
<h1>UnicodeExtensionComponents( _extension_ )</h1>
<p>
The UnicodeExtensionComponents abstract operation returns the attributes and keywords from _extension_, which must be a Unicode locale extension sequence. If an attribute or a keyword occurs multiple times in _extension_, only the first occurence is returned. The following steps are taken:
</p>
<emu-alg>
1. Let _attributes_ be the empty List.
1. Let _keywords_ be the empty List.
1. Let _isKeyword_ be *false*.
1. Let _size_ be the number of elements in _extension_.
1. Let _k_ be 3.
1. Repeat, while _k_ < _size_
1. Let _e_ be ! Call(%StringProto_indexOf%, _extension_, « `"-"`, _k_ »).
1. If _e_ = -1, let _len_ be _size_ - _k_; else let _len_ be _e_ - _k_.
1. Let _subtag_ be the String value equal to the substring of _extension_ consisting of the code units at indices _k_ (inclusive) through _k_ + _len_ (exclusive).
1. If _isKeyword_ is *false*, then
1. If _len_ ≠ 2 and _subtag_ is not an element of _attributes_, then
1. Append _subtag_ to _attributes_.
1. Else,
1. If _len_ = 2, then
1. If _keywords_ does not contain an element whose [[Key]] is the same as _key_, then
1. Append the Record{[[Key]]: _key_, [[Value]]: _value_} to _keywords_.
1. Else,
1. If _value_ is not the empty String, then
1. Let _value_ be the string-concatenation of _value_ and `"-"`.
1. Let _value_ be the string-concatenation of _value_ and _subtag_.
1. If _len_ = 2, then
1. Let _isKeyword_ be *true*.
1. Let _key_ be _subtag_.
1. Let _value_ be the empty String.
1. Let _k_ be _k_ + _len_ + 1.
1. If _isKeyword_ is *true*, then
1. If _keywords_ does not contain an element whose [[Key]] is the same as _key_, then
1. Append the Record{[[Key]]: _key_, [[Value]]: _value_} to _keywords_.
1. Return the Record{[[Attributes]]: _attributes_, [[Keywords]]: _keywords_}.
</emu-alg>
</emu-clause>
<emu-clause id="sec-insert-unicode-extension-and-canonicalize" aoid=InsertUnicodeExtensionAndCanonicalize>
<h1>InsertUnicodeExtensionAndCanonicalize( _locale_, _extension_ )</h1>
<p>
The InsertUnicodeExtensionAndCanonicalize abstract operation inserts _extension_, which must be a Unicode locale extension sequence, into _locale_, which must be a String value with a structurally valid and canonicalized BCP 47 language tag. The following steps are taken:
</p>
<p>
The following algorithm refers to <a href="https://www.unicode.org/reports/tr35/#Identifiers">UTS 35's Unicode Language and Locale Identifiers grammar</a>.
</p>
<emu-alg>
1. Assert: _locale_ does not contain a substring that is a Unicode locale extension sequence.
1. Assert: _extension_ is a Unicode extension sequence.
1. Assert: _tag_ matches the `unicode_locale_id` production.
1. Let _privateIndex_ be ! Call(%StringProto_indexOf%, _locale_, « `"-x-"` »).
1. If _privateIndex_ = -1, then
1. Let _locale_ be the concatenation of _locale_ and _extension_.
1. Else,
1. Let _preExtension_ be the substring of _locale_ from position 0, inclusive, to position _privateIndex_, exclusive.
1. Let _postExtension_ be the substring of _locale_ from position _privateIndex_ to the end of the string.
1. Let _locale_ be the string-concatenation of _preExtension_, _extension_, and _postExtension_.
1. Assert: IsStructurallyValidLanguageTag(_locale_) is *true*.
1. Return ! CanonicalizeUnicodeLocaleId(_locale_).
</emu-alg>
</emu-clause>
<emu-clause id="sec-Intl.Locale">
<h1>Intl.Locale( _tag_ [, _options_] )</h1>
<p>
The following algorithm refers to <a href="https://www.unicode.org/reports/tr35/#Identifiers">UTS 35's Unicode Language and Locale Identifiers grammar</a>.
When the *Intl.Locale* function is called with an argument _tag_ and an optional argument _options_, the following steps are taken:
</p>
<emu-alg>
1. If NewTarget is *undefined*, throw a *TypeError* exception.
1. Let _relevantExtensionKeys_ be %Locale%.[[RelevantExtensionKeys]].
1. Let _internalSlotsList_ be « [[InitializedLocale]], [[Locale]], [[Calendar]], [[Collation]], [[HourCycle]], [[NumberingSystem]] ».
1. If _relevantExtensionKeys_ contains `"kf"`, then
1. Append [[CaseFirst]] as the last element of _internalSlotsList_.
1. If _relevantExtensionKeys_ contains `"kn"`, then
1. Append [[Numeric]] as the last element of _internalSlotsList_.
1. Let _locale_ be ? OrdinaryCreateFromConstructor(NewTarget, *%LocalePrototype%*, _internalSlotsList_).
1. If Type(_tag_) is not String or Object, throw a *TypeError* exception.
1. If Type(_tag_) is Object and _tag_ has an [[InitializedLocale]] internal slot, then
1. Let _tag_ be _tag_.[[Locale]].
1. Else,
1. Let _tag_ be ? ToString(_tag_).
1. If _options_ is *undefined*, then
1. Let _options_ be ! ObjectCreate(*null*).
1. Else
1. Let _options_ be ? ToObject(_options_).
1. Set _tag_ to ? ApplyOptionsToTag(_tag_, _options_).
1. Let _opt_ be a new Record.
1. Let _calendar_ be ? GetOption(_options_, `"calendar"`, `"string"`, *undefined*, *undefined*).
1. If _calendar_ is not *undefined*, then
1. If _calendar_ does not match the `type` sequence (from <a href="http://unicode.org/reports/tr35/#Unicode_locale_identifier">UTS 35 Unicode Locale Identifier, section 3.2</a>), throw a *RangeError* exception.
1. Set _opt_.[[ca]] to _calendar_.
1. Let _collation_ be ? GetOption(_options_, `"collation"`, `"string"`, *undefined*, *undefined*).
1. If _collation_ is not *undefined*, then
1. If _collation_ does not match the `type` sequence (from <a href="http://unicode.org/reports/tr35/#Unicode_locale_identifier">UTS 35 Unicode Locale Identifier, section 3.2</a>), throw a *RangeError* exception.
1. Set _opt_.[[co]] to _collation_.
1. Let _hc_ be ? GetOption(_options_, `"hourCycle"`, `"string"`, « `"h11"`, `"h12"`, `"h23"`, `"h24"` », *undefined*).
1. Set _opt_.[[hc]] to _hc_.
1. Let _kf_ be ? GetOption(_options_, `"caseFirst"`, `"string"`, « `"upper"`, `"lower"`, `"false"` », *undefined*).
1. Set _opt_.[[kf]] to _kf_.
1. Let _kn_ be ? GetOption(_options_, `"numeric"`, `"boolean"`, *undefined*, *undefined*).
1. If _kn_ is not *undefined*, set _kn_ to ! ToString(_kn_).
1. Set _opt_.[[kn]] to _kn_.
1. Let _numberingSystem_ be ? GetOption(_options_, `"numberingSystem"`, `"string"`, *undefined*, *undefined*).
1. If _numberingSystem_ is not *undefined*, then
1. If _numberingSystem_ does not match the `type` sequence (from <a href="http://unicode.org/reports/tr35/#Unicode_locale_identifier">UTS 35 Unicode Locale Identifier, section 3.2</a>), throw a *RangeError* exception.
1. Set _opt_.[[nu]] to _numberingSystem_.
1. Let _r_ be ! ApplyUnicodeExtensionToTag(_tag_, _opt_, _relevantExtensionKeys_).
1. Set _locale_.[[Locale]] to _r_.[[locale]].
1. Set _locale_.[[Calendar]] to _r_.[[ca]].
1. Set _locale_.[[Collation]] to _r_.[[co]].
1. Set _locale_.[[HourCycle]] to _r_.[[hc]].
1. If _relevantExtensionKeys_ contains `"kf"`, then
1. Set _locale_.[[CaseFirst]] to _r_.[[kf]].
1. If _relevantExtensionKeys_ contains `"kn"`, then
1. If ! SameValue(_r_.[[kn]], `"true"`) is true or ! SameValue(_r_.[[kn]], `""`) is true, then
1. Let _numeric_ be true.
1. Else,
1. Let _numeric_ be false.
1. Set _locale_.[[Numeric]] to _numeric_.
1. Set _locale_.[[NumberingSystem]] to _r_.[[nu]].
1. Return _locale_.
</emu-alg>
</emu-clause>
</emu-clause>
<emu-clause id="sec-properties-of-intl-locale-constructor">
<h1>Properties of the Intl.Locale Constructor</h1>
<p>
The Intl.Locale constructor has the following properties:
</p>
<emu-clause id="sec-Intl.Locale.prototype">
<h1>Intl.Locale.prototype</h1>
<p>
The value of *Intl.Locale.prototype* is *%LocalePrototype%*.
</p>
<p>
This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }.
</p>
</emu-clause>
<emu-clause id="sec-intl.locale-internal-slots">
<h1>Internal slots</h1>
<p>
The value of the [[RelevantExtensionKeys]] internal slot is « `"ca"`, `"co"`, `"hc"`, `"kf"`, `"kn"`, `"nu"` ». If %Collator%.[[RelevantExtensionKeys]] does not contain `"kf"`, then remove `"kf"` from %Locale%.[[RelevantExtensionKeys]]. If %Collator%.[[RelevantExtensionKeys]] does not contain `"kn"`, then remove `"kn"` from %Locale%.[[RelevantExtensionKeys]].
</p>
</emu-clause>
</emu-clause>
<emu-clause id="sec-properties-of-intl-locale-prototype-object">
<h1>Properties of the Intl.Locale Prototype Object</h1>
<p>
The Intl.Locale prototype object is itself an ordinary object. %LocalePrototype% is not an Intl.Locale instance and does not have an [[InitializedLocale]] internal slot or any of the other internal slots of Intl.Locale instance objects.
</p>
<emu-clause id="sec-Intl.Locale.prototype.constructor">
<h1>Intl.Locale.prototype.constructor</h1>
<p>
The initial value of *Intl.Locale.prototype.constructor* is *%Locale%*.
</p>
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype-@@tostringtag">
<h1>Intl.Locale.prototype[ @@toStringTag ]</h1>
<p>
The initial value of the @@toStringTag property is the string value `"Intl.Locale"`.
</p>
<p>
This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.
</p>
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype.maximize">
<h1>Intl.Locale.prototype.maximize ()</h1>
<emu-alg>
1. Let _loc_ be the *this* value.
1. If Type(_loc_) is not Object or _loc_ does not have an [[InitializedLocale]] internal slot, then
1. Throw a *TypeError* exception.
1. Let _maximal_ be the result of the <a href="https://www.unicode.org/reports/tr35/#Likely_Subtags">Add Likely Subtags</a> algorithm applied to _loc_.[[Locale]]. If an error is signaled, set _maximal_ to _loc_.[[Locale]].
1. Return ! Construct(%Locale%, _maximal_).
</emu-alg>
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype.minimize">
<h1>Intl.Locale.prototype.minimize ()</h1>
<emu-alg>
1. Let _loc_ be the *this* value.
1. If Type(_loc_) is not Object or _loc_ does not have an [[InitializedLocale]] internal slot, then
1. Throw a *TypeError* exception.
1. Let _minimal_ be the result of the <a href="https://www.unicode.org/reports/tr35/#Likely_Subtags">Remove Likely Subtags</a> algorithm applied to _loc_.[[Locale]]. If an error is signaled, set _minimal_ to _loc_.[[Locale]].
1. Return ! Construct(%Locale%, _minimal_).
</emu-alg>
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype.toString">
<h1>Intl.Locale.prototype.toString ()</h1>
<emu-alg>
1. Let _loc_ be the *this* value.
1. If Type(_loc_) is not Object or _loc_ does not have an [[InitializedLocale]] internal slot, then
1. Throw a *TypeError* exception.
1. Return _loc_.[[Locale]].
</emu-alg>
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype.baseName">
<h1>get Intl.Locale.prototype.baseName</h1>
<p>`Intl.Locale.prototype.baseName` is an accessor property whose set accessor function is *undefined*. The following algorithm refers to <a href="https://www.unicode.org/reports/tr35/#Identifiers">UTS 35's Unicode Language and Locale Identifiers grammar</a>. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _loc_ be the *this* value.
1. If Type(_loc_) is not Object or _loc_ does not have an [[InitializedLocale]] internal slot, then
1. Throw a *TypeError* exception.
1. Let _locale_ be _loc_.[[Locale]].
1. Return the substring of _locale_ corresponding to the `unicode_language_id` production.
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype.calendar">
<h1>get Intl.Locale.prototype.calendar</h1>
<p>`Intl.Locale.prototype.calendar` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _loc_ be the *this* value.
1. If Type(_loc_) is not Object or _loc_ does not have an [[InitializedLocale]] internal slot, then
1. Throw a *TypeError* exception.
1. Return _loc_.[[Calendar]].
</emu-alg>
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype.caseFirst">
<h1>get Intl.Locale.prototype.caseFirst</h1>
<p>This property only exists if %Locale%.[[RelevantExtensionKeys]] contains `"kf"`.</p>
<p>`Intl.Locale.prototype.caseFirst` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _loc_ be the *this* value.
1. If Type(_loc_) is not Object or _loc_ does not have an [[InitializedLocale]] internal slot, then
1. Throw a *TypeError* exception.
1. Return _loc_.[[CaseFirst]].
</emu-alg>
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype.collation">
<h1>get Intl.Locale.prototype.collation</h1>
<p>`Intl.Locale.prototype.collation` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _loc_ be the *this* value.
1. If Type(_loc_) is not Object or _loc_ does not have an [[InitializedLocale]] internal slot, then
1. Throw a *TypeError* exception.
1. Return _loc_.[[Collation]].
</emu-alg>
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype.hourCycle">
<h1>get Intl.Locale.prototype.hourCycle</h1>
<p>`Intl.Locale.prototype.hourCycle` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _loc_ be the *this* value.
1. If Type(_loc_) is not Object or _loc_ does not have an [[InitializedLocale]] internal slot, then
1. Throw a *TypeError* exception.
1. Return _loc_.[[HourCycle]].
</emu-alg>
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype.numeric">
<h1>get Intl.Locale.prototype.numeric</h1>
<p>This property only exists if %Locale%.[[RelevantExtensionKeys]] contains `"kn"`.</p>
<p>`Intl.Locale.prototype.numeric` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _loc_ be the *this* value.
1. If Type(_loc_) is not Object or _loc_ does not have an [[InitializedLocale]] internal slot, then
1. Throw a *TypeError* exception.
1. Return _loc_.[[Numeric]].
</emu-alg>
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype.numberingSystem">
<h1>get Intl.Locale.prototype.numberingSystem</h1>
<p>`Intl.Locale.prototype.numberingSystem` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _loc_ be the *this* value.
1. If Type(_loc_) is not Object or _loc_ does not have an [[InitializedLocale]] internal slot, then
1. Throw a *TypeError* exception.
1. Return _loc_.[[NumberingSystem]].
</emu-alg>
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype.language">
<h1>get Intl.Locale.prototype.language</h1>
<p>`Intl.Locale.prototype.language` is an accessor property whose set accessor function is *undefined*. The following algorithm refers to <a href="https://www.unicode.org/reports/tr35/#Identifiers">UTS 35's Unicode Language and Locale Identifiers grammar</a>. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _loc_ be the *this* value.
1. If Type(_loc_) is not Object or _loc_ does not have an [[InitializedLocale]] internal slot, then
1. Throw a *TypeError* exception.
1. Let _locale_ be _loc_.[[Locale]].
1. Assert: _locale_ matches the `unicode_locale_id` production.
1. Return the substring of _locale_ corresponding to the `unicode_language_subtag` production of the `unicode_language_id`.
</emu-alg>
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype.script">
<h1>get Intl.Locale.prototype.script</h1>
<p>`Intl.Locale.prototype.script` is an accessor property whose set accessor function is *undefined*. The following algorithm refers to <a href="https://www.unicode.org/reports/tr35/#Identifiers">UTS 35's Unicode Language and Locale Identifiers grammar</a>. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _loc_ be the *this* value.
1. If Type(_loc_) is not Object or _loc_ does not have an [[InitializedLocale]] internal slot, then
1. Throw a *TypeError* exception.
1. Let _locale_ be _loc_.[[Locale]].
1. Assert: _locale_ matches the `unicode_locale_id` production.
1. If the `unicode_language_id` production of _locale_ does not contain the `["-" unicode_script_subtag]` sequence, return *undefined*.
1. Return the substring of _locale_ corresponding to the `unicode_script_subtag` production of the `unicode_language_id`.
</emu-alg>
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype.region">
<h1>get Intl.Locale.prototype.region</h1>
<p>`Intl.Locale.prototype.region` is an accessor property whose set accessor function is *undefined*. The following algorithm refers to <a href="https://www.unicode.org/reports/tr35/#Identifiers">UTS 35's Unicode Language and Locale Identifiers grammar</a>. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _loc_ be the *this* value.
1. If Type(_loc_) is not Object or _loc_ does not have an [[InitializedLocale]] internal slot, then
1. Throw a *TypeError* exception.
1. Let _locale_ be _loc_.[[Locale]].
1. Assert: _locale_ matches the `unicode_locale_id` production.
1. If the `unicode_language_id` production of _locale_ does not contain the `["-" unicode_region_subtag]` sequence, return *undefined*.
1. Return the substring of _locale_ corresponding to the `unicode_region_subtag` production of the `unicode_language_id`.
</emu-alg>
</emu-clause>
</emu-clause>
</emu-clause>
<emu-clause id="sec-locale-modified-algorithms">
<h1>Modified algorithms</h1>
<emu-clause id="sec-canonicalizelanguagetag" aoid="CanonicalizeLanguageTag">
<h1><del>CanonicalizeLanguageTag</del><ins>CanonicalizeUnicodeLocaleId</ins> ( _locale_ )</h1>
<p>
The <del>CanonicalizeLanguageTag</del><ins>CanonicalizeUnicodeLocaleId</ins> abstract operation returns the canonical and case-regularized form of the _locale_ argument (which must be a String value that is a structurally valid Unicode BCP 47 Locale Identifier as verified by the IsStructurallyValidLanguageTag abstract operation).
<del>A conforming implementation shall take the steps specified in the “BCP 47 Language Tag to Unicode BCP 47 Locale Identifier” algorithm, from <a href="https://unicode.org/reports/tr35/#BCP_47_Language_Tag_Conversion">Unicode Technical Standard #35 LDML § 3.3.1 BCP 47 Language Tag Conversion</a>.</del>
<ins>The following steps are taken:</ins>
</p>
<emu-alg>
1. <ins>Let _localeId_ be the string _locale_ after performing the first step specified in the “<a href="https://www.unicode.org/reports/tr35/tr35.html#Language_Tag_to_Locale_Identifier">BCP 47 Language Tag to Unicode BCP 47 Locale Identifier</a>” algorithm, from <a href="https://unicode.org/reports/tr35/#BCP_47_Language_Tag_Conversion">Unicode Technical Standard #35 LDML § 3.3.1 BCP 47 Language Tag Conversion</a>, on it. (The result is a Unicode BCP 47 locale identifier, in canonical syntax but not necessarily in canonical form.)
1. <ins>Let _localeId_ be the string _localeId_ after performing the algorithm to <a href="https://unicode.org/reports/tr35/#Canonical_Unicode_Locale_Identifiers">transform it to canonical form</a>. (The result is a Unicode BCP 47 locale identifier, in both canonical syntax and canonical form.)
1. <ins>If _localeId_ contains a substring _extension_ that is a Unicode locale extension sequence, then
1. <ins>Let _components_ be ! UnicodeExtensionComponents(_extension_).
1. <ins>Let _attributes_ be _components_.[[Attributes]].
1. <ins>Let _keywords_ be _components_.[[Keywords]].
1. <ins>Let _newExtension_ be `"u"`.
1. <ins>For each element _attr_ of _attributes_ in List order, do
1. <ins>Append `"-"` to _newExtension_.
1. <ins>Append _attr_ to _newExtension_.
1. <ins>For each element _keyword_ of _keywords_ in List order, do
1. <ins>Append `"-"` to _newExtension_.
1. <ins>Append _keyword_.[[Key]] to _newExtension_.
1. <ins>If _keyword_.[[Value]] is not the empty String, then
1. <ins>Append `"-"` to _newExtension_.
1. <ins>Append _keyword_.[[Value]] to _newExtension_.
1. <ins>Assert: _newExtension_ is not equal to `"u"`.
1. <ins>Let _localeId_ be _localeId_ with the substring corresponding to _extension_ replaced by the string _newExtension_.
1. <ins>Return _localeId_.
</emu-alg>
<emu-note>
<ins>The third step of this algorithm ensures that a Unicode locale extension sequence in the returned language tag contains:</ins>
<ul>
<li><ins>only the first instance of any attribute duplicated in the input, and</ins></li>
<li><ins>only the first keyword for a given key in the input.</ins></li>
</ul>
</emu-note>
</emu-clause>
<emu-clause id="sec-canonicalizelocalelist" aoid="CanonicalizeLocaleList">
<h1>CanonicalizeLocaleList ( _locales_ )</h1>
<p>
The abstract operation CanonicalizeLocaleList takes the following steps:
</p>
<emu-alg>
1. If _locales_ is *undefined*, then
1. Return a new empty List.
1. Let _seen_ be a new empty List.
1. If Type(_locales_) is String <ins>or _locales_ has an [[InitializedLocale]] internal slot</ins>, then
1. Let _O_ be CreateArrayFromList(« _locales_ »).
1. Else,
1. Let _O_ be ? ToObject(_locales_).
1. Let _len_ be ? ToLength(? Get(_O_, `"length"`)).
1. Let _k_ be 0.
1. Repeat, while _k_ < _len_
1. Let _Pk_ be ToString(_k_).
1. Let _kPresent_ be ? HasProperty(_O_, _Pk_).
1. If _kPresent_ is *true*, then
1. Let _kValue_ be ? Get(_O_, _Pk_).
1. If Type(_kValue_) is not String or Object, throw a *TypeError* exception.
1. <ins>If Type(_kValue_) is Object and _kValue_ has an [[InitializedLocale]] internal slot, then</ins>
1. <ins>Let _tag_ be _kValue_.[[Locale]].</ins>
1. <ins>Else,</ins>
1. Let _tag_ be ? ToString(_kValue_).
1. If IsStructurallyValidLanguageTag(_tag_) is *false*, throw a *RangeError* exception.
1. Let _canonicalizedTag_ be <del>CanonicalizeLanguageTag</del><ins>CanonicalizeUnicodeLocaleId</ins>(_tag_).
1. If _canonicalizedTag_ is not an element of _seen_, append _canonicalizedTag_ as the last element of _seen_.
1. Increase _k_ by 1.
1. Return _seen_.
</emu-alg>
<emu-note type=editor>
When integrating into the main specification, the Intl.Locale object handling in this algorithm may be refactored to turn all strings into Intl.Locale instances, moving logic from ResolveLocale. This will be an editorial cleanup.
</emu-note>
</emu-clause>
<emu-clause id="sec-resolvelocale" aoid="ResolveLocale">
<h1>ResolveLocale ( _availableLocales_, _requestedLocales_, _options_, _relevantExtensionKeys_, _localeData_ )</h1>
<p>
The ResolveLocale abstract operation compares a BCP 47 language priority list _requestedLocales_ against the locales in _availableLocales_ and determines the best available language to meet the request. _availableLocales_, _requestedLocales_, and _relevantExtensionKeys_ must be provided as List values, _options_ and _localeData_ as Records.
</p>
<p>
The following steps are taken:
</p>
<emu-alg>
1. Let _matcher_ be _options_.[[localeMatcher]].
1. If _matcher_ is *"lookup"*, then
1. Let _r_ be LookupMatcher(_availableLocales_, _requestedLocales_).
1. Else,
1. Let _r_ be BestFitMatcher(_availableLocales_, _requestedLocales_).
1. Let _foundLocale_ be _r_.[[locale]].
1. Let _result_ be a new Record.
1. Set _result_.[[dataLocale]] to _foundLocale_.
1. Let _supportedExtension_ be *"-u"*.
1. For each element _key_ of _relevantExtensionKeys_ in List order, do
1. Let _foundLocaleData_ be _localeData_.[[<_foundLocale_>]].
1. Assert: Type(_foundLocaleData_) is Record.
1. Let _keyLocaleData_ be _foundLocaleData_.[[<_key_>]].
1. Assert: Type(_keyLocaleData_) is List.
1. Let _value_ be _keyLocaleData_[0].
1. Assert: Type(_value_) is either String or Null.
1. Let _supportedExtensionAddition_ be *""*.
1. If _r_ has an [[extension]] field, then
1. Let _requestedValue_ be UnicodeExtensionValue(_r_.[[extension]], _key_).
1. If _requestedValue_ is not *undefined*, then
1. If _requestedValue_ is not the empty String, then
1. If _keyLocaleData_ contains _requestedValue_, then
1. Let _value_ be _requestedValue_.
1. Let _supportedExtensionAddition_ be the string-concatenation of *"-"*, _key_, *"-"*, and _value_.
1. Else if _keyLocaleData_ contains *"true"*, then
1. Let _value_ be *"true"*.
1. Let _supportedExtensionAddition_ be the string-concatenation of *"-"* and _key_.
1. If _options_ has a field [[<_key_>]], then
1. Let _optionsValue_ be _options_.[[<_key_>]].
1. Assert: Type(_optionsValue_) is either String, Undefined, or Null.
1. If _keyLocaleData_ contains _optionsValue_, then
1. If SameValue(_optionsValue_, _value_) is *false*, then
1. Let _value_ be _optionsValue_.
1. Let _supportedExtensionAddition_ be *""*.
1. Set _result_.[[<_key_>]] to _value_.
1. Append _supportedExtensionAddition_ to _supportedExtension_.
1. If the number of elements in _supportedExtension_ is greater than 2, then
1. Let _privateIndex_ be Call(%StringProto_indexOf%, _foundLocale_, « *"-x-"* »).
1. If _privateIndex_ = -1, then
1. Let _foundLocale_ be the string-concatenation of _foundLocale_ and _supportedExtension_.
1. Else,
1. Let _preExtension_ be the substring of _foundLocale_ from position 0, inclusive, to position _privateIndex_, exclusive.
1. Let _postExtension_ be the substring of _foundLocale_ from position _privateIndex_ to the end of the string.
1. Let _foundLocale_ be the string-concatenation of _preExtension_, _supportedExtension_, and _postExtension_.
1. Assert: IsStructurallyValidLanguageTag(_foundLocale_) is *true*.
1. Let _foundLocale_ be <del>CanonicalizeLanguageTag</del><ins>CanonicalizeUnicodeLocaleId</ins>(_foundLocale_).
1. Set _result_.[[locale]] to _foundLocale_.
1. Return _result_.
</emu-alg>
<emu-note>
Non-normative summary: Two algorithms are available to match the locales: the Lookup algorithm described in RFC 4647 section 3.4, and an implementation dependent best-fit algorithm. Independent of the locale matching algorithm, options specified through Unicode locale extension sequences are negotiated separately, taking the caller's relevant extension keys and locale data as well as client-provided options into consideration. The abstract operation returns a record with a [[locale]] field whose value is the language tag of the selected locale, and fields for each key in _relevantExtensionKeys_ providing the selected value for that key.
</emu-note>
</emu-clause>
</emu-clause>