1. Introduction
This section is informative.
Technical reports published by the W3C that include programming language interfaces have typically been described using the Object Management Group’s Interface Definition Language (IDL) [OMGIDL] . The IDL provides a means to describe these interfaces in a language independent manner. Usually, additional language binding appendices are included in such documents which detail how the interfaces described with the IDL correspond to constructs in the given language.
However,
the
bindings
in
these
specifications
for
the
language
most
commonly
used
on
the
web,
ECMAScript,
are
consistently
specified
with
low
enough
precision
as
to
result
in
interoperability
issues.
In
addition,
each
specification
must
describe
the
same
basic
information,
such
as
DOM
interfaces
described
in
IDL
corresponding
to
properties
on
the
ECMAScript
global
object,
or
the
unsigned
long
IDL
type
mapping
to
the
Number
type
in
ECMAScript.
This specification defines an IDL language similar to OMG IDL for use by specifications that define interfaces for Web APIs. A number of extensions are given to the IDL to support common functionality that previously must have been written in prose. In addition, precise language bindings for the ECMAScript language are given.
2. Interface definition language
This
section
describes
a
language,
Web
IDL
,
which
can
be
used
to
define
interfaces
for
APIs
in
the
Web
platform.
A
specification
that
defines
Web
APIs
can
include
one
or
more
IDL
fragments
that
describe
the
interfaces
(the
state
and
behavior
that
objects
can
exhibit)
for
the
APIs
defined
by
that
specification.
An
IDL
fragment
is
a
sequence
of
definitions
that
matches
the
The different kinds of definitions that can appear in an IDL fragment are: interfaces , partial interface definitions , interface mixins , partial mixin definitions , callback functions , callback interfaces , namespaces , partial namespace definitions , dictionaries , partial dictionary definitions , typedefs and includes statements . These are all defined in the following sections.
Each
definition
(matching
[extended_attributes ]interface identifier { /* interface_members... */ };
Definitions ::ExtendedAttributeList Definition Definitions ε
Definition ::CallbackOrInterfaceOrMixin Namespace Partial Dictionary Enum Typedef IncludesStatement
The following is an example of an IDL fragment .
[Exposed =Window ]interface Paint { }; [Exposed =Window ]interface SolidColor :Paint {attribute double red ;attribute double green ;attribute double blue ; }; [Exposed =Window ]interface Pattern :Paint {attribute DOMString imageURL ; }; [Exposed =Window ]interface GraphicalWindow {constructor ();readonly attribute unsigned long width ;readonly attribute unsigned long height ;attribute Paint currentPaint ;void drawRectangle (double x ,double y ,double width ,double height );void drawText (double x ,double y ,DOMString text ); };
Here,
four
interfaces
are
being
defined.
The
GraphicalWindow
interface
has
two
read
only
attributes
,
one
writable
attribute,
and
two
operations
defined
on
it.
Objects
that
implement
the
GraphicalWindow
interface
will
expose
these
attributes
and
operations
in
a
manner
appropriate
to
the
particular
language
being
used.
In
ECMAScript,
the
attributes
on
the
IDL
interfaces
will
be
exposed
as
accessor
properties
and
the
operations
as
data
properties
whose
value
is
a
built-in
function
object
on
a
prototype
object
for
all
GraphicalWindow
objects;
each
ECMAScript
object
that
implements
GraphicalWindow
will
have
that
prototype
object
in
its
prototype
chain.
The
constructor
operation
that
appears
on
GraphicalWindow
causes
a
constructor
to
exist
in
ECMAScript
implementations,
so
that
calling
new
GraphicalWindow()
would
return
a
new
object
that
implemented
the
interface.
All
interfaces
have
the
[
Exposed
]
extended
attribute
,
which
ensures
the
interfaces
are
only
available
in
Realms
whose
global
object
is
a
Window
object.
2.1. Names
Every
interface
,
partial
interface
definition
,
namespace
,
partial
namespace
definition
,
dictionary
,
partial
dictionary
definition
,
enumeration
,
callback
function
,
callback
interface
and
typedef
(together
called
named
definitions
)
and
every
constant
,
attribute
,
and
dictionary
member
has
an
identifier
,
as
do
some
operations
.
The
identifier
is
determined
by
an
-
For named definitions , the
identifier token that appears directly after theinterface ,namespace ,dictionary ,enum orcallback keyword determines the identifier of that definition.interface interface_identifier { /* interface_members... */ };partial interface interface_identifier { /* interface_members... */ };namespace namespace_identifier { /* namespace_members... */ };partial namespace namespace_identifier { /* namespace_members... */ };dictionary dictionary_identifier { /* dictionary_members... */ };partial dictionary dictionary_identifier { /* dictionary_members... */ };enum enumeration_identifier {"enum" ,"values" /* , ... */ };callback callback_identifier =return_type (/* arguments... */);callback interface callback_interface_identifier { /* interface_members... */ }; -
For attributes , typedefs and dictionary members , the final
identifier token before the semicolon at the end of the declaration determines the identifier.[
extended_attributes ]interface identifier {attribute type attribute_identifier ; };typedef type typedef_identifier ;dictionary identifier {type dictionary_member_identifier ; }; -
For constants , the
identifier token before the equals sign determines the identifier.const type constant_identifier = 42; -
For operations , the
identifier token that appears after the return type but before the opening parenthesis (that is, one that is matched as part of theOptionalOperationName grammar symbol in anOperationRest ) determines the identifier of the operation. If there is no suchidentifier token, then the operation does not have an identifier.interface interface_identifier {return_type operation_identifier (/* arguments... */); };
Note: Operations can have no identifier when they are being used to declare a special kind of operation , such as a getter or setter.
For
all
of
these
constructs,
the
identifier
is
the
value
of
the
Note:
A
leading
"_"
is
used
to
escape
an
identifier
from
looking
like
a
reserved
word
so
that,
for
example,
an
interface
named
"
interface
"
can
be
defined.
The
leading
"_"
is
dropped
to
unescape
the
identifier.
Operation
arguments
can
take
a
slightly
wider
set
of
identifiers.
In
an
operation
declaration,
the
identifier
of
an
argument
is
specified
immediately
after
its
type
and
is
given
by
either
an
interface interface_identifier {return_type operation_identifier (argument_type argument_identifier /* , ... */); };
ArgumentNameKeyword ::async attribute callback const constructor deleter dictionary enum getter includes inherit interface iterable maplike mixin namespace partial readonly required setlike setter static stringifier typedef unrestricted
If
an
The
identifier
of
any
of
the
abovementioned
IDL
constructs
(except
operation
arguments)
must
not
be
"
constructor
",
"
toString
",
or
begin
with
a
U+005F
LOW
LINE
("_")
character.
These
are
known
as
reserved
identifiers
.
Although
the
"
toJSON
"
identifier
is
not
a
reserved
identifier
,
it
must
only
be
used
for
regular
operations
that
convert
objects
to
JSON
types
,
as
described
in
§ 2.5.3.1
toJSON
.
Note: Further restrictions on identifier names for particular constructs may be made in later sections.
Within the set of IDL fragments that a given implementation supports, the identifier of every interface , namespace , dictionary , enumeration , callback function , callback interface and typedef must not be the same as the identifier of any other interface , namespace , dictionary , enumeration , callback function , callback interface or typedef .
Within an IDL fragment , a reference to a definition need not appear after the declaration of the referenced definition. References can also be made across IDL fragments .
Therefore, the following IDL fragment is valid:
[Exposed =Window ]interface B :A {void f (SequenceOfLongs x ); }; [Exposed =Window ]interface A { };typedef sequence <long >SequenceOfLongs ;
The following IDL fragment demonstrates how identifiers are given to definitions and interface members .
// Typedef identifier: "number"typedef double number ; // Interface identifier: "System" [Exposed =Window ]interface System { // Operation identifier: "createObject" // Operation argument identifier: "interface"object createObject (DOMString _interface ); // Operation argument identifier: "interface"sequence <object >getObjects (DOMString interface ); // Operation has no identifier; it declares a getter.getter DOMString (DOMString keyName ); }; // Interface identifier: "TextField" [Exposed =Window ]interface TextField { // Attribute identifier: "const"attribute boolean _const ; // Attribute identifier: "value"attribute DOMString ?_value ; };
Note
that
while
the
second
attribute
on
the
TextField
interface
need
not
have
been
escaped
with
an
underscore
(because
"
value
"
is
not
a
keyword
in
the
IDL
grammar),
it
is
still
unescaped
to
obtain
the
attribute’s
identifier
.
2.2. Interfaces
IDL
fragments
are
used
to
describe
object
oriented
systems.
In
such
systems,
objects
are
entities
that
have
identity
and
which
are
encapsulations
of
state
and
behavior.
An
interface
is
a
definition
(matching
[extended_attributes ]interface identifier { /* interface_members... */ };
An
interface
is
a
specification
of
a
set
of
interface
members
(matching
Interfaces in Web IDL describe how objects that implement the interface behave. In bindings for object oriented languages, it is expected that an object that implements a particular IDL interface provides ways to inspect and modify the object’s state and to invoke the behavior described by the interface.
An interface can be defined to inherit from another interface. If the identifier of the interface is followed by a U+003A COLON (":") character and an identifier , then that identifier identifies the inherited interface. An object that implements an interface that inherits from another also implements that inherited interface. The object therefore will also have members that correspond to the interface members from the inherited interface.
interface identifier :identifier_of_inherited_interface { /* interface_members... */ };
The order that members appear in has significance for property enumeration in the ECMAScript binding .
Interfaces may specify an interface member that has the same name as one from an inherited interface. Objects that implement the derived interface will expose the member on the derived interface. It is language binding specific whether the overridden member can be accessed on the object.
Consider the following two interfaces.
[Exposed =Window ]interface A {void f ();void g (); }; [Exposed =Window ]interface B :A {void f ();void g (DOMString x ); };
In
the
ECMAScript
language
binding,
an
instance
of
B
will
have
a
prototype
chain
that
looks
like
the
following:
[Object.prototype: the Object prototype object] ↑ [A.prototype: interface prototype object for A] ↑ [B.prototype: interface prototype object for B] ↑ [instanceOfB]
Calling
instanceOfB.f()
in
ECMAScript
will
invoke
the
f
defined
on
B
.
However,
the
f
from
A
can
still
be
invoked
on
an
object
that
implements
B
by
calling
A.prototype.f.call(instanceOfB)
.
The inherited interfaces of a given interface A is the set of all interfaces that A inherits from, directly or indirectly. If A does not inherit from another interface, then the set is empty. Otherwise, the set includes the interface B that A inherits from and all of B ’s inherited interfaces .
An interface must not be declared such that its inheritance hierarchy has a cycle. That is, an interface A cannot inherit from itself, nor can it inherit from another interface B that inherits from A , and so on.
Note that general multiple inheritance of interfaces is not supported, and objects also cannot implement arbitrary sets of interfaces. Objects can be defined to implement a single given interface A , which means that it also implements all of A ’s inherited interfaces . In addition, an includes statement can be used to define that objects implementing an interface A will always also include the members of the interface mixins A includes .
Each
interface
member
can
be
preceded
by
a
list
of
extended
attributes
(matching
[extended_attributes ]interface identifier { [extended_attributes ]const type constant_identifier = 42; [extended_attributes ]attribute type identifier ; [extended_attributes ]return_type identifier (/* arguments... */); };
The
IDL
for
interfaces
can
be
split
into
multiple
parts
by
using
partial
interface
definitions
(matching
interface SomeInterface { /* interface_members... */ };partial interface SomeInterface { /* interface_members... */ };
Note: Partial interface definitions are intended for use as a specification editorial aide, allowing the definition of an interface to be separated over more than one section of the document, and sometimes multiple documents.
The order of appearance of an interface definition and any of its partial interface definitions does not matter.
Note: A partial interface definition cannot specify that the interface inherits from another interface. Inheritance must be specified on the original interface definition.
The relevant language binding determines how interfaces correspond to constructs in the language.
The
following
extended
attributes
are
applicable
to
interfaces:
[
Exposed
],
[
Global
],
[
LegacyWindowAlias
],
[
LegacyFactoryFunction
],
[
LegacyNoInterfaceObject
],
[
LegacyOverrideBuiltIns
],
and
[
SecureContext
].
The
following
extended
attributes
are
applicable
to
partial
interfaces
:
[
Exposed
],
[
LegacyOverrideBuiltIns
],
and
[
SecureContext
].
Interfaces
which
are
not
annotated
with
a
[
LegacyNoInterfaceObject
]
extended
attribute
must
be
annotated
with
an
[
Exposed
]
extended
attribute
.
The qualified name of an interface interface is defined as follows:
-
Let identifier be the identifier of interface .
-
If interface has a [
LegacyNamespace
] extended attribute , then:-
Let namespace be the identifier argument of the [
LegacyNamespace
] extended attribute . -
Return the concatenation of « namespace , identifier » with separator U+002E FULL STOP (".") .
-
-
Return identifier .
CallbackOrInterfaceOrMixin ::callback CallbackRestOrInterface interface InterfaceOrMixin
InterfaceOrMixin ::InterfaceRest MixinRest
InterfaceRest ::identifier Inheritance { InterfaceMembers } ;
Partial ::partial PartialDefinition
PartialDefinition ::interface PartialInterfaceOrPartialMixin PartialDictionary Namespace
PartialInterfaceOrPartialMixin ::PartialInterfaceRest MixinRest
PartialInterfaceRest ::identifier { PartialInterfaceMembers } ;
InterfaceMembers ::ExtendedAttributeList InterfaceMember InterfaceMembers ε
InterfaceMember ::PartialInterfaceMember Constructor
PartialInterfaceMembers ::ExtendedAttributeList PartialInterfaceMember PartialInterfaceMembers ε
PartialInterfaceMember ::Const Operation Stringifier StaticMember Iterable AsyncIterable ReadOnlyMember ReadWriteAttribute ReadWriteMaplike ReadWriteSetlike
Inheritance ::: identifier ε
The
following
IDL
fragment
demonstrates
the
definition
of
two
mutually
referential
interfaces
.
Both
Human
and
Dog
inherit
from
Animal
.
Objects
that
implement
either
of
those
two
interfaces
will
thus
have
a
name
attribute.
[Exposed =Window ]interface Animal {attribute DOMString name ; }; [Exposed =Window ]interface Human :Animal {attribute Dog ?pet ; }; [Exposed =Window ]interface Dog :Animal {attribute Human ?owner ; };
The following IDL fragment defines simplified versions of a DOM interfaces and a callback interface .
[Exposed =Window ]interface Node {readonly attribute DOMString nodeName ;readonly attribute Node ?parentNode ;Node appendChild (Node newChild );void addEventListener (DOMString type ,EventListener listener ); };callback interface EventListener {void handleEvent (Event event ); };
Plain
objects
can
implement
a
callback
interface
like
EventListener
:
var node= getNode(); // Obtain an instance of Node. var listener= { handleEvent: function ( event) { // ... } }; node. addEventListener( "click" , listener); // This works. node. addEventListener( "click" , function () { ... }); // As does this.
It
is
not
possible
for
such
an
object
to
implement
an
interface
like
Node
,
however:
var node= getNode(); // Obtain an instance of Node. var newNode= { nodeName: "span" , parentNode: null , appendChild: function ( newchild) { // ... }, addEventListener: function ( type, listener) { // ... } }; node. appendChild( newNode); // This will throw a TypeError exception.
2.3. Interface mixins
An
interface
mixin
is
a
definition
(matching
interface mixin identifier { /* mixin_members... */ };
Note: Interface mixins , much like partial interfaces , are intended for use as a specification editorial aide, allowing a coherent set of functionalities to be grouped together, and included in multiple interfaces, possibly across documents. They are not meant to be exposed through language bindings. Guidance on when to choose partial interfaces , interface mixins , or partial interface mixins can be found in § 2.3.1 Using mixins and partials .
An
interface
mixin
is
a
specification
of
a
set
of
interface
mixin
members
(matching
These constants , regular operations , regular attributes , and stringifiers describe the behaviors that can be implemented by an object, as if they were specified on the interface that includes them.
Static attributes , static operations , special operations except for stringifiers , and iterable , asynchronously iterable , maplike , and setlike declarations cannot appear in interface mixin declarations.
As
with
interfaces,
the
IDL
for
interface
mixins
can
be
split
into
multiple
parts
by
using
partial
interface
mixin
definitions
(matching
interface mixin SomeMixin { /* mixin_members... */ };partial interface mixin SomeMixin { /* mixin_members... */ };
The order that members appear in has significance for property enumeration in the ECMAScript binding .
Note that unlike interfaces or dictionaries , interface mixins do not create types.
Of
the
extended
attributes
defined
in
this
specification,
only
the
[
Exposed
]
and
[
SecureContext
]
extended
attributes
are
applicable
to
interface
mixins
.
An
includes
statement
is
a
definition
(matching
interface_identifier includes mixin_indentifier ;
The first identifier must reference a interface I . The second identifier must reference an interface mixin M .
Each member of M is considered to be a member of each interface I , J , K , … that includes M , as if a copy of each member had been made. So for a given member m of M , interface I is considered to have a member m I , interface J is considered to have a member m J , interface K is considered to have a member m K , and so on. The host interfaces of m I , m J , and m K , are I , J , and K respectively.
Note: In ECMAScript, this implies that each regular operation declared as a member of interface mixin M , and exposed as a data property with a built-in function object value, is a distinct built-in function object in each interface prototype object whose associated interface includes M . Similarly, for attributes , each copy of the accessor property has distinct built-in function objects for its getters and setters.
The order of appearance of includes statements affects the order in which interface mixin are included by their host interface .
Member order isn’t clearly specified, in particular when interface mixins are defined in separate documents. It is discussed in issue #432 .
No extended attributes defined in this specification are applicable to includes statements .
The
following
IDL
fragment
defines
an
interface
,
Entry
,
and
an
interface
mixin
,
Observable
.
The
includes
statement
specifies
that
Observable
’s
members
are
always
included
on
objects
implementing
Entry
.
interface Entry {readonly attribute unsigned short entryType ; // ... };interface mixin Observable {void addEventListener (DOMString type ,EventListener listener ,boolean useCapture ); // ... };Entry includes Observable ;
An
ECMAScript
implementation
would
thus
have
an
addEventListener
property
in
the
prototype
chain
of
every
Entry
:
var e= getEntry(); // Obtain an instance of Entry. typeof e. addEventListener; // Evaluates to "function".
CallbackOrInterfaceOrMixin ::callback CallbackRestOrInterface interface InterfaceOrMixin
Partial ::partial PartialDefinition
MixinRest ::mixin identifier { MixinMembers } ;
MixinMembers ::ExtendedAttributeList MixinMember MixinMembers ε
MixinMember ::Const RegularOperation Stringifier ReadOnly AttributeRest
IncludesStatement ::identifier includes identifier ;
2.3.1. Using mixins and partials
This section is informative.
Interface mixins allow the sharing of attributes , constants , and operations across multiple interfaces . If you’re only planning to extend a single interface, you might consider using a partial interface instead.
For example, instead of:
interface mixin WindowSessionStorage {readonly attribute Storage sessionStorage ; };Window includes WindowSessionStorage ;
do:
partial interface Window {readonly attribute Storage sessionStorage ; };
Additionally, you can rely on extending interface mixins exposed by other specifications to target common use cases, such as exposing a set of attributes , constants , or operations across both window and worker contexts.
For example, instead of the common but verbose:
interface mixin GlobalCrypto {readonly attribute Crypto crypto ; };Window includes GlobalCrypto ;WorkerGlobalScope includes GlobalCrypto ;
you
can
extend
the
WindowOrWorkerGlobalScope
interface
mixin
using
a
partial
interface
mixin
:
partial interface mixin WindowOrWorkerGlobalScope {readonly attribute Crypto crypto ; };
2.4. Callback interfaces
A
callback
interface
is
a
definition
matching
Note: A callback interface is not an interface . The name and syntax are left over from earlier versions of this standard, where these concepts had more in common.
A
callback
interface
is
a
specification
of
a
set
of
callback
interface
members
(matching
callback interface identifier { /* interface_members... */ };
Note: See also the similarly named callback function definition.
Callback interfaces must define exactly one regular operation .
Specification authors should not define callback interfaces unless required to describe the requirements of existing APIs. Instead, a callback function should be used.
The
definition
of
EventListener
as
a
callback
interface
is
an
example
of
an
existing
API
that
needs
to
allow
objects
with
a
given
property
(in
this
case
handleEvent
)
to
be
considered
to
implement
the
interface.
For
new
APIs,
and
those
for
which
there
are
no
compatibility
concerns,
using
a
callback
function
will
allow
only
a
function
object
(in
the
ECMAScript
language
binding).
Callback
interfaces
which
declare
constants
must
be
annotated
with
an
[
Exposed
]
extended
attribute
.
CallbackRestOrInterface ::CallbackRest interface identifier { CallbackInterfaceMembers } ;
CallbackInterfaceMembers ::ExtendedAttributeList CallbackInterfaceMember CallbackInterfaceMembers ε
CallbackInterfaceMember ::Const RegularOperation
2.5. Members
Interfaces
,
interface
mixins
,
and
namespaces
are
specifications
of
a
set
of
members
(respectively
matching
When an interface includes an interface mixin , each member of the interface mixin is also considered a member of the interface. In contrast, inherited interface members are not considered members of the interface.
The algorithm steps for every regular operation , regular attribute getter, and regular attribute setter’s defined on an interface or interface mixin have access to a this value, which is an IDL value of the interface type that the member is declared on or that includes the interface mixin the member is declared on.
Attribute setter’s algorithm steps also have access to the given value , which is an IDL value of the type the attribute is declared as.
Interfaces , interface mixins , callback interfaces and namespaces each support a different set of members , which are specified in § 2.2 Interfaces , § 2.3 Interface mixins , § 2.4 Callback interfaces , and § 2.6 Namespaces , and summarized in the following informative table:
Interfaces | Callback interfaces | Interface mixins | Namespaces | |
---|---|---|---|---|
Constants | ● | ● | ● | |
Regular attributes | ● | ● | Only read only attributes | |
Static attributes | ● | |||
Regular Operations | ● | ● | ● | ● |
Special Operations | ● | Only stringifiers | ||
Static Operations | ● | |||
Iterable declarations | ● | |||
Asynchronously iterable declarations | ● | |||
Maplike declarations | ● | |||
Setlike declarations | ● |
2.5.1. Constants
A
constant
is
a
declaration
(matching
Constants have in the past primarily been used to define named integer codes in the style of an enumeration. The Web platform is moving away from this design pattern in favor of the use of strings. Editors who wish to use this feature are strongly advised to discuss this by filing an issue before proceeding.
const type constant_identifier = 42;
The
identifier
of
a
constant
must
not
be
the
same
as
the
identifier
of
another
interface
member
or
callback
interface
member
defined
on
the
same
interface
or
callback
interface
.
The
identifier
also
must
not
be
"
length
",
"
name
"
or
"
prototype
".
Note: These three names are the names of properties that are defined on the interface object in the ECMAScript language binding.
The
type
of
a
constant
(matching
The
Note:
These
values
–
in
addition
to
strings
and
the
empty
sequence
–
can
also
be
used
to
specify
the
default
value
of
a
dictionary
member
or
of
an
optional
argument
.
Note
that
strings,
the
empty
sequence
The
value
of
the
boolean
literal
tokens
boolean
values
true
and
false
.
The
value
of
an
-
Let S be the sequence of characters matched by the
integer token. -
Let sign be −1 if S begins with U+002D HYPHEN-MINUS ("-") , and 1 otherwise.
-
Let base be the base of the number based on the characters that follow the optional leading U+002D HYPHEN-MINUS ("-") character:
- U+0030 DIGIT ZERO ("0") , U+0058 LATIN CAPITAL LETTER X ("X")
- U+0030 DIGIT ZERO ("0") , U+0078 LATIN SMALL LETTER X ("x")
-
The base is 16.
- U+0030 DIGIT ZERO ("0")
-
The base is 8.
- Otherwise
-
The base is 10.
-
Let number be the result of interpreting all remaining characters following the optional leading U+002D HYPHEN-MINUS ("-") character and any characters indicating the base as an integer specified in base base .
-
Return sign × number .
The
type
of
an
-
Let S be the sequence of characters matched by the
decimal token. -
Let result be the Mathematical Value that would be obtained if S were parsed as an ECMAScript
NumericLiteral . -
If the
decimal token is being used as the value for afloat
orunrestricted float
, then the value of thedecimal token is the IEEE 754 single-precision floating point number closest to result . -
Otherwise, the
decimal token is being used as the value for adouble
orunrestricted double
, and the value of thedecimal token is the IEEE 754 double-precision floating point number closest to result . [IEEE-754]
The
value
of
a
constant
value
specified
as
-
Type
unrestricted float
, constant valueInfinity -
The value is the IEEE 754 single-precision positive infinity value.
-
Type
unrestricted double
, constant valueInfinity -
The value is the IEEE 754 double-precision positive infinity value.
-
Type
unrestricted float
, constant value-Infinity -
The value is the IEEE 754 single-precision negative infinity value.
-
Type
unrestricted double
, constant value-Infinity -
The value is the IEEE 754 double-precision negative infinity value.
-
Type
unrestricted float
, constant valueNaN -
The value is the IEEE 754 single-precision NaN value with the bit pattern 0x7fc00000.
-
Type
unrestricted double
, constant valueNaN -
The value is the IEEE 754 double-precision NaN value with the bit pattern 0x7ff8000000000000.
The
type
of
a
float
or
double
.
The
value
of
the
If VT is the type of the value assigned to a constant, and DT is the type of the constant, dictionary member or optional argument itself, then these types must be compatible, which is the case if DT and VT are identical, or DT is a nullable type whose inner type is VT .
Constants are not associated with particular instances of the interface or callback interface on which they appear. It is language binding specific whether constants are exposed on instances.
The ECMAScript language binding does however allow constants to be accessed through objects implementing the IDL interfaces on which the constants are declared. For example, with the following IDL:
[Exposed =Window ]interface A {const short rambaldi = 47; };
the
constant
value
can
be
accessed
in
ECMAScript
either
as
A.rambaldi
or
instanceOfA.rambaldi
.
The
following
extended
attributes
are
applicable
to
constants:
[
Exposed
],
[
SecureContext
].
Const ::const ConstType identifier = ConstValue ;
ConstValue ::BooleanLiteral FloatLiteral integer
BooleanLiteral ::true false
FloatLiteral ::decimal -Infinity Infinity NaN
ConstType ::PrimitiveType identifier
The following IDL fragment demonstrates how constants of the above types can be defined.
[Exposed =Window ]interface Util {const boolean DEBUG =false ;const octet LF = 10;const unsigned long BIT_MASK = 0x0000fc00;const double AVOGADRO = 6.022e23; };
2.5.2. Attributes
An
attribute
is
an
interface
member
or
namespace
member
(matching
-
regular attributes , which are those used to declare that objects implementing the interface will have a data field member with the given identifier
interface interface_identifier {attribute type identifier ; }; -
static attributes , which are used to declare attributes that are not associated with a particular object implementing the interface
interface interface_identifier {static attribute type identifier ; };
If
an
attribute
has
no
The
identifier
of
an
attribute
must
not
be
the
same
as
the
identifier
of
another
interface
member
defined
on
the
same
interface
.
The
identifier
of
a
static
attribute
must
not
be
"
prototype
".
The
type
of
the
attribute
is
given
by
the
type
(matching
The type of the attribute, after resolving typedefs, must not be a nullable or non-nullable version of any of the following types:
-
a union type that has a nullable or non-nullable sequence type, dictionary, or record as one of its flattened member types
The
attribute
is
read
only
if
the
interface interface_identifier {readonly attribute type identifier ; };
Attributes
whose
type
is
a
promise
type
must
be
read
only
.
Additionally,
they
cannot
have
any
of
the
extended
attributes
[
LegacyLenientSetter
],
[
PutForwards
],
[
Replaceable
],
or
[
SameObject
].
A
regular
attribute
that
is
not
read
only
can
be
declared
to
inherit
its
getter
from
an
ancestor
interface.
This
can
be
used
to
make
a
read
only
attribute
in
an
ancestor
interface
be
writable
on
a
derived
interface.
An
attribute
inherits
its
getter
if
its
declaration
includes
Note:
The
grammar
ensures
that
[Exposed =Window ]interface Ancestor {readonly attribute TheType theIdentifier ; }; [Exposed =Window ]interface Derived :Ancestor {inherit attribute TheType theIdentifier ; };
When
the
interface interface_identifier {stringifier attribute DOMString identifier ; };
The
following
extended
attributes
are
applicable
to
regular
and
static
attributes:
[
Exposed
],
[
SameObject
],
[
SecureContext
].
The
following
extended
attributes
are
applicable
only
to
regular
attributes:
[
LegacyLenientSetter
],
[
LegacyLenientThis
],
[
PutForwards
],
[
Replaceable
],
[
LegacyUnforgeable
].
ReadOnlyMember ::readonly ReadOnlyMemberRest
ReadOnlyMemberRest ::AttributeRest MaplikeRest SetlikeRest
ReadWriteAttribute ::inherit AttributeRest AttributeRest
AttributeRest ::attribute TypeWithExtendedAttributes AttributeName ;
AttributeName ::AttributeNameKeyword identifier
AttributeNameKeyword ::async required
ReadOnly ::readonly ε
The following IDL fragment demonstrates how attributes can be declared on an interface :
[Exposed =Window ]interface Animal { // A simple attribute that can be set to any string value.readonly attribute DOMString name ; // An attribute whose value can be assigned to.attribute unsigned short age ; }; [Exposed =Window ]interface Person :Animal { // An attribute whose getter behavior is inherited from Animal, and need not be // specified in the description of Person.inherit attribute DOMString name ; };
2.5.3. Operations
An
operation
is
an
interface
member
,
callback
interface
member
or
namespace
member
(matching
-
regular operations , which are those used to declare that objects implementing the interface will have a method with the given identifier
interface interface_identifier {return_type identifier (/* arguments... */); }; -
special operations , which are used to declare special behavior on objects implementing the interface, such as object indexing and stringification
interface interface_identifier { /* special_keyword */return_type identifier (/* arguments... */); /* special_keyword */return_type (/* arguments... */); }; -
static operations , which are used to declare operations that are not associated with a particular object implementing the interface
interface interface_identifier {static return_type identifier (/* arguments... */); };
If
an
operation
has
an
identifier
but
no
If an operation has no identifier, then it must be declared to be a special operation using one of the special keywords.
The
identifier
of
a
regular
operation
or
static
operation
must
not
be
the
same
as
the
identifier
of
a
constant
or
attribute
defined
on
the
same
interface
,
callback
interface
or
namespace
.
The
identifier
of
a
static
operation
must
not
be
"
prototype
".
Note: The identifier can be the same as that of another operation on the interface, however. This is how operation overloading is specified.
The identifier of a static operation also must not be the same as the identifier of a regular operation defined on the same interface .
The
return
type
of
the
operation
is
given
by
the
type
(matching
void
indicates
that
the
operation
returns
no
value.
If
the
return
type
is
an
identifier
followed
by
An
operation’s
arguments
(matching
Note:
For
expressiveness,
the
identifier
of
an
operation
argument
can
also
be
specified
as
one
of
the
keywords
matching
the
If
the
If the operation argument type, after resolving typedefs, is a nullable type , its inner type must not be a dictionary type .
interface interface_identifier {return_type identifier (type identifier ,type identifier /* , ... */); };
The identifier of each argument must not be the same as the identifier of another argument in the same operation declaration.
Each
argument
can
be
preceded
by
a
list
of
extended
attributes
(matching
interface interface_identifier {return_type identifier ([extended_attributes ]type identifier , [extended_attributes ]type identifier /* , ... */); };
The following IDL fragment demonstrates how regular operations can be declared on an interface :
[Exposed =Window ]interface Dimensions {attribute unsigned long width ;attribute unsigned long height ; }; [Exposed =Window ]interface Button { // An operation that takes no arguments and returns a boolean.boolean isMouseOver (); // Overloaded operations.void setDimensions (Dimensions size );void setDimensions (unsigned long width ,unsigned long height ); };
An
operation
or
constructor
operation
is
considered
to
be
variadic
if
the
final
argument
uses
the
interface interface_identifier {return_type identifier (type ...identifier );return_type identifier (type identifier ,type ...identifier ); };
Extended
attributes
that
take
an
argument
list
([
LegacyFactoryFunction
],
of
those
defined
in
this
specification)
and
callback
functions
are
also
considered
to
be
variadic
when
the
The following IDL fragment defines an interface that has two variadic operations:
[Exposed =Window ]interface IntegerSet {readonly attribute unsigned long cardinality ;void union (long ...ints );void intersection (long ...ints ); };
In the ECMAScript binding, variadic operations are implemented by functions that can accept the subsequent arguments:
var s= getIntegerSet(); // Obtain an instance of IntegerSet. s. union(); // Passing no arguments corresponding to 'ints'. s. union( 1 , 4 , 7 ); // Passing three arguments corresponding to 'ints'.
A binding for a language that does not support variadic functions might specify that an explicit array or list of integers be passed to such an operation.
An
argument
is
considered
to
be
an
optional
argument
if
it
is
declared
with
the
interface interface_identifier {return_type identifier (type identifier ,optional type identifier ); };
Optional
arguments
can
also
have
a
default
value
specified.
If
the
argument’s
identifier
is
followed
by
a
U+003D
EQUALS
SIGN
("=")
and
a
value
(matching
interface interface_identifier {return_type identifier (type identifier ,optional type identifier = "value"); };
It
is
strongly
suggested
not
to
use
a
default
value
of
boolean
-typed
arguments,
as
this
can
be
confusing
for
authors
who
might
otherwise
expect
the
default
conversion
of
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 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.
This is to encourage API designs that do not require authors to pass an empty dictionary value when they wish only to use the dictionary’s default values.
Usually
the
default
value
provided
will
be
When
a
boolean
literal
token
(
-
Let S be the sequence of Unicode scalar values matched by the
string token with its leading and trailing U+0022 QUOTATION MARK ('"') characters removed. -
Depending on the type of the argument:
-
DOMString
- an enumeration type
-
The value of the
string token is the sequence of 16 bit unsigned integer code units (hereafter referred to just as code units ) corresponding to the UTF-16 encoding of S . -
ByteString
-
The value of the
string token is the sequence of 8 bit unsigned integer code units corresponding to the UTF-8 encoding of S . -
USVString
-
The value of the
string token is S .
-
If the type of the optional argument is an enumeration , then its default value if specified must be one of the enumeration’s values .
Optional
argument
default
values
can
also
be
specified
using
the
two
token
value
Optional
argument
default
values
can
also
be
specified
using
the
two
token
value
The following IDL fragment defines an interface with a single operation that can be invoked with two different argument list lengths:
[Exposed =Window ]interface ColorCreator {object createColor (double v1 ,double v2 ,double v3 ,optional double alpha ); };
It is equivalent to an interface that has two overloaded operations :
[Exposed =Window ]interface ColorCreator {object createColor (double v1 ,double v2 ,double v3 );object createColor (double v1 ,double v2 ,double v3 ,double alpha ); };
The following IDL fragment defines an interface with an operation that takes a dictionary argument:
dictionary LookupOptions {boolean caseSensitive =false ; }; [Exposed =Window ]interface AddressBook {boolean hasAddressForName (USVString name ,optional LookupOptions options = {}); };
If
hasAddressForName
is
called
with
only
one
argument,
the
second
argument
will
be
a
default-initialized
LookupOptions
dictionary,
which
will
cause
caseSensitive
to
be
set
to
The
following
extended
attributes
are
applicable
to
operations:
[
Default
],
[
Exposed
],
[
NewObject
],
[
SecureContext
],
[
LegacyUnforgeable
].
DefaultValue ::ConstValue string [ ] { } null
Operation ::RegularOperation SpecialOperation
RegularOperation ::ReturnType OperationRest
SpecialOperation ::Special RegularOperation
Special ::getter setter deleter
OperationRest ::OptionalOperationName ( ArgumentList ) ;
OptionalOperationName ::OperationName ε
OperationName ::OperationNameKeyword identifier
OperationNameKeyword ::includes
ArgumentList ::Argument Arguments ε
Arguments ::, Argument Arguments ε
Argument ::ExtendedAttributeList ArgumentRest
ArgumentRest ::optional TypeWithExtendedAttributes ArgumentName Default Type Ellipsis ArgumentName
ArgumentName ::ArgumentNameKeyword identifier
Ellipsis ::... ε
ArgumentNameKeyword ::async attribute callback const constructor deleter dictionary enum getter includes inherit interface iterable maplike mixin namespace partial readonly required setlike setter static stringifier typedef unrestricted
ReturnType ::Type void
2.5.3.1. toJSON
By
declaring
a
toJSON
regular
operation
,
an
interface
specifies
how
to
convert
the
objects
that
implement
it
to
JSON
types
.
The
toJSON
regular
operation
is
reserved
for
this
usage.
It
must
take
zero
arguments
and
return
a
JSON
type
.
The JSON types are:
-
boolean
, -
nullable types whose inner type is a JSON type ,
-
annotated types whose inner type is a JSON type ,
-
union types whose member types are JSON types ,
-
typedefs whose type being given a new name is a JSON type ,
-
sequence types whose parameterized type is a JSON type ,
-
frozen array types whose parameterized type is a JSON type ,
-
dictionary types where the types of all members declared on the dictionary and all its inherited dictionaries are JSON types ,
-
records where all of their values are JSON types ,
-
object
, -
interface types that have a
toJSON
operation declared on themselves or one of their inherited interfaces .
How
the
toJSON
regular
operation
is
made
available
on
an
object
in
a
language
binding,
and
how
exactly
the
JSON
types
are
converted
into
a
JSON
string,
is
language
binding
specific.
Note:
In
the
ECMAScript
language
binding,
this
is
done
by
exposing
a
toJSON
method
which
returns
the
JSON
type
converted
into
an
ECMAScript
value
that
can
be
turned
into
a
JSON
string
by
the
JSON.stringify()
function.
Additionally,
in
the
ECMAScript
language
binding,
the
toJSON
operation
can
take
a
[
Default
]
extended
attribute
,
in
which
case
the
default
toJSON
operation
is
exposed
instead.
The
following
IDL
fragment
defines
an
interface
Transaction
that
has
a
toJSON
method
defined
in
prose:
[Exposed =Window ]interface Transaction {readonly attribute DOMString from ;readonly attribute DOMString to ;readonly attribute double amount ;readonly attribute DOMString description ;readonly attribute unsigned long number ;TransactionJSON toJSON (); };dictionary TransactionJSON {Account from ;Account to ;double amount ;DOMString description ; };
The
toJSON
regular
operation
of
Transaction
interface
could
be
defined
as
follows:
To
invoke
the
toJSON()
operation
of
the
Transaction
interface,
run
the
following
steps:
-
Let json be a new
TransactionJSON
dictionary. -
For each attribute identifier attr in « "from", "to", "amount", "description" »:
-
Let value be result of getting the underlying value of the attribute identified by attr , given this .
-
Set json [ attr ] to value .
-
-
Return json .
In
the
ECMAScript
language
binding,
there
would
exist
a
toJSON()
method
on
Transaction
objects:
// Get an instance of Transaction. var txn= getTransaction(); // Evaluates to an object like this: // { // from: "Bob", // to: "Alice", // amount: 50, // description: "books" // } txn. toJSON(); // Evaluates to a string like this: // '{"from":"Bob","to":"Alice","amount":50,"description":"books"}' JSON. stringify( txn);
2.5.4. Constructor operations
If
an
interface
has
a
constructor
operation
member
(matching
Multiple constructor operations may appear on a given interface . For each constructor operation on the interface , there will be a way to attempt to construct an instance by passing the specified arguments.
The prose definition of a constructor operation must either initialize the value passed as this , or throw an exception.
See § 3.7.1 Interface object for details on how a constructor operation is to be implemented.
The following IDL defines two interfaces. The second has constructor operations , while the first does not.
[Exposed =Window ]interface NodeList {Node item (unsigned long index );readonly attribute unsigned long length ; }; [Exposed =Window ]interface Circle {constructor ();constructor (double radius );attribute double r ;attribute double cx ;attribute double cy ;readonly attribute double circumference ; };
An
ECMAScript
implementation
supporting
these
interfaces
would
implement
a
[[Construct]]
internal
method
on
the
Circle
interface
object
which
would
return
a
new
object
that
implements
the
interface.
It
would
take
either
zero
or
one
argument.
It
is
unclear
whether
the
NodeList
interface
object
would
implement
a
[[Construct]]
internal
method.
In
any
case,
trying
to
use
it
as
a
constructor
will
cause
a
TypeError
to
be
thrown.
<https://github.com/heycam/webidl/issues/698>
var x= new Circle(); // This uses the zero-argument constructor to create a // reference to a platform object that implements the // Circle interface. var y= new Circle( 1.25 ); // This also creates a Circle object, this time using // the one-argument constructor. var z= new NodeList(); // This would throw a TypeError, since no // constructor is declared.
Constructor ::constructor ( ArgumentList ) ;
Ellipsis ::... ε
ArgumentNameKeyword ::async attribute callback const constructor deleter dictionary enum getter includes inherit interface iterable maplike mixin namespace partial readonly required setlike setter static stringifier typedef unrestricted
2.5.5. Special operations
A special operation is a declaration of a certain kind of special behavior on objects implementing the interface on which the special operation declarations appear. Special operations are declared by using a special keyword in an operation declaration.
There are four kinds of special operations. The table below indicates for a given kind of special operation what special keyword is used to declare it and what the purpose of the special operation is:
Special operation | Keyword | Purpose |
---|---|---|
Getters |
| Defines behavior for when an object is indexed for property retrieval. |
Setters |
| Defines behavior for when an object is indexed for property assignment or creation. |
Deleters |
| Defines behavior for when an object is indexed for property deletion. |
Stringifiers |
|
Defines
how
an
object
is
converted
into
a
DOMString
.
|
Not all language bindings support all of the four kinds of special object behavior. When special operations are declared using operations with no identifier, then in language bindings that do not support the particular kind of special operations there simply will not be such functionality.
The following IDL fragment defines an interface with a getter and a setter:
[Exposed =Window ]interface Dictionary {readonly attribute unsigned long propertyCount ;getter double (DOMString propertyName );setter void (DOMString propertyName ,double propertyValue ); };
In language bindings that do not support property getters and setters, objects implementing Dictionary will not have that special behavior.
Defining a special operation with an identifier is equivalent to separating the special operation out into its own declaration without an identifier. This approach is allowed to simplify prose descriptions of an interface’s operations.
The following two interfaces are equivalent:
[Exposed =Window ]interface Dictionary {readonly attribute unsigned long propertyCount ;getter double getProperty (DOMString propertyName );setter void setProperty (DOMString propertyName ,double propertyValue ); };
[Exposed =Window ]interface Dictionary {readonly attribute unsigned long propertyCount ;double getProperty (DOMString propertyName );void setProperty (DOMString propertyName ,double propertyValue );getter double (DOMString propertyName );setter void (DOMString propertyName ,double propertyValue ); };
A given special keyword must not appear twice on an operation.
Getters
and
setters
come
in
two
varieties:
ones
that
take
a
DOMString
as
a
property
name,
known
as
named
property
getters
and
named
property
setters
,
and
ones
that
take
an
unsigned
long
as
a
property
index,
known
as
indexed
property
getters
and
indexed
property
setters
.
There
is
only
one
variety
of
deleter:
named
property
deleters
.
See
§ 2.5.5.2
Indexed
properties
and
§ 2.5.5.3
Named
properties
for
details.
On a given interface , there must exist at most one stringifier, at most one named property deleter , and at most one of each variety of getter and setter.
If an interface has a setter of a given variety, then it must also have a getter of that variety. If it has a named property deleter , then it must also have a named property getter .
Special operations declared using operations must not be variadic nor have any optional arguments .
If an object implements more than one interface that defines a given special operation, then it is undefined which (if any) special operation is invoked for that operation.
2.5.5.1. Stringifiers
When
an
interface
has
a
stringifier
,
it
indicates
that
objects
that
implement
the
interface
have
a
non-default
conversion
to
a
string.
As
mentioned
above,
stringifiers
can
be
specified
using
an
operation
declared
with
the
interface interface_identifier {stringifier DOMString identifier ();stringifier DOMString (); };
If an operation used to declare a stringifier does not have an identifier , then prose accompanying the interface must define the stringification behavior of the interface. If the operation does have an identifier, then the object is converted to a string by invoking the operation to obtain the string.
Stringifiers
declared
with
operations
must
be
declared
to
take
zero
arguments
and
return
a
DOMString
.
As
a
shorthand,
if
the
interface interface_identifier {stringifier ; };
The following two interfaces are equivalent:
[Exposed =Window ]interface A {stringifier DOMString (); };
[Exposed =Window ]interface A {stringifier ; };
The
DOMString
or
USVString
.
It
also
must
not
be
placed
on
a
static
attribute
.
interface interface_identifier {stringifier attribute DOMString identifier ; };
Stringifier ::stringifier StringifierRest
StringifierRest ::ReadOnly AttributeRest RegularOperation ;
The
following
IDL
fragment
defines
an
interface
that
will
stringify
to
the
value
of
its
name
attribute:
[Exposed =Window ]interface Student {constructor ();attribute unsigned long id ;stringifier attribute DOMString name ; };
In
the
ECMAScript
binding,
using
a
Student
object
in
a
context
where
a
string
is
expected
will
result
in
the
value
of
the
object’s
name
property
being
used:
var s= new Student(); s. id= 12345678 ; s. name= '周杰倫' ; var greeting= 'Hello, ' + s+ '!' ; // Now greeting == 'Hello, 周杰倫!'.
The following IDL fragment defines an interface that has custom stringification behavior that is not specified in the IDL itself.
[Exposed =Window ]interface Student {constructor ();attribute unsigned long id ;attribute DOMString ?familyName ;attribute DOMString givenName ;stringifier DOMString (); };
Thus, prose is required to explain the stringification behavior, such as the following paragraph:
Objects that implement the
Student
interface must stringify as follows. If the value of thefamilyName
attribute isnull , the stringification of the object is the value of thegivenName
attribute. Otherwise, if the value of thefamilyName
attribute is notnull , the stringification of the object is the concatenation of the value of thegivenName
attribute, a single space character, and the value of thefamilyName
attribute.
An ECMAScript implementation of the IDL would behave as follows:
var s= new Student(); s. id= 12345679 ; s. familyName= 'Smithee' ; s. givenName= 'Alan' ; var greeting= 'Hi ' + s; // Now greeting == 'Hi Alan Smithee'.
2.5.5.2. Indexed properties
An interface that defines an indexed property getter is said to support indexed properties . By extension, a platform object is said to support indexed properties if it implements an interface that itself does.
If an interface supports indexed properties , then the interface definition must be accompanied by a description of what indices the object can be indexed with at any given time. These indices are called the supported property indices .
Interfaces
that
support
indexed
properties
must
define
an
integer-typed
attribute
named
"
length
".
Indexed
property
getters
must
be
declared
to
take
a
single
unsigned
long
argument.
Indexed
property
setters
must
be
declared
to
take
two
arguments,
where
the
first
is
an
unsigned
long
.
interface interface_identifier {getter type identifier (unsigned long identifier );setter type identifier (unsigned long identifier ,type identifier );getter type (unsigned long identifier );setter type (unsigned long identifier ,type identifier ); };
The following requirements apply to the definitions of indexed property getters and setters:
-
If an indexed property getter was specified using an operation with an identifier , then the value returned when indexing the object with a given supported property index is the value that would be returned by invoking the operation, passing the index as its only argument. If the operation used to declare the indexed property getter did not have an identifier, then the interface definition must be accompanied by a description of how to determine the value of an indexed property for a given index.
-
If an indexed property setter was specified using an operation with an identifier, then the behavior that occurs when indexing the object for property assignment with a given supported property index and value is the same as if the operation is invoked, passing the index as the first argument and the value as the second argument. If the operation used to declare the indexed property setter did not have an identifier, then the interface definition must be accompanied by a description of how to set the value of an existing indexed property and how to set the value of a new indexed property for a given property index and value.
Note that if an indexed property getter or setter is specified using an operation with an identifier , then indexing an object with an integer that is not a supported property index does not necessarily elicit the same behavior as invoking the operation with that index. The actual behavior in this case is language binding specific.
In the ECMAScript language binding, a regular property lookup is done. For example, take the following IDL:
[Exposed =Window ]interface A {getter DOMString toWord (unsigned long index ); };
Assume
that
an
object
implementing
A
has
supported
property
indices
in
the
range
0
≤
index
<
2.
Also
assume
that
toWord
is
defined
to
return
its
argument
converted
into
an
English
word.
The
behavior
when
invoking
the
operation
with
an
out
of
range
index
is
different
from
indexing
the
object
directly:
var a= getA(); a. toWord( 0 ); // Evalautes to "zero". a[ 0 ]; // Also evaluates to "zero". a. toWord( 5 ); // Evaluates to "five". a[ 5 ]; // Evaluates to undefined, since there is no property "5".
The
following
IDL
fragment
defines
an
interface
OrderedMap
which
allows
retrieving
and
setting
values
by
name
or
by
index
number:
[Exposed =Window ]interface OrderedMap {readonly attribute unsigned long size ;getter any getByIndex (unsigned long index );setter void setByIndex (unsigned long index ,any value );getter any get (DOMString name );setter void set (DOMString name ,any value ); };
Since
all
of
the
special
operations
are
declared
using
operations
with
identifiers,
the
only
additional
prose
that
is
necessary
is
that
which
describes
what
keys
those
sets
have.
Assuming
that
the
get()
operation
is
defined
to
return
OrderedMap
,
then
the
following
two
sentences
would
suffice:
An object map implementing
OrderedMap
supports indexed properties with indices in the range 0 ≤ index <map.size
.Such objects also support a named property for every name that, if passed to
get()
, would return a non-null value.
As
described
in
§ 3.9
Legacy
platform
objects
,
an
ECMAScript
implementation
would
create
properties
on
a
legacy
platform
object
implementing
OrderedMap
that
correspond
to
entries
in
both
the
named
and
indexed
property
sets.
These
properties
can
then
be
used
to
interact
with
the
object
in
the
same
way
as
invoking
the
object’s
methods,
as
demonstrated
below:
// Assume map is a legacy platform object implementing the OrderedMap interface. var map= getOrderedMap(); var x, y; x= map[ 0 ]; // If map.length > 0, then this is equivalent to: // // x = map.getByIndex(0) // // since a property named "0" will have been placed on map. // Otherwise, x will be set to undefined, since there will be // no property named "0" on map. map[ 1 ] = false ; // This will do the equivalent of: // // map.setByIndex(1, false) y= map. apple; // If there exists a named property named "apple", then this // will be equivalent to: // // y = map.get('apple') // // since a property named "apple" will have been placed on // map. Otherwise, y will be set to undefined, since there // will be no property named "apple" on map. map. berry= 123 ; // This will do the equivalent of: // // map.set('berry', 123) delete map. cake; // If a named property named "cake" exists, then the "cake" // property will be deleted, and then the equivalent to the // following will be performed: // // map.remove("cake")
2.5.5.3. Named properties
An interface that defines a named property getter is said to support named properties . By extension, a platform object is said to support named properties if it implements an interface that itself does.
If an interface supports named properties , then the interface definition must be accompanied by a description of the ordered set of names that can be used to index the object at any given time. These names are called the supported property names .
Named
property
getters
and
deleters
must
be
declared
to
take
a
single
DOMString
argument.
Named
property
setters
must
be
declared
to
take
two
arguments,
where
the
first
is
a
DOMString
.
interface interface_identifier {getter type identifier (DOMString identifier );setter type identifier (DOMString identifier ,type identifier );deleter type identifier (DOMString identifier );getter type (DOMString identifier );setter type (DOMString identifier ,type identifier );deleter type (DOMString identifier ); };
The following requirements apply to the definitions of named property getters, setters and deleters:
-
If a named property getter was specified using an operation with an identifier , then the value returned when indexing the object with a given supported property name is the value that would be returned by invoking the operation, passing the name as its only argument. If the operation used to declare the named property getter did not have an identifier, then the interface definition must be accompanied by a description of how to determine the value of a named property for a given property name.
-
If a named property setter was specified using an operation with an identifier, then the behavior that occurs when indexing the object for property assignment with a given supported property name and value is the same as if the operation is invoked, passing the name as the first argument and the value as the second argument. If the operation used to declare the named property setter did not have an identifier, then the interface definition must be accompanied by a description of how to set the value of an existing named property and how to set the value of a new named property for a given property name and value.
-
If a named property deleter was specified using an operation with an identifier, then the behavior that occurs when indexing the object for property deletion with a given supported property name is the same as if the operation is invoked, passing the name as the only argument. If the operation used to declare the named property deleter did not have an identifier, then the interface definition must be accompanied by a description of how to delete an existing named property for a given property name.
Note: As with indexed properties , if an named property getter , setter or deleter is specified using an operation with an identifier , then indexing an object with a name that is not a supported property name does not necessarily elicit the same behavior as invoking the operation with that name; the behavior is language binding specific.
2.5.6. Static attributes and operations
Static
attributes
and
static
operations
are
ones
that
are
not
associated
with
a
particular
instance
of
the
interface
on
which
it
is
declared,
and
is
instead
associated
with
the
interface
itself.
Static
attributes
and
operations
are
declared
by
using
the
It is language binding specific whether it is possible to invoke a static operation or get or set a static attribute through a reference to an instance of the interface.
StaticMember ::static StaticMemberRest
StaticMemberRest ::ReadOnly AttributeRest RegularOperation
The
following
IDL
fragment
defines
an
interface
Circle
that
has
a
static
operation
declared
on
it:
[Exposed =Window ]interface Point { /* ... */ }; [Exposed =Window ]interface Circle {attribute double cx ;attribute double cy ;attribute double radius ;static readonly attribute long triangulationCount ;static Point triangulate (Circle c1 ,Circle c2 ,Circle c3 ); };
In
the
ECMAScript
language
binding,
the
function
object
for
triangulate
and
the
accessor
property
for
triangulationCount
will
exist
on
the
interface
object
for
Circle
:
var circles= getCircles(); // an Array of Circle objects typeof Circle. triangulate; // Evaluates to "function" typeof Circle. triangulationCount; // Evaluates to "number" Circle. prototype. triangulate; // Evaluates to undefined Circle. prototype. triangulationCount; // Also evaluates to undefined circles[ 0 ]. triangulate; // As does this circles[ 0 ]. triangulationCount; // And this // Call the static operation var triangulationPoint= Circle. triangulate( circles[ 0 ], circles[ 1 ], circles[ 2 ]); // Find out how many triangulations we have done window. alert( Circle. triangulationCount);
2.5.7. Overloading
If a regular operation or static operation defined on an interface has an identifier that is the same as the identifier of another operation on that interface of the same kind (regular or static), then the operation is said to be overloaded . When the identifier of an overloaded operation is used to invoke one of the operations on an object that implements the interface, the number and types of the arguments passed to the operation determine which of the overloaded operations is actually invoked. Constructor operations can be overloaded too. There are some restrictions on the arguments that overloaded operations and constructors can be specified to take, and in order to describe these restrictions, the notion of an effective overload set is used.
Operations must not be overloaded across interface , partial interface , interface mixin , and partial interface mixin definitions.
For example, the overloads for both f and g are disallowed:
[Exposed =Window ]interface A {void f (); };partial interface A {void f (double x );void g (); };partial interface A {void g (DOMString x ); };
Note
that
constructor
operations
and
[
LegacyFactoryFunction
]
extended
attributes
are
disallowed
from
appearing
on
partial
interface
definitions,
so
there
is
no
need
to
also
disallow
overloading
for
constructors.
An
effective
overload
set
represents
the
allowable
invocations
for
a
particular
operation
,
constructor
(specified
with
a
constructor
operation
or
[
LegacyFactoryFunction
]),
or
callback
function
.
The
algorithm
to
compute
the
effective
overload
set
operates
on
one
of
the
following
four
types
of
IDL
constructs,
and
listed
with
them
below
are
the
inputs
to
the
algorithm
needed
to
compute
the
set.
- For regular operations
- For static operations
-
-
the interface on which the operations are to be found
-
the identifier of the operations
-
the number of arguments to be passed
-
- For constructors
-
-
the interface on which the constructor operations are to be found
-
the number of arguments to be passed
-
- For legacy factory functions
-
-
the interface on which the [
LegacyFactoryFunction
] extended attributes are to be found -
the identifier of the legacy factory function
-
the number of arguments to be passed
-
An effective overload set is used, among other things, to determine whether there are ambiguities in the overloaded operations and constructors specified on an interface.
The items of an effective overload set are tuples of the form ( callable , type list , optionality list ) whose items are described below:
-
A callable is an operation if the effective overload set is for regular operations , static operations , or constructor operations ; and it is an extended attribute if the effective overload set is for legacy factory functions .
-
A type list is a list of IDL types.
-
An optionality list is a list of three possible optionality values – "required", "optional" or "variadic" – indicating whether the argument at a given index was declared as being optional or corresponds to a variadic argument.
Each tuple represents an allowable invocation of the operation, constructor, or callback function with an argument value list of the given types. Due to the use of optional arguments and variadic operations and constructors, there may be multiple items in an effective overload set identifying the same operation or constructor.
-
the identifier of the operation or legacy factory function is A
-
the argument count is N
-
the interface is I
Whenever an argument of an extended attribute is mentioned, it is referring to an argument of the extended attribute’s named argument list .
-
Let S be an ordered set .
-
Let F be an ordered set with items as follows, according to the kind of effective overload set :
- For regular operations
-
The elements of F are the regular operations with identifier A defined on interface I .
- For static operations
-
The elements of F are the static operations with identifier A defined on interface I .
- For constructors
-
The elements of F are the constructor operations on interface I .
- For legacy factory functions
-
The elements of F are the [
LegacyFactoryFunction
] extended attributes on interface I whose named argument lists’ identifiers are A .
-
Let maxarg be the maximum number of arguments the operations, legacy factory functions, or callback functions in F are declared to take. For variadic operations and legacy factory functions, the argument on which the ellipsis appears counts as a single argument.
Note: So
void f(long x, long... y);
is considered to be declared to take two arguments. -
Let max be max ( maxarg , N ).
-
For each operation or extended attribute X in F :
-
Let arguments be the list of arguments X is declared to take.
-
Let n be the size of arguments .
-
Let types be a type list .
-
Let optionalityValues be an optionality list .
-
For each argument in arguments :
-
If X is declared to be variadic , then:
-
For each i in the range n to max − 1, inclusive:
-
Let t be a type list .
-
Let o be an optionality list .
-
-
-
Let i be n − 1.
-
While i ≥ 0:
-
If arguments [ i ] is not optional (i.e., it is not marked as "optional" and is not a final, variadic argument), then break .
-
Let t be a type list .
-
Let o be an optionality list .
-
Append the tuple ( X , t , o ) to S .
Note: if i is 0, this means to add to S the tuple ( X , « », « »); (where "« »" represents an empty list ).
-
Set i to i − 1.
-
-
-
Return S .
For the following interface:
[Exposed =Window ]interface A { /* f1 */void f (DOMString a ); /* f2 */void f (Node a ,DOMString b ,double ...c ); /* f3 */void f (); /* f4 */void f (Event a ,DOMString b ,optional DOMString c ,double ...d ); };
assuming
Node
and
Event
are
two
other
interfaces
of
which
no
object
can
implement
both,
the
effective
overload
set
for
regular
operations
with
identifier
f
and
argument
count
4
is:
« (f1, « DOMString », « required »), (f2, « Node, DOMString », « required, required »), (f2, « Node, DOMString, double », « required, required, variadic »), (f2, « Node, DOMString, double, double », « required, required, variadic, variadic »), (f3, « », « »), (f4, « Event, DOMString », « required, required »), (f4, « Event, DOMString, DOMString », « required, required, optional »), (f4, « Event, DOMString, DOMString, double », « required, required, optional, variadic ») »
Two types are distinguishable if the following algorithm returns true .
-
If one type includes a nullable type and the other type either includes a nullable type , is a union type with flattened member types including a dictionary type , or is a dictionary type , return false .
-
If both types are either a union type or nullable union type , return true if each member type of the one is distinguishable with each member type of the other, or false otherwise.
-
If one type is a union type or nullable union type, return true if each member type of the union type is distinguishable with the non-union type, or false otherwise.
-
Consider the two "innermost" types derived by taking each type’s inner type if it is an annotated type , and then taking its inner type inner type if the result is a nullable type . If these two innermost types appear or are in categories appearing in the following table and there is a “●” mark in the corresponding entry or there is a letter in the corresponding entry and the designated additional requirement below the table is satisfied, then return true . Otherwise return false .
Categories:
- interface-like
- dictionary-like
- sequence-like
booleannumeric typesstring typesobjectsymbolinterface-likecallback functiondictionary-likesequence-likeboolean ● ● ● ● ● ● ● ● numeric types ● ● ● ● ● ● ● string types ● ● ● ● ● ● object ● symbol ● ● ● ● interface-like (a) ● ● ● callback function ● dictionary-like ● sequence-like -
The two identified interface-like types are not the same, and no single platform object implements both interface-like types.
double
andDOMString
are distinguishable because there is a ● at the intersection of numeric types with string types .double
andlong
are not distinguishable because they are both numeric types , and there is no ● or letter at the intersection of numeric types with numeric types .Given:callback interface CBIface {void handle (); }; [Exposed =Window ]interface Iface {attribute DOMString attr2 ; };dictionary Dict {DOMString field1 ; };CBIface
is distinguishable fromIface
because there’s a ● at the intersection of dictionary-like and interface-like, but it is not distinguishable fromDict
because there’s no ● at the intersection of dictionary-like and itself.Promise types do not appear in the above table, and as a consequence are not distinguishable with any other type.
If there is more than one item in an effective overload set that has a given type list size , then for those items there must be an index i such that for each pair of items the types at index i are distinguishable . The lowest such index is termed the distinguishing argument index for the items of the effective overload set with the given type list size.
Consider
the
effective
overload
set
shown
in
the
previous
example.
There
are
multiple
items
in
the
set
with
type
lists
2,
3
and
4.
For
each
of
these
type
list
size,
the
distinguishing
argument
index
is
0,
since
Node
and
Event
are
distinguishable
.
The following use of overloading however is invalid:
[Exposed =Window ]interface B {void f (DOMString x );void f (USVString x ); };
In addition, for each index j , where j is less than the distinguishing argument index for a given type list size, the types at index j in all of the items’ type lists must be the same, and the optionality values at index j in all of the items’ optionality lists must be the same.
The following is invalid:
[Exposed =Window ]interface B { /* f1 */void f (DOMString w ); /* f2 */void f (long w ,double x ,Node y ,Node z ); /* f3 */void f (double w ,double x ,DOMString y ,Node z ); };
For argument count 4, the effective overload set is:
« (f1, « DOMString », « required »), (f2, « long, double, Node, Node », « required, required, required, required »), (f3, « double, double, DOMString, Node », « required, required, required, required ») »
Looking
at
items
with
type
list
size
4,
the
distinguishing
argument
index
is
2,
since
Node
and
DOMString
are
distinguishable
.
However,
since
the
arguments
in
these
two
overloads
at
index
0
are
different,
the
overloading
is
invalid.
2.5.7.1. Overloading vs. union types
This section is informative.
For specifications defining IDL operations , it might seem that overloads and a combination of union types and optional arguments have some feature overlap.
It
is
first
important
to
note
that
overloads
have
different
behaviors
than
union
types
or
optional
arguments
,
and
one
cannot
be
fully
defined
using
the
other
(unless,
of
course,
additional
prose
is
provided,
which
can
defeat
the
purpose
of
the
Web
IDL
type
system).
For
example,
consider
the
stroke()
operations
defined
on
the
CanvasDrawPath
interface
[HTML]
:
interface CanvasDrawPathExcerpt {void stroke ();void stroke (Path2D path ); };
Per
the
ECMAScript
language
binding,
calling
stroke(undefined)
on
an
object
implementing
CanvasDrawPathExcerpt
would
attempt
to
call
the
second
overload,
yielding
a
TypeError
since
Path2D
.
However,
if
the
operations
were
instead
defined
with
optional
arguments
and
merged
into
one,
interface CanvasDrawPathExcerptOptional {void stroke (optional Path2D path ); };
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
used
for
stroke()
.
Additionally, there are semantic differences as well. Union types are usually used in the sense that "any of the types would work in about the same way". In contrast, overloaded operations are designed to map well to language features such as C++ overloading, and are usually a better fit for operations with more substantial differences in what they do given arguments of different types. However, in most cases, operations with such substantial differences are best off with different names to avoid confusion for Web developers, since the ECMAScript language does not provide language-level overloading. As such, overloads are rarely appropriate for new APIs, instead often appearing in legacy APIs or in specialized circumstances.
That being said, we offer the following recommendations and examples in case of difficulties to determine what Web IDL language feature to use:
-
In the unusual case where the operation needs to return values of different types for different argument types, overloading will result in more expressive IDL fragments. This is almost never appropriate API design, and separate operations with distinct names usually are a better choice for such cases.
Suppose there is an operation
calculate()
that accepts along
,DOMString
, orCalculatableInterface
(an interface type ) as its only argument, and returns a value of the same type as its argument. It would be clearer to write the IDL fragment using overloaded operations asinterface A {long calculate (long input );DOMString calculate (DOMString input );CalculatableInterface calculate (CalculatableInterface input ); };than using a union type with a typedef as
typedef (long or DOMString or CalculatableInterface )Calculatable ;interface A {Calculatable calculate (Calculatable input ); };which does not convey the fact that the return value is always of the same type as input .
The problem is exacerbated when one of the overloads has a return type of
void
, since union types cannot even containvoid
as a member type . In that case, a return type ofany
needs to be used with appropriate prose defining the return type, further decreasing expressiveness.If the specified
calculate()
is a new API and does not have any compatibility concerns, it is suggested to use different names for the overloaded operations, perhaps asinterface A {long calculateNumber (long input );DOMString calculateString (DOMString input );CalculatableInterface calculateCalculatableInterface (CalculatableInterface input ); };which allows Web developers to write explicit and unambiguous code.
-
When the operation has significantly different semantics for different argument types or lengths, overloading is preferred. Again, in such scenarios, it is usually better to create separate operations with distinct names, but legacy APIs sometimes follow this pattern.
As an example, the
supports(property, value)
andsupports(conditionText)
operations of theCSS
interface are defined as the following IDL fragment [CSS3-CONDITIONAL] [CSSOM] .partial interface CSS {static boolean supports (CSSOMString property ,CSSOMString value );static boolean supports (CSSOMString conditionText ); };Using optional arguments one can rewrite the IDL fragment as follows:
partial interface CSSExcerptOptional {static boolean supports (CSSOMString propertyOrConditionText ,optional CSSOMString value ); };Even though the IDL is shorter in the second version, two distinctively different concepts are conflated in the first argument. Without overloads , the question "is property or conditionText paired with value ?" is much more difficult to answer without reading the prose definition of the operation. This makes the second version remarkably less readable than the first.
Another consideration is that the prose for overloaded operations can be specified in separate blocks, which can aid in both reading and writing specifications. This is not the case for optional arguments . This means that in the first case the specification author can write the prose definition of the operations as:
The
supports( property , value )
method, when called, must run these steps:-
…
The
supports( conditionText )
method, when called, must run these steps:-
…
Yet using value as an optional argument , the specification author has to use more boilerplate-style text to effectively replicate the overload resolution algorithm .
The
supports( propertyOrConditionText , value )
method, when called, must run these steps:-
If value is given, then:
-
Let property be propertyOrConditionText .
-
…
-
-
Otherwise:
-
Let conditionText be propertyOrConditionText .
-
…
-
If the two overloads have little to no shared parts, it is better to leave overload resolution to the IDL mechanism.
-
-
If the operation accepts multiple types for multiple arguments with no coupling between types of different arguments, union types can sometimes be the only viable solution.
typedef (long long or DOMString or CalculatableInterface )SupportedArgument ;interface A {void add (SupportedArgument operand1 ,SupportedArgument operand2 ); };For the
add()
operation above, to specify it using overloads would requireinterface A {void add (long long operand1 ,long long operand2 );void add (long long operand1 ,DOMString operand2 );void add (long long operand1 ,CalculatableInterface operand2 );void add (DOMString operand1 ,long long operand2 );void add (DOMString operand1 ,DOMString operand2 );void add (DOMString operand1 ,CalculatableInterface operand2 );void add (CalculatableInterface operand1 ,long long operand2 );void add (CalculatableInterface operand1 ,DOMString operand2 );void add (CalculatableInterface operand1 ,CalculatableInterface operand2 ); };and nine times the corresponding prose!
-
Specification authors are encouraged to treat missing argument and
undefined argument the same way in the ECMAScript language binding.Given the following IDL fragment:
interface A {void foo ();void foo (Node ?arg ); };Using the ECMAScript language binding, calling
foo(undefined)
andfoo(null)
would both run the steps corresponding to thefoo( arg )
operation, with arg set to null, whilefoo()
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 bothfoo()
andfoo(undefined)
as " arg is missing".interface A {void foo (optional Node ?arg ); };In general, optionality is best expressed using the
optional keyword, and not using overloads.
When the case fits none of the categories above, it is up to the specification author to choose the style, since it is most likely that either style would sufficiently and conveniently describe the intended behavior. However, the definition and conversion algorithms of union types and optional arguments are simpler to implement and reason about than those of overloads , and usually result in more idiomatic APIs in the ECMAScript language binding. Thus, unless any other considerations apply, union types (and/or optional arguments ) are the default choice.
Specifications are also free to mix and match union types and overloads, if the author finds it appropriate and convenient.
2.5.8. Iterable declarations
An
interface
can
be
declared
to
be
iterable
by
using
an
iterable
declaration
(matching
interface interface_identifier {iterable <value_type >;iterable <key_type ,value_type >; };
Objects implementing an interface that is declared to be iterable support being iterated over to obtain a sequence of values.
Note:
In
the
ECMAScript
language
binding,
an
interface
that
is
iterable
will
have
entries
,
forEach
,
keys
,
values
,
and
@@iterator
properties
on
its
interface
prototype
object
.
If a single type parameter is given, then the interface has a value iterator and provides values of the specified type. If two type parameters are given, then the interface has a pair iterator and provides value pairs with the given types.
A value pair , given a key type and a value type, is a struct with two items :
-
an item whose name is "key", which is referred to as the value pair 's key , and whose value is an IDL value of the key type;
-
an item whose name is "value", which is referred to as the value pair 's value , and whose value is an IDL value of the value type.
A value iterator must only be declared on an interface that supports indexed properties . The value-type of the value iterator must be the same as the type returned by the indexed property getter . A value iterator is implicitly defined to iterate over the object’s indexed properties.
A pair iterator must not be declared on an interface that supports indexed properties .
Prose accompanying an interface with a pair iterator must define a list of value pairs for each instance of the interface , which is the list of value pairs to iterate over .
The ECMAScript forEach method that is generated for a value iterator invokes its callback like Array.prototype.forEach does, and the forEach method for a pair iterator invokes its callback like Map.prototype.forEach does.
Since value iterators are currently allowed only on interfaces that support indexed properties , it makes sense to use an Array-like forEach method. There may be a need for value iterators (a) on interfaces that do not support indexed properties , or (b) with a forEach method that instead invokes its callback like Set.prototype.forEach (where the key is the same as the value). If you’re creating an API that needs such a forEach method, please file an issue .
Note:
This
is
how
array
iterator
objects
work.
For
interfaces
that
support
indexed
properties
,
the
iterator
objects
returned
by
entries
,
keys
,
values
,
and
@@iterator
are
actual
array
iterator
objects
.
Interfaces
with
iterable
declarations
must
not
have
any
interface
members
named
"
entries
",
"
forEach
",
"
keys
",
or
"
values
",
or
have
any
inherited
interfaces
that
have
members
with
these
names.
Consider
the
following
interface
SessionManager
,
which
allows
access
to
a
number
of
Session
objects
keyed
by
username:
[Exposed =Window ]interface SessionManager {Session getSessionForUser (DOMString username );iterable <DOMString ,Session >; }; [Exposed =Window ]interface Session {readonly attribute DOMString username ; // ... };
The behavior of the iterator could be defined like so:
The value pairs to iterate over are the list of value pairs with the key being the username and the value being the open
Session
object on theSessionManager
object corresponding to that username, sorted by username.
In
the
ECMAScript
language
binding,
the
interface
prototype
object
for
the
SessionManager
interface
has
a
values
method
that
is
a
function,
which,
when
invoked,
returns
an
iterator
object
that
itself
has
a
next
method
that
returns
the
next
value
to
be
iterated
over.
It
has
keys
and
entries
methods
that
iterate
over
the
usernames
of
session
objects
and
username/
Session
object
pairs,
respectively.
It
also
has
a
@@iterator
method
that
allows
a
SessionManager
to
be
used
in
a
for..of
loop
that
has
the
same
value
as
the
entries
method:
// Get an instance of SessionManager. // Assume that it has sessions for two users, "anna" and "brian". var sm= getSessionManager(); typeof SessionManager. prototype. values; // Evaluates to "function" var it= sm. values(); // values() returns an iterator object String( it); // Evaluates to "[object SessionManager Iterator]" typeof it. next; // Evaluates to "function" // This loop will log "anna" and then "brian". for (;;) { let result= it. next(); if ( result. done) { break ; } let session= result. value; console. log( session. username); } // This loop will also log "anna" and then "brian". for ( let usernameof sm. keys()) { console. log( username); } // Yet another way of accomplishing the same. for ( let [ username, session] of sm) { console. log( username); }
An interface must not have more than one iterable declaration . The inherited interfaces of an interface with an iterable declaration must not also have an iterable declaration . An interface with an iterable declaration and its inherited interfaces must not have a maplike declaration , setlike declaration , or asynchronously iterable declaration .
The
following
extended
attributes
are
applicable
to
iterable
declarations
:
[
Exposed
],
[
SecureContext
].
Iterable ::iterable < TypeWithExtendedAttributes OptionalType > ;
OptionalType ::, TypeWithExtendedAttributes ε
2.5.9. Asynchronously iterable declarations
An
interface
can
be
declared
to
be
asynchronously
iterable
by
using
an
asynchronously
iterable
declaration
(matching
interface interface_identifier { async iterable<value_type>; async iterable<value_type>(/* arguments... */); async iterable<key_type, value_type>; async iterable<key_type, value_type>(/* arguments... */); };
Objects that implement an interface that is declared to be asynchronously iterable support being iterated over asynchronously to obtain a sequence of values.
If a single type parameter is given, then the interface has a value asynchronously iterable declaration and asynchronously provides values of the specified type. If two type parameters are given, then the interface has a pair asynchronously iterable declaration and asynchronously provides value pairs with the given types.
If
given,
an
asynchronously
iterable
declaration
's
arguments
(matching
@@asyncIterator
and
values
properties
on
its
interface
prototype
object
.
If
the
interface
has
a
pair
asynchronously
iterable
declaration
,
it
will
additionally
have
entries
and
keys
properties.
All
of
these
methods
can
be
passed
optional
arguments,
which
correspond
to
the
argument
list
in
the
asynchronously
iterable
declaration
,
and
are
processed
by
the
asynchronous
iterator
initialization
steps
,
if
any
exist.
With
this
in
mind,
the
requirement
that
all
arguments
be
optional
ensures
that,
in
the
ECMAScript
binding,
for
-
await
-
of
can
work
directly
on
instances
of
the
interface,
since
for
-
await
-
of
calls
the
@@asyncIterator
method
with
no
arguments.
Prose
accompanying
an
interface
with
an
asynchronously
iterable
declaration
must
define
a
get
the
next
iteration
result
algorithm.
This
algorithm
receives
the
instance
of
the
interface
that
is
being
iterated,
as
well
as
the
async
iterator
itself
(which
can
be
useful
for
storing
state).
It
must
return
a
Promise
that
either
rejects,
resolves
with
undefined
to
signal
the
end
of
the
iteration,
or
resolves
with
one
of
the
following:
- for value asynchronously iterable declarations :
-
a value of the type given in the declaration;
- for pair asynchronously iterable declarations :
-
a tuple containing a value of the first type given in the declaration, and a value of the second type given in the declaration.
The
prose
may
also
define
an
asynchronous
iterator
return
algorithm.
This
algorithm
receives
the
instance
of
the
interface
that
is
being
iterated,
the
async
iterator
itself,
and
a
single
argument
value
of
type
any
.
This
algorithm
is
invoked
in
the
case
of
premature
termination
of
the
async
iterator.
It
must
return
a
Promise
;
if
that
promise
fulfills,
its
fulfillment
value
will
be
ignored,
but
if
it
rejects,
that
failure
will
be
passed
on
to
users
of
the
async
iterator
API.
In
the
ECMAScript
binding,
this
algorithm
allows
customizing
the
behavior
when
the
async
iterator’s
return()
method
is
invoked.
This
most
commonly
occurs
when
a
break
or
return
statement
causes
an
exit
from
a
for
-
await
-
of
loop.
We
could
add
a
similar
hook
for
throw()
.
So
far
there
has
been
no
need,
but
if
you
are
creating
an
API
that
needs
such
capabilities,
please
file
an
issue
.
The prose may also define asynchronous iterator initialization steps . These receive the instance of the interface being iterated, the newly-created iterator object, and a list of IDL values representing the arguments passed, if any.
Interfaces
with
an
asynchronously
iterable
declaration
must
not
have
any
interface
members
named
"
entries
",
"
keys
",
or
"
values
",
or
have
any
inherited
interfaces
that
have
interface
members
with
these
names.
Consider
the
following
interface
SessionManager
,
which
allows
access
to
a
number
of
Session
objects
keyed
by
username:
[Exposed =Window ]interface SessionManager {Session getSessionForUser (DOMString username );async iterable <DOMString ,Session >; }; [Exposed =Window ]interface Session {readonly attribute DOMString username ; // ... };
The behavior of the iterator could be defined like so:
The asynchronous iterator initialization steps for a
SessionManager
async iterator iterator are:
Set iterator ’s current state to "not yet started".
To get the next iteration result for a
SessionManager
manager and its async iterator iterator :
Let promise be a new promise.
Let key be the following value, if it exists, or null otherwise:
- If iterator ’s current state is "not yet started"
the smallest username in manager ’s open sessions, in lexicographical order
- Otherwise
the smallest username in manager ’s open sessions that is greater than iterator ’s current state, in lexicographical order
Note: iterator ’s current state might no longer be present in the open sessions.
If key is null, then:
Resolve promise with undefined.
Otherwise:
Let session be the
Session
object corresponding to key .Resolve promise with ( username , session ).
Set iterator ’s current state to username .
Return promise .
In
the
ECMAScript
language
binding,
the
interface
prototype
object
for
the
SessionManager
interface
has
a
values
method
that
is
a
function,
which,
when
invoked,
returns
an
asynchronous
iterator
object
that
itself
has
a
next
method
that
returns
the
next
value
to
be
iterated
over.
It
has
keys
and
entries
methods
that
iterate
over
the
usernames
of
session
objects
and
(username,
Session
)
object
pairs,
respectively.
It
also
has
a
@@asyncIterator
method
that
allows
a
SessionManager
to
be
used
in
a
for
await..of
loop
that
has
the
same
value
as
the
entries
method:
// Get an instance of SessionManager. // Assume that it has sessions for two users, "anna" and "brian". var sm= getSessionManager(); typeof SessionManager. prototype. values; // Evaluates to "function" var it= sm. values(); // values() returns an iterator object typeof it. next; // Evaluates to "function" // This loop will log "anna" and then "brian". for await( let usernameof sm. keys()) { console. log( username); } // Yet another way of accomplishing the same. for await( let [ username, session] of sm) { console. log( username); }
An interface must not have more than one asynchronously iterable declaration . The inherited interfaces of an interface with an asynchronously iterable declaration must not also have an asynchronously iterable declaration . An interface with an asynchronously iterable declaration and its inherited interfaces must not have a maplike declaration , setlike declaration , or iterable declaration .
The
following
extended
attributes
are
applicable
to
asynchronously
iterable
declarations
:
[
Exposed
],
[
SecureContext
].
these extended attributes are not currently taken into account. When they are, the effect will be as you would expect.
AsyncIterable ::async iterable < TypeWithExtendedAttributes OptionalType > OptionalArgumentList ;
OptionalArgumentList ::( ArgumentList ) ε
2.5.10. Maplike declarations
An
interface
can
be
declared
to
be
maplike
by
using
a
maplike
declaration
(matching
interface interface_identifier {readonly maplike <key_type ,value_type >;maplike <key_type ,value_type >; };
Objects implementing an interface that is declared to be maplike represent an ordered list of key–value pairs known as its map entries . The types used for the keys and values are given in the angle brackets of the maplike declaration. Keys are required to be unique.
The map entries of an object implementing a maplike interface is empty at the of the object’s creation. Prose accompanying the interface can describe how the map entries of an object change.
Maplike
interfaces
support
an
API
for
querying
the
map
entries
appropriate
for
the
language
binding.
If
the
Note:
In
the
ECMAScript
language
binding,
the
API
for
interacting
with
the
map
entries
is
similar
to
that
available
on
ECMAScript
Map
objects.
If
the
entries
,
forEach
,
get
,
has
,
keys
,
values
,
@@iterator
methods,
and
a
size
getter.
For
read–write
maplikes,
it
also
includes
clear
,
delete
,
and
set
methods.
Maplike
interfaces
must
not
have
any
interface
members
named
"
entries
",
"
forEach
",
"
get
",
"
has
",
"
keys
",
"
size
",
or
"
values
",
or
have
any
inherited
interfaces
that
have
members
with
these
names.
Read–write
maplike
interfaces
must
not
have
any
attributes
or
constants
named
"
clear
",
"
delete
",
or
"
set
",
or
have
any
inherited
interfaces
that
have
attributes
or
constants
with
these
names.
Note:
Operations
named
"
clear
",
"
delete
",
or
"
set
"
are
allowed
on
read–write
maplike
interfaces
and
will
prevent
the
default
implementation
of
these
methods
being
added
to
the
interface
prototype
object
in
the
ECMAScript
language
binding.
This
allows
the
default
behavior
of
these
operations
to
be
overridden.
An interface must not have more than one maplike declaration . The inherited interfaces of a maplike interface must not also have a maplike declaration . A maplike interface and its inherited interfaces must not have an iterable declaration , an asynchronously iterable declaration , a setlike declaration , or an indexed property getter .
ReadOnlyMember ::readonly ReadOnlyMemberRest
ReadWriteMaplike ::MaplikeRest
MaplikeRest ::maplike < TypeWithExtendedAttributes , TypeWithExtendedAttributes > ;
No extended attributes defined in this specification are applicable to maplike declarations .
2.5.11. Setlike declarations
An
interface
can
be
declared
to
be
setlike
by
using
a
setlike
declaration
(matching
interface interface_identifier {readonly setlike <type >;setlike <type >; };
Objects implementing an interface that is declared to be setlike represent an ordered list of values known as its set entries . The type of the values is given in the angle brackets of the setlike declaration. Values are required to be unique.
The set entries of an object implementing a setlike interface is empty at the of the object’s creation. Prose accompanying the interface can describe how the set entries of an object change.
Setlike
interfaces
support
an
API
for
querying
the
set
entries
appropriate
for
the
language
binding.
If
the
Note:
In
the
ECMAScript
language
binding,
the
API
for
interacting
with
the
set
entries
is
similar
to
that
available
on
ECMAScript
Set
objects.
If
the
entries
,
forEach
,
has
,
keys
,
values
,
@@iterator
methods,
and
a
size
getter.
For
read–write
setlikes,
it
also
includes
add
,
clear
,
and
delete
methods.
Setlike
interfaces
must
not
have
any
interface
members
named
"
entries
",
"
forEach
",
"
has
",
"
keys
",
"
size
",
or
"
values
",
or
have
any
inherited
interfaces
that
have
members
with
these
names.
Read–write
setlike
interfaces
must
not
have
any
attributes
or
constants
named
"
add
",
"
clear
",
or
"
delete
",
or
have
any
inherited
interfaces
that
have
attributes
or
constants
with
these
names.
Note:
Operations
named
"
add
",
"
clear
",
or
"
delete
"
are
allowed
on
read–write
setlike
interfaces
and
will
prevent
the
default
implementation
of
these
methods
being
added
to
the
interface
prototype
object
in
the
ECMAScript
language
binding.
This
allows
the
default
behavior
of
these
operations
to
be
overridden.
An interface must not have more than one setlike declaration . The inherited interfaces of a setlike interface must not also have a setlike declaration . A setlike interface and its inherited interfaces must not have an iterable declaration , an asynchronously iterable declaration , a maplike declaration , or an indexed property getter .
ReadOnlyMember ::readonly ReadOnlyMemberRest
ReadWriteSetlike ::SetlikeRest
SetlikeRest ::setlike < TypeWithExtendedAttributes > ;
No extended attributes defined in this specification are applicable to setlike declarations .
2.6. Namespaces
A
namespace
is
a
definition
(matching
namespace identifier { /* namespace_members... */ };
A
namespace
is
a
specification
of
a
set
of
namespace
members
(matching
As
with
interfaces,
the
IDL
for
namespaces
can
be
split
into
multiple
parts
by
using
partial
namespace
definitions
(matching
namespace SomeNamespace { /* namespace_members... */ };partial namespace SomeNamespace { /* namespace_members... */ };
Note: As with partial interface definitions, partial namespace definitions are intended for use as a specification editorial aide, allowing the definition of a namespace to be separated over more than one section of the document, and sometimes multiple documents.
The order that members appear in has significance for property enumeration in the ECMAScript binding .
Note that unlike interfaces or dictionaries, namespaces do not create types.
Of
the
extended
attributes
defined
in
this
specification,
only
the
[
Exposed
]
and
[
SecureContext
]
extended
attributes
are
applicable
to
namespaces.
Namespaces
must
be
annotated
with
the
[
Exposed
]
extended
attribute
.
Partial ::partial PartialDefinition
Namespace ::namespace identifier { NamespaceMembers } ;
NamespaceMembers ::ExtendedAttributeList NamespaceMember NamespaceMembers ε
NamespaceMember ::RegularOperation readonly AttributeRest
The following IDL fragment defines a namespace .
namespace VectorUtils {readonly attribute Vector unit ;double dotProduct (Vector x ,Vector y );Vector crossProduct (Vector x ,Vector y ); };
An
ECMAScript
implementation
would
then
expose
a
global
VectorUtils
data
property
which
was
a
simple
object
(with
prototype
%ObjectPrototype%
)
with
enumerable
data
properties
for
each
declared
operation,
and
enumerable
get-only
accessors
for
each
declared
attribute:
Object. getPrototypeOf( VectorUtils); // Evaluates to Object.prototype. Object. keys( VectorUtils); // Evaluates to ["dotProduct", "crossProduct"]. Object. getOwnPropertyDescriptor( VectorUtils, "dotProduct" ); // Evaluates to { value: <a function>, enumerable: true, configurable: true, writable: true }. Object. getOwnPropertyDescriptor( VectorUtils, "unit" ); // Evaluates to { get: <a function>, enumerable: true, configurable: true }.
2.7. Dictionaries
A
dictionary
is
a
definition
(matching
dictionary identifier { /* dictionary_members... */ };
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 , then that identifier identifies the inherited dictionary. The identifier must identify a dictionary.
A dictionary must not be declared such that its inheritance hierarchy has a cycle. That is, a dictionary A cannot inherit from itself, nor can it inherit from another dictionary B that inherits from A , and so on.
dictionary Base { /* dictionary_members... */ };dictionary Derived :Base { /* dictionary_members... */ };
The inherited dictionaries of a given dictionary D is the set of all dictionaries that D inherits from, directly or indirectly. If D does not inherit from another dictionary, then the set is empty. Otherwise, the set includes the dictionary E that D inherits from and all of E ’s inherited dictionaries .
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 required is optional .
Note that specifying dictionary members as 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 optional in all other cases, including when a dictionary type is used solely as the return type of operations .
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 entries for each of the dictionary members defined on D and on any of D ’s inherited dictionaries . Dictionary members that are specified as required , or that are specified as having a default value , will always have such corresponding entries . Other members' entries might or might not exist in the dictionary value.
In
the
ECMAScript
binding,
a
value
of
As
with
operation
argument
default
values
,
it
is
strongly
encouraged
not
to
use
boolean
-typed
dictionary
members
,
as
this
can
be
confusing
for
authors
who
might
otherwise
expect
the
default
conversion
of
An ordered map with string keys can be implicitly treated as a dictionary value of a specific dictionary D if all of its entries correspond to dictionary members , as long as those entries have the correct types, and there are entries present for any required or defaulted dictionary members.
dictionary Descriptor {DOMString name ;sequence <unsigned long >serviceIdentifiers ; };
A
Descriptor
dictionary
could
be
created
as
in
the
following
steps:
-
Let identifiers be « 1, 3, 7 ».
-
Return «[ "name" → "test", "serviceIdentifiers" → identifiers ]».
Each
dictionary
member
(matching
If the type of the dictionary member , after resolving typedefs, is a nullable type , its inner type must not be a dictionary type .
dictionary identifier {type identifier ; };
If
the
identifier
is
followed
by
a
U+003D
EQUALS
SIGN
("=")
and
a
value
(matching
dictionary identifier {type identifier = "value"; };
When
a
boolean
literal
token
(
If the type of the dictionary member is an enumeration , then its default value if specified must be one of the enumeration’s values .
If
the
type
of
the
dictionary
member
is
preceded
by
the
dictionary identifier {required type identifier ; };
The type of a dictionary member must not include the dictionary it appears on. A type includes a dictionary D if at least one of the following is true:
-
the type is D
-
the type is a dictionary that inherits from D
-
the type is a nullable type whose inner type includes D
-
the type is a sequence type or frozen array whose element type includes D
-
the type is a union type , one of whose member types includes D
-
the type is a dictionary, one of whose members or inherited members has a type that includes D
-
the type is
record < K , V >
where V includes D
As
with
interfaces,
the
IDL
for
dictionaries
can
be
split
into
multiple
parts
by
using
partial
dictionary
definitions
(matching
dictionary SomeDictionary { /* dictionary_members... */ };partial dictionary SomeDictionary { /* dictionary_members... */ };
Note: As with partial interface definitions, partial dictionary definitions are intended for use as a specification editorial aide, allowing the definition of an interface to be separated over more than one section of the document, and sometimes multiple documents.
The order of the dictionary members on a given dictionary is such that inherited dictionary members are ordered before non-inherited members, and the dictionary members on the one dictionary definition (including any partial dictionary definitions) are ordered lexicographically by the Unicode codepoints that comprise their identifiers.
For example, with the following definitions:
dictionary B :A {long b ;long a ; };dictionary A {long c ;long g ; };dictionary C :B {long e ;long f ; };partial dictionary A {long h ;long d ; };
the
order
of
the
dictionary
members
of
a
dictionary
value
of
type
C
is
c,
d,
g,
h,
a,
b,
e,
f.
Dictionaries are required to have their members ordered because in some language bindings the behavior observed when passing a dictionary value to a platform object depends on the order the dictionary members are fetched. For example, consider the following additional interface:
[Exposed =Window ]interface Something {void f (A a ); };
and this ECMAScript code:
var something= getSomething(); // Get an instance of Something. var x= 0 ; var dict= { }; Object. defineProperty( dict, "d" , { get: function () { return ++ x; } }); Object. defineProperty( dict, "c" , { get: function () { return ++ x; } }); something. f( dict);
The
order
that
the
dictionary
members
are
fetched
in
determines
what
values
they
will
be
taken
to
have.
Since
the
order
for
A
is
defined
to
be
c
then
d,
the
value
for
c
will
be
1
and
the
value
for
d
will
be
2.
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 .
No extended attributes are applicable to dictionaries.
Partial ::partial PartialDefinition
Dictionary ::dictionary identifier Inheritance { DictionaryMembers } ;
DictionaryMembers ::DictionaryMember DictionaryMembers ε
DictionaryMember ::ExtendedAttributeList DictionaryMemberRest
DictionaryMemberRest ::required TypeWithExtendedAttributes identifier ; Type identifier Default ;
PartialDictionary ::dictionary identifier { DictionaryMembers } ;
Default ::= DefaultValue ε
DefaultValue ::ConstValue string [ ] { } null
Inheritance ::: identifier ε
One use of dictionary types is to allow a number of optional arguments to an operation without being constrained as to the order they are specified at the call site. For example, consider the following IDL fragment :
[Exposed =Window ]interface Point {constructor ();attribute double x ;attribute double y ; };dictionary PaintOptions {DOMString ?fillPattern = "black";DOMString ?strokePattern =null ;Point position ; }; [Exposed =Window ]interface GraphicsContext {void drawRectangle (double width ,double height ,optional PaintOptions options ); };
In
an
ECMAScript
implementation
of
the
IDL,
an
Object
can
be
passed
in
for
the
optional
PaintOptions
dictionary:
// Get an instance of GraphicsContext. var ctx= getGraphicsContext(); // Draw a rectangle. ctx. drawRectangle( 300 , 200 , { fillPattern: "red" , position: new Point( 10 , 10 ) });
Both fillPattern and strokePattern are given default values , so if they are omitted, the definition of drawRectangle can assume that they have the given default values and not include explicit wording to handle their non-presence.
2.8. Exceptions
An
exception
is
a
type
of
object
that
represents
an
error
and
which
can
be
thrown
or
treated
as
a
first
class
value
by
implementations.
Web
IDL
does
not
allow
exceptions
to
be
defined,
but
instead
has
a
number
of
pre-defined
exceptions
that
specifications
can
reference
and
throw
in
their
definition
of
operations,
attributes,
and
so
on.
Exceptions
have
an
error
name
,
a
DOMString
,
which
is
the
type
of
error
the
exception
represents,
and
a
message
,
which
is
an
optional,
user
agent-defined
value
that
provides
human
readable
details
of
the
error.
There are two kinds of exceptions available to be thrown from specifications. The first is a simple exception , which is identified by one of the following types:
These
correspond
to
all
of
the
ECMAScript
error
objects
(apart
from
SyntaxError
and
Error
,
which
are
deliberately
omitted
as
they
are
reserved
for
use
by
the
ECMAScript
parser
and
by
authors,
respectively).
The
meaning
of
each
simple
exception
matches
its
corresponding
error
object
in
the
ECMAScript
specification.
The
second
kind
of
exception
is
a
DOMException
,
which
is
an
exception
that
encapsulates
a
name
and
an
optional
integer
code,
for
compatibility
with
historically
defined
exceptions
in
the
DOM.
For
simple
exceptions
,
the
error
name
is
the
type
of
the
exception.
For
a
DOMException
,
the
error
name
must
be
one
of
the
names
listed
in
the
error
names
table
below.
The
table
also
indicates
the
DOMException
's
integer
code
for
that
error
name,
if
it
has
one.
Note:
As
DOMException
is
an
interface
type
,
it
can
be
used
as
a
type
in
IDL.
This
allows
for
example
an
operation
to
be
declared
to
have
a
DOMException
return
type
.
Simple
exceptions
can
be
created
by
providing
their
error
name
.
A
DOMException
can
be
created
by
providing
its
error
name
followed
by
DOMException
.
Exceptions
can
also
be
thrown
,
by
providing
the
same
details
required
to
create
one.
The resulting behavior from creating and throwing an exception is language binding-specific.
Note: See § 3.14.3 Creating and throwing exceptions for details on what creating and throwing an exception entails in the ECMAScript language binding.
Here
is
are
some
examples
of
wording
to
use
to
create
and
throw
exceptions.
To
throw
a
new
simple
exception
named
TypeError
:
Throw
a
TypeError
.
To
throw
a
new
DOMException
with
error
name
"
NotAllowedError
":
Throw an "NotAllowedError
"DOMException
.
To
create
a
new
DOMException
with
error
name
"
SyntaxError
":
Let object be a newly created "SyntaxError
"DOMException
.
2.8.1. Error names
The
error
names
table
below
lists
all
the
allowed
error
names
for
DOMException
,
a
description,
and
legacy
code
values.
The
DOMException
names
marked
as
deprecated
are
kept
for
legacy
purposes
but
their
usage
is
discouraged.
Note: If an error name is not listed here, please file a bug as indicated at the top of this specification and it will be addressed shortly. Thanks!
Note:
Don’t
confuse
the
"
SyntaxError
"
DOMException
defined
here
with
ECMAScript’s
SyntaxError
.
"
SyntaxError
"
DOMException
is
used
to
report
parsing
errors
in
web
APIs,
for
example
when
parsing
selectors,
while
the
ECMAScript
SyntaxError
is
reserved
for
the
ECMAScript
parser.
To
help
disambiguate
this
further,
always
favor
the
"
SyntaxError
"
DOMException
notation
over
just
using
SyntaxError
to
refer
to
the
DOMException
.
[DOM]
Name | Description | Legacy code name and value |
---|---|---|
"
IndexSizeError
"
|
Deprecated.
Use
RangeError
instead.
|
INDEX_SIZE_ERR
(1)
|
"
DOMStringSizeError
"
|
Deprecated.
Use
RangeError
instead.
|
DOMSTRING_SIZE_ERR
(2)
|
"
HierarchyRequestError
"
| The operation would yield an incorrect node tree . [DOM] |
HIERARCHY_REQUEST_ERR
(3)
|
"
WrongDocumentError
"
| The object is in the wrong document . [DOM] |
WRONG_DOCUMENT_ERR
(4)
|
"
InvalidCharacterError
"
| The string contains invalid characters. |
INVALID_CHARACTER_ERR
(5)
|
"
NoDataAllowedError
"
| Deprecated. |
NO_DATA_ALLOWED_ERR
(6)
|
"
NoModificationAllowedError
"
| The object can not be modified. |
NO_MODIFICATION_ALLOWED_ERR
(7)
|
"
NotFoundError
"
| The object can not be found here. |
NOT_FOUND_ERR
(8)
|
"
NotSupportedError
"
| The operation is not supported. |
NOT_SUPPORTED_ERR
(9)
|
"
InUseAttributeError
"
| The attribute is in use. |
INUSE_ATTRIBUTE_ERR
(10)
|
"
InvalidStateError
"
| The object is in an invalid state. |
INVALID_STATE_ERR
(11)
|
"
SyntaxError
"
| The string did not match the expected pattern. |
SYNTAX_ERR
(12)
|
"
InvalidModificationError
"
| The object can not be modified in this way. |
INVALID_MODIFICATION_ERR
(13)
|
"
NamespaceError
"
| The operation is not allowed by Namespaces in XML . [XML-NAMES] |
NAMESPACE_ERR
(14)
|
"
InvalidAccessError
"
|
Deprecated.
Use
TypeError
for
invalid
arguments,
"
NotSupportedError
"
DOMException
for
unsupported
operations,
and
"
NotAllowedError
"
DOMException
for
denied
requests
instead.
|
INVALID_ACCESS_ERR
(15)
|
"
ValidationError
"
| Deprecated. |
VALIDATION_ERR
(16)
|
"
TypeMismatchError
"
|
Deprecated.
Use
TypeError
instead.
|
TYPE_MISMATCH_ERR
(17)
|
"
SecurityError
"
| The operation is insecure. |
SECURITY_ERR
(18)
|
"
NetworkError
"
| A network error occurred. |
NETWORK_ERR
(19)
|
"
AbortError
"
| The operation was aborted. |
ABORT_ERR
(20)
|
"
URLMismatchError
"
| The given URL does not match another URL. |
URL_MISMATCH_ERR
(21)
|
"
QuotaExceededError
"
| The quota has been exceeded. |
QUOTA_EXCEEDED_ERR
(22)
|
"
TimeoutError
"
| The operation timed out. |
TIMEOUT_ERR
(23)
|
"
InvalidNodeTypeError
"
| The supplied node is incorrect or has an incorrect ancestor for this operation. |
INVALID_NODE_TYPE_ERR
(24)
|
"
DataCloneError
"
| The object can not be cloned. |
DATA_CLONE_ERR
(25)
|
"
EncodingError
"
| The encoding operation (either encoded or decoding) failed. | — |
"
NotReadableError
"
| The I/O read operation failed. | — |
"
UnknownError
"
| The operation failed for an unknown transient reason (e.g. out of memory). | — |
"
ConstraintError
"
| A mutation operation in a transaction failed because a constraint was not satisfied. | — |
"
DataError
"
| Provided data is inadequate. | — |
"
TransactionInactiveError
"
| A request was placed against a transaction which is currently not active, or which is finished. | — |
"
ReadOnlyError
"
| The mutating operation was attempted in a "readonly" transaction. | — |
"
VersionError
"
| An attempt was made to open a database using a lower version than the existing version. | — |
"
OperationError
"
| The operation failed for an operation-specific reason. | — |
"
NotAllowedError
"
| The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission. | — |
2.9. Enumerations
An
enumeration
is
a
definition
(matching
DOMString
values
that
can
be
assigned
to
an
attribute
or
passed
to
an
operation
.
enum identifier {"enum" ,"values" /* , ... */ };
The
enumeration
values
are
specified
as
a
comma-separated
list
of
It
is
strongly
suggested
that
enumeration
values
be
all
lowercase,
and
that
multiple
words
be
separated
using
dashes
or
not
be
separated
at
all,
unless
there
is
a
specific
reason
to
use
another
value
naming
scheme.
For
example,
an
enumeration
value
that
indicates
an
object
should
be
created
could
be
named
"
createobject
"
or
"
create-object
".
Consider
related
uses
of
enumeration
values
when
deciding
whether
to
dash-separate
or
not
separate
enumeration
value
words
so
that
similar
APIs
are
consistent.
The behavior when a string value that is not one a valid enumeration value is used when assigning to an attribute , or passed as an operation argument, whose type is the enumeration, is language binding specific.
Note: In the ECMAScript binding, assignment of an invalid string value to an attribute is ignored, while passing such a value in other contexts (for example as an operation argument) results in an exception being thrown.
No extended attributes defined in this specification are applicable to enumerations .
Enum ::enum identifier { EnumValueList } ;
EnumValueList ::string EnumValueListComma
EnumValueListComma ::, EnumValueListString ε
EnumValueListString ::string EnumValueListComma ε
The following IDL fragment defines an enumeration that is used as the type of an attribute and an operation argument:
enum MealType {"rice" ,"noodles" ,"other" }; [Exposed =Window ]interface Meal {attribute MealType type ;attribute double size ; // in gramsvoid initialize (MealType type ,double size ); };
An ECMAScript implementation would restrict the strings that can be assigned to the type property or passed to the initializeMeal function to those identified in the enumeration .
var meal= getMeal(); // Get an instance of Meal. meal. initialize( "rice" , 200 ); // Operation invoked as normal. try { meal. initialize( "sandwich" , 100 ); // Throws a TypeError. } catch ( e) { } meal. type= "noodles" ; // Attribute assigned as normal. meal. type= "dumplings" ; // Attribute assignment ignored. meal. type== "noodles" ; // Evaluates to true.
2.10. Callback functions
The “Custom DOM Elements” spec wants to use callback function types for platform object provided functions. Should we rename “callback functions” to just “functions” to make it clear that they can be used for both purposes?
A
callback
function
is
a
definition
(matching
callback identifier =return_type (/* arguments... */);
Note: See also the similarly named callback interfaces .
The
identifier
on
the
left
of
the
equals
sign
gives
the
name
of
the
callback
function
and
the
return
type
and
argument
list
(matching
Callback functions must not be used as the type of a constant .
The
following
extended
attribute
is
applicable
to
callback
functions:
[
LegacyTreatNonObjectAsNull
].
CallbackOrInterfaceOrMixin ::callback CallbackRestOrInterface interface InterfaceOrMixin
CallbackRest ::identifier = ReturnType ( ArgumentList ) ;
The following IDL fragment defines a callback function used for an API that invokes a user-defined function when an operation is complete.
callback AsyncOperationCallback =void (DOMString status ); [Exposed =Window ]interface AsyncOperations {void performOperation (AsyncOperationCallback whenFinished ); };
In the ECMAScript language binding, a function object is passed as the operation argument.
var ops= getAsyncOperations(); // Get an instance of AsyncOperations. ops. performOperation( function ( status) { window. alert( "Operation finished, status is " + status+ "." ); });
2.11. Typedefs
A
typedef
is
a
definition
(matching
typedef type identifier ;
The
type
being
given
a
new
name
is
specified
after
the
The
No extended attributes defined in this specification are applicable to typedefs .
Typedef ::typedef TypeWithExtendedAttributes identifier ;
The following IDL fragment demonstrates the use of typedefs to allow the use of a short identifier instead of a long sequence type .
[Exposed =Window ]interface Point {attribute double x ;attribute double y ; };typedef sequence <Point >Points ; [Exposed =Window ]interface Widget {boolean pointWithinBounds (Point p );boolean allPointsWithinBounds (Points ps ); };
2.12. Objects implementing interfaces
In a given implementation of a set of IDL fragments , an object can be described as being a platform object .
Platform objects are objects that implement an interface .
Legacy
platform
objects
are
platform
objects
that
implement
an
interface
which
does
not
have
a
[
Global
]
extended
attribute
,
and
which
supports
indexed
properties
,
named
properties
,
or
both.
In
a
browser,
for
example,
the
browser-implemented
DOM
objects
(implementing
interfaces
such
as
Node
and
Document
)
that
provide
access
to
a
web
page’s
contents
to
ECMAScript
running
in
the
page
would
be
platform
objects
.
These
objects
might
be
exotic
objects,
implemented
in
a
language
like
C++,
or
they
might
be
native
ECMAScript
objects.
Regardless,
an
implementation
of
a
given
set
of
IDL
fragments
needs
to
be
able
to
recognize
all
platform
objects
that
are
created
by
the
implementation.
This
might
be
done
by
having
some
internal
state
that
records
whether
a
given
object
is
indeed
a
platform
object
for
that
implementation,
or
perhaps
by
observing
that
the
object
is
implemented
by
a
given
internal
C++
class.
How
exactly
platform
objects
are
recognized
by
a
given
implementation
of
a
set
of
IDL
fragments
is
implementation
specific.
All
other
objects
in
the
system
would
not
be
treated
as
platform
objects.
For
example,
assume
that
a
web
page
opened
in
a
browser
loads
an
ECMAScript
library
that
implements
DOM
Core.
This
library
would
be
considered
to
be
a
different
implementation
from
the
browser
provided
implementation.
The
objects
created
by
the
ECMAScript
library
that
implement
the
Node
interface
will
not
be
treated
as
platform
objects
that
implement
Node
by
the
browser
implementation.
Callback
interfaces
,
on
the
other
hand,
can
be
implemented
by
any
ECMAScript
object.
This
allows
Web
APIs
to
invoke
author-defined
operations.
For
example,
the
DOM
Events
implementation
allows
authors
to
register
callbacks
by
providing
objects
that
implement
the
EventListener
interface.
2.13. Types
This section lists the types supported by Web IDL, the set of values corresponding to each type, and how constants of that type are represented.
The
following
types
are
known
as
integer
types
:
byte
,
octet
,
short
,
unsigned
short
,
long
,
unsigned
long
,
long
long
and
unsigned
long
long
.
The
following
types
are
known
as
numeric
types
:
the
integer
types
,
float
,
unrestricted
float
,
double
and
unrestricted
double
.
The
primitive
types
are
boolean
and
the
numeric
types
.
The
string
types
are
DOMString
,
all
enumeration
types
,
ByteString
and
USVString
.
The
typed
array
types
are
Int8Array
,
Int16Array
,
Int32Array
,
Uint8Array
,
Uint16Array
,
Uint32Array
,
Uint8ClampedArray
,
Float32Array
and
Float64Array
.
The
buffer
source
types
are
ArrayBuffer
,
DataView
,
and
the
typed
array
types
.
The
object
type,
all
interface
types
,
and
all
callback
interface
types
are
known
as
object
types
.
Every type has a type name , which is a string, not necessarily unique, that identifies the type. Each sub-section below defines what the type name is for each type.
When conversions are made from language binding specific types to IDL types in order to invoke an operation or assign a value to an attribute , all conversions necessary will be performed before the specified functionality of the operation or attribute assignment is carried out. If the conversion cannot be performed, then the operation will not run or the attribute will not be updated. In some language bindings, type conversions could result in an exception being thrown. In such cases, these exceptions will be propagated to the code that made the attempt to invoke the operation or assign to the attribute.
Type ::SingleType UnionType Null
TypeWithExtendedAttributes ::ExtendedAttributeList Type
SingleType ::DistinguishableType any PromiseType
UnionType ::( UnionMemberType or UnionMemberType UnionMemberTypes )
UnionMemberType ::ExtendedAttributeList DistinguishableType UnionType Null
UnionMemberTypes ::or UnionMemberType UnionMemberTypes ε
DistinguishableType ::PrimitiveType Null StringType Null identifier Null sequence < TypeWithExtendedAttributes > Null object Null symbol Null BufferRelatedType Null FrozenArray < TypeWithExtendedAttributes > Null ObservableArray < TypeWithExtendedAttributes > Null RecordType Null
PrimitiveType ::UnsignedIntegerType UnrestrictedFloatType boolean byte octet
UnrestrictedFloatType ::unrestricted FloatType FloatType
FloatType ::float double
UnsignedIntegerType ::unsigned IntegerType IntegerType
IntegerType ::short long OptionalLong
OptionalLong ::long ε
StringType ::ByteString DOMString USVString
PromiseType ::Promise < ReturnType >
RecordType ::record < StringType , TypeWithExtendedAttributes >
Null ::? ε
2.13.1. any
The
any
type
is
the
union
of
all
other
possible
non-
union
types.
Its
type
name
is
"
Any
".
The
any
type
is
like
a
discriminated
union
type,
in
that
each
of
its
values
has
a
specific
non-
any
type
associated
with
it.
For
example,
one
value
of
the
any
type
is
the
unsigned
long
150,
while
another
is
the
long
150.
These
are
distinct
values.
The
particular
type
of
an
any
value
is
known
as
its
specific
type
.
(Values
of
union
types
also
have
specific
types
.)
2.13.2. void
The
void
type
has
a
unique
value.
It can only be used as the return type of an operation or the parameter of a promise type .
The
type
name
of
the
void
type
is
"
Void
".
2.13.3. boolean
The
boolean
type
has
two
values:
true
and
false
.
boolean
constant
values
in
IDL
are
represented
with
the
The
type
name
of
the
boolean
type
is
"
Boolean
".
2.13.4. byte
The
byte
type
is
a
signed
integer
type
that
has
values
in
the
range
[−128,
127].
byte
constant
values
in
IDL
are
represented
with
The
type
name
of
the
byte
type
is
"
Byte
".
2.13.5. octet
The
octet
type
is
an
unsigned
integer
type
that
has
values
in
the
range
[0,
255].
octet
constant
values
in
IDL
are
represented
with
The
type
name
of
the
octet
type
is
"
Octet
".
2.13.6. short
The
short
type
is
a
signed
integer
type
that
has
values
in
the
range
[−32768,
32767].
short
constant
values
in
IDL
are
represented
with
The
type
name
of
the
short
type
is
"
Short
".
2.13.7. unsigned short
The
unsigned
short
type
is
an
unsigned
integer
type
that
has
values
in
the
range
[0,
65535].
unsigned
short
constant
values
in
IDL
are
represented
with
The
type
name
of
the
unsigned
short
type
is
"
UnsignedShort
".
2.13.8. long
The
long
type
is
a
signed
integer
type
that
has
values
in
the
range
[−2147483648,
2147483647].
long
constant
values
in
IDL
are
represented
with
The
type
name
of
the
long
type
is
"
Long
".
2.13.9. unsigned long
The
unsigned
long
type
is
an
unsigned
integer
type
that
has
values
in
the
range
[0,
4294967295].
unsigned
long
constant
values
in
IDL
are
represented
with
The
type
name
of
the
unsigned
long
type
is
"
UnsignedLong
".
2.13.10. long long
The
long
long
type
is
a
signed
integer
type
that
has
values
in
the
range
[−9223372036854775808,
9223372036854775807].
long
long
constant
values
in
IDL
are
represented
with
The
type
name
of
the
long
long
type
is
"
LongLong
".
2.13.11. unsigned long long
The
unsigned
long
long
type
is
an
unsigned
integer
type
that
has
values
in
the
range
[0,
18446744073709551615].
unsigned
long
long
constant
values
in
IDL
are
represented
with
The
type
name
of
the
unsigned
long
long
type
is
"
UnsignedLongLong
".
2.13.12. float
The
float
type
is
a
floating
point
numeric
type
that
corresponds
to
the
set
of
finite
single-precision
32
bit
IEEE
754
floating
point
numbers.
[IEEE-754]
float
constant
values
in
IDL
are
represented
with
The
type
name
of
the
float
type
is
"
Float
".
Unless
there
are
specific
reasons
to
use
a
32
bit
floating
point
type,
specifications
should
use
double
rather
than
float
,
since
the
set
of
values
that
a
double
can
represent
more
closely
matches
an
ECMAScript
Number.
2.13.13. unrestricted float
The
unrestricted
float
type
is
a
floating
point
numeric
type
that
corresponds
to
the
set
of
all
possible
single-precision
32
bit
IEEE
754
floating
point
numbers,
finite,
non-finite,
and
special
"not
a
number"
values
(NaNs).
[IEEE-754]
unrestricted
float
constant
values
in
IDL
are
represented
with
The
type
name
of
the
unrestricted
float
type
is
"
UnrestrictedFloat
".
2.13.14. double
The
double
type
is
a
floating
point
numeric
type
that
corresponds
to
the
set
of
finite
double-precision
64
bit
IEEE
754
floating
point
numbers.
[IEEE-754]
double
constant
values
in
IDL
are
represented
with
The
type
name
of
the
double
type
is
"
Double
".
2.13.15. unrestricted double
The
unrestricted
double
type
is
a
floating
point
numeric
type
that
corresponds
to
the
set
of
all
possible
double-precision
64
bit
IEEE
754
floating
point
numbers,
finite,
non-finite,
and
special
"not
a
number"
values
(NaNs).
[IEEE-754]
unrestricted
double
constant
values
in
IDL
are
represented
with
The
type
name
of
the
unrestricted
double
type
is
"
UnrestrictedDouble
".
2.13.16. DOMString
The
DOMString
type
corresponds
to
the
set
of
all
possible
sequences
of
code
units
.
Such
sequences
are
commonly
interpreted
as
UTF-16
encoded
strings
[RFC2781]
although
this
is
not
required.
While
DOMString
is
defined
to
be
an
OMG
IDL
boxed
sequence
<
unsigned
short
>
valuetype
in
DOM
Level
3
Core
§The
DOMString
Type
,
this
document
defines
DOMString
to
be
an
intrinsic
type
so
as
to
avoid
special
casing
that
sequence
type
in
various
situations
where
a
string
is
required.
Note:
Note
also
that
DOMString
.
To
allow
DOMString
,
written
as
DOMString?
in
IDL,
needs
to
be
used.
Nothing
in
this
specification
requires
a
DOMString
value
to
be
a
valid
UTF-16
string.
For
example,
a
DOMString
value
might
include
unmatched
surrogate
pair
characters.
However,
authors
of
specifications
using
Web
IDL
might
want
to
obtain
a
sequence
of
Unicode
scalar
values
given
a
particular
sequence
of
code
units
.
There
is
no
way
to
represent
a
constant
DOMString
value
in
IDL,
although
DOMString
dictionary
member
default
values
and
operation
optional
argument
default
values
can
be
set
to
the
value
of
a
The
type
name
of
the
DOMString
type
is
"
String
".
2.13.17. ByteString
The
ByteString
type
corresponds
to
the
set
of
all
possible
sequences
of
bytes.
Such
sequences
might
be
interpreted
as
UTF-8
encoded
strings
[RFC3629]
or
strings
in
some
other
8-bit-per-code-unit
encoding,
although
this
is
not
required.
There
is
no
way
to
represent
a
constant
ByteString
value
in
IDL,
although
ByteString
dictionary
member
default
values
and
operation
optional
argument
default
values
can
be
set
to
the
value
of
a
The
type
name
of
the
ByteString
type
is
"
ByteString
".
Specifications
should
only
use
ByteString
for
interfacing
with
protocols
that
use
bytes
and
strings
interchangeably,
such
as
HTTP.
In
general,
strings
should
be
represented
with
DOMString
values,
even
if
it
is
expected
that
values
of
the
string
will
always
be
in
ASCII
or
some
8
bit
character
encoding.
Sequences
or
frozen
arrays
with
octet
or
byte
elements,
Uint8Array
,
or
Int8Array
should
be
used
for
holding
8
bit
data
rather
than
ByteString
.
2.13.18. USVString
The
USVString
type
corresponds
to
the
set
of
all
possible
sequences
of
Unicode
scalar
values
,
which
are
all
of
the
Unicode
code
points
apart
from
the
surrogate
code
points.
There
is
no
way
to
represent
a
constant
USVString
value
in
IDL,
although
USVString
dictionary
member
default
values
and
operation
optional
argument
default
values
can
be
set
to
the
value
of
a
The
type
name
of
the
USVString
type
is
"
USVString
".
Specifications
should
only
use
USVString
for
APIs
that
perform
text
processing
and
need
a
string
of
Unicode
scalar
values
to
operate
on.
Most
APIs
that
use
strings
should
instead
be
using
DOMString
,
which
does
not
make
any
interpretations
of
the
code
units
in
the
string.
When
in
doubt,
use
DOMString
.
2.13.19. object
The
object
type
corresponds
to
the
set
of
all
possible
non-null
object
references.
There
is
no
way
to
represent
a
constant
object
value
in
IDL.
To
denote
a
type
that
includes
all
possible
object
references
plus
the
object?
.
The
type
name
of
the
object
type
is
"
Object
".
2.13.20. symbol
The
symbol
type
corresponds
to
the
set
of
all
possible
symbol
values.
Symbol
values
are
opaque,
non-
object
values
which
nevertheless
have
identity
(i.e.,
are
only
equal
to
themselves).
There
is
no
way
to
represent
a
constant
symbol
value
in
IDL.
The
type
name
of
the
symbol
type
is
"
Symbol
".
2.13.21. Interface types
An identifier that identifies an interface is used to refer to a type that corresponds to the set of all possible non-null references to objects that implement that interface.
An IDL value of the interface type is represented just by an object reference.
There is no way to represent a constant object reference value for a particular interface type in IDL.
To
denote
a
type
that
includes
all
possible
references
to
objects
implementing
the
given
interface
plus
the
The type name of an interface type is the identifier of the interface.
2.13.22. Callback interface types
An identifier that identifies a callback interface is used to refer to a type that corresponds to the set of all possible non-null references to objects.
An IDL value of the interface type is represented by a tuple of an object reference and a callback context . The callback context is a language binding specific value, and is used to store information about the execution context at the time the language binding specific object reference is converted to an IDL value.
Note: For ECMAScript objects, the callback context is used to hold a reference to the incumbent settings object at the time the Object value is converted to an IDL callback interface type value. See § 3.2.15 Callback interface types .
There is no way to represent a constant object reference value for a particular callback interface type in IDL.
To
denote
a
type
that
includes
all
possible
references
to
objects
plus
the
The type name of a callback interface type is the identifier of the callback interface .
2.13.23. Dictionary types
An identifier that identifies a dictionary is used to refer to a type that corresponds to the set of all dictionaries that adhere to the dictionary definition.
The literal syntax for ordered maps may also be used to represent dictionaries, when it is implicitly understood from context that the map is being treated as an instance of a specific dictionary type. However, there is no way to represent a constant dictionary value inside IDL fragments.
The type name of a dictionary type is the identifier of the dictionary.
2.13.24. Enumeration types
An
identifier
that
identifies
an
enumeration
is
used
to
refer
to
a
type
whose
values
are
the
set
of
strings
(sequences
of
code
units
,
as
with
DOMString
)
that
are
the
enumeration’s
values
.
Like
DOMString
,
there
is
no
way
to
represent
a
constant
enumeration
value
in
IDL,
although
enumeration-typed
dictionary
member
default
values
and
operation
optional
argument
default
values
can
be
set
to
the
value
of
a
The type name of an enumeration type is the identifier of the enumeration.
2.13.25. Callback function types
An identifier that identifies a callback function is used to refer to a type whose values are references to objects that are functions with the given signature.
Note:
If
the
[
LegacyTreatNonObjectAsNull
]
extended
attribute
is
specified
on
the
definition
of
the
callback
function
,
the
values
can
be
references
to
objects
that
are
not
functions.
An IDL value of the callback function type is represented by a tuple of an object reference and a callback context .
Note: As with callback interface types , the callback context is used to hold a reference to the incumbent settings object at the time an ECMAScript Object value is converted to an IDL callback function type value. See § 3.2.18 Callback function types .
There is no way to represent a constant callback function value in IDL.
The type name of a callback function type is the identifier of the callback function.
2.13.26. Nullable types — T ?
A
nullable
type
is
an
IDL
type
constructed
from
an
existing
type
(called
the
inner
type
),
which
just
allows
the
additional
value
-
any
, -
a Promise type ,
-
another nullable type, or
-
a union type that itself includes a nullable type or has a dictionary type as one of its flattened member types .
Note: Although dictionary types can in general be nullable, they cannot when used as the type of an operation argument or a dictionary member.
Nullable
type
constant
values
in
IDL
are
represented
in
the
same
way
that
constant
values
of
their
inner
type
would
be
represented,
or
with
the
The
type
name
of
a
nullable
type
is
the
concatenation
of
the
type
name
of
the
inner
type
T
and
the
string
"
OrNull
".
For
example,
a
type
that
allows
the
values
boolean?
:
[Exposed =Window ]interface NetworkFetcher {void get (optional boolean ?areWeThereYet =false ); };
The
following
interface
has
two
attributes
:
one
whose
value
can
be
a
DOMString
or
the
Node
object
or
the
[Exposed =Window ]interface Node {readonly attribute DOMString ?namespaceURI ;readonly attribute Node ?parentNode ; // ... };
2.13.27. Sequence types — sequence< T >
The sequence< T > type is a parameterized type whose values are (possibly zero-length) lists of values of type T .
Sequences are always passed by value. In language bindings where a sequence is represented by an object of some kind, passing a sequence to a platform object will not result in a reference to the sequence being kept by that object. Similarly, any sequence returned from a platform object will be a copy and modifications made to it will not be visible to the platform object.
The literal syntax for lists may also be used to represent sequences, when it is implicitly understood from context that the list is being treated as a sequences. However, there is no way to represent a constant sequence value inside IDL fragments.
Sequences must not be used as the type of an attribute or constant .
Note: This restriction exists so that it is clear to specification writers and API users that sequences are copied rather than having references to them passed around. Instead of a writable attribute of a sequence type, it is suggested that a pair of operations to get and set the sequence is used.
The
type
name
of
a
sequence
type
is
the
concatenation
of
the
type
name
for
T
and
the
string
"
Sequence
".
Any
list
can
be
implicitly
treated
as
a
sequence<
T
>
,
as
long
as
it
contains
only
items
that
are
of
type
T
.
2.13.28. Record types — record< K , V >
A
record
type
is
a
parameterized
type
whose
values
are
ordered
maps
with
keys
that
are
instances
of
K
and
values
that
are
instances
of
V
.
K
must
be
one
of
DOMString
,
USVString
,
or
ByteString
.
The literal syntax for ordered maps may also be used to represent records, when it is implicitly understood from context that the map is being treated as a record. However, there is no way to represent a constant record value inside IDL fragments.
Records are always passed by value. In language bindings where a record is represented by an object of some kind, passing a record to a platform object will not result in a reference to the record being kept by that object. Similarly, any record returned from a platform object will be a copy and modifications made to it will not be visible to the platform object.
Records must not be used as the type of an attribute or constant .
The
type
name
of
a
record
type
is
the
concatenation
of
the
type
name
for
K
,
the
type
name
for
V
and
the
string
"
Record
".
Any
ordered
map
can
be
implicitly
treated
as
a
record<
K
,
V
>
,
as
long
as
it
contains
only
entries
whose
keys
are
all
of
of
type
K
and
whose
values
are
all
of
type
V
.
2.13.29. Promise types — Promise< T >
A promise type is a parameterized type whose values are references to objects that “is used as a place holder for the eventual results of a deferred (and possibly asynchronous) computation result of an asynchronous operation”. See section 25.4 of the ECMAScript specification for details on the semantics of promise objects.
Promise types are non-nullable, but T may be nullable.
There is no way to represent a promise value in IDL.
The
type
name
of
a
promise
type
is
the
concatenation
of
the
type
name
for
T
and
the
string
"
Promise
".
2.13.30. Union types
A
union
type
is
a
type
whose
set
of
values
is
the
union
of
those
in
two
or
more
other
types.
Union
types
(matching
For
example,
you
might
write
(Node
or
DOMString)
or
(double
or
sequence<double>)
.
When
applying
a
(Node
or
DOMString)?
.
Note
that
the
member
types
of
a
union
type
do
not
descend
into
nested
union
types.
So
for
(double
or
(sequence<long>
or
Event)
or
(Node
or
DOMString)?)
the
member
types
are
double
,
(sequence<long>
or
Event)
and
(Node
or
DOMString)?
.
Like
the
any
type,
values
of
union
types
have
a
specific
type
,
which
is
the
particular
member
type
that
matches
the
value.
The flattened member types of a union type , possibly annotated , is a set of types determined as follows:
-
Let T be the union type .
-
Initialize S to ∅.
-
For each member type U of T :
-
If U is an annotated type , then set U to be the inner type of U .
-
If U is a nullable type , then set U to be the inner type of U .
-
If U is a union type , then add to S the flattened member types of U .
-
Otherwise, U is not a union type . Add U to S .
-
-
Return S .
Note:
For
example,
the
flattened
member
types
of
the
union
type
(Node
or
(sequence<long>
or
Event)
or
(XMLHttpRequest
or
DOMString)?
or
sequence<(sequence<double>
or
NodeList)>)
are
the
six
types
Node
,
sequence<long>
,
Event
,
XMLHttpRequest
,
DOMString
and
sequence<(sequence<double>
or
NodeList)>
.
The number of nullable member types of a union type is an integer determined as follows:
-
Let T be the union type .
-
Initialize n to 0.
-
For each member type U of T :
-
If U is a nullable type , then:
-
Set n to n + 1.
-
Set U to be the inner type of U .
-
-
If U is a union type , then:
-
Let m be the number of nullable member types of U .
-
Set n to n + m .
-
-
-
Return n .
The
any
type
must
not
be
used
as
a
union
member
type
.
The number of nullable member types of a union type must be 0 or 1, and if it is 1 then the union type must also not have a dictionary type in its flattened member types .
A type includes a nullable type if:
-
the type is a nullable type , or
-
the type is an annotated type and its inner type is a nullable type, or
-
the type is a union type and its number of nullable member types is 1.
Each pair of flattened member types in a union type , T and U , must be distinguishable .
Union type constant values in IDL are represented in the same way that constant values of their member types would be represented.
The
type
name
of
a
union
type
is
formed
by
taking
the
type
names
of
each
member
type,
in
order,
and
joining
them
with
the
string
"
Or
".
DistinguishableType ::PrimitiveType Null StringType Null identifier Null sequence < TypeWithExtendedAttributes > Null object Null symbol Null BufferRelatedType Null FrozenArray < TypeWithExtendedAttributes > Null ObservableArray < TypeWithExtendedAttributes > Null RecordType Null
2.13.31. Annotated types
Additional types can be created from existing ones by specifying certain extended attributes on the existing types. Such types are called annotated types , and the types they annotate are called inner types .
[Clamp]
long
defines
a
new
annotated
type
,
whose
behavior
is
based
on
that
of
the
inner
type
long
,
but
modified
as
specified
by
the
[
Clamp
]
extended
attribute.
The
following
extended
attributes
are
applicable
to
types
:
[
AllowShared
],
[
Clamp
],
[
EnforceRange
],
and
[
LegacyNullToEmptyString
].
-
Let extended attributes be a new empty set .
-
If type appears as part of a
TypeWithExtendedAttributes production, append each of the extended attributes present in the production’sExtendedAttributeList to extended attributes . -
If type is a member type of a union type U , append each of the extended attributes associated with U to extended attributes .
-
If type appears as part of a
Type production directly within anArgument production, append to extended attributes all of the extended attributes present in the production’sExtendedAttributeList that are applicable to types .[
Exposed =Window ]interface I {void f ([XAttr ]long attrib ); };Note that this is an example of this step only if [
XAttr
] is applicable to types ; otherwise [XAttr
] applies to the argument, and not the argument’s type. -
If type appears as part of a
Type production directly within anDictionaryMember production, append to extended attributes all of the extended attributes present in the production’sExtendedAttributeList that are applicable to types .dictionary D { [XAttr ]long member ; };Note that this is an example of this step only if [
XAttr
] is applicable to types ; otherwise [XAttr
] applies to the dictionary member, and not the member’s type. -
If type is a typedef , append the extended attributes associated with the type being given a new name to extended attributes .
-
Return extended attributes .
For any type, the extended attributes associated with it must only contain extended attributes that are applicable to types .
The type name of a type associated with extended attributes is the concatenation of the type name of the original type with the set of strings corresponding to the identifiers of each extended attribute associated with the type, sorted in lexicographic order.
2.13.32. Buffer source types
There are a number of types that correspond to sets of all possible non-null references to objects that represent a buffer of data or a view on to a buffer of data. The table below lists these types and the kind of buffer or view they represent.
Type | Kind of buffer |
---|---|
ArrayBuffer
| An object that holds a pointer (which may be null) to a buffer of a fixed number of bytes |
DataView
|
A
view
on
to
an
ArrayBuffer
that
allows
typed
access
to
integers
and
floating
point
values
stored
at
arbitrary
offsets
into
the
buffer
|
Int8Array
,
Int16Array
,
Int32Array
|
A
view
on
to
an
ArrayBuffer
that
exposes
it
as
an
array
of
two’s
complement
signed
integers
of
the
given
size
in
bits
|
Uint8Array
,
Uint16Array
,
Uint32Array
|
A
view
on
to
an
ArrayBuffer
that
exposes
it
as
an
array
of
unsigned
integers
of
the
given
size
in
bits
|
Uint8ClampedArray
|
A
view
on
to
an
ArrayBuffer
that
exposes
it
as
an
array
of
unsigned
8
bit
integers
with
clamped
conversions
|
Float32Array
,
Float64Array
|
A
view
on
to
an
ArrayBuffer
that
exposes
it
as
an
array
of
IEEE
754
floating
point
numbers
of
the
given
size
in
bits
|
Note: These types all correspond to classes defined in ECMAScript.
There is no way to represent a constant value of any of these types in IDL.
The type name of all of these types is the name of the type itself.
At the specification prose level, IDL buffer source types are simply references to objects. To inspect or manipulate the bytes inside the buffer, specification prose must first either get a reference to the bytes held by the buffer source or get a copy of the bytes held by the buffer source . With a reference to the buffer source’s bytes, specification prose can get or set individual byte values using that reference.
Extreme care must be taken when writing specification text that gets a reference to the bytes held by a buffer source, as the underlying data can easily be changed by the script author or other APIs at unpredictable times. If you are using a buffer source type as an operation argument to obtain a chunk of binary data that will not be modified, it is strongly recommended to get a copy of the buffer source’s bytes at the beginning of the prose defining the operation.
Requiring prose to explicitly get a reference to or copy of the bytes is intended to help specification reviewers look for problematic uses of these buffer source types.
When
designing
APIs
that
take
a
buffer,
it
is
recommended
to
use
the
BufferSource
typedef
rather
than
ArrayBuffer
or
any
of
the
view
types.
When
designing
APIs
that
create
and
return
a
buffer,
it
is
recommended
to
use
the
ArrayBuffer
type
rather
than
Uint8Array
.
Attempting
to
get
a
reference
to
or
get
a
copy
of
the
bytes
held
by
a
buffer
source
when
the
ArrayBuffer
has
been
detached
will
fail
in
a
language
binding-specific
manner.
Note: See § 3.2.24 Buffer source types below for how interacting with buffer source types works in the ECMAScript language binding.
We should include an example of specification text that uses these types and terms.
BufferRelatedType ::ArrayBuffer DataView Int8Array Int16Array Int32Array Uint8Array Uint16Array Uint32Array Uint8ClampedArray Float32Array Float64Array
2.13.33. Frozen array types — FrozenArray< T >
A frozen array type is a parameterized type whose values are references to objects that hold a fixed length array of unmodifiable values. The values in the array are of type T .
Since FrozenArray< T > values are references, they are unlike sequence types , which are lists of values that are passed by value.
There is no way to represent a constant frozen array value in IDL.
The
type
name
of
a
frozen
array
type
is
the
concatenation
of
the
type
name
for
T
and
the
string
"
Array
".
2.13.34. Observable array types — ObservableArray< T >
An observable array type is a parametrized type whose values are references to a combination of a mutable list of objects of type T , as well as behavior to perform when author code modifies the contents of the list.
The parametrized type must not be a dictionary type , sequence type , or record type .
Similar to sequence types and frozen array types , observable array types wrap around ECMAScript array types, imposing additional semantics on their usage.
Observable array types must only be used as the type of regular attributes .
For an attribute whose type is an observable array type, specification authors can specify a series of algorithms:
-
set an indexed value , which accepts an IDL value that is about to be set in the observable array, and the index at which it is being set;
-
delete an indexed value , which accepts an IDL value that is about to be removed from the observable array, and the index from which it is being removed.
Both of these algorithms are optional, and if not provided, the default behavior will be to do nothing. Either algorithm may throw an exception, e.g. to reject invalid values.
Note that when ECMAScript code sets an existing index to a new value, this will first call the delete an indexed value algorithm to remove the existing value, and then the set an indexed value algorithm with the new value.
Every regular attribute whose type is an observable array type has a backing list , which is a list , initially empty. Specification authors can modify the contents of the backing list, which will automatically be reflected in the contents of the observable array as observed by ECMAScript code. Similarly, any modifications by ECMAScript code to the contents of the observable array will be reflected back into the backing list, after passing through the set an indexed value and delete an indexed value algorithms.
There is no way to represent a constant observable array value in IDL.
The
type
name
of
an
observable
array
type
is
the
concatenation
of
the
type
name
for
T
and
the
string
"
ObservableArray
".
[Exposed =Window ]interface Building {attribute ObservableArray <Employee >employees ; };
The behavior of the attribute could be defined like so:
The set an indexed value algorithm forBuilding
’semployees
attribute, given employee and index , is:
If employee is not allowed to enter the building today, then throw a "
NotAllowedError
"DOMException
.If index is greater than 200, then throw a "
QuotaExceededError
"DOMException
.Put employee to work!
The delete an indexed value algorithm for
Building
’semployees
attribute, given employee and index , is:
Alert security that employee has left the building.
Then,
ECMAScript
code
could
manipulate
the
employees
property
in
various
ways:
// Get an instance of Building. const building= getBuilding(); building. employees. push( new Employee( "A" )); building. employees. push( new Employee( "B" )); building. employees. push( new Employee( "C" )); building. employees. splice( 1 , 1 ); const employeeB= building. employees. pop(); building. employees= [ new Employee( "D" ), employeeB, new Employee( "C" )]; building. employees. length= 0 ; // Will throw: building. employees. push( "not an Employee; a string instead" );
All of these manipulations would pass through the above-defined set an indexed value algorithm, potentially throwing if the conditions described there were met. They would also perform the appropriate side effects listed there and in the delete an indexed value algorithm.
Another
thing
to
note
about
the
above
code
example
is
how
all
of
the
ECMAScript
array
methods
from
%ArrayPrototype%
work
on
the
observable
array.
Indeed,
it
fully
behaves
like
an
Array
instance:
const normalArray= []; // If building.employees were defined as an indexed property getter interface: normalArray // would contains a single item, building.employees. // // For observable arrays (and frozen arrays): normalArray contains all of the items inside // of building.employees. normalArray. concat( building. employees); // names is an ECMAScript Array. const names= building. employees. map( employee=> employee. name); // Passes various brand checks: console. assert( building. employeesinstanceof Array); console. assert( Array. isArray( building. employees)); console. assert( building. employees. constructor=== Array); // Even is treated as an array by JSON.stringify! console. assert( JSON. stringify( building. employees) === `["object Employee"]` );
2.14. Extended attributes
An
extended
attribute
is
an
annotation
that
can
appear
on
definitions
,
types
as
annotated
types
,
interface
members
,
interface
mixin
members
,
callback
interface
members
,
namespace
members
,
dictionary
members
,
and
operation
arguments,
and
is
used
to
control
how
language
bindings
will
handle
those
constructs.
Extended
attributes
are
specified
with
an
The
Grammar symbol | Form | Example |
---|---|---|
| takes no arguments |
[Replaceable]
|
| takes an argument list |
Not
currently
used;
previously
used
by
[Constructor(double
x,
double
y)]
|
| takes a named argument list |
[LegacyFactoryFunction=Image(DOMString
src)]
|
| takes an identifier |
[PutForwards=name]
|
| takes an identifier list |
[Exposed=(Window,Worker)]
|
This specification defines a number of extended attributes that are applicable to the ECMAScript language binding, which are described in § 3.3 Extended attributes . Each extended attribute definition will state which of the above five forms are allowed.
ExtendedAttributeList ::[ ExtendedAttribute ExtendedAttributes ] ε
ExtendedAttributes ::, ExtendedAttribute ExtendedAttributes ε
ExtendedAttribute ::( ExtendedAttributeInner ) ExtendedAttributeRest [ ExtendedAttributeInner ] ExtendedAttributeRest { ExtendedAttributeInner } ExtendedAttributeRest Other ExtendedAttributeRest
ExtendedAttributeRest ::ExtendedAttribute ε
ExtendedAttributeInner ::( ExtendedAttributeInner ) ExtendedAttributeInner [ ExtendedAttributeInner ] ExtendedAttributeInner { ExtendedAttributeInner } ExtendedAttributeInner OtherOrComma ExtendedAttributeInner ε
Other ::integer decimal identifier string other - -Infinity . ... : ; < = > ? ByteString DOMString FrozenArray Infinity NaN ObservableArray Promise USVString any boolean byte double false float long null object octet or optional record sequence short symbol true unsigned void ArgumentNameKeyword BufferRelatedType
OtherOrComma ::Other ,
IdentifierList ::identifier Identifiers
Identifiers ::, identifier Identifiers ε
ExtendedAttributeNoArgs ::identifier
ExtendedAttributeArgList ::identifier ( ArgumentList )
ExtendedAttributeIdent ::identifier = identifier
ExtendedAttributeIdentList ::identifier = ( IdentifierList )
ExtendedAttributeNamedArgList ::identifier = identifier ( ArgumentList )
3. ECMAScript binding
This section describes how definitions written with the IDL defined in § 2 Interface definition language correspond to particular constructs in ECMAScript, as defined by the ECMAScript Language Specification [ECMA-262] .
Unless otherwise specified, objects defined in this section are ordinary objects as described in ECMA-262 Ordinary object internal methods and internal slots , and if the object is a function object , ECMA-262 Built-in function objects .
This section may redefine certain internal methods and/or internal slots of objects. Other specifications may also override the definitions of any internal method and/or internal slots of a platform object that is an instance of an interface . These objects with changed semantics shall be treated in accordance with the rules for exotic objects.
As
overriding
internal
ECMAScript
object
methods
is
a
low
level
operation
and
can
result
in
objects
that
behave
differently
from
ordinary
objects,
this
facility
should
not
be
used
unless
necessary
for
security
or
compatibility.
This
is
currently
used
to
define
the
HTMLAllCollection
and
Location
interfaces.
[HTML]
Unless otherwise specified, exotic objects defined in this section and other specifications have the same internal slots as ordinary objects, and all of the internal methods for which alternative definitions are not given are the same as those of ordinary objects.
Unless
otherwise
specified,
the
[[Extensible]]
internal
slot
of
objects
defined
in
this
section
has
the
value
Unless
otherwise
specified,
the
[[Prototype]]
internal
slot
of
objects
defined
in
this
section
is
%ObjectPrototype%
.
Some
objects
described
in
this
section
are
defined
to
have
a
class
string
,
which
is
the
string
to
include
in
the
string
returned
from
Object.prototype.toString.
Object.prototype.toString
.
If
an
object
has
a
class
string
classString
,
then
the
object
must,
at
the
time
it
is
created,
have
a
property
whose
name
is
the
@@toStringTag
symbol
with
PropertyDescriptor{[[Writable]]:
Algorithms in this section use the conventions described in ECMA-262 Algorithm conventions , such as the use of steps and substeps, the use of mathematical operations, and so on. This section may also reference abstract operations and notations defined in other parts of ECMA-262.
When
an
algorithm
says
to
throw
a
Something
Error
then
this
means
to
construct
a
new
ECMAScript
Something
Error
object
in
the
current
Realm
and
to
throw
it,
just
as
the
algorithms
in
ECMA-262
do.
Note that algorithm steps can call in to other algorithms and abstract operations and not explicitly handle exceptions that are thrown from them. When an exception is thrown by an algorithm or abstract operation and it is not explicitly handled by the caller, then it is taken to end the algorithm and propagate out to its caller, and so on.
Consider the following algorithm:
-
Let x be the ECMAScript value passed in to this algorithm.
-
Let y be the result of calling ToString ( x ).
-
Return y .
Since
ToString
can
throw
an
exception
(for
example
if
passed
the
object
({
toString:
function()
{
throw
1
}
})
),
and
the
exception
is
not
handled
in
the
above
algorithm,
if
one
is
thrown
then
it
causes
this
algorithm
to
end
and
for
the
exception
to
propagate
out
to
its
caller,
if
there
is
one.
3.1. ECMAScript environment
In an ECMAScript implementation of a given set of IDL fragments , there will exist a number of ECMAScript objects that correspond to definitions in those IDL fragments . These objects are termed the initial objects , and comprise the following:
Each Realm must have its own unique set of each of the initial objects , created before control enters any ECMAScript execution context associated with the Realm, but after the global object for that Realm is created. The [[Prototype]]s of all initial objects in a given Realm must come from that same Realm .
In an HTML user agent, multiple Realms can exist when multiple frames or windows are created. Each frame or window will have its own set of initial objects , which the following HTML document demonstrates:
<!DOCTYPE html> < title > Different Realms</ title > < iframe id = a ></ iframe > < script > var iframe= document. getElementById( "a" ); var w= iframe. contentWindow; // The global object in the frame Object== w. Object; // Evaluates to false, per ECMA-262 Node== w. Node; // Evaluates to false iframeinstanceof w. Node; // Evaluates to false iframeinstanceof w. Object; // Evaluates to false iframe. appendChildinstanceof Function; // Evaluates to true iframe. appendChildinstanceof w. Function; // Evaluates to false </ script >
Note: All interfaces define which Realms they are exposed in. This allows, for example, Realms for Web Workers to expose different sets of supported interfaces from those exposed in Realms for Web pages.
Although at the time of this writing the ECMAScript specification does not reflect this, every ECMAScript object must have an associated Realm . The mechanisms for associating objects with Realms are, for now, underspecified. However, we note that in the case of platform objects , the associated Realm is equal to the object’s relevant Realm , and for non-exotic function objects (i.e. not callable proxies, and not bound functions) the associated Realm is equal to the value of the function object 's [[Realm]] internal slot.
3.2. ECMAScript type mapping
This section describes how types in the IDL map to types in ECMAScript.
Each sub-section below describes how values of a given IDL type are represented in ECMAScript. For each IDL type, it is described how ECMAScript values are converted to an IDL value when passed to a platform object expecting that type, and how IDL values of that type are converted to ECMAScript values when returned from a platform object.
Note that the sub-sections and algorithms below also apply to annotated types created by applying extended attributes to the types named in their headers.
3.2.1. any
Since
the
IDL
any
type
is
the
union
of
all
other
IDL
types,
it
can
correspond
to
any
ECMAScript
value
type.
An
ECMAScript
value
V
is
converted
to
an
IDL
any
value
by
running
the
following
algorithm:
-
If V is
undefined , then return anobject
reference to a special object that represents the ECMAScriptundefined value. -
If V is
null , then return thenull object?
reference. -
If Type ( V ) is Boolean, then return the
boolean
value that represents the same truth value. -
If Type ( V ) is Number, then return the result of converting V to an
unrestricted double
. -
If Type ( V ) is String, then return the result of converting V to a
DOMString
. -
If Type ( V ) is Symbol, then return the result of converting V to a
symbol
. -
If Type ( V ) is Object, then return an IDL
object
value that references V .
An
IDL
any
value
is
converted
to
an
ECMAScript
value
as
follows.
If
the
value
is
an
object
reference
to
a
special
object
that
represents
an
ECMAScript
any
value
as
described
in
the
remainder
of
this
section
are
performed.
3.2.2. void
An
ECMAScript
value
V
is
converted
to
an
IDL
void
value
by
returning
the
unique
void
value,
ignoring
V
.
The
unique
IDL
void
value
is
converted
to
the
ECMAScript
3.2.3. boolean
The
IDL
boolean
value
true
is
converted
to
the
ECMAScript
boolean
value
false
is
converted
to
the
ECMAScript
3.2.4. Integer types
Mathematical operations used in this section, including those defined in ECMA-262 Algorithm conventions , are to be understood as computing exact mathematical results on mathematical real numbers.
In effect, where x is a Number value, “operating on x ” is shorthand for “operating on the mathematical real number that represents the same numeric value as x ”.
3.2.4.1. byte
An
ECMAScript
value
V
is
converted
to
an
IDL
byte
value
by
running
the
following
algorithm:
-
Let x be ? ConvertToInt ( V , 8, "
signed
"). -
Return the IDL
byte
value that represents the same numeric value as x .
The
result
of
converting
an
IDL
byte
value
to
an
ECMAScript
value
is
a
Number
that
represents
the
same
numeric
value
as
the
IDL
byte
value.
The
Number
value
will
be
an
integer
in
the
range
[−128,
127].
3.2.4.2. octet
An
ECMAScript
value
V
is
converted
to
an
IDL
octet
value
by
running
the
following
algorithm:
-
Let x be ? ConvertToInt ( V , 8, "
unsigned
"). -
Return the IDL
octet
value that represents the same numeric value as x .
The
result
of
converting
an
IDL
octet
value
to
an
ECMAScript
value
is
a
Number
that
represents
the
same
numeric
value
as
the
IDL
octet
value.
The
Number
value
will
be
an
integer
in
the
range
[0,
255].
3.2.4.3. short
An
ECMAScript
value
V
is
converted
to
an
IDL
short
value
by
running
the
following
algorithm:
-
Let x be ? ConvertToInt ( V , 16, "
signed
"). -
Return the IDL
short
value that represents the same numeric value as x .
The
result
of
converting
an
IDL
short
value
to
an
ECMAScript
value
is
a
Number
that
represents
the
same
numeric
value
as
the
IDL
short
value.
The
Number
value
will
be
an
integer
in
the
range
[−32768,
32767].
3.2.4.4. unsigned short
An
ECMAScript
value
V
is
converted
to
an
IDL
unsigned
short
value
by
running
the
following
algorithm:
-
Let x be ? ConvertToInt ( V , 16, "
unsigned
"). -
Return the IDL
unsigned short
value that represents the same numeric value as x .
The
result
of
converting
an
IDL
unsigned
short
value
to
an
ECMAScript
value
is
a
Number
that
represents
the
same
numeric
value
as
the
IDL
unsigned
short
value.
The
Number
value
will
be
an
integer
in
the
range
[0,
65535].
3.2.4.5. long
An
ECMAScript
value
V
is
converted
to
an
IDL
long
value
by
running
the
following
algorithm:
-
Let x be ? ConvertToInt ( V , 32, "
signed
"). -
Return the IDL
long
value that represents the same numeric value as x .
The
result
of
converting
an
IDL
long
value
to
an
ECMAScript
value
is
a
Number
that
represents
the
same
numeric
value
as
the
IDL
long
value.
The
Number
value
will
be
an
integer
in
the
range
[−2147483648,
2147483647].
3.2.4.6. unsigned long
An
ECMAScript
value
V
is
converted
to
an
IDL
unsigned
long
value
by
running
the
following
algorithm:
-
Let x be ? ConvertToInt ( V , 32, "
unsigned
"). -
Return the IDL
unsigned long
value that represents the same numeric value as x .
The
result
of
converting
an
IDL
unsigned
long
value
to
an
ECMAScript
value
is
a
Number
that
represents
the
same
numeric
value
as
the
IDL
unsigned
long
value.
The
Number
value
will
be
an
integer
in
the
range
[0,
4294967295].
3.2.4.7. long long
An
ECMAScript
value
V
is
converted
to
an
IDL
long
long
value
by
running
the
following
algorithm:
-
Let x be ? ConvertToInt ( V , 64, "
signed
"). -
Return the IDL
long long
value that represents the same numeric value as x .
The
result
of
converting
an
IDL
long
long
value
to
an
ECMAScript
value
is
a
Number
value
that
represents
the
closest
numeric
value
to
the
long
long
,
choosing
the
numeric
value
with
an
even
significand
if
there
are
two
equally
close
values
.
If
the
long
long
is
in
the
range
[−2
53
+
1,
2
53
−
1],
then
the
Number
will
be
able
to
represent
exactly
the
same
value
as
the
long
long
.
3.2.4.8. unsigned long long
An
ECMAScript
value
V
is
converted
to
an
IDL
unsigned
long
long
value
by
running
the
following
algorithm:
-
Let x be ? ConvertToInt ( V , 64, "
unsigned
"). -
Return the IDL
unsigned long long
value that represents the same numeric value as x .
The
result
of
converting
an
IDL
unsigned
long
long
value
to
an
ECMAScript
value
is
a
Number
value
that
represents
the
closest
numeric
value
to
the
unsigned
long
long
,
choosing
the
numeric
value
with
an
even
significand
if
there
are
two
equally
close
values
.
If
the
unsigned
long
long
is
less
than
or
equal
to
2
53
−
1,
then
the
Number
will
be
able
to
represent
exactly
the
same
value
as
the
unsigned
long
long
.
3.2.4.9. Abstract operations
IntegerPart( n ) :
ConvertToInt( V , bitLength , signedness ) :
-
If bitLength is 64, then:
-
Let upperBound be 2 53 − 1.
-
If signedness is "
unsigned
", then let lowerBound be 0. -
Otherwise let lowerBound be −2 53 + 1.
Note: this ensures
long long
types associated with [EnforceRange
] or [Clamp
] extended attributes are representable in ECMAScript’s Number type as unambiguous integers.
-
-
Otherwise, if signedness is "
unsigned
", then:-
Let lowerBound be 0.
-
Let upperBound be 2 bitLength − 1.
-
-
Otherwise:
-
Let lowerBound be -2 bitLength − 1 .
-
Let upperBound be 2 bitLength − 1 − 1.
-
-
If x is −0, then set x to +0.
-
If the conversion is to an IDL type associated with the [
EnforceRange
] extended attribute , then: -
If x is not
NaN and the conversion is to an IDL type associated with the [Clamp
] extended attribute, then: -
If x is
NaN , +0, +∞, or −∞, then return +0. -
Set x to ! IntegerPart ( x ).
-
Set x to x modulo 2 bitLength .
-
If signedness is "
signed
" and x ≥ 2 bitLength − 1 , then return x − 2 bitLength . -
Otherwise, return x .
3.2.5. float
An
ECMAScript
value
V
is
converted
to
an
IDL
float
value
by
running
the
following
algorithm:
-
Let S be the set of finite IEEE 754 single-precision floating point values except −0, but with two special values added: 2 128 and −2 128 .
-
Let y be the number in S that is closest to x , selecting the number with an even significand if there are two equally close values . (The two special values 2 128 and −2 128 are considered to have even significands for this purpose.)
-
If y is +0 and x is negative, return −0.
-
Return y .
The
result
of
converting
an
IDL
float
value
to
an
ECMAScript
value
is
the
Number
value
that
represents
the
same
numeric
value
as
the
IDL
float
value.
3.2.6. unrestricted float
An
ECMAScript
value
V
is
converted
to
an
IDL
unrestricted
float
value
by
running
the
following
algorithm:
-
If x is
NaN , then return the IDLunrestricted float
value that represents the IEEE 754 NaN value with the bit pattern 0x7fc00000 [IEEE-754] . -
Let S be the set of finite IEEE 754 single-precision floating point values except −0, but with two special values added: 2 128 and −2 128 .
-
Let y be the number in S that is closest to x , selecting the number with an even significand if there are two equally close values . (The two special values 2 128 and −2 128 are considered to have even significands for this purpose.)
-
If y is 2 128 , return +∞.
-
If y is −2 128 , return −∞.
-
If y is +0 and x is negative, return −0.
-
Return y .
Note:
Since
there
is
only
a
single
ECMAScript
The
result
of
converting
an
IDL
unrestricted
float
value
to
an
ECMAScript
value
is
a
Number:
-
If the IDL
unrestricted float
value is a NaN, then the Number value isNaN . -
Otherwise, the Number value is the one that represents the same numeric value as the IDL
unrestricted float
value.
3.2.7. double
The
result
of
converting
an
IDL
double
value
to
an
ECMAScript
value
is
the
Number
value
that
represents
the
same
numeric
value
as
the
IDL
double
value.
3.2.8. unrestricted double
An
ECMAScript
value
V
is
converted
to
an
IDL
unrestricted
double
value
by
running
the
following
algorithm:
-
If x is
NaN , then return the IDLunrestricted double
value that represents the IEEE 754 NaN value with the bit pattern 0x7ff8000000000000 [IEEE-754] . -
Return the IDL
unrestricted double
value that represents the same numeric value as x .
Note:
Since
there
is
only
a
single
ECMAScript
The
result
of
converting
an
IDL
unrestricted
double
value
to
an
ECMAScript
value
is
a
Number:
-
If the IDL
unrestricted double
value is a NaN, then the Number value isNaN . -
Otherwise, the Number value is the one that represents the same numeric value as the IDL
unrestricted double
value.
3.2.9. DOMString
An
ECMAScript
value
V
is
converted
to
an
IDL
DOMString
value
by
running
the
following
algorithm:
-
If V is
null and the conversion is to an IDL type associated with the [LegacyNullToEmptyString
] extended attribute, then return theDOMString
value that represents the empty string. -
Let x be ToString ( V ).
-
Return the IDL
DOMString
value that represents the same sequence of code units as the one the ECMAScript String value x represents.
The
result
of
converting
an
IDL
DOMString
value
to
an
ECMAScript
value
is
the
String
value
that
represents
the
same
sequence
of
code
units
that
the
IDL
DOMString
represents.
3.2.10. ByteString
An
ECMAScript
value
V
is
converted
to
an
IDL
ByteString
value
by
running
the
following
algorithm:
-
Let x be ToString ( V ).
-
If the value of any element of x is greater than 255, then throw a
TypeError
. -
Return an IDL
ByteString
value whose length is the length of x , and where the value of each element is the value of the corresponding element of x .
The
result
of
converting
an
IDL
ByteString
value
to
an
ECMAScript
value
is
a
String
value
whose
length
is
the
length
of
the
ByteString
,
and
the
value
of
each
element
of
which
is
the
value
of
the
corresponding
element
of
the
ByteString
.
3.2.11. USVString
An
ECMAScript
value
V
is
converted
to
an
IDL
USVString
value
by
running
the
following
algorithm:
-
Let string be the result of converting V to a
DOMString
. -
Return an IDL
USVString
value that is the result of converting string to a sequence of Unicode scalar values .
An
IDL
USVString
value
is
converted
to
an
ECMAScript
value
by
running
the
following
algorithm:
-
Let scalarValues be the sequence of Unicode scalar values the
USVString
represents. -
Let string be the sequence of code units that results from encoding scalarValues in UTF-16.
-
Return the String value that represents the same sequence of code units as string .
3.2.12. object
IDL
object
values
are
represented
by
ECMAScript
Object
values.
The
result
of
converting
an
IDL
object
value
to
an
ECMAScript
value
is
the
Object
value
that
represents
a
reference
to
the
same
object
that
the
IDL
object
represents.
3.2.13. symbol
IDL
symbol
values
are
represented
by
ECMAScript
Symbol
values.
The
result
of
converting
an
IDL
symbol
value
to
an
ECMAScript
value
is
the
Symbol
value
that
represents
a
reference
to
the
same
symbol
that
the
IDL
symbol
represents.
3.2.14. Interface types
IDL interface type values are represented by ECMAScript Object values (including function objects ).
An ECMAScript value V is converted to an IDL interface type value by running the following algorithm (where I is the interface ):
-
If V implements I , then return the IDL interface type value that represents a reference to that platform object.
The result of converting an IDL interface type value to an ECMAScript value is the Object value that represents a reference to the same object that the IDL interface type value represents.
3.2.15. Callback interface types
IDL callback interface type values are represented by ECMAScript Object values (including function objects ).
An ECMAScript value V is converted to an IDL callback interface type value by running the following algorithm:
-
Return the IDL callback interface type value that represents a reference to V , with the incumbent settings object as the callback context .
The result of converting an IDL callback interface type value to an ECMAScript value is the Object value that represents a reference to the same object that the IDL callback interface type value represents.
3.2.16. Dictionary types
IDL dictionary type values are represented by ECMAScript Object values. Properties on the object (or its prototype chain) correspond to dictionary members .
An ECMAScript value esDict is converted to an IDL dictionary type value by running the following algorithm (where D is the dictionary type ):
-
If Type ( esDict ) is not Undefined, Null or Object, then throw a
TypeError
. -
Let idlDict be an empty ordered map , representing a dictionary of type D .
-
Let dictionaries be a list consisting of D and all of D ’s inherited dictionaries , in order from least to most derived.
-
For each dictionary dictionary in dictionaries , in order:
-
For each dictionary member member declared on dictionary , in lexicographical order:
-
Let key be the identifier of member .
-
Let esMemberValue be an ECMAScript value, depending on Type ( esDict ):
-
If esMemberValue is not
undefined , then:-
Let idlMemberValue be the result of converting esMemberValue to an IDL value whose type is the type member is declared to be of.
-
Set idlDict [ key ] to idlMemberValue .
-
-
Otherwise, if esMemberValue is
undefined but member has a default value , then:-
Let idlMemberValue be member ’s default value.
-
Set idlDict [ key ] to idlMemberValue .
-
-
Otherwise, if esMemberValue is
undefined and member is required , then throw aTypeError
.
-
-
-
Return idlDict .
Note: The order that dictionary members are looked up on the ECMAScript object are not necessarily the same as the object’s property enumeration order.
An IDL dictionary value V is converted to an ECMAScript Object value by running the following algorithm (where D is the dictionary ):
-
Let O be ! OrdinaryObjectCreate (
%ObjectPrototype%
). -
Let dictionaries be a list consisting of D and all of D ’s inherited dictionaries , in order from least to most derived.
-
For each dictionary dictionary in dictionaries , in order:
-
For each dictionary member member declared on dictionary , in lexicographical order:
-
Let key be the identifier of member .
-
If V [ key ] exists , then:
-
Let idlValue be V [ key ].
-
Let value be the result of converting idlValue to an ECMAScript value.
-
Perform ! CreateDataProperty ( O , key , value ).
Recall that if member has a default value , then key will always exist in V .
-
-
-
-
Return O .
3.2.17. Enumeration types
IDL enumeration types are represented by ECMAScript String values.
An ECMAScript value V is converted to an IDL enumeration type value as follows (where E is the enumeration ):
-
Let S be the result of calling ToString ( V ).
-
If S is not one of E ’s enumeration values , then throw a
TypeError
. -
Return the enumeration value of type E that is equal to S .
The result of converting an IDL enumeration type value to an ECMAScript value is the String value that represents the same sequence of code units as the enumeration value .
3.2.18. Callback function types
IDL
callback
function
types
are
represented
by
ECMAScript
function
objects
,
except
in
the
[
LegacyTreatNonObjectAsNull
]
case,
when
they
can
be
any
object.
An ECMAScript value V is converted to an IDL callback function type value by running the following algorithm:
-
If the result of calling IsCallable ( V ) is
false and the conversion to an IDL value is not being performed due to V being assigned to an attribute whose type is a nullable callback function that is annotated with [LegacyTreatNonObjectAsNull
], then throw aTypeError
. -
Return the IDL callback function type value that represents a reference to the same object that V represents, with the incumbent settings object as the callback context .
The result of converting an IDL callback function type value to an ECMAScript value is a reference to the same object that the IDL callback function type value represents.
3.2.19. Nullable types — T ?
IDL
nullable
type
values
are
represented
by
values
of
either
the
ECMAScript
type
corresponding
to
the
inner
IDL
type
,
or
the
ECMAScript
An
ECMAScript
value
V
is
converted
to
an
IDL
nullable
type
T
?
value
(where
T
is
the
inner
type
)
as
follows:
-
If Type ( V ) is not Object, and the conversion to an IDL value is being performed due to V being assigned to an attribute whose type is a nullable callback function that is annotated with [
LegacyTreatNonObjectAsNull
], then return the IDL nullable typeT ?
valuenull . -
Otherwise, if V is
null orundefined , then return the IDL nullable typeT ?
valuenull . -
Otherwise, return the result of converting V using the rules for the inner IDL type
T
.
The result of converting an IDL nullable type value to an ECMAScript value is:
-
If the IDL nullable type
T ?
value isnull , then the ECMAScript value isnull . -
Otherwise, the ECMAScript value is the result of converting the IDL nullable type value to the inner IDL type
T
.
3.2.20. Sequences — sequence< T >
IDL sequence< T > values are represented by ECMAScript Array values.
An ECMAScript value V is converted to an IDL sequence< T > value as follows:
-
Let method be ? GetMethod ( V ,
@@iterator
). -
Return the result of creating a sequence from V and method .
An IDL sequence value S of type sequence< T > is converted to an ECMAScript Array object as follows:
-
Let n be the length of S .
-
Let A be a new Array object created as if by the expression
[]
. -
Initialize i to be 0.
-
While i < n :
-
Let V be the value in S at index i .
-
Let E be the result of converting V to an ECMAScript value.
-
Let P be the result of calling ToString ( i ).
-
Call CreateDataProperty ( A , P , E ).
-
Set i to i + 1.
-
-
Return A .
3.2.20.1. Creating a sequence from an iterable
To create an IDL value of type sequence< T > given an iterable iterable and an iterator getter method , perform the following steps:
-
Let iter be ? GetIterator ( iterable ,
sync , method ). -
Initialize i to be 0.
-
Repeat
-
Let next be ? IteratorStep ( iter ).
-
If next is
false , then return an IDL sequence value of type sequence< T > of length i , where the value of the element at index j is S j . -
Let nextItem be ? IteratorValue ( next ).
-
Initialize S i to the result of converting nextItem to an IDL value of type T .
-
Set i to i + 1.
-
The following interface defines an attribute of a sequence type as well as an operation with an argument of a sequence type.
[Exposed =Window ]interface Canvas {sequence <DOMString >getSupportedImageCodecs ();void drawPolygon (sequence <double >coordinates );sequence <double >getLastDrawnPolygon (); // ... };
In
an
ECMAScript
implementation
of
this
interface,
an
Array
object
with
elements
of
type
String
is
used
to
represent
a
sequence<DOMString>
,
while
an
Array
with
elements
of
type
Number
represents
a
sequence<double>
.
The
Array
objects
are
effectively
passed
by
value;
every
time
the
getSupportedImageCodecs()
function
is
called
a
new
Array
is
returned,
and
whenever
an
Array
is
passed
to
drawPolygon
no
reference
will
be
kept
after
the
call
completes.
// Obtain an instance of Canvas. Assume that getSupportedImageCodecs() // returns a sequence with two DOMString values: "image/png" and "image/svg+xml". var canvas= getCanvas(); // An Array object of length 2. var supportedImageCodecs= canvas. getSupportedImageCodecs(); // Evaluates to "image/png". supportedImageCodecs[ 0 ]; // Each time canvas.getSupportedImageCodecs() is called, it returns a // new Array object. Thus modifying the returned Array will not // affect the value returned from a subsequent call to the function. supportedImageCodecs[ 0 ] = "image/jpeg" ; // Evaluates to "image/png". canvas. getSupportedImageCodecs()[ 0 ]; // This evaluates to false, since a new Array object is returned each call. canvas. getSupportedImageCodecs() == canvas. getSupportedImageCodecs(); // An Array of Numbers... var a= [ 0 , 0 , 100 , 0 , 50 , 62.5 ]; // ...can be passed to a platform object expecting a sequence<double>. canvas. drawPolygon( a); // Each element will be converted to a double by first calling ToNumber(). // So the following call is equivalent to the previous one, except that // "hi" will be alerted before drawPolygon() returns. a= [ false , '' , { valueOf: function () { alert( 'hi' ); return 100 ; } }, 0 , '50' , new Number( 62.5 )]; canvas. drawPolygon( a); // Modifying an Array that was passed to drawPolygon() is guaranteed not to // have an effect on the Canvas, since the Array is effectively passed by value. a[ 4 ] = 20 ; var b= canvas. getLastDrawnPolygon(); alert( b[ 4 ]); // This would alert "50".
3.2.21. Records — record< K , V >
IDL record < K , V > values are represented by ECMAScript Object values.
An
ECMAScript
value
O
is
converted
to
an
IDL
record
<
K
,
V
>
value
as
follows:
-
Let result be a new empty instance of
record < K , V >
. -
Let keys be ? O .[[OwnPropertyKeys]]().
-
For each key of keys :
-
Let desc be ? O .[[GetOwnProperty]]( key ).
-
If desc is not
undefined and desc .[[Enumerable]] istrue :-
Let typedKey be key converted to an IDL value of type K .
-
Let typedValue be value converted to an IDL value of type V .
-
Set result [ typedKey ] to typedValue .
Note: it’s possible that typedKey is already in result , if O is a proxy object.
-
-
-
Return result .
An
IDL
record
<…>
value
D
is
converted
to
an
ECMAScript
value
as
follows:
-
Let result be ! OrdinaryObjectCreate (
%ObjectPrototype%
). -
For each key → value of D :
-
Let esKey be key converted to an ECMAScript value .
-
Let esValue be value converted to an ECMAScript value .
-
Let created be ! CreateDataProperty ( result , esKey , esValue ).
-
Assert: created is
true .
-
-
Return result .
Passing
the
ECMAScript
value
{b:
3,
a:
4}
as
a
record
<DOMString,
double>
argument
would
result
in
the
IDL
value
«[
"
b
"
→
3,
"
a
"
→
4
]».
Records
only
consider
own
enumerable
properties,
so
given
an
IDL
operation
record<DOMString,
double>
identity(record<DOMString,
double>
arg)
which
returns
its
argument,
the
following
code
passes
its
assertions:
let proto= { a: 3 , b: 4 }; let obj= { __proto__: proto, d: 5 , c: 6 } Object. defineProperty( obj, "e" , { value: 7 , enumerable: false }); let result= identity( obj); console. assert( result. a=== undefined ); console. assert( result. b=== undefined ); console. assert( result. e=== undefined ); let entries= Object. entries( result); console. assert( entries[ 0 ][ 0 ] === "d" ); console. assert( entries[ 0 ][ 1 ] === 5 ); console. assert( entries[ 1 ][ 0 ] === "c" ); console. assert( entries[ 1 ][ 1 ] === 6 );
Record keys and values can be constrained, although keys can only be constrained among the three string types. The following conversions have the described results:
Value | Passed to type | Result |
---|---|---|
{"😞":
1}
|
record
<ByteString,
double>
|
TypeError
|
{"\uD83D":
1}
|
record
<USVString,
double>
|
«[
"
\uFFFD
"
→
1
]»
|
{"\uD83D":
{hello:
"world"}}
|
record
<DOMString,
double>
|
«[
"
\uD83D
"
→
0
]»
|
3.2.22. Promise types — Promise< T >
IDL promise type values are represented by ECMAScript PromiseCapability records.
An
ECMAScript
value
V
is
converted
to
an
IDL
Promise
<
T
>
value
as
follows:
-
Let promiseCapability be ? NewPromiseCapability (
%Promise%
). -
Perform ? Call ( promiseCapability .[[Resolve]],
undefined , « V »). -
Return promiseCapability .
The result of converting an IDL promise type value to an ECMAScript value is the value of the [[Promise]] field of the record that IDL promise type represents.
3.2.22.1. Creating and manipulating Promises
To
create
a
new
Promise
<
T
>
in
a
Realm
realm
,
perform
the
following
steps:
-
Let constructor be realm .[[Intrinsics]].[[
%Promise%
]]. -
Return ? NewPromiseCapability ( constructor ).
To
create
a
resolved
promise
of
type
Promise
<
T
>
,
with
x
(a
value
of
type
T
)
in
a
Realm
realm
,
perform
the
following
steps:
-
Let value be the result of converting x to an ECMAScript value.
-
Let constructor be realm .[[Intrinsics]].[[
%Promise%
]]. -
Let promiseCapability be ? NewPromiseCapability ( constructor ).
-
Perform ! Call ( promiseCapability .[[Resolve]],
undefined , « value »). -
Return promiseCapability .
To
create
a
rejected
promise
of
type
Promise
<
T
>
,
with
reason
r
(an
ECMAScript
value)
in
a
Realm
realm
,
perform
the
following
steps:
-
Let constructor be realm .[[Intrinsics]].[[
%Promise%
]]. -
Let promiseCapability be ? NewPromiseCapability ( constructor ).
-
Perform ! Call ( promiseCapability .[[Reject]],
undefined , « r »). -
Return promiseCapability .
To
resolve
a
Promise
<
T
>
p
with
x
(a
value
of
type
T
),
perform
the
following
steps:
-
If x is not given, then let it be the
void
value. -
Let value be the result of converting x to an ECMAScript value.
If
T
is
void
,
then
the
x
argument
is
optional,
allowing
a
simpler
"
resolve
p"
usage.
To
reject
a
Promise
<
T
>
p
with
reason
r
(an
ECMAScript
value),
perform
the
following
steps:
To
react
to
a
Promise
<
T
>
promise
,
given
one
or
two
sets
of
steps
to
perform,
covering
when
the
promise
is
fulfilled,
rejected,
or
both,
perform
the
following
steps:
-
Let onFulfilledSteps be the following steps given argument V :
-
Let value be the result of converting V to an IDL value of type T .
-
If there are no steps that are required to be run if the promise was fulfilled, then return
undefined . -
Let result be the result of performing any steps that were required to be run if the promise was fulfilled, given value if T is not
void
. -
Return result , converted to an ECMAScript value .
-
-
Let onFulfilled be ! CreateBuiltinFunction ( onFulfilledSteps , « »):
-
Let onRejectedSteps be the following steps given argument R :
-
Let reason be the result of converting R to an IDL value of type
any
. -
If there are no steps that are required to be run if the promise was rejected, then return
undefined . -
Let result be the result of performing any steps that were required to be run if the promise was rejected, given reason .
-
Return result , converted to an ECMAScript value .
-
-
Let onRejected be ! CreateBuiltinFunction ( onRejectedSteps , « »):
-
Let constructor be promise .[[Promise]].[[Realm]].[[Intrinsics]].[[
%Promise%
]]. -
Let newCapability be ? NewPromiseCapability ( constructor ).
Note: Not all callers will use the returned
Promise
. Implementations might wish to avoid creating newCapability in those cases. -
Return ! PerformPromiseThen ( promise .[[Promise]], onFulfilled , onRejected , newCapability ).
Note:
This
algorithm
will
behave
in
a
very
similar
way
to
the
Promise.then()
method.
In
particular,
if
the
steps
return
a
value
of
type
U
or
Promise
<
U
>
,
this
algorithm
returns
a
Promise
<
U
>
as
well.
To
perform
some
steps
upon
fulfillment
of
a
Promise
<
T
>
promise
given
some
steps
steps
taking
a
value
of
type
T
,
perform
the
following
steps:
-
React to promise :
-
If promise was fulfilled with value v , then:
-
Perform steps with v .
-
-
To
perform
some
steps
upon
rejection
of
a
Promise
<
T
>
promise
given
some
steps
steps
taking
an
ECMAScript
value,
perform
the
following
steps:
-
React to promise :
-
If promise was rejected with reason r , then:
-
Perform steps with r .
-
-
To
wait
for
all
with
a
list
of
Promise
<
T
>
values
promises
,
with
success
steps
successSteps
that
take
a
list
of
T
values
and
failure
steps
failureSteps
that
take
a
rejection
reason
any
value,
perform
the
following
steps:
-
Let fullfilledCount be 0.
-
Let rejected be false.
-
Let rejectionHandlerSteps be the following steps given arg :
-
If rejected is true, abort these steps.
-
Set rejected to true.
-
Perform failureSteps given arg .
-
-
Let rejectionHandler be ! CreateBuiltinFunction ( rejectionHandlerSteps , « »):
-
Let total be promises ’s size .
-
If total is 0, then:
-
Queue a microtask to perform successSteps given « ».
-
Return.
-
-
Let index be 0.
-
Let result be a list containing total null values.
-
For each promise of promises :
-
Let promiseIndex be index .
-
Let fulfillmentHandler be the following steps given arg :
-
Set result [ promiseIndex ] to arg .
-
Set fullfilledCount to fullfilledCount + 1.
-
If fullfilledCount equals total , then perform successSteps given result .
-
-
Let fulfillmentHandler be ! CreateBuiltinFunction ( fulfillmentHandler , « »):
-
Perform PerformPromiseThen ( promise , fulfillmentHandler , rejectionHandler ).
-
Set index to index + 1.
-
To
get
a
promise
for
waiting
for
all
with
a
list
of
Promise
<
T
>
values
promises
and
a
Realm
realm
,
perform
the
following
steps:
-
Let promise be a new promise of type
Promise < sequence < T >>
in realm . -
Let successSteps be the following steps, given results :
-
Resolve promise with results .
-
-
Let failureSteps be the following steps, given reason :
-
Reject promise with reason .
-
-
Wait for all with promises , given successSteps and failureSteps .
-
Return promise .
This
phrase
is
useful
when
you
wish
to
aggregate
the
results
of
multiple
promises,
and
then
produce
another
promise
from
them,
in
the
same
way
that
Promise.all()
functions
for
JavaScript
code.
3.2.22.2. Examples
delay
is
an
operation
that
returns
a
promise
that
will
be
fulfilled
in
a
number
of
milliseconds.
It
illustrates
how
simply
you
can
resolve
a
promise,
with
one
line
of
prose.
interface I {Promise <void >delay (unrestricted double ms ); };
The
delay(
ms
)
method
steps
are:
-
Let realm be this ’s relevant Realm .
-
If ms is NaN, let ms be +0; otherwise let ms be the maximum of ms and +0.
-
Let p be a new promise in realm .
-
Run the following steps in parallel :
-
Wait ms milliseconds.
-
Resolve p .
-
-
Return p .
The
validatedDelay
operation
is
much
like
the
delay
function
,
except
it
will
validate
its
arguments.
This
shows
how
to
use
rejected
promises
to
signal
immediate
failure
before
even
starting
any
asynchronous
operations.
interface I {Promise <void >validatedDelay (unrestricted double ms ); };
The
validatedDelay(
ms
)
method
steps
are:
-
Let realm be this ’s relevant Realm .
-
If ms is NaN, return a promise rejected with a
TypeError
in realm . -
If ms < 0, return a promise rejected with a
RangeError
in realm . -
Let p be a new promise in realm .
-
Run the following steps in parallel :
-
Wait ms milliseconds.
-
Resolve p .
-
-
Return p .
addDelay
is
an
operation
that
adds
an
extra
number
of
milliseconds
of
delay
between
promise
settling
and
the
returned
promise
settling.
interface I {Promise <any >addDelay (Promise <any >promise ,unrestricted double ms ); };
The
addDelay(
ms
,
promise
)
method
steps
are:
-
Let realm be this ’s relevant Realm .
-
Let taskSource be some appropriate task source .
-
If ms is NaN, let ms be +0; otherwise let ms be the maximum of ms and +0.
-
Let p be a new promise in realm .
-
React to promise :
-
If promise was fulfilled with value v , then:
-
Run the following steps in parallel :
-
Wait ms milliseconds.
-
Queue a task to run the following steps on taskSource :
-
Resolve p with v .
-
-
-
-
If promise was rejected with reason r , then:
-
Run the following steps in parallel :
-
Wait ms milliseconds.
-
Queue a task to run the following steps on taskSource :
-
Reject p with r .
-
-
-
-
-
Return p .
environment.ready
is
an
attribute
that
signals
when
some
part
of
some
environment,
e.g.
a
DOM
document,
becomes
"ready".
It
illustrates
how
to
encode
environmental
asynchronicity.
interface Environment {readonly attribute Promise <void >ready ; };
Every
Environment
object
must
have
a
ready
promise
,
which
is
a
Promise
<
void
>
.
The
ready
attribute
getter
steps
are:
-
Return this ’s ready promise .
To
create
an
Environment
object
in
a
Realm
realm
,
perform
the
following
steps:
-
Let environment be new
Environment
object in realm . -
Set environment ’s ready promise to a new promise in realm .
-
Run the following steps in parallel :
-
Do some asynchronous work.
-
If environment becomes ready successfully, resolve environment ’s ready promise .
-
If environment fails to become ready, reject environment ’s ready promise with a "
NetworkError
"DOMException
.
-
-
Return environment .
addBookmark
is
an
operation
that
requests
that
the
user
add
the
current
web
page
as
a
bookmark.
It’s
drawn
from
some
iterative
design
work
and
illustrates
a
more
real-world
scenario
of
appealing
to
environmental
asynchrony,
as
well
as
immediate
rejections.
interface I {Promise <void >addBookmark (); };
The
addBookmark()
method
steps
are:
-
If this method was not invoked as a result of explicit user action, return a promise rejected with a "
SecurityError
"DOMException
. -
If the document’s mode of operation is standalone, return a promise rejected with a "
NotSupportedError
"DOMException
. -
Let promise be a new promise .
-
Let info be the result of getting a web application’s metadata.
-
Run the following steps in parallel :
-
Using info , and in a manner that is user-agent specific, allow the end user to make a choice as to whether they want to add the bookmark.
-
If the end-user aborts the request to add the bookmark (e.g., they hit escape, or press a "cancel" button), reject promise with an "
AbortError
"DOMException
. -
Otherwise, resolve promise .
-
-
-
Return promise .
Several
places
in
[SERVICE-WORKERS]
use
get
a
promise
to
wait
for
all
.
batchRequest
illustrates
a
simplified
version
of
one
of
their
uses.
It
takes
as
input
a
sequence
of
URLs,
and
returns
a
promise
for
a
sequence
of
Response
objects
created
by
fetching
the
corresponding
URL.
If
any
of
the
fetches
fail,
it
will
return
a
promise
rejected
with
that
failure.
interface I {Promise <sequence <Response >>batchRequest (sequence <USVString >urls ); };
The
batchRequest(
urls
)
method
steps
are:
-
Let responsePromises be « ».
-
For each url of urls :
-
Let p be the result of getting a promise to wait for all with responsePromises .
-
Return p .
3.2.23. Union types
IDL union type values are represented by ECMAScript values that correspond to the union’s member types .
To convert an ECMAScript value V to an IDL union type value is done as follows:
-
If the union type includes a nullable type and V is
null orundefined , then return the IDL valuenull . -
Let types be the flattened member types of the union type .
-
If V is
null orundefined , then:-
If types includes a dictionary type , then return the result of converting V to that dictionary type.
-
-
If V is a platform object , then:
-
If types includes an interface type that V implements , then return the IDL value that is a reference to the object V .
-
If types includes
object
, then return the IDL value that is a reference to the object V .
-
-
If Type ( V ) is Object and V has an [[ArrayBufferData]] internal slot , then:
-
If types includes
ArrayBuffer
, then return the result of converting V toArrayBuffer
. -
If types includes
object
, then return the IDL value that is a reference to the object V .
-
-
If Type ( V ) is Object and V has a [[DataView]] internal slot , then:
-
If types includes
DataView
, then return the result of converting V toDataView
. -
If types includes
object
, then return the IDL value that is a reference to the object V .
-
-
If Type ( V ) is Object and V has a [[TypedArrayName]] internal slot , then:
-
If types includes a typed array type whose name is the value of V ’s [[TypedArrayName]] internal slot , then return the result of converting V to that type.
-
If types includes
object
, then return the IDL value that is a reference to the object V .
-
-
If IsCallable ( V ) is true, then:
-
If types includes a callback function type, then return the result of converting V to that callback function type.
-
If types includes
object
, then return the IDL value that is a reference to the object V .
-
-
If Type ( V ) is Object, then:
-
If types includes a sequence type , then
-
Let method be ? GetMethod ( V ,
@@iterator
). -
If method is not
undefined , return the result of creating a sequence of that type from V and method .
-
-
If types includes a frozen array type , then
-
Let method be ? GetMethod ( V ,
@@iterator
). -
If method is not
undefined , return the result of creating a frozen array of that type from V and method .
-
-
If types includes a dictionary type , then return the result of converting V to that dictionary type.
-
If types includes a record type , then return the result of converting V to that record type.
-
If types includes a callback interface type, then return the result of converting V to that callback interface type .
-
If types includes
object
, then return the IDL value that is a reference to the object V .
-
-
If Type ( V ) is Boolean, then:
-
If types includes a
boolean
, then return the result of converting V toboolean
.
-
-
If Type ( V ) is Number, then:
-
If types includes a numeric type , then return the result of converting V to that numeric type .
-
-
If types includes a string type , then return the result of converting V to that type.
-
If types includes a numeric type , then return the result of converting V to that numeric type .
-
If types includes a
boolean
, then return the result of converting V toboolean
.
An
IDL
union
type
value
is
converted
to
an
ECMAScript
value
as
follows.
If
the
value
is
an
object
reference
to
a
special
object
that
represents
an
ECMAScript
3.2.24. Buffer source types
Values
of
the
IDL
buffer
source
types
are
represented
by
objects
of
the
corresponding
ECMAScript
class,
with
the
additional
restriction
that
unless
the
type
is
associated
with
the
[
AllowShared
]
extended
attribute,
they
can
only
be
backed
by
ECMAScript
ArrayBuffer
objects,
and
not
SharedArrayBuffer
objects.
An
ECMAScript
value
V
is
converted
to
an
IDL
ArrayBuffer
value
by
running
the
following
algorithm:
-
If Type ( V ) is not Object, or V does not have an [[ArrayBufferData]] internal slot , then throw a
TypeError
. -
If the conversion is not to an IDL type associated with the [
AllowShared
] extended attribute , and IsSharedArrayBuffer ( V ) is true, then throw aTypeError
. -
Return the IDL
ArrayBuffer
value that is a reference to the same object as V .
An
ECMAScript
value
V
is
converted
to
an
IDL
DataView
value
by
running
the
following
algorithm:
-
If Type ( V ) is not Object, or V does not have a [[DataView]] internal slot , then throw a
TypeError
. -
If the conversion is not to an IDL type associated with the [
AllowShared
] extended attribute , and IsSharedArrayBuffer ( V .[[ViewedArrayBuffer]]) is true, then throw aTypeError
. -
Return the IDL
DataView
value that is a reference to the same object as V .
An
ECMAScript
value
V
is
converted
to
an
IDL
Int8Array
,
Int16Array
,
Int32Array
,
Uint8Array
,
Uint16Array
,
Uint32Array
,
Uint8ClampedArray
,
Float32Array
or
Float64Array
value
by
running
the
following
algorithm:
-
Let T be the IDL type V is being converted to.
-
Let typedArrayName be the name of T ’s inner type if T is an annotated type , or the name of T otherwise.
-
If Type ( V ) is not Object, or V does not have a [[TypedArrayName]] internal slot with a value equal to typedArrayName , then throw a
TypeError
. -
If the conversion is not to an IDL type associated with the [
AllowShared
] extended attribute , and IsSharedArrayBuffer ( V .[[ViewedArrayBuffer]]) is true, then throw aTypeError
. -
Return the IDL value of type T that is a reference to the same object as V .
The result of converting an IDL value of any buffer source type to an ECMAScript value is the Object value that represents a reference to the same object that the IDL value represents.
When
getting
a
reference
to
or
getting
a
copy
of
the
bytes
held
by
a
buffer
source
that
is
an
ECMAScript
ArrayBuffer
,
DataView
or
typed
array
object,
these
steps
must
be
followed:
-
Let O be the ECMAScript object that is the buffer source.
-
Initialize arrayBuffer to O .
-
Initialize offset to 0.
-
Initialize length to 0.
-
If O has a [[ViewedArrayBuffer]] internal slot , then:
-
Set arrayBuffer to the value of O ’s [[ViewedArrayBuffer]] internal slot .
-
Set offset to the value of O ’s [[ByteOffset]] internal slot .
-
Set length to the value of O ’s [[ByteLength]] internal slot .
-
-
Otherwise, set length to the value of O ’s [[ArrayBufferByteLength]] internal slot .
-
If IsDetachedBuffer ( arrayBuffer ) is
true , then return the empty byte sequence. -
Let data be the value of O ’s [[ArrayBufferData]] internal slot .
-
Return a reference to or copy of (as required) the length bytes in data starting at byte offset offset .
To
detach
an
ArrayBuffer
,
these
steps
must
be
followed:
-
Let O be the ECMAScript object that is the
ArrayBuffer
. -
Perform ! DetachArrayBuffer ( O ).
3.2.25. Frozen arrays — FrozenArray< T >
Values of frozen array types are represented by frozen ECMAScript Array object references.
An ECMAScript value V is converted to an IDL FrozenArray< T > value by running the following algorithm:
-
Let values be the result of converting V to IDL type sequence< T > .
-
Return the result of creating a frozen array from values .
To create a frozen array from a sequence of values of type T , follow these steps:
-
Let array be the result of converting the sequence of values of type T to an ECMAScript value.
-
Perform SetIntegrityLevel ( array , "
frozen
"). -
Return array .
The result of converting an IDL FrozenArray< T > value to an ECMAScript value is the Object value that represents a reference to the same object that the IDL FrozenArray< T > represents.
3.2.25.1. Creating a frozen array from an iterable
To create an IDL value of type FrozenArray< T > given an iterable iterable and an iterator getter method , perform the following steps:
-
Let values be the result of creating a sequence of type sequence< T > from iterable and method .
-
Return the result of creating a frozen array from values .
3.2.26. Observable arrays — ObservableArray< T >
Values of observable array types are represented by observable array exotic objects .
Instead of the usual conversion algorithms, observable array types have special handling as part of the attribute getter and attribute setter algorithms.
In the ECMAScript binding, ECMAScript objects that represent platform objects have a backing observable array exotic object for each regular attribute of an observable array type . These are created and managed as part of the define the attributes algorithm.
-
Assert: obj implements an interface with the regular attribute attribute .
-
Let oa be obj ’s backing observable array exotic object for attribute .
-
Return oa .[[ProxyHandler]].[[BackingList]].
3.3. Extended attributes
This section defines a number of extended attributes whose presence affects the ECMAScript binding.
3.3.1. [AllowShared]
If
the
[
AllowShared
]
extended
attribute
appears
on
one
of
the
buffer
source
types
,
it
creates
a
new
IDL
type
that
allows
the
buffer
source
type
to
be
backed
by
an
ECMAScript
SharedArrayBuffer
,
instead
of
only
by
a
non-shared
ArrayBuffer
.
The
[
AllowShared
]
extended
attribute
must
take
no
arguments
.
A
type
that
is
not
a
buffer
source
type
must
not
be
associated
with
the
[
AllowShared
]
extended
attribute.
See
the
rules
for
converting
ECMAScript
values
to
IDL
buffer
source
types
in
§ 3.2.24
Buffer
source
types
for
the
specific
requirements
that
the
use
of
[
AllowShared
]
entails.
AllowShared
]
extended
attribute,
while
the
other
does
not:
[Exposed =Window ]interface RenderingContext {void readPixels (long width ,long height ,BufferSource pixels );void readPixelsShared (long width ,long height , [AllowShared ]BufferSource pixels ); };
With
this
definition,
a
call
to
readPixels
with
an
SharedArrayBuffer
instance,
or
any
typed
array
or
DataView
backed
by
one,
will
throw
a
TypeError
exception.
In
contrast,
a
call
to
readPixelsShared
will
allow
such
objects
as
input.
3.3.2. [Clamp]
If
the
[
Clamp
]
extended
attribute
appears
on
one
of
the
integer
types
,
it
creates
a
new
IDL
type
such
that
that
when
an
ECMAScript
Number
is
converted
to
the
IDL
type,
out-of-range
values
will
be
clamped
to
the
range
of
valid
values,
rather
than
using
the
operators
that
use
a
modulo
operation
(
ToInt32
,
ToUint32
,
etc.).
The
[
Clamp
]
extended
attribute
must
take
no
arguments
.
A
type
annotated
with
the
[
Clamp
]
extended
attribute
must
not
appear
in
a
read
only
attribute.
A
type
must
not
be
associated
with
both
the
[
Clamp
]
and
[
EnforceRange
]
extended
attributes.
A
type
that
is
not
an
integer
type
must
not
be
associated
with
the
[
Clamp
]
extended
attribute.
See
the
rules
for
converting
ECMAScript
values
to
the
various
IDL
integer
types
in
§ 3.2.4
Integer
types
for
the
specific
requirements
that
the
use
of
[
Clamp
]
entails.
In
the
following
IDL
fragment
,
two
operations
are
declared
that
take
three
octet
arguments;
one
uses
the
[
Clamp
]
extended
attribute
on
all
three
arguments,
while
the
other
does
not:
[Exposed =Window ]interface GraphicsContext {void setColor (octet red ,octet green ,octet blue );void setColorClamped ([Clamp ]octet red , [Clamp ]octet green , [Clamp ]octet blue ); };
A
call
to
setColorClamped
with
Number
values
that
are
out
of
range
for
an
octet
are
clamped
to
the
range
[0,
255].
// Get an instance of GraphicsContext. var context= getGraphicsContext(); // Calling the non-[Clamp] version uses ToUint8 to coerce the Numbers to octets. // This is equivalent to calling setColor(255, 255, 1). context. setColor( - 1 , 255 , 257 ); // Call setColorClamped with some out of range values. // This is equivalent to calling setColorClamped(0, 255, 255). context. setColorClamped( - 1 , 255 , 257 );
3.3.3. [Default]
If
the
[
Default
]
extended
attribute
appears
on
a
regular
operation
,
then
it
indicates
that
steps
described
in
the
corresponding
default
operation
must
be
carried
out
when
the
operation
is
invoked.
The
[
Default
]
extended
attribute
must
take
no
arguments
.
The
[
Default
]
extended
attribute
must
not
be
used
on
anything
other
than
a
regular
operation
for
which
a
corresponding
default
operation
has
been
defined.
As
an
example,
the
[
Default
]
extended
attribute
is
suitable
for
use
on
toJSON
regular
operations
:
[Exposed =Window ]interface Animal {attribute DOMString name ;attribute unsigned short age ; [Default ]object toJSON (); }; [Exposed =Window ]interface Human :Animal {attribute Dog ?pet ; [Default ]object toJSON (); }; [Exposed =Window ]interface Dog :Animal {attribute DOMString ?breed ; };
In
the
ECMAScript
language
binding,
there
would
exist
a
toJSON()
method
on
Animal
,
Human
,
and
(via
inheritance)
Dog
objects:
// Get an instance of Human. var alice= getHuman(); // Evaluates to an object like this (notice how "pet" still holds // an instance of Dog at this point): // // { // name: "Alice", // age: 59, // pet: Dog // } alice. toJSON(); // Evaluates to an object like this (notice how "breed" is absent, // as the Dog interface doesn’t declare a default toJSON operation): // // { // name: "Tramp", // age: 6 // } alice. pet. toJSON(); // Evaluates to a string like this: // '{"name":"Alice","age":59,"pet":{"name":"Tramp","age":6}}' JSON. stringify( alice);
3.3.4. [EnforceRange]
If
the
[
EnforceRange
]
extended
attribute
appears
on
one
of
the
integer
types
,
it
creates
a
new
IDL
type
such
that
that
when
an
ECMAScript
Number
is
converted
to
the
IDL
type,
out-of-range
values
will
cause
an
exception
to
be
thrown,
rather
than
being
converted
to
a
valid
value
using
using
the
operators
that
use
a
modulo
operation
(
ToInt32
,
ToUint32
,
etc.).
The
Number
will
be
rounded
toward
zero
before
being
checked
against
its
range.
The
[
EnforceRange
]
extended
attribute
must
take
no
arguments
.
A
type
annotated
with
the
[
EnforceRange
]
extended
attribute
must
not
appear
in
a
read
only
attribute.
A
type
must
not
be
associated
with
both
the
[
Clamp
]
and
[
EnforceRange
]
extended
attributes.
A
type
that
is
not
an
integer
type
must
not
be
associated
with
the
[
EnforceRange
]
extended
attribute.
See
the
rules
for
converting
ECMAScript
values
to
the
various
IDL
integer
types
in
§ 3.2
ECMAScript
type
mapping
for
the
specific
requirements
that
the
use
of
[
EnforceRange
]
entails.
In
the
following
IDL
fragment
,
two
operations
are
declared
that
take
three
octet
arguments;
one
uses
the
[
EnforceRange
]
extended
attribute
on
all
three
arguments,
while
the
other
does
not:
[Exposed =Window ]interface GraphicsContext {void setColor (octet red ,octet green ,octet blue );void setColorEnforcedRange ([EnforceRange ]octet red , [EnforceRange ]octet green , [EnforceRange ]octet blue ); };
In
an
ECMAScript
implementation
of
the
IDL,
a
call
to
setColorEnforcedRange
with
Number
values
that
are
out
of
range
for
an
octet
will
result
in
an
exception
being
thrown.
// Get an instance of GraphicsContext. var context= getGraphicsContext(); // Calling the non-[EnforceRange] version uses ToUint8 to coerce the Numbers to octets. // This is equivalent to calling setColor(255, 255, 1). context. setColor( - 1 , 255 , 257 ); // When setColorEnforcedRange is called, Numbers are rounded towards zero. // This is equivalent to calling setColor(0, 255, 255). context. setColorEnforcedRange( - 0.9 , 255 , 255.2 ); // The following will cause a TypeError to be thrown, since even after // rounding the first and third argument values are out of range. context. setColorEnforcedRange( - 1 , 255 , 256 );
3.3.5. [Exposed]
When
the
[
Exposed
]
extended
attribute
appears
on
an
interface
,
partial
interface
,
interface
mixin
,
partial
interface
mixin
,
callback
interface
,
namespace
,
partial
namespace
,
or
an
individual
interface
member
,
interface
mixin
member
,
or
namespace
member
,
it
indicates
that
the
construct
is
exposed
on
that
particular
set
of
global
interfaces.
The
[
Exposed
]
extended
attribute
must
either
take
an
identifier
or
take
an
identifier
list
.
Each
of
the
identifiers
mentioned
must
be
a
global
name
and
be
unique.
This
list
of
identifiers
is
known
as
the
construct’s
own
exposure
set
.
To get the exposure set of a construct C , run the following steps:
-
Assert: C is an interface , callback interface , namespace , interface member , interface mixin member , or namespace member .
-
Let H be C ’s host interface if C is an interface mixin member , or null otherwise.
-
If C is an interface member , interface mixin member , or namespace member , then:
-
If the [
Exposed
] extended attribute is specified on C , then:-
If H is set, return the intersection of C ’s own exposure set and H ’s exposure set .
-
Otherwise, return C ’s own exposure set .
-
-
Otherwise, set C to be the interface , partial interface , interface mixin , partial interface mixin , namespace , or partial namespace C is declared on.
-
-
If C is a partial interface , partial interface mixin , or partial namespace , then:
-
If the [
Exposed
] extended attribute is specified on C , then:-
If H is set, return the intersection of C ’s own exposure set and H ’s exposure set .
-
Otherwise, return C ’s own exposure set .
-
-
Otherwise, set C to be the original interface , interface mixin , or namespace definition of C .
-
-
If C is an interface mixin , then:
-
If the [
Exposed
] extended attribute is specified on C , then return the intersection of C ’s own exposure set and H ’s exposure set . -
Otherwise, set C to H .
-
-
Assert: C is an interface , callback interface or namespace .
-
Assert: The [
Exposed
] extended attribute is specified on C . -
Return C ’s own exposure set .
If
[
Exposed
]
appears
on
an
overloaded
operation
,
then
it
must
appear
identically
on
all
overloads.
The
[
Exposed
]
extended
attribute
must
not
be
specified
both
on
an
interface
member
,
interface
mixin
member
,
or
namespace
member
,
and
on
the
partial
interface
,
partial
interface
mixin
,
or
partial
namespace
definition
the
member
is
declared
on.
Note:
This
is
because
adding
an
[
Exposed
]
extended
attribute
on
a
partial
interface
,
partial
interface
mixin
,
or
partial
namespace
is
shorthand
for
annotating
each
of
its
members
.
If
[
Exposed
]
appears
on
a
partial
interface
or
partial
namespace
,
then
the
partial’s
own
exposure
set
must
be
a
subset
of
the
exposure
set
of
the
partial’s
original
interface
or
namespace
.
If
[
Exposed
]
appears
on
an
interface
or
namespace
member
,
then
the
member
's
exposure
set
must
be
a
subset
of
the
exposure
set
of
the
interface
or
namespace
it
is
a
member
of.
If
[
Exposed
]
appears
both
on
a
partial
interface
mixin
and
its
original
interface
mixin
,
then
the
partial
interface
mixin
's
own
exposure
set
must
be
a
subset
of
the
interface
mixin
's
own
exposure
set
.
If
[
Exposed
]
appears
both
on
an
interface
mixin
member
and
the
interface
mixin
it
is
a
member
of,
then
the
interface
mixin
members
's
own
exposure
set
must
be
a
subset
of
the
interface
mixin
's
own
exposure
set
.
If an interface X inherits from another interface Y then the exposure set of X must be a subset of the exposure set of Y .
Note:
As
an
interface
mixin
can
be
included
by
different
interfaces
,
the
exposure
set
of
its
members
is
a
function
of
the
interface
that
includes
them.
If
the
interface
mixin
member
,
partial
interface
mixin
,
or
interface
mixin
is
annotated
with
an
[
Exposed
]
extended
attribute
,
then
the
interface
mixin
member
's
exposure
set
is
the
intersection
of
the
relevant
construct’s
own
exposure
set
with
the
the
host
interface
's
exposure
set
.
Otherwise,
it
is
the
host
interface
's
exposure
set
.
-
If realm .[[GlobalObject]] does not implement an interface that is in construct ’s exposure set , then return false.
-
If construct is available in both secure and non-secure contexts , then return true.
-
If the relevant settings object of realm .[[GlobalObject]] is a secure context , then return true.
-
Otherwise, return false.
Note: Since it is not possible for the relevant settings object for an ECMAScript global object to change whether it is a secure context or not over time, an implementation’s decision to create properties for an interface or interface member can be made once, at the time the initial objects are created.
See
§ 3.7
Interfaces
,
§ 3.7.5
Constants
,
§ 3.7.6
Attributes
,
§ 3.7.7
Operations
,
and
§ 3.7.8
Maplike
and
setlike
iterator
behavior
for
the
specific
requirements
that
the
use
of
[
Exposed
]
entails.
[
Exposed
]
is
intended
to
be
used
to
control
whether
interfaces
,
callback
interfaces
,
namespaces
,
or
individual
interface
,
mixin
or
namespace
members
are
available
for
use
in
workers,
Worklet
,
Window
,
or
any
combination
of
the
above.
The following IDL fragment shows how that might be achieved:
[Exposed =Window ,Global =Window ]interface Window { // ... }; // By using the same identifier Worker for both SharedWorkerGlobalScope // and DedicatedWorkerGlobalScope, both can be addressed in an [Exposed] // extended attribute at once. [Exposed =Worker ,Global =Worker ]interface SharedWorkerGlobalScope :WorkerGlobalScope { // ... }; [Exposed =Worker ,Global =Worker ]interface DedicatedWorkerGlobalScope :WorkerGlobalScope { // ... }; // Dimensions is available for use in workers and on the main thread. [Exposed =(Window ,Worker )]interface Dimensions {constructor (double width ,double height );readonly attribute double width ;readonly attribute double height ; }; // WorkerNavigator is only available in workers. Evaluating WorkerNavigator // in the global scope of a worker would give you its interface object, while // doing so on the main thread will give you a ReferenceError. [Exposed =Worker ]interface WorkerNavigator { // ... }; // Node is only available on the main thread. Evaluating Node // in the global scope of a worker would give you a ReferenceError. [Exposed =Window ]interface Node { // ... }; // MathUtils is available for use in workers and on the main thread. [Exposed =(Window ,Worker )]namespace MathUtils {double someComplicatedFunction (double x ,double y ); }; // WorkerUtils is only available in workers. Evaluating WorkerUtils // in the global scope of a worker would give you its namespace object, while // doing so on the main thread will give you a ReferenceError. [Exposed =Worker ]namespace WorkerUtils {void setPriority (double x ); }; // NodeUtils is only available in the main thread. Evaluating NodeUtils // in the global scope of a worker would give you a ReferenceError. [Exposed =Window ]namespace NodeUtils {DOMString getAllText (Node node ); };
3.3.6. [Global]
If
the
[
Global
]
extended
attribute
appears
on
an
interface
,
it
indicates
that
objects
implementing
this
interface
can
be
used
as
the
global
object
in
a
Realm
,
and
that
the
structure
of
the
prototype
chain
and
how
properties
corresponding
to
interface
members
will
be
reflected
on
the
prototype
objects
will
be
different
from
other
interfaces.
Specifically:
-
Any named properties will be exposed on an object in the prototype chain – the named properties object – rather than on the object itself.
-
Interface members from the interface will correspond to properties on the object itself rather than on interface prototype objects .
Placing named properties on an object in the prototype chain is done so that variable declarations and bareword assignments will shadow the named property with a property on the global object itself.
Placing properties corresponding to interface members on the object itself will mean that common feature detection methods like the following will work:
var indexedDB= window. indexedDB|| window. webkitIndexedDB|| window. mozIndexedDB|| window. msIndexedDB; var requestAnimationFrame= window. requestAnimationFrame|| window. mozRequestAnimationFrame|| ...;
Because
of
the
way
variable
declarations
are
handled
in
ECMAScript,
the
code
above
would
result
in
the
window.indexedDB
and
window.requestAnimationFrame
evaluating
to
If
the
[
Global
]
extended
attributes
is
used
on
an
interface
,
then:
-
The interface must not define a named property setter .
-
The interface must not define indexed property getters or setters .
-
The interface must not define a constructor operation .
-
The interface must not also be declared with the [
LegacyOverrideBuiltIns
] extended attribute. -
The interface must not inherit from another interface with the [
LegacyOverrideBuiltIns
] extended attribute. -
Any other interface must not inherit from it.
If
[
Global
]
is
specified
on
a
partial
interface
definition,
then
that
partial
interface
definition
must
be
the
part
of
the
interface
definition
that
defines
the
named
property
getter
.
The
[
Global
]
extended
attribute
must
not
be
used
on
an
interface
that
can
have
more
than
one
object
implementing
it
in
the
same
Realm
.
Note: This is because the named properties object , which exposes the named properties, is in the prototype chain, and it would not make sense for more than one object’s named properties to be exposed on an object that all of those objects inherit from.
If
an
interface
is
declared
with
the
[
Global
]
extended
attribute
,
then
there
must
not
be
more
than
one
member
across
the
interface
with
the
same
identifier
.
There
also
must
not
be
more
than
one
stringifier
or
more
than
one
iterable
declaration
,
asynchronously
iterable
declaration
,
maplike
declaration
or
setlike
declaration
across
those
interfaces.
Note: This is because all of the members of the interface get flattened down on to the object that implements the interface.
The
[
Global
]
extended
attribute
can
also
be
used
to
give
a
name
to
one
or
more
global
interfaces,
which
can
then
be
referenced
by
the
[
Exposed
]
extended
attribute.
The
[
Global
]
extended
attribute
must
either
take
an
identifier
or
take
an
identifier
list
.
The
identifier
argument
or
identifier
list
argument
the
[
Global
]
extended
attribute
is
declared
with
define
the
interface’s
global
names
.
Note:
The
identifier
argument
list
exists
so
that
more
than
one
global
interface
can
be
addressed
with
a
single
name
in
an
[
Exposed
]
extended
attribute
.
See
§ 3.7.4
Named
properties
object
for
the
specific
requirements
that
the
use
of
[
Global
]
entails
for
named
properties
,
and
§ 3.7.5
Constants
,
§ 3.7.6
Attributes
and
§ 3.7.7
Operations
for
the
requirements
relating
to
the
location
of
properties
corresponding
to
interface
members
.
The
Window
interface
exposes
frames
as
properties
on
the
Window
object.
Since
the
Window
object
also
serves
as
the
ECMAScript
global
object,
variable
declarations
or
assignments
to
the
named
properties
will
result
in
them
being
replaced
by
the
new
value.
Variable
declarations
for
attributes
will
not
create
a
property
that
replaces
the
existing
one.
[Exposed =Window ,Global ]interface Window {getter any (DOMString name );attribute DOMString name ; // ... };
The
following
HTML
document
illustrates
how
the
named
properties
on
the
Window
object
can
be
shadowed,
and
how
the
property
for
an
attribute
will
not
be
replaced
when
declaring
a
variable
of
the
same
name:
<!DOCTYPE html> < title > Variable declarations and assignments on Window</ title > < iframe name = abc ></ iframe > <!-- Shadowing named properties --> < script > window. abc; // Evaluates to the iframe’s Window object. abc= 1 ; // Shadows the named property. window. abc; // Evaluates to 1. </ script > <!-- Preserving properties for IDL attributes --> < script > Window. prototype. def= 2 ; // Places a property on the prototype. window. hasOwnProperty( "length" ); // Evaluates to true. length; // Evaluates to 1. def; // Evaluates to 2. </ script > < script > var length; // Variable declaration leaves existing property. length; // Evaluates to 1. var def; // Variable declaration creates shadowing property. def; // Evaluates to undefined. </ script >
3.3.7. [NewObject]
If
the
[
NewObject
]
extended
attribute
appears
on
a
regular
or
static
operation
,
then
it
indicates
that
when
calling
the
operation,
a
reference
to
a
newly
created
object
must
always
be
returned.
The
[
NewObject
]
extended
attribute
must
take
no
arguments
.
The
[
NewObject
]
extended
attribute
must
not
be
used
on
anything
other
than
a
regular
or
static
operation
whose
return
type
is
an
interface
type
or
a
promise
type
.
As
an
example,
this
extended
attribute
is
suitable
for
use
on
the
createElement()
operation
on
the
Document
interface,
since
a
new
object
should
always
be
returned
when
it
is
called.
[DOM]
[Exposed =Window ]interface Document :Node { [NewObject ]Element createElement (DOMString localName ); // ... };
3.3.8. [PutForwards]
If
the
[
PutForwards
]
extended
attribute
appears
on
a
read
only
regular
attribute
declaration
whose
type
is
an
interface
type
,
it
indicates
that
assigning
to
the
attribute
will
have
specific
behavior.
Namely,
the
assignment
is
“forwarded”
to
the
attribute
(specified
by
the
extended
attribute
argument)
on
the
object
that
is
currently
referenced
by
the
attribute
being
assigned
to.
The
[
PutForwards
]
extended
attribute
must
take
an
identifier
.
Assuming
that:
-
A is the attribute on which the [
PutForwards
] extended attribute appears, -
I is the interface on which A is declared,
-
J is the interface type that A is declared to be of, and
-
N is the identifier argument of the extended attribute,
then there must be another attribute B declared on J whose identifier is N . Assignment of a value to the attribute A on an object implementing I will result in that value being assigned to attribute B of the object that A references, instead.
Note
that
[
PutForwards
]-annotated
attributes
can
be
chained.
That
is,
an
attribute
with
the
[
PutForwards
]
extended
attribute
can
refer
to
an
attribute
that
itself
has
that
extended
attribute.
There
must
not
exist
a
cycle
in
a
chain
of
forwarded
assignments.
A
cycle
exists
if,
when
following
the
chain
of
forwarded
assignments,
a
particular
attribute
on
an
interface
is
encountered
more
than
once.
An
attribute
with
the
[
PutForwards
]
extended
attribute
must
not
also
be
declared
with
the
[
LegacyLenientSetter
]
or
[
Replaceable
]
extended
attributes.
The
[
PutForwards
]
extended
attribute
must
not
be
used
on
an
attribute
that
is
not
read
only
.
The
[
PutForwards
]
extended
attribute
must
not
be
used
on
a
static
attribute
.
The
[
PutForwards
]
extended
attribute
must
not
be
used
on
an
attribute
declared
on
a
namespace
.
See
the
Attributes
section
for
how
[
PutForwards
]
is
to
be
implemented.
The
following
IDL
fragment
defines
interfaces
for
names
and
people.
The
[
PutForwards
]
extended
attribute
is
used
on
the
name
attribute
of
the
Person
interface
to
indicate
that
assignments
to
that
attribute
result
in
assignments
to
the
full
attribute
of
the
Person
object:
[Exposed =Window ]interface Name {attribute DOMString full ;attribute DOMString family ;attribute DOMString given ; }; [Exposed =Window ]interface Person { [PutForwards =full ]readonly attribute Name name ;attribute unsigned short age ; };
In
the
ECMAScript
binding,
this
would
allow
assignments
to
the
name
property:
var p= getPerson(); // Obtain an instance of Person. p. name= 'John Citizen' ; // This statement... p. name. full= 'John Citizen' ; // ...has the same behavior as this one.
3.3.9. [Replaceable]
If
the
[
Replaceable
]
extended
attribute
appears
on
a
read
only
regular
attribute
,
it
indicates
that
setting
the
corresponding
property
on
the
platform
object
will
result
in
an
own
property
with
the
same
name
being
created
on
the
object
which
has
the
value
being
assigned.
This
property
will
shadow
the
accessor
property
corresponding
to
the
attribute,
which
exists
on
the
interface
prototype
object
.
The
[
Replaceable
]
extended
attribute
must
take
no
arguments
.
An
attribute
with
the
[
Replaceable
]
extended
attribute
must
not
also
be
declared
with
the
[
LegacyLenientSetter
]
or
[
PutForwards
]
extended
attributes.
The
[
Replaceable
]
extended
attribute
must
not
be
used
on
an
attribute
that
is
not
read
only
.
The
[
Replaceable
]
extended
attribute
must
not
be
used
on
a
static
attribute
.
The
[
Replaceable
]
extended
attribute
must
not
be
used
on
an
attribute
declared
on
a
namespace
.
See
§ 3.7.6
Attributes
for
the
specific
requirements
that
the
use
of
[
Replaceable
]
entails.
The following IDL fragment defines an interface with an operation that increments a counter, and an attribute that exposes the counter’s value, which is initially 0:
[Exposed =Window ]interface Counter { [Replaceable ]readonly attribute unsigned long value ;void increment (); };
Assigning
to
the
value
property
on
a
platform
object
implementing
Counter
will
shadow
the
property
that
corresponds
to
the
attribute
:
var counter= getCounter(); // Obtain an instance of Counter. counter. value; // Evaluates to 0. counter. hasOwnProperty( "value" ); // Evaluates to false. Object. getPrototypeOf( counter). hasOwnProperty( "value" ); // Evaluates to true. counter. increment(); counter. increment(); counter. value; // Evaluates to 2. counter. value= 'a' ; // Shadows the property with one that is unrelated // to Counter::value. counter. hasOwnProperty( "value" ); // Evaluates to true. counter. increment(); counter. value; // Evaluates to 'a'. delete counter. value; // Reveals the original property. counter. value; // Evaluates to 3.
3.3.10. [SameObject]
If
the
[
SameObject
]
extended
attribute
appears
on
a
read
only
attribute
,
then
it
indicates
that
when
getting
the
value
of
the
attribute
on
a
given
object,
the
same
value
must
always
be
returned.
The
[
SameObject
]
extended
attribute
must
take
no
arguments
.
The
[
SameObject
]
extended
attribute
must
not
be
used
on
anything
other
than
a
read
only
attribute
whose
type
is
an
interface
type
or
object
.
As
an
example,
this
extended
attribute
is
suitable
for
use
on
the
implementation
attribute
on
the
Document
interface
since
the
same
object
is
always
returned
for
a
given
Document
object.
[DOM]
[Exposed =Window ]interface Document :Node { [SameObject ]readonly attribute DOMImplementation implementation ; // ... };
3.3.11. [SecureContext]
If
the
[
SecureContext
]
extended
attribute
appears
on
an
interface
,
partial
interface
,
interface
mixin
,
partial
interface
mixin
,
callback
interface
,
namespace
,
partial
namespace
,
interface
member
,
interface
mixin
member
,
or
namespace
member
,
it
indicates
that
the
construct
is
exposed
only
within
a
secure
context
.
The
[
SecureContext
]
extended
attribute
must
not
be
used
on
any
other
construct.
The
[
SecureContext
]
extended
attribute
must
take
no
arguments
.
A
construct
is
available
in
both
secure
and
non-secure
contexts
if
it
is
not
available
only
in
secure
contexts
(i.e.,
if
no
[
SecureContext
]
extended
attribute
applies
to
it).
To check if a construct C is available only in secure contexts , run the following steps:
-
Assert: C is an interface , callback interface , namespace , interface member , interface mixin member , or namespace member .
-
Let H be C ’s host interface if C is an interface mixin member , or null otherwise.
-
If C is an interface member , interface mixin member , or namespace member , then:
-
If the [
SecureContext
] extended attribute is specified on C , then return true. -
Otherwise, set C to be the interface , partial interface , interface mixin , partial interface mixin , namespace , or partial namespace C is declared on.
-
-
If C is a partial interface , partial interface mixin , or partial namespace , then:
-
If the [
SecureContext
] extended attribute is specified on C , then return true. -
Otherwise, set C to be the original interface , interface mixin , or namespace definition of C .
-
-
If C is an interface mixin , then:
-
If the [
SecureContext
] extended attribute is specified on C , then return true. -
Otherwise, set C to H .
-
-
Assert: C is an interface , callback interface or namespace .
-
If the [
SecureContext
] extended attribute is specified on C , then return true. -
Otherwise, return false.
Note: Whether a construct is available only in secure contexts influences whether it is exposed in a given Realm .
If
[
SecureContext
]
appears
on
an
overloaded
operation
,
then
it
must
appear
on
all
overloads.
The
[
SecureContext
]
extended
attribute
must
not
be
specified
both
on
-
an interface member and its interface or partial interface ;
-
an interface mixin member and its interface mixin or partial interface mixin ;
-
a namespace member and its namespace or partial namespace .
Note:
This
is
because
adding
the
[
SecureContext
]
extended
attribute
on
a
member
when
its
containing
definition
is
also
annotated
with
the
[
SecureContext
]
extended
attribute
does
not
further
restrict
the
exposure
of
the
member
.
An
interface
without
the
[
SecureContext
]
extended
attribute
must
not
inherit
from
another
interface
that
does
specify
[
SecureContext
].
The following IDL fragment defines an interface with one operation that is executable from all contexts, and two which are executable only from secure contexts.
[Exposed =Window ]interface PowerfulFeature { // This call will succeed in all contexts.Promise <Result >calculateNotSoSecretResult (); // This operation will not be exposed to a non-secure context. In such a context, // there will be no "calculateSecretResult" property on PowerfulFeature.prototype. [SecureContext ]Promise <Result >calculateSecretResult (); // The same applies here: the attribute will not be exposed to a non-secure context, // and in a non-secure context there will be no "secretBoolean" property on // PowerfulFeature.prototype. [SecureContext ]readonly attribute boolean secretBoolean ; }; // HeartbeatSensor will not be exposed in a non-secure context, nor will its members. // In such a context, there will be no "HeartbeatSensor" property on Window. [SecureContext ]interface HeartbeatSensor {Promise <float >getHeartbeatsPerMinute (); }; // The interface mixin members defined below will never be exposed in a non-secure context, // regardless of whether the interface that includes them is. // In a non-secure context, there will be no "snap" property on // PowerfulFeature.prototype. [SecureContext ]interface mixin Snapshotable {Promise <boolean >snap (); };PowerfulFeature includes Snapshotable ; // On the other hand, the following interface mixin members will be exposed // to a non-secure context when included by a host interface // that doesn’t have the [SecureContext] extended attribute. // In a non-secure context, there will be a "log" property on // PowerfulFeatures.prototype.interface mixin Loggable {Promise <boolean >log (); };PowerfulFeatures includes Loggable ;
3.3.12. [Unscopable]
If
the
[
Unscopable
]
extended
attribute
appears
on
a
regular
attribute
or
regular
operation
,
it
indicates
that
an
object
that
implements
an
interface
with
the
given
interface
member
will
not
include
its
property
name
in
any
object
environment
record
with
it
as
its
base
object.
The
result
of
this
is
that
bare
identifiers
matching
the
property
name
will
not
resolve
to
the
property
in
a
with
statement.
This
is
achieved
by
including
the
property
name
on
the
interface
prototype
object
’s
@@unscopables
property’s
value.
The
[
Unscopable
]
extended
attribute
must
take
no
arguments
.
The
[
Unscopable
]
extended
attribute
must
not
appear
on
anything
other
than
a
regular
attribute
or
regular
operation
.
The
[
Unscopable
]
extended
attribute
must
not
be
used
on
an
attribute
declared
on
a
namespace
.
See
§ 3.7.3
Interface
prototype
object
for
the
specific
requirements
that
the
use
of
[
Unscopable
]
entails.
For example, with the following IDL:
[Exposed =Window ]interface Thing {void f (); [Unscopable ]g (); };
the
f
property
can
be
referenced
with
a
bare
identifier
in
a
with
statement
but
the
g
property
cannot:
var thing= getThing(); // An instance of Thing with ( thing) { f; // Evaluates to a Function object. g; // Throws a ReferenceError. }
3.4. Legacy extended attributes
This section defines a number of extended attributes whose presence affects the ECMAScript binding. Unlike those in § 3.3 Extended attributes , these exist only so that legacy Web platform features can be specified. They should not be used in specifications, unless required to specify the behavior of legacy APIs.
Editors who believe they have a good reason for using these extended attributes are strongly advised to discuss this by filing an issue before proceeding.
3.4.1. [LegacyFactoryFunction]
Instead of using this feature, give your interface a constructor operation .
If
the
[
LegacyFactoryFunction
]
extended
attribute
appears
on
an
interface
,
it
indicates
that
the
ECMAScript
global
object
will
have
a
property
with
the
specified
name
whose
value
is
a
function
that
can
create
objects
that
implement
the
interface.
Multiple
[
LegacyFactoryFunction
]
extended
attributes
may
appear
on
a
given
interface.
The
[
LegacyFactoryFunction
]
extended
attribute
must
take
a
named
argument
list
.
The
LegacyFactoryFunction
]'s
identifier
.
For
each
[
LegacyFactoryFunction
]
extended
attribute
on
the
interface,
there
will
be
a
way
to
construct
an
object
that
implements
the
interface
by
passing
the
specified
arguments
to
the
constructor
that
is
the
value
of
the
aforementioned
property.
The
identifier
used
for
the
legacy
factory
function
must
not
be
the
same
as
that
used
by
a
[
LegacyFactoryFunction
]
extended
attribute
on
another
interface,
must
not
be
the
same
as
an
identifier
used
by
a
[
LegacyWindowAlias
]
extended
attribute
on
this
interface
or
another
interface,
must
not
be
the
same
as
an
identifier
of
an
interface
that
has
an
interface
object
,
and
must
not
be
one
of
the
reserved
identifiers
.
The
[
LegacyFactoryFunction
]
and
[
Global
]
extended
attributes
must
not
be
specified
on
the
same
interface
.
See § 3.7.2 Legacy factory functions for details on how legacy factory functions are to be implemented.
The
following
IDL
defines
an
interface
that
uses
the
[
LegacyFactoryFunction
]
extended
attribute.
[Exposed =Window ,LegacyFactoryFunction =Audio (DOMString src )]interface HTMLAudioElement :HTMLMediaElement { // ... };
An
ECMAScript
implementation
that
supports
this
interface
will
allow
the
construction
of
HTMLAudioElement
objects
using
the
Audio
function.
typeof Audio; // Evaluates to 'function'. var a2= new Audio( 'a.flac' ); // Creates an HTMLAudioElement using the // one-argument constructor.
As
an
additional
legacy
quirk,
these
factory
functions
will
have
a
prototype
property
equal
to
the
prototype
of
the
original
interface:
console. assert( Audio. prototype=== HTMLAudioElement. prototype);
3.4.2. [LegacyLenientSetter]
If
the
[
LegacyLenientSetter
]
extended
attribute
appears
on
a
read
only
regular
attribute
,
it
indicates
that
a
no-op
setter
will
be
generated
for
the
attribute’s
accessor
property.
This
results
in
erroneous
assignments
to
the
property
in
strict
mode
to
be
ignored
rather
than
causing
an
exception
to
be
thrown.
Pages
have
been
observed
where
authors
have
attempted
to
polyfill
an
IDL
attribute
by
assigning
to
the
property,
but
have
accidentally
done
so
even
if
the
property
exists.
In
strict
mode,
this
would
cause
an
exception
to
be
thrown,
potentially
breaking
page.
Without
[
LegacyLenientSetter
],
this
could
prevent
a
browser
from
shipping
the
feature.
The
[
LegacyLenientSetter
]
extended
attribute
must
take
no
arguments
.
It
must
not
be
used
on
anything
other
than
a
read
only
regular
attribute
.
An
attribute
with
the
[
LegacyLenientSetter
]
extended
attribute
must
not
also
be
declared
with
the
[
PutForwards
]
or
[
Replaceable
]
extended
attributes.
The
[
LegacyLenientSetter
]
extended
attribute
must
not
be
used
on
an
attribute
declared
on
a
namespace
.
See
the
Attributes
section
for
how
[
LegacyLenientSetter
]
is
to
be
implemented.
The
following
IDL
fragment
defines
an
interface
that
uses
the
[
LegacyLenientSetter
]
extended
attribute.
[Exposed =Window ]interface Example { [LegacyLenientSetter ]readonly attribute DOMString x ;readonly attribute DOMString y ; };
An ECMAScript implementation that supports this interface will have a setter on the accessor property that correspond to x, which allows any assignment to be ignored in strict mode.
"use strict" ; var example= getExample(); // Get an instance of Example. // Fine; while we are in strict mode, there is a setter that is a no-op. example. x= 1 ; // Throws a TypeError, since we are in strict mode and there is no setter. example. y= 1 ;
3.4.3. [LegacyLenientThis]
If
the
[
LegacyLenientThis
]
extended
attribute
appears
on
a
regular
attribute
,
it
indicates
that
invocations
of
the
attribute’s
getter
or
setter
with
a
The
[
LegacyLenientThis
]
extended
attribute
must
take
no
arguments
.
It
must
not
be
used
on
a
static
attribute
.
The
[
LegacyLenientThis
]
extended
attribute
must
not
be
used
on
an
attribute
declared
on
a
namespace
.
See
the
Attributes
section
for
how
[
LegacyLenientThis
]
is
to
be
implemented.
The
following
IDL
fragment
defines
an
interface
that
uses
the
[
LegacyLenientThis
]
extended
attribute.
[Exposed =Window ]interface Example { [LegacyLenientThis ]attribute DOMString x ;attribute DOMString y ; };
An
ECMAScript
implementation
that
supports
this
interface
will
allow
the
getter
and
setter
of
the
accessor
property
that
corresponds
to
x
to
be
invoked
with
something
other
than
an
Example
object.
var example= getExample(); // Get an instance of Example. var obj= { }; // Fine. example. x; // Ignored, since the this value is not an Example object and [LegacyLenientThis] is used. Object. getOwnPropertyDescriptor( Example. prototype, "x" ). get. call( obj); // Also ignored, since Example.prototype is not an Example object and [LegacyLenientThis] is used. Example. prototype. x; // Throws a TypeError, since Example.prototype is not an Example object. Example. prototype. y;
3.4.4. [LegacyNamespace]
Instead of using this feature, interface names can be formed with a naming convention of starting with a particular prefix for a set of interfaces, as part of the identifier, without the intervening dot.
If
the
[
LegacyNamespace
]
extended
attribute
appears
on
an
interface
,
it
indicates
that
the
interface
object
for
this
interface
will
not
be
created
as
a
property
of
the
global
object,
but
rather
as
a
property
of
the
namespace
identified
by
the
argument
to
the
extended
attribute.
The
[
LegacyNamespace
]
extended
attribute
take
an
identifier
.
This
identifier
must
be
the
identifier
of
a
namespace.
The
[
LegacyNamespace
]
and
[
LegacyNoInterfaceObject
]
extended
attributes
must
not
be
specified
on
the
same
interface.
See § 3.13.1 Namespace object for details on how an interface is exposed on a namespace.
LegacyNamespace
]
to
be
defined
inside
of
it.
namespace Foo { }; [LegacyNamespace =Foo ]interface Bar {constructor (); };
In an ECMAScript implementation of the above namespace and interface, the constructor Bar can be accessed as follows:
var instance= new Foo. Bar();
3.4.5. [LegacyNoInterfaceObject]
If
the
[
LegacyNoInterfaceObject
]
extended
attribute
appears
on
an
interface
,
it
indicates
that
an
interface
object
will
not
exist
for
the
interface
in
the
ECMAScript
binding.
The
[
LegacyNoInterfaceObject
]
extended
attribute
must
take
no
arguments
.
The
[
LegacyNoInterfaceObject
]
extended
attribute
must
not
be
specified
on
an
interface
that
has
any
constructors
or
static
operations
defined
on
it.
An
interface
that
does
not
have
the
[
LegacyNoInterfaceObject
]
extended
attribute
specified
must
not
inherit
from
an
interface
that
has
the
[
LegacyNoInterfaceObject
]
extended
attribute
specified.
See
§ 3.7
Interfaces
for
the
specific
requirements
that
the
use
of
[
LegacyNoInterfaceObject
]
entails.
The following IDL fragment defines two interfaces, one whose interface object is exposed on the ECMAScript global object, and one whose isn’t:
[Exposed =Window ]interface Storage {void addEntry (unsigned long key ,any value ); }; [Exposed =Window ,LegacyNoInterfaceObject ]interface Query {any lookupEntry (unsigned long key ); };
An
ECMAScript
implementation
of
the
above
IDL
would
allow
manipulation
of
Storage
’s
prototype,
but
not
Query
’s.
typeof Storage; // evaluates to "object" // Add some tracing alert() call to Storage.addEntry. var fn= Storage. prototype. addEntry; Storage. prototype. addEntry= function ( key, value) { alert( 'Calling addEntry()' ); return fn. call( this , key, value); }; typeof Query; // evaluates to "undefined" var fn= Query. prototype. lookupEntry; // exception, Query isn’t defined
3.4.6. [LegacyNullToEmptyString]
If
the
[
LegacyNullToEmptyString
]
extended
attribute
appears
on
the
DOMString
type,
it
creates
a
new
IDL
type
such
that
that
when
an
ECMAScript
null
",
which
is
the
default,
it
will
be
converted
to
the
empty
string.
The
[
LegacyNullToEmptyString
]
extended
attribute
must
not
be
associated
with
a
type
that
is
not
DOMString
.
Note:
This
means
that
even
DOMString?
must
not
use
[
LegacyNullToEmptyString
],
since
See
§ 3.2.9
DOMString
for
the
specific
requirements
that
the
use
of
[
LegacyNullToEmptyString
]
entails.
[Exposed =Window ]interface Dog {attribute DOMString name ;attribute [LegacyNullToEmptyString ]DOMString owner ;boolean isMemberOfBreed ([LegacyNullToEmptyString ]DOMString breedName ); };
An
ECMAScript
implementation
implementing
the
Dog
interface
would
convert
a
owner
property
or
passed
as
the
argument
to
the
isMemberOfBreed
function
to
the
empty
string
rather
than
"
null
":
var d= getDog(); // Assume d is a platform object implementing the Dog // interface. d. name= null ; // This assigns the string "null" to the .name // property. d. owner= null ; // This assigns the string "" to the .owner property. d. isMemberOfBreed( null ); // This passes the string "" to the isMemberOfBreed // function.
3.4.7. [LegacyOverrideBuiltIns]
If
the
[
LegacyOverrideBuiltIns
]
extended
attribute
appears
on
an
interface
,
it
indicates
that
for
a
legacy
platform
object
implementing
the
interface,
properties
corresponding
to
all
of
the
object’s
supported
property
names
will
appear
to
be
on
the
object,
regardless
of
what
other
properties
exist
on
the
object
or
its
prototype
chain.
This
means
that
named
properties
will
always
shadow
any
properties
that
would
otherwise
appear
on
the
object.
This
is
in
contrast
to
the
usual
behavior,
which
is
for
named
properties
to
be
exposed
only
if
there
is
no
property
with
the
same
name
on
the
object
itself
or
somewhere
on
its
prototype
chain.
The
[
LegacyOverrideBuiltIns
]
extended
attribute
must
take
no
arguments
and
must
not
appear
on
an
interface
that
does
not
define
a
named
property
getter
or
that
also
is
declared
with
the
[
Global
]
extended
attribute
.
If
the
extended
attribute
is
specified
on
a
partial
interface
definition,
then
that
partial
interface
definition
must
be
the
part
of
the
interface
definition
that
defines
the
named
property
getter
.
If
the
[
LegacyOverrideBuiltIns
]
extended
attribute
is
specified
on
a
partial
interface
definition,
it
is
considered
to
appear
on
the
interface
itself.
See
§ 3.9
Legacy
platform
objects
and
§ 3.9.3
[[DefineOwnProperty]]
for
the
specific
requirements
that
the
use
of
[
LegacyOverrideBuiltIns
]
entails.
The following IDL fragment defines two interfaces , one that has a named property getter and one that does not.
[Exposed =Window ]interface StringMap {readonly attribute unsigned long length ;getter DOMString lookup (DOMString key ); }; [Exposed =Window ,LegacyOverrideBuiltIns ]interface StringMap2 {readonly attribute unsigned long length ;getter DOMString lookup (DOMString key ); };
In an ECMAScript implementation of these two interfaces, getting certain properties on objects implementing the interfaces will result in different values:
// Obtain an instance of StringMap. Assume that it has "abc", "length" and // "toString" as supported property names. var map1= getStringMap(); // This invokes the named property getter. map1. abc; // This fetches the "length" property on the object that corresponds to the // length attribute. map1. length; // This fetches the "toString" property from the object’s prototype chain. map1. toString; // Obtain an instance of StringMap2. Assume that it also has "abc", "length" // and "toString" as supported property names. var map2= getStringMap2(); // This invokes the named property getter. map2. abc; // This also invokes the named property getter, despite the fact that the "length" // property on the object corresponds to the length attribute. map2. length; // This too invokes the named property getter, despite the fact that "toString" is // a property in map2’s prototype chain. map2. toString;
3.4.8. [LegacyTreatNonObjectAsNull]
If
the
[
LegacyTreatNonObjectAsNull
]
extended
attribute
appears
on
a
callback
function
,
then
it
indicates
that
any
value
assigned
to
an
attribute
whose
type
is
a
nullable
callback
function
will
be
converted
more
loosely:
if
the
value
is
not
an
object,
it
will
be
converted
to
null,
and
if
the
value
is
not
callable
,
it
will
be
converted
to
a
callback
function
value
that
does
nothing
when
called.
See
§ 3.2.19
Nullable
types
—
T?
,
§ 3.2.18
Callback
function
types
and
§ 3.12
Invoking
callback
functions
for
the
specific
requirements
that
the
use
of
[
LegacyTreatNonObjectAsNull
]
entails.
The
following
IDL
fragment
defines
an
interface
that
has
one
attribute
whose
type
is
a
[
LegacyTreatNonObjectAsNull
]-annotated
callback
function
and
another
whose
type
is
a
callback
function
without
the
extended
attribute
:
callback OccurrenceHandler =void (DOMString details ); [LegacyTreatNonObjectAsNull ]callback ErrorHandler =void (DOMString details ); [Exposed =Window ]interface Manager {attribute OccurrenceHandler ?handler1 ;attribute ErrorHandler ?handler2 ; };
In an ECMAScript implementation, assigning a value that is not an object (such as a Number value), or that is not callable to handler1 will have different behavior from that when assigning to handler2:
var manager= getManager(); // Get an instance of Manager. manager. handler1= function () { }; manager. handler1; // Evaluates to the function. try { manager. handler1= 123 ; // Throws a TypeError. } catch ( e) { } try { manager. handler1= {}; // Throws a TypeError. } catch ( e) { } manager. handler2= function () { }; manager. handler2; // Evaluates to the function. manager. handler2= 123 ; manager. handler2; // Evaluates to null. manager. handler2= {}; manager. handler2; // Evaluates to the object.
3.4.9. [LegacyUnenumerableNamedProperties]
If
the
[
LegacyUnenumerableNamedProperties
]
extended
attribute
appears
on
a
interface
that
supports
named
properties
,
it
indicates
that
all
the
interface’s
named
properties
are
unenumerable.
The
[
LegacyUnenumerableNamedProperties
]
extended
attribute
must
take
no
arguments
and
must
not
appear
on
an
interface
that
does
not
define
a
named
property
getter
.
If
the
[
LegacyUnenumerableNamedProperties
]
extended
attribute
is
specified
on
an
interface,
then
it
applies
to
all
its
derived
interfaces
and
must
not
be
specified
on
any
of
them.
See
§ 3.9.1
[[GetOwnProperty]]
for
the
specific
requirements
that
the
use
of
[
LegacyUnenumerableNamedProperties
]
entails.
3.4.10. [LegacyUnforgeable]
If
the
[
LegacyUnforgeable
]
extended
attribute
appears
on
regular
attributes
or
non-
static
operations
,
it
indicates
that
the
attribute
or
operation
will
be
reflected
as
an
ECMAScript
property
in
a
way
that
means
its
behavior
cannot
be
modified
and
that
performing
a
property
lookup
on
the
object
will
always
result
in
the
attribute’s
property
value
being
returned.
In
particular,
the
property
will
be
non-configurable
and
will
exist
as
an
own
property
on
the
object
itself
rather
than
on
its
prototype.
An
attribute
or
operation
is
said
to
be
unforgeable
on
a
given
interface
A
if
the
attribute
or
operation
is
declared
on
A
,
and
is
annotated
with
the
[
LegacyUnforgeable
]
extended
attribute
.
The
[
LegacyUnforgeable
]
extended
attribute
must
take
no
arguments
.
The
[
LegacyUnforgeable
]
extended
attribute
must
not
appear
on
anything
other
than
a
regular
attribute
or
a
non-
static
operation
.
If
it
does
appear
on
an
operation
,
then
it
must
appear
on
all
operations
with
the
same
identifier
on
that
interface.
The
[
LegacyUnforgeable
]
extended
attribute
must
not
be
used
on
an
attribute
declared
on
a
namespace
.
If an attribute or operation X is unforgeable on an interface A , and A is one of the inherited interfaces of another interface B , then B must not have a regular attribute or non- static operation with the same identifier as X .
For example, the following is disallowed:
[Exposed =Window ]interface A1 { [LegacyUnforgeable ]readonly attribute DOMString x ; }; [Exposed =Window ]interface B1 :A1 {void x (); // Invalid; would be shadowed by A1’s x. }; [Exposed =Window ]interface B2 :A1 { };B2 includes M1 ;interface mixin M1 {void x (); // Invalid; B2’s copy of x would be shadowed by A1’s x. };
See
§ 3.7.6
Attributes
,
§ 3.7.7
Operations
,
§ 3.8
Platform
objects
implementing
interfaces
,
§ 3.9
Legacy
platform
objects
and
§ 3.9.3
[[DefineOwnProperty]]
for
the
specific
requirements
that
the
use
of
[
LegacyUnforgeable
]
entails.
The
following
IDL
fragment
defines
an
interface
that
has
two
attributes
,
one
of
which
is
designated
as
[
LegacyUnforgeable
]:
[Exposed =Window ]interface System { [LegacyUnforgeable ]readonly attribute DOMString username ;readonly attribute long long loginTime ; };
In an ECMAScript implementation of the interface, the username attribute will be exposed as a non-configurable property on the object itself:
var system= getSystem(); // Get an instance of System. system. hasOwnProperty( "username" ); // Evaluates to true. system. hasOwnProperty( "loginTime" ); // Evaluates to false. System. prototype. hasOwnProperty( "username" ); // Evaluates to false. System. prototype. hasOwnProperty( "loginTime" ); // Evaluates to true. try { // This call would fail, since the property is non-configurable. Object. defineProperty( system, "username" , { value: "administrator" }); } catch ( e) { } // This defineProperty call would succeed, because System.prototype.loginTime // is configurable. var forgedLoginTime= 5 ; Object. defineProperty( System. prototype, "loginTime" , { value: forgedLoginTime}); system. loginTime; // So this now evaluates to forgedLoginTime.
3.4.11. [LegacyWindowAlias]
If
the
[
LegacyWindowAlias
]
extended
attribute
appears
on
an
interface
,
it
indicates
that
the
Window
interface
will
have
a
property
for
each
identifier
mentioned
in
the
extended
attribute,
whose
value
is
the
interface
object
for
the
interface.
The
[
LegacyWindowAlias
]
extended
attribute
must
either
take
an
identifier
or
take
an
identifier
list
.
The
LegacyWindowAlias
]'s
identifiers
.
Each
of
the
identifiers
of
[
LegacyWindowAlias
]
must
not
be
the
same
as
one
used
by
a
[
LegacyWindowAlias
]
extended
attribute
on
this
interface
or
another
interface,
must
not
be
the
same
as
the
identifier
used
by
a
[
LegacyFactoryFunction
]
extended
attribute
on
this
interface
or
another
interface,
must
not
be
the
same
as
an
identifier
of
an
interface
that
has
an
interface
object
,
and
must
not
be
one
of
the
reserved
identifiers
.
The
[
LegacyWindowAlias
]
and
[
LegacyNoInterfaceObject
]
extended
attributes
must
not
be
specified
on
the
same
interface.
The
[
LegacyWindowAlias
]
and
[
LegacyNamespace
]
extended
attributes
must
not
be
specified
on
the
same
interface.
The
[
LegacyWindowAlias
]
extended
attribute
must
not
be
specified
on
an
interface
that
does
not
include
the
Window
interface
in
its
exposure
set
.
An
interface
must
not
have
more
than
one
[
LegacyWindowAlias
]
extended
attributes
specified.
See § 3.7 Interfaces for details on how legacy window aliases are to be implemented.
The
following
IDL
defines
an
interface
that
uses
the
[
LegacyWindowAlias
]
extended
attribute.
[Exposed =Window ,LegacyWindowAlias =WebKitCSSMatrix ]interface DOMMatrix :DOMMatrixReadOnly { // ... };
An
ECMAScript
implementation
that
supports
this
interface
will
expose
two
properties
on
the
Window
object
with
the
same
value
and
the
same
characteristics;
one
for
exposing
the
interface
object
normally,
and
one
for
exposing
it
with
a
legacy
name.
WebKitCSSMatrix=== DOMMatrix; // Evaluates to true. var m= new WebKitCSSMatrix(); // Creates a new object that // implements DOMMatrix. m. constructor=== DOMMatrix; // Evaluates to true. m. constructor=== WebKitCSSMatrix; // Evaluates to true. {}. toString. call( m); // Evaluates to '[object DOMMatrix]'.
3.5. Security
Certain algorithms in the sections below are defined to perform a security check on a given object. This check is used to determine whether a given operation invocation or attribute access should be allowed. The security check takes the following three inputs:
-
the platform object on which the operation invocation or attribute access is being done,
-
the identifier of the operation or attribute, and
-
the type of the function object – "
method
" (when it corresponds to an IDL operation), or "getter
" or "setter
" (when it corresponds to the getter or setter function of an IDL attribute).
Note: The HTML Standard defines how a security check is performed. [HTML]
3.6. Overload resolution algorithm
In order to define how function invocations are resolved, the overload resolution algorithm is defined. Its input is an effective overload set , S , and a list of ECMAScript values, args . Its output is a pair consisting of the operation or extended attribute of one of S ’s entries and a list of IDL values or the special value “missing”. The algorithm behaves as follows:
-
Let maxarg be the length of the longest type list of the entries in S .
-
Let n be the size of args .
-
Initialize argcount to be min( maxarg , n ).
-
Remove from S all entries whose type list is not of length argcount .
-
Initialize d to −1.
-
Initialize method to
undefined . -
If there is more than one entry in S , then set d to be the distinguishing argument index for the entries of S .
-
Initialize values to be an empty list, where each entry will be either an IDL value or the special value “missing”.
-
Initialize i to 0.
-
While i < d :
-
Let V be args [ i ].
-
Let type be the type at index i in the type list of any entry in S .
Note: All entries in S at this point have the same type and optionality value at index i .
-
Let optionality be the value at index i in the list of optionality values of any entry in S .
-
If optionality is “optional” and V is
undefined , then:-
If the argument at index i is declared with a default value , then append to values that default value.
-
Otherwise, append to values the special value “missing”.
-
-
Otherwise, append to values the result of converting V to IDL type type .
-
Set i to i + 1.
-
-
If i = d , then:
-
Let V be args [ i ].
Note: This is the argument that will be used to resolve which overload is selected.
-
If V is
undefined , and there is an entry in S whose list of optionality values has “optional” at index i , then remove from S all other entries. -
Otherwise: if V is
null orundefined , and there is an entry in S that has one of the following types at position i of its type list,-
an annotated type whose inner type is one of the above types
-
a union type or annotated union type that includes a nullable type or that has a dictionary type in its flattened members
then remove from S all other entries.
-
Otherwise: if V is a platform object , and there is an entry in S that has one of the following types at position i of its type list,
-
an interface type that V implements
-
a nullable version of any of the above types
-
an annotated type whose inner type is one of the above types
-
a union type , nullable union type, or annotated union type that has one of the above types in its flattened member types
then remove from S all other entries.
-
-
Otherwise: if Type ( V ) is Object, V has an [[ArrayBufferData]] internal slot , and there is an entry in S that has one of the following types at position i of its type list,
-
a nullable version of either of the above types
-
an annotated type whose inner type is one of the above types
-
a union type , nullable union type, or annotated union type that has one of the above types in its flattened member types
then remove from S all other entries.
-
Otherwise: if Type ( V ) is Object, V has a [[DataView]] internal slot , and there is an entry in S that has one of the following types at position i of its type list,
-
a nullable version of either of the above types
-
an annotated type whose inner type is one of the above types
-
a union type , nullable union type, or annotated union type that has one of the above types in its flattened member types
then remove from S all other entries.
-
Otherwise: if Type ( V ) is Object, V has a [[TypedArrayName]] internal slot , and there is an entry in S that has one of the following types at position i of its type list,
-
a typed array type whose name is equal to the value of V ’s [[TypedArrayName]] internal slot
-
a nullable version of either of the above types
-
an annotated type whose inner type is one of the above types
-
a union type , nullable union type, or annotated union type that has one of the above types in its flattened member types
then remove from S all other entries.
-
-
Otherwise: if IsCallable ( V ) is true, and there is an entry in S that has one of the following types at position i of its type list,
-
a callback function type
-
a nullable version of any of the above types
-
an annotated type whose inner type is one of the above types
-
a union type , nullable union type, or annotated union type that has one of the above types in its flattened member types
then remove from S all other entries.
-
-
Otherwise: if Type ( V ) is Object and there is an entry in S that has one of the following types at position i of its type list,
-
a nullable version of any of the above types
-
an annotated type whose inner type is one of the above types
-
a union type , nullable union type, or annotated union type that has one of the above types in its flattened member types
and after performing the following steps,
-
Let method be ? GetMethod ( V ,
@@iterator
).
method is not
undefined , then remove from S all other entries. -
Otherwise: if Type ( V ) is Object and there is an entry in S that has one of the following types at position i of its type list,
-
a nullable version of any of the above types
-
an annotated type whose inner type is one of the above types
-
a union type , nullable union type, or annotated union type that has one of the above types in its flattened member types
then remove from S all other entries.
-
Otherwise: if Type ( V ) is Boolean and there is an entry in S that has one of the following types at position i of its type list,
-
an annotated type whose inner type is one of the above types
-
a union type , nullable union type, or annotated union type that has one of the above types in its flattened member types
then remove from S all other entries.
-
Otherwise: if Type ( V ) is Number and there is an entry in S that has one of the following types at position i of its type list,
-
an annotated type whose inner type is one of the above types
-
a union type , nullable union type, or annotated union type that has one of the above types in its flattened member types
then remove from S all other entries.
-
Otherwise: if there is an entry in S that has one of the following types at position i of its type list,
-
a nullable version of any of the above types
-
an annotated type whose inner type is one of the above types
-
a union type , nullable union type, or annotated union type that has one of the above types in its flattened member types
then remove from S all other entries.
-
Otherwise: if there is an entry in S that has one of the following types at position i of its type list,
-
an annotated type whose inner type is one of the above types
-
a union type , nullable union type, or annotated union type that has one of the above types in its flattened member types
then remove from S all other entries.
-
Otherwise: if there is an entry in S that has one of the following types at position i of its type list,
-
an annotated type whose inner type is one of the above types
-
a union type , nullable union type, or annotated union type that has one of the above types in its flattened member types
then remove from S all other entries.
-
Otherwise: if there is an entry in S that has
any
at position i of its type list, then remove from S all other entries.
-
-
Let callable be the operation or extended attribute of the single entry in S .
-
If i = d and method is not
undefined , then-
Let V be args [ i ].
-
Let T be the type at index i in the type list of the remaining entry in S .
-
If T is a sequence type , then append to values the result of creating a sequence of type T from V and method .
-
Otherwise, T is a frozen array type . Append to values the result of creating a frozen array of type T from V and method .
-
Set i to i + 1.
-
-
While i < argcount :
-
Let V be args [ i ].
-
Let type be the type at index i in the type list of the remaining entry in S .
-
Let optionality be the value at index i in the list of optionality values of the remaining entry in S .
-
If optionality is “optional” and V is
undefined , then:-
If the argument at index i is declared with a default value , then append to values that default value.
-
Otherwise, append to values the special value “missing”.
-
-
Otherwise, append to values the result of converting V to IDL type type .
-
Set i to i + 1.
-
-
While i is less than the number of arguments callable is declared to take:
-
If callable ’s argument at index i is declared with a default value , then append to values that default value.
-
Otherwise, if callable ’s argument at index i is not variadic, then append to values the special value “missing”.
-
Set i to i + 1.
-
-
Return the pair < callable , values >.
The overload resolution algorithm performs both the identification of which overloaded operation, constructor, etc. is being called, and the conversion of the ECMAScript argument values to their corresponding IDL values. Informally, it operates as follows.
First, the selection of valid overloads is done by considering the number of ECMAScript arguments that were passed in to the function:
-
If there are more arguments passed in than the longest overload argument list, then they are ignored.
-
After ignoring these trailing arguments, only overloads that can take this exact number of arguments are considered. If there are none, then a
TypeError
is thrown.
Once we have a set of possible overloads with the right number of arguments, the ECMAScript values are converted from left to right. The nature of the restrictions on overloading means that if we have multiple possible overloads at this point, then there will be one position in the argument list that will be used to distinguish which overload we will finally select; this is the distinguishing argument index .
We
first
convert
the
arguments
to
the
left
of
the
distinguishing
argument.
(There
is
a
requirement
that
an
argument
to
the
left
of
the
distinguishing
argument
index
has
the
same
type
as
in
the
other
overloads,
at
the
same
index.)
Then
we
inspect
the
type
of
the
ECMAScript
value
that
is
passed
in
at
the
distinguishing
argument
index
to
determine
which
IDL
type
it
may
correspond
to.
This
allows
us
to
select
the
final
overload
that
will
be
invoked.
If
the
value
passed
in
is
TypeError
.
Generally,
the
inspection
of
the
value
at
the
distinguishing
argument
index
does
not
have
any
side
effects,
and
the
only
side
effects
in
the
overload
resolution
algorithm
are
the
result
of
converting
the
ECMAScript
values
to
IDL
values.
(An
exception
exists
when
one
of
the
overloads
has
a
sequence
type
or
frozen
array
type
at
the
distinguishing
argument
index.
In
this
case,
we
attempt
to
get
the
@@iterator
property
to
determine
the
appropriate
overload,
and
perform
the
conversion
of
the
distinguishing
argument
separately
before
continuing
with
the
next
step.)
At this point, we have determined which overload to use. We now convert the remaining arguments, from the distinguishing argument onwards, again ignoring any additional arguments that were ignored due to being passed after the last possible argument.
When
converting
an
optional
argument’s
ECMAScript
value
to
its
equivalent
IDL
value,
Optional
arguments
corresponding
to
a
final,
variadic
argument
do
not
treat
3.7. Interfaces
For
every
interface
that
is
exposed
in
a
given
Realm
and
that
is
not
declared
with
the
[
LegacyNoInterfaceObject
]
or
[
LegacyNamespace
]
extended
attributes
,
a
corresponding
property
exists
on
the
Realm
's
global
object
.
The
name
of
the
property
is
the
identifier
of
the
interface,
and
its
value
is
an
object
called
the
interface
object
.
The
characteristics
of
an
interface
object
are
described
in
§ 3.7.1
Interface
object
.
If
the
[
LegacyWindowAlias
]
extended
attribute
was
specified
on
an
exposed
interface,
then
for
each
identifier
in
[
LegacyWindowAlias
]'s
identifiers
there
exists
a
corresponding
property
on
the
Window
global
object.
The
name
of
the
property
is
the
given
identifier
,
and
its
value
is
a
reference
to
the
interface
object
for
the
interface
.
In
addition,
for
every
[
LegacyFactoryFunction
]
extended
attribute
on
an
exposed
interface,
a
corresponding
property
exists
on
the
ECMAScript
global
object.
The
name
of
the
property
is
the
[
LegacyFactoryFunction
]'s
identifier
,
and
its
value
is
an
object
called
a
legacy
factory
function
,
which
allows
creation
of
objects
that
implement
the
interface.
The
characteristics
of
a
legacy
factory
function
are
described
in
§ 3.7.2
Legacy
factory
functions
.
3.7.1. Interface object
The interface object for a given interface is a built-in function object . It has properties that correspond to the constants and static operations defined on that interface, as described in sections § 3.7.5 Constants and § 3.7.7 Operations .
If the interface is declared with a constructor operation , then the interface object can be called as a constructor to create an object that implements that interface. Calling that interface as a function will throw an exception.
Interface objects whose interfaces are not declared with a constructor operation will throw when called, both as a function and as a constructor .
An interface object for an interface has an associated object called the interface prototype object . This object has properties that correspond to the regular attributes and regular operations defined on the interface, and is described in more detail in § 3.7.3 Interface prototype object .
Note:
Since
an
interface
object
is
a
function
object
the
typeof
operator
will
return
"function"
when
applied
to
an
interface
object.
An interface may have overridden constructor steps , which can change the behavior of the interface object when called or constructed. By default interfaces do not have such steps.
In general, constructors are described by defining a constructor operation and its behavior. The overridden constructor steps are used only for more complicated situations. Editors who wish to use this feature are strongly advised to discuss this by filing an issue before proceeding.
The interface object for a given interface I with identifier id and in Realm realm is created as follows:
-
Let steps be I ’s overridden constructor steps if they exist, or the following steps otherwise:
-
If I was not declared with a constructor operation , then throw a
TypeError
. -
Let args be the passed arguments.
-
Let n be the size of args .
-
Let id be the identifier of interface I .
-
Compute the effective overload set for constructors with identifier id on interface I and with argument count n , and let S be the result.
-
Let < constructor , values > be the result of passing S and args . to the overload resolution algorithm .
-
Let object be the result of internally creating a new object implementing I , with realm and
NewTarget
. -
Perform the actions listed in the description of constructor with values as the argument values and object as this .
-
Let O be object , converted to an ECMAScript value .
-
Assert: O is an object that implements I .
-
Assert: O .[[Realm]] is realm .
-
Return O .
-
-
Let constructorProto be realm .[[Intrinsics]].[[
%FunctionPrototype%
]]. -
If I inherits from some other interface P , then set constructorProto to the interface object of P in realm .
-
Let F be ! CreateBuiltinFunction ( steps , « [[Unforgeables]] », realm , constructorProto ).
-
Let unforgeables be ! OrdinaryObjectCreate (
null ). -
Define the unforgeable regular operations of I on unforgeables , given realm .
-
Define the unforgeable regular attributes of I on unforgeables , given realm .
-
Set F .[[Unforgeables]] to unforgeables .
Note: this object is never exposed to user code. It exists only to ensure all instances of an interface with an unforgeable member use the same JavaScript function objects for attribute getters , attribute setters and operation functions .
-
Perform ! SetFunctionName ( F , id ).
-
Let length be 0.
-
If I was declared with a constructor operation , then
-
Compute the effective overload set for constructors with identifier id on interface I and with argument count 0, and let S be the result.
-
Set length to the length of the shortest argument list of the entries in S .
-
-
Perform ! SetFunctionLength ( F , length ).
-
Let proto be the result of creating an interface prototype object of interface I in realm .
-
Perform ! DefinePropertyOrThrow ( F , "
prototype
", PropertyDescriptor{[[Value]]: proto , [[Writable]]:false , [[Enumerable]]:false , [[Configurable]]:false }). -
Define the constants of interface I on F given realm .
-
Define the static attributes of interface I on F given realm .
-
Define the static operations of interface I on F given realm .
-
Return F .
3.7.2. Legacy factory functions
A
legacy
factory
function
that
exists
due
to
one
or
more
[
LegacyFactoryFunction
]
extended
attributes
with
a
given
identifier
is
a
built-in
function
object
.
It
allows
constructing
objects
that
implement
the
interface
on
which
the
[
LegacyFactoryFunction
]
extended
attributes
appear.
The legacy factory function with identifier id for a given interface I in Realm realm is created as follows:
-
Let steps be the following steps:
-
Let args be the passed arguments.
-
Let n be the size of args .
-
Compute the effective overload set for legacy factory functions with identifier id on interface I and with argument count n , and let S be the result.
-
Let < constructor , values > be the result of passing S and args to the overload resolution algorithm .
-
Let object be the result of internally creating a new object implementing I , with realm and
NewTarget
. -
Perform the actions listed in the description of constructor with values as the argument values and object as this .
-
Let O be object , converted to an ECMAScript value .
-
Assert: O is an object that implements I .
-
Assert: O .[[Realm]] is realm .
-
Return O .
-
Let F be ! CreateBuiltinFunction ( steps , « », realm ).
-
Perform ! SetFunctionName ( F , id ).
-
Compute the effective overload set for legacy factory functions with identifier id on interface I and with argument count 0, and let S be the result.
-
Let length be the length of the shortest argument list of the entries in S .
-
Perform ! SetFunctionLength ( F , length ).
-
Let proto be the interface prototype object of interface I in realm .
-
Perform ! DefinePropertyOrThrow ( F , "
prototype
", PropertyDescriptor{[[Value]]: proto , [[Writable]]:false , [[Enumerable]]:false , [[Configurable]]:false }). -
Return F .
3.7.3. Interface prototype object
There
will
exist
an
interface
prototype
object
for
every
interface
defined,
regardless
of
whether
the
interface
was
declared
with
the
[
LegacyNoInterfaceObject
]
extended
attribute
.
The interface prototype object for a given interface interface and Realm realm is created as follows:
-
Let proto be null.
-
If interface is declared with the [
Global
] extended attribute , and interface supports named properties , then set proto to the result of creating a named properties object for interface and realm . -
Otherwise, if interface is declared to inherit from another interface, then set proto to the interface prototype object in realm of that inherited interface .
-
Otherwise, if interface is the
DOMException
interface , then set proto to realm .[[Intrinsics]].[[%ErrorPrototype%
]]. -
Otherwise, set proto to realm .[[Intrinsics]].[[
%ObjectPrototype%
]]. -
Assert: Type ( proto ) is Object.
-
Let interfaceProtoObj be ! OrdinaryObjectCreate ( proto ).
-
If interface has any member declared with the [
Unscopable
] extended attribute , then:Should an
@@unscopables
property also be defined if interface is declared with the [Global
] extended attribute ? This is discussed in issue #544 .-
Let unscopableObject be ! OrdinaryObjectCreate (
null ). -
For each exposed member member of interface that is declared with the [
Unscopable
] extended attribute :-
Let id be member ’s identifier .
-
Perform ! CreateDataProperty ( unscopableObject , id ,
true ).
-
-
Let desc be the PropertyDescriptor{[[Value]]: unscopableObject , [[Writable]]:
false , [[Enumerable]]:false , [[Configurable]]:true }. -
Perform ! DefinePropertyOrThrow ( interfaceProtoObj ,
@@unscopables
, desc ).
-
-
If interface is declared with the [
Global
] extended attribute , or interface is in the set of inherited interfaces of an interface that is declared with the [Global
] extended attribute , then:-
Set the internal methods of interfaceProtoObj which are specific to immutable prototype exotic objects to the definitions specified in ECMA-262 Immutable prototype exotic objects .
-
-
If interface is not declared with the [
Global
] extended attribute , then:-
Define the regular attributes of interface on interfaceProtoObj given realm .
-
Define the regular operations of interface on interfaceProtoObj given realm .
-
Define the iteration methods of interface on interfaceProtoObj given realm .
-
Define the asynchronous iteration methods of interface on interfaceProtoObj given realm .
-
-
Define the constants of interface on interfaceProtoObj given realm .
-
If the [
LegacyNoInterfaceObject
] extended attribute was not specified on interface , then:-
Let constructor be the interface object of interface in realm .
-
Let desc be the PropertyDescriptor{[[Writable]]:
true , [[Enumerable]]:false , [[Configurable]]:true , [[Value]]: constructor }. -
Perform ! DefinePropertyOrThrow ( interfaceProtoObj , "
constructor
", desc ).
-
-
Return interfaceProtoObj .
Additionally, interface prototype objects get properties declaratively from:
Define those properties imperatively instead.
The
interface
prototype
object
of
an
interface
that
is
defined
with
the
[
LegacyNoInterfaceObject
]
extended
attribute
will
be
accessible.
For
example,
with
the
following
IDL:
[Exposed =Window ,LegacyNoInterfaceObject ]interface Foo { };partial interface Window {attribute Foo foo ; };
it
is
not
possible
to
access
the
interface
prototype
object
through
the
interface
object
(since
it
does
not
exist
as
window.Foo
).
However,
an
instance
of
Foo
can
expose
the
interface
prototype
object
by
calling
its
[[GetPrototypeOf]]
internal
method
–
Object.getPrototypeOf(window.foo)
in
this
example.
The
class
string
of
an
interface
prototype
object
is
the
concatenation
of
the
interface
’s
qualified
name
and
the
string
"
Prototype
".
.
3.7.4. Named properties object
For
every
interface
declared
with
the
[
Global
]
extended
attribute
that
supports
named
properties
,
there
will
exist
an
object
known
as
the
named
properties
object
for
that
interface
on
which
named
properties
are
exposed.
-
Let proto be null.
-
If interface is declared to inherit from another interface, then set proto to the interface prototype object in realm for the inherited interface .
-
Otherwise, set proto to realm .[[Intrinsics]].[[
%ObjectPrototype%
]]. -
Let obj be ! MakeBasicObject (« [[Prototype]], [[Extensible]] »).
-
Set obj .[[GetOwnProperty]] as specified in § 3.7.4.1 [[GetOwnProperty]] .
-
Set obj .[[DefineOwnProperty]] as specified in § 3.7.4.2 [[DefineOwnProperty]] .
-
Set obj .[[Delete]] as specified in § 3.7.4.3 [[Delete]] .
-
Set obj .[[SetPrototypeOf]] as specified in § 3.7.4.4 [[SetPrototypeOf]] .
-
Set obj .[[PreventExtensions]] as specified in § 3.7.4.5 [[PreventExtensions]] .
-
Set obj .[[Prototype]] to proto .
-
Return obj .
The
class
string
of
a
named
properties
object
is
the
concatenation
of
the
interface
’s
identifier
and
the
string
"
Properties
".
3.7.4.1. [[GetOwnProperty]]
When the [[GetOwnProperty]] internal method of a named properties object O is called with property key P , the following steps are taken:
-
Let A be the interface for the named properties object O .
-
Let object be O .[[Realm]]'s global object .
-
Assert: object implements A .
-
If the result of running the named property visibility algorithm with property name P and object object is true, then:
-
Let operation be the operation used to declare the named property getter.
-
Let value be an uninitialized variable.
-
If operation was defined without an identifier , then set value to the result of performing the steps listed in the interface description to determine the value of a named property with P as the name.
-
Otherwise, operation was defined with an identifier. Set value to the result of performing the steps listed in the description of operation with P as the only argument value.
-
Let desc be a newly created Property Descriptor with no fields.
-
Set desc .[[Value]] to the result of converting value to an ECMAScript value.
-
If A implements an interface with the [
LegacyUnenumerableNamedProperties
] extended attribute , then set desc .[[Enumerable]] tofalse , otherwise set it totrue . -
Set desc .[[Writable]] to
true and desc .[[Configurable]] totrue . -
Return desc .
-
-
Return OrdinaryGetOwnProperty ( O , P ).
3.7.4.2. [[DefineOwnProperty]]
When the [[DefineOwnProperty]] internal method of a named properties object is called, the following steps are taken:
-
Return
false .
3.7.4.3. [[Delete]]
When the [[Delete]] internal method of a named properties object is called, the following steps are taken:
-
Return
false .
3.7.4.4. [[SetPrototypeOf]]
When the [[SetPrototypeOf]] internal method of a named properties object O is called with ECMAScript language value V , the following step is taken:
-
Return ? SetImmutablePrototype ( O , V ).
3.7.4.5. [[PreventExtensions]]
When the [[PreventExtensions]] internal method of a named properties object is called, the following steps are taken:
-
Return
false .
Note: this keeps named properties object extensible by making [[PreventExtensions]] fail.
3.7.5. Constants
Constants
are
exposed
on
interface
objects
,
legacy
callback
interface
objects
,
interface
prototype
objects
,
and
on
the
single
object
that
implements
the
interface,
when
an
interface
is
declared
with
the
[
Global
]
extended
attribute
.
-
For each constant const that is a member of definition :
-
Let value be the result of converting const ’s IDL value to an ECMAScript value.
-
Let desc be the PropertyDescriptor{[[Writable]]:
false , [[Enumerable]]:true , [[Configurable]]:false , [[Value]]: value }. -
Let id be const ’s identifier .
-
Perform ! DefinePropertyOrThrow ( target , id , desc ).
3.7.6. Attributes
Static
attributes
are
exposed
on
the
interface
object
.
Regular
attributes
are
exposed
on
the
interface
prototype
object
,
unless
the
attribute
is
unforgeable
or
if
the
interface
was
declared
with
the
[
Global
]
extended
attribute
,
in
which
case
they
are
exposed
on
every
object
that
implements
the
interface.
-
Let attributes be the list of regular attributes that are members of definition .
-
Remove from attributes all the attributes that are unforgeable .
-
Define the attributes attributes of definition on target given realm .
-
Let attributes be the list of static attributes that are members of definition .
-
Define the attributes attributes of definition on target given realm .
-
Let attributes be the list of unforgeable regular attributes that are members of definition .
-
Define the attributes attributes of definition on target given realm .
-
For each attribute attr of attributes :
-
Let getter be the result of creating an attribute getter given attr , definition , and realm .
-
Let setter be the result of creating an attribute setter given attr , definition , and realm .
Note: the algorithm to create an attribute setter returns
undefined if attr is read only . -
Let configurable be
false if attr is unforgeable andtrue otherwise. -
Let desc be the PropertyDescriptor{[[Get]]: getter , [[Set]]: setter , [[Enumerable]]:
true , [[Configurable]]: configurable }. -
Let id be attr ’s identifier .
-
Perform ! DefinePropertyOrThrow ( target , id , desc ).
-
If attr ’s type is an observable array type with type argument T , then set target ’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm , given T , attr ’s set an indexed value algorithm, and attr ’s delete an indexed value algorithm.
The attribute getter is created as follows, given an attribute attribute , a namespace or interface target , and a Realm realm :
-
Let steps be the following series of steps:
-
Try running the following steps:
-
Let idlObject be null.
-
If target is an interface , and attribute is a regular attribute :
-
Let esValue be the
this value, if it is notnull orundefined , or realm ’s global object otherwise. (This will subsequently cause aTypeError
in a few steps, if the global object does not implement target and [LegacyLenientThis
] is not specified.) -
If esValue is a platform object , then perform a security check , passing esValue , attribute ’s identifier , and "getter".
-
If esValue does not implement target , then:
-
If attribute was specified with the [
LegacyLenientThis
] extended attribute , then returnundefined .
-
-
If attribute ’s type is an observable array type , then return esValue ’s backing observable array exotic object for attribute .
-
Set idlObject to the IDL interface type value that represents a reference to esValue .
-
-
Let R be the result of getting the underlying value of attribute given idlObject .
-
Return the result of converting R to an ECMAScript value of the type attribute is declared as.
-
And then, if an exception E was thrown :
-
If attribute ’s type is a promise type , then return ! Call (
%Promise_reject%
,%Promise%
, « E »). -
Otherwise, end these steps and allow the exception to propagate.
-
-
Let F be ! CreateBuiltinFunction ( steps , « », realm ).
-
Let name be the string "
get
" prepended to attribute ’s identifier . -
Perform ! SetFunctionName ( F , name ).
-
Perform ! SetFunctionLength ( F , 0).
-
Return F .
The attribute setter is created as follows, given an attribute attribute , a namespace or interface target , and a Realm realm :
-
If target is a namespace :
-
Assert: attribute is read only .
-
Return
undefined .
-
-
If attribute is read only and does not have a [
LegacyLenientSetter
], [PutForwards
] or [Replaceable
] extended attribute , returnundefined ; there is no attribute setter function. -
Assert: attribute ’s type is not a promise type .
-
Let steps be the following series of steps:
-
Let V be the value of the first argument passed.
-
Let id be attribute ’s identifier .
-
Let idlObject be null.
-
If attribute is a regular attribute :
-
Let esValue be the
this value, if it is notnull orundefined , or realm ’s global object otherwise. (This will subsequently cause aTypeError
in a few steps, if the global object does not implement target and [LegacyLenientThis
] is not specified.) -
If esValue is a platform object , then perform a security check , passing esValue , id , and "setter".
-
Let validThis be true if esValue implements target , or false otherwise.
-
If validThis is false and attribute was not specified with the [
LegacyLenientThis
] extended attribute , then throw aTypeError
. -
If attribute is declared with the [
Replaceable
] extended attribute, then:-
Perform ? CreateDataProperty ( esValue , id , V ).
-
Return
undefined .
-
-
If validThis is false, then return
undefined . -
If attribute is declared with a [
LegacyLenientSetter
] extended attribute, then returnundefined . -
If attribute is declared with a [
PutForwards
] extended attribute, then: -
Set idlObject to the IDL interface type value that represents a reference to esValue .
-
If attribute ’s type is an observable array type with type argument T :
-
Let newValues be the result of converting V to an IDL value of type sequence< T > .
-
Let oa be idlObject ’s attribute ’s backing observable array exotic object .
-
Set the length of oa .[[ProxyHandler]] to 0.
-
Let i be 0.
-
While i < newValues ’s size :
-
Perform the algorithm steps given by oa .[[ProxyHandler]].[[SetAlgorithm]], given newValues [ i ] and i .
-
Append newValues [ i ] to oa .[[ProxyHandler]].[[BackingList]].
-
-
Return
undefined .
-
-
-
Let idlValue be determined as follows:
- attribute ’s type is an enumeration
-
-
If S is not one of the enumeration’s values , then return
undefined . -
Otherwise, idlValue is the enumeration value equal to S .
- Otherwise
- idlValue is the result of converting V to an IDL value of attribute ’s type.
-
Perform the actions listed in the description of attribute that occur on setting, with idlValue as the given value and idlObject as this if it is not null.
-
Return
undefined
-
Let F be ! CreateBuiltinFunction ( steps , « », realm ).
-
Let name be the string "
set
" prepended to id . -
Perform ! SetFunctionName ( F , name ).
-
Perform ! SetFunctionLength ( F , 1).
-
Return F .
Note: Although there is only a single property for an IDL attribute, since accessor property getters and setters are passed a this value for the object on which property corresponding to the IDL attribute is accessed, they are able to expose instance-specific data.
Note:
Attempting
to
assign
to
a
property
corresponding
to
a
read
only
attribute
results
in
different
behavior
depending
on
whether
the
script
doing
so
is
in
strict
mode.
When
in
strict
mode,
such
an
assignment
will
result
in
a
TypeError
being
thrown.
When
not
in
strict
mode,
the
assignment
attempt
will
be
ignored.
3.7.7. Operations
For
each
unique
identifier
of
an
exposed
operation
defined
on
the
interface
,
there
exist
a
corresponding
property.
Static
operations
are
exposed
of
the
interface
object
.
Regular
operations
are
exposed
on
the
interface
prototype
object
,
unless
the
operation
is
unforgeable
or
the
interface
was
declared
with
the
[
Global
]
extended
attribute
,
in
which
case
they
are
exposed
on
every
object
that
implements
the
interface.
-
Let operations be the list of regular operations that are members of definition .
-
Remove from operations all the operations that are unforgeable .
-
Define the operations operations of definition on target given realm .
-
Let operations be the list of static operations that are members of definition .
-
Define the operations operations of definition on target given realm .
-
Let operations be the list of unforgeable regular operations that are members of definition .
-
Define the operations operations of definition on target given realm .
-
For each operation op of operations :
-
Let method be the result of creating an operation function given op , definition , and realm .
-
Let modifiable be
false if op is unforgeable andtrue otherwise. -
Let desc be the PropertyDescriptor{[[Value]]: method , [[Writable]]: modifiable , [[Enumerable]]:
true , [[Configurable]]: modifiable }. -
Let id be op ’s identifier .
-
Perform ! DefinePropertyOrThrow ( target , id , desc ).
-
Let id be op ’s identifier .
-
Let steps be the following series of steps, given function argument values args :
-
Try running the following steps:
-
Let idlObject be null.
-
If target is an interface , and op is not a static operation :
-
Let esValue be the
this value, if it is notnull orundefined , or realm ’s global object otherwise. (This will subsequently cause aTypeError
in a few steps, if the global object does not implement target and [LegacyLenientThis
] is not specified.) -
If esValue is a platform object , then perform a security check , passing esValue , id , and "method".
-
If esValue does not implement the interface target , throw a
TypeError
. -
Set idlObject to the IDL interface type value that represents a reference to esValue .
-
-
Let n be the size of args .
-
Compute the effective overload set for regular operations (if op is a regular operation) or for static operations (if op is a static operation) with identifier id on target and with argument count n , and let S be the result.
-
Let < operation , values > be the result of passing S and args to the overload resolution algorithm .
-
Let R be
null . -
If operation is declared with a [
Default
] extended attribute , then:-
Set R be the result of performing the actions listed in operation ’s corresponding default operation , with values as the argument values and idlObject as this if it is not null.
-
-
Otherwise:
-
Set R be the result of performing the actions listed in the description of operation , with values as the argument values and idlObject as this if it is not null.
-
-
Return R , converted to an ECMAScript value .
R is assumed to be an IDL value of the type op is declared to return. <https://github.com/heycam/webidl/issues/674>
-
And then, if an exception E was thrown :
-
If op has a return type that is a promise type , then return ! Call (
%Promise_reject%
,%Promise%
, « E »). -
Otherwise, end these steps and allow the exception to propagate.
-
-
Let F be ! CreateBuiltinFunction ( steps , « », realm ).
-
Perform ! SetFunctionName ( F , id ).
-
Compute the effective overload set for regular operations (if op is a regular operation) or for static operations (if op is a static operation) with identifier id on target and with argument count 0, and let S be the result.
-
Let length be the length of the shortest argument list in the entries in S .
-
Perform ! SetFunctionLength ( F , length ).
-
Return F .
3.7.7.1. Default operations
Only
regular
operations
which
have
a
corresponding
default
operation
defined
below
may
be
declared
with
a
[
Default
]
extended
attribute
.
3.7.7.1.1. Default toJSON operation
The
corresponding
default
operation
of
the
toJSON
operation
is
the
default
toJSON
operation
.
The
return
type
of
the
default
toJSON
operation
must
be
object
.
To invoke the default toJSON operation of interface I , run the the following steps:
-
Let map be a new ordered map .
-
Let stack be the result of creating an inheritance stack for interface I .
-
Invoke collect attribute values of an inheritance stack on this , passing it stack and map as arguments.
-
Let result be ! OrdinaryObjectCreate (
%ObjectPrototype%
). -
For each key → value of map ,
-
Let k be key converted to an ECMAScript value .
-
Let v be value converted to an ECMAScript value .
-
Perform ! CreateDataProperty ( result , k , v ).
-
-
Return result .
To invoke the collect attribute values of an inheritance stack abstract operation with stack stack and ordered map map as arguments, run the the following steps:
-
Let I be the result of popping from stack .
-
Invoke collect attribute values on this , passing it I and map as arguments.
-
If stack is not empty , then invoke collect attribute values of an inheritance stack on this , passing it stack and map as arguments.
To invoke the collect attribute values abstract operation with interface I and ordered map map as arguments, run the the following steps:
-
If a
toJSON
operation with a [Default
] extended attribute is declared on I , then for each exposed regular attribute attr that is an interface member of I , in order:-
Let id be the identifier of attr .
-
Let value be the result of getting the underlying value of attr given this .
-
To create an inheritance stack for interface I , run the the following steps:
The
following
IDL
fragment
defines
a
number
of
interfaces
,
which
are
inherited
interfaces
of
A
,
and
interface
mixins
,
which
are
included
by
A
or
by
A
’s
inherited
interfaces
,
as
show
in
the
below
inheritance
tree.
C* - M4 | B - M3 | M1 - A - M2*
Interfaces
and
interface
mixins
marked
with
an
asterisk
("*")
declare
a
toJSON
operation
with
a
[
Default
]
extended
attribute
.
[Exposed=Window] interface A : B { attribute DOMString a; }; [Exposed=Window] interface B : C { attribute DOMString b; }; [Exposed=Window] interface C { [Default] object toJSON(); attribute DOMString c; }; interface mixin M1 { attribute DOMString m1; }; interface mixin M2 { [Default] object toJSON(); attribute DOMString m2; }; interface mixin M3 { attribute DOMString m3; }; interface mixin M4 { attribute DOMString m4; }; A includes M1; A includes M2; B includes M3; C includes M4;
Calling
the
toJSON()
method
of
an
object
implementing
interface
A
defined
above
would
return
the
following
JSON
object:
{ "a" : "..." , "m1" : "..." , "m2" : "..." , "c" : "..." , "m4" : "..." }
An
object
implementing
interface
B
would
return:
{ "c" : "..." , "m4" : "..." }
3.7.7.2. Stringifiers
If the interface has an exposed stringifier , then there must exist a property with the following characteristics:
-
The name of the property is "
toString
". -
If the stringifier is unforgeable on the interface or if the interface was declared with the [
Global
] extended attribute , then the property exists on every object that implements the interface. Otherwise, the property exists on the interface prototype object . -
The property has attributes { [[Writable]]: B , [[Enumerable]]:
true , [[Configurable]]: B }, where B isfalse if the stringifier is unforgeable on the interface, andtrue otherwise. -
The value of the property is a built-in function object , which behaves as follows:
-
Let O be the result of calling ToObject on the
this value. -
If O is a platform object , then perform a security check , passing:
-
the platform object O ,
-
the identifier of the stringifier , and
-
the type "
method
".
-
-
If O does not implement the interface on which the stringifier was declared, then throw a
TypeError
. -
Let V be an uninitialized variable.
-
Depending on where
stringifier
was specified:- on an attribute
-
Set V to the result of performing the actions listed in the description of the attribute that occur when getting (or those listed in the description of the inherited attribute, if this attribute is declared to inherit its getter ), with O as the object.
- on an operation with an identifier
-
Set V to the result of performing the actions listed in the description of the operation, using O as the
this value and passing no arguments. - on an operation with no identifier
-
Set V to the result of performing the stringification behavior of the interface.
-
Return the result of converting V to a String value.
-
-
The value of the function object ’s
length
property is the Number value0 . -
The value of the function object ’s
name
property is the String value "toString
".
3.7.8. Maplike and setlike iterator behavior
3.7.8.1. @@iterator
If
the
interface
has
a
maplike
declaration
or
a
setlike
declaration
,
then
a
property
must
exist
whose
name
is
the
@@iterator
symbol,
with
attributes
{
[[Writable]]:
The location of the property is determined as follows:
-
If the interface was declared with the [
Global
] extended attribute , then the property exists on the single object that implements the interface. -
Otherwise, the property exists solely on the interface’s interface prototype object .
If the interface has a maplike declaration or setlike declaration , then the function object is a built-in function object that, when invoked, must behave as follows:
-
Let object be the result of calling ToObject on the
this value. -
If object is a platform object , then perform a security check , passing:
-
the platform object object ,
-
the identifier "
@@iterator
", and -
the type "
method
".
-
-
If object does not implement the interface on which the maplike declaration or setlike declaration is defined, then throw a
TypeError
. -
If the interface has a maplike declaration , then:
-
Let backing be the value of the [[BackingMap]] internal slot of object .
-
Return CreateMapIterator ( backing , "
key+value
").
-
-
Otherwise:
-
Let backing be the value of the [[BackingSet]] internal slot of object .
-
Return CreateSetIterator ( backing , "
value
").
-
The
value
of
the
@@iterator
function
object
’s
length
property
is
the
Number
value
The
value
of
the
@@iterator
function
object
’s
name
property
is
the
String
value
"
entries
"
if
the
interface
has
a
maplike
declaration
and
the
String
"
values
"
if
the
interface
has
a
setlike
declaration
.
3.7.8.2. forEach
If
the
interface
has
a
maplike
declaration
or
a
setlike
declaration
,
then
a
forEach
data
property
must
exist
with
attributes
{
[[Writable]]:
The location of the property is determined as follows:
-
If the interface was declared with the [
Global
] extended attribute , then the property exists on the single object that implements the interface. -
Otherwise, the property exists solely on the interface’s interface prototype object .
If the interface has a maplike declaration or setlike declaration then the method, when invoked, must behave as follows:
-
Let object be the result of calling ToObject on the
this value. -
If object is a platform object , then perform a security check , passing:
-
the platform object object ,
-
the identifier "
forEach
", and -
the type "
method
".
-
-
Let interface be the interface on which the maplike declaration or setlike declaration is declared.
-
If object does not implement interface , then throw a
TypeError
. -
Let callbackFn be the value of the first argument passed to the function, or
undefined if the argument was not supplied. -
If IsCallable ( callbackFn ) is
false , throw aTypeError
. -
Let thisArg be the value of the second argument passed to the function, or
undefined if the argument was not supplied. -
Let backing be the value of the [[BackingMap]] internal slot of object , if the interface has a maplike declaration , or the [[BackingSet]] internal slot of object otherwise.
-
Let callbackWrapper be a built-in function object that, when invoked, behaves as follows:
-
Let v and k be the first two arguments passed to the function.
-
Let thisArg be the
this value. -
Perform ? Call ( callbackFn , thisArg , « v , k , object »).
Note: The callbackWrapper function simply calls the incoming callbackFn with object as the third argument rather than its internal [[BackingMap]] or [[BackingSet]] object.
Can the script author observe that callbackWrapper might be a new function every time forEach is called? What’s the best way of specifying that there’s only one function that has captured an environment?
-
-
Perform ? Call ( forEach , backing , « callbackWrapper , thisArg »).
-
Return
undefined .
The
value
of
the
function
object
’s
length
property
is
the
Number
value
The
value
of
the
function
object
’s
name
property
is
the
String
value
"
forEach
".
3.7.9. Iterable declarations
-
If definition has an indexed property getter , then:
-
Perform ! CreateMethodProperty ( target ,
@@iterator
,%ArrayProto_values%
). -
If definition has a value iterator , then:
-
Perform ! CreateDataProperty ( target , "
entries
",%ArrayProto_entries%
). -
Perform ! CreateDataProperty ( target , "
keys
",%ArrayProto_keys%
). -
Perform ! CreateDataProperty ( target , "
values
",%ArrayProto_values%
). -
Perform ! CreateDataProperty ( target , "
forEach
",%ArrayProto_forEach%
).
-
-
-
Otherwise, if definition has a pair iterator , then:
-
Define the
@@iterator
andentries
methods:-
Let steps be the following series of steps:
-
If esValue is a platform object , then perform a security check , passing esValue , "
@@iterator
", and "method
". -
If esValue does not implement definition , then throw a
TypeError
. -
Return a newly created default iterator object for definition , with esValue as its target , "
key+value
" as its kind , and index set to 0.
-
Let F be ! CreateBuiltinFunction ( steps , « », realm ).
-
Perform ! SetFunctionName ( F , "
entries
"). -
Perform ! SetFunctionLength ( F , 0).
-
Perform ! CreateMethodProperty ( target ,
@@iterator
, F ). -
Perform ! CreateDataProperty ( target , "
entries
", F ).
-
-
Define the
keys
method:-
Let steps be the following series of steps:
-
If esValue is a platform object , then perform a security check , passing esValue , "
keys
", and "method
". -
If esValue does not implement definition , then throw a
TypeError
. -
Return a newly created default iterator object for definition , with esValue as its target , "
key
" as its kind , and index set to 0.
-
Let F be ! CreateBuiltinFunction ( steps , « », realm ).
-
Perform ! SetFunctionName ( F , "
keys
"). -
Perform ! SetFunctionLength ( F , 0).
-
Perform ! CreateDataProperty ( target , "
keys
", F ).
-
-
Define the
values
method:-
Let steps be the following series of steps:
-
If esValue is a platform object , then perform a security check , passing esValue , "
values
", and "method
". -
If esValue does not implement definition , then throw a
TypeError
. -
Return a newly created default iterator object for definition , with esValue as its target , "
value
" as its kind , and index set to 0.
-
Let F be ! CreateBuiltinFunction ( steps , « », realm ).
-
Perform ! SetFunctionName ( F , "
values
"). -
Perform ! SetFunctionLength ( F , 0).
-
Perform ! CreateDataProperty ( target , "
values
", F ).
-
-
Define the
forEach
method:-
Let steps be the following series of steps, given function argument values callback and thisArg :
-
If esValue is a platform object , then perform a security check , passing esValue , "
forEach
", and "method
". -
If esValue does not implement definition , then throw a
TypeError
. -
Let idlObject be the IDL interface type value that represents a reference to esValue .
-
Let pairs be idlObject ’s list of value pairs to iterate over .
-
Let i be 0.
-
While i < pairs ’s size :
-
Let pair be pairs [ i ].
-
Invoke idlCallback with « pair ’s value , pair ’s key , idlObject » and with thisArg as the callback this value .
-
Set pairs to idlObject ’s current list of value pairs to iterate over . (It might have changed.)
-
Set i to i + 1.
-
-
Let F be ! CreateBuiltinFunction ( steps , « », realm ).
-
Perform ! SetFunctionName ( F , "
forEach
"). -
Perform ! SetFunctionLength ( F , 1).
-
Perform ! CreateDataProperty ( target , "
forEach
", F ).
-
-
3.7.9.1. Default iterator objects
A default iterator object for a given interface , target and iteration kind is an object whose [[Prototype]] internal slot is the iterator prototype object for the interface .
A default iterator object has three internal values:
-
its target , which is an object whose values are to be iterated,
-
its kind , which is the iteration kind,
-
its index , which is the current index into the values to be iterated.
Note: Default iterator objects are only used for pair iterators ; value iterators , as they are currently restricted to iterating over an object’s supported indexed properties , use standard ECMAScript Array iterator objects.
Note:
Default
iterator
objects
do
not
have
class
strings
;
when
Object.prototype.toString()
is
called
on
a
default
iterator
object
of
a
given
interface
,
the
class
string
of
the
iterator
prototype
object
of
that
interface
is
used.
3.7.9.2. Iterator prototype object
The iterator prototype object for a given interface is an object that exists for every interface that has a pair iterator . It serves as the prototype for default iterator objects for the interface.
The
[[Prototype]]
internal
slot
of
an
iterator
prototype
object
must
be
%IteratorPrototype%
.
-
Let result be a value determined by the value of kind :
-
"
key
" -
-
Let idlKey be pair ’s key .
-
Let key be the result of converting idlKey to an ECMAScript value.
-
result is key .
-
-
"
value
" -
-
Let idlValue be pair ’s value .
-
Let value be the result of converting idlValue to an ECMAScript value.
-
result is value .
-
-
"
key+value
" -
-
Let idlKey be pair ’s key .
-
Let idlValue be pair ’s value .
-
Let key be the result of converting idlKey to an ECMAScript value.
-
Let value be the result of converting idlValue to an ECMAScript value.
-
Let array be the result of performing ArrayCreate (2).
-
Call CreateDataProperty ( array , "
0
", key ). -
Call CreateDataProperty ( array , "
1
", value ). -
result is array .
-
-
"
-
Return CreateIterResultObject ( result ,
false ).
An
iterator
prototype
object
must
have
a
next
data
property
with
attributes
{
[[Writable]]:
-
Let interface be the interface for which the iterator prototype object exists.
-
Let object be the result of calling ToObject on the
this value. -
If object is a platform object , then perform a security check , passing:
-
the platform object object ,
-
the identifier "
next
", and -
the type "
method
".
-
-
If object is not a default iterator object for interface , then throw a
TypeError
. -
Let index be object ’s index .
-
Let kind be object ’s kind .
-
Let values be object ’s target 's value pairs to iterate over .
-
Let len be the length of values .
-
If index is greater than or equal to len , then return CreateIterResultObject (
undefined ,true ). -
Let pair be the entry in values at index index .
-
Set object ’s index to index + 1.
-
Return the iterator result for pair and kind .
The
class
string
of
an
iterator
prototype
object
for
a
given
interface
is
the
result
of
concatenating
the
identifier
of
the
interface
and
the
string
"
Iterator
".
3.7.10. Asynchronous iterable declarations
-
If definition does not have an an asynchronously iterable declaration (of either sort), then return.
-
Assert: definition does not have an indexed property getter or an iterable declaration .
-
If definition has a pair asynchronously iterable declaration , then define the
@@asyncIterator
andentries
methods:-
Let steps be the following series of steps, given function argument values args :
-
If esValue is a platform object , then perform a security check , passing esValue , "
@@asyncIterator
", and "method
". -
If esValue does not implement definition , then throw a
TypeError
. -
Let idlObject be the IDL interface type value that represents a reference to esValue .
-
Let idlArgs be the result of converting arguments for an asynchronous iterator method given args .
-
Let iterator be a newly created default asynchronous iterator object for definition with idlObject as its target , "
key+value
" as its kind , and is finished set to false. -
Run the asynchronous iterator initialization steps for definition with idlObject , iterator , and idlArgs , if any such steps exist.
-
Return iterator .
-
Let F be ! CreateBuiltinFunction ( steps , « », realm ).
-
Perform ! SetFunctionName ( F , "
entries
"). -
Perform ! SetFunctionLength ( F , 0).
-
Perform ! CreateMethodProperty ( target ,
@@asyncIterator
, F ). -
Perform ! CreateDataProperty ( target , "
entries
", F ).
-
-
If definition has a pair asynchronously iterable declaration , then define the
keys
method:-
Let steps be the following series of steps, given function argument values args :
-
If esValue is a platform object , then perform a security check , passing esValue , "
keys
", and "method
". -
If esValue does not implement definition , then throw a
TypeError
. -
Let idlObject be the IDL interface type value that represents a reference to esValue .
-
Let idlArgs be the result of converting arguments for an asynchronous iterator method given args .
-
Let iterator be a newly created default asynchronous iterator object for definition with idlObject as its target , "
key
" as its kind , and is finished set to false. -
Run the asynchronous iterator initialization steps for definition with idlObject , iterator , and idlArgs , if any such steps exist.
-
Return iterator .
-
Let F be ! CreateBuiltinFunction ( steps , « », realm ).
-
Perform ! SetFunctionName ( F , "
keys
"). -
Perform ! SetFunctionLength ( F , 0).
-
Perform ! CreateDataProperty ( target , "
keys
", F ).
-
-
Define the
values
, and possibly@@asyncIterator
, methods:-
Let steps be the following series of steps, given function argument values args :
-
If esValue is a platform object , then perform a security check , passing esValue , "
values
", and "method
". -
If esValue does not implement definition , then throw a
TypeError
. -
Let idlObject be the IDL interface type value that represents a reference to esValue .
-
Let idlArgs be the result of converting arguments for an asynchronous iterator method given args .
-
Let iterator be a newly created default asynchronous iterator object for definition with idlObject as its target , "
value
" as its kind , and is finished set to false. -
Run the asynchronous iterator initialization steps for definition with idlObject , iterator , and idlArgs , if any such steps exist.
-
Return iterator .
-
Let F be ! CreateBuiltinFunction ( steps , « », realm ).
-
Perform ! SetFunctionName ( F , "
values
"). -
Perform ! SetFunctionLength ( F , 0).
-
Perform ! CreateDataProperty ( target , "
values
", F ). -
If definition has a value asynchronously iterable declaration , then perform ! CreateMethodProperty ( target ,
@@asyncIterator
, F ).
-
-
Let idlArgs be an empty list.
-
Let argCount be the number of arguments of definition ’s asynchronously iterable declaration , or 0 if the asynchronously iterable declaration does not have an argument list.
-
Let i be 0.
-
While i < argCount :
-
If i ≥ args ’s size , or if args [ i ] is
undefined , then:-
If the argument to the asynchronously iterable declaration at index i is declared with a default value , then append that default value to idlArgs .
-
Otherwise, append to idlArgs the special value "missing".
-
-
Otherwise, append to idlArgs the result of converting args [ i ] to the IDL type given in the asynchronously iterable declaration 's argument list at index i .
-
Set i to i + 1.
-
-
Return idlArgs .
This is essentially a hyper-specialization of the overload resolution algorithm for the case where no overloads are allowed and all arguments are optional.
3.7.10.1. Default asynchronous iterator objects
A default asynchronous iterator object for a given interface , target and iteration kind is an object whose [[Prototype]] internal slot is the asynchronous iterator prototype object for the interface .
A default asynchronous iterator object has internal values:
-
its target , which is an object whose values are to be iterated,
-
its kind , which is the iteration kind,
-
its ongoing promise , which is a
Promise
or null, -
its is finished , which is a boolean.
Note:
Default
asynchronous
iterator
objects
do
not
have
class
strings
;
when
Object.prototype.toString()
is
called
on
a
default
asynchronous
iterator
object
of
a
given
interface
,
the
class
string
of
the
asynchronous
iterator
prototype
object
of
that
interface
is
used.
3.7.10.2. Asynchronous iterator prototype object
The asynchronous iterator prototype object for a given interface is an object that exists for every interface that has an asynchronously iterable declaration . It serves as the prototype for default asynchronous iterator objects for the interface.
The
[[Prototype]]
internal
slot
of
an
asynchronous
iterator
prototype
object
must
be
%AsyncIteratorPrototype%
.
An
asynchronous
iterator
prototype
object
must
have
a
next
data
property
with
attributes
{
[[Writable]]:
-
Let interface be the interface for which the asynchronous iterator prototype object exists.
-
Let thisValidationPromiseCapability be ! NewPromiseCapability (
%Promise%
). -
Let object be the result of calling ToObject on the
this value. -
IfAbruptRejectPromise ( object , thisValidationPromiseCapability ).
-
If object is a platform object , then perform a security check , passing:
-
the platform object object ,
-
the identifier "
next
", and -
the type "
method
".
If this threw an exception e , then:
-
-
If object is not a default asynchronous iterator object for interface , then:
-
Let nextSteps be the following steps:
-
Let nextPromiseCapability be ! NewPromiseCapability (
%Promise%
). -
If object ’s is finished is true, then:
-
Let result be CreateIterResultObject (
undefined ,true ). -
Perform ! Call ( nextPromiseCapability .[[Resolve]],
undefined , « result »). -
Return nextPromiseCapability .[[Promise]].
-
-
Let kind be object ’s kind .
-
Let nextPromise be the result of getting the next iteration result with object ’s target and object .
-
Let fulfillSteps be the following steps, given next :
-
Set object ’s ongoing promise to null.
-
If next is
undefined , then:-
Set object ’s is finished to true.
-
Return ! CreateIterResultObject (
undefined ,true ).
-
-
Otherwise, if interface has a pair asynchronously iterable declaration :
-
Assert: next is a value pair .
-
Return the iterator result for next and kind .
-
-
Otherwise:
-
Assert: interface has a value asynchronously iterable declaration .
-
Assert: next is a value of the type that appears in the declaration.
-
Let value be next , converted to an ECMAScript value .
-
Return ! CreateIterResultObject ( value ,
false ).
-
-
-
Let onFulfilled be ! CreateBuiltinFunction ( fulfillSteps , « »).
-
Perform ! PerformPromiseThen ( nextPromise , onFulfilled ,
undefined , nextPromiseCapability ). -
Return nextPromiseCapability .[[Promise]].
-
-
Let promise be object ’s ongoing promise .
-
If promise is not null, then:
-
Let afterOngoingPromiseCapability be ! NewPromiseCapability (
%Promise%
). -
Let onFulfilled be ! CreateBuiltinFunction ( nextSteps , « »).
-
Perform ! PerformPromiseThen ( promise , onFulfilled ,
undefined , afterOngoingPromiseCapability ). -
Set object ’s ongoing promise to afterOngoingPromiseCapability .[[Promise]].
-
-
Otherwise:
-
Run nextSteps and set object ’s ongoing promise to the result.
-
-
Return object ’s ongoing promise .
If
an
asynchronous
iterator
return
algorithm
is
defined
for
the
interface
,
then
the
asynchronous
iterator
prototype
object
must
have
a
return
data
property
with
attributes
{
[[Writable]]:
-
Let interface be the interface for which the asynchronous iterator prototype object exists.
-
Let returnPromiseCapability be ! NewPromiseCapability (
%Promise%
). -
Let object be the result of calling ToObject on the
this value. -
IfAbruptRejectPromise ( object , returnPromiseCapability ).
-
If object is a platform object , then perform a security check , passing:
-
the platform object object ,
-
the identifier "
return
", and -
the type "
method
".
If this threw an exception e , then:
-
-
If object is not a default asynchronous iterator object for interface , then:
-
If object ’s ongoing promise is not null, then:
-
If object ’s is finished is true, then:
-
Let result be ! CreateIterResultObject ( value ,
true ). -
Perform ! Call ( returnPromiseCapability .[[Resolve]],
undefined , « result »). -
Return returnPromiseCapability .[[Promise]].
-
-
Set object ’s is finished to true.
-
Let returnPromise be the result of running the asynchronous iterator return algorithm for interface , given object ’s target , object , and value .
-
Let fulfillSteps be the following steps:
-
Return ! CreateIterResultObject ( value ,
true ).
-
-
Let onFulfilled be ! CreateBuiltinFunction ( fulfillSteps , « »).
-
Perform ! PerformPromiseThen ( returnPromise , onFulfilled ,
undefined , returnPromiseCapability ). -
Return returnPromiseCapability .[[Promise]].
The
class
string
of
an
asynchronous
iterator
prototype
object
for
a
given
interface
is
the
result
of
concatenating
the
identifier
of
the
interface
and
the
string
"
AsyncIterator
".
3.7.11. Maplike declarations
Any
object
that
implements
an
interface
that
has
a
maplike
declaration
must
have
a
[[BackingMap]]
internal
slot
,
which
is
initially
set
to
a
newly
created
Map
object.
This
Map
object’s
[[MapData]]
internal
slot
is
the
object’s
map
entries
.
If an interface A is declared with a maplike declaration , then there exists a number of additional properties on A ’s interface prototype object . These additional properties are described in the sub-sections below.
Some of the properties below are defined to have a function object value that forwards to the internal map object for a given function name. Such functions behave as follows when invoked:
-
Let O be the
this value. -
Let arguments be the list of arguments passed to this function.
-
Let name be the function name.
-
If O is a platform object , then perform a security check , passing:
-
the platform object O ,
-
an identifier equal to name , and
-
the type "
method
".
-
-
Let map be the
Map
object that is the value of O ’s [[BackingMap]] internal slot .
3.7.11.1. size
There
must
exist
a
size
property
on
A
’s
interface
prototype
object
with
the
following
characteristics:
-
The property has attributes { [[Get]]: G , [[Enumerable]]:
false , [[Configurable]]:true }, where G is the interface’s map size getter , defined below. -
The map size getter is a built-in function object whose behavior when invoked is as follows:
-
Let O be the
this value. -
If O is a platform object , then perform a security check , passing:
-
the platform object O ,
-
the identifier "
size
", and -
the type "
getter
".
-
-
Let map be the
Map
object that is the value of O ’s [[BackingMap]] internal slot . -
Return Get ( map , "
size
").
The value of the function object ’s
length
property is the Number value0 .The value of the function object ’s
name
property is the String value "size
". -
3.7.11.2. entries
An
entries
data
property
must
exist
on
A
’s
interface
prototype
object
with
attributes
{
[[Writable]]:
@@iterator
property.
3.7.11.3. keys and values
For
both
of
keys
and
values
,
there
must
exist
a
data
property
with
that
name
on
A
’s
interface
prototype
object
with
the
following
characteristics:
-
The property has attributes { [[Writable]]:
true , [[Enumerable]]:false , [[Configurable]]:true }. -
The value of the property is a built-in function object that forwards that name to the internal map object .
The
value
of
the
function
objects
’
length
properties
is
the
Number
value
The
value
of
the
function
object
’s
name
property
is
the
String
value
"
keys
"
or
"
values
",
correspondingly.
3.7.11.4. get and has
For
both
of
get
and
has
,
there
must
exist
a
data
property
with
that
name
on
A
’s
interface
prototype
object
with
the
following
characteristics:
-
The property has attributes { [[Writable]]:
true , [[Enumerable]]:false , [[Configurable]]:true }. -
The value of the property is a built-in function object that behaves as follows when invoked:
-
Let O be the
this value. -
Let name be the name of the property – "
get
" or "has
". -
If O is a platform object , then perform a security check , passing:
-
the platform object O ,
-
an identifier equal to name , and
-
the type "
method
".
-
-
Let map be the
Map
object that is the value of O ’s [[BackingMap]] internal slot . -
Let keyType be the key type specified in the maplike declaration .
-
Let keyArg be the first argument passed to this function, or
undefined if not supplied. -
Let keyIDL be the result of converting keyArg to an IDL value of type keyType .
-
Let key be the result of converting keyIDL to an ECMAScript value.
-
The
value
of
the
function
object
’s
length
properties
is
the
Number
value
The
value
of
the
function
object
’s
name
property
is
the
String
value
"
get
"
or
"
has
",
correspondingly.
3.7.11.5. clear
If
A
does
not
declare
a
member
with
identifier
"
clear
",
and
A
was
declared
with
a
read–write
maplike
declaration,
then
a
clear
data
property
with
the
following
characteristics
must
exist
on
A
’s
interface
prototype
object
:
-
The property has attributes { [[Writable]]:
true , [[Enumerable]]:false , [[Configurable]]:true }. -
The value of the property is a built-in function object that forwards
clear
to the internal map object .
The
value
of
the
function
object
’s
length
property
is
the
Number
value
The
value
of
the
function
object
’s
name
property
is
the
String
value
"
clear
".
3.7.11.6. delete
If
A
does
not
declare
a
member
with
identifier
"
delete
",
and
A
was
declared
with
a
read–write
maplike
declaration,
then
a
delete
data
property
with
the
following
characteristics
must
exist
on
A
’s
interface
prototype
object
:
-
The property has attributes { [[Writable]]:
true , [[Enumerable]]:false , [[Configurable]]:true }. -
The value of the property is a built-in function object that behaves as follows when invoked:
-
Let O be the
this value. -
If O is a platform object , then perform a security check , passing:
-
the platform object O ,
-
the identifier "
delete
", and -
the type "
method
".
-
-
Let map be the
Map
object that is the value of O ’s [[BackingMap]] internal slot . -
Let keyType be the key type specified in the maplike declaration .
-
Let keyArg be the first argument passed to this function, or
undefined if not supplied. -
Let keyIDL be the result of converting keyArg to an IDL value of type keyType .
-
Let key be the result of converting keyIDL to an ECMAScript value.
-
The
value
of
the
function
object
’s
length
property
is
the
Number
value
The
value
of
the
function
object
’s
name
property
is
the
String
value
"
delete
".
3.7.11.7. set
If
A
does
not
declare
a
member
with
identifier
"
set
",
and
A
was
declared
with
a
read–write
maplike
declaration,
then
a
set
data
property
with
the
following
characteristics
must
exist
on
A
’s
interface
prototype
object
:
-
The property has attributes { [[Writable]]:
true , [[Enumerable]]:false , [[Configurable]]:true }. -
The value of the property is a built-in function object that behaves as follows when invoked:
-
Let O be the
this value. -
If O is a platform object , then perform a security check , passing:
-
the platform object O ,
-
the identifier "
set
", and -
the type "
method
".
-
-
Let map be the
Map
object that is the value of O ’s [[BackingMap]] internal slot . -
Let keyType and valueType be the key and value types specified in the maplike declaration .
-
Let keyArg be the first argument passed to this function, or
undefined if not supplied. -
Let valueArg be the second argument passed to this function, or
undefined if not supplied. -
Let keyIDL be the result of converting keyArg to an IDL value of type keyType .
-
Let valueIDL be the result of converting valueArg to an IDL value of type valueType .
-
Let key be the result of converting keyIDL to an ECMAScript value.
-
Let value be the result of converting valueIDL to an ECMAScript value.
-
Return O .
-
The
value
of
the
function
object
’s
length
property
is
the
Number
value
The
value
of
the
function
object
’s
name
property
is
the
String
value
"
set
".
3.7.12. Setlike declarations
Any
object
that
implements
an
interface
that
has
a
setlike
declaration
must
have
a
[[BackingSet]]
internal
slot
,
which
is
initially
set
to
a
newly
created
Set
object.
This
Set
object’s
[[SetData]]
internal
slot
is
the
object’s
set
entries
.
If an interface A is declared with a setlike declaration , then there exists a number of additional properties on A ’s interface prototype object . These additional properties are described in the sub-sections below.
Some of the properties below are defined to have a built-in function object value that forwards to the internal set object for a given function name. Such functions behave as follows when invoked:
-
Let O be the
this value. -
Let arguments be the list of arguments passed to this function.
-
Let name be the function name.
-
If O is a platform object , then perform a security check , passing:
-
the platform object O ,
-
an identifier equal to name , and
-
the type "
method
".
-
-
Let set be the
Set
object that is the value of O ’s [[BackingSet]] internal slot .
3.7.12.1. size
A
size
property
must
exist
on
A
’s
interface
prototype
object
with
the
following
characteristics:
-
The property has attributes { [[Get]]: G , [[Enumerable]]:
false , [[Configurable]]:true }, where G is the interface’s set size getter , defined below. -
The set size getter is a built-in function object whose behavior when invoked is as follows:
-
Let O be the
this value. -
If O is a platform object , then perform a security check , passing:
-
the platform object O ,
-
the identifier "
size
", and -
the type "
getter
".
-
-
Let set be the
Set
object that is the value of O ’s [[BackingSet]] internal slot . -
Return the result of calling the [[Get]] internal method of set passing "
size
" and set as arguments.
The value of the function object ’s
length
property is the Number value0 .The value of the function object ’s
name
property is the String value "size
". -
3.7.12.2. values
A
values
data
property
must
exist
on
A
’s
interface
prototype
object
with
attributes
{
[[Writable]]:
@@iterator
property.
3.7.12.3. entries and keys
For
both
of
entries
and
keys
,
there
must
exist
a
data
property
with
that
name
on
A
’s
interface
prototype
object
with
the
following
characteristics:
-
The property has attributes { [[Writable]]:
true , [[Enumerable]]:false , [[Configurable]]:true }. -
The value of the property is a built-in function object that forwards that name to the internal set object .
The
value
of
the
function
object
’s
length
properties
is
the
Number
value
The
value
of
the
function
object
’s
name
property
is
the
String
value
"
entries
"
or
"
keys
",
correspondingly.
3.7.12.4. has
There
must
exist
a
has
data
property
on
A
’s
interface
prototype
object
with
the
following
characteristics:
-
The property has attributes { [[Writable]]:
true , [[Enumerable]]:false , [[Configurable]]:true }. -
The value of the property is a built-in function object that behaves as follows when invoked:
-
Let O be the
this value. -
If O is a platform object , then perform a security check , passing:
-
the platform object O ,
-
the identifier "
has
", and -
the type "
method
".
-
-
Let set be the
Set
object that is the value of O ’s [[BackingSet]] internal slot . -
Let type be the value type specified in the setlike declaration .
-
Let arg be the first argument passed to this function, or
undefined if not supplied. -
Let idlValue be the result of converting arg to an IDL value of type type .
-
Let value be the result of converting idlValue to an ECMAScript value.
-
The
value
of
the
function
object
’s
length
property
is
a
Number
value
The
value
of
the
function
object
’s
name
property
is
the
String
value
"
has
".
3.7.12.5. add and delete
For
both
of
add
and
delete
,
if:
-
A does not declare an member with a matching identifier, and
-
A was declared with a read–write setlike declaration,
then a data property with that name and the following characteristics must exist on A ’s interface prototype object :
-
The property has attributes { [[Writable]]:
true , [[Enumerable]]:false , [[Configurable]]:true }. -
The value of the property is a built-in function object that behaves as follows when invoked:
-
Let O be the
this value. -
Let name be the name of the property – "
add
" or "delete
". -
If O is a platform object , then perform a security check , passing:
-
the platform object O ,
-
an identifier equal to name , and
-
the type "
method
".
-
-
Let set be the
Set
object that is the value of O ’s [[BackingSet]] internal slot . -
Let type be the value type specified in the setlike declaration .
-
Let arg be the first argument passed to this function, or
undefined if not supplied. -
Let idlValue be the result of converting arg to an IDL value of type type .
-
Let value be the result of converting idlValue to an ECMAScript value.
-
If name is "delete", then return result .
-
Otherwise, return O .
-
The
value
of
the
function
object
’s
length
property
is
the
Number
value
The
value
of
the
function
object
’s
name
property
is
the
String
value
"
add
"
or
"
delete
",
correspondingly.
3.7.12.6. clear
If
A
does
not
declare
a
member
with
a
matching
identifier,
and
A
was
declared
with
a
read–write
setlike
declaration,
then
a
clear
data
property
with
the
following
characteristics
must
exist
on
A
’s
interface
prototype
object
:
-
The property has attributes { [[Writable]]:
true , [[Enumerable]]:false , [[Configurable]]:true }. -
The value of the property is a built-in function object that forwards
clear
to the internal map object .
The
value
of
the
function
object
’s
length
property
is
the
Number
value
The
value
of
the
function
object
’s
name
property
is
the
String
value
"
clear
".
3.8. Platform objects implementing interfaces
Specifications may reference the concept " object implements interface " in various ways, including " object is an interface object".
Every platform object is associated with a Realm , just as the initial objects are. This Realm is stored in the platform object 's [[Realm]] slot. It is the responsibility of specifications using Web IDL to state which Realm (or, by proxy, which global object) each platform object is associated with. In particular, the algorithms below associate the new platform object with the Realm given as an argument.
-
Return the result of internally creating a new object implementing interface , with realm and
undefined .
-
Assert: interface is exposed in realm .
-
If newTarget is
undefined , then:-
Let prototype be the interface prototype object for interface in realm .
-
-
Otherwise:
-
Assert: IsCallable ( newTarget ) is true.
-
If Type ( prototype ) is not Object, then:
-
Let targetRealm be GetFunctionRealm ( newTarget ).
-
Set prototype to the interface prototype object for interface in targetRealm .
-
-
-
Let instance be ! MakeBasicObject ( « [[Prototype]], [[Extensible]], [[Realm]], [[PrimaryInterface]] »).
-
Set instance .[[Realm]] to realm .
-
Set instance .[[PrimaryInterface]] to interface .
-
Set instance .[[Prototype]] to prototype .
-
Let interfaces be the inclusive inherited interfaces of interface .
-
For every interface ancestor interface in interfaces :
-
Let unforgeables be the value of the [[Unforgeables]] slot of the interface object of ancestor interface in realm .
-
Let keys be ! unforgeables .[[OwnPropertyKeys]]().
-
For each element key of keys :
-
Let descriptor be ! unforgeables .[[GetOwnProperty]]( key ).
-
Perform ! DefinePropertyOrThrow ( instance , key , descriptor ).
-
-
-
If interface is declared with the [
Global
] extended attribute , then:-
Define the regular operations of interface on instance , given realm .
-
Define the regular attributes of interface on instance , given realm .
-
Define the iteration methods of interface on instance given realm .
-
Define the asynchronous iteration methods of interface on instance given realm .
-
Define the global property references on instance , given realm .
-
Set instance .[[SetPrototypeOf]] as defined in § 3.8.1 [[SetPrototypeOf]] .
-
-
Otherwise, if interfaces contains an interface which supports indexed properties , named properties , or both:
-
Set instance .[[GetOwnProperty]] as defined in § 3.9.1 [[GetOwnProperty]] .
-
Set instance .[[Set]] as defined in § 3.9.2 [[Set]] .
-
Set instance .[[DefineOwnProperty]] as defined in § 3.9.3 [[DefineOwnProperty]] .
-
Set instance .[[Delete]] as defined in § 3.9.4 [[Delete]] .
-
Set instance .[[PreventExtensions]] as defined in § 3.9.5 [[PreventExtensions]] .
-
Set instance .[[OwnPropertyKeys]] as defined in § 3.9.6 [[OwnPropertyKeys]] .
-
-
Return instance .
-
Let interfaces be a list that contains every interface that is exposed in realm .
-
Sort interfaces in such a way that if A and B are items of interfaces , and A inherits from B , A has a higher index in interfaces than B .
-
For every interface of interfaces :
-
If interface is not declared with the [
LegacyNoInterfaceObject
] or [LegacyNamespace
] extended attributes , then:-
Let id be interface ’s identifier .
-
Let interfaceObject be the result of creating an interface object for interface with id in realm .
-
Perform ! CreateMethodProperty ( target , id , interfaceObject ).
-
If the interface is declared with a [
LegacyWindowAlias
] extended attribute , and target implements theWindow
interface , then:-
For every identifier id in [
LegacyWindowAlias
]'s identifiers :-
Perform ! CreateMethodProperty ( target , id , interfaceObject ).
-
-
-
-
If the interface is declared with a [
LegacyFactoryFunction
] extended attribute , then:-
For every identifier id in [
LegacyFactoryFunction
]'s identifiers :-
Let legacyFactoryFunction be the result of creating a legacy factory function with id for interface in realm .
-
Perform ! CreateMethodProperty ( target , id , legacyFactoryFunction ).
-
-
-
-
For every callback interface interface that is exposed in realm and on which constants are defined:
-
Let id be interface ’s identifier .
-
Let interfaceObject be the result of creating a legacy callback interface object for interface with id in realm .
-
Perform ! CreateMethodProperty ( target , id , interfaceObject ).
-
-
For every namespace namespace that is exposed in realm :
-
Let id be namespace ’s identifier .
-
Let namespaceObject be the result of creating a namespace object for namespace in realm .
-
Perform ! CreateMethodProperty ( target , id , namespaceObject ).
-
Multiple platform objects with different global objects will share a reference to the same interface in their [[PrimaryInterface]] internal slots. For example, a page may contain a same-origin iframe, with the iframe’s method being called on the main page’s element of the same kind, with no exception thrown.
Interface mixins do not participate directly in the evaluation of the implements algorithm. Instead, each interface that the interface mixin is included in has its own "copy" of each member of the interface mixin , and the corresponding operation function checks that the receiver implements the particular interface which includes the interface mixin .
The Realm that a given platform object is associated with can change after it has been created. When the Realm associated with a platform object is changed, its [[Prototype]] internal slot must be immediately updated to be the interface prototype object of the primary interface from the platform object ’s newly associated Realm .
The
class
string
of
a
platform
object
that
implements
one
or
more
interfaces
must
be
the
qualified
name
of
the
primary
interface
of
the
platform
object.
Additionally,
platform
objects
which
implement
an
interface
which
has
a
[
Global
]
extended
attribute
get
properties
declaratively
from:
Define those properties imperatively instead.
3.8.1. [[SetPrototypeOf]]
When
the
[[SetPrototypeOf]]
internal
method
of
a
platform
object
O
that
implements
an
interface
with
the
[
Global
]
extended
attribute
is
called
with
ECMAScript
language
value
V
,
the
following
step
is
taken:
-
Return ? SetImmutablePrototype ( O , V ).
Note:
For
Window
objects,
it
is
unobservable
whether
this
is
implemented,
since
the
presence
of
the
WindowProxy
object
ensures
that
[[SetPrototypeOf]]
is
never
called
on
a
Window
object
directly.
For
other
global
objects,
however,
this
is
necessary.
3.9. Legacy platform objects
Legacy platform objects will appear to have additional properties that correspond to their indexed and named properties . These properties are not “real” own properties on the object, but are made to look like they are by being exposed by the [[GetOwnProperty]] internal method .
It is permissible for an object to implement multiple interfaces that support indexed properties. However, if so, and there are conflicting definitions as to the object’s supported property indices , then it is undefined what additional properties the object will appear to have, or what its exact behavior will be with regard to its indexed properties. The same applies for named properties.
The indexed property getter that is defined on the derived-most interface that the legacy platform object implements is the one that defines the behavior when indexing the object with an array index . Similarly for indexed property setters . This way, the definitions of these special operations from ancestor interfaces can be overridden.
A property name is an unforgeable property name on a given platform object O if the object implements an interface that has an interface member with that identifier and that interface member is unforgeable on any of the interfaces that O implements.
Support for getters is handled in § 3.9.1 [[GetOwnProperty]] , and for setters in § 3.9.3 [[DefineOwnProperty]] and § 3.9.2 [[Set]] .
Additionally, legacy platform objects have internal methods as defined in:
3.9.1. [[GetOwnProperty]]
The [[GetOwnProperty]] internal method of every legacy platform object O must behave as follows when called with property name P :
-
Return LegacyPlatformObjectGetOwnProperty ( O , P ,
false ).
3.9.2. [[Set]]
The [[Set]] internal method of every legacy platform object O must behave as follows when called with property name P , value V , and ECMAScript language value Receiver :
-
If O and Receiver are the same object, then:
-
If O implements an interface with an indexed property setter and P is an array index , then:
-
Invoke the indexed property setter with P and V .
-
Return
true .
-
-
If O implements an interface with a named property setter and Type ( P ) is String, then:
-
Invoke the named property setter with P and V .
-
Return
true .
-
-
-
Let ownDesc be LegacyPlatformObjectGetOwnProperty ( O , P ,
true ). -
Perform ? OrdinarySetWithOwnDescriptor ( O , P , V , Receiver , ownDesc ).
3.9.3. [[DefineOwnProperty]]
When the [[DefineOwnProperty]] internal method of a legacy platform object O is called with property key P and Property Descriptor Desc , the following steps must be taken:
-
If O supports indexed properties and P is an array index , then:
-
If the result of calling IsDataDescriptor ( Desc ) is
false , then returnfalse . -
If O does not implement an interface with an indexed property setter , then return
false . -
Invoke the indexed property setter with P and Desc .[[Value]].
-
Return
true .
-
-
If O supports named properties , O does not implement an interface with the [
Global
] extended attribute , Type ( P ) is String, and P is not an unforgeable property name of O , then:-
Let creating be true if P is not a supported property name , and false otherwise.
-
If O implements an interface with the [
LegacyOverrideBuiltIns
] extended attribute or O does not have an own property named P , then:-
If creating is false and O does not implement an interface with a named property setter , then return
false . -
If O implements an interface with a named property setter , then:
-
If the result of calling IsDataDescriptor ( Desc ) is
false , then returnfalse . -
Invoke the named property setter with P and Desc .[[Value]].
-
Return
true .
-
-
-
-
If O does not implement an interface with the [
Global
] extended attribute , then set Desc .[[Configurable]] totrue . -
Return OrdinaryDefineOwnProperty ( O , P , Desc ).
3.9.4. [[Delete]]
The [[Delete]] internal method of every legacy platform object O must behave as follows when called with property name P .
-
If O supports indexed properties and P is an array index , then:
-
Let index be the result of calling ToUint32 ( P ).
-
If index is not a supported property index , then return
true . -
Return
false .
-
-
If O supports named properties , O does not implement an interface with the [
Global
] extended attribute and the result of calling the named property visibility algorithm with property name P and object O is true, then:-
If O does not implement an interface with a named property deleter , then return
false . -
Let operation be the operation used to declare the named property deleter.
-
If operation was defined without an identifier , then:
-
Perform the steps listed in the interface description to delete an existing named property with P as the name.
-
If the steps indicated that the deletion failed, then return
false .
-
-
Otherwise, operation was defined with an identifier:
-
Perform the steps listed in the description of operation with P as the only argument value.
-
If operation was declared with a return type of
boolean
and the steps returnedfalse , then returnfalse .
-
-
Return
true .
-
-
If O has an own property with name P , then:
-
If the property is not configurable, then return
false . -
Otherwise, remove the property from O .
-
-
Return
true .
3.9.5. [[PreventExtensions]]
When the [[PreventExtensions]] internal method of a legacy platform object is called, the following steps are taken:
-
Return
false .
Note: this keeps legacy platform objects extensible by making [[PreventExtensions]] fail for them.
3.9.6. [[OwnPropertyKeys]]
This document does not define a complete property enumeration order for platform objects implementing interfaces (or for platform objects representing exceptions ). However, it does for legacy platform objects by defining the [[OwnPropertyKeys]] internal method as follows.
When the [[OwnPropertyKeys]] internal method of a legacy platform object O is called, the following steps are taken:
-
Let keys be a new empty list of ECMAScript String and Symbol values.
-
If O supports indexed properties , then for each index of O ’s supported property indices , in ascending numerical order, append ! ToString ( index ) to keys .
-
If O supports named properties , then for each P of O ’s supported property names that is visible according to the named property visibility algorithm , append P to keys .
-
For each P of O ’s own property keys that is a String, in ascending chronological order of property creation, append P to keys .
-
For each P of O ’s own property keys that is a Symbol, in ascending chronological order of property creation, append P to keys .
-
Assert: keys has no duplicate items.
-
Return keys .
3.9.7. Abstract operations
To determine if a property name P is an array index , the following algorithm is applied:
-
If Type ( P ) is not String, then return
false . -
Let index be ! CanonicalNumericIndexString ( P ).
-
If index is
undefined , then returnfalse . -
If IsInteger ( index ) is
false , then returnfalse . -
If index is −0, then return
false . -
If index < 0, then return
false . -
If index ≥ 2 32 − 1, then return
false .Note: 2 32 − 1 is the maximum array length allowed by ECMAScript.
-
Return
true .
The
named
property
visibility
algorithm
is
used
to
determine
if
a
given
named
property
is
exposed
on
an
object.
Some
named
properties
are
not
exposed
on
an
object
depending
on
whether
the
[
LegacyOverrideBuiltIns
]
extended
attribute
was
used.
The
algorithm
operates
as
follows,
with
property
name
P
and
object
O
:
-
If P is not a supported property name of O , then return false.
-
If O has an own property named P , then return false.
Note: This will include cases in which O has unforgeable properties, because in practice those are always set up before objects have any supported property names, and once set up will make the corresponding named properties invisible.
-
If O implements an interface that has the [
LegacyOverrideBuiltIns
] extended attribute , then return true. -
Let prototype be O .[[GetPrototypeOf]]().
-
While prototype is not null:
-
If prototype is not a named properties object , and prototype has an own property named P , then return false.
-
Set prototype to prototype .[[GetPrototypeOf]]().
-
-
Return true.
This should ensure that for objects with named properties, property resolution is done in the following order:
-
Indexed properties.
-
Own properties, including unforgeable attributes and operations.
-
Then, if [
LegacyOverrideBuiltIns
]:-
Named properties.
-
Properties from the prototype chain.
-
-
Otherwise, if not [
LegacyOverrideBuiltIns
]:-
Properties from the prototype chain.
-
Named properties.
-
To invoke an indexed property setter with property name P and ECMAScript value V , the following steps must be performed:
-
Let index be the result of calling ToUint32 ( P ).
-
Let creating be true if index is not a supported property index , and false otherwise.
-
Let operation be the operation used to declare the indexed property setter.
-
Let T be the type of the second argument of operation .
-
Let value be the result of converting V to an IDL value of type T .
-
If operation was defined without an identifier , then:
-
If creating is true, then perform the steps listed in the interface description to set the value of a new indexed property with index as the index and value as the value.
-
Otherwise, creating is false. Perform the steps listed in the interface description to set the value of an existing indexed property with index as the index and value as the value.
-
-
Otherwise, operation was defined with an identifier. Perform the steps listed in the description of operation with index and value as the two argument values.
To invoke a named property setter with property name P and ECMAScript value V , the following steps must be performed:
-
Let creating be true if P is not a supported property name , and false otherwise.
-
Let operation be the operation used to declare the named property setter.
-
Let T be the type of the second argument of operation .
-
Let value be the result of converting V to an IDL value of type T .
-
If operation was defined without an identifier , then:
-
If creating is true, then perform the steps listed in the interface description to set the value of a new named property with P as the name and value as the value.
-
Otherwise, creating is false. Perform the steps listed in the interface description to set the value of an existing named property with P as the name and value as the value.
-
-
Otherwise, operation was defined with an identifier. Perform the steps listed in the description of operation with P and value as the two argument values.
The LegacyPlatformObjectGetOwnProperty abstract operation performs the following steps when called with an object O , a property name P , and a boolean ignoreNamedProps value:
-
If O supports indexed properties and P is an array index , then:
-
Let index be the result of calling ToUint32 ( P ).
-
If index is a supported property index , then:
-
Let operation be the operation used to declare the indexed property getter.
-
Let value be an uninitialized variable.
-
If operation was defined without an identifier , then set value to the result of performing the steps listed in the interface description to determine the value of an indexed property with index as the index.
-
Otherwise, operation was defined with an identifier. Set value to the result of performing the steps listed in the description of operation with index as the only argument value.
-
Let desc be a newly created Property Descriptor with no fields.
-
Set desc .[[Value]] to the result of converting value to an ECMAScript value.
-
If O implements an interface with an indexed property setter , then set desc .[[Writable]] to
true , otherwise set it tofalse . -
Set desc .[[Enumerable]] and desc .[[Configurable]] to
true . -
Return desc .
-
-
Set ignoreNamedProps to true.
-
-
If O supports named properties and ignoreNamedProps is false, then:
-
If the result of running the named property visibility algorithm with property name P and object O is true, then:
-
Let operation be the operation used to declare the named property getter.
-
Let value be an uninitialized variable.
-
If operation was defined without an identifier , then set value to the result of performing the steps listed in the interface description to determine the value of a named property with P as the name.
-
Otherwise, operation was defined with an identifier. Set value to the result of performing the steps listed in the description of operation with P as the only argument value.
-
Let desc be a newly created Property Descriptor with no fields.
-
Set desc .[[Value]] to the result of converting value to an ECMAScript value.
-
If O implements an interface with a named property setter , then set desc .[[Writable]] to
true , otherwise set it tofalse . -
If O implements an interface with the [
LegacyUnenumerableNamedProperties
] extended attribute , then set desc .[[Enumerable]] tofalse , otherwise set it totrue . -
Set desc .[[Configurable]] to
true . -
Return desc .
-
-
-
Return OrdinaryGetOwnProperty ( O , P ).
3.10. Observable array exotic objects
An
observable
array
exotic
object
is
a
specific
type
of
ECMAScript
Proxy
exotic
object
which
is
created
using
the
proxy
traps
defined
in
this
section.
They
are
defined
in
this
manner
because
the
ECMAScript
specification
includes
special
treatment
for
Proxy
exotic
objects
that
have
Array
instances
as
their
proxy
target,
and
we
want
to
ensure
that
observable
array
types
are
exposed
to
ECMAScript
code
with
this
special
treatment
intact.
The
proxy
traps
used
by
observable
array
exotic
objects
work
to
ensure
a
number
of
invariants
beyond
those
of
normal
Array
instances:
-
The arrays have no holes, i.e. every property in the inclusive range 0 through
observableArray.length
− 1 will be filled with a value compatible with the specified Web IDL type, and no array index properties will exist outside that range. -
The property descriptors for important properties cannot be changed from their default configuration; indexed properties always remain as configurable, enumerable, and writable data properties, while the
length
property remains as a non-configurable, non-enumerable, and writable data property. -
Adding additional properties to the array cannot be prevented using, for example,
Object.preventExtensions()
.
-
Let innerArray be ! ArrayCreate (0).
-
Let handler be ! OrdinaryObjectCreate (
null , « [[Type]], [[SetAlgorithm]], [[DeleteAlgorithm]], [[BackingList]] »). -
Set handler .[[Type]] to T .
-
Set handler .[[SetAlgorithm]] to setAlgorithm .
-
Set handler .[[DeleteAlgorithm]] to deleteAlgorithm .
-
Let defineProperty be ! CreateBuiltinFunction (the steps from § 3.10.1 defineProperty , « », realm ).
-
Perform ! CreateDataProperty ( handler , "
defineProperty
", defineProperty ). -
Let deleteProperty be ! CreateBuiltinFunction (the steps from § 3.10.2 deleteProperty , « », realm ).
-
Perform ! CreateDataProperty ( handler , "
deleteProperty
", deleteProperty ). -
Let get be ! CreateBuiltinFunction (the steps from § 3.10.3 get , « », realm ).
-
Perform ! CreateDataProperty ( handler , "
get
", get ). -
Let getOwnPropertyDescriptor be ! CreateBuiltinFunction (the steps from § 3.10.4 getOwnPropertyDescriptor , « », realm ).
-
Perform ! CreateDataProperty ( handler , "
getOwnPropertyDescriptor
", getOwnPropertyDescriptor ). -
Let has be ! CreateBuiltinFunction (the steps from § 3.10.5 has , « », realm ).
-
Perform ! CreateDataProperty ( handler , "
has
", has ). -
Let ownKeys be ! CreateBuiltinFunction (the steps from § 3.10.6 ownKeys , « », realm ).
-
Perform ! CreateDataProperty ( handler , "
ownKeys
", ownKeys ). -
Let preventExtensions be ! CreateBuiltinFunction (the steps from § 3.10.7 preventExtensions , « », realm ).
-
Perform ! CreateDataProperty ( handler , "
preventExtensions
", preventExtensions ). -
Let set be ! CreateBuiltinFunction (the steps from § 3.10.8 set , « », realm ).
-
Perform ! CreateDataProperty ( handler , "
set
", set ). -
Return ! ProxyCreate ( innerArray , handler ).
3.10.1.
defineProperty
defineProperty
proxy
trap
for
observable
array
exotic
objects
,
given
O
,
P
,
and
descriptorObj
are
as
follows:
-
Let handler be the
this value. -
Let descriptor be ! ToPropertyDescriptor ( descriptorObj ).
-
If P is "length", then:
-
If ! IsAccessorDescriptor ( descriptor ) is
true , then returnfalse . -
If descriptor .[[Configurable]] is present and has the value
true , then returnfalse . -
If descriptor .[[Enumerable]] is present and has the value
true , then returnfalse . -
If descriptor .[[Writable]] is present and has the value
false , then returnfalse . -
If descriptor .[[Value]] is present, then return the result of setting the length given handler and descriptor .[[Value]].
-
Return
true .
-
-
If P is an array index , then:
-
If ! IsAccessorDescriptor ( descriptor ) is
true , then returnfalse . -
If descriptor .[[Configurable]] is present and has the value
false , then returnfalse . -
If descriptor .[[Enumerable]] is present and has the value
false , then returnfalse . -
If descriptor .[[Writable]] is present and has the value
false , then returnfalse . -
If descriptor .[[Value]] is present, then return the result of setting the indexed value given handler , P , and descriptor .[[Value]].
-
Return
true .
-
-
Return ? O .[[DefineOwnProperty]]( P , descriptor ).
3.10.2.
deleteProperty
deleteProperty
proxy
trap
for
observable
array
exotic
objects
,
given
O
and
P
,
are
as
follows:
-
Let handler be the
this value. -
If P is "length", then return
false . -
If P is an array index , then:
-
Return ? O .[[Delete]]( P ).
3.10.3.
get
get
proxy
trap
for
observable
array
exotic
objects
,
given
O
,
P
,
and
Receiver
,
are
as
follows:
-
Let handler be the
this value. -
Let length be handler .[[BackingList]]'s size .
-
If P is "length", then return length .
-
If P is an array index , then:
-
If index ≥ length , then return
undefined . -
Let esValue be the result of converting handler .[[BackingList]][ index ] to an ECMAScript value.
-
Assert: the above step never throws an exception.
-
Return esValue .
-
Return ? O .[[Get]]( P , Receiver ).
3.10.4.
getOwnPropertyDescriptor
getOwnPropertyDescriptor
proxy
trap
for
observable
array
exotic
objects
,
given
O
and
P
,
are
as
follows:
-
Let handler be the
this value. -
Let length be handler .[[BackingList]]'s size .
-
If P is "length", then return ! FromPropertyDescriptor (PropertyDescriptor{[[Configurable]]:
false , [[Enumerable]]:false , [[Writable]]:true , [[Value]]: length }). -
If P is an array index , then
-
If index ≥ length , then return
undefined . -
Let esValue be the result of converting handler .[[BackingList]][ index ] to an ECMAScript value.
-
Assert: the above step never throws an exception.
-
Return ! FromPropertyDescriptor (PropertyDescriptor{[[Configurable]]:
true , [[Enumerable]]:true , [[Writable]]:true , [[Value]]: esValue }).
-
Return ! FromPropertyDescriptor ( ? O .[[GetOwnProperty]]( P )).
3.10.5.
has
has
proxy
trap
for
observable
array
exotic
objects
,
given
O
and
P
,
are
as
follows:
-
Let handler be the
this value. -
If P is "length", then return
true . -
If P is an array index , then:
-
Return ? O .[[HasProperty]]( P ).
3.10.6.
ownKeys
ownKeys
proxy
trap
for
observable
array
exotic
objects
,
given
O
,
are
as
follows:
3.10.7.
preventExtensions
preventExtensions
proxy
trap
for
observable
array
exotic
objects
are
as
follows:
-
Return
false .
3.10.8.
set
set
proxy
trap
for
observable
array
exotic
objects
,
given
O
,
P
,
V
,
and
Receiver
,
are
as
follows:
-
Let handler be the
this value. -
If P is "length", then return the result of setting the length given handler and V .
-
If P is an array index , then return the result of setting the indexed value given handler , P , and V .
-
Return ? O .[[Set]]( P , V , Receiver ).
3.10.9. Abstract operations
-
If uint32Len ≠ numberLen , then throw a
RangeError
exception. -
Let oldLen be handler .[[BackingList]]'s size .
-
If uint32Len > oldLen , then return
false . -
Let indexToDelete be oldLen − 1.
-
While indexToDelete ≥ uint32Len :
-
Perform the algorithm steps given by handler .[[DeleteAlgorithm]], given handler .[[BackingList]][ indexToDelete ] and indexToDelete .
-
Remove the last item from handler .[[BackingList]].
-
Set indexToDelete to indexToDelete − 1.
-
-
Let oldLen be handler .[[BackingList]]'s size .
-
If index > oldLen , return
false . -
Let idlValue be the result of converting V to the type given by handler .[[Type]].
-
If index < oldLen , then:
-
Perform the algorithm steps given by handler .[[DeleteAlgorithm]], given handler .[[BackingList]][ index ] and index .
-
-
Perform the algorithm steps given by handler .[[SetAlgorithm]], given idlValue and index .
-
If index = oldLen , then append idlValue to handler .[[BackingList]].
-
Otherwise, set handler .[[BackingList]][ index ] to idlValue .
-
Return
true .
3.11. Callback interfaces
As described in § 2.12 Objects implementing interfaces , callback interfaces can be implemented in script by any ECMAScript object. The following cases explain how a callback interface 's operation is invoked on a given object:
-
If the object is callable , then the implementation of the operation is the callable object itself.
-
Otherwise, the implementation of the operation is calling the result of invoking the internal [[Get]] method on the object with a property name that is the identifier of the operation.
Note that ECMAScript objects need not have properties corresponding to constants on them to be considered as implementing callback interfaces that happen to have constants declared on them.
A Web IDL arguments list is a list of values each of which is either an IDL value or the special value “missing”, which represents a missing optional argument.
-
Let esArgs be an empty list .
-
Let i be 0.
-
Let count be 0.
-
While i < args ’s size :
-
If args [ i ] is the special value “missing”, then append
undefined to esArgs . -
Otherwise, args [ i ] is an IDL value:
-
Let convertResult be the result of converting args [ i ] to an ECMAScript value. Rethrow any exceptions.
-
Append convertResult to esArgs .
-
Set count to i + 1.
-
-
Set i to i + 1.
-
-
Truncate esArgs to contain count items.
-
Return esArgs .
To call a user object’s operation , given a callback interface type value value , operation name opName , Web IDL arguments list args , and optional callback this value thisArg , perform the following steps. These steps will either return an IDL value or throw an exception.
-
Let completion be an uninitialized variable.
-
If thisArg was not given, let thisArg be
undefined . -
Let O be the ECMAScript object corresponding to value .
-
Let realm be O ’s associated Realm .
-
Let relevant settings be realm ’s settings object .
-
Let stored settings be value ’s callback context .
-
Prepare to run script with relevant settings .
-
Prepare to run a callback with stored settings .
-
Let X be O .
-
If ! IsCallable ( O ) is false, then:
-
Let getResult be Get ( O , opName ).
-
If getResult is an abrupt completion , set completion to getResult and jump to the step labeled return .
-
Set X to getResult .[[Value]].
-
If ! IsCallable ( X ) is
false , then set completion to a new Completion {[[Type]]: throw, [[Value]]: a newly createdTypeError
object, [[Target]]: empty}, and jump to the step labeled return . -
Set thisArg to O (overriding the provided value).
-
-
Let esArgs be the result of converting args to an ECMAScript arguments list. If this throws an exception, set completion to the completion value representing the thrown exception and jump to the step labeled return .
-
Let callResult be Call ( X , thisArg , esArgs ).
-
If callResult is an abrupt completion , set completion to callResult and jump to the step labeled return .
-
Set completion to the result of converting callResult .[[Value]] to an IDL value of the same type as the operation’s return type.
-
Return: at this point completion will be set to an ECMAScript completion value.
-
Clean up after running a callback with stored settings .
-
Clean up after running script with relevant settings .
-
If completion is a normal completion, return completion .
-
If completion is an abrupt completion and the operation has a return type that is not a promise type , return completion .
-
Let rejectedPromise be ! Call (
%Promise_reject%
,%Promise%
, « completion .[[Value]]»). -
Return the result of converting rejectedPromise to the operation’s return type.
-
3.11.1. Legacy callback interface object
For every callback interface that is exposed in a given Realm and on which constants are defined, a corresponding property exists on the Realm 's global object . The name of the property is the identifier of the callback interface , and its value is an object called the legacy callback interface object .
The legacy callback interface object for a given callback interface is a built-in function object . It has properties that correspond to the constants defined on that interface, as described in sections § 3.7.5 Constants .
Note:
Since
a
legacy
callback
interface
object
is
a
function
object
the
typeof
operator
will
return
"function"
when
applied
to
a
legacy
callback
interface
object
.
The legacy callback interface object for a given callback interface interface with identifier id and in Realm realm is created as follows:
-
Let steps be the following steps:
-
Let F be ! CreateBuiltinFunction ( steps , « », realm ).
-
Perform ! SetFunctionName ( F , id ).
-
Perform ! SetFunctionLength ( F , 0).
-
Define the constants of interface on F given realm .
-
Return F .
3.12. Invoking callback functions
An ECMAScript callable object that is being used as a callback function value is called in a manner similar to how operations on callback interface values are called (as described in the previous section).
To invoke a callback function type value callable with a Web IDL arguments list args and an optional callback this value thisArg , perform the following steps. These steps will either return an IDL value or throw an exception.
-
Let completion be an uninitialized variable.
-
If thisArg was not given, let thisArg be
undefined . -
Let F be the ECMAScript object corresponding to callable .
-
If ! IsCallable ( F ) is
false :-
Note: This is only possible when the callback function came from an attribute marked with [
LegacyTreatNonObjectAsNull
]. -
If the callback function’s return type is
void
, return. -
Return the result of converting
undefined to the callback function’s return type.
-
-
Let realm be F ’s associated Realm .
-
Let relevant settings be realm ’s settings object .
-
Let stored settings be callable ’s callback context .
-
Prepare to run script with relevant settings .
-
Prepare to run a callback with stored settings .
-
Let esArgs be the result of converting args to an ECMAScript arguments list. If this throws an exception, set completion to the completion value representing the thrown exception and jump to the step labeled return .
-
Let callResult be Call ( F , thisArg , esArgs ).
-
If callResult is an abrupt completion , set completion to callResult and jump to the step labeled return .
-
Set completion to the result of converting callResult .[[Value]] to an IDL value of the same type as the operation’s return type.
-
Return: at this point completion will be set to an ECMAScript completion value.
-
Clean up after running a callback with stored settings .
-
Clean up after running script with relevant settings .
-
If completion is a normal completion, return completion .
-
If completion is an abrupt completion and the callback function has a return type that is not a promise type , return completion .
-
Let rejectedPromise be ! Call (
%Promise_reject%
,%Promise%
, « completion .[[Value]]»). -
Return the result of converting rejectedPromise to the callback function’s return type.
-
Some callback functions are instead used as constructors . Such callback functions must not have a return type that is a promise type .
To construct a callback function type value callable with a Web IDL arguments list args , perform the following steps. These steps will either return an IDL value or throw an exception.
-
Let completion be an uninitialized variable.
-
Let F be the ECMAScript object corresponding to callable .
-
If ! IsConstructor ( F ) is
false , throw aTypeError
exception. -
Let realm be F ’s associated Realm .
-
Let relevant settings be realm ’s settings object .
-
Let stored settings be callable ’s callback context .
-
Prepare to run script with relevant settings .
-
Prepare to run a callback with stored settings .
-
Let esArgs be the result of converting args to an ECMAScript arguments list. If this throws an exception, set completion to the completion value representing the thrown exception and jump to the step labeled return .
-
Let callResult be Construct ( F , esArgs ).
-
If callResult is an abrupt completion , set completion to callResult and jump to the step labeled return .
-
Set completion to the result of converting callResult .[[Value]] to an IDL value of the same type as the operation’s return type.
-
Return: at this point completion will be set to an ECMAScript completion value.
-
Clean up after running a callback with stored settings .
-
Clean up after running script with relevant settings .
-
Return completion .
-
3.13. Namespaces
For every namespace that is exposed in a given Realm , a corresponding property exists on the Realm 's global object . The name of the property is the identifier of the namespace, and its value is an object called the namespace object .
The characteristics of a namespace object are described in § 3.13.1 Namespace object .
3.13.1. Namespace object
The namespace object for a given namespace namespace and Realm realm is created as follows:
-
Let namespaceObject be ! OrdinaryObjectCreate ( realm .[[Intrinsics]].[[
%ObjectPrototype%
]]). -
Define the regular attributes of namespace on namespaceObject given realm .
-
Define the regular operations of namespace on namespaceObject given realm .
-
For each exposed interface interface which has the [
LegacyNamespace
] extended attribute with the identifier of namespace as its argument,-
Let id be interface ’s identifier .
-
Let interfaceObject be the result of creating an interface object for interface with id in realm .
-
Perform ! CreateMethodProperty ( namespaceObject , id , interfaceObject ).
-
-
Return namespaceObject .
3.14. Exceptions
3.14.1.
DOMException
custom
bindings
In
the
ECMAScript
binding,
the
interface
prototype
object
for
DOMException
has
its
[[Prototype]]
internal
slot
set
to
the
intrinsic
object
%ErrorPrototype%
,
as
defined
in
the
create
an
interface
prototype
object
abstract
operation.
Additionally,
if
an
implementation
gives
native
Error
objects
special
powers
or
nonstandard
properties
(such
as
a
stack
property),
it
should
also
expose
those
on
DOMException
instances.
3.14.2. Exception objects
Simple exceptions are represented by native ECMAScript objects of the corresponding type.
A
DOMException
is
represented
by
a
platform
object
that
implements
the
DOMException
interface.
3.14.3. Creating and throwing exceptions
To
create
a
simple
exception
or
DOMException
E
,
with
a
string
giving
the
error
name
N
for
the
DOMException
case
and
optionally
a
string
giving
a
user
agent-defined
message
M
:
-
If M was not specified, let M be
undefined . -
Let args be a list of ECMAScript values determined based on the type of E :
-
E
is
DOMException
-
args is « M , N ».
- E is a simple exception
-
args is « M ».
-
E
is
-
Let X be an object determined based on the type of E :
-
E
is
DOMException
-
X is the
DOMException
interface object from the current Realm . - E is a simple exception
-
X is the constructor for the corresponding ECMAScript error from the current Realm .
-
E
is
To
throw
a
simple
exception
or
DOMException
,
with
a
string
giving
the
error
name
for
the
DOMException
case
and
optionally
a
string
giving
a
user
agent-defined
message:
-
Let O be the result of creating an exception with the same arguments.
-
Throw O .
The above algorithms restrict objects representing exceptions propagating out of a function object to be ones that are associated with the Realm of that function object (i.e., the current Realm at the time the function executes). For example, consider the IDL:
[Exposed =Window ]interface MathUtils { // If x is negative, throws a "NotSupportedError" DOMException.double computeSquareRoot (double x ); };
If
we
apply
computeSquareRoot
to
a
MathUtils
object
from
a
different
Realm
,
then
the
exception
thrown
will
be
from
the
Realm
of
the
method,
not
the
object
it
is
applied
to:
const myMU= window. getMathUtils(); // A MathUtils object from this Realm const otherMU= otherWindow. getMathUtils(); // A MathUtils object from a different Realm myMUinstanceof Object; // Evaluates to true. otherMUinstanceof Object; // Evaluates to false. otherMUinstanceof otherWindow. Object; // Evaluates to true. try { otherMU. doComputation. call( myMU, - 1 ); } catch ( e) { console. assert( ! ( einstanceof DOMException)); console. assert( einstanceof otherWindow. DOMException); }
3.14.4. Handling exceptions
Unless specified otherwise, whenever ECMAScript runtime semantics are invoked due to requirements in this document and end due to an exception being thrown, that exception must propagate to the caller, and if not caught there, to its caller, and so on.
Per Document conventions , an algorithm specified in this document may intercept thrown exceptions, either by specifying the exact steps to take if an exception was thrown , or by explicitly handling abrupt completions .
The
following
IDL
fragment
defines
two
interfaces
and
an
exception
.
The
valueOf
attribute
on
ExceptionThrower
is
defined
to
throw
an
exception
whenever
an
attempt
is
made
to
get
its
value.
[Exposed =Window ]interface Dahut {attribute DOMString type ; }; [Exposed =Window ]interface ExceptionThrower { // This attribute always throws a NotSupportedError and never returns a value.attribute long valueOf ; };
Assuming an ECMAScript implementation supporting this interface, the following code demonstrates how exceptions are handled:
var d= getDahut(); // Obtain an instance of Dahut. var et= getExceptionThrower(); // Obtain an instance of ExceptionThrower. try { d. type= { toString: function () { throw "abc" ; } }; } catch ( e) { // The string "abc" is caught here, since as part of the conversion // from the native object to a string, the anonymous function // was invoked, and none of the [[DefaultValue]], ToPrimitive or // ToString algorithms are defined to catch the exception. } try { d. type= { toString: { } }; } catch ( e) { // An exception is caught here, since an attempt is made to invoke // [[Call]] on the native object that is the value of toString // property. } try { d. type= Symbol(); } catch ( e) { // An exception is caught here, since an attempt is made to invoke // the ECMAScript ToString abstract operation on a Symbol value. } d. type= et; // An uncaught "NotSupportedError" DOMException is thrown here, since the // [[DefaultValue]] algorithm attempts to get the value of the // "valueOf" property on the ExceptionThrower object. The exception // propagates out of this block of code.
3.15. Synthetic module records
A Synthetic Module Record is used to represent information about a module that is defined by specifications. The set of exported names is static, and determined at creation time (as an argument to CreateSyntheticModule ), while the set of exported values can be changed over time using SetSyntheticModuleExport . It has no imports or dependencies.
Note: A Synthetic Module Record could be used for defining a variety of module types: for example, built-in modules, or JSON modules, or CSS modules.
Note: Synthetic Module Records are being developed in concert with the authors of the JavaScript Standard Library proposal, and might eventually move to the ECMAScript specification. [JSSTDLIB] [ECMA-262] .
In addition to the Module Record Fields , Synthetic Module Records have the additional fields listed below. Each of these fields is initially set in CreateSyntheticModule .
Field Name | Value Type | Meaning |
---|---|---|
[[ExportNames]] | List of String | A List of all names that are exported. |
[[EvaluationSteps]] | An abstract operation | An abstract operation that will be performed upon evaluation of the module, taking the Synthetic Module Record as its sole argument. These will usually set up the exported values, by using SetSyntheticModuleExport . They must not modify [[ExportNames]]. They may return an abrupt completion. |
3.15.1. CreateSyntheticModule
-
Return Synthetic Module Record { [[Realm]]: realm , [[Environment]]:
undefined , [[Namespace]]:undefined , [[HostDefined]]: hostDefined , [[ExportNames]]: exportNames , [[EvaluationSteps]]: evaluationSteps }.
Note: we could set up [[Environment]] either here or in Link (). It is done in Link () for symmetry with Source Text Module Records , but there is no observable difference.
3.15.2. SetSyntheticModuleExport
-
Let envRec be module .[[Environment]]'s EnvironmentRecord .
-
Perform envRec . SetMutableBinding ( exportName , exportValue ,
true ).
3.15.3. Concrete Methods
The following are the concrete methods for Synthetic Module Record that implement the corresponding Module Record abstract methods.
3.15.3.1. GetExportedNames
It performs the following steps:
-
Let module be this Synthetic Module Record .
-
Return module .[[ExportNames]].
3.15.3.2. ResolveExport
It performs the following steps:
-
Let module be this Synthetic Module Record .
-
If module .[[ExportNames]] does not contain exportName , return
null . -
Return ResolvedBinding Record { [[Module]]: module , [[BindingName]]: exportName }.
3.15.3.3. Link
It performs the following steps:
-
Let module be this Synthetic Module Record .
-
Let realm be module .[[Realm]].
-
Assert: realm is not
undefined . -
Let env be NewModuleEnvironment ( realm .[[GlobalEnv]]).
-
Set module .[[Environment]] to env .
-
Let envRec be env ’s EnvironmentRecord .
-
For each exportName in module .[[ExportNames]],
-
Perform ! envRec . CreateMutableBinding ( exportName ,
false ). -
Perform ! envRec . InitializeBinding ( exportName ,
undefined ).
-
-
Return
undefined .
3.15.3.4. Evaluate
It performs the following steps:
-
Let module be this Synthetic Module Record .
-
Let moduleCxt be a new ECMAScript code execution context .
-
Set the Function of moduleCxt to
null . -
Assert: module .[[Realm]] is not
undefined . -
Set the Realm of moduleCxt to module .[[Realm]].
-
Set the ScriptOrModule of moduleCxt to module .
-
Set the VariableEnvironment of moduleCxt to module .[[Environment]].
-
Set the LexicalEnvironment of moduleCxt to module .[[Environment]].
-
Suspend the currently running execution context .
-
Push moduleCxt on to the execution context stack ; moduleCxt is now the running execution context .
-
Let completion be the result of performing module .[[EvaluationSteps]]( module ).
-
Suspend moduleCxt and remove it from the execution context stack .
-
Resume the context that is now on the top of the execution context stack as the running execution context .
-
Return Completion ( completion ).
4. Common definitions
This section specifies some common definitions that all conforming implementations must support.
4.1. ArrayBufferView
typedef (Int8Array or Int16Array or Int32Array or Uint8Array or Uint16Array or Uint32Array or Uint8ClampedArray or Float32Array or Float64Array or DataView )ArrayBufferView ;
The
ArrayBufferView
typedef
is
used
to
represent
objects
that
provide
a
view
on
to
an
ArrayBuffer
.
4.2. BufferSource
typedef (ArrayBufferView or ArrayBuffer )BufferSource ;
The
BufferSource
typedef
is
used
to
represent
objects
that
are
either
themselves
an
ArrayBuffer
or
which
provide
a
view
on
to
an
ArrayBuffer
.
4.3. DOMException
The
DOMException
type
is
an
interface
type
defined
by
the
following
IDL
fragment:
[Exposed =(Window ,Worker ),Serializable ]interface DOMException { // but see below note about ECMAScript bindingconstructor (optional DOMString = "",
message optional DOMString = "Error");
name readonly attribute DOMString name ;readonly attribute DOMString message ;readonly attribute unsigned short code ;const unsigned short INDEX_SIZE_ERR = 1;const unsigned short DOMSTRING_SIZE_ERR = 2;const unsigned short HIERARCHY_REQUEST_ERR = 3;const unsigned short WRONG_DOCUMENT_ERR = 4;const unsigned short INVALID_CHARACTER_ERR = 5;const unsigned short NO_DATA_ALLOWED_ERR = 6;const unsigned short NO_MODIFICATION_ALLOWED_ERR = 7;const unsigned short NOT_FOUND_ERR = 8;const unsigned short NOT_SUPPORTED_ERR = 9;const unsigned short INUSE_ATTRIBUTE_ERR = 10;const unsigned short INVALID_STATE_ERR = 11;const unsigned short SYNTAX_ERR = 12;const unsigned short INVALID_MODIFICATION_ERR = 13;const unsigned short NAMESPACE_ERR = 14;const unsigned short INVALID_ACCESS_ERR = 15;const unsigned short VALIDATION_ERR = 16;const unsigned short TYPE_MISMATCH_ERR = 17;const unsigned short SECURITY_ERR = 18;const unsigned short NETWORK_ERR = 19;const unsigned short ABORT_ERR = 20;const unsigned short URL_MISMATCH_ERR = 21;const unsigned short QUOTA_EXCEEDED_ERR = 22;const unsigned short TIMEOUT_ERR = 23;const unsigned short INVALID_NODE_TYPE_ERR = 24;const unsigned short DATA_CLONE_ERR = 25; };
Note: as discussed in § 3.14.1 DOMException custom bindings , the ECMAScript binding imposes additional requirements beyond the normal ones for interface types .
Each
DOMException
object
has
an
associated
name
and
message
,
both
strings
.
The
DOMException(
message
,
name
)
constructor,
when
invoked,
must
run
these
steps:
The
name
attribute’s
getter
must
return
this
DOMException
object’s
name
.
The
message
attribute’s
getter
must
return
this
DOMException
object’s
message
.
The
code
attribute’s
getter
must
return
the
legacy
code
indicated
in
the
error
names
table
for
this
DOMException
object’s
name
,
or
0
if
no
such
entry
exists
in
the
table.
DOMException
objects
are
serializable
objects
.
Their serialization steps , given value and serialized , are:
- Set serialized .[[Name]] to value ’s name .
- Set serialized .[[Message]] to value ’s message .
-
User
agents
should
attach
a
serialized
representation
of
any
interesting
accompanying
data
which
are
not
yet
specified,
notably
the
stack
property, to serialized .
Their deserialization steps , given value and serialized , are:
- Set value ’s name to serialized .[[Name]].
- Set value ’s message to serialized .[[Message]].
- If any other data is attached to serialized , then deserialize and attach it to value .
4.4. DOMTimeStamp
typedef unsigned long long DOMTimeStamp ;
The
DOMTimeStamp
type
is
used
for
representing
a
number
of
milliseconds,
either
as
an
absolute
time
(relative
to
some
epoch)
or
as
a
relative
amount
of
time.
Specifications
that
use
this
type
will
need
to
define
how
the
number
of
milliseconds
is
to
be
interpreted.
4.5. Function
callback Function =any (any ...);
arguments
The
Function
callback
function
type
is
used
for
representing
function
values
with
no
restriction
on
what
arguments
are
passed
to
it
or
what
kind
of
value
is
returned
from
it.
4.6. VoidFunction
callback VoidFunction =void ();
The
VoidFunction
callback
function
type
is
used
for
representing
function
values
that
take
no
arguments
and
do
not
return
any
value.
5. Extensibility
This section is informative.
Extensions to language binding requirements can be specified using extended attributes that do not conflict with those defined in this document. Extensions for private, project-specific use should not be included in IDL fragments appearing in other specifications. It is recommended that extensions that are required for use in other specifications be coordinated with the group responsible for work on Web IDL , which at the time of writing is the W3C Web Platform Working Group , for possible inclusion in a future version of this document.
Extensions to any other aspect of the IDL language are strongly discouraged.
6. Legacy constructs
This section is informative.
Legacy
WebIDL
constructs
exist
only
so
that
legacy
Web
platform
features
can
be
specified.
They
are
generally
prefixed
with
the
"
Legacy
"
string.
It
is
strongly
discouraged
to
use
legacy
WebIDL
constructs
in
specifications
unless
required
to
specify
the
behavior
of
legacy
Web
platform
features,
or
for
consistency
with
such
features.
Editors
who
wish
to
use
legacy
WebIDL
constructs
are
strongly
advised
to
discuss
this
by
filing
an
issue
before
proceeding.
Marking a construct as legacy does not, in itself, imply that it is about to be removed from this specification. It does suggest however, that it is a good candidate for future removal from this specification, whenever various heuristics indicate that the Web platform features it helps specify can be removed altogether or can be modified to rely on non-legacy WebIDL constructs instead.
7. Referencing this specification
This section is informative.
It is expected that other specifications that define Web platform interfaces using one or more IDL fragments will reference this specification. It is suggested that those specifications include a sentence such as the following, to indicate that the IDL is to be interpreted as described in this specification:
The IDL fragment in Appendix A of this specification must, in conjunction with the IDL fragments defined in this specification’s normative references, be interpreted as required for conforming sets of IDL fragments , as described in the “Web IDL” specification. [WEBIDL]
In addition, it is suggested that the conformance class for user agents in referencing specifications be linked to the conforming implementation class from this specification:
A conforming FooML user agent must also be a conforming implementation of the IDL fragment in Appendix A of this specification, as described in the “Web IDL” specification. [WEBIDL]
8. Privacy and Security Considerations
This specification defines a conversion layer between JavaScript and IDL values. An incorrect implementation of this layer can lead to security issues.
This
specification
also
provides
the
ability
to
use
JavaScript
values
directly,
through
the
any
and
object
IDL
types.
These
values
need
to
be
handled
carefully
to
avoid
security
issues.
In
particular,
user
script
can
run
in
response
to
nearly
any
manipulation
of
these
values,
and
invalidate
the
expectations
of
specifications
or
implementations
using
them.
This
specification
makes
it
possible
to
interact
with
SharedArrayBuffer
objects,
which
can
be
used
to
build
timing
attacks.
Specifications
that
use
these
objects
need
to
consider
such
attacks.
9. Acknowledgements
This section is informative.
The editor would like to thank the following people for contributing to this specification: Glenn Adams, David Andersson, Jake Archibald, L. David Baron, Art Barstow, Nils Barth, Robin Berjon, David Bruant, Jan-Ivar Bruaroey, Marcos Cáceres, Giovanni Campagna, Domenic Denicola, Chris Dumez, Michael Dyck, Daniel Ehrenberg, Brendan Eich, João Eiras, Gorm Haug Eriksen, Sigbjorn Finne, David Flanagan, Aryeh Gregor, Dimitry Golubovsky, James Graham, Aryeh Gregor, Tiancheng “Timothy” Gu, Kartikaya Gupta, Marcin Hanclik, Jed Hartman, Stefan Haustein, Dominique Hazaël-Massieux, Ian Hickson, Björn Höhrmann, Kyle Huey, Lachlan Hunt, Oliver Hunt, Jim Jewett, Wolfgang Keller, Anne van Kesteren, Olav Junker Kjær, Takayoshi Kochi, Magnus Kristiansen, Takeshi Kurosawa, Yves Lafon, Travis Leithead, Jim Ley, Kevin Lindsey, Jens Lindström, Peter Linss, 呂康豪 (Kang-Hao Lu), Kyle Machulis, Darien Maillet Valentine, Mark Miller, Ms2ger, Andrew Oakley, 岡坂 史紀 (Shiki Okasaka), Jason Orendorff, Olli Pettay, Simon Pieters, Andrei Popescu, François Remy, Tim Renouf, Tim Ruffles, Alex Russell, Takashi Sakamoto, Doug Schepers, Jonas Sicking, Garrett Smith, Sam Sneddon, Jungkee Song, Josh Soref, Maciej Stachowiak, Anton Tayanovskyy, triple-underscore, Peter Van der Beken, Jeff Walden, Allen Wirfs-Brock, Jeffrey Yasskin and, Collin Xu.
Special thanks also go to Sam Weinig for maintaining this document while the editor was unavailable to do so.
IDL grammar
This
section
defines
an
LL(1)
grammar
whose
start
symbol,
Each production in the grammar has on its right hand side either a non-zero sequence of terminal and non-terminal symbols, or an epsilon (ε) which indicates no symbols. Symbols that begin with an uppercase letter are non-terminal symbols. Symbols in monospaced fonts are terminal symbols. Symbols in sans-serif font that begin with a lowercase letter are terminal symbols that are matched by the regular expressions (using Perl 5 regular expression syntax [PERLRE] ) as follows:
|
=
|
/
-?([1-9][0-9]*|0[Xx][0-9A-Fa-f]+|0[0-7]*)
/
|
|
=
|
/
-?(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+)
/
|
|
=
|
/
[_-]?[A-Za-z][0-9A-Z_a-z-]*
/
|
|
=
|
/
"[^"]*"
/
|
|
=
|
/
[\t\n\r
]+
/
|
|
=
|
/
\
/
\
/.*|
\
/\*(.|\n)*?\*
\
/
/
|
|
=
|
/
[^\t\n\r
0-9A-Za-z]
/
|
The
tokenizer
operates
on
a
sequence
of
Unicode
characters
[UNICODE]
.
When
tokenizing,
the
longest
possible
match
must
be
used.
For
example,
if
the
input
text
is
“
a1
”,
it
is
tokenized
as
a
single
long
",
and
“
.
”
is
tokenized
as
the
quoted
terminal
symbol
The
IDL
syntax
is
case
sensitive,
both
for
the
quoted
terminal
symbols
used
in
the
grammar
and
the
values
used
for
A
"
is
distinct
from
one
named
"
a
",
and
an
extended
attribute
[
legacyfactoryfunction
]
will
not
be
recognized
as
the
[
LegacyFactoryFunction
]
extended
attribute.
Implicitly,
any
number
of
The
following
LL(1)
grammar,
starting
with
Definitions ::ExtendedAttributeList Definition Definitions εDefinition ::CallbackOrInterfaceOrMixin Namespace Partial Dictionary Enum Typedef IncludesStatement ArgumentNameKeyword ::async attribute callback const constructor deleter dictionary enum getter includes inherit interface iterable maplike mixin namespace partial readonly required setlike setter static stringifier typedef unrestricted CallbackOrInterfaceOrMixin ::callback CallbackRestOrInterface interface InterfaceOrMixin InterfaceOrMixin ::InterfaceRest MixinRest InterfaceRest ::identifier Inheritance { InterfaceMembers } ; Partial ::partial PartialDefinition PartialDefinition ::interface PartialInterfaceOrPartialMixin PartialDictionary Namespace PartialInterfaceOrPartialMixin ::PartialInterfaceRest MixinRest PartialInterfaceRest ::identifier { PartialInterfaceMembers } ; InterfaceMembers ::ExtendedAttributeList InterfaceMember InterfaceMembers εInterfaceMember ::PartialInterfaceMember Constructor PartialInterfaceMembers ::ExtendedAttributeList PartialInterfaceMember PartialInterfaceMembers εPartialInterfaceMember ::Const Operation Stringifier StaticMember Iterable AsyncIterable ReadOnlyMember ReadWriteAttribute ReadWriteMaplike ReadWriteSetlike Inheritance ::: identifier εMixinRest ::mixin identifier { MixinMembers } ; MixinMembers ::ExtendedAttributeList MixinMember MixinMembers εMixinMember ::Const RegularOperation Stringifier ReadOnly AttributeRest IncludesStatement ::identifier includes identifier ; CallbackRestOrInterface ::CallbackRest interface identifier { CallbackInterfaceMembers } ; CallbackInterfaceMembers ::ExtendedAttributeList CallbackInterfaceMember CallbackInterfaceMembers εCallbackInterfaceMember ::Const RegularOperation Const ::const ConstType identifier = ConstValue ; ConstValue ::BooleanLiteral FloatLiteral integer BooleanLiteral ::true false FloatLiteral ::decimal -Infinity Infinity NaN ConstType ::PrimitiveType identifier ReadOnlyMember ::readonly ReadOnlyMemberRest ReadOnlyMemberRest ::AttributeRest MaplikeRest SetlikeRest ReadWriteAttribute ::inherit AttributeRest AttributeRest AttributeRest ::attribute TypeWithExtendedAttributes AttributeName ; AttributeName ::AttributeNameKeyword identifier AttributeNameKeyword ::async required ReadOnly ::readonly εDefaultValue ::ConstValue string [ ] { } null Operation ::RegularOperation SpecialOperation RegularOperation ::ReturnType OperationRest SpecialOperation ::Special RegularOperation Special ::getter setter deleter OperationRest ::OptionalOperationName ( ArgumentList ) ; OptionalOperationName ::OperationName εOperationName ::OperationNameKeyword identifier OperationNameKeyword ::includes ArgumentList ::Argument Arguments εArguments ::, Argument Arguments εArgument ::ExtendedAttributeList ArgumentRest ArgumentRest ::optional TypeWithExtendedAttributes ArgumentName Default Type Ellipsis ArgumentName ArgumentName ::ArgumentNameKeyword identifier Ellipsis ::... εReturnType ::Type void Constructor ::constructor ( ArgumentList ) ; Stringifier ::stringifier StringifierRest StringifierRest ::ReadOnly AttributeRest RegularOperation ; StaticMember ::static StaticMemberRest StaticMemberRest ::ReadOnly AttributeRest RegularOperation Iterable ::iterable < TypeWithExtendedAttributes OptionalType > ; OptionalType ::, TypeWithExtendedAttributes εAsyncIterable ::async iterable < TypeWithExtendedAttributes OptionalType > OptionalArgumentList ; OptionalArgumentList ::( ArgumentList ) εReadWriteMaplike ::MaplikeRest MaplikeRest ::maplike < TypeWithExtendedAttributes , TypeWithExtendedAttributes > ; ReadWriteSetlike ::SetlikeRest SetlikeRest ::setlike < TypeWithExtendedAttributes > ; Namespace ::namespace identifier { NamespaceMembers } ; NamespaceMembers ::ExtendedAttributeList NamespaceMember NamespaceMembers εNamespaceMember ::RegularOperation readonly AttributeRest Dictionary ::dictionary identifier Inheritance { DictionaryMembers } ; DictionaryMembers ::DictionaryMember DictionaryMembers εDictionaryMember ::ExtendedAttributeList DictionaryMemberRest DictionaryMemberRest ::required TypeWithExtendedAttributes identifier ; Type identifier Default ; PartialDictionary ::dictionary identifier { DictionaryMembers } ; Default ::= DefaultValue εEnum ::enum identifier { EnumValueList } ; EnumValueList ::string EnumValueListComma EnumValueListComma ::, EnumValueListString εEnumValueListString ::string EnumValueListComma εCallbackRest ::identifier = ReturnType ( ArgumentList ) ; Typedef ::typedef TypeWithExtendedAttributes identifier ; Type ::SingleType UnionType Null TypeWithExtendedAttributes ::ExtendedAttributeList Type SingleType ::DistinguishableType any PromiseType UnionType ::( UnionMemberType or UnionMemberType UnionMemberTypes ) UnionMemberType ::ExtendedAttributeList DistinguishableType UnionType Null UnionMemberTypes ::or UnionMemberType UnionMemberTypes εDistinguishableType ::PrimitiveType Null StringType Null identifier Null sequence < TypeWithExtendedAttributes > Null object Null symbol Null BufferRelatedType Null FrozenArray < TypeWithExtendedAttributes > Null ObservableArray < TypeWithExtendedAttributes > Null RecordType Null PrimitiveType ::UnsignedIntegerType UnrestrictedFloatType boolean byte octet UnrestrictedFloatType ::unrestricted FloatType FloatType FloatType ::float double UnsignedIntegerType ::unsigned IntegerType IntegerType IntegerType ::short long OptionalLong OptionalLong ::long εStringType ::ByteString DOMString USVString PromiseType ::Promise < ReturnType > RecordType ::record < StringType , TypeWithExtendedAttributes > Null ::? εBufferRelatedType ::ArrayBuffer DataView Int8Array Int16Array Int32Array Uint8Array Uint16Array Uint32Array Uint8ClampedArray Float32Array Float64Array ExtendedAttributeList ::[ ExtendedAttribute ExtendedAttributes ] εExtendedAttributes ::, ExtendedAttribute ExtendedAttributes εExtendedAttribute ::( ExtendedAttributeInner ) ExtendedAttributeRest [ ExtendedAttributeInner ] ExtendedAttributeRest { ExtendedAttributeInner } ExtendedAttributeRest Other ExtendedAttributeRest ExtendedAttributeRest ::ExtendedAttribute εExtendedAttributeInner ::( ExtendedAttributeInner ) ExtendedAttributeInner [ ExtendedAttributeInner ] ExtendedAttributeInner { ExtendedAttributeInner } ExtendedAttributeInner OtherOrComma ExtendedAttributeInner εOther ::integer decimal identifier string other - -Infinity . ... : ; < = > ? ByteString DOMString FrozenArray Infinity NaN ObservableArray Promise USVString any boolean byte double false float long null object octet or optional record sequence short symbol true unsigned void ArgumentNameKeyword BufferRelatedType OtherOrComma ::Other , IdentifierList ::identifier Identifiers Identifiers ::, identifier Identifiers εExtendedAttributeNoArgs ::identifier ExtendedAttributeArgList ::identifier ( ArgumentList ) ExtendedAttributeIdent ::identifier = identifier ExtendedAttributeIdentList ::identifier = ( IdentifierList ) ExtendedAttributeNamedArgList ::identifier = identifier ( ArgumentList )
Note:
The
While
the
Document conventions
The following typographic conventions are used in this document:
-
Defining instances of terms: example term
-
Links to terms defined in this document or elsewhere: example term
-
Grammar terminals:
sometoken -
Grammar non-terminals:
ExampleGrammarNonTerminal -
Grammar symbols:
identifier -
IDL types:
unsigned long
-
ECMAScript classes:
Map
-
ECMAScript language types: Object
-
Code snippets:
a = b + obj.f()
-
Unicode characters: U+0030 DIGIT ZERO ("0")
-
Extended attributes: [
ExampleExtendedAttribute
] -
Variable names in prose and algorithms: exampleVariableName .
-
IDL informal syntax examples:
[
extended_attributes ]interface identifier { /* interface_members... */ };(Specific parts of the syntax discussed in surrounding prose are highlighted .)
-
IDL grammar snippets:
ExampleGrammarNonTerminal ::OtherNonTerminal sometoken other AnotherNonTerminal ε //nothing -
Non-normative notes:
Note: This is a note.
-
Non-normative examples:
-
Normative warnings:
This is a warning.
-
Code blocks:
// This is an IDL code block. [
Exposed =Window ]interface Example {attribute long something ; };// This is an ECMAScript code block. window. onload= function () { window. alert( "loaded" ); };
The following conventions are used in the algorithms in this document:
-
Algorithms use the conventions of the ECMAScript specification, including the ! and ? notation for unwrapping Completion Records .
-
Algorithms sometimes treat returning/throwing values and returning Completion Records interchangeably. That is, an algorithm that uses return/throw terminology may be treated as returning a Completion Record , while one that returns a Completion Record may be treated as returning a value or throwing an exception. Similarly, to catch exceptions, defining the behavior to adopt when an exception was thrown and checking if the Completion Record ’s [[Type]] field is “throw” are equivalent.
-
Completion Records are extended by allowing them to contain values that are not ECMAScript values, such as Web IDL values.
Conformance
Everything in this specification is normative except for diagrams, examples, notes and sections marked as being informative.
This specification depends on the Infra Standard. [INFRA]
The following conformance classes are defined by this specification:
- conforming set of IDL fragments
-
A set of IDL fragments is considered to be a conforming set of IDL fragments if, taken together, they satisfy all of the must-, required- and shall-level criteria in this specification that apply to IDL fragments.
- conforming implementation
-
A user agent is considered to be a conforming implementation relative to a conforming set of IDL fragments if it satisfies all of the must-, required- and shall-level criteria in this specification that apply to implementations for all language bindings that the user agent supports.
- conforming ECMAScript implementation
-
A user agent is considered to be a conforming ECMAScript implementation relative to a conforming set of IDL fragments if it satisfies all of the must-, required- and shall-level criteria in this specification that apply to implementations for the ECMAScript language binding.