diff --git a/index.bs b/index.bs
index c6e4dd42..8655b60a 100644
--- a/index.bs
+++ b/index.bs
@@ -2279,7 +2279,7 @@ corresponding argument omitted.
If the type of an argument is a [=dictionary type=] or a [=union type=] that has
a [=dictionary type=] as one
of its [=flattened member types=], and that dictionary type and its ancestors have no
-[=required dictionary member|required members=], and the argument is either the final argument or is
+[=dictionary member/required=] [=dictionary member|members=], and the argument is either the final argument or is
followed only by [=optional arguments=], then the argument must be specified as
optional and have a default value provided.
@@ -3877,8 +3877,8 @@ defined with [=optional arguments=] and merged into one,
};
-the [=overload resolution algorithm=] would treat the path argument as [=not
-present=] given the same call stroke(undefined)
, and not throw any exceptions.
+the [=overload resolution algorithm=] would treat the path argument as missing
+given the same call stroke(undefined)
, and not throw any exceptions.
Note: For this particular example, the latter behavior is actually what Web developers would
generally expect. If {{CanvasDrawPath}} were to be designed today, [=optional arguments=] would be
@@ -4062,8 +4062,7 @@ determine what Web IDL language feature to use:
class="idl">foo(|arg|) operation, with |arg| set to null, while foo()
alone
would go to the first overload. This can be a surprising behavior for many API users. Instead,
specification authors are encouraged to use an [=optional argument=], which would categorize
- both foo()
and foo(undefined)
as "|arg| is [=not
- present=]".
+ both foo()
and foo(undefined)
as "|arg| is missing".
interface A { @@ -4741,9 +4740,15 @@ where [=map/keys=] are strings and [=map/values=] are of a particular type speci };-Dictionaries are always passed by value. In language bindings where a dictionary is represented by an object of some kind, passing a -dictionary to a [=platform object=] will not result in a reference to the dictionary being kept by that object. -Similarly, any dictionary returned from a platform object will be a copy and modifications made to it will not be visible to the platform object. +Dictionary instances do not retain a reference to their language-specific representations (e.g., +the corresponding ECMAScript object). So for example, returning a dictionary from an [=operation=] +will result in a new ECMAScript object being created from the current values of the dictionary. And, +an operation that accepts a dictionary as an argument will perform a one-time conversion from the +given ECMAScript value into the dictionary, based on the current properties of the ECMAScript +object. Modifications to the dictionary will not be reflected in the corresponding ECMAScript +object, and vice-versa. + +Dictionaries must not be used as the type of an [=attribute=] or [=constant=]. A dictionary can be defined to inherit from another dictionary. If the identifier of the dictionary is followed by a colon and a [=identifier=], @@ -4772,30 +4777,49 @@ from another dictionary, then the set is empty. Otherwise, the set includes the dictionary |E| that |D| [=interface/inherits=] from and all of |E|’s [=inherited dictionaries=]. -A dictionary value of type |D| can have key–value pairs corresponding -to the dictionary members defined on |D| and on any of |D|’s -[=inherited dictionaries=]. -On a given dictionary value, the presence of each dictionary member -is optional, unless that member is specified as required. -A dictionary member is said to be -present -in a dictionary value if the value [=map/exists|contains an entry with the key=] -given by the member's [=identifier=], otherwise it is [=not present=]. -Dictionary members can also optionally have a default value, which is -the value to use for the dictionary member when passing a value to a -[=platform object=] that does -not have a specified value. Dictionary members with default values are -always considered to be present. +[=Dictionary members=] can be specified as +required, meaning that +converting a language-specific value to a dictionary requires providing a value for that member. Any +dictionary member that is not [=dictionary member/required=] is +optional. + +Note that specifying [=dictionary members=] as [=dictionary member/required=] only has +an observable effect when converting other representations of dictionaries (like an ECMAScript value +supplied as an argument to an [=operation=]) to an IDL dictionary. Specification authors should +leave the members [=dictionary member/optional=] in all other cases, including when a dictionary +type is used solely as the [=return type=] of [=operations=]. + +[=dictionary member/Optional=] [=dictionary members=] can also be specified as having a +default value, +which is the value used by default when author code or specification text does not provide a value +for that member. + +A given dictionary value of type |D| can have [=map/entries=] for each of the dictionary members +defined on |D| and on any of |D|’s [=inherited dictionaries=]. Dictionary members that are specified +as [=dictionary member/required=], or that are specified as having a +[=dictionary member/default value=], will always have such corresponding [=map/entries=]. Other +members' entries might or might not [=map/exist=] in the dictionary value.
- In the ECMAScript binding, a value of
+ As with [=optional argument/default value|operation argument default values=], it is strongly
+ encouraged not to use
@@ -4811,16 +4835,6 @@ dictionary members. 1. Return «[ "name" → "test", "serviceIdentifiers" → |identifiers| ]».
- As with [=optional argument/default value|operation argument default values=],
- it is strongly suggested not to use
dictionary identifier { @@ -5000,10 +5013,6 @@ The identifier of a dictionary member must not be the same as that of another dictionary member defined on the dictionary or on that dictionary’s [=inherited dictionaries=]. -Dictionaries must not be used as the type of an -[=attribute=] or -[=constant=]. - No [=extended attributes=] are applicable to dictionaries. @@ -7756,9 +7765,7 @@ the object (or its prototype chain) correspond to [=dictionary members=]. running the following algorithm (where |D| is the [=dictionary type=]): 1. If Type(|esDict|) is not Undefined, Null or Object, then [=ECMAScript/throw=] a {{ECMAScript/TypeError}}. - 1. Let |idlDict| be an empty dictionary value of type |D|; - every [=dictionary member=] - is initially considered to be [=not present=]. + 1. Let |idlDict| be an empty [=ordered map=], representing a dictionary of type |D|. 1. Let |dictionaries| be a list consisting of |D| and all of |D|’s [=inherited dictionaries=], in order from least to most derived. 1. For each dictionary |dictionary| in |dictionaries|, in order: @@ -7774,13 +7781,12 @@ the object (or its prototype chain) correspond to [=dictionary members=]. 1. If |esMemberValue| is notundefined , then: 1. Let |idlMemberValue| be the result of [=converted to an IDL value|converting=] |esMemberValue| to an IDL value whose type is the type |member| is declared to be of. - 1. Set the dictionary member on |idlDict| with key name |key| to the value |idlMemberValue|. This dictionary member is considered to be [=present=]. + 1. [=map/Set=] |idlDict|[|key|] to |idlMemberValue|. 1. Otherwise, if |esMemberValue| isundefined but |member| has a [=dictionary member/default value=], then: 1. Let |idlMemberValue| be |member|’s default value. - 1. Set the dictionary member on |idlDict| with key name |key| to the value |idlMemberValue|. This dictionary member is considered to be [=present=]. - 1. Otherwise, if |esMemberValue| is -undefined and |member| is a - [=required dictionary member=], then throw a {{ECMAScript/TypeError}}. + 1. [=map/Set=] |idlDict|[|key|] to |idlMemberValue|. + 1. Otherwise, if |esMemberValue| isundefined and |member| is + [=dictionary member/required=], then throw a {{ECMAScript/TypeError}}. 1. Return |idlDict|. @@ -7799,10 +7805,13 @@ up on the ECMAScript object are not necessarily the same as the object’s prope 1. For each dictionary |dictionary| in |dictionaries|, in order: 1. For each dictionary member |member| declared on |dictionary|, in lexicographical order: 1. Let |key| be the [=identifier=] of |member|. - 1. If the dictionary member named |key| is [=present=] in |V|, then: - 1. Let |idlValue| be the value of |member| on |V|. + 1. If |V|[|key|] [=map/exists=], then: + 1. Let |idlValue| be |V|[|key|]. 1. Let |value| be the result of [=converted to an ECMAScript value|converting=] |idlValue| to an ECMAScript value. 1. Perform [=!=] CreateDataProperty(|O|, |key|, |value|). + +Recall that if |member| has a [=dictionary member/default value=], + then |key| will always [=map/exist=] in |V|.
1. Return |O|.