From 4d1a24ac5b20e37026f698289eb780c434777dcd Mon Sep 17 00:00:00 2001 From: Zibi Braniecki Date: Wed, 26 Feb 2020 15:54:31 -0800 Subject: [PATCH] Normative: Adding Intl.Locale specification. (#406) --- spec/annexes.html | 2 +- spec/conventions.html | 10 + spec/index.html | 1 + spec/locale.html | 431 ++++++++++++++++++++++++++++++++ spec/locales-currencies-tz.html | 41 ++- spec/negotiation.html | 13 +- 6 files changed, 487 insertions(+), 11 deletions(-) create mode 100644 spec/locale.html diff --git a/spec/annexes.html b/spec/annexes.html index 86aed836..c91bc4f7 100644 --- a/spec/annexes.html +++ b/spec/annexes.html @@ -13,7 +13,7 @@

Implementation Dependent Behaviour

Additional values for some properties of _options_ arguments ()
  • - Canonicalization of extension subtag sequences beyond the rules of RFC 5646 () + Canonicalization of extension subtag sequences beyond the rules of RFC 5646 ()
  • The default locale () diff --git a/spec/conventions.html b/spec/conventions.html index a4d4b042..fb7eeafb 100644 --- a/spec/conventions.html +++ b/spec/conventions.html @@ -106,6 +106,16 @@

    Well-Known Intrinsic Objects

    `Intl.RelativeTimeFormat.prototype` The initial value of the `prototype` data property of the intrinsic %RelativeTimeFormat% (). + + %Locale% + `Intl.Locale` + The `Intl.Locale` constructor (). + + + %LocalePrototype% + `Intl.Locale.prototype` + The initial value of the `prototype` data property of the intrinsic %Locale% (). + diff --git a/spec/index.html b/spec/index.html index a4eae871..54db6cf8 100644 --- a/spec/index.html +++ b/spec/index.html @@ -82,6 +82,7 @@ + diff --git a/spec/locale.html b/spec/locale.html new file mode 100644 index 00000000..1eb98a29 --- /dev/null +++ b/spec/locale.html @@ -0,0 +1,431 @@ + +

    Locale Objects

    + + +

    The Intl.Locale Constructor

    + +

    + The Locale constructor is the %Locale% intrinsic object and a standard built-in property of the Intl object. Behaviour common to all service constructor properties of the Intl object is specified in . +

    + + +

    ApplyOptionsToTag( _tag_, _options_ )

    +

    + The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar. +

    + + + 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` production, 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` production, 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_language_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 `"-"` and 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_). + +
    + + +

    ApplyUnicodeExtensionToTag( _tag_, _options_, _relevantExtensionKeys_ )

    +

    + The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar. +

    + + + 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_. + +
    + + +

    UnicodeExtensionComponents( _extension_ )

    +

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

    + + + 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_}. + +
    + + +

    InsertUnicodeExtensionAndCanonicalize( _locale_, _extension_ )

    +

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

    +

    + The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar. +

    + + + 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_). + +
    + + +

    Intl.Locale( _tag_ [, _options_] )

    + +

    + The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar. + + When the *Intl.Locale* function is called with an argument _tag_ and an optional argument _options_, the following steps are taken: +

    + + + 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 UTS 35 Unicode Locale Identifier, section 3.2), 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 UTS 35 Unicode Locale Identifier, section 3.2), 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 UTS 35 Unicode Locale Identifier, section 3.2), 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_. + +
    +
    + + +

    Properties of the Intl.Locale Constructor

    + +

    + The Intl.Locale constructor has the following properties: +

    + + +

    Intl.Locale.prototype

    + +

    + The value of *Intl.Locale.prototype* is *%LocalePrototype%*. +

    +

    + This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }. +

    +
    + + +

    Internal slots

    + +

    + 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]]. +

    +
    +
    + + +

    Properties of the Intl.Locale Prototype Object

    + +

    + 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. +

    + + +

    Intl.Locale.prototype.constructor

    + +

    + The initial value of *Intl.Locale.prototype.constructor* is *%Locale%*. +

    +
    + + +

    Intl.Locale.prototype[ @@toStringTag ]

    + +

    + The initial value of the @@toStringTag property is the string value *"Intl.Locale"*. +

    + +

    + This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }. +

    +
    + + +

    Intl.Locale.prototype.maximize ()

    + + + 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 Add Likely Subtags algorithm applied to _loc_.[[Locale]]. If an error is signaled, set _maximal_ to _loc_.[[Locale]]. + 1. Return ! Construct(%Locale%, _maximal_). + +
    + + +

    Intl.Locale.prototype.minimize ()

    + + + 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 Remove Likely Subtags algorithm applied to _loc_.[[Locale]]. If an error is signaled, set _minimal_ to _loc_.[[Locale]]. + 1. Return ! Construct(%Locale%, _minimal_). + +
    + + +

    Intl.Locale.prototype.toString ()

    + + + 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]]. + +
    + + +

    get Intl.Locale.prototype.baseName

    +

    `Intl.Locale.prototype.baseName` is an accessor property whose set accessor function is *undefined*. The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar. Its get accessor function performs the following steps:

    + + 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. +
    + + +

    get Intl.Locale.prototype.calendar

    +

    `Intl.Locale.prototype.calendar` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:

    + + 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]]. + +
    + + +

    get Intl.Locale.prototype.caseFirst

    +

    This property only exists if %Locale%.[[RelevantExtensionKeys]] contains *"kf"*.

    +

    `Intl.Locale.prototype.caseFirst` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:

    + + 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]]. + +
    + + +

    get Intl.Locale.prototype.collation

    +

    `Intl.Locale.prototype.collation` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:

    + + 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]]. + +
    + + +

    get Intl.Locale.prototype.hourCycle

    +

    `Intl.Locale.prototype.hourCycle` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:

    + + 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]]. + +
    + + +

    get Intl.Locale.prototype.numeric

    +

    This property only exists if %Locale%.[[RelevantExtensionKeys]] contains *"kn"*.

    +

    `Intl.Locale.prototype.numeric` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:

    + + 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]]. + +
    + + +

    get Intl.Locale.prototype.numberingSystem

    +

    `Intl.Locale.prototype.numberingSystem` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:

    + + 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]]. + +
    + + +

    get Intl.Locale.prototype.language

    +

    `Intl.Locale.prototype.language` is an accessor property whose set accessor function is *undefined*. The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar. Its get accessor function performs the following steps:

    + + 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`. + +
    + + +

    get Intl.Locale.prototype.script

    +

    `Intl.Locale.prototype.script` is an accessor property whose set accessor function is *undefined*. The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar. Its get accessor function performs the following steps:

    + + 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`. + +
    + + +

    get Intl.Locale.prototype.region

    +

    `Intl.Locale.prototype.region` is an accessor property whose set accessor function is *undefined*. The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar. Its get accessor function performs the following steps:

    + + 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`. + +
    +
    +
    diff --git a/spec/locales-currencies-tz.html b/spec/locales-currencies-tz.html index d7eda591..615a06e5 100644 --- a/spec/locales-currencies-tz.html +++ b/spec/locales-currencies-tz.html @@ -54,20 +54,51 @@

    IsStructurallyValidLanguageTag ( _locale_ )

    - -

    CanonicalizeLanguageTag ( _locale_ )

    + +

    CanonicalizeUnicodeLocaleId ( _locale_ )

    - The CanonicalizeLanguageTag 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). - A conforming implementation shall take the steps specified in the “BCP 47 Language Tag to Unicode BCP 47 Locale Identifier” algorithm, from Unicode Technical Standard #35 LDML § 3.3.1 BCP 47 Language Tag Conversion. + The CanonicalizeUnicodeLocaleId 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). + The following steps are taken:

    + + + 1. Let _localeId_ be the string _locale_ after performing the steps specified in the “BCP 47 Language Tag to Unicode BCP 47 Locale Identifier” algorithm, from Unicode Technical Standard #35 LDML § 3.3.1 BCP 47 Language Tag Conversion, on it. (The result is a Unicode BCP 47 locale identifier, in canonical syntax but not necessarily in canonical form.) + 1. Let _localeId_ be the string _localeId_ after performing the algorithm to transform it to canonical form. (The result is a Unicode BCP 47 locale identifier, in both canonical syntax and canonical form.) + 1. If _localeId_ contains a substring _extension_ that is a Unicode locale extension sequence, then + 1. Let _components_ be ! UnicodeExtensionComponents(_extension_). + 1. Let _attributes_ be _components_.[[Attributes]]. + 1. Let _keywords_ be _components_.[[Keywords]]. + 1. Let _newExtension_ be *"u"*. + 1. For each element _attr_ of _attributes_ in List order, do + 1. Append *"-"* to _newExtension_. + 1. Append _attr_ to _newExtension_. + 1. For each element _keyword_ of _keywords_ in List order, do + 1. Append *"-"* to _newExtension_. + 1. Append _keyword_.[[Key]] to _newExtension_. + 1. If _keyword_.[[Value]] is not the empty String, then + 1. Append *"-"* to _newExtension_. + 1. Append _keyword_.[[Value]] to _newExtension_. + 1. Assert: _newExtension_ is not equal to *"u"*. + 1. Let _localeId_ be _localeId_ with the substring corresponding to _extension_ replaced by the string _newExtension_. + 1. Return _localeId_. + + + + The third step of this algorithm ensures that a Unicode locale extension sequence in the returned language tag contains: + +
      +
    • only the first instance of any attribute duplicated in the input, and
    • +
    • only the first keyword for a given key in the input.
    • +
    +

    DefaultLocale ()

    - The DefaultLocale abstract operation returns a String value representing the structurally valid () and canonicalized () BCP 47 language tag for the host environment's current locale. + The DefaultLocale abstract operation returns a String value representing the structurally valid () and canonicalized () BCP 47 language tag for the host environment's current locale.

    diff --git a/spec/negotiation.html b/spec/negotiation.html index 180ffcc3..cc44dfa5 100644 --- a/spec/negotiation.html +++ b/spec/negotiation.html @@ -13,7 +13,7 @@

    Internal slots of Service Constructors

      -
    • [[AvailableLocales]] is a List that contains structurally valid () and canonicalized () BCP 47 language tags identifying the locales for which the implementation provides the functionality of the constructed objects. Language tags on the list must not have a Unicode locale extension sequence. The list must include the value returned by the DefaultLocale abstract operation (), and must not include duplicates. Implementations must include in [[AvailableLocales]] locales that can serve as fallbacks in the algorithm used to resolve locales (see ). For example, implementations that provide a *"de-DE"* locale must include a *"de"* locale that can serve as a fallback for requests such as *"de-AT"* and *"de-CH"*. For locales that in current usage would include a script subtag (such as Chinese locales), old-style language tags without script subtags must be included such that, for example, requests for *"zh-TW"* and *"zh-HK"* lead to output in traditional Chinese rather than the default simplified Chinese. The ordering of the locales within [[AvailableLocales]] is irrelevant.
    • +
    • [[AvailableLocales]] is a List that contains structurally valid () and canonicalized () BCP 47 language tags identifying the locales for which the implementation provides the functionality of the constructed objects. Language tags on the list must not have a Unicode locale extension sequence. The list must include the value returned by the DefaultLocale abstract operation (), and must not include duplicates. Implementations must include in [[AvailableLocales]] locales that can serve as fallbacks in the algorithm used to resolve locales (see ). For example, implementations that provide a *"de-DE"* locale must include a *"de"* locale that can serve as a fallback for requests such as *"de-AT"* and *"de-CH"*. For locales that in current usage would include a script subtag (such as Chinese locales), old-style language tags without script subtags must be included such that, for example, requests for *"zh-TW"* and *"zh-HK"* lead to output in traditional Chinese rather than the default simplified Chinese. The ordering of the locales within [[AvailableLocales]] is irrelevant.
    • [[RelevantExtensionKeys]] is a List of keys of the language tag extensions defined in Unicode Technical Standard 35 that are relevant for the functionality of the constructed objects.
    • [[SortLocaleData]] and [[SearchLocaleData]] (for Intl.Collator) and [[LocaleData]] (for Intl.NumberFormat, Intl.DateTimeFormat, and Intl.PluralRules) are records that have fields for each locale contained in [[AvailableLocales]]. The value of each of these fields must be a record that has fields for each key contained in [[RelevantExtensionKeys]]. The value of each of these fields must be a non-empty list of those values defined in Unicode Technical Standard 35 for the given key that are supported by the implementation for the given locale, with the first element providing the default value.
    @@ -41,7 +41,7 @@

    CanonicalizeLocaleList ( _locales_ )

    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, then + 1. If Type(_locales_) is String or _locales_ has an [[InitializedLocale]] internal slot, then 1. Let _O_ be CreateArrayFromList(« _locales_ »). 1. Else, 1. Let _O_ be ? ToObject(_locales_). @@ -53,9 +53,12 @@

    CanonicalizeLocaleList ( _locales_ )

    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. Let _tag_ be ? ToString(_kValue_). + 1. If Type(_kValue_) is Object and _kValue_ has an [[InitializedLocale]] internal slot, then + 1. Let _tag_ be _kValue_.[[Locale]]. + 1. Else, + 1. Let _tag_ be ? ToString(_kValue_). 1. If IsStructurallyValidLanguageTag(_tag_) is *false*, throw a *RangeError* exception. - 1. Let _canonicalizedTag_ be CanonicalizeLanguageTag(_tag_). + 1. Let _canonicalizedTag_ be CanonicalizeUnicodeLocaleId(_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_. @@ -219,7 +222,7 @@

    ResolveLocale ( _availableLocales_, _requestedLocales_, _options_, _relevant 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 CanonicalizeLanguageTag(_foundLocale_). + 1. Let _foundLocale_ be CanonicalizeUnicodeLocaleId(_foundLocale_). 1. Set _result_.[[locale]] to _foundLocale_. 1. Return _result_.