1.Introduction
This section is informative.
This standard defines an interface definition language, Web IDL, that can be used to describeinterfaces that are intended to be implemented in web browsers. Web IDL is an IDL variant with anumber of features that allow the behavior of common script objects in the web platform to bespecified more readily. How interfaces described with Web IDL correspond to constructs withinJavaScript execution environments is also detailed here.
Concretely, Web IDL provides a syntax for specifying the surface APIs of web platform objects, aswell as JavaScript bindings that detail how those APIs manifest as JavaScript constructs. Thisensures common tasks, such as installing global properties, processing numeric inputs, or exposingiteration behavior, remain uniform across web platform specifications: such specifications describetheir interfaces using Web IDL, and then use prose to specify API-specific details.
The term "JavaScript" is used to refer to ECMA-262, rather than the official term ECMAScript, since the term JavaScript is more widely known.
2.Interface definition language
This section describes a language,Web IDL, which can be used to defineinterfaces for APIs in the Web platform. A specification that defines Web APIscan include one or moreIDL fragments thatdescribe the interfaces (the state and behavior that objects can exhibit)for the APIs defined by that specification.AnIDL fragment isa sequence of definitions that matches the
The different kinds ofdefinitions that can appear in anIDL fragment are:interfaces,partial interface definitions,interface mixins,partial mixin definitions,callback functions,callback interfaces,namespaces,partial namespace definitions,dictionaries,partial dictionary definitions,typedefs andincludes statements.These are all defined in the following sections.
Eachdefinition (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 anIDL 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 ;undefined drawRectangle (double x ,double y ,double width ,double height );undefined drawText (double x ,double y ,DOMString text );};
Here, fourinterfaces are being defined. TheGraphicalWindow
interface has tworead onlyattributes, one writable attribute, and twooperations defined on it. Objects that implement theGraphicalWindow
interface will expose these attributes and operations in a manner appropriate to the particular language being used.
In JavaScript, the attributes on the IDL interfaces will be exposed as accessor properties and the operations as data properties whose value is abuilt-in function object on a prototype object for allGraphicalWindow
objects; each JavaScript object that implementsGraphicalWindow
will have that prototype object in its prototype chain.
Theconstructor operation that appears onGraphicalWindow
causes aconstructor to exist in JavaScript implementations, so that callingnew GraphicalWindow()
would return a new object that implemented the interface.
Allinterfaces have the [Exposed
]extended attribute, which ensures the interfaces are only available inrealms whoseglobal object is aWindow
object.
2.1.Names
Everyinterface,partial interface definition,namespace,partial namespace definition,dictionary,partial dictionary definition,enumeration,callback function,callback interface andtypedef (together callednamed definitions)and everyconstant,attribute,anddictionary member has anidentifier, as do someoperations.The identifier is determined by an
Fornamed definitions,the
identifier token that appearsdirectly after theinterface ,namespace ,dictionary ,enum orcallback keyworddetermines 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... */ };Forattributes,typedefs anddictionary members,the final
identifier token before thesemicolon 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 ;};Forconstants,the
identifier token before theequals sign determines the identifier.const type constant_identifier = 42;Foroperations, the
identifier token that appearsafter 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. Ifthere 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 aspecial kind of operation, such as a getter or setter.
For all of these constructs, theidentifier is the value of the
Note: A leading U+005F (_) is used to escape an identifier from lookinglike a reserved word so that, for example, an interface named "interface
" can bedefined. The leading U+005F (_) is dropped to unescape theidentifier.
Operation arguments can take a slightly wider set of identifiers. In an operationdeclaration, the identifier of an argument is specified immediately after itstype 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
Theidentifier of any of the abovementionedIDL constructs (except operation arguments) must not be "constructor
","toString
",or begin with a U+005F (_). Theseare known asreserved identifiers.
Although the "toJSON
"identifier is not areserved identifier,it must only be used forregular operations that convert objects toJSON types,as described in§ 2.5.3.1 toJSON.
Note: Further restrictions on identifier names for particular constructs can be madein later sections.
Within the set ofIDL fragments that a given implementation supports,theidentifier of everyinterface,namespace,dictionary,enumeration,callback function,callback interface andtypedef must notbe the same as the identifier of any otherinterface,namespace,dictionary,enumeration,callback function,callback interface ortypedef.
Within anIDL fragment, a referenceto adefinition need not appear afterthe declaration of the referenced definition. References can also be madeacrossIDL fragments.
Therefore, the followingIDL fragment is valid:
[Exposed =Window ]interface B :A {undefined f (SequenceOfLongs x );};[Exposed =Window ]interface A {};typedef sequence <long >SequenceOfLongs ;
The followingIDL fragment demonstrates howidentifiers are given to definitions andinterface 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 secondattribute on theTextField
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’sidentifier.
2.2.Interfaces
IDL fragments are used todescribe object oriented systems. In such systems, objects are entitiesthat have identity and which are encapsulations of state and behavior.Aninterface is a definition (matching
[extended_attributes ]interface identifier { /* interface_members... */};
An interface is a specification of a set ofinterface members (matching
Interfaces in Web IDL describe how objects that implement theinterface behave. In bindings for object oriented languages, it isexpected that an object that implements a particular IDL interfaceprovides ways to inspect and modify the object’s state and toinvoke the behavior described by the interface.
An interface can be defined toinherit from another interface.If the identifier of the interface is followed by aU+003A (:)and anidentifier,then that identifier identifies the inherited interface.An object that implements an interface that inherits from anotheralso implements that inherited interface. The object therefore will alsohave 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 theJavaScript binding.
Interfaces may specify an interface member that has the same name asone from an inherited interface. Objects that implement the derivedinterface will expose the member on the derived interface. It islanguage binding specific whether the overridden member can beaccessed on the object.
Consider the following two interfaces.
[Exposed =Window ]interface A {undefined f ();undefined g ();};[Exposed =Window ]interface B :A {undefined f ();undefined g (DOMString x );};
In the JavaScript language binding, an instance ofB
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]
CallinginstanceOfB.f()
in JavaScript will invoke the f defined onB
. However, the f fromA
can still be invoked on an object that implementsB
by callingA.prototype.f.call(instanceOfB)
.
Theinherited interfaces ofa given interfaceA is the set of all interfaces thatA inherits from, directly or indirectly. IfA does notinherit from another interface, then the set is empty. Otherwise, the setincludes the interfaceB thatAinherits from and all ofB’sinherited interfaces.
An interface must not be declared such thatits inheritance hierarchy has a cycle. That is, an interfaceA cannot inherit from itself, nor can it inherit from anotherinterfaceB that inherits fromA, and so on.
Note that general multiple inheritance of interfaces is not supported, andobjects also cannot implement arbitrary sets of interfaces.Objects can be defined to implement a single given interfaceA,which means that it also implements all ofA’sinherited interfaces.In addition, anincludes statement can be usedto define that objects implementing aninterfaceA will always also include themembers of theinterface mixinsAincludes.
Each interface member can be preceded by a list ofextended 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 usingpartial interface definitions(matching
interface SomeInterface { /* interface_members... */};partial interface SomeInterface { /* interface_members... */};
Note: Partial interface definitions are intended for use as a specificationeditorial aide, allowing the definition of an interface to be separatedover more than one section of the document, and sometimes multiple documents.
The order of appearance of aninterface definition and any of itspartial interface definitions does not matter.
Note: A partial interface definition cannot specify that the interfaceinherits from another interface.Inheritance is to be specified on the originalinterface definition.
The relevant language binding determines how interfaces correspond to constructsin the language.
The following extended attributes are applicable to interfaces:[CrossOriginIsolated
],[Exposed
],[Global
],[LegacyFactoryFunction
],[LegacyNoInterfaceObject
],[LegacyOverrideBuiltIns
],[LegacyWindowAlias
], and[SecureContext
].
The following extended attributes are applicable topartial interfaces:[CrossOriginIsolated
],[Exposed
],[LegacyOverrideBuiltIns
], and[SecureContext
].
Interfaces must be annotated with an [Exposed
]extended attribute.
Thequalified name of aninterfaceinterface is defined as follows:
Letidentifier be theidentifier ofinterface.
Ifinterface has a [
LegacyNamespace
]extended attribute, then:Letnamespace be the identifier argument of the [
LegacyNamespace
]extended attribute.Return theconcatenation of «namespace,identifier » withseparator U+002E (.).
Returnidentifier.
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 InheritAttribute
Inheritance ::: identifier ε
The followingIDL fragment demonstrates the definition of two mutually referentialinterfaces. BothHuman
andDog
inherit fromAnimal
. Objects that implement either of those two interfaces will thus have aname
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 followingIDL fragment defines simplified versions of a DOMinterfaces and acallback interface.
[Exposed =Window ]interface Node {readonly attribute DOMString nodeName ;readonly attribute Node ?parentNode ;Node appendChild (Node newChild );undefined addEventListener (DOMString type ,EventListener listener );};callback interface EventListener {undefined handleEvent (Event event );};
Plain objects can implement acallback interface likeEventListener
:
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 aninterface likeNode
, 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
Aninterface mixin is a definition (matching
interface mixin identifier { /* mixin_members... */};
Note:Interface mixins, much likepartial 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 choosepartial interfaces,interface mixins,orpartial interface mixins can be found in§ 2.3.1 Using mixins and partials.
Aninterface mixin is a specification of a set ofinterface mixin members (matching
Theseconstants,regular operations,regular attributes, andstringifiers describe the behaviors that can be implemented by an object,as if they were specified on theinterface thatincludes them.
Static attributes,static operations,special operations, anditerable,asynchronously iterable,maplike, andsetlike declarations cannot appear ininterface mixin declarations.
As with interfaces, the IDL forinterface mixins can be split into multiple parts by usingpartial 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 enumerationin theJavaScript binding.
Note that unlikeinterfaces ordictionaries,interface mixins do not create types.
Of the extended attributes defined in this specification,only the [CrossOriginIsolated
], [Exposed
], and [SecureContext
] extended attributesare applicable tointerface mixins.
Anincludes statement is a definition(matching
interface_identifier includes mixin_identifier ;
The firstidentifier must reference ainterfaceI.The second identifier must reference aninterface mixinM.
Eachmember ofM is considered to beamember of eachinterfaceI,J,K, … thatincludesM,as if a copy of eachmember had been made.So for a given memberm ofM,interfaceI is considered to have amembermI,interfaceJ is considered to have amembermJ,interfaceK is considered to have amembermK, and so on.Thehost interfaces ofmI,mJ,andmK, areI,J, andK respectively.
Note: In JavaScript, this implies that eachregular operation declared as amember ofinterface mixinM,and exposed as a data property with abuilt-in function object value,is a distinctbuilt-in function object in eachinterface prototype object whose associatedinterfaceincludesM.Similarly, forattributes, each copy of the accessor property hasdistinctbuilt-in function objects for its getters and setters.
The order of appearance ofincludes statements affects the order in whichinterface mixin areincluded by theirhost interface.
Member order isn’t clearly specified,in particular wheninterface mixins are defined in separate documents.It is discussed inissue #432.
Noextended attributes defined in this specification are applicable toincludes statements.
The followingIDL fragment defines aninterface,Entry
, and aninterface mixin,Observable
. Theincludes statement specifies thatObservable
’smembers are always included on objects implementingEntry
.
interface Entry {readonly attribute unsigned short entryType ; // ...};interface mixin Observable {undefined addEventListener (DOMString type ,EventListener listener ,boolean useCapture ); // ...};Entry includes Observable ;
A JavaScript implementation would thus have anaddEventListener
property in the prototype chain of everyEntry
:
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 OptionalReadOnly AttributeRest
IncludesStatement ::identifier includes identifier ;
2.3.1.Using mixins and partials
This section is informative.
Interface mixins allow the sharing ofattributes,constants, andoperations acrossmultipleinterfaces.If you’re only planning to extend a single interface,you might consider using apartial 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 extendinginterface mixins exposed by other specificationsto target common use cases, such asexposing a set ofattributes,constants, oroperations 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 theWindowOrWorkerGlobalScope
interface mixin using apartial interface mixin:
partial interface mixin WindowOrWorkerGlobalScope {readonly attribute Crypto crypto ;};
2.4.Callback interfaces
Acallback interface is adefinition matching
Note: Acallback interface is not aninterface. The name and syntax are left over fromearlier versions of this standard, where these concepts had more in common.
Acallback interface is a specification of a set ofcallback interface members (matching
callback interface identifier { /* interface_members... */};
Note: See also the similarly namedcallback function definition.
Callback interfaces must define exactly oneregular operation.
Specification authors should not definecallback interfaces unless required to describe the requirements of existing APIs. Instead, acallback function should be used.
The definition ofEventListener
as acallback interface is an example of an existing API that needs to allow objects with a given property (in this casehandleEvent
) to be considered to implement the interface. For new APIs, and those for which there are no compatibility concerns, using acallback function will allow only afunction object (in the JavaScript language binding).
Callback interfaces which declareconstants 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, andnamespaces are specifications of a set ofmembers (respectively matching
When aninterfaceincludes aninterface mixin, eachmember of the interface mixin is also considered a member of the interface. In contrast,inherited interface members are not considered members of the interface.
Theconstructor steps,getter steps,setter steps, andmethod steps for the variousmembers defined on aninterface orinterface mixin have access to athis value, which is an IDL value of theinterface type that the member isdeclared on or thatincludes theinterface mixin the member is declared on.
Setter steps also have access tothe given value,which is an IDL value of the type theattribute is declared as.
Interfaces,interface mixins,callback interfaces andnamespaces each support adifferent set ofmembers,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:
2.5.1.Constants
Aconstant 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 byfiling an issue before proceeding.
const type constant_identifier = 42;
Theidentifier of aconstant must not be the same as the identifierof anotherinterface member orcallback interface member defined on the sameinterface orcallback interface.The identifier also must notbe "length
", "name
" or "prototype
".
Note: These three names are the names of properties that are defined on theinterface object in the JavaScript 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 thedefault value of a dictionary member orof an optional argument.Note that strings, theempty sequence
The value of the boolean literal tokensboolean
valuestrue
andfalse
.
The value of an
LetS be the sequence ofscalar values matched by the
integer token.Letsign be −1 ifS begins with U+002D (-), and 1 otherwise.
Letbase be the base of the number based on thescalar values that follow the optional leading U+002D (-):
- U+0030 (0), U+0058 (X)
- U+0030 (0), U+0078 (x)
The base is 16.
- U+0030 (0)
The base is 8.
- Otherwise
The base is 10.
Letnumber be the result of interpreting all remainingscalar values following the optional leading U+002D (-)character and anyscalar values indicating the base as an integer specified in basebase.
Returnsign ×number.
The type of an
LetS be the sequence ofscalar values matched by the
decimal token.Letresult be the Mathematical Value that would be obtained ifS were parsed as a JavaScript
NumericLiteral .If the
decimal token is beingused as the value for afloat
orunrestricted float
, thenthe value of thedecimal tokenis the IEEE 754 single-precision floating point number closest toresult.Otherwise, the
decimal token is beingused as the value for adouble
orunrestricted double
, andthe value of thedecimal tokenis the IEEE 754 double-precision floating point number closest toresult.[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 afloat
ordouble
.
The value of the
IfVT is the type of the value assigned to a constant, andDT is the type of the constant, dictionary member or optional argument itself, then these types mustbe compatible, which is the case ifDT andVT are identical,orDT is anullable type whoseinner type isVT.
Constants are not associated withparticular instances of theinterface orcallback interface on which they appear. It is language binding specific whetherconstants are exposed on instances.
The JavaScript language binding does however allowconstants to be accessed through objects implementing the IDLinterfaces on which theconstants are declared. For example, with the following IDL:
[Exposed =Window ]interface A {const short rambaldi = 47;};
the constant value can be accessed in JavaScript either asA.rambaldi
orinstanceOfA.rambaldi
.
The following extended attributes are applicable to constants:[CrossOriginIsolated
],[Exposed
], and[SecureContext
].
Const ::const ConstType identifier = ConstValue ;
ConstValue ::BooleanLiteral FloatLiteral integer
BooleanLiteral ::true false
FloatLiteral ::decimal -Infinity Infinity NaN
ConstType ::PrimitiveType identifier
The followingIDL fragment demonstrates howconstants 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
Anattribute is aninterface member ornamespace member (matching
regular attributes, which are thoseused to declare that objects implementing theinterface will have a data field member with the givenidentifier
interface interface_identifier {attribute type identifier ;};static attributes, which are usedto 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
Thegetter steps of an attributeattr should be introduced using text of the form “Theattr
getter steps are:” followed by a list, or “Theattr
getter stepsare to” followed by an inline description.
Thesetter steps of an attributeattr should be introduced using text of the form “Theattr
setter steps are:” followed by a list, or “Theattr
setter stepsare to” followed by an inline description.
Note: When defininggetter steps, you implicitly have access tothis.When definingsetter steps, you implicitly have access tothis andthe given value.
Theidentifier of anattribute must not be the same as the identifierof anotherinterface member defined on the sameinterface.The identifier of a static attribute must notbe "prototype
".
The type of the attribute is given by the type (matching
The type of the attribute, after resolving typedefs, must not be anullable or non-nullable version of any of the following types:
aunion type that has a nullable or non-nullable sequence type, dictionary,or recordas one of itsflattened member types
The attribute isread only if the
interface interface_identifier {readonly attribute type identifier ;};
Attributes whose type is apromise type must beread only. Additionally, they cannot haveany of theextended attributes [LegacyLenientSetter
], [PutForwards
], [Replaceable
], or[SameObject
].
Aregular attribute that is notread only can be declared toinherit its getter from an ancestor interface. This can be used to make a read only attributein an ancestor interface be writable on a derived interface. An attributeinherits its getter ifits 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 followingextended attributes are applicable to regular and static attributes:[CrossOriginIsolated
],[Exposed
],[SameObject
], and[SecureContext
].
The followingextended attributes are applicable only to regular attributes:[LegacyLenientSetter
],[LegacyLenientThis
],[PutForwards
],[Replaceable
],[LegacyUnforgeable
].
ReadOnlyMember ::readonly ReadOnlyMemberRest
ReadOnlyMemberRest ::AttributeRest MaplikeRest SetlikeRest
ReadWriteAttribute ::AttributeRest
InheritAttribute ::inherit AttributeRest
AttributeRest ::attribute TypeWithExtendedAttributes AttributeName ;
AttributeName ::AttributeNameKeyword identifier
AttributeNameKeyword ::async required
OptionalReadOnly ::readonly ε
The followingIDL fragment demonstrates howattributes can be declared on aninterface:
[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
Anoperation is aninterface member,callback interface member ornamespace member (matching
regular operations, whichare those used to declare that objects implementing theinterface will have a method withthe givenidentifier
interface interface_identifier {return_type identifier (/* arguments... */);};special operations,which are used to declare special behavior on objectsimplementing 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 witha 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 operationusing one of the special keywords.
The identifier of aregular operation orstatic operation must not be the same as the identifierof aconstant orattribute defined on the sameinterface,callback interface ornamespace.The identifier of a static operation must not be "prototype
".
Note: The identifier can be the sameas that of another operation on the interface, however.This is how operation overloading is specified.
Note: Theidentifier of astatic operation can be the same as the identifierof aregular operation defined on the sameinterface.
Thereturn type of the operation is givenby the type (matching
An operation’s arguments (matching
Note: For expressiveness, the identifier of an operation argument can also be specifiedas one of the keywords matching the
If the
If the operation argument type, after resolving typedefs,is anullable type,itsinner type must not be adictionary type.
interface interface_identifier {return_type identifier (type identifier ,type identifier /* , ... */);};
The identifier of each argument must not be the sameas the identifier of another argument in the same operation declaration.
Each argument can be preceded by a list ofextended attributes (matching
interface interface_identifier {return_type identifier ([extended_attributes ]type identifier , [extended_attributes ]type identifier /* , ... */);};
The followingIDL fragment demonstrates howregular operations can be declared on aninterface:
[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.undefined setDimensions (Dimensions size );undefined setDimensions (unsigned long width ,unsigned long height );};
An operation orconstructor operation is considered to bevariadic if the final argument uses the
interface interface_identifier {return_type identifier (type ...identifier );return_type identifier (type identifier ,type ...identifier );};
Extended attributes thattake an argument list ([LegacyFactoryFunction
], of thosedefined in this specification) andcallback functions are also considered to bevariadic when the
The followingIDL fragment defines an interface that has two variadic operations:
[Exposed =Window ]interface IntegerSet {readonly attribute unsigned long cardinality ;undefined union (long ...ints );undefined intersection (long ...ints );};
In the JavaScript 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 anoptional argument if it is declared with the
interface interface_identifier {return_type identifier (type identifier ,optional type identifier );};
Optional arguments can also have adefault value specified. If the argument’s identifier is followed by a U+003D (=)and a value (matching
interface interface_identifier {return_type identifier (type identifier ,optional type identifier = "value");};
It is strongly suggested not to use adefault value ofboolean
-typed arguments, as this can be confusing for authors who might otherwise expect the default conversion of
If the type of an argument is adictionary type or aunion type that hasadictionary type as oneof itsflattened member types, and that dictionary type and its ancestors have norequiredmembers, and the argument is either the final argument or isfollowed only byoptional arguments, then the argument must be specified asoptional 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 (
When theundefined
value.
LetS be the sequence ofscalar values matched bythe
string tokenwith its leading and trailing U+0022 (")scalar values removed.Depending on the type of the argument:
DOMString
USVString
- anenumeration type
The value of the
string tokenisS.ByteString
Assert:S doesn’t contain anycode points higher than U+00FF.
The value of the
string tokenis theisomorphic encoding ofS.
If the type of theoptional argument is anenumeration, then itsdefault value if specified mustbe one of theenumeration’s values.
Optional argument default values can also be specified using thetwo token value
Optional argument default values can also be specified using the two token value
The followingIDL fragment defines aninterface with a singleoperation 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 aninterface that has twooverloadedoperations:
[Exposed =Window ]interface ColorCreator {object createColor (double v1 ,double v2 ,double v3 );object createColor (double v1 ,double v2 ,double v3 ,double alpha );};
The followingIDL fragment defines aninterface with an operation that takes a dictionary argument:
dictionary LookupOptions {boolean caseSensitive =false ;};[Exposed =Window ]interface AddressBook {boolean hasAddressForName (USVString name ,optional LookupOptions options = {});};
IfhasAddressForName
is called with only one argument, the second argument will be a default-initializedLookupOptions
dictionary, which will causecaseSensitive
to be set to
The following extended attributes are applicable to operations:[CrossOriginIsolated
],[Default
],[Exposed
],[LegacyUnforgeable
],[NewObject
], and[SecureContext
].
Themethod steps of an operationoperation should be introduced using text of the form“Theoperation(arg1,arg2, ...)
methodsteps are:” followed by a list, or “Theoperation(arg1,arg2, ...)
method steps are to” followed by an inline description.
Note: When definingmethod steps, you implicitly have access tothis.
DefaultValue ::ConstValue string [ ] { } null undefined
Operation ::RegularOperation SpecialOperation
RegularOperation ::Type 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
2.5.3.1.toJSON
By declaring atoJSON
regular operation,aninterface specifies how to convert the objects that implement it toJSON types.
ThetoJSON
regular operation is reserved for this usage.It must take zero arguments and return aJSON type.
TheJSON types are:
nullable types whoseinner type is aJSON type,
annotated types whoseinner type is aJSON type,
union types whosemember types areJSON types,
typedefs whosetype being given a new name is aJSON type,
sequence types whose parameterized type is aJSON type,
frozen array types whose parameterized type is aJSON type,
dictionary types where the types of allmembers declared on the dictionary and all itsinherited dictionaries areJSON types,
records where all of theirvalues areJSON types,
interface types that have a
toJSON
operation declared on themselves orone of theirinherited interfaces.
How thetoJSON
regular operation is made available on an object in a language binding,and how exactly theJSON types are converted into a JSON string,is language binding specific.
Note: In the JavaScript language binding,this is done by exposing atoJSON
methodwhich returns theJSON type converted into a JavaScript valuethat can be turned into a JSON stringby theJSON.stringify()
function.Additionally, in the JavaScript language binding,thetoJSON
operation can take a [Default
]extended attribute,in which case thedefault toJSON steps are exposed instead.
The followingIDL fragment defines an interfaceTransaction
that has atoJSON
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 ;};
ThetoJSON
regular operation ofTransaction
interface could be defined as follows:
ThetoJSON()
method steps are:
Letjson be a newmap.
For each attributeidentifierattr in « "from", "to", "amount", "description" »:
Letvalue be the result of running thegetter steps ofattr onthis.
Setjson[attr] tovalue.
Returnjson.
In the JavaScript language binding, there would exist atoJSON()
method onTransaction
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 aninterface has aconstructor operation member (matching
Multipleconstructor operations may appear on a giveninterface.For eachconstructor operation on theinterface, there will be a way to attempt toconstruct an instance by passing the specified arguments.
Theconstructor steps of aconstructor operation that is a member of an interfacenamedinterface should be introduced using text of the form “Thenewinterface(arg1,arg2, ...)
constructor stepsare:” followed by a list, or “Thenewinterface(arg1,arg2, ...)
constructor stepsare to” followed by an inline description.
Theconstructor steps must do nothing, initialize the value passed asthis, or throw anexception.
If the constructor does not initializethis, one can write “Thenew Example(init)
constructorsteps are to do nothing.”
See§ 3.7.1 Interface object for details on how aconstructor operation is to be implemented.
The following IDL defines two interfaces. The second hasconstructor 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 ;};
A JavaScript implementation supporting these interfaces would implement a [[Construct]] internal method on theCircle
interface object which would return a new object thatimplements the interface. It would take either zero or one argument.
It is unclear whether theNodeList
interface object would implement a [[Construct]] internal method. In any case, trying to use it as a constructor will cause aTypeError
to be thrown.[whatwg/webidl Issue #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.Stringifiers
When aninterface has astringifier, it indicates that objectsthat implement the interface have a non-default conversion to a string. Stringifiers can bespecified using a
interface interface_identifier {stringifier ;};
Prose accompanying the interface must definethestringification behavior of the interface.
TheDOMString
orUSVString
.It also must not be placed onastatic attribute.
interface interface_identifier {stringifier attribute DOMString identifier ;};
On a giveninterface, there must exist at most one stringifier.
Stringifier ::stringifier StringifierRest
StringifierRest ::OptionalReadOnly AttributeRest ;
The followingIDL fragment defines an interface that will stringify to the value of itsname
attribute:
[Exposed =Window ]interface Student {constructor ();attribute unsigned long id ;stringifier attribute DOMString name ;};
In the JavaScript binding, using aStudent
object in a context where a string is expected will result in the value of the object’sname
property being used:
var s= new Student(); s. id= 12345678 ; s. name= '周杰倫' ; var greeting= 'Hello, ' + s+ '!' ; // Now greeting == 'Hello, 周杰倫!'.
The followingIDL 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 ;};
Thus, there needs to be prose to explain the stringification behavior. We assume that thefamilyName
andgivenName
attributes are backed by family name and given name concepts, respectively.
Thestringification behavior steps are:
A JavaScript 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.6.Special operations
Aspecial operation is adeclaration of a certain kind of special behavior on objects implementingthe interface on which the special operation declarations appear.Special operations are declared by using aspecial keyword in an operation declaration.
There are three kinds of special operations. The table below indicatesfor a given kind of special operation what special keywordis 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. |
Not all language bindings support all of the four kinds of specialobject behavior. When special operations are declared usingoperations with no identifier, then in language bindings that donot support the particular kind of special operations there simplywill 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 undefined (DOMString propertyName ,double propertyValue );};
In language bindings that do not support property getters and setters, objects implementingDictionary will not have that special behavior.
Defining a special operation with anidentifier is equivalent to separating the special operation out into its owndeclaration without an identifier. This approach is allowed tosimplifymethod steps 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 undefined setProperty (DOMString propertyName ,double propertyValue );};
[Exposed =Window ]interface Dictionary {readonly attribute unsigned long propertyCount ;double getProperty (DOMString propertyName );undefined setProperty (DOMString propertyName ,double propertyValue );getter double (DOMString propertyName );setter undefined (DOMString propertyName ,double propertyValue );};
A givenspecial keyword must notappear twice on an operation.
Getters and setters come in two varieties: ones thattake aDOMString
as a property name,known asnamed property getters andnamed property setters,and ones that take anunsigned long
as a property index, known asindexed property getters andindexed property setters.There is only one variety of deleter:named property deleters.See§ 2.5.6.1 Indexed properties and§ 2.5.6.2 Named properties for details.
On a giveninterface,there must exist at most onenamed 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 thatvariety. If it has anamed property deleter,then it must also have anamed property getter.
Special operations declared using operations must notbevariadic nor have anyoptional arguments.
If an object implements more than oneinterface that defines a given special operation, then it is undefined which (if any)special operation is invoked for that operation.
2.5.6.1.Indexed properties
Aninterface that defines anindexed property getter is said tosupport indexed properties.By extension, aplatform object is said tosupport indexed properties ifit implements aninterface that itself does.
If an interfacesupports indexed properties,then the interface definition must be accompanied bya description of what indices the object can be indexed with atany given time. These indices are called thesupported property indices.
Interfaces thatsupport indexed properties must defineaninteger-typedattribute named "length
".
Indexed property getters mustbe declared to take a singleunsigned long
argument.Indexed property setters mustbe declared to take two arguments, where the first is anunsigned 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 anindexed property getter was specified using anoperation with anidentifier,then the value returned when indexing the object with a givensupported property index is the value that would be returned by invoking the operation, passingthe index as its only argument. If the operation used to declare the indexed property getterdid not have an identifier, then the interface definition must be accompaniedby a description of how todetermine the value of an indexed property for a given index.
If anindexed property setter was specified using an operationwith an identifier,then the behavior that occurs when indexing the object for property assignment with a given supported property index and valueis the same as if the operation is invoked, passingthe index as the first argument and the value as the second argument. If the operation used to declare the indexed property setterdid not have an identifier, then the interface definition must be accompaniedby a description of how toset the value of an existing indexed property and how toset the value of a new indexed property for a given property index and value.
Note that if anindexed property getter orsetter is specified using anoperation with anidentifier, then indexing an object with an integer that is not asupported 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 JavaScript 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 implementingA
hassupported 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 theoperation 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 followingIDL fragment defines an interfaceOrderedMap
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 undefined setByIndex (unsigned long index ,any value );getter any get (DOMString name );setter undefined 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 theget()
operation is defined to returnOrderedMap
, then the following two sentences would suffice:
An objectmap 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, a JavaScript implementation would create properties on alegacy platform object implementingOrderedMap
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.6.2.Named properties
Aninterface that defines anamed property getter is said tosupport named properties.By extension, aplatform object is said tosupport named properties ifit implements aninterface that itself does.
If an interfacesupports named properties,then the interface definition must be accompanied bya description of the ordered set of names that can be used to index the objectat any given time. These names are called thesupported property names.
Named property getters and deleters mustbe declared to take a singleDOMString
argument.Named property setters mustbe declared to take two arguments, where the first is aDOMString
.
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 anamed property getter was specified using anoperation with anidentifier,then the value returned when indexing the object with a givensupported property name is the value that would be returned by invoking the operation, passingthe name as its only argument. If the operation used to declare the named property getterdid not have an identifier, then the interface definition must be accompaniedby a description of how todetermine the value of a named property for a given property name.
If anamed property setter was specified using an operationwith an identifier,then the behavior that occurs when indexing the object for property assignment with a given supported property name and valueis the same as if the operation is invoked, passingthe name as the first argument and the value as the second argument. If the operation used to declare the named property setterdid not have an identifier, then the interface definition must be accompaniedby a description of how toset the value of an existing named property and how toset the value of a new named property for a given property name and value.
If anamed property deleter was specified using an operationwith an identifier,then the behavior that occurs when indexing the object for property deletion with a given supported property nameis the same as if the operation is invoked, passingthe name as the only argument. If the operation used to declare the named property deleterdid not have an identifier, then the interface definition must be accompaniedby a description of how todelete an existing named property for a given property name.
Note: As withindexed properties,if annamed property getter,setter ordeleter is specified using anoperation with anidentifier,then indexing an object with a name that is not asupported property name does not necessarily elicit the same behavior as invoking the operation with that name; the behavioris language binding specific.
2.5.7.Static attributes and operations
Static attributes andstatic operations are ones thatare not associated with a particular instance of theinterface on which it is declared, and is instead associated with the interfaceitself. Static attributes and operations are declared by using the
It is language binding specific whether it is possible to invokea static operation or get or set a static attribute through a referenceto an instance of the interface.
StaticMember ::static StaticMemberRest
StaticMemberRest ::OptionalReadOnly AttributeRest RegularOperation
The followingIDL fragment defines an interfaceCircle
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 JavaScript language binding, thefunction object fortriangulate
and the accessor property fortriangulationCount
will exist on theinterface object forCircle
:
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.8.Overloading
If aregular operation orstatic operation defined on aninterface has anidentifier that is the same as the identifier of another operation on thatinterface of the same kind (regular or static), then the operation is said to beoverloaded. When the identifierof an overloaded operation is used to invoke one of theoperations on an object that implements the interface, thenumber and types of the arguments passed to the operationdetermine which of the overloaded operations is actuallyinvoked.Constructor operations can be overloaded too.There are some restrictions on the argumentsthat overloaded operations and constructors can bespecified to take, and in order to describe these restrictions,the notion of aneffective overload set is used.
A set of overloadedoperations must either:
contain nooperations whosereturn type is apromise type;
only containoperations whosereturn type is apromise type.
Operations must not be overloaded acrossinterface,partial interface,interface mixin, andpartial interface mixin definitions.
For example, the overloads for bothf andg are disallowed:
[Exposed =Window ]interface A {undefined f ();};partial interface A {undefined f (double x );undefined g ();};partial interface A {undefined g (DOMString x );};
Note thatconstructor operations and [LegacyFactoryFunction
]extended attributes are disallowed from appearing onpartial interface definitions, so there is no need to also disallow overloading for constructors.
Aneffective overload set represents the allowable invocations for a particularoperation,constructor (specified with aconstructor operation or [LegacyFactoryFunction
]), orcallback function.The algorithm tocompute the effective overload set operates on one of the following four types of IDL constructs, and listed with them below arethe inputs to the algorithm needed to compute the set.
- For regular operations
- For static operations
theinterface on which theoperations are to be found
theidentifier of the operations
the number of arguments to be passed
- For constructors
theinterface on which theconstructor operations are to be found
the number of arguments to be passed
- For legacy factory functions
theinterface on which the [
LegacyFactoryFunction
]extended attributes are to be foundtheidentifier of the legacy factory function
the number of arguments to be passed
Aneffective overload set is used, among other things, to determine whether there areambiguities in the overloaded operations and constructors specified on an interface.
Theitems of aneffective overload set aretuples of the form(callable,type list,optionality list)whoseitems are described below:
Acallable is anoperation if theeffective overload set is forregular operations,static operations, orconstructor operations; and it is anextended attribute if theeffective overload set is forlegacy factory functions.
Atype list is alist of IDL types.
Anoptionality list is alist ofthree possibleoptionality values – "required", "optional" or "variadic" –indicating whether the argument at a given index wasdeclared as beingoptional or corresponds to avariadic argument.
Eachtuple represents an allowable invocation of the operation,constructor, or callback function with an argument value list of the given types.Due to the use ofoptional arguments andvariadic operationsand constructors, there may be multiple items in aneffective overload set identifyingthe same operation or constructor.
the identifier of the operation or legacy factory function isA
the argument count isN
the interface isI
Whenever an argument of an extended attribute is mentioned, it is referring to an argument of the extended attribute’snamed argument list.
LetS be anordered set.
LetF be anordered set withitems as follows,according to the kind ofeffective overload set:
- For regular operations
The elements ofF are theregular operations withidentifierA defined on interfaceI.
- For static operations
The elements ofF are thestatic operations withidentifierA defined on interfaceI.
- For constructors
The elements ofF are theconstructor operations on interfaceI.
- For legacy factory functions
The elements ofF are the[
LegacyFactoryFunction
]extended attributes on interfaceI whosenamed argument lists' identifiers areA.
Letmaxarg be the maximum number of arguments the operations,legacy factory functions, or callback functions inF are declared to take.Forvariadic operations and legacy factory functions,the argument on which the ellipsis appears counts as a single argument.
Note: So
undefined f(long x, long... y);
is considered to be declared to take two arguments.Letmax bemax(maxarg,N).
For each operation or extended attributeX inF:
Letarguments be thelist of argumentsX is declared to take.
Letn be thesize ofarguments.
Lettypes be atype list.
LetoptionalityValues be anoptionality list.
For eachargument inarguments:
IfX is declared to bevariadic, then:
Leti ben − 1.
Whilei ≥ 0:
Ifarguments[i] is notoptional (i.e., it is not marked as "optional" and is nota final, variadic argument), thenbreak.
Lett be atype list.
Leto be anoptionality list.
Note: ifi is 0, this means to add toS the tuple (X, « », « »);(where "« »" represents anempty list).
Seti toi − 1.
ReturnS.
For the following interface:
[Exposed =Window ]interface A { /* f1 */undefined f (DOMString a ); /* f2 */undefined f (Node a ,DOMString b ,double ...c ); /* f3 */undefined f (); /* f4 */undefined f (Event a ,DOMString b ,optional DOMString c ,double ...d );};
assumingNode
andEvent
are two other interfaces of which no object can implement both, theeffective overload set forregular operations with identifierf
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 aredistinguishable ifthe following algorithm returnstrue.
If one typeincludes a nullable type and the other type eitherincludes a nullable type,is aunion type withflattened member types including adictionary type, oris adictionary type,returnfalse.
If both types are either aunion type ornullableunion type,returntrue if each member type of the oneis distinguishable with each member type of the other,orfalse otherwise.
If one type is aunion type or nullable union type,returntrue if eachmember type of the union type is distinguishablewith the non-union type,orfalse otherwise.
Consider the two "innermost" types derived by taking each type’sinner type if it is anannotated type, and then taking itsinner type inner typeif the result is anullable type. If these two innermost types appear or are in categoriesappearing in the following table and there is a “●” mark in the corresponding entryor there is a letter in the corresponding entry and the designated additionalrequirement below the table is satisfied, then returntrue.Otherwise returnfalse.
Categories:
- interface-like
- dictionary-like
- sequence-like
undefinedbooleannumeric typesbigintstring typesobjectsymbolinterface-likecallback functiondictionary-likeasync iterablesequence-likeundefined ● ● ● ● ● ● ● ● ● ● boolean ● ● ● ● ● ● ● ● ● ● numeric types (b) ● ● ● ● ● ● ● ● bigint ● ● ● ● ● ● ● ● string types ● ● ● ● ● (d) ● object ● symbol ● ● ● ● ● interface-like (a) ● ● ● ● callback function (c) ● ● dictionary-like ● ● async iterable sequence-like The two identified interface-like types arenot the same, and no singleplatform object implements bothinterface-like types.
The types are distinguishable, but there isa separate restriction on their use inoverloading below. Please also notetheadvice about using unions of these types.
Acallback function that does not have[
LegacyTreatNonObjectAsNull
] extended attribute isdistinguishable from a type in the dictionary-like category.For example, when converting an ECMAScript value tounion type which includes acallback function and a dictionary-like type, if the value iscallable, then it is converted to acallback function. Otherwise, it is converted to a dictionary-like type.The types are distinguishable, but when converting from an ECMAScript value,astring object is never converted to anasync iterable type (even if it has a
%Symbol.iterator%
method), if astring type is also in the overload set or union.
double
andDOMString
are distinguishable because there is a ● at the intersection ofnumeric types withstring types.double
andlong
are not distinguishable because they are bothnumeric types, and there is no ● or letter at the intersection ofnumeric types withnumeric types.Given:callback interface CBIface {undefined 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 oneitem in aneffective overload set that has a giventype listsize,then for those items there must be an indexi such thatfor each pair of items the types at indexi aredistinguishable.The lowest such index is termed thedistinguishing argument index for the items of theeffective overload set with the given type list size.
Aneffective overload set must not contain more thanoneitem with the sametype listsize, where oneitem has abigint
argument at thedistinguishing argument index and another has anumeric type argument at thedistinguishing argument index.
Consider theeffective 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, thedistinguishing argument index is 0, sinceNode
andEvent
aredistinguishable.
The following use of overloading however is invalid:
[Exposed =Window ]interface B {undefined f (DOMString x );undefined f (USVString x );};
In addition, for each indexj, wherej is less than thedistinguishing argument index for a given type list size, the types at indexj inall of the items' type lists must be the same,and theoptionality values at indexj in all of the items' optionality lists mustbe the same.
The following is invalid:
[Exposed =Window ]interface B { /* f1 */undefined f (DOMString w ); /* f2 */undefined f (long w ,double x ,Node y ,Node z ); /* f3 */undefined f (double w ,double x ,DOMString y ,Node z );};
For argument count 4, theeffective 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, thedistinguishing argument index is 2, sinceNode
andDOMString
aredistinguishable. However, since the arguments in these two overloads at index 0 are different, the overloading is invalid.
2.5.8.1.Overloading vs. union types
This section is informative.
For specifications defining IDLoperations, it might seem thatoverloads and acombination ofunion types andoptional arguments have some feature overlap.
It is first important to note thatoverloads have different behaviors thanunion types oroptional arguments, and onecannot 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 thestroke()
operations defined on theCanvasDrawPath
interface[HTML]:
interface CanvasDrawPathExcerpt {undefined stroke ();undefined stroke (Path2D path );};
Per the JavaScript language binding, callingstroke(undefined)
on an objectimplementingCanvasDrawPathExcerpt
would attempt to call the secondoverload, yielding aTypeError
sincePath2D
. However, if the operations were insteaddefined withoptional arguments and merged into one,
interface CanvasDrawPathExcerptOptional {undefined stroke (optional Path2D path );};
theoverload resolution algorithm would treat thepath argument as missinggiven the same callstroke(undefined)
, and not throw any exceptions.
Note: For this particular example, the latter behavior is actually what Web developers wouldgenerally expect. IfCanvasDrawPath
were to be designed today,optional arguments would beused forstroke()
.
Additionally, there are semantic differences as well.Union types are usually used in the sensethat "any of the types would work in about the same way". In contrast,overloaded operations aredesigned to map well to language features such as C++ overloading, and are usually a better fit foroperations 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 differentnames to avoid confusion for Web developers, since the JavaScript language does not providelanguage-level overloading. As such, overloads are rarely appropriate for new APIs, instead oftenappearing in legacy APIs or in specialized circumstances.
That being said, we offer the following recommendations and examples in case of difficulties todetermine what Web IDL language feature to use:
In the unusual case where the operation needs to return values of different types for differentargument types,overloading will result in more expressive IDL fragments.This is almost never appropriate API design, and separate operations with distinctnames usually are a better choice for such cases.
Suppose there is an operation
calculate()
that accepts along
,DOMString
, orCalculatableInterface
(aninterface type) as itsonly argument, and returns a value of the same type as its argument. It would be clearer towrite the IDL fragment usingoverloaded operations asinterface A {long calculate (long input );DOMString calculate (DOMString input );CalculatableInterface calculate (CalculatableInterface input );};than using aunion type with atypedef 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 asinput.
If the specified
calculate()
is a new API and does not have anycompatibility 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 orlengths,overloading is preferred. Again, in such scenarios, it is usually betterto create separate operations with distinct names, but legacy APIs sometimes follow thispattern.
As an example, the
supports(property, value)
andsupports(conditionText)
operations of theCSS
interface are defined as thefollowing IDL fragment[CSS3-CONDITIONAL][CSSOM].partial interface CSS {static boolean supports (CSSOMString property ,CSSOMString value );static boolean supports (CSSOMString conditionText );};Usingoptional 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 areconflated in the first argument. Withoutoverloads, the question "isproperty orconditionText paired withvalue?"is much more difficult to answer without reading themethod steps of the operation. Thismakes the second version remarkably less readable than the first.
Another consideration is that themethod steps foroverloaded operations can bespecified in separate blocks, which can aid in both reading and writing specifications. This isnot the case foroptional arguments. This means that in the first case the specificationauthor can write themethod steps of the operations as:
The
supports(property,value)
method steps are:…
The
supports(conditionText)
method steps are:…
Yet usingvalue as anoptional argument, the specification author has touse more boilerplate-style text to effectively replicate theoverload resolution algorithm.
The
supports(propertyOrConditionText,value)
method steps are:Ifvalue is given, then:
Letproperty bepropertyOrConditionText.
…
Otherwise:
LetconditionText bepropertyOrConditionText.
…
If the two overloads have little to no shared parts, it is better to leave overload resolutionto the IDL mechanism.
If the operation accepts multiple types for multiple arguments with no coupling between types ofdifferent arguments,union types can sometimes be the only viable solution.
typedef (long long or DOMString or CalculatableInterface )SupportedArgument ;interface A {undefined add (SupportedArgument operand1 ,SupportedArgument operand2 );};For the
add()
operation above, to specify it usingoverloads would requireinterface A {undefined add (long long operand1 ,long long operand2 );undefined add (long long operand1 ,DOMString operand2 );undefined add (long long operand1 ,CalculatableInterface operand2 );undefined add (DOMString operand1 ,long long operand2 );undefined add (DOMString operand1 ,DOMString operand2 );undefined add (DOMString operand1 ,CalculatableInterface operand2 );undefined add (CalculatableInterface operand1 ,long long operand2 );undefined add (CalculatableInterface operand1 ,DOMString operand2 );undefined 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 JavaScript language binding.Given the following IDL fragment:
interface A {undefined foo ();undefined foo (Node ?arg );};Using the JavaScript language binding, calling
foo(undefined)
andfoo(null)
would both run the steps corresponding to thefoo(arg)
operation, witharg set to null, whilefoo()
alonewould go to the first overload. This can be a surprising behavior for many API users. Instead,specification authors are encouraged to use anoptional argument, which would categorizebothfoo()
andfoo(undefined)
as "arg is missing".interface A {undefined foo (optional Node ?arg );};In general, optionality is best expressed using the
optional keyword, and notusing overloads.
When the case fits none of the categories above, it is up to the specification author to choose thestyle, since it is most likely that either style would sufficiently and conveniently describe theintended behavior. However, the definition andconversion algorithms ofunion types andoptional arguments are simpler to implement and reason about thanthose ofoverloads, and usually result in more idiomatic APIsin the JavaScript language binding. Thus, unless any other considerations apply,union types,optional arguments, or both are the default choice.
Specifications are also free to mix and match union types and overloads, if the author finds itappropriate and convenient.
2.5.9.Iterable declarations
Aninterface can be declared to beiterable by using aniterable declaration (matching
interface interface_identifier {iterable <value_type >;iterable <key_type ,value_type >;};
Objects implementing an interface that is declared to be iterablesupport being iterated over to obtain a sequence of values.
Note: In the JavaScript language binding, an interface that is iterablewill haveentries
,forEach
,keys
,values
, and%Symbol.iterator%
properties on itsinterface prototype object.
If a single type parameter is given, then the interface has avalue iterator and providesvalues of the specified type.If two type parameters are given, then the interface has apair iterator and providesvalue pairs with the given types.
Avalue pair, given a key type and a value type, is astruct with twoitems:
anitem whosename is "key", which is referred to as thevalue pair’skey, and whose value is an IDL value of the key type;
anitem whosename is "value", which is referred to as thevalue pair’svalue, and whose value is an IDL value of thevalue type.
Avalue iterator must only be declared on an interfacethatsupports indexed properties.The value-type of thevalue iterator must be the same as the type returned bytheindexed property getter.Avalue iterator is implicitlydefined to iterate over the object’s indexed properties.
Apair iterator must not be declared on an interfacethatsupports indexed properties.
Prose accompanying aninterface with apair iterator must define alist ofvalue pairs for each instance of theinterface, which is the list ofvalue pairs to iterate over.
The JavaScript forEach method that is generated for avalue iterator invokes its callback like Array.prototype.forEach does, and the forEach method for apair iterator invokes its callback like Map.prototype.forEach does.
Sincevalue iterators are currently allowed only on interfaces thatsupport indexed properties, it makes sense to use an Array-like forEach method. There could be a need forvalue iterators (a) on interfaces that do notsupport 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, pleasefile an issue.
Note: This is howarray iterator objects work.For interfaces thatsupport indexed properties,the iterator objects returned byentries
,keys
,values
, and%Symbol.iterator%
areactualarray iterator objects.
Interfaces with aniterable declaration must not have anyattributes,constants, orregular operations named "entries
", "forEach
", "keys
", or"values
", or have anyinherited interfaces that haveattributes,constants,orregular operations with these names.
Consider the following interfaceSessionManager
, which allows access to a number ofSession
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:
Thevalue pairs to iterate over are the list ofvalue pairs with thekey being the username and thevalue being the open
Session
object on theSessionManager
object corresponding to that username, sorted by username.
In the JavaScript language binding, theinterface prototype object for theSessionManager
interface has avalues
method that is a function, which, when invoked, returns an iterator object that itself has anext
method that returns the next value to be iterated over. It haskeys
andentries
methods that iterate over the usernames of session objects and username/Session
object pairs, respectively. It also has a%Symbol.iterator%
method that allows aSessionManager
to be used in afor..of
loop that has the same value as theentries
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 oneiterable declaration.Theinherited interfaces of an interface with aniterable declaration must not also have aniterable declaration.An interface with aniterable declaration and itsinherited interfaces must not have amaplike declaration,setlike declaration, orasynchronously iterable declaration.
The following extended attributes are applicable toiterable declarations:[CrossOriginIsolated
],[Exposed
], and[SecureContext
].
Iterable ::iterable < TypeWithExtendedAttributes OptionalType > ;
OptionalType ::, TypeWithExtendedAttributes ε
2.5.10.Asynchronously iterable declarations
Aninterface can be declared to be asynchronously iterable by using anasynchronously 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 thatimplement aninterface that is declared to be asynchronously iterable supportbeing iterated over asynchronously to obtain a sequence of values.
If a single type parameter is given, then the interface has avalue asynchronously iterable declaration and asynchronously provides values of thespecified type. If two type parameters are given, then the interface has apair asynchronously iterable declaration and asynchronously providesvalue pairs with the given types.
If given, anasynchronously iterable declaration’s arguments (matching
%Symbol.asyncIterator%
andvalues
properties on itsinterface prototype object. If the interface has apair asynchronously iterable declaration, it will additionally haveentries
andkeys
properties. All of these methods can be passed optional arguments, which correspond to the argument list in theasynchronously iterable declaration, and are processed by theasynchronous iterator initialization steps, if any exist.With this in mind, the requirement that all arguments be optional ensures that, in the JavaScript binding,for
-await
-of
can work directly on instances of the interface, sincefor
-await
-of
calls the%Symbol.asyncIterator%
method with no arguments.
Prose accompanying aninterface with anasynchronously iterable declaration must define aget the next iteration result algorithm.This algorithm receives the instance of theinterface that is being iterated, as well as theasync iterator itself (which can be useful for storing state).It must return aPromise
that either rejects, resolves with a specialend ofiteration value to signal the end of the iteration, or resolves with one of the following:
- forvalue asynchronously iterable declarations:
a value of the type given in the declaration;
- forpair asynchronously iterable declarations:
atuple 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 anasynchronous iterator return algorithm. Thisalgorithm receives the instance of theinterface that is being iterated, the async iteratoritself, and a single argument value of typeany
. This algorithm is invoked in the case ofpremature termination of the async iterator. It must return aPromise
; if that promisefulfills, its fulfillment value will be ignored, but if it rejects, that failure will be passed onto users of the async iterator API.
In the JavaScript binding, this algorithm allows customizing the behavior when theasync iterator’sreturn()
method is invoked. This most commonly occurs when abreak
orreturn
statement causes an exit from afor
-await
-of
loop.
We could add a similar hook forthrow()
. So far there has been no need,but if you are creating an API that needs such capabilities, pleasefile an issue.
The prose may also defineasynchronous iterator initialization steps. Thesereceive the instance of theinterface being iterated, the newly-created iterator object, and alist of IDL values representing the arguments passed, if any.
Interfaces with anasynchronously iterable declaration must not have anyattributes,constants, orregular operations named "entries
", "keys
", or"values
", or have anyinherited interfaces that haveattributes,constants,orregular operations with these names.
Consider the following interfaceSessionManager
, which allows access to a number ofSession
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:
Theasynchronous iterator initialization steps for a
SessionManager
async iteratoriterator are:
Setiterator’scurrent state to "notyet started".
Toget the next iteration result for a
SessionManager
manager and its async iteratoriterator:
Letpromise be a new promise.
Letkey be the following value, if it exists, or null otherwise:
- Ifiterator’scurrent state is "not yet started"
the smallest username inmanager’s open sessions, in lexicographical order
- Otherwise
the smallest username inmanager’s open sessions that is greater thaniterator’s current state, in lexicographical order
Note:iterator’scurrent state might no longer bepresent in the open sessions.
Ifkey is null, then:
Resolvepromise withend of iteration.
Otherwise:
Letsession be the
Session
object corresponding tokey.Resolvepromise with (username,session).
Setiterator’scurrent state tousername.
Returnpromise.
In the JavaScript language binding, theinterface prototype object for theSessionManager
interface has avalues
method that is a function, which, when invoked, returns an asynchronous iterator object that itself has anext
method that returns the next value to be iterated over. It haskeys
andentries
methods that iterate over the usernames of session objects and (username,Session
) object pairs, respectively. It also has a%Symbol.asyncIterator%
method that allows aSessionManager
to be used in afor await..of
loop that has the same value as theentries
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); }
Aninterface must not have more than oneasynchronously iterable declaration.Theinherited interfaces of aninterface with anasynchronously iterable declaration must not also have anasynchronously iterable declaration.Aninterface with anasynchronously iterable declaration and itsinherited interfaces must not have amaplike declaration,setlike declaration, oriterable declaration.
The following extended attributes are applicable toasynchronously iterable declarations:[CrossOriginIsolated
],[Exposed
], and[SecureContext
].
theseextended 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.11.Maplike declarations
Aninterface can be declared to bemaplike by using amaplike 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 maplikerepresent anordered map of key–value pairs, initially empty,known as that object’smap entries.The types used for the keys and values are given in the anglebrackets of the maplike declaration. Keys are required to be unique.
Specification authors can modify the contents of themap entries,which will automatically be reflected in the contents of the objectas observed by JavaScript code.
Maplike interfaces support an API for querying the map entriesappropriate for the language binding. If the
Note: In the JavaScript language binding, the API for interactingwith the map entries is similar to that available on JavaScriptMap
objects. If theentries
,forEach
,get
,has
,keys
,values
,%Symbol.iterator%
methods, and asize
getter.For read–write maplikes, it also includesclear
,delete
, andset
methods.
Maplike interfaces must not have anyattributes,constants, orregular operations named"entries
", "forEach
", "get
", "has
","keys
", "size
", or "values
", or have anyinherited interfaces that haveattributes,constants, orregular operations withthese names.
Read–write maplike interfaces must nothave anyattributes orconstants named"clear
", "delete
",or "set
", or have anyinherited interfaces that haveattributes orconstants with these names.
Note: Read-write maplike interfacescan haveregular operations named"clear
", "delete
", or "set
", which will override the defaultimplementation of those methods (defined in§ 3.7.11 Maplike declarations). If such regular operations aredefined, they must match the input and output expectations of each method, defined in their defaultimplementation sections.
An interface must not have more than onemaplike declaration.Theinherited interfaces of a maplike interface must notalso have amaplike declaration.A maplike interface and itsinherited interfaces must not have aniterable declaration,anasynchronously iterable declaration,asetlike declaration, oranindexed property getter.
ReadOnlyMember ::readonly ReadOnlyMemberRest
ReadWriteMaplike ::MaplikeRest
MaplikeRest ::maplike < TypeWithExtendedAttributes , TypeWithExtendedAttributes > ;
Noextended attributes defined in this specification are applicable tomaplike declarations.
Add example.
2.5.12.Setlike declarations
Aninterface can be declared to besetlike by using asetlike declaration (matching
interface interface_identifier {readonly setlike <type >;setlike <type >;};
Objects implementing an interface that is declared to be setlikerepresent anordered set of values, initially empty,known as that object’sset entries.The type of the values is given in the anglebrackets of the setlike declaration. Values are required to be unique.
Specification authors can modify the contents of theset entries,which will automatically be reflected in the contents of the objectas observed by JavaScript code.
Setlike interfaces support an API for querying the set entriesappropriate for the language binding. If the
Note: In the JavaScript language binding, the API for interactingwith the set entries is similar to that available on JavaScriptSet
objects. If theentries
,forEach
,has
,keys
,values
,%Symbol.iterator%
methods, and asize
getter.For read–write setlikes, it also includesadd
,clear
, anddelete
methods.
Setlike interfaces must not have anyattributes,constants, orregular operations named"entries
", "forEach
", "has
", "keys
","size
", or "values
", or have anyinherited interfaces that haveattributes,constants, orregular operations with these names.
Read–write setlike interfaces must nothave anyattributes orconstants named"add
", "clear
",or "delete
", or have anyinherited interfaces that haveattributes orconstants with these names.
Note: Read-write setlike interfacescan haveregular operations named"add
", "clear
", or "delete
", which will override the defaultimplementation of those methods (defined in§ 3.7.12 Setlike declarations). If such regular operations aredefined, they must match the input and output expectations of each method, defined in their defaultimplementation sections.
An interface must not have more than onesetlike declaration.Theinherited interfaces of a setlike interface must notalso have asetlike declaration.A setlike interface and itsinherited interfaces must not have aniterable declaration,anasynchronously iterable declaration,amaplike declaration, oranindexed property getter.
ReadOnlyMember ::readonly ReadOnlyMemberRest
ReadWriteSetlike ::SetlikeRest
SetlikeRest ::setlike < TypeWithExtendedAttributes > ;
Noextended attributes defined in this specification are applicable tosetlike declarations.
Add example.
2.6.Namespaces
Anamespace is a definition (matching
namespace identifier { /* namespace_members... */};
A namespace is a specification of a set ofnamespace members (matching
As with interfaces, the IDL for namespaces can be split into multiple parts by usingpartial namespace definitions(matching
namespace SomeNamespace { /* namespace_members... */};partial namespace SomeNamespace { /* namespace_members... */};
Note: As with partial interface definitions, partial namespace definitions are intended foruse as a specification editorial aide, allowing the definition of a namespace to beseparated over more than one section of the document, and sometimes multipledocuments.
The order that members appear in has significance for property enumeration in theJavaScript binding.
Note that unlike interfaces or dictionaries, namespaces do not create types.
Of the extended attributes defined in this specification, only the [CrossOriginIsolated
], [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 Const
The followingIDL fragment defines anamespace.
namespace VectorUtils {readonly attribute Vector unit ;double dotProduct (Vector x ,Vector y );Vector crossProduct (Vector x ,Vector y );};
A JavaScript implementation would then expose a globalVectorUtils
data property which was a simple object (with prototype%Object.prototype%
) 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
Adictionary is a definition (matching
dictionary identifier { /* dictionary_members... */};
Dictionary instances do not retain a reference to their language-specific representations (e.g.,the corresponding JavaScript object). So for example, returning a dictionary from anoperation will result in a new JavaScript 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 thegiven JavaScript value into the dictionary, based on the current properties of the JavaScriptobject. Modifications to the dictionary will not be reflected in the corresponding JavaScriptobject, and vice-versa.
Dictionaries must not be used as the type of anattribute orconstant.
A dictionary can be defined toinherit from another dictionary.If the identifier of the dictionary is followed by a colon and aidentifier,then that identifier identifies the inherited dictionary. The identifiermust identify a dictionary.
A dictionary must not be declared such thatits inheritance hierarchy has a cycle. That is, a dictionaryA cannot inherit from itself, nor can it inherit from anotherdictionaryB that inherits fromA, and so on.
dictionary Base { /* dictionary_members... */};dictionary Derived :Base { /* dictionary_members... */};
Theinherited dictionaries ofa given dictionaryD is the set of all dictionaries thatD inherits from, directly or indirectly. IfD does notinherit from another dictionary, then the set is empty. Otherwise, the setincludes the dictionaryE thatDinherits from and all ofE’sinherited dictionaries.
Dictionary members can be specified asrequired, meaning thatconverting a language-specific value to a dictionary requires providing a value for that member. Anydictionary member that is notrequired isoptional.
Note that specifyingdictionary members asrequired only hasan observable effect when converting other representations of dictionaries (like a JavaScript valuesupplied as an argument to anoperation) to an IDL dictionary. Specification authors shouldleave the membersoptional in all other cases, including when a dictionarytype is used solely as thereturn type ofoperations.
A given dictionary value of typeD can haveentries for each of the dictionary membersdefined onD and on any ofD’sinherited dictionaries. Dictionary members that are specifiedasrequired, or that are specified as having adefault value, will always have such correspondingentries. Othermembers' entries might or might notexist in the dictionary value.
In the JavaScript binding, a value of
As withoperation argument default values, it is strongly encouraged not to useboolean
-typeddictionary members, as this can be confusing for authors who might otherwise expect the default conversion of
Anordered map with stringkeys can be implicitly treated as a dictionary value of aspecific dictionaryD if all of itsentries correspond todictionary members, as longas those entries have the correct types, and there areentries present for anyrequired ordefaulted dictionary members.
dictionary Descriptor {DOMString name ;sequence <unsigned long >serviceIdentifiers ;};
ADescriptor
dictionary could be created as in the following steps:
Letidentifiers be « 1, 3, 7 ».
Return «[ "name" → "test", "serviceIdentifiers" →identifiers ]».
Eachdictionary member (matching
If the type of thedictionary member, after resolving typedefs,is anullable type,itsinner type must not be adictionary type.
dictionary identifier {type identifier ;};
If the identifier for anoptionaldictionary member is followed by aU+003D (=) and a value (matching
dictionary identifier {type identifier = "value";};
When a boolean literal token (
If the type of thedictionary member is anenumeration, then itsdefault value if specified mustbe one of theenumeration’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 includethe dictionary it appears on. A type includes a dictionaryD if at least one of the following is true:
the type isD
the type is a dictionary thatinherits fromD
the type is anullable type whoseinner type includesD
the type is asequence type orfrozen array whose element type includesD
the type is aunion type,one of whosemember types includesD
the type is a dictionary, one of whose members or inherited members hasa type that includesD
the type is
record<K,V>
whereV includesD
As with interfaces, the IDL for dictionaries can be split into multiple partsby usingpartial 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 specificationeditorial aide, allowing the definition of an interface to be separatedover more than one section of the document, and sometimes multiple documents.
The order of thedictionary members on a given dictionary is such that inherited dictionary members are orderedbefore non-inherited members, and the dictionary members on the onedictionary definition (including any partial dictionary definitions) areordered lexicographically by the Unicode codepoints that comprise theiridentifiers.
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 thedictionary members of a dictionary value of typeC
is c, d, g, h, a, b, e, f.
Dictionaries need 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 {undefined f (A a );};
and this JavaScript 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 forA
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 bethe same as that of another dictionary member defined on the dictionary oron that dictionary’sinherited dictionaries.
Noextended 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 undefined
Inheritance ::: identifier ε
One use of dictionary types is to allow a number ofoptional arguments to anoperation without being constrained as to the order they are specified at the call site. For example, consider the followingIDL fragment:
[Exposed =Window ]interface Point {constructor ();attribute double x ;attribute double y ;};dictionary PaintOptions {DOMString fillPattern = "black";DOMString strokePattern ;Point position ;};[Exposed =Window ]interface GraphicsContext {undefined drawRectangle (double width ,double height ,optional PaintOptions options );};
In a JavaScript implementation of the IDL, an Object can be passed in for theoptionalPaintOptions
dictionary:
// Get an instance of GraphicsContext. var ctx= getGraphicsContext(); // Draw a rectangle. ctx. drawRectangle( 300 , 200 , { fillPattern: "red" , position: new Point( 10 , 10 ) });
The members ofPaintOptions
areoptional. IffillPattern
is omitted, the definition ofdrawRectangle
can assume that it has the given default values and not include explicit wording to handle its omission.drawRectangle
needs to explicitly handle the case wherestrokePattern
andposition
are omitted.
2.8.Exceptions
Anexception is a type of object that represents an error andwhich can be thrown or treated as a first class value by implementations. Web IDL has a number ofpre-defined exceptions that specifications can reference and throw in their definition ofoperations, attributes, and so on. Custom exception types can also be defined, asinterfaces thatinherit fromDOMException
.
Asimple exception is identified by one of thefollowing types:
EvalError
RangeError
ReferenceError
TypeError
URIError
These correspond to all of the JavaScripterror objects (apart fromSyntaxError
andError
, which are deliberatelyomitted as they are reserved for use by the JavaScript parser and by authors, respectively). Themeaning of eachsimple exception matches its corresponding error object in the JavaScriptspecification.
The second kind of exception is aDOMException
, which provides furtherprogrammatically-introspectable detail on the error that occurred by giving aname.Suchnames are drawn from theDOMException
names table below.
AsDOMException
is aninterface type, it can be used as a type in IDL. Thisallows for example anoperation to be declared to have aDOMException
return type. Thisis generally a bad pattern, however, as exceptions are meant to be thrown and not returned.
The final kind of exception is a derived interface ofDOMException
. These are more complicated,and thus described in the dedicated section§ 2.8.2 DOMException derived interfaces.
Simple exceptions can becreated by providing theirtype name. ADOMException
can becreated by providing itsname followed byDOMException
. Exceptions can also bethrown, by providing the same detailsrequired tocreate one. In both cases, the caller may provide additional informationabout what the exception indicates, which is useful when constructing the exception’s message.
Here is are some examples of wording to use to create and throw exceptions. To throw a newsimple exception whose type isTypeError
:
To throw a newDOMException
withname "NotAllowedError
":
To create a newDOMException
withname "SyntaxError
":
Letobject be a newlycreated "
SyntaxError
"DOMException
.
Toreject a promise with a newDOMException
withname "OperationError
":
Rejectp with an "OperationError
"DOMException
.
An example of including additional information used to construct the exception message would be:
Throw a "SyntaxError
"DOMException
indicating that the given value had disallowed trailing spaces.
Such additional context is most helpful to implementers when it is not immediately obvious why the exception is being thrown, e.g., because there are many different steps in the algorithm which throw a "SyntaxError
"DOMException
. In contrast, if your specification throws a "NotAllowedError
"DOMException
immediately after checking if the user has provided permission to use a given feature, it’s fairly obvious what sort of message the implementation ought to construct, and so specifying it is not necessary.
The resulting behavior from creating and throwing an exception is language binding specific.
See§ 3.14.3 Creating and throwing exceptions for details on what creating and throwing anexception entails in the JavaScript language binding.
2.8.1.BaseDOMException
error names
TheDOMException
names table below lists all theallowednames for instances of the baseDOMException
interface, along with adescription of what such names mean, and legacy numeric error code values.
Interfacesinheriting fromDOMException
, in the manner describedin§ 2.8.2 DOMException derived interfaces, will have their own names, not listed in this table.
Whencreating orthrowing aDOMException
, specifications must useone of these names. If a specification author believes none of these names are a good fit for theircase, they mustfile an issue to discuss adding a new name to the shared namespace, so that the community can coordinate suchefforts. Note that adding new use-case-specific names is only important if you believe webdevelopers will discriminate multiple error conditions arising from a single API.
TheDOMException
names marked as deprecated are kept for legacy purposes, buttheir usage is discouraged.
Note: Don’t confuse the "SyntaxError
"DOMException
defined herewith JavaScript’sSyntaxError
."SyntaxError
"DOMException
is used to report parsing errors in web APIs,for example when parsing selectors,while the JavaScriptSyntaxError
is reserved for the JavaScript parser.To help disambiguate this further,always favor the "SyntaxError
"DOMException
notationover just usingSyntaxError
to refer to theDOMException
.[DOM]
Name | Description | Legacy code name and value |
---|---|---|
"IndexSizeError " | Deprecated. UseRangeError instead. | INDEX_SIZE_ERR (1) |
"HierarchyRequestError " | The operation would yield an incorrectnode tree.[DOM] | HIERARCHY_REQUEST_ERR (3) |
"WrongDocumentError " | The object is in the wrongdocument.[DOM] | WRONG_DOCUMENT_ERR (4) |
"InvalidCharacterError " | The string contains invalid characters. | INVALID_CHARACTER_ERR (5) |
"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 by anotherelement.[DOM] | 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 byNamespaces in XML.[XML-NAMES] | NAMESPACE_ERR (14) |
"InvalidAccessError " | Deprecated. UseTypeError for invalid arguments, "NotSupportedError "DOMException for unsupported operations, and "NotAllowedError "DOMException for denied requests instead. | INVALID_ACCESS_ERR (15) |
"TypeMismatchError " | Deprecated. UseTypeError 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 " | Deprecated. | URL_MISMATCH_ERR (21) |
"QuotaExceededError " | The quota has been exceeded. | QUOTA_EXCEEDED_ERR (22) |
"TimeoutError " | The operation timed out. | TIMEOUT_ERR (23) |
"InvalidNodeTypeError " | The suppliednode is incorrect or has an incorrect ancestor for this operation.[DOM] | 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.[INDEXEDDB] | — |
"DataError " | Provided data is inadequate. | — |
"TransactionInactiveError " | A request was placed against a transaction which is currently not active, or which is finished.[INDEXEDDB] | — |
"ReadOnlyError " | The mutating operation was attempted in a "readonly" transaction.[INDEXEDDB] | — |
"VersionError " | An attempt was made to open a database using a lower version than the existing version.[INDEXEDDB] | — |
"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. | — |
"OptOutError " | The user opted out of the process. | — |
2.8.2.DOMException
derived interfaces
When an exception needs to carry additional programmatically-introspectable information, beyond whatcan be provided with aDOMException
’sname, specification authors can create aninterface whichinherits fromDOMException
. Such interfaces need to followcertain rules, in order to have a predictable shape for developers. Specifically:
Theidentifier of theinterface must end with
Error
, and must not be anyof the names in theDOMException
names table.Theinterface must have aconstructor operation which sets the instance’sname to the interface’sidentifier.
Theirconstructor operation must take as its first parameter anoptional
DOMString
namedmessage defaulting to the empty string, and must set the instance’smessage tomessage.Theirconstructor operation should take as its second parameter adictionary containingthe additional information that needs to be exposed.
They should haveread onlyattributes, whose names are the same as the members of theconstructor dictionary, which return the values accepted by the constructor operation.
They should beserializable objects, whoseserialization steps anddeserialization steps preserve the additional information.
These requirements mean that the inheritedcode
property of theseinterfaces will always return 0.
DOMException
derived interface which carries along an additional "protocol error code", which is derived from what the server sent over some some hypothetical network protocol "protocol X", could look something like this:[Exposed =Window ,Serializable ]interface ProtocolXError :DOMException {constructor (optional DOMString message = "",ProtocolXErrorOptions options );readonly attribute unsigned long long errorCode ;};dictionary ProtocolXErrorOptions {required [EnforceRange ]unsigned long long errorCode ;};
EveryProtocolXError
instance has anerror code, a number.
new ProtocolXError(message,options)
constructor steps are:ProtocolXError
objects areserializable objects.
Run the
DOMException
serialization steps givenvalue andserialized.Setserialized.[[ErrorCode]] tovalue’serror code.
Run the
DOMException
deserialization steps givenserialized andvalue.Setvalue’serror code toserialized.[[ErrorCode]].
Tocreate orthrow aDOMException
derived interface, supply itsinterfaceidentifier as well as the additional information needed to construct it.
To throw an instance of theProtocolXError
exemplifiedabove:
Throw a
ProtocolXError
whoseerror code is 42.
2.9.Enumerations
Anenumeration is a definition (matchingDOMString
values that can be assigned to anattribute or passed to anoperation.
enum identifier {"enum" ,"values" /* , ... */ };
Theenumeration values are specifiedas 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 a valid enumeration valueis used when assigning to anattribute,or passed as anoperation argument,whose type is the enumeration, is language binding specific.
Note: In the JavaScript binding, assignment of an invalid string value to anattribute is ignored, whilepassing such a value in other contexts (for example as anoperation argument)results in an exception being thrown.
Noextended attributes defined in this specification are applicable toenumerations.
Enum ::enum identifier { EnumValueList } ;
EnumValueList ::string EnumValueListComma
EnumValueListComma ::, EnumValueListString ε
EnumValueListString ::string EnumValueListComma ε
The followingIDL fragment defines anenumeration that is used as the type of anattribute and anoperation argument:
enum MealType {"rice" ,"noodles" ,"other" };[Exposed =Window ]interface Meal {attribute MealType type ;attribute double size ; // in gramsundefined initialize (MealType type ,double size );};
A JavaScript implementation would restrict the strings that can be assigned to the type property or passed to the initializeMeal function to those identified in theenumeration.
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?
Acallback function is a definition (matching
callback identifier =return_type (/* arguments... */);
Note: See also the similarly namedcallback interfaces.
Theidentifier on theleft of the equals sign gives the name of thecallback function and the return type and argument list (matching
Callback functions must notbe used as the type of aconstant.
The following extended attribute is applicable to callback functions:[LegacyTreatNonObjectAsNull
].
CallbackOrInterfaceOrMixin ::callback CallbackRestOrInterface interface InterfaceOrMixin
CallbackRest ::identifier = Type ( ArgumentList ) ;
The followingIDL fragment defines acallback function used for an API that invokes a user-defined function when an operation is complete.
callback AsyncOperationCallback =undefined (DOMString status );[Exposed =Window ]interface AsyncOperations {undefined performOperation (AsyncOperationCallback whenFinished );};
In the JavaScript language binding, afunction 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
Atypedef is a definition (matching
typedef type identifier ;
Thetype being given a new name is specified after the
The
Noextended attributes defined in this specification are applicable totypedefs.
Typedef ::typedef TypeWithExtendedAttributes identifier ;
The followingIDL fragment demonstrates the use oftypedefs to allow the use of a shortidentifier instead of a longsequence 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 ofIDL fragments,an object can be described as being aplatform object.
Platform objects are objectsthat implement aninterface.
Legacy platform objects areplatform objects that implement aninterface whichdoes not have a [Global
]extended attribute, and whichsupports indexed properties,named properties, or both.
In a browser, for example,the browser-implemented DOM objects (implementing interfaces such asNode
andDocument
) that provide access to a web page’s contentsto JavaScript running in the page would beplatform objects. These objects might be exotic objects,implemented in a language like C++, or they might be native JavaScript objects. Regardless,an implementation of a given set of IDL fragments needs to be able to recognize allplatform objects that are created by the implementation. This might be done by having some internal state that records whethera given object is indeed a platform object for that implementation, or perhaps by observingthat the object is implemented by a given internal C++ class. How exactly platform objectsare 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 thata web page opened in a browser loads a JavaScript library that implements DOM Core. This librarywould be considered to be a different implementation from the browser provided implementation.The objects created by the JavaScript library that implement theNode
interfacewill not be treated as platform objects that implementNode
by the browser implementation.
Callback interfaces, on the other hand, can be implemented by any JavaScript object. Thisallows Web APIs to invoke author-defined operations. For example, the DOM Events implementationallows authors to register callbacks by providing objects that implement theEventListener
interface.
2.13.Types
This section lists the types supported by Web IDL,the set of values orInfra typecorresponding to each type, and howconstants of that type are represented.
The following types are known asinteger types:byte
,octet
,short
,unsigned short
,long
,unsigned long
,long long
andunsigned long long
.
The following types are known asnumeric types:theinteger types,float
,unrestricted float
,double
andunrestricted double
.
Theprimitive types arebigint
,boolean
and thenumeric types.
Thestring types areDOMString
, allenumeration types,ByteString
andUSVString
.
Thebuffer types areArrayBuffer
andSharedArrayBuffer
.
Thetyped array types areInt8Array
,Int16Array
,Int32Array
,Uint8Array
,Uint16Array
,Uint32Array
,Uint8ClampedArray
,BigInt64Array
,BigUint64Array
,Float16Array
,Float32Array
, andFloat64Array
.
Thebuffer view types areDataView
and thetyped array types.
Thebuffer source types are thebuffer types and thebuffer view types.
Theobject
type,allinterface types, andallcallback interface types are known asobject types.
When conversions are made from language binding specific types to IDL types in order to invoke anoperation or assign a value to anattribute, 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 async iterable < TypeWithExtendedAttributes > Null object Null symbol Null BufferRelatedType Null FrozenArray < TypeWithExtendedAttributes > Null ObservableArray < TypeWithExtendedAttributes > Null RecordType Null undefined Null
PrimitiveType ::UnsignedIntegerType UnrestrictedFloatType boolean byte octet bigint
UnrestrictedFloatType ::unrestricted FloatType FloatType
FloatType ::float double
UnsignedIntegerType ::unsigned IntegerType IntegerType
IntegerType ::short long OptionalLong
OptionalLong ::long ε
StringType ::ByteString DOMString USVString
PromiseType ::Promise < Type >
RecordType ::record < StringType , TypeWithExtendedAttributes >
Null ::? ε
2.13.1.any
Theany
type is the union of all other possiblenon-union types.
Theany
type is likea discriminated union type, in that each of its values has aspecific non-any
typeassociated with it. For example, one value of theany
type is theunsigned long
150, while another is thelong
150.These are distinct values.
The particular type of anany
value is known as itsspecific type.(Values ofunion types also havespecific types.)
2.13.2.undefined
Theundefined
type has a unique value.
undefined
constant values in IDLare represented with the
undefined
must not be used as the type of an argument in any circumstance(in anoperation,callback function,constructor operation, etc),or as the type of adictionary member,whether directly or in a union.Instead, use anoptional argument or a non-requireddictionary member.
Note: This value was previously spelledvoid
,and more limited in how it was allowed to be used.
2.13.3.boolean
Theboolean
type corresponds tobooleans.
boolean
constant values in IDL arerepresented with the
2.13.4.byte
Thebyte
type corresponds to8-bit signed integers.
byte
constant values in IDL arerepresented with
2.13.5.octet
Theoctet
type corresponds to8-bit unsigned integers.
octet
constant values in IDL arerepresented with
2.13.6.short
Theshort
type corresponds to16-bit signed integers.
short
constant values in IDL arerepresented with
2.13.7.unsigned short
Theunsigned short
type corresponds to16-bit unsigned integers.
unsigned short
constant values in IDL arerepresented with
2.13.8.long
Thelong
type corresponds to32-bit signed integers.
long
constant values in IDL arerepresented with
2.13.9.unsigned long
Theunsigned long
type corresponds to32-bit unsigned integers.
unsigned long
constant values in IDL arerepresented with
2.13.10.long long
Thelong long
type corresponds to64-bit signed integers.
long long
constant values in IDL arerepresented with
2.13.11.unsigned long long
Theunsigned long long
type corresponds to64-bit unsigned integers.
unsigned long long
constant values in IDL arerepresented with
2.13.12.float
Thefloat
type is a floating point numerictype that corresponds to the set of finite single-precision 32-bitIEEE 754 floating point numbers.[IEEE-754]
float
constant values in IDL arerepresented with
Unless there are specific reasons to use a 32-bit floating point type, specifications should usedouble
rather thanfloat
, since the set of values that adouble
can represent more closely matches a JavaScript Number.
2.13.13.unrestricted float
Theunrestricted float
type is a floating point numerictype that corresponds to the set of all possible single-precision 32-bitIEEE 754 floating point numbers, finite, non-finite, and special "not a number" values (NaNs).[IEEE-754]
unrestricted float
constant values in IDL arerepresented with
2.13.14.double
Thedouble
type is a floating point numerictype that corresponds to the set of finite double-precision 64-bitIEEE 754 floating point numbers.[IEEE-754]
double
constant values in IDL arerepresented with
2.13.15.unrestricted double
Theunrestricted double
type is a floating point numerictype that corresponds to the set of all possible double-precision 64-bitIEEE 754 floating point numbers, finite, non-finite, and special "not a number" values (NaNs).[IEEE-754]
unrestricted double
constant values in IDL arerepresented with
2.13.16.bigint
Thebigint
type is an arbitrary integer type, unrestricted in range.
bigint
constant values in IDL are represented with
2.13.17.DOMString
TheDOMString
type corresponds tostrings.
Note:DOMString
. To allowDOMString
, written asDOMString?
in IDL, needs to be used.
Note: ADOMString
value might include unmatchedsurrogatecode points. UseUSVString
if this is not desirable.
There is no way to represent a constantDOMString
value in IDL, althoughDOMString
dictionary memberdefault values andoperation optional argumentdefault values can be set tothe value of a
2.13.18.ByteString
TheByteString
type corresponds tobyte sequences.
There is no way to represent a constantByteString
value in IDL, althoughByteString
dictionary memberdefault values andoperation optional argumentdefault values can be set tothe value of a
Specifications should only useByteString
for interfacing with protocols that use bytes and strings interchangeably, such as HTTP. In general, strings should be represented withDOMString
values, even if it is expected that values of the string will always be in ASCII or some 8-bit character encoding.Sequences orfrozen arrays withoctet
orbyte
elements,Uint8Array
, orInt8Array
should be used for holding 8-bit data rather thanByteString
.
2.13.19.USVString
TheUSVString
typecorresponds toscalar value strings.Depending on the context,these can be treated as sequences ofcode units orscalar values.
There is no way to represent a constantUSVString
value in IDL, althoughUSVString
dictionary memberdefault values andoperation optional argumentdefault values can be set tothe value of a
Specifications should only useUSVString
for APIs that perform text processing and need a string ofscalar values to operate on. Most APIs that use strings should instead be usingDOMString
, which does not make any interpretations of thecode units in the string. When in doubt, useDOMString
.
2.13.20.object
Theobject
type corresponds to the set ofall possible non-null object references.
There is no way to represent a constantobject
value in IDL.
To denote a type that includes all possible object references plus theobject?
.
2.13.21.symbol
Thesymbol
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 constantsymbol
value in IDL.
2.13.22.Interface types
Anidentifier thatidentifies aninterface is used to refer toa type that corresponds to the set of all possible non-null references to objects thatimplement that interface.
An IDL value of the interface type is represented justby an object reference.
There is no way to represent a constant object reference value fora particular interface type in IDL.
To denote a type that includes all possible references to objects implementingthe given interface plus the
2.13.23.Callback interface types
Anidentifier that identifies acallback interface is used to refer to a type thatcorresponds 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 acallback context.Thecallback context is a language binding specific value, and is used to store informationabout the execution context at the time the language binding specific object reference isconverted to an IDL value.
Note: For JavaScript objects, thecallback context is used to hold a reference to theincumbent settings object at the time the Object value is converted to an IDLcallback interface type value. See§ 3.2.16 Callback interface types.
There is no way to represent a constant object reference value for a particularcallback interface type in IDL.
To denote a type that includes all possible references to objects plus the
2.13.24.Dictionary types
Anidentifier thatidentifies adictionary is used to refer toa type that corresponds to the set of all dictionaries that adhere tothe dictionary definition.
The literal syntax forordered maps may also be used to represent dictionaries, when it isimplicitly understood from context that the map is being treated as an instance of a specificdictionary type. However, there is no way to represent a constant dictionary value inside IDLfragments.
2.13.25.Enumeration types
Anidentifier thatidentifies anenumeration is used torefer to a type whose values are the set of strings (sequences ofcode units, as withDOMString
) that are theenumeration’s values.
LikeDOMString
, there is no way to represent a constantenumeration value in IDL, although enumeration-typeddictionary memberdefault values andoperation optional argumentdefault values can be set tothe value of a
2.13.26.Callback function types
Anidentifier that identifiesacallback function is used to refer toa type whose values are references to objects that are functions with the given signature.
Note: If the [LegacyTreatNonObjectAsNull
]extended attribute is specified on thedefinition ofthecallback 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 objectreference and acallback context.
Note: As withcallback interface types, thecallback context is used to hold areference to theincumbent settings object atthe time a JavaScript Object value is converted to an IDLcallback function type value. See§ 3.2.19 Callback function types.
There is no way to represent a constantcallback function value in IDL.
2.13.27.Nullable types —T?
Anullable type is an IDL type constructedfrom an existing type (called theinner type),which just allows the additional value
any
,another nullable type, or
aunion type that itselfincludes a nullable type or has a dictionary type as one of itsflattened 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 thatconstant values of theirinner type would be represented, or with the
For example, a type that allows the valuesboolean?
:
[Exposed =Window ]interface NetworkFetcher {undefined get (optional boolean ?areWeThereYet =false );};
The followinginterface has twoattributes: one whose value can be aDOMString
or theNode
object or the
[Exposed =Window ]interface Node {readonly attribute DOMString ?namespaceURI ;readonly attribute Node ?parentNode ; // ...};
2.13.28.Sequence types — sequence<T>
Thesequence<T> type is a parameterized type whose values are (possibly zero-length)lists ofvalues of typeT.
Sequences are always passed by value. Inlanguage bindings where a sequence is represented by an object ofsome kind, passing a sequence to aplatform object will not result in a reference to the sequence being kept by that object.Similarly, any sequence returned from a platform objectwill be a copy and modifications made to it will not be visible to the platform object.
The literal syntax forlists may also be used to represent sequences, when it is implicitlyunderstood from context that the list is being treated as a sequences. However, there is no way torepresent a constant sequence value inside IDL fragments.
Sequences must not be used as thetype of anattribute orconstant.
Note: This restriction exists so that it is clear to specification writersand API users thatsequences are copied rather than having referencesto them passed around. Instead of a writableattribute of a sequencetype, it is suggested that a pair ofoperations to get and set thesequence is used.
Anylist can be implicitly treated as asequence<T>
, as long as it containsonlyitems that are of typeT.
2.13.29.Async iterable types — async iterable<T>
Anasync iterable type is a parameterizedtype whose values are references to objects that can produce an asynchronously iterable, possibly infinite,sequence of values of typeT.
Unlikesequences, which are fixed-length lists where all values are known in advance, the asynchronouslyiterable sequences created by async iterables are lazy. Their values may be produced asynchronouslyonly during iteration, and thus the values or length might not be known at the time the asynciterable is created.
Async iterables are passed by reference in language bindings where they are represented by an object.This means that passing an async iterable to aplatform object will result in a reference to theasync iterable being kept by that object. Similarly, any async iterable returned from a platformobject will be a reference to the same object and modifications made to it will be visible to theplatform object. This is in contrast to sequences, which are always passed by value.
Note: Async iterables cannot be constructed from IDL. If returned from an operation, or used as thetype of a dictionary member, the async iterable will have originated from the host environment andhave been turned into an IDL type via a language binding. Instead of returning an async iterablefrom an IDL operation, the operation might want to return aninterface that has anasynchronously iterable declaration.
Async iterables must not be used as the type of anattribute orconstant.
There is no way to represent an async iterable value in IDL.
2.13.30.Record types — record<K,V>
Arecord type is a parameterized type whose values areordered maps withkeys that are instances ofK andvalues that are instances ofV.K must be oneofDOMString
,USVString
, orByteString
.
The literal syntax forordered maps may also be used to represent records, when it is implicitlyunderstood from context that the map is being treated as a record. However, there is no way torepresent a constant record value inside IDL fragments.
Records are always passed by value. In language bindings where a recordis represented by an object of some kind, passing a recordto aplatform object will not result in a reference to the recordbeing kept by that object. Similarly, any record returned from aplatform object will be a copy and modifications made to it will not be visibleto the platform object.
Records must not be used as the type of anattribute orconstant.
Anyordered map can be implicitly treated as arecord<K,V>
, as long asit contains onlyentries whosekeys are all of of typeK and whosevalues are all of typeV.
2.13.31.Promise types — Promise<T>
Apromise type is a parameterized typewhose values are references to objects that “is used as a place holderfor the eventual results of a deferred (and possibly asynchronous) computationresult of an asynchronous operation”.Seesection 25.4 of the JavaScript specification for details on the semantics of promise objects.
Promise types are non-nullable, butT may be nullable.
There is no way to represent a promise value in IDL.
2.13.32.Union types
Aunion type is a type whose set of valuesis 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 themember 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 aredouble
,(sequence<long> or Event)
and(Node or DOMString)?
.
Like theany
type, values ofunion types have aspecific type,which is the particularmember type that matches the value.
Theflattened member types of aunion type, possiblyannotated, is a set of types determined as follows:
LetT be theunion type.
InitializeS to ∅.
For eachmember typeU ofT:
IfU is anannotated type, thensetU to be theinner type ofU.
IfU is anullable type, thensetU to be theinner type ofU.
IfU is aunion type, thenadd toS theflattened member types ofU.
Otherwise,U is not aunion type.AddU toS.
ReturnS.
Note: For example, theflattened member types of theunion type(Node or (sequence<long> or Event) or (XMLHttpRequest or DOMString)? or sequence<(sequence<double> or NodeList)>)
are the six typesNode
,sequence<long>
,Event
,XMLHttpRequest
,DOMString
andsequence<(sequence<double> or NodeList)>
.
Thenumber of nullable member types of aunion type is an integer determined as follows:
LetT be theunion type.
Initializen to 0.
For eachmember typeU ofT:
IfU is anullable type, then:
Setn ton + 1.
SetU to be theinner type ofU.
IfU is aunion type, then:
Letm be thenumber of nullable member types ofU.
Setn ton +m.
Returnn.
Theany
type must notbe used as aunion member type.
Thenumber of nullable member types of aunion type mustbe 0 or 1, and if it is 1 then the union type must also not haveadictionary type in itsflattened member types.
A typeincludes a nullable type if:
the type is anullable type, or
the type is anannotated type and itsinner type is a nullable type, or
the type is aunion type and itsnumber of nullable member types is 1.
Each pair offlattened member types in aunion type,T andU,must bedistinguishable.
It is possible to create a union ofbigint
and anumeric type.However, this is generally only supposed to be used for interfaces such asNumberFormat, which formats the values rather than using them incalculations.It would not be appropriate to accept such a union, only to then convert values of thenumeric type to abigint
for further processing, as this runs the risk of introducingprecision errors.Pleasefile an issue before using this feature.
A typeincludes undefined if:
the type is
undefined
, orthe type is anullable type and itsinner typeincludes undefined, or
the type is anannotated type and itsinner typeincludes undefined, or
the type is aunion type and one of itsmember typesincludes undefined.
Union type constant valuesin IDL are represented in the same way that constant values of theirmember types would berepresented.
DistinguishableType ::PrimitiveType Null StringType Null identifier Null sequence < TypeWithExtendedAttributes > Null async iterable < TypeWithExtendedAttributes > Null object Null symbol Null BufferRelatedType Null FrozenArray < TypeWithExtendedAttributes > Null ObservableArray < TypeWithExtendedAttributes > Null RecordType Null undefined Null
2.13.33.Annotated types
Additional types can be created from existing ones by specifying certainextended attributes onthe existing types. Such types are calledannotated types, and the types theyannotate are calledinner types.
[Clamp] long
defines a newannotated type, whose behavior is based on that of theinner typelong
, but modified as specified by the [Clamp
] extended attribute.The following extended attributes areapplicable to types:[AllowResizable
],[AllowShared
],[Clamp
],[EnforceRange
], and[LegacyNullToEmptyString
].
Letextended attributes be a new emptyset.
Iftype appears as part of a
TypeWithExtendedAttributes production,append each of theextended attributes present in the production’sExtendedAttributeList toextended attributes.Iftype is amember type of aunion typeU,append each of theextended attributes associated withU toextended attributes.
Iftype appears as part of a
Type productiondirectly within anArgument production,append toextended attributes all of theextended attributes present in theproduction’sExtendedAttributeList that areapplicable to types.[
Exposed =Window ]interface I {undefined f ([XAttr ]long attrib );};Note that this is an example of this step only if [
XAttr
] isapplicable to types; otherwise [XAttr
] applies to the argument, and not the argument’s type.Iftype appears as part of a
Type productiondirectly within aDictionaryMember production,append toextended attributes all of theextended attributes present in the production’sExtendedAttributeList that areapplicable to types.dictionary D { [XAttr ]long member ;};Note that this is an example of this step only if [
XAttr
] isapplicable to types; otherwise [XAttr
] applies to the dictionary member, and not the member’s type.Iftype is atypedef,append theextended attributes associated with thetype being given a new name toextended attributes.
Returnextended attributes.
For any type, theextended attributes associated with it must only containextended attributes that areapplicable to types.
2.13.34.Buffer source types
There are a number of types that correspond to sets of all possible non-nullreferences to objects that represent a buffer of data or a view on to a buffer ofdata. 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 can be null) to a buffer of a fixed number of bytes |
SharedArrayBuffer | An object that holds a pointer (which cannot be null) to a shared buffer of a fixed number of bytes |
DataView | A view on to abuffer type instance that allows typed access to integers and floating point values stored at arbitrary offsets into the buffer |
Int8Array | A view on to abuffer type instance that exposes it as an array of two’s complement signed integers of the given size in bits |
Int16Array | |
Int32Array | |
BigInt64Array | |
Uint8Array | A view on to abuffer type instance that exposes it as an array of unsigned integers of the given size in bits |
Uint16Array | |
Uint32Array | |
BigUint64Array | |
Uint8ClampedArray | A view on to abuffer type instance that exposes it as an array of8-bit unsigned integers with clamped conversions |
Float16Array | A view on to abuffer type instance that exposes it as an array of IEEE 754 floating point numbers of the given size in bits; Float16Array corresponds to the ECMAScript proposal[PROPOSAL-FLOAT16ARRAY]. |
Float32Array | |
Float64Array |
Note: These types all correspond to classes defined in JavaScript.
There is no way to represent a constant value of any of these types in IDL.
At the specification prose level, IDLbuffer source types are simply references to objects. Toinspect or manipulate the bytes inside the buffer, specification prose needs to use the algorithmsin§ 3.2.26 Buffer source types.
BufferRelatedType ::ArrayBuffer SharedArrayBuffer DataView Int8Array Int16Array Int32Array Uint8Array Uint16Array Uint32Array Uint8ClampedArray BigInt64Array BigUint64Array Float16Array Float32Array Float64Array
2.13.35.Frozen array types — FrozenArray<T>
Afrozen array type is a parameterizedtype whose values are references to objects that hold a fixed length arrayof unmodifiable values. The values in the array are of typeT.
Frozen array types must only be used as the type ofregular attributes orstatic attributes defined on aninterface.
[Exposed =Window ]interface PersonalPreferences {readonly attribute FrozenArray <DOMString >favoriteColors ;attribute FrozenArray <DOMString >favoriteFoods ;undefined randomizeFavoriteColors ();};
The behavior of these attributes could be defined like so:
EachPersonalPreferences
has associatedfavorite colors, aFrozenArray
<DOMString
>, initially equal to the result ofcreating a frozen array from « "purple
", "aquamarine
" ».Each
PersonalPreferences
has an associatedfavorite foods, aFrozenArray
<DOMString
>, initially equal to the result ofcreating a frozen array from the empty list.The
favoriteColors
getter steps are to returnthis’s favorite colors.The
favoriteFoods
getter steps are to returnthis’s favorite foods.The
favoriteFoods
setter steps are to setthis’s favorite foods tothe given value.The
randomizeFavoriteColors()
method steps are:
LetnewFavoriteColors be a list of two strings representing colors, chosen randomly.
Setthis’s favorite colors to the result ofcreating a frozen array fromnewFavoriteColors.
SinceFrozenArray<T> valuesare references, they are unlikesequence types,which are lists of values that are passed by value.
There is no way to represent a constant frozen array value in IDL.
2.13.36.Observable array types — ObservableArray<T>
Anobservable array type is a parameterized typewhose values are references to a combination of a mutable list of objects of typeT, as well asbehavior to perform when author code modifies the contents of the list.
The parameterized typeT must not be adictionary type,sequence type,record type,orobservable array type. However,T may be nullable.
Similar tosequence types andfrozen array types, observable array types wrap aroundJavaScript array types, imposing additional semantics on their usage.
Observable array types must only be used as the type ofregular attributes defined on aninterface.
For an attribute whose type is an observable array type, specification authors can specify a seriesof algorithms:
set an indexed value, which accepts an IDLvalue 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 anIDL value that is about to be removed from the observable array, and the index from which it isbeing removed.
Both of these algorithms are optional, and if not provided, the default behavior will be to donothing. Either algorithm may throw an exception, e.g., to reject invalid values.
Note that when JavaScript code sets an existing index to a new value, this will first call thedelete an indexed value algorithm to remove the existing value, andthen theset an indexed value algorithm with the new value.
Everyregular attribute whose type is anobservable array type has abacking list, which is alist, initially empty.Specification authors can modify the contents of the backing list, which will automatically bereflected in the contents of the observable array as observed by JavaScript code. Similarly, anymodifications by JavaScript code to the contents of the observable array will be reflected back intothe backing list, after passing through theset an indexed value anddelete an indexed value algorithms.
There is no way to represent a constant observable array value in IDL.
[Exposed =Window ]interface Building {attribute ObservableArray <Employee >employees ;};
The behavior of the attribute could be defined like so:
Theset an indexed value algorithm forBuilding
’semployees
attribute, givenemployee andindex, is:
Ifemployee is not allowed to enter the building today, then throw a"
NotAllowedError
"DOMException
.Ifindex is greater than 200, then throw a "
QuotaExceededError
"DOMException
.Putemployee to work!
Thedelete an indexed value algorithm for
Building
’semployees
attribute, givenemployee andindex, is:
Alert security thatemployee has left the building.
Then, JavaScript code could manipulate theemployees
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( 2 , 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-definedset 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 thedelete an indexed value algorithm.
Another thing to note about the above code example is how all of the JavaScript array methods from%Array.prototype%
work on the observable array. Indeed, it fully behaves like anArray
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 a JavaScript 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! (Note the outer []s.) console. assert( JSON. stringify( building. employees) === `[{}]` );
2.14.Extended attributes
Anextended attribute is an annotationthat can appear ondefinitions,types asannotated types,interface members,interface mixin members,callback interface members,namespace members,dictionary members,andoperation arguments, andis 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)] | |
takes a wildcard | [Exposed=*] |
This specification defines a number of extended attributes thatare applicable to the JavaScript language binding, which are described in§ 3.3 Extended attributes.Each extended attribute definition will state which of the abovefive 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 bigint boolean byte double false float long null object octet or optional record sequence short symbol true unsigned undefined ArgumentNameKeyword BufferRelatedType
OtherOrComma ::Other ,
IdentifierList ::identifier Identifiers
Identifiers ::, identifier Identifiers ε
ExtendedAttributeNoArgs ::identifier
ExtendedAttributeArgList ::identifier ( ArgumentList )
ExtendedAttributeIdent ::identifier = identifier
ExtendedAttributeWildcard ::identifier = *
ExtendedAttributeIdentList ::identifier = ( IdentifierList )
ExtendedAttributeNamedArgList ::identifier = identifier ( ArgumentList )
3.JavaScript binding
This section describes how definitions written with the IDL defined in§ 2 Interface definition language correspond to particular constructsin JavaScript, as defined by theECMAScript Language Specification[ECMA-262].
Unless otherwise specified, objects defined in this section are ordinary objects as described inECMAScript § 10.1 Ordinary Object Internal Methods and Internal Slots, and if theobject is afunction object,ECMAScript § 10.3 Built-in Function Objects.
This section may redefine certain internal methods and internal slots of objects. Otherspecifications may also override the definitions of any internal method or internal slots of aplatform object that is an instance of aninterface. These objects with changed semanticsshall be treated in accordance with the rules for exotic objects.
As overriding internal JavaScript 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 theHTMLAllCollection
andLocation
interfaces.[HTML]
Unless otherwise specified, exotic objects defined in this section and other specifications have thesameinternal slots as ordinary objects, and all of the internal methods forwhich alternative definitions are not given are the same asthose of ordinary objects.
Unless otherwise specified, the [[Extensible]] internal slotof objects defined in this section has the value
Unless otherwise specified, the [[Prototype]] internal slotof objects defined in this section is%Object.prototype%
.
Some objects described in this section are defined to have aclass string,which is the string to include in the string returned fromObject.prototype.toString
.
If an object has aclass stringclassString, then the object must,at the time it is created, have a property whose name is the%Symbol.toStringTag%
symbolwith PropertyDescriptor{[[Writable]]:
Algorithms in this section use the conventions described inECMAScript § 5.2 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 tothrow aSomethingError
then this means to construct a new JavaScriptSomethingError
object inthecurrent 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 andnot explicitly handle exceptions that are thrown from them. When an exceptionis thrown by an algorithm or abstract operation and it is not explicitlyhandled by the caller, then it is taken to end the algorithm and propagate outto its caller, and so on.
Consider the following algorithm:
SinceToString 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.JavaScript environment
In a JavaScript implementation of a given set ofIDL fragments,there will exist a number of JavaScript objects that correspond todefinitions in thoseIDL fragments.These objects are termed theinitial objects,and comprise the following:
Eachrealm must have its own unique set of each oftheinitial objects, createdbefore control enters any JavaScript execution context associated with therealm, but after theglobal object for that realm is created. The [[Prototype]]sof all initial objects in a givenrealm must come fromthat samerealm.
In an HTML user agent, multiplerealms can exist when multiple frames or windows are created. Each frame or window will have its own set ofinitial 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: Allinterfaces define whichrealms they areexposed in.This allows, for example,realms for Web Workers toexpose different sets of supported interfaces from those exposed in realmsfor Web pages.
Although at the time of this writing the JavaScript specification does not reflect this,every JavaScript object must have anassociatedrealm. The mechanismsfor associating objects with realms are, for now, underspecified. However, we note thatin the case ofplatform objects, theassociated realm is equal to the object’srelevant realm, andfor non-exoticfunction objects (i.e. notcallable proxies, and not bound functions)the associated realm is equal to the value of thefunction object’s [[Realm]] internalslot.
3.2.JavaScript type mapping
This section describes how types in the IDL map to types in JavaScript.
Each sub-section below describes how values of a given IDL type are representedin JavaScript. For each IDL type, it is described how JavaScript values areconverted to an IDL value when passed to aplatform object expecting that type, and how IDL valuesof that type areconverted to JavaScript values when returned from a platform object.
Note that the sub-sections and algorithms below also apply toannotated types created by applyingextended attributes to the types named in their headers.
3.2.1.any
Since the IDLany
typeis the union of all other IDL types, it can correspond to anyJavaScript value type.
A JavaScript valueV isconverted to an IDLany
value by running the following algorithm:
IfV is
undefined , thenreturn the uniqueundefined
IDL value.IfV is
null , thenreturn thenull object?
reference.IfVis a Boolean, thenreturn the
boolean
value that represents the same truth value.IfVis a Number, thenreturn the result ofconvertingV to an
unrestricted double
.IfVis a BigInt, thenreturn the result ofconvertingV to a
bigint
.IfVis a String, thenreturn the result ofconvertingV to a
DOMString
.IfVis a Symbol, thenreturn the result ofconvertingV to a
symbol
.IfVis an Object, thenreturn an IDL
object
value that referencesV.
An IDLany
value isconverted to a JavaScript value according to the rules for converting thespecific type of the IDLany
value as described in the remainder of this section.
3.2.2.undefined
A JavaScript valueV isconverted to an IDLundefined
value by returning the uniqueundefined
value, ignoringV.
The unique IDLundefined
value isconverted to the JavaScript
3.2.3.boolean
The IDLboolean
valuetrue
isconverted to the JavaScriptboolean
valuefalse
is converted to the JavaScript
3.2.4.Integer types
Mathematical operations used in this section,including those defined inECMAScript § 5.2 Algorithm Conventions,are to be understood as computing exact mathematical resultson mathematical real numbers.
In effect, wherex is a Number value,“operating onx” is shorthand for“operating on the mathematical real number that represents the same numeric value asx”.
3.2.4.1.byte
A JavaScript valueV isconverted to an IDLbyte
value by running the following algorithm:
Letx be?ConvertToInt(V, 8, "
signed
").Return the IDL
byte
value that represents the same numeric value asx.
The result ofconverting an IDLbyte
value to a JavaScript value is a Number that represents the same numeric value as the IDLbyte
value. The Number value will be an integer in the range [−128, 127].
3.2.4.2.octet
A JavaScript valueV isconverted to an IDLoctet
value by running the following algorithm:
Letx be?ConvertToInt(V, 8, "
unsigned
").Return the IDL
octet
value that represents the same numeric value asx.
The result ofconverting an IDLoctet
value to a JavaScript value is a Number that represents the same numeric value as the IDLoctet
value. The Number value will be an integer in the range [0, 255].
3.2.4.3.short
A JavaScript valueV isconverted to an IDLshort
value by running the following algorithm:
Letx be?ConvertToInt(V, 16, "
signed
").Return the IDL
short
value that represents the same numeric value asx.
The result ofconverting an IDLshort
value to a JavaScript value is a Number that represents the same numeric value as the IDLshort
value. The Number value will be an integer in the range [−32768, 32767].
3.2.4.4.unsigned short
A JavaScript valueV isconverted to an IDLunsigned short
value by running the following algorithm:
Letx be?ConvertToInt(V, 16, "
unsigned
").Return the IDL
unsigned short
value that represents the same numeric value asx.
The result ofconverting an IDLunsigned short
value to a JavaScript value is a Number that represents the same numeric value as the IDLunsigned short
value. The Number value will be an integer in the range [0, 65535].
3.2.4.5.long
A JavaScript valueV isconverted to an IDLlong
value by running the following algorithm:
Letx be?ConvertToInt(V, 32, "
signed
").Return the IDL
long
value that represents the same numeric value asx.
The result ofconverting an IDLlong
value to a JavaScript value is a Number that represents the same numeric value as the IDLlong
value. The Number value will be an integer in the range [−2147483648, 2147483647].
3.2.4.6.unsigned long
A JavaScript valueV isconverted to an IDLunsigned long
value by running the following algorithm:
Letx be?ConvertToInt(V, 32, "
unsigned
").Return the IDL
unsigned long
value that represents the same numeric value asx.
The result ofconverting an IDLunsigned long
value to a JavaScript value is a Number that represents the same numeric value as the IDLunsigned long
value. The Number value will be an integer in the range [0, 4294967295].
3.2.4.7.long long
A JavaScript valueV isconverted to an IDLlong long
value by running the following algorithm:
Letx be?ConvertToInt(V, 64, "
signed
").Return the IDL
long long
value that represents the same numeric value asx.
The result ofconverting an IDLlong long
value to a JavaScript value is a Number value that represents the closest numeric value to thelong long
, choosing the numeric value with aneven significand if there are twoequally close values. If thelong long
is in the range [−253 + 1, 253 − 1], then the Number will be able to represent exactly the same value as thelong long
.
3.2.4.8.unsigned long long
A JavaScript valueV isconverted to an IDLunsigned long long
value by running the following algorithm:
Letx be?ConvertToInt(V, 64, "
unsigned
").Return the IDL
unsigned long long
value that represents the same numeric value asx.
The result ofconverting an IDLunsigned long long
value to a JavaScript value is a Number value that represents the closest numeric value to theunsigned long long
, choosing the numeric value with aneven significand if there are twoequally close values. If theunsigned long long
is less than or equal to 253 − 1, then the Number will be able to represent exactly the same value as theunsigned long long
.
3.2.4.9.Abstract operations
ConvertToInt(V,bitLength,signedness):
IfbitLength is 64, then:
LetupperBound be 253 − 1.
Ifsignedness is "
unsigned
", then letlowerBound be 0.Otherwise letlowerBound be −253 + 1.
Note: this ensures
long long
typesassociated with [EnforceRange
] or[Clamp
]extended attributes are representable in JavaScript’sNumber type as unambiguous integers.
Otherwise, ifsignedness is "
unsigned
", then:LetlowerBound be 0.
LetupperBound be 2bitLength − 1.
Otherwise:
LetlowerBound be -2bitLength − 1.
LetupperBound be 2bitLength − 1 − 1.
Ifx is −0, then setx to +0.
If the conversion is to an IDL typeassociated with the [
EnforceRange
]extended attribute, then:Setx toIntegerPart(x).
Returnx.
Ifx is not
NaN and the conversion is to an IDL typeassociated with the [Clamp
] extended attribute,then:Ifx is
NaN , +0, +∞, or −∞,then return +0.Setx toIntegerPart(x).
Setx toxmodulo 2bitLength.
Ifsignedness is "
signed
" andx ≥ 2bitLength − 1,then returnx − 2bitLength.Otherwise, returnx.
3.2.5.float
A JavaScript valueV isconverted to an IDLfloat
value by running the following algorithm:
LetS be the set of finite IEEE 754 single-precision floatingpoint values except −0, but with two special values added: 2128 and−2128.
Lety be the number inS that is closesttox, selecting the number with aneven significand if there are twoequally close values.(The two special values 2128 and −2128 are considered to have even significands for this purpose.)
Ify is +0 andx is negative, return −0.
Returny.
The result ofconverting an IDLfloat
value to a JavaScript value is the Number value that represents the same numeric value as the IDLfloat
value.
3.2.6.unrestricted float
A JavaScript valueV isconverted to an IDLunrestricted float
value by running the following algorithm:
Ifx is
NaN , then return the IDLunrestricted float
value that represents the IEEE 754 NaN value with the bit pattern 0x7fc00000[IEEE-754].LetS be the set of finite IEEE 754 single-precision floatingpoint values except −0, but with two special values added: 2128 and−2128.
Lety be the number inS that is closesttox, selecting the number with aneven significand if there are twoequally close values.(The two special values 2128 and −2128 are considered to have even significands for this purpose.)
Ify is 2128, return +∞.
Ify is −2128, return −∞.
Ify is +0 andx is negative, return −0.
Returny.
Note: Since there is only a single JavaScript
The result ofconverting an IDLunrestricted float
value to a JavaScript value is a Number:
If the IDL
unrestricted float
value is a NaN,then the Number value isNaN .Otherwise, the Number value isthe one that represents the same numeric value as the IDL
unrestricted float
value.
3.2.7.double
The result ofconverting an IDLdouble
value to a JavaScript value is the Number value that represents the same numeric value as the IDLdouble
value.
3.2.8.unrestricted double
A JavaScript valueV isconverted to an IDLunrestricted double
value by running the following algorithm:
Ifx is
NaN , thenreturn the IDLunrestricted double
value that representsthe IEEE 754 NaN value with the bit pattern 0x7ff8000000000000[IEEE-754].Return the IDL
unrestricted double
valuethat represents the same numeric value asx.
Note: Since there is only a single JavaScript
The result ofconverting an IDLunrestricted double
value to a JavaScript value is a Number:
If the IDL
unrestricted double
value is a NaN,then the Number value isNaN .Otherwise, the Number value isthe one that represents the same numeric value as the IDL
unrestricted double
value.
3.2.9.bigint
The result ofconverting an IDLbigint
value to a JavaScript value is a BigInt:
A JavaScript valueV isconverted to an IDLnumeric typeT orbigint
value by running the following algorithm:
Ifxis a BigInt, then
Return the IDL
bigint
value that represents the same numeric value asx.
Assert:xis a Number.
Return the result ofconvertingx toT.
3.2.10.DOMString
A JavaScript valueV isconverted to an IDLDOMString
value by running the following algorithm:
IfV is
null and the conversion is to an IDL typeassociated with the [LegacyNullToEmptyString
] extendedattribute, then return theDOMString
value that represents the empty string.Return the IDL
DOMString
value that represents the same sequence of code units as the one the JavaScript String valuex represents.
The result ofconverting an IDLDOMString
value to a JavaScript value is the String value that represents the same sequence ofcode units that the IDLDOMString
represents.
3.2.11.ByteString
A JavaScript valueV isconverted to an IDLByteString
value by running the following algorithm:
The result ofconverting an IDLByteString
value to a JavaScript value is a String value whose length is the length of theByteString
, and the value of eachelement of which is the value of the corresponding element of theByteString
.
3.2.12.USVString
A JavaScript valueV isconverted to an IDLUSVString
value by running the following algorithm:
Letstring be the result ofconvertingV to a
DOMString
.Return an IDL
USVString
value that is the result ofconvertingstring to a sequence ofscalar values.
The result ofconverting an IDLUSVString
valueS to a JavaScript value isS.
3.2.13.object
IDLobject
values are represented by JavaScript Object values.
A JavaScript valueV isconverted to an IDLobject
value by running the following algorithm:
IfVis not an Object, thenthrow a
TypeError
.Return the IDL
object
value that is a reference to the same object asV.
The result ofconverting an IDLobject
value to a JavaScript value is the Object value that represents a reference to the same object that the IDLobject
represents.
3.2.14.symbol
IDLsymbol
values are represented by JavaScript Symbol values.
symbol
value by running the following algorithm:IfVis not a Symbol, thenthrow a
TypeError
.Return the IDL
symbol
value that is a reference to the same symbol asV.
The result ofconverting an IDLsymbol
value to a JavaScript value is the Symbol value that represents a reference to the same symbol that the IDLsymbol
represents.
3.2.15.Interface types
IDLinterface type values are represented by JavaScript Object values (includingfunction objects).
A JavaScript valueV isconverted to an IDLinterface type value by running the following algorithm (whereI is theinterface):
IfVimplementsI, then return the IDLinterface type value that represents a reference to that platform object.
The result ofconverting an IDLinterface type value to a JavaScript value is the Object value that represents a reference to the same object that the IDLinterface type value represents.
3.2.16.Callback interface types
IDLcallback interface type values are represented by JavaScript Object values (includingfunction objects).
A JavaScript valueV isconverted to an IDLcallback interface type value by running the following algorithm:
IfVis not an Object, thenthrow a
TypeError
.Return the IDLcallback interface type value that represents a reference toV, withtheincumbent settings object as thecallback context.
The result ofconverting an IDLcallback interface type value to a JavaScript value is the Object value that represents a reference to the same object that the IDLcallback interface type value represents.
3.2.17.Dictionary types
IDLdictionary type values are representedby JavaScript Object values. Properties onthe object (or its prototype chain) correspond todictionary members.
A JavaScript valuejsDict isconverted to an IDLdictionary type value by running the following algorithm (whereD is thedictionary type):
IfjsDictis not an Object andjsDict is neither
undefined nornull , thenthrow aTypeError
.LetidlDict be an emptyordered map, representing a dictionary of typeD.
Letdictionaries be a list consisting ofD and all ofD’sinherited dictionaries,in order from least to most derived.
For each dictionarydictionary indictionaries, in order:
For each dictionary membermember declared ondictionary, in lexicographical order:
Letkey be theidentifier ofmember.
IfjsDict is either
undefined ornull , then:LetjsMemberValue be
undefined .
Otherwise,
IfjsMemberValue is not
undefined , then:LetidlMemberValue be the result ofconvertingjsMemberValue to an IDL value whose type is the typemember is declared to be of.
SetidlDict[key] toidlMemberValue.
Otherwise, ifjsMemberValue is
undefined butmember has adefault value, then:LetidlMemberValue bemember’s default value.
SetidlDict[key] toidlMemberValue.
Otherwise, ifjsMemberValue is
undefined andmember isrequired, then throw aTypeError
.
ReturnidlDict.
Note: The order thatdictionary members are lookedup on the JavaScript object are not necessarily the same as the object’s property enumeration order.
An IDL dictionary valueV isconverted to a JavaScript Object value by running the following algorithm (whereD is thedictionary):
LetO beOrdinaryObjectCreate(
%Object.prototype%
).Letdictionaries be a list consisting ofD and all ofD’sinherited dictionaries,in order from least to most derived.
For each dictionarydictionary indictionaries, in order:
For each dictionary membermember declared ondictionary, in lexicographical order:
Letkey be theidentifier ofmember.
IfV[key]exists, then:
LetidlValue beV[key].
Letvalue be the result ofconvertingidlValue to a JavaScript value.
Perform!CreateDataPropertyOrThrow(O,key,value).
Recall that ifmember has adefault value,thenkey will alwaysexist inV.
ReturnO.
3.2.18.Enumeration types
IDLenumeration types are represented by JavaScript Stringvalues.
A JavaScript valueV isconverted to an IDLenumeration type value as follows (whereE is theenumeration):
IfS is not one ofE’senumeration values,thenthrow a
TypeError
.Return the enumeration value of typeE that is equal toS.
The result ofconverting an IDLenumeration type value to a JavaScript value is the String value that represents the same sequence ofcode units as theenumeration value.
3.2.19.Callback function types
IDLcallback function types are represented by JavaScriptfunction objects, except in the[LegacyTreatNonObjectAsNull
] case, when they can be any object.
A JavaScript valueV isconverted to an IDLcallback function type value by running the following algorithm:
If the result of callingIsCallable(V) is
false and the conversion to an IDL valueis not being performed duetoV being assigned to anattribute whose type is anullablecallback function that is annotated with [LegacyTreatNonObjectAsNull
],thenthrow aTypeError
.Return the IDLcallback function type valuethat represents a reference to the same object thatV represents, with theincumbent settings object as thecallback context.
The result ofconverting an IDLcallback function type value to a JavaScript value is a reference to the same object that the IDLcallback function type value represents.
3.2.20.Nullable types —T?
IDLnullable type values are representedby values of either the JavaScript type corresponding to theinner IDL type, orthe JavaScript
A JavaScript valueV isconverted to an IDLnullable typeT?
value (whereT is theinner type) as follows:
IfVis not an Object, andthe conversion to an IDL value is being performed duetoV being assigned to anattribute whose type is anullablecallback function that is annotated with [
LegacyTreatNonObjectAsNull
],then return the IDLnullable typeT?
valuenull .Otherwise, ifV is
undefined ,andTincludes undefined,return the uniqueundefined
value.Otherwise, ifV is
null orundefined , then return the IDLnullable typeT?
valuenull .Otherwise, return the result ofconvertingV using the rules for theinner IDL type
T
.
The result ofconverting an IDLnullable type value to a JavaScript value is:
If the IDLnullable type
T?
value isnull ,then the JavaScript value isnull .Otherwise, the JavaScript value is the result ofconverting the IDLnullable type valueto theinner IDL type
T
.
3.2.21.Sequences — sequence<T>
IDLsequence<T> values are represented byJavaScript Array values.
A JavaScript valueV isconverted to an IDLsequence<T> value as follows:
Letmethod be?GetMethod(V,
%Symbol.iterator%
).Return the result ofcreating a sequence fromV andmethod.
An IDL sequence valueS of typesequence<T> isconverted to a JavaScript Array object as follows:
Letn be the length ofS.
LetA be a new Array object created as if by the expression
[]
.Initializei to be 0.
Whilei <n:
LetV be the value inS at indexi.
LetE be the result ofconvertingV to a JavaScript value.
Perform!CreateDataPropertyOrThrow(A,P,E).
Seti toi + 1.
ReturnA.
3.2.21.1.Creating a sequence from an iterable
To create an IDL value of typesequence<T> given an iterableiterable and an iterator gettermethod, perform the following steps:
LetiteratorRecord be?GetIteratorFromMethod(iterable,method).
Initializei to be 0.
Repeat
Letnext be?IteratorStepValue(iteratorRecord).
Ifnext is
done ,then return an IDL sequence value of typesequence<T> of lengthi, where the value of the elementat indexj isSj.InitializeSi to the result ofconvertingnext to an IDL value of typeT.
Seti toi + 1.
The followinginterface defines anattribute of a sequence type as well as anoperation with an argument of a sequence type.
[Exposed =Window ]interface Canvas {sequence <DOMString >getSupportedImageCodecs ();undefined drawPolygon (sequence <double >coordinates );sequence <double >getLastDrawnPolygon (); // ...};
In a JavaScript implementation of this interface, an Array object with elements of type String is used to represent asequence<DOMString>
, while an Array with elements of type Number represents asequence<double>
. The Array objects are effectively passed by value; every time thegetSupportedImageCodecs()
function is called a new Array is returned, and whenever an Array is passed todrawPolygon
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.22.Async iterables — async iterable<T>
In the JavaScript binding, IDLasync iterable values are represented byastruct with the followingitems:
object, a JavaScript value
method, a JavaScript value
type, either "
sync
" or "async
"
IfVis not an Object, thenthrow a
TypeError
.Letmethod be?GetMethod(obj,
%Symbol.asyncIterator%
).Ifmethod is
undefined :SetsyncMethod to?GetMethod(obj,
%Symbol.iterator%
).Return an IDLasync iterable value withobject set toV,method set tosyncMethod, andtype set to"
sync
".
Return an IDLasync iterable value withobject set toV,method set tomethod, andtype set to"
async
".
3.2.22.1.Iterating async iterators
Anasync iterable is not directly iterated over. Instead, it is first opened to createanasync iterator. Theasync iterator can be asynchronously iterated over to produce values.
Async iterators arestructs with the followingitems:
underlying record, anIterator Record
type parameter, an IDL type representing the type of values produced by the async iterator
Toopen anasync iterable<T>
iterable:
Letiterator be?GetIteratorFromMethod(iterable’sobject,iterable’smethod).
Ifiterable’stype is "
sync
", setiterator toCreateAsyncFromSyncIterator(iterator).Return anasync iterator value withunderlying record set toiterator andtype parameter set toT.
Toget the next value of anasync iteratoriterator:
LetnextResult beIteratorNext(iterator’sunderlying record).
IfnextResult is anabrupt completion, returna promise rejected withnextResult.[[Value]].
LetnextPromise bea promise resolved withnextResult.[[Value]].
Return the result ofreacting tonextPromise with the following fulfillmentsteps, giveniterResult:
IfiterResultis not an Object,throw a
TypeError
.Letdone be?IteratorComplete(iterResult).
Ifdone is true:
Returnend of iteration.
Otherwise:
LetV be?IteratorValue(iterResult).
Letvalue be the result ofconvertingV to an IDLvalue of typeiterator’stype parameter.
Returnvalue.
Toclose anasync iterator<T>
iterator, with an ECMAScript valuereason:
LetiteratorRecord beiterator’sunderlying record.
LetiteratorObj beiteratorRecord.[[Iterator]].
LetreturnMethod beGetMethod(iteratorObj, "
return
").IfreturnMethod is anabrupt completion, returna promise rejected withreturnMethod.[[Value]].
IfreturnMethod is
undefined , returna promise resolved withundefined
.LetreturnResult beCall(returnMethod.[[Value]],iteratorObj, «reason »).
IfreturnResult is anabrupt completion, returna promise rejected withreturnResult.[[Value]].
LetreturnPromise bea promise resolved withreturnResult.[[Value]].
Return the result ofreacting toreturnPromise with the following fulfillment steps,givenreturnPromiseResult:
IfreturnPromiseResultis not an Object,throw a
TypeError
.Return
undefined
.
concatN
is anoperation that returns a promise that will be fulfilled with the concatenation of all the strings yielded by the async iterable passed to it. It stops concatenating and closes the iterator once the async iterable has yieldedmaxN strings.
interface I { Promise<DOMString> concatN(async iterable<DOMString> strings, unsigned long maxN);};
TheconcatN(iterable,maxN)
method steps are:
Letpromise bea new promise.
Letresult be the empty string.
Letn be 0.
Letiterator be the result ofopeningiterable.
Letstep be a sequence of steps that will be used to process the async iterable:
Letnext be the result ofgetting the next value ofiterator.
React tonext:
Ifnext was fulfilled with valuev:
Ifv isend of iteration,resolvepromise withresult.
Setresult to the result of concatenatingresult andv.
Setn ton + 1.
Ifn ismaxN, then:
Otherwise:
Callstep.
Ifnext was rejected with reasonr,rejectpromise withr.
Callstep.
Returnpromise.
3.2.23.Records — record<K,V>
IDLrecord<K,V> values are represented byJavaScript Object values.
A JavaScript valueO isconverted to an IDLrecord<K,V>
value as follows:
Letresult be a new empty instance of
record<K,V>
.Letkeys be?O.[[OwnPropertyKeys]]().
For eachkey ofkeys:
Letdesc be?O.[[GetOwnProperty]](key).
Ifdesc is not
undefined anddesc.[[Enumerable]] istrue :LettypedKey bekeyconverted to an IDL value of typeK.
LettypedValue bevalueconverted to an IDL value of typeV.
Setresult[typedKey] totypedValue.
Note: It’s possible thattypedKey is already inresult,ifK is
USVString
andkey contains unpaired surrogates.
Returnresult.
An IDLrecord<…>
valueD isconverted to a JavaScript value as follows:
Letresult beOrdinaryObjectCreate(
%Object.prototype%
).For eachkey →value ofD:
LetjsKey bekeyconverted to a JavaScript value.
LetjsValue bevalueconverted to a JavaScript value.
Letcreated be!CreateDataProperty(result,jsKey,jsValue).
Assert:created is
true .
Returnresult.
Passing the JavaScript value{b: 3, a: 4}
as arecord<DOMString, double>
argument would result in the IDL value «[ "b
" → 3, "a
" → 4 ]».
Records only considerownenumerable properties, so given an IDL operationrecord<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.24.Promise types — Promise<T>
IDLpromise type values are represented by JavaScriptPromiseCapability records.
A JavaScript valueV isconverted to an IDLPromise<T>
value as follows:
LetpromiseCapability be?NewPromiseCapability(
%Promise%
).ReturnpromiseCapability.
The result ofconverting an IDLpromise type value to a JavaScript value is the value of the [[Promise]] field of the record that IDLpromise type represents.
3.2.24.1.Creating and manipulating Promises
Tocreate a newPromise<T>
in arealmrealm, perform the following steps:
Letconstructor berealm.[[Intrinsics]].[[
%Promise%
]].Return?NewPromiseCapability(constructor).
To create aresolved promise of typePromise<T>
, withx (a value of typeT) in arealmrealm, perform the following steps:
Letvalue be the result ofconvertingx to aJavaScript value.
Letconstructor berealm.[[Intrinsics]].[[
%Promise%
]].LetpromiseCapability be?NewPromiseCapability(constructor).
Perform!Call(promiseCapability.[[Resolve]],
undefined ,«value »).ReturnpromiseCapability.
To create arejected promise of typePromise<T>
, with reasonr (a JavaScript value) in arealmrealm, perform the following steps:
Letconstructor berealm.[[Intrinsics]].[[
%Promise%
]].LetpromiseCapability be?NewPromiseCapability(constructor).
ReturnpromiseCapability.
Toresolve aPromise<T>
p withx (a value of typeT), perform the following steps:
Ifx is not given, then let it be the
undefined
value.Letvalue be the result ofconvertingx to aJavaScript value.
IfT isundefined
, then thex argument is optional, allowing a simpler "resolve p" usage.
Toreject aPromise<T>
p with reasonr (a JavaScript value), perform the following steps:
Toreact to aPromise<T>
promise, given one or two sets of steps to perform, covering when the promise is fulfilled, rejected, or both, perform the following steps:
LetonFulfilledSteps be the following steps given argumentV:
Letvalue be the result ofconvertingV to an IDLvalue of typeT.
If there is a set of steps to be run if the promise was fulfilled, then letresult bethe result of performing them, givenvalue ifT is not
undefined
. Otherwise, letresult bevalue.Returnresult,converted to a JavaScript value.
LetonFulfilled beCreateBuiltinFunction(onFulfilledSteps, « »):
LetonRejectedSteps be the following steps given argumentR:
Letreason be the result ofconvertingR to an IDL value of type
any
.If there is a set of steps to be run if the promise was rejected, then letresult bethe result of performing them, givenreason. Otherwise, letresult bea promise rejected withreason.
Returnresult,converted to a JavaScript value.
LetonRejected beCreateBuiltinFunction(onRejectedSteps, « »):
Letconstructor bepromise.[[Promise]].[[Realm]].[[Intrinsics]].[[
%Promise%
]].LetnewCapability be?NewPromiseCapability(constructor).
Note: Not all callers will use the returned
Promise
. Implementations might wish toavoid creatingnewCapability in those cases.PerformPerformPromiseThen(promise.[[Promise]],onFulfilled,onRejected,newCapability).
ReturnnewCapability.
Note: This algorithm will behave in a very similar way to thepromise.then()
method. In particular, if the steps return a value of typeU orPromise<U>
, this algorithm returns aPromise<U>
as well.
To perform some stepsupon fulfillment of aPromise<T>
promise given some stepssteps taking a value of typeT, perform the following steps:
Return the result ofreacting topromise:
Ifpromise was fulfilled with valuev, then:
Performsteps withv.
To perform some stepsupon rejection of aPromise<T>
promise given some stepssteps taking a JavaScript value, perform the following steps:
Return the result ofreacting topromise:
Ifpromise was rejected with reasonr, then:
Performsteps withr.
Towait for all with alist ofPromise<T>
valuespromises, with success stepssuccessSteps that take alist ofT values and failure stepsfailureSteps that take a rejection reasonany
value, perform the following steps:
LetfullfilledCount be 0.
Letrejected be false.
LetrejectionHandlerSteps be the following steps givenarg:
Ifrejected is true, abort these steps.
Setrejected to true.
PerformfailureSteps givenarg.
LetrejectionHandler beCreateBuiltinFunction(rejectionHandlerSteps, « »):
Lettotal bepromises’ssize.
Iftotal is 0, then:
Queue a microtask to performsuccessSteps given « ».
Return.
Letindex be 0.
Letresult be alist containingtotal null values.
For eachpromise ofpromises:
LetpromiseIndex beindex.
LetfulfillmentHandler be the following steps givenarg:
Setresult[promiseIndex] toarg.
SetfullfilledCount tofullfilledCount + 1.
IffullfilledCount equalstotal, then performsuccessSteps givenresult.
LetfulfillmentHandler beCreateBuiltinFunction(fulfillmentHandler, « »):
PerformPerformPromiseThen(promise,fulfillmentHandler,rejectionHandler).
Setindex toindex + 1.
Toget a promise for waiting for all with alist ofPromise<T>
valuespromises and arealmrealm, perform the following steps:
Letpromise bea new promise of type
Promise<sequence<T>>
inrealm.LetsuccessSteps be the following steps, givenresults:
Resolvepromise withresults.
LetfailureSteps be the following steps, givenreason:
Rejectpromise withreason.
Wait for all withpromises, givensuccessSteps andfailureSteps.
Returnpromise.
This definition is useful when you wish to aggregate the results of multiple promises, and then produce another promise from them, in the same way thatPromise.all()
functions for JavaScript code. If you do not need to produce another promise, thenwaiting for all is likely better.
Promise<T>
promise, setpromise.[[Promise]].[[PromiseIsHandled]] to true.This definition is useful for promises for which you expect rejections to often be ignored; it ensures such promises do not causeunhandledrejection
events. The most common use case is for promise properties, which the web developer might or might not consult. An example is thewritableStreamWriter.closed
promise.
3.2.24.2.Examples
delay
is anoperation 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 <undefined >delay (unrestricted double ms );};
Thedelay(ms)
method steps are:
Letrealm bethis’srelevant realm.
LettaskSource be some appropriatetask source.
Ifms is NaN, letms be +0; otherwise letms be the maximum ofms and +0.
Letp bea new promise inrealm.
Run the following stepsin parallel:
Waitms milliseconds.
Queue a task ontaskSource toresolvep.
Returnp.
ThevalidatedDelay
operation is much likethedelay
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 <undefined >validatedDelay (unrestricted double ms );};
ThevalidatedDelay(ms)
method steps are:
Letrealm bethis’srelevant realm.
LettaskSource be some appropriatetask source.
Ifms is NaN, returna promise rejected with a
TypeError
inrealm.Ifms < 0, returna promise rejected with a
RangeError
inrealm.Letp bea new promise inrealm.
Run the following stepsin parallel:
Waitms milliseconds.
Queue a task ontaskSource toresolvep.
Returnp.
addDelay
is anoperation that adds an extra number of milliseconds of delay betweenpromise settling and the returned promise settling.
interface I {Promise <any >addDelay (Promise <any >promise ,unrestricted double ms );};
TheaddDelay(ms,promise)
method steps are:
Letrealm bethis’srelevant realm.
LettaskSource be some appropriatetask source.
Ifms is NaN, letms be +0; otherwise letms be the maximum ofms and +0.
Letp bea new promise inrealm.
React topromise:
Ifpromise was fulfilled with valuev, then:
Run the following stepsin parallel:
Waitms milliseconds.
Queue a task ontaskSource toresolvep withv.
Ifpromise was rejected with reasonr, then:
Run the following stepsin parallel:
Waitms milliseconds.
Queue a task ontaskSource torejectp withr.
Returnp.
environment.ready
is anattribute 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 <undefined >ready ;};
EveryEnvironment
object must have aready promise, which is aPromise<undefined>
.
Theready
attribute getter steps are:
Returnthis’sready promise.
To create anEnvironment
object in arealmrealm, perform the following steps:
LettaskSource be some appropriatetask source.
Letenvironment benew
Environment
object inrealm.Setenvironment’sready promise toa new promise inrealm.
Run the following stepsin parallel:
Do some asynchronous work.
Ifenvironment becomes ready successfully, thenqueue a task ontaskSource toresolveenvironment’sready promise.
Ifenvironment fails to become ready, thenqueue a task ontaskSource torejectenvironment’sready promise with a"
NetworkError
"DOMException
.
Returnenvironment.
addBookmark
is anoperation that requests that the user add the current web page as a bookmark. It’s drawn fromsome iterative design work and illustrates a more real-world scenario of appealing to environmental asynchrony, as well as immediate rejections.
interface I {Promise <undefined >addBookmark ();};
TheaddBookmark()
method steps are:
LettaskSource be some appropriatetask source.
If this method was not invoked as a result of explicit user action, returna promise rejected with a "
SecurityError
"DOMException
.If the document’s mode of operation is standalone, returna promise rejected with a"
NotSupportedError
"DOMException
.Letpromise bea new promise.
Letinfo be the result of getting a web application’s metadata.
Run the following stepsin parallel:
Usinginfo, and in a manner that is user-agent specific, allow the end user to make achoice 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, orpress a "cancel" button), thenqueue a task ontaskSource torejectpromise with an "
AbortError
"DOMException
.Otherwise,queue a task ontaskSource toresolvepromise.
Returnpromise.
Several places in[SERVICE-WORKERS] useget a promise to wait for all.batchRequest
illustrates a simplified version of one of their uses. It takes as input asequence of URLs, and returns a promise for asequence ofResponse
objects created by fetching the corresponding URL. If any of the fetches fail, it will returna promise rejected with that failure.
interface I {Promise <sequence <Response >>batchRequest (sequence <USVString >urls );};
ThebatchRequest(urls)
method steps are:
LetresponsePromises be « ».
For eachurl ofurls:
Letp be the result ofgetting a promise to wait for all withresponsePromises.
Returnp.
3.2.25.Union types
IDLunion type values are represented by JavaScript valuesthat correspond to the union’smember types.
Toconvert a JavaScript valueV to an IDLunion type value is done as follows:
If theunion typeincludes undefined andV is
undefined ,then return the uniqueundefined
value.If theunion typeincludes a nullable type andV is
null orundefined ,then return the IDL valuenull .Lettypes be theflattened member types of theunion type.
IfV is
null orundefined , then:Iftypes includes adictionary type, then return theresult ofconvertingV to that dictionary type.
IfVis a platform object, then:
Iftypes includes aninterface type thatVimplements, then return the IDL value that is a reference to the objectV.
Iftypes includes
object
, then return the IDL valuethat is a reference to the objectV.
IfVis an Object,V has an [[ArrayBufferData]]internal slot, andIsSharedArrayBuffer(V) is false, then:
Iftypes includes
ArrayBuffer
, then return theresult ofconvertingV toArrayBuffer
.Iftypes includes
object
, then return the IDL valuethat is a reference to the objectV.
IfVis an Object,V, has an [[ArrayBufferData]]internal slot, andIsSharedArrayBuffer(V) is true, then:
Iftypes includes
SharedArrayBuffer
, then return theresult ofconvertingV toSharedArrayBuffer
.Iftypes includes
object
, then return the IDL valuethat is a reference to the objectV.
IfVis an Object andV has a [[DataView]]internal slot, then:
Iftypes includes
DataView
, then return theresult ofconvertingV toDataView
.Iftypes includes
object
, then return the IDL valuethat is a reference to the objectV.
IfVis an Object andV has a [[TypedArrayName]]internal slot, then:
Iftypes includes atyped array type whose name is the value ofV’s [[TypedArrayName]]internal slot, then return theresult ofconvertingV to that type.
Iftypes includes
object
, then return the IDL valuethat is a reference to the objectV.
IfIsCallable(V) is true, then:
Iftypes includes acallback function type, then return the result ofconvertingV to that callback function type.
Iftypes includes
object
, then return the IDL valuethat is a reference to the objectV.
IfVis an Object, then:
Iftypes includes anasync iterable type, then
Iftypes does not include astring type orV does not have a [[StringData]]internal slot, then
LetasyncMethod be?GetMethod(V,
%Symbol.asyncIterator%
).IfasyncMethod is not
undefined ,return an IDLasync iterable value withobject set toV,method set tosyncMethod, andtype set to "async
".LetsyncMethod be?GetMethod(V,
%Symbol.iterator%
).IfsyncMethod is not
undefined ,return an IDLasync iterable value withobject set toV,method set tosyncMethod, andtype set to "sync
".
Iftypes includes asequence type, then
Letmethod be?GetMethod(V,
%Symbol.iterator%
).Ifmethod is not
undefined ,return the result ofcreating a sequence of that type fromV andmethod.
Iftypes includes afrozen array type, then
Letmethod be?GetMethod(V,
%Symbol.iterator%
).Ifmethod is not
undefined ,return the result ofcreating a frozen array of that type fromV andmethod.
Iftypes includes adictionary type, then return theresult ofconvertingV to that dictionary type.
Iftypes includes arecord type, then return theresult ofconvertingV to that record type.
Iftypes includes acallback interface type, then return the result ofconvertingV to thatcallback interface type.
Iftypes includes
object
, then return the IDL valuethat is a reference to the objectV.
IfVis a Boolean, then:
Iftypes includes
boolean
,then return the result ofconvertingV toboolean
.
IfVis a Number, then:
Iftypes includes anumeric type,then return the result ofconvertingV to thatnumeric type.
IfVis a BigInt, then:
Iftypes includes
bigint
,then return the result ofconvertingV tobigint
Iftypes includes astring type,then return the result ofconvertingV to that type.
Iftypes includes anumeric type and
bigint
,then return the result ofconvertingV to either thatnumeric type orbigint
.Iftypes includes anumeric type,then return the result ofconvertingV to thatnumeric type.
Iftypes includes
boolean
,then return the result ofconvertingV toboolean
.Iftypes includes
bigint
,then return the result ofconvertingV tobigint
.
An IDL union type value isconverted to a JavaScript value according to the rules for converting thespecific type of the IDL union type value as described in this section (§ 3.2 JavaScript type mapping).
3.2.26.Buffer source types
A value of an IDLArrayBuffer
is represented by an object of the corresponding JavaScript class.If it is notassociated with the [AllowResizable
]extended attribute, it can only be backed by JavaScriptArrayBuffer
objectsV for whichIsResizableArrayBuffer(V) is false.
A value of an IDLSharedArrayBuffer
is represented by an object of the corresponding JavaScriptclass. If it is notassociated with the [AllowResizable
]extended attribute, it can only be backed by JavaScriptSharedArrayBuffer
objectsV for whichIsResizableArrayBuffer(V) is false.
Values of the IDLbuffer view types are represented by objects of the corresponding JavaScriptclass, with the following additional restrictions on those objects.
- If the type is notassociated with either the [
AllowResizable
] or [AllowShared
]extended attribute, if applicable, they can only be backed by JavaScriptArrayBuffer
objectsV for whichIsResizableArrayBuffer(V) is false. - If the type isassociated with the [
AllowResizable
]extended attribute but not with the [AllowShared
]extended attribute, if applicable, they can only be backed by JavaScriptArrayBuffer
objects. - If the type isassociated with the [
AllowShared
]extended attribute but not with the [AllowResizable
]extended attribute, they can only be backed by JavaScriptArrayBuffer
andSharedArrayBuffer
objectsV for whichIsResizableArrayBuffer(V) is false. - If the type isassociated with both the [
AllowResizable
] and the [AllowShared
]extended attributes, they can be backed by any JavaScriptArrayBuffer
orSharedArrayBuffer
object.
A JavaScript valueV isconverted to an IDLArrayBuffer
value by running the following algorithm:
IfVis not an Object,orV does not have an [[ArrayBufferData]]internal slot,thenthrow a
TypeError
.IfIsSharedArrayBuffer(V) is true, thenthrow a
TypeError
.If the conversion is not to an IDL typeassociated with the [
AllowResizable
]extended attribute, andIsResizableArrayBuffer(V) is true,thenthrow aTypeError
.Return the IDL
ArrayBuffer
value that is a referenceto the same object asV.
A JavaScript valueV isconverted to an IDLSharedArrayBuffer
value by running the following algorithm:
IfVis not an Object,orV does not have an [[ArrayBufferData]]internal slot,thenthrow a
TypeError
.IfIsSharedArrayBuffer(V) is false, thenthrow a
TypeError
.If the conversion is not to an IDL typeassociated with the [
AllowResizable
]extended attribute, andIsResizableArrayBuffer(V) is true,thenthrow aTypeError
.Return the IDL
SharedArrayBuffer
value that is a referenceto the same object asV.
A JavaScript valueV isconverted to an IDLDataView
value by running the following algorithm:
IfVis not an Object,orV does not have a [[DataView]]internal slot,thenthrow a
TypeError
.If the conversion is not to an IDL typeassociated with the [
AllowShared
]extended attribute, andIsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is true,thenthrow aTypeError
.If the conversion is not to an IDL typeassociated with the [
AllowResizable
]extended attribute, andIsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) is true,thenthrow aTypeError
.Return the IDL
DataView
value that is a referenceto the same object asV.
A JavaScript valueV isconverted to an IDLInt8Array
,Int16Array
,Int32Array
,Uint8Array
,Uint16Array
,Uint32Array
,Uint8ClampedArray
,BigInt64Array
,BigUint64Array
,Float16Array
,Float32Array
, orFloat64Array
value by running the following algorithm:
LetT be the IDL typeV is being converted to.
IfVis not an Object,orV does not have a [[TypedArrayName]]internal slot with a value equal toT’s name,thenthrow a
TypeError
.If the conversion is not to an IDL typeassociated with the [
AllowShared
]extended attribute, andIsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is true,thenthrow aTypeError
.If the conversion is not to an IDL typeassociated with the [
AllowResizable
]extended attribute, andIsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) is true,thenthrow aTypeError
.Return the IDL value of typeT that is a reference to the same object asV.
ArrayBuffer
from abyte sequencebytes in arealmrealm:LetjsArrayBuffer be?AllocateArrayBuffer(realm.[[Intrinsics]].[[
%ArrayBuffer%
]],bytes’slength).LetarrayBuffer be the result ofconvertingjsArrayBuffer to an IDL value of type
ArrayBuffer
.Writebytes intoarrayBuffer.
ReturnarrayBuffer.
SharedArrayBuffer
from abyte sequencebytes in arealmrealm:LetjsSharedArrayBuffer be?AllocateSharedArrayBuffer(realm.[[Intrinsics]].[[
%SharedArrayBuffer%
]],bytes’slength).LetsharedArrayBuffer be the result ofconvertingjsSharedArrayBuffer to an IDL value of type
SharedArrayBuffer
.Writebytes intosharedArrayBuffer.
ReturnsharedArrayBuffer.
ArrayBufferView
types from abyte sequencebytes in arealmrealm:Assert: if the type is not
DataView
, thenbytes’slengthmodulo theelement size of that type is 0.LetarrayBuffer be the result ofcreating an
ArrayBuffer
frombytes inrealm.LetjsArrayBuffer be the result ofconvertingarrayBuffer to a JavaScript value.
Letconstructor be the appropriate constructor fromrealm.[[Intrinsics]] for the typeof
ArrayBufferView
being created.Return the result ofconvertingjsView into the given type.
LetjsBufferSource be the result ofconvertingbufferSource to a JavaScript value.
LetjsArrayBuffer bejsBufferSource.
Letoffset be 0.
Letlength be 0.
IfjsBufferSource has a [[ViewedArrayBuffer]]internal slot, then:
SetjsArrayBuffer tojsBufferSource.[[ViewedArrayBuffer]].
Setoffset tojsBufferSource.[[ByteOffset]].
Setlength tojsBufferSource.[[ByteLength]].
Otherwise:
Assert:jsBufferSource is an
ArrayBuffer
orSharedArrayBuffer
object.Setlength tojsBufferSource.[[ArrayBufferByteLength]].
IfIsDetachedBuffer(jsArrayBuffer) is true, then return the emptybyte sequence.
Letbytes be a newbyte sequence oflength equal tolength.
Fori inthe rangeoffset tooffset +length − 1, inclusive, setbytes[i −offset] toGetValueFromBuffer(jsArrayBuffer,i, Uint8,true, Unordered).
Returnbytes.
LetjsBufferSource be the result ofconvertingbufferSource to a JavaScript value.
IfjsBufferSource has a [[ViewedArrayBuffer]] internal slot, then returnjsBufferSource.[[ByteLength]].
ReturnjsBufferSource.[[ArrayBufferByteLength]].
IfbufferSource is abuffer type instance, then returnbufferSource.
LetjsBufferView be the result ofconvertingbufferSource to a JavaScript value.
LetjsBuffer bejsBufferView.[[ViewedArrayBuffer]].
IfIsSharedArrayBuffer(jsBuffer) is false, then return the result ofconvertingjsBuffer to an IDL value of type
ArrayBuffer
.Return the result ofconvertingjsBuffer to an IDL value oftype
SharedArrayBuffer
.
LetjsArrayBuffer be the result ofconvertingarrayBuffer to a JavaScript value.
Assert:bytes’slength ≤jsArrayBuffer.[[ArrayBufferByteLength]]−startingOffset.
Fori inthe rangestartingOffset tostartingOffset +bytes’slength − 1, inclusive, performSetValueInBuffer(jsArrayBuffer,i, Uint8,bytes[i -startingOffset], true, Unordered).
ArrayBufferView
view, optionally given astartingOffset (default 0):LetjsView be the result ofconvertingview toa JavaScript value.
Assert:bytes’slength ≤jsView.[[ByteLength]] −startingOffset.
Assert: ifview is not a
DataView
, thenbytes’slengthmodulo theelement size ofview’s type is 0.LetarrayBuffer be the result ofconvertingjsView.[[ViewedArrayBuffer]] to an IDL value of type
ArrayBuffer
.Writebytes intoarrayBuffer withstartingOffset set tojsView.[[ByteOffset]] +startingOffset.
SharedArrayBuffer
object is involved.For the non-shared cases, a more recommended pattern is totransfer theArrayBuffer
first if possible, to ensure the writes cannot overlap with other modifications, and then give the newArrayBuffer
instance to author code as necessary. Alternately, you canget a copy of the bytes held by the buffer source, modify those bytes, and then use them tocreate a newArrayBuffer
orArrayBufferView
to give back to author code.
ArrayBuffer
arrayBuffer:LetjsArrayBuffer be the result ofconvertingarrayBuffer to a JavaScript value.
Perform?DetachArrayBuffer(jsArrayBuffer).
This will throw an exception ifjsArrayBuffer has an [[ArrayBufferDetachKey]] that is not undefined, such as is the case with the value ofWebAssembly.Memory
’sbuffer
attribute.[WASM-JS-API-1]
Detaching a buffer that is alreadydetached is a no-op.
LetjsArrayBuffer be the result ofconvertingbufferSource to a JavaScript value.
IfjsArrayBuffer has a [[ViewedArrayBuffer]] internal slot, then setjsArrayBuffer tojsArrayBuffer.[[ViewedArrayBuffer]].
ReturnIsDetachedBuffer(jsArrayBuffer).
LetjsArrayBuffer be the result ofconvertingbufferSource to a JavaScript value.
IfjsArrayBuffer has a [[ViewedArrayBuffer]] internal slot, then setjsArrayBuffer tojsArrayBuffer.[[ViewedArrayBuffer]].
IfIsSharedArrayBuffer(jsArrayBuffer) is true, then return false.
IfIsDetachedBuffer(jsArrayBuffer) is true, then return false.
IfjsArrayBuffer.[[ArrayBufferDetachKey]] is not
undefined , thenreturn false.Return true.
ArrayBuffer
arrayBuffer, optionally given arealmtargetRealm:LetjsArrayBuffer be the result ofconvertingarrayBuffer to a JavaScript value.
IfIsDetachedBuffer(jsArrayBuffer) is false, thenthrow a
TypeError
.LetarrayBufferData bejsArrayBuffer.[[ArrayBufferData]].
LetarrayBufferByteLength bejsArrayBuffer.[[ArrayBufferByteLength]].
Perform?DetachArrayBuffer(jsArrayBuffer).
IftargetRealm is not given, lettargetRealm be thecurrent realm.
LetjsTransferred be?AllocateArrayBuffer(targetRealm.[[Intrinsics]].[[
%ArrayBuffer%
]], 0).SetjsTransferred.[[ArrayBufferData]] toarrayBufferData.
SetjsTransferred.[[ArrayBufferByteLength]] toarrayBufferByteLength.
Return the result ofconvertingjsTransferred to an IDLvalue of type
ArrayBuffer
.
arrayBuffer cannot bedetached, for the reasonsexplained in that algorithm’sdefinition;
arrayBuffer is alreadydetached;
Sufficient memory cannot be allocated inrealm. Generally this will only be the caseifrealm is in a differentagent cluster than the one in whicharrayBuffer wasallocated. If they are in the sameagent cluster, then implementations will justchange the backing pointers to get the same observable results with better performanceand no allocations.
3.2.27.Frozen arrays — FrozenArray<T>
Values of frozen array types are represented by frozen JavaScriptArray object references.
A JavaScript valueV isconverted to an IDLFrozenArray<T> value by running the following algorithm:
Letvalues be the result ofconvertingV to IDL typesequence<T>.
Return the result ofcreating a frozen array fromvalues.
Tocreate a frozen array from a sequence of values of typeT, follow these steps:
Letarray be the result ofconverting the sequence of values of typeT to a JavaScript value.
Perform!SetIntegrityLevel(array, "
frozen
").Returnarray.
The result ofconverting an IDLFrozenArray<T> value to a JavaScriptvalue is the Object value that represents a referenceto the same object that the IDLFrozenArray<T> represents.
3.2.27.1.Creating a frozen array from an iterable
To create an IDL value of typeFrozenArray<T> given an iterableiterable and an iterator gettermethod, perform the following steps:
Letvalues be the result ofcreating a sequence of typesequence<T> fromiterable andmethod.
Return the result ofcreating a frozen array fromvalues.
3.2.28.Observable arrays — ObservableArray<T>
Values of observable array types are represented byobservable array exotic objects.
Instead of the usual conversion algorithms, observable array types have special handling as part oftheattribute getter andattribute setter algorithms.
In the JavaScript binding, JavaScript objects that representplatform objects have abacking observable array exotic object for eachregular attribute of anobservable array type. These are created and managed as part of thedefine the attributes algorithm.
Assert:objimplements aninterface with theregular attributeattribute.
Letoa beobj’sbacking observable array exotic object forattribute.
Returnoa.[[ProxyHandler]].[[BackingList]].
3.3.Extended attributes
This section defines a number ofextended attributes whose presence affects the JavaScript binding.
3.3.1.[AllowResizable]
If the [AllowResizable
]extended attribute appears on abuffer type, it creates a newIDL type that allows for the respective corresponding JavaScriptArrayBuffer
orSharedArrayBuffer
object to be resizable.
If the [AllowResizable
]extended attribute appears on one of thebuffer view types andthe [AllowShared
]extended attribute does not, it creates a new IDL type that allows thebuffer view type to be backed by a JavaScriptArrayBuffer
that isresizable, instead of only by a fixed-lengthArrayBuffer
.
If the [AllowResizable
]extended attribute and the [AllowShared
]extended attribute both appear on one of thebuffer view types, it creates a new IDL type that allows the bufferview type to be additionally backed by a JavaScriptSharedArrayBuffer
that is growable.
The [AllowResizable
] extended attribute musttake no arguments.
A type that is not abuffer source type must not beassociated with the [AllowResizable
] extended attribute.
See the rules for converting JavaScript values to IDLbuffer source types in§ 3.2.26 Buffer source types for the specific requirements that the use of [AllowResizable
] entails.
See theexample in§ 3.3.2 [AllowShared] for example usage of both [AllowResizable
] and [AllowShared
].
3.3.2.[AllowShared]
If the [AllowShared
]extended attribute appears on one of thebuffer view types, itcreates a new IDL type that allows the object to be backed by anSharedArrayBuffer
instead ofonly by anArrayBuffer
.
The [AllowShared
] extended attribute musttake no arguments.
A type that is not abuffer view type must not beassociated with the [AllowShared
] extended attribute.
See the rules for converting JavaScript values to IDLbuffer view types in§ 3.2.26 Buffer source types for the specific requirements that the use of [AllowShared
] entails.
AllowResizable
] and [AllowShared
]extended attribute:[Exposed =Window ]interface ExampleBufferFeature {undefined writeInto (ArrayBufferView dest );undefined writeIntoResizable ([AllowResizable ]ArrayBufferView dest );undefined writeIntoShared ([AllowShared ]ArrayBufferView dest );undefined writeIntoSharedResizable ([AllowResizable ,AllowShared ]ArrayBufferView dest );};
With this definition,
- A call to
writeInto
with anybuffer view type backed by either a resizableArrayBuffer
instance or aSharedArrayBuffer
instance, will throw aTypeError
exception. - A call to
writeIntoResizable
with anybuffer view type backed by aSharedArrayBuffer
instance, will throw aTypeError
exception. - A call to
writeIntoShared
with anybuffer view type backed by a resizableArrayBuffer
instance or a growableSharedArrayBuffer
instance, will throw aTypeError
exception. - A call to
writeIntoSharedResizable
will accept anybuffer view type backed by aArrayBuffer
instance or aSharedArrayBuffer
instance.
3.3.3.[Clamp]
If the [Clamp
]extended attribute appears on one of theinteger types, it creates a newIDL type such that that when a JavaScript Number is converted to the IDL type,out-of-range values will be clamped to the range of valid values, rather than using the operatorsthat use a modulo operation (ToInt32,ToUint32, etc.).
The [Clamp
]extended attribute musttake no arguments.
A type annotated with the [Clamp
] extended attribute must not appear in aread only attribute. A type must not beassociated with both the[Clamp
] and [EnforceRange
] extended attributes. A type that is not aninteger type mustnot beassociated with the [Clamp
] extended attribute.
See the rules for converting JavaScript values to the various IDL integertypes in§ 3.2.4 Integer types for the specific requirements that the use of[Clamp
] entails.
In the followingIDL fragment, twooperations are declared that take threeoctet
arguments; one uses the [Clamp
]extended attribute on all three arguments, while the other does not:
[Exposed =Window ]interface GraphicsContext {undefined setColor (octet red ,octet green ,octet blue );undefined setColorClamped ([Clamp ]octet red , [Clamp ]octet green , [Clamp ]octet blue );};
A call tosetColorClamped
with Number values that are out of range for anoctet
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.4.[CrossOriginIsolated]
If the [CrossOriginIsolated
]extended attribute appears on aninterface,partial interface,interface mixin,partial interface mixin,callback interface,namespace,partial namespace,interface member,interface mixin member, ornamespace member,it indicates that the construct isexposed only within an environment whosecross-origin isolated capability is true. The[CrossOriginIsolated
] extended attribute must not be used on any other construct.
The [CrossOriginIsolated
] extended attribute musttake no arguments.
If [CrossOriginIsolated
] appears on anoverloadedoperation,then it must appear on all overloads.
The [CrossOriginIsolated
]extended attribute must not be specified both on
aninterface member and itsinterface orpartial interface;
aninterface mixin member and itsinterface mixin orpartial interface mixin;
anamespace member and itsnamespace orpartial namespace.
Note: This is because adding the [CrossOriginIsolated
]extended attribute on amember when its containing definition is also annotated with the [CrossOriginIsolated
]extended attribute does not further restrict the exposure of themember.
Aninterface without the [CrossOriginIsolated
]extended attribute must notinherit from another interfacethat does specify [CrossOriginIsolated
].
The followingIDL fragment defines an interface with oneoperation that is executable from all contexts, and two which are executable only from cross-origin isolated contexts.
[Exposed =Window ]interface ExampleFeature { // This call will succeed in all contexts.Promise <Result >calculateNotSoSecretResult (); // This operation will not be exposed to a non-isolated context. In such a context, // there will be no "calculateSecretResult" property on ExampleFeature.prototype. [CrossOriginIsolated ]Promise <Result >calculateSecretResult (); // The same applies here: the attribute will not be exposed to a non-isolated context, // and in such a context there will be no "secretBoolean" property on // ExampleFeature.prototype. [CrossOriginIsolated ]readonly attribute boolean secretBoolean ;};// HighResolutionTimer will not be exposed in a non-isolated context, nor will its members.// In such a context, there will be no "HighResolutionTimer" property on Window.[Exposed =Window ,CrossOriginIsolated ]interface HighResolutionTimer {DOMHighResTimeStamp getHighResolutionTime ();};// The interface mixin members defined below will never be exposed in a non-isolated// context, regardless of whether the interface that includes them is. That is, in// non-isolated context, there will be no "snap" property on ExampleFeature.prototype.[CrossOriginIsolated ]interface mixin Snapshotable {Promise <boolean >snap ();};ExampleFeature includes Snapshotable ;// On the other hand, the following interface mixin members will be exposed to a// non-isolated context when included by a host interface that doesn’t have the// [CrossOriginIsolated] extended attribute. That is, in a non-isolated context, there will// be a "log" property on ExampleFeature.prototype.interface mixin Loggable {Promise <boolean >log ();};ExampleFeature includes Loggable ;
3.3.5.[Default]
If the [Default
]extended attribute appears on aregular operation, then it indicatesthat the appropriatedefault method steps must be carried out when the operation is invoked.
The [Default
] extended attribute musttake no arguments.
The [Default
] extended attribute must not be used on anything other than aregular operation thathas default method steps defined.
As an example, the [Default
] extended attribute is suitable for use ontoJSON
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 JavaScript language binding, there would exist atoJSON()
method onAnimal
,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 use the default toJSON steps): // // { // 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.6.[EnforceRange]
If the [EnforceRange
]extended attribute appears on one of theinteger types, it createsa new IDL type such that that when a JavaScript Number is converted to the IDLtype, out-of-range values will cause an exception to be thrown, rather than being converted to avalid 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 musttake no arguments.
A type annotated with the [EnforceRange
] extended attribute must not appear in aread only attribute. A type must not beassociated with both the [Clamp
] and [EnforceRange
] extended attributes. A type that is not aninteger type must not beassociated with the[EnforceRange
] extended attribute.
See the rules for converting JavaScript values to the various IDL integertypes in§ 3.2 JavaScript type mapping for the specific requirements that the use of[EnforceRange
] entails.
In the followingIDL fragment, twooperations are declared that take threeoctet
arguments; one uses the [EnforceRange
]extended attribute on all three arguments, while the other does not:
[Exposed =Window ]interface GraphicsContext {undefined setColor (octet red ,octet green ,octet blue );undefined setColorEnforcedRange ([EnforceRange ]octet red , [EnforceRange ]octet green , [EnforceRange ]octet blue );};
In a JavaScript implementation of the IDL, a call to setColorEnforcedRange with Number values that are out of range for anoctet
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.7.[Exposed]
When the [Exposed
]extended attribute appears onaninterface,partial interface,interface mixin,partial interface mixin,callback interface,namespace,partial namespace, oran individualinterface member,interface mixin member, ornamespace member,it indicates that the construct is exposedon that particular set of global interfaces.
The [Exposed
]extended attribute must eithertake an identifier,take an identifier list ortake a wildcard.Each of the identifiers mentioned must be aglobal name of someinterface and be unique.
Theown exposure set is either aset of identifiers or the special value*
, defined as follows:
- If the [
Exposed
]extended attributetakes an identifierI Theown exposure set is theset «I ».
- If the [
Exposed
]extended attributetakes an identifier listI Theown exposure set is thesetI.
- If the [
Exposed
]extended attributetakes a wildcard Theown exposure set is
*
.
[Exposed=*]
is to be used with care. It is only appropriate when an API does not expose significant new capabilities. If the API might be restricted or disabled in some environments, it is preferred to list the globals explicitly.
Theexposure set intersection of a constructC and interface-or-nullH is defined asfollows:
Assert:C is aninterface member,interface mixin member,namespace member,partial interface,partial interface mixin,partial namespace, orinterface mixin.
Assert:H is aninterface or null.
IfH is null, returnC’sown exposure set.
IfC’sown exposure set is
*
, returnH’sexposure set.IfH’sexposure set is
*
, returnC’sown exposure set.Return theintersection ofC’sown exposure set andH’sexposure set.
Assert:C is aninterface,callback interface,namespace,interface member,interface mixin member, ornamespace member.
LetH beC’shost interface ifC is aninterface mixin member, or null otherwise.
IfC is aninterface member,interface mixin member, ornamespace member, then:
If the [
Exposed
]extended attribute is specified onC,return theexposure set intersection ofC andH.SetC to theinterface,partial interface,interface mixin,partial interface mixin,namespace, orpartial namespaceC is declared on.
IfC is apartial interface,partial interface mixin, orpartial namespace, then:
If the [
Exposed
]extended attribute is specified onC,return theexposure set intersection ofC andH.SetC to the originalinterface,interface mixin, ornamespace definitionofC.
IfC is aninterface mixin, then:
Assert:H is not null.
If the [
Exposed
]extended attribute is specified onC,return theexposure set intersection ofC andH.SetC toH.
Assert:C is aninterface,callback interface ornamespace.
Assert: The [
Exposed
]extended attribute is specified onC.ReturnC’sown exposure set.
If [Exposed
] appears on anoverloadedoperation,then it must appear identically on all overloads.
The [Exposed
] extended attribute must not be specified both onaninterface member,interface mixin member, ornamespace member, and onthepartial interface,partial interface mixin, orpartial namespace definitionthemember is declared on.
Note: This is because adding an [Exposed
]extended attribute on apartial interface,partial interface mixin, orpartial namespace is shorthand for annotating each of itsmembers.
If [Exposed
] appears on apartial interface orpartial namespace,then the partial’sown exposure set must be a subset oftheexposure set of the partial’s originalinterface ornamespace.
If [Exposed
] appears on aninterface ornamespace member,then themember’sexposure set must be a subsetof theexposure set of theinterface ornamespace it is a member of.
If [Exposed
] appears both on apartial interface mixin and its originalinterface mixin,then thepartial interface mixin’sown exposure set must be a subset of theinterface mixin’sown exposure set.
If [Exposed
] appears both on aninterface mixin member and theinterface mixin it is a member of,then theinterface mixin members’sown exposure set must be a subset of theinterface mixin’sown exposure set.
If an interfaceXinherits from another interfaceY then theexposure set ofX must be a subset of theexposure set ofY.
Note: As aninterface mixin can beincluded by differentinterfaces,theexposure set of itsmembers is a function oftheinterface thatincludes them.If theinterface mixin member,partial interface mixin, orinterface mixin is annotated with an [Exposed
]extended attribute,then theinterface mixin member’sexposure set is theintersection of the relevant construct’sown exposure set with thehost interface’sexposure set.Otherwise, it is thehost interface’sexposure set.
Ifconstruct’sexposure set is not
*
, andrealm.[[GlobalObject]] doesnot implement aninterface that is inconstruct’sexposure set, then return false.Ifrealm’ssettings object is not asecure context, andconstruct isconditionally exposed on [
SecureContext
], then return false.Ifrealm’ssettings object’scross-origin isolated capability is false, andconstruct isconditionally exposed on [
CrossOriginIsolated
], then return false.Return true.
Assert:construct is aninterface,callback interface,namespace,interface member,interface mixin member, ornamespace member.
LetH beconstruct’shost interface ifconstruct is aninterface mixin member,or null otherwise.
Ifconstruct is aninterface member,interface mixin member, ornamespace member, then:
If theexposure conditionextended attribute is specified onconstruct,then return true.
Otherwise, setconstruct to be theinterface,partial interface,interface mixin,partial interface mixin,namespace, orpartial namespaceconstruct is declared on.
Ifconstruct is apartial interface,partial interface mixin, orpartial namespace, then:
If theexposure conditionextended attribute is specified onconstruct,then return true.
Otherwise, setconstruct to be the originalinterface,interface mixin, ornamespace definition ofconstruct.
Ifconstruct is aninterface mixin, then:
If theexposure conditionextended attribute is specified onconstruct,then return true.
Otherwise, setconstruct toH.
Assert:construct is aninterface,callback interface ornamespace.
If theexposure conditionextended attribute is specified onconstruct,then return true.
Otherwise, return false.
Note: Since it is not possible for therelevant settings object for a JavaScript global object to change whether it is asecure context orcross-origin isolated capability over time, animplementation’s decision to create properties for an interface or interface member can be madeonce, at the time theinitial objects are created.
See§ 3.7 Interfaces,§ 3.7.5 Constants,§ 3.7.6 Attributes,§ 3.7.7 Operations, andfor the specific requirements that the use of[Exposed
] entails.
[Exposed
] is intended to be used to control whetherinterfaces,callback interfaces,namespaces, or individualinterface,mixin ornamespace 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 {undefined 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.8.[Global]
If the [Global
]extended attribute appears on aninterface,it indicates that objects implementing this interface willbe used as the global object in arealm.
The [Global
]extended attribute also defines theglobal names for theinterface:
- If the [
Global
]extended attributetakes an identifier « the givenidentifier »
- If the [
Global
]extended attributetakes an identifier list the identifier list
The [Global
] extended attribute must be one of the forms given above.
Note: Theglobal names for theinterface are theidentifiers that can be used toreference it in the [Exposed
]extended attribute.A single name can be shared across multiple different global interfaces,allowing an interface to more easily use [Exposed
] to expose itself to all of them at once.For example, "Worker
" is used to refer to several distinct types of threading-relatedglobal interfaces.
For these globalinterfaces, the structure of the prototype chain and how propertiescorresponding tointerface members will be reflected on the prototype objects will be differentfrom other interfaces. Specifically:
Anynamed properties will be exposed on an object in the prototype chain – thenamed properties object –rather than on the object itself.
Interface members from theinterface will correspond to properties on the object itself rather than oninterface prototype objects.
Allrealms have anis global prototype chain mutable boolean,which can be set when therealm is created.Its value can not change during the lifetime of therealm.By default it is set to false.
This allows theShadowRealm
global to have a mutable prototype.
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 JavaScript, the code above would result in thewindow.indexedDB
andwindow.requestAnimationFrame
evaluating to
If the [Global
]extended attributes isused on aninterface, then:
The interface must not define anamed property setter.
The interface must not defineindexed property getters orsetters.
The interface must not define aconstructor operation.
The interface must not also be declared with the [
LegacyOverrideBuiltIns
]extended attribute.The interface must notinherit from another interface with the[
LegacyOverrideBuiltIns
] extended attribute.Any other interface must notinherit from it.
If [Global
] is specified onapartial interface definition, then that partial interface definition mustbe the part of the interface definition that definesthenamed property getter.
The [Global
]extended attribute must notbe used on aninterface that can have morethan one object implementing it in the samerealm.
Note: This is because thenamed properties object,which exposes the named properties, is in the prototype chain, and it would not makesense for more than one object’s named properties to be exposed on an object thatall of those objects inherit from.
If an interface is declared with the [Global
]extended attribute, thenthere must not be more than onemember acrossthe interfacewith the sameidentifier.There also must not be more thanonestringifier or more than oneiterable declaration,asynchronously iterable declaration,maplike declaration orsetlike declaration across those interfaces.
Note: This is because all of themembers of the interfaceget flattened down on to the object thatimplements the interface.
See§ 3.7.4 Named properties object for the specific requirementsthat the use of [Global
] entails fornamed properties,and§ 3.7.5 Constants,§ 3.7.6 Attributes and§ 3.7.7 Operations for the requirements relating to the location of propertiescorresponding tointerface members.
TheWindow
interface exposes frames as properties on theWindow
object. Since theWindow
object also serves as the JavaScript 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 =Window ]interface Window {getter any (DOMString name );attribute DOMString name ; // ...};
The following HTML document illustrates how the named properties on theWindow
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.9.[NewObject]
If the [NewObject
]extended attribute appears on aregular orstaticoperation,then it indicates that when calling the operation,a reference to a newly created objectmust always be returned.
The [NewObject
]extended attribute musttake no arguments.
The [NewObject
]extended attribute must notbe used on anything other than aregular orstaticoperation whosereturn type is aninterface type orapromise type.
As an example, this extended attribute is suitable for use on thecreateElement()
operation on theDocument
interface, since a new object is always returned when it is called.[DOM]
[Exposed =Window ]interface Document :Node { [NewObject ]Element createElement (DOMString localName ); // ...};
3.3.10.[PutForwards]
If the [PutForwards
]extended attribute appears on aread onlyregular attribute declaration whose type isaninterface type,it indicates that assigning to the attribute will have specific behavior.Namely, the assignment is “forwarded” to the attribute (specified bythe extended attribute argument) on the object that is currentlyreferenced by the attribute being assigned to.
The [PutForwards
] extendedattribute musttake an identifier.Assuming that:
A is theattribute on which the [
PutForwards
]extended attribute appears,I is theinterface on whichA is declared,
J is theinterface type thatA is declared to be of, and
N is theidentifier argument of the extended attribute,
then there must be anotherattributeB declared onJ whoseidentifier isN. Assignment of a value to the attributeA on an object implementingI will result in that valuebeing assigned to attributeB of the object thatA references, instead.
Note that [PutForwards
]-annotatedattributes can bechained. 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 achain of forwarded assignments. A cycle exists if, when followingthe chain of forwarded assignments, a particular attribute onaninterface isencountered more than once.
An attribute with the [PutForwards
]extended attribute must not also be declaredwith the [LegacyLenientSetter
] or[Replaceable
] extended attributes.
The [PutForwards
]extended attribute must not be usedon anattribute thatis notread only.
The [PutForwards
] extended attributemust not be used on astatic attribute.
The [PutForwards
] extended attributemust not be used on an attribute declared onanamespace.
See theAttributes section for how[PutForwards
]is to be implemented.
The followingIDL fragment defines interfaces for names and people. The [PutForwards
] extended attribute is used on thename
attribute of thePerson
interface to indicate that assignments to that attribute result in assignments to thefull
attribute of thePerson
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 JavaScript binding, this would allow assignments to thename
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.11.[Replaceable]
If the [Replaceable
]extended attribute appears on aread onlyregular attribute,it indicates that setting the corresponding property on theplatform object will result inan own property with the same name being created on the objectwhich has the value being assigned. This property will shadowthe accessor property corresponding to the attribute, whichexists on theinterface prototype object.
The [Replaceable
]extended attribute musttake no arguments.
An attribute with the [Replaceable
]extended attribute must not also be declaredwith the [LegacyLenientSetter
] or[PutForwards
] extended attributes.
The [Replaceable
]extended attribute must not be usedon anattribute thatis notread only.
The [Replaceable
] extended attributemust not be used on astatic attribute.
The [Replaceable
] extended attributemust not be used on an attribute declared onanamespace.
See§ 3.7.6 Attributes for the specific requirements that the use of[Replaceable
] entails.
The followingIDL fragment defines aninterface with anoperation that increments a counter, and anattribute that exposes the counter’s value, which is initially 0:
[Exposed =Window ]interface Counter { [Replaceable ]readonly attribute unsigned long value ;undefined increment ();};
Assigning to thevalue
property on aplatform object implementingCounter
will shadow the property that corresponds to theattribute:
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.12.[SameObject]
If the [SameObject
]extended attribute appears on aread onlyattribute, then itindicates that when getting the value of the attribute on a givenobject, the same value must alwaysbe returned.
The [SameObject
]extended attribute musttake no arguments.
The [SameObject
]extended attribute must notbe used on anything other than aread onlyattribute whose type is aninterface type orobject
.
As an example, this extended attribute is suitable for use on theimplementation
attribute on theDocument
interface since the same object is always returned for a givenDocument
object.[DOM]
[Exposed =Window ]interface Document :Node { [SameObject ]readonly attribute DOMImplementation implementation ; // ...};
3.3.13.[SecureContext]
If the [SecureContext
]extended attribute appears on aninterface,partial interface,interface mixin,partial interface mixin,callback interface,namespace,partial namespace,interface member,interface mixin member, ornamespace member,it indicates that the construct isexposed only within asecure context.The [SecureContext
] extended attribute must not be usedon any other construct.
The [SecureContext
] extended attribute musttake no arguments.
If [SecureContext
] appears on anoverloadedoperation,then it must appear on all overloads.
The [SecureContext
]extended attribute must not be specified both on
aninterface member and itsinterface orpartial interface;
aninterface mixin member and itsinterface mixin orpartial interface mixin;
anamespace member and itsnamespace orpartial namespace.
Note: This is because adding the [SecureContext
]extended attribute on amember whenits containing definition is also annotated with the [SecureContext
]extended attribute does not further restrict the exposure of themember.
Aninterface without the [SecureContext
]extended attribute must notinherit from another interfacethat does specify [SecureContext
].
[SecureContext
] must not be specified on a construct is that isconditionally exposed on[CrossOriginIsolated
]. (Doing so would be redundant, since every environment which iscross-origin isolated is also asecure context.)
The followingIDL fragment defines an interface with oneoperation that is executable from all contexts, and two which are executable only from secure contexts.
[Exposed =Window ]interface ExampleFeature { // 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 ExampleFeature.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 // ExampleFeature.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.[Exposed =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. That is, in a non-secure// context, there will be no "snap" property on ExampleFeature.prototype.[SecureContext ]interface mixin Snapshotable {Promise <boolean >snap ();};ExampleFeature 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. That is, in a non-secure context, there will be a "log" property on// ExampleFeature.prototype.interface mixin Loggable {Promise <boolean >log ();};ExampleFeature includes Loggable ;
3.3.14.[Unscopable]
If the [Unscopable
]extended attribute appears on aregular attribute orregular operation, itindicates that an object thatimplements an interface with the giveninterface member will not include its property name in any objectenvironment record with it as its base object. The result of this isthat bare identifiers matching the property name will not resolve tothe property in awith
statement. This is achieved byincluding the property name on theinterface prototype object’s%Symbol.unscopables%
property’s value.
The [Unscopable
]extended attribute musttake no arguments.
The [Unscopable
]extended attribute must not appear onanything other than aregular attribute orregular operation.
The [Unscopable
] extended attribute must not be used on an attribute declared on anamespace.
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 {undefined f (); [Unscopable ]g ();};
thef
property can be referenced with a bare identifier in awith
statement but theg
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 ofextended attributes whose presence affects the JavaScriptbinding. Unlike those in§ 3.3 Extended attributes, these exist only so that legacy Web platformfeatures can be specified. They should not be used in specifications, unless required to specify thebehavior of legacy APIs.
Editors who believe they have a good reason for using these extended attributes are strongly advisedto discuss this byfiling an issue before proceeding.
3.4.1.[LegacyFactoryFunction]
Instead of using this feature, give your interface aconstructor operation.
If the [LegacyFactoryFunction
]extended attribute appears on aninterface,it indicates that the JavaScript global object will have a property with thespecified name whose value is a function that cancreate objects that implement the interface.Multiple [LegacyFactoryFunction
] extendedattributes may appear on a given interface.
The [LegacyFactoryFunction
] extended attribute musttake a named argument list.TheLegacyFactoryFunction
]'sidentifier.For each [LegacyFactoryFunction
] extended attribute on the interface,there will be a way to construct an object thatimplements the interface by passing the specified arguments to theconstructor that is the value of the aforementioned property.
Theidentifier used for the legacy factory function must notbe the same as that used by a [LegacyFactoryFunction
]extended attribute on another interface, must notbe the same as anidentifier used by a [LegacyWindowAlias
]extended attribute on this interface or another interface,must not be the same as anidentifier of an interfacethat has aninterface object,and must not be one of thereserved identifiers.
The [LegacyFactoryFunction
] and [Global
]extended attributes must not be specified on thesameinterface.
See§ 3.7.2 Legacy factory functions for details on how legacy factory functionsare to be implemented.
The following IDL defines an interface that uses the [LegacyFactoryFunction
] extended attribute.
[Exposed =Window ,LegacyFactoryFunction =Audio (DOMString src )]interface HTMLAudioElement :HTMLMediaElement { // ...};
A JavaScript implementation that supports this interface will allow the construction ofHTMLAudioElement
objects using theAudio
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 aprototype
property equal to theprototype
of the original interface:
console. assert( Audio. prototype=== HTMLAudioElement. prototype);
3.4.2.[LegacyLenientSetter]
If the [LegacyLenientSetter
]extended attribute appears on aread onlyregular attribute,it indicates that a no-op setter will be generated for the attribute’saccessor property. This results in erroneous assignments to the propertyin 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 attributeby assigning to the property, but have accidentally done so even if the property exists. In strictmode, 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 attributemusttake no arguments.It must not be used on anything other thanaread onlyregular attribute.
An attribute with the [LegacyLenientSetter
]extended attribute must not also be declaredwith the [PutForwards
]or [Replaceable
] extended attributes.
The [LegacyLenientSetter
] extended attribute must not be used on an attribute declared on anamespace.
See theAttributes 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 ;};
A JavaScript 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 aregular attribute,it indicates that invocations of the attribute’s getter or setterwith a
The [LegacyLenientThis
] extended attributemusttake no arguments.It must not be used on astatic attribute.
The [LegacyLenientThis
] extended attribute must not be used on an attribute declared on anamespace.
See theAttributes 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 ;};
A JavaScript 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 anExample
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 namingconvention 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 aninterface, it indicates thattheinterface object for this interface will not be created as a property of the globalobject, but rather as a property of thenamespace identified by the argument to the extendedattribute.
The [LegacyNamespace
] extended attribute musttake an identifier.This identifier must be theidentifier of anamespace definition.
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 a JavaScript 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 aninterface,it indicates that aninterface object will not exist for the interface in the JavaScript binding.
The [LegacyNoInterfaceObject
] extended attributemusttake no arguments.
The [LegacyNoInterfaceObject
] extended attributemust not be specified on an interface that has anyconstructors orstatic operations defined on it.
An interface that does not have the [LegacyNoInterfaceObject
] extendedattribute specified must not inheritfrom an interface that has the [LegacyNoInterfaceObject
] extendedattribute specified.
See§ 3.7 Interfaces for the specific requirements that the use of[LegacyNoInterfaceObject
] entails.
The followingIDL fragment defines two interfaces, one whose interface object is exposed on the JavaScript global object, and one whose isn’t:
[Exposed =Window ]interface Storage {undefined addEntry (unsigned long key ,any value );};[Exposed =Window ,LegacyNoInterfaceObject ]interface Query {any lookupEntry (unsigned long key );};
A JavaScript implementation of the above IDL would allow manipulation ofStorage
’s prototype, but notQuery
’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 theDOMString
orUSVString
type,it creates a new IDL type such that that when a JavaScriptnull
", which is the default, it will be converted to the empty string.
The [LegacyNullToEmptyString
] extended attribute must not beassociated with a type that is notDOMString
orUSVString
.
Note: This means that evenDOMString?
must not use [LegacyNullToEmptyString
], since
See§ 3.2.10 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 );};
A JavaScript implementation implementing theDog
interface would convert aowner
property or passed as the argument to theisMemberOfBreed
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 aninterface,it indicates that for alegacy platform object implementing the interface,properties corresponding to all ofthe object’ssupported property names will appear to be on the object,regardless of what other properties exist on the object or itsprototype chain. This means that named properties will always shadowany properties that would otherwise appear on the object.This is in contrast to the usual behavior, which is for named propertiesto be exposed only if there is no property with thesame name on the object itself or somewhere on its prototype chain.
The [LegacyOverrideBuiltIns
]extended attribute musttake no arguments and must not appear on an interfacethat does not define anamed property getter or that also is declared with the [Global
]extended attribute.If the extended attribute is specified onapartial interface definition, then that partial interface definition mustbe the part of the interface definition that definesthenamed property getter.
If the [LegacyOverrideBuiltIns
] extended attribute is specified on apartial interface definition, it is considered to appear on theinterface itself.
See§ 3.9 Legacy platform objects and§ 3.9.3 [[DefineOwnProperty]] for the specific requirements that the use of[LegacyOverrideBuiltIns
] entails.
The followingIDL fragment defines twointerfaces, one that has anamed 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 a JavaScript 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 acallback function, thenit indicates that any value assigned to anattribute whose type is anullablecallback function will be converted more loosely: if the value is not an object, it will beconverted to null, and if the value is notcallable, it will be converted to acallback function value that does nothing when called.
See§ 3.2.20 Nullable types — T?,§ 3.2.19 Callback function types and§ 3.12 Invoking callback functions for the specific requirements that the use of[LegacyTreatNonObjectAsNull
] entails.
The followingIDL fragment defines an interface that has one attribute whose type is a [LegacyTreatNonObjectAsNull
]-annotatedcallback function and another whose type is acallback function without theextended attribute:
callback OccurrenceHandler =undefined (DOMString details );[LegacyTreatNonObjectAsNull ]callback ErrorHandler =undefined (DOMString details );[Exposed =Window ]interface Manager {attribute OccurrenceHandler ?handler1 ;attribute ErrorHandler ?handler2 ;};
In a JavaScript implementation, assigning a value that is not an object (such as a Number value), or that is notcallable 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 ainterface thatsupports named properties,it indicates that all the interface’s named properties are unenumerable.
The [LegacyUnenumerableNamedProperties
]extended attribute musttake no arguments and must not appear on an interfacethat does not define anamed property getter.
If the [LegacyUnenumerableNamedProperties
]extended attribute is specified on an interface, then it applies to all its derived interfaces andmust 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 onregular attributes or non-staticoperations,it indicates that the attribute or operationwill be reflected as a JavaScript propertyin a way that means its behavior cannot be modifiedand that performing a property lookup on the objectwill always result in the attribute’s property value being returned.In particular, the property will be non-configurableand will exist as an own property on the object itselfrather than on its prototype.
An attribute or operation is said to beunforgeable on a given interfaceA if the attribute or operation is declared onA,and is annotated with the [LegacyUnforgeable
]extended attribute.
The [LegacyUnforgeable
] extended attribute musttake no arguments.
The [LegacyUnforgeable
]extended attribute must not appearon anything other than aregular attribute or a non-staticoperation.If it does appear on anoperation,then it must appear on all operationswith the sameidentifier on that interface.
The [LegacyUnforgeable
] extended attribute must not be usedon an attribute declared on anamespace.
If an attribute or operationX isunforgeable on an interfaceA,andA is one of theinherited interfaces of another interfaceB,thenB must not have aregular attribute or non-staticoperation with the sameidentifier asX.
For example, the following is disallowed:
[Exposed =Window ]interface A1 { [LegacyUnforgeable ]readonly attribute DOMString x ;};[Exposed =Window ]interface B1 :A1 {undefined x (); // Invalid; would be shadowed by A1’s x.};[Exposed =Window ]interface B2 :A1 { };B2 includes M1 ;interface mixin M1 {undefined 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 followingIDL fragment defines an interface that has twoattributes, one of which is designated as [LegacyUnforgeable
]:
[Exposed =Window ]interface System { [LegacyUnforgeable ]readonly attribute DOMString username ;readonly attribute long long loginTime ;};
In a JavaScript 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 aninterface,it indicates that theWindow
interface will have a propertyfor eachidentifier mentioned in the extended attribute,whose value is theinterface object for the interface.
The [LegacyWindowAlias
] extended attribute must eithertake an identifier ortake an identifier list.TheLegacyWindowAlias
]'sidentifiers.
Each of theidentifiers 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 theidentifier used by a [LegacyFactoryFunction
]extended attribute on this interface or another interface,must not be the same as anidentifier of an interface that has aninterface object,and must not be one of thereserved 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 specifiedon an interface that does not include theWindow
interface in itsexposure set.
An interface must not have more than one [LegacyWindowAlias
] extended attributes specified.
See§ 3.7 Interfaces for details on how legacy window aliasesare to be implemented.
The following IDL defines an interface that uses the [LegacyWindowAlias
] extended attribute.
[Exposed =Window ,LegacyWindowAlias =WebKitCSSMatrix ]interface DOMMatrix :DOMMatrixReadOnly { // ...};
A JavaScript implementation that supports this interface will expose two properties on theWindow
object with the same value and the same characteristics; one for exposing theinterface 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 toperform a security check on a givenobject. This check is used to determine whether a givenoperation invocation orattribute access should beallowed. The security check takes the following three inputs:
theplatform object onwhich the operation invocation or attribute access is being done,
theidentifier of the operation or attribute, and
the type of thefunction object –"
method
" (when it corresponds to an IDL operation), or"getter
" or "setter
" (when it corresponds to thegetter 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, theoverload resolution algorithm is defined. Its input is aneffective overload set,S, and a list of JavaScript values,args. Its output is a pair consisting of theoperation orextended attribute of one ofS’s entries and a list of IDL values or the special value “missing”. The algorithm behaves as follows:
Letmaxarg be the length of the longest type list of the entries inS.
Letn be thesize ofargs.
Initializeargcount to be min(maxarg,n).
Remove fromS all entries whose type list is not of lengthargcount.
Initialized to −1.
Initializemethod to
undefined .If there is more than one entry inS, then setd to be thedistinguishing argument index for the entries ofS.
Initializevalues to be an empty list, where each entry will be either an IDL value or the special value “missing”.
Initializei to 0.
Whilei <d:
LetV beargs[i].
Lettype be the type at indexi in the type list of any entry inS.
Note: All entries inS at this point have the same type andoptionality value at indexi.
Letoptionality be the value at indexi in the list ofoptionality values of any entry inS.
Ifoptionality is “optional” andV is
undefined , then:If the argument at indexi is declared with adefault value,then append tovalues that default value.
Otherwise, append tovalues the special value “missing”.
Otherwise, append tovalues the result ofconvertingV to IDL typetype.
Seti toi + 1.
Ifi =d, then:
LetV beargs[i].
Note: This is the argument that will be used to resolve which overload is selected.
IfV is
undefined , and there is an entry inS whose list ofoptionality values has “optional” at indexi,then remove fromS all other entries.Otherwise: ifV is
null orundefined ,and there is an entry inS that has one of the following types at positioni of its type list,anannotated type whoseinner type is one of the above types
aunion type orannotated union type thatincludes a nullable type or thathas adictionary type in itsflattened members
then remove fromS all other entries.
Otherwise: ifVis a platform object, andthere is an entry inS that has one of the following types at positioni of its type list,
aninterface type thatVimplements
anullable version of any of the above types
anannotated type whoseinner type is one of the above types
aunion type,nullable union type, orannotated union typethat has one of the above types in itsflattened member types
then remove fromS all other entries.
Otherwise: ifVis an Object,V has an [[ArrayBufferData]]internal slot, andthere is an entry inS that has one of the following types at positioni of its type list,
anullable version of either of the above types
anannotated type whoseinner type is one of the above types
aunion type,nullable union type, orannotated union typethat has one of the above types in itsflattened member types
then remove fromS all other entries.
Otherwise: ifVis an Object,V has a [[DataView]]internal slot, andthere is an entry inS that has one of the following types at positioni of its type list,
anullable version of either of the above types
anannotated type whoseinner type is one of the above types
aunion type,nullable union type, orannotated union typethat has one of the above types in itsflattened member types
then remove fromS all other entries.
Otherwise: ifVis an Object,V has a [[TypedArrayName]]internal slot, andthere is an entry inS that has one of the following types at positioni of its type list,
atyped array type whose nameis equal to the value ofV’s [[TypedArrayName]]internal slot
anullable version of either of the above types
anannotated type whoseinner type is one of the above types
aunion type,nullable union type, orannotated union typethat has one of the above types in itsflattened member types
then remove fromS all other entries.
Otherwise: ifIsCallable(V) is true,and there is an entry inS that has one of the following types at positioni of its type list,
acallback function type
anullable version of any of the above types
anannotated type whoseinner type is one of the above types
aunion type,nullable union type, orannotated union typethat has one of the above types in itsflattened member types
then remove fromS all other entries.
Otherwise: ifVis an Object andthere is an entry inS that has one of thefollowing types at positioni of its type list,
anullable version of any of the above types
anannotated type whoseinner type is one of the above types
aunion type,nullable union type, orannotated union typethat has one of the above types in itsflattened member types
and the following are not all true,
V has a [[StringData]]internal slot
S has one of the following types at positioni of its type list,
anullable version of astring type
anannotated type whoseinner type is astring type
aunion type,nullable union type, orannotated union typethat has one of the above types in itsflattened member types
and after performing the following steps,
Letmethod be?GetMethod(V,
%Symbol.asyncIterator%
).Ifmethod is
undefined , then setmethod to?GetMethod(V,%Symbol.iterator%
).
method is not
undefined , then remove fromS allother entries.Otherwise: ifVis an Object andthere is an entry inS that has one of thefollowing types at positioni of its type list,
anullable version of any of the above types
anannotated type whoseinner type is one of the above types
aunion type,nullable union type, orannotated union typethat has one of the above types in itsflattened member types
and after performing the following steps,
Letmethod be?GetMethod(V,
%Symbol.iterator%
).
method is not
undefined , then remove fromS allother entries.Otherwise: ifVis an Object andthere is an entry inS that has one of the following types at positioni of its type list,
anullable version of any of the above types
anannotated type whoseinner type is one of the above types
aunion type,nullable union type, orannotated union typethat has one of the above types in itsflattened member types
then remove fromS all other entries.
Otherwise: ifVis a Boolean and there is an entry inS that has one of the following types at positioni of its type list,
anannotated type whoseinner type is one of the above types
aunion type,nullable union type, orannotated union typethat has one of the above types in itsflattened member types
then remove fromS all other entries.
Otherwise: ifVis a Number and there is an entry inS that has one of the following types at positioni of its type list,
anannotated type whoseinner type is one of the above types
aunion type,nullable union type, orannotated union typethat has one of the above types in itsflattened member types
then remove fromS all other entries.
Otherwise: ifVis a BigInt and there is an entry inS that has one of the following types at positioni of its type list,
anannotated type whoseinner type is one of the above types
aunion type,nullable union type, orannotated union typethat has one of the above types in itsflattened member types
then remove fromS all other entries.
Otherwise: if there is an entry inS that has one of the following types at positioni of its type list,
anullable version of any of the above types
anannotated type whoseinner type is one of the above types
aunion type,nullable union type, orannotated union typethat has one of the above types in itsflattened member types
then remove fromS all other entries.
Otherwise: if there is an entry inS that has one of the following types at positioni of its type list,
anannotated type whoseinner type is one of the above types
aunion type,nullable union type, orannotated union typethat has one of the above types in itsflattened member types
then remove fromS all other entries.
Otherwise: if there is an entry inS that has one of the following types at positioni of its type list,
anannotated type whoseinner type is one of the above types
aunion type,nullable union type, orannotated union typethat has one of the above types in itsflattened member types
then remove fromS all other entries.
Otherwise: if there is an entry inS that has one of the following types at positioni of its type list,
anannotated type whoseinner type is one of the above types
aunion type,nullable union type, orannotated union typethat has one of the above types in itsflattened member types
then remove fromS all other entries.
Otherwise: if there is an entry inS that has
any
at positioni of its type list, then remove fromS all other entries.
Letcallable be theoperation orextended attribute of the single entry inS.
Ifi =d andmethod is not
undefined , thenLetV beargs[i].
LetT be the type at indexi in thetype list of the remaining entry inS.
Assert:T is asequence type.
Append tovalues the result ofcreating a sequence of typeT fromV andmethod.
Seti toi + 1.
Whilei <argcount:
LetV beargs[i].
Lettype be the type at indexi in the type list of the remaining entry inS.
Letoptionality be the value at indexi in the list ofoptionality values of the remaining entry inS.
Ifoptionality is “optional” andV is
undefined , then:If the argument at indexi is declared with adefault value,then append tovalues that default value.
Otherwise, append tovalues the special value “missing”.
Otherwise, append tovalues the result ofconvertingV to IDL typetype.
Seti toi + 1.
Whilei is less than the number of argumentscallable is declared to take:
Ifcallable’s argument at indexi is declared with adefault value,then append tovalues that default value.
Otherwise, ifcallable’s argument at indexi is not variadic, then append tovalues the special value “missing”.
Seti toi + 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 JavaScript 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 JavaScript arguments that were passed in to the function:
If there are more arguments passed in than the longestoverload argument list, then they are ignored.
After ignoring these trailing arguments, only overloadsthat 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 JavaScript 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 thedistinguishing 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 JavaScript value that is passed in at the distinguishing argument index to determine which IDL type it can correspond to. This allows us to select the final overload that will be invoked. If the value passed in isTypeError
. 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 JavaScript values to IDL values. (An exception exists when one of the overloads has anasync iterable type,sequence type orfrozen array type at the distinguishing argument index. In this case, we attempt to get the%Symbol.asyncIterator%
/%Symbol.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 anoptional argument’s JavaScript value to its equivalent IDL value,
Optional arguments corresponding to a final, variadic argument do not treat
3.7.Interfaces
For everyinterface that isexposed ina givenrealm and that is not declared withthe [LegacyNoInterfaceObject
] or [LegacyNamespace
]extended attributes,a corresponding property exists on therealm’sglobal object.The name of the property is theidentifier of the interface,and its value is an object called theinterface object.The characteristics of an interface object are described in§ 3.7.1 Interface object.
If the [LegacyWindowAlias
] extended attribute was specified on anexposed interface,then for eachidentifier in [LegacyWindowAlias
]'sidentifiers there exists a corresponding property on theWindow
global object.The name of the property is the givenidentifier,and its value is a reference to theinterface object for theinterface.
In addition, for every [LegacyFactoryFunction
] extended attribute on anexposed interface,a corresponding property exists on the JavaScript global object.The name of the property is the [LegacyFactoryFunction
]'sidentifier,and its value is an object called alegacy 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.
Toimplementation-check an objectjsValue against the interfaceinterface, with the identifiername and the typetype:
Ifobject is aplatform object,thenperform a security check, passing:
the platform objectobject
the identifiername
the typetype
Returnobject.
This algo is not yet consistently used everywhere.
3.7.1.Interface object
Theinterface object for a giveninterface is abuilt-in function object.It has properties that correspond to theconstants andstatic operations defined on that interface,as described in sections§ 3.7.5 Constants and§ 3.7.7 Operations.
If theinterface is declared with aconstructor operation,then theinterface object can be called as aconstructor to create an object thatimplements that interface.Calling that interface as a function will throw an exception.
Interface objects whoseinterfaces are not declaredwith aconstructor operation will throw when called,both as a function and as aconstructor.
Aninterface object for aninterface has an associated object called theinterface prototype object.This object has properties that correspond totheregular attributes andregular operations defined on the interface,and is described in more detail in§ 3.7.3 Interface prototype object.
Note: Since aninterface object is afunction object thetypeof
operator will return "function" when applied to an interface object.
An interface may haveoverridden constructor steps, which canchange the behavior of theinterface object when called or constructed. Bydefault interfaces do not have such steps.
In general, constructors are described by defining aconstructor operation and its behavior. Theoverridden constructor steps are used only for more complicated situations. Editors who wish to use this feature are strongly advised to discuss this byfiling an issue before proceeding.
Theinterface object for a giveninterfaceI withidentifierid and inrealmrealm iscreated as follows:
Letsteps beI’soverridden constructor steps if they exist, orthe following steps otherwise:
IfI was not declared with aconstructor operation,thenthrow a
TypeError
.Letargs be the passed arguments.
Letn be thesize ofargs.
Letid be the identifier of interfaceI.
Compute the effective overload set for constructors withidentifierid oninterfaceI and with argument countn, and letS be the result.
Let <constructor,values> be the resultof passingS andargs to theoverload resolution algorithm.
Letobject be the result ofinternally creating a new object implementingI, withrealm and
NewTarget
.Perform theconstructor steps ofconstructor withobject asthis andvalues as the argument values.
LetO beobject,converted to a JavaScript value.
Assert:O is an object thatimplementsI.
Assert:O.[[Realm]] isrealm.
ReturnO.
LetconstructorProto berealm.[[Intrinsics]].[[
%Function.prototype%
]].IfI inherits from some other interfaceP,then setconstructorProto to theinterface object ofP inrealm.
LetF beCreateBuiltinFunction(steps, « [[Unforgeables]] »,realm,constructorProto).
Letunforgeables beOrdinaryObjectCreate(
null ).Define the unforgeable regular operations ofI onunforgeables, givenrealm.
Define the unforgeable regular attributes ofI onunforgeables, givenrealm.
SetF.[[Unforgeables]] tounforgeables.
Note: this object is never exposed to user code. It exists only to ensure all instancesof an interface with an unforgeable member use the same JavaScript function objects forattribute getters,attribute setters andoperation functions.
PerformSetFunctionName(F,id).
Letlength be 0.
IfI was declared with aconstructor operation, then
Compute the effective overload set for constructors withidentifierid oninterfaceI and with argument count 0, and letS be the result.
Setlength to the length of theshortest argument list of the entries inS.
PerformSetFunctionLength(F,length).
Letproto be the result ofcreating an interfaceprototype object ofinterfaceI inrealm.
Perform!DefinePropertyOrThrow(F, "
prototype
",PropertyDescriptor{[[Value]]:proto, [[Writable]]:false , [[Enumerable]]:false , [[Configurable]]:false }).Define the constants ofinterfaceI onF givenrealm.
Define the static attributes ofinterfaceI onF givenrealm.
Define the static operations ofinterfaceI onF givenrealm.
ReturnF.
3.7.2.Legacy factory functions
Alegacy factory function that exists due to one or more[LegacyFactoryFunction
]extended attributes with a givenidentifier is abuilt-in function object.It allows constructing objects thatimplement the interface on which the[LegacyFactoryFunction
] extended attributes appear.
Thelegacy factory function withidentifierid for a giveninterfaceI inrealmrealm iscreated as follows:
Letsteps be the following steps:
Letargs be the passed arguments.
Letn be thesize ofargs.
Compute the effective overload set for legacy factory functions withidentifierid oninterfaceI and with argument countn, and letS be the result.
Let <constructor,values> be the result of passingS andargs to theoverload resolution algorithm.
Letobject be the result ofinternally creating a new object implementingI, withrealm and
NewTarget
.Perform theconstructor steps ofconstructor withobject asthis andvalues as the argument values.
LetO beobject,converted to a JavaScript value.
Assert:O is an object thatimplementsI.
Assert:O.[[Realm]] isrealm.
ReturnO.
LetF beCreateBuiltinFunction(steps, « »,realm).
PerformSetFunctionName(F,id).
Compute the effective overload set for legacy factory functions withidentifierid oninterfaceI and with argument count 0, and letS be the result.
Letlength be the length of the shortest argument list of the entries inS.
PerformSetFunctionLength(F,length).
Letproto be theinterface prototype object ofinterfaceI inrealm.
Perform!DefinePropertyOrThrow(F, "
prototype
",PropertyDescriptor{[[Value]]:proto, [[Writable]]:false , [[Enumerable]]:false , [[Configurable]]:false }).ReturnF.
3.7.3.Interface prototype object
There will exist aninterface prototype object for everyinterface defined,regardless of whether the interface was declaredwith the [LegacyNoInterfaceObject
]extended attribute.
Theinterface prototype object for a giveninterfaceinterface andrealmrealm iscreated as follows:
Letproto be null.
Ifinterface is declared with the [
Global
]extended attribute,andinterfacesupports named properties,then setproto to the result ofcreating a namedproperties object forinterface andrealm.Otherwise, ifinterface is declared to inherit from another interface,then setproto to theinterface prototype object inrealm of thatinherited interface.
Otherwise, ifinterface is the
DOMException
interface,then setproto torealm.[[Intrinsics]].[[%Error.prototype%
]].Otherwise, setproto torealm.[[Intrinsics]].[[
%Object.prototype%
]].Assert:protois an Object.
LetinterfaceProtoObj be null.
Ifrealm’sis global prototype chain mutable is true, then:
SetinterfaceProtoObj toOrdinaryObjectCreate(proto).
Otherwise, ifinterface is declared with the [
Global
]extended attribute, orinterface is in the set ofinherited interfaces of an interfacethat is declared with the [Global
]extended attribute, then:SetinterfaceProtoObj toMakeBasicObject(« [[Prototype]], [[Extensible]] »).
SetinterfaceProtoObj.[[Prototype]] toproto.
Set the internal methods ofinterfaceProtoObj which are specific toimmutable prototype exotic objects to the definitions specified inECMA-262 Immutable prototype exotic objects.
Otherwise, setinterfaceProtoObj toOrdinaryObjectCreate(proto).
Ifinterface has anymember declared with the [
Unscopable
]extended attribute,then:LetunscopableObject beOrdinaryObjectCreate(
null ).For eachexposedmembermember ofinterface that is declared with the [
Unscopable
]extended attribute:Letid bemember’sidentifier.
Perform!CreateDataPropertyOrThrow(unscopableObject,id,
true ).
Letdesc be the PropertyDescriptor{[[Value]]:unscopableObject,[[Writable]]:
false , [[Enumerable]]:false ,[[Configurable]]:true }.Perform!DefinePropertyOrThrow(interfaceProtoObj,
%Symbol.unscopables%
,desc).
Ifinterface is not declared with the [
Global
]extended attribute, then:Define the regular attributes ofinterface oninterfaceProtoObj givenrealm.
Define the regular operations ofinterface oninterfaceProtoObj givenrealm.
Define the iteration methods ofinterface oninterfaceProtoObj givenrealm.
Define the asynchronous iteration methods ofinterface oninterfaceProtoObj givenrealm.
Define the constants ofinterface oninterfaceProtoObj givenrealm.
If the [
LegacyNoInterfaceObject
]extended attribute was not specified oninterface, then:Letconstructor be theinterface object ofinterface inrealm.
Letdesc be the PropertyDescriptor{[[Writable]]:
true ,[[Enumerable]]:false , [[Configurable]]:true ,[[Value]]:constructor}.Perform!DefinePropertyOrThrow(interfaceProtoObj, "
constructor
",desc).
ReturninterfaceProtoObj.
Additionally,interface prototype objects get properties declaratively from:
Define those properties imperatively instead.
Theinterface prototype object of aninterface 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 theinterface object (since it does not exist aswindow.Foo
). However, an instance ofFoo
can expose the interface prototype object by calling its [[GetPrototypeOf]]internal method –Object.getPrototypeOf(window.foo)
in this example.
Theclass string of aninterface prototype object is theinterface’squalified name.
3.7.4.Named properties object
For everyinterface declared with the [Global
]extended attribute thatsupports named properties,there will exist an object known as thenamed properties object for that interface on which named properties are exposed.
Letproto be null.
Ifinterface is declared to inherit from another interface,then setproto to theinterface prototype object inrealm for theinherited interface.
Otherwise, setproto torealm.[[Intrinsics]].[[
%Object.prototype%
]].Letobj beMakeBasicObject(« [[Prototype]], [[Extensible]] »).
Setobj.[[GetOwnProperty]] as specified in§ 3.7.4.1 [[GetOwnProperty]].
Setobj.[[DefineOwnProperty]] as specified in§ 3.7.4.2 [[DefineOwnProperty]].
Setobj.[[Delete]] as specified in§ 3.7.4.3 [[Delete]].
Setobj.[[SetPrototypeOf]] as specified in§ 3.7.4.4 [[SetPrototypeOf]].
Setobj.[[PreventExtensions]] as specified in§ 3.7.4.5 [[PreventExtensions]].
Setobj.[[Prototype]] toproto.
Returnobj.
Note: The [[OwnPropertyKeys]] internal method of a named properties objectcontinues to useOrdinaryOwnPropertyKeys,unlike the counterpart forlegacy platform objects.Since named properties are not “real” own properties,they will not be returned by this internal method.
Theclass string of anamed properties object is the concatenation of theinterface’sidentifier and the string "Properties
".
3.7.4.1.[[GetOwnProperty]]
When the [[GetOwnProperty]] internal method of anamed properties objectO is called with property keyP, the following steps are taken:
LetA be theinterface for thenamed properties objectO.
Letobject beO.[[Realm]]'sglobal object.
Assert:objectimplementsA.
If the result of running thenamed property visibility algorithm withproperty nameP and objectobject is true, then:
Letoperation be the operation used to declare the named property getter.
Letvalue be an uninitialized variable.
Ifoperation was defined without anidentifier, thensetvalue to the result of performing the steps listed in the interface description todetermine the value of a named property withP as the name.
Otherwise,operation was defined with an identifier. Setvalue to the resultof performing the steps listed in the description ofoperation withP as the only argument value.
Letdesc be a newly createdProperty Descriptor with no fields.
Setdesc.[[Value]] to the result ofconvertingvalue to a JavaScript value.
IfAimplements an interface with the[
LegacyUnenumerableNamedProperties
]extended attribute,then setdesc.[[Enumerable]] tofalse ,otherwise set it totrue .Setdesc.[[Writable]] to
true anddesc.[[Configurable]] totrue .Returndesc.
ReturnOrdinaryGetOwnProperty(O,P).
3.7.4.2.[[DefineOwnProperty]]
When the [[DefineOwnProperty]] internal method of anamed properties object is called, the following steps are taken:
Return
false .
3.7.4.3.[[Delete]]
When the [[Delete]] internal method of anamed properties object is called, the following steps are taken:
Return
false .
3.7.4.4.[[SetPrototypeOf]]
When the [[SetPrototypeOf]] internal method of anamed properties objectO is called with JavaScript language valueV, the following step is taken:
IfO’sassociated realm’sis global prototype chain mutable is true,return?OrdinarySetPrototypeOf(O,V).
Return?SetImmutablePrototype(O,V).
3.7.4.5.[[PreventExtensions]]
When the [[PreventExtensions]] internal method of anamed properties object is called, the following steps are taken:
Return
false .
Note: this keepsnamed properties object extensible by making [[PreventExtensions]] fail.
3.7.5.Constants
Constants are exposed oninterface objects,legacy callback interface objects,interface prototype objects, andon the single object thatimplements the interface,when an interface is declared with the [Global
]extended attribute.
For eachconstantconst that is amember ofdefinition:
Letvalue be the result ofconvertingconst’s IDL value to a JavaScript value.
Letdesc be the PropertyDescriptor{[[Writable]]:
false ,[[Enumerable]]:true , [[Configurable]]:false ,[[Value]]:value}.Letid beconst’sidentifier.
Perform!DefinePropertyOrThrow(target,id,desc).
3.7.6.Attributes
Static attributes are exposed on theinterface object.Regular attributes are exposed on theinterface prototype object,unless the attribute isunforgeable orif the interface was declared with the [Global
]extended attribute,in which case they are exposed on every object thatimplements the interface.
Letattributes be thelist ofregular attributes that aremembers ofdefinition.
Remove fromattributes all theattributes that areunforgeable.
Define the attributesattributes ofdefinition ontarget givenrealm.
Letattributes be thelist ofstatic attributes that aremembers ofdefinition.
Define the attributesattributes ofdefinition ontarget givenrealm.
Letattributes be thelist ofunforgeableregular attributes that aremembers ofdefinition.
Define the attributesattributes ofdefinition ontarget givenrealm.
For eachattributeattr ofattributes:
Letgetter be the result of creating anattribute getter givenattr,definition, andrealm.
Letsetter be the result of creating anattribute setter givenattr,definition, andrealm.
Note: the algorithm to create anattribute setter returns
undefined ifattr isread only.Letconfigurable be
false ifattr isunforgeable andtrue otherwise.Letdesc be the PropertyDescriptor{[[Get]]:getter, [[Set]]:setter,[[Enumerable]]:
true , [[Configurable]]:configurable}.Letid beattr’sidentifier.
Perform!DefinePropertyOrThrow(target,id,desc).
Ifattr’s type is anobservable array type with type argumentT, then settarget’sbacking observable array exotic object forattr to the result ofcreating an observable array exotic object inrealm, givenT,attr’sset an indexed value algorithm, andattr’sdelete an indexed value algorithm.
Theattribute getter is created as follows, given anattributeattribute, anamespace orinterfacetarget, and arealmrealm:
Letsteps be the following series of steps:
Try running the following steps:
LetidlObject be null.
Iftarget is aninterface, andattribute is aregular attribute:
LetjsValue be the
this value, if it is notnull orundefined , orrealm’sglobal object otherwise.(This will subsequently cause aTypeError
in a few steps, ifthe global object does not implementtarget and [LegacyLenientThis
] is notspecified.)IfjsValueis a platform object, thenperform a security check,passingjsValue,attribute’sidentifier, and "getter".
IfjsValue does notimplementtarget, then:
Ifattribute was specified with the [
LegacyLenientThis
]extended attribute, then returnundefined .
Ifattribute’s type is anobservable array type, then returnjsValue’sbacking observable array exotic object forattribute.
SetidlObject to the IDLinterface type value that represents a referencetojsValue.
LetR be the result of running thegetter steps ofattribute withidlObject asthis.
Return the result ofconvertingR to aJavaScript value of the typeattribute is declared as.
And then, ifan exceptionE was thrown:
Ifattribute’s type is apromise type, then return!Call(
%Promise.reject%
,%Promise%
, «E»).Otherwise, end these steps and allow the exception to propagate.
LetF beCreateBuiltinFunction(steps, « »,realm).
Letname be the string "
get
" prepended toattribute’sidentifier.PerformSetFunctionName(F,name).
PerformSetFunctionLength(F, 0).
ReturnF.
Theattribute setter is created as follows, given anattributeattribute, anamespace orinterfacetarget, and arealmrealm:
Iftarget is anamespace:
Assert:attribute isread only.
Return
undefined .
Ifattribute isread only and does not have a[
LegacyLenientSetter
], [PutForwards
] or [Replaceable
]extended attribute, returnundefined ; there is noattribute setter function.Assert:attribute’s type is not apromise type.
Letsteps be the following series of steps:
LetV be the value of the first argument passed.
Letid beattribute’sidentifier.
LetidlObject be null.
Ifattribute is aregular attribute:
LetjsValue be the
this value, if it is notnull orundefined , orrealm’sglobal object otherwise.(This will subsequently cause aTypeError
in a few steps, ifthe global object does not implementtarget and [LegacyLenientThis
] is notspecified.)IfjsValueis a platform object, thenperform a security check, passingjsValue,id, and "setter".
LetvalidThis be true ifjsValueimplementstarget, or false otherwise.
IfvalidThis is false andattribute was not specified with the [
LegacyLenientThis
]extended attribute, thenthrow aTypeError
.Ifattribute is declared with the [
Replaceable
] extended attribute, then:Perform?CreateDataPropertyOrThrow(jsValue,id,V).
Return
undefined .
IfvalidThis is false, then return
undefined .Ifattribute is declared with a [
LegacyLenientSetter
] extended attribute, thenreturnundefined .Ifattribute is declared with a [
PutForwards
] extended attribute, then:IfQis not an Object, thenthrow a
TypeError
.LetforwardId be the identifier argument of the [
PutForwards
] extendedattribute.Return
undefined .
SetidlObject to the IDLinterface type value that represents a referencetojsValue.
Ifattribute’s type is anobservable array type with type argumentT:
LetnewValues be the result ofconvertingV toan IDL value of typesequence<T>.
Letoa beidlObject’sattribute’sbacking observable array exotic object.
Set the length ofoa.[[ProxyHandler]] to 0.
Leti be 0.
Whilei <newValues’ssize:
Perform the algorithm steps given byoa.[[ProxyHandler]].[[SetAlgorithm]], givennewValues[i] andi.
AppendnewValues[i] tooa.[[ProxyHandler]].[[BackingList]].
Return
undefined .
LetidlValue be determined as follows:
- attribute’s type is anenumeration
IfS is not one of theenumeration’s values, thenreturn
undefined .Otherwise,idlValue is the enumeration value equal toS.
- Otherwise
- idlValue is the result ofconvertingV to an IDL value ofattribute’s type.
Perform thesetter steps ofattribute,withidlObject asthis andidlValue asthe given value.
Return
undefined
LetF beCreateBuiltinFunction(steps, « »,realm).
Letname be the string "
set
" prepended toid.PerformSetFunctionName(F,name).
PerformSetFunctionLength(F, 1).
ReturnF.
Note: Although there is only a single property for an IDL attribute, sinceaccessor property getters and setters are passed athis value for the object on which property corresponding to the IDL attribute isaccessed, they are able to expose instance-specific data.
Note: Attempting to assign to a property corresponding to aread onlyattribute 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 aTypeError
being thrown. When not in strict mode, the assignment attempt will be ignored.
3.7.7.Operations
For each uniqueidentifier of anexposedoperation defined on theinterface,there exist a corresponding property.Static operations are exposed of theinterface object.Regular operations are exposed on theinterface prototype object,unless the operation isunforgeable orthe interface was declared with the [Global
]extended attribute,in which case they are exposed on every object thatimplements the interface.
Letoperations be thelist ofregular operations that aremembers ofdefinition.
Remove fromoperations all theoperations that areunforgeable.
Define the operationsoperations ofdefinition ontarget givenrealm.
Letoperations be thelist ofstatic operations that aremembers ofdefinition.
Define the operationsoperations ofdefinition ontarget givenrealm.
Letoperations be thelist ofunforgeableregular operations that aremembers ofdefinition.
Define the operationsoperations ofdefinition ontarget givenrealm.
For eachoperationop ofoperations:
Letmethod be the result ofcreating an operation function givenop,definition, andrealm.
Letmodifiable be
false ifop isunforgeable andtrue otherwise.Letdesc be the PropertyDescriptor{[[Value]]:method,[[Writable]]:modifiable, [[Enumerable]]:
true ,[[Configurable]]:modifiable}.Letid beop’sidentifier.
Perform!DefinePropertyOrThrow(target,id,desc).
Letid beop’sidentifier.
Letsteps be the following series of steps, given function argumentvaluesargs:
Try running the following steps:
LetidlObject be null.
Iftarget is aninterface, andop is not astatic operation:
LetjsValue be the
this value, if it is notnull orundefined , orrealm’sglobal object otherwise.(This will subsequently cause aTypeError
in a few steps, ifthe global object does not implementtarget and [LegacyLenientThis
] is notspecified.)IfjsValueis a platform object, thenperform a security check,passingjsValue,id, and "method".
IfjsValue does notimplement the interfacetarget,throw a
TypeError
.SetidlObject to the IDLinterface type value that represents a referencetojsValue.
Letn be thesize ofargs.
Compute the effective overload set forregular operations (ifop is aregular operation) or forstatic operations (ifop is a static operation)withidentifierid ontarget and with argument countn, and letS bethe result.
Let <operation,values> be the result of passingS andargs to theoverload resolution algorithm.
LetR be
null .Ifoperation is declared with a [
Default
]extended attribute, then:Assert:operationhas default method steps.
SetR to the result of running thedefault method steps foroperation,withidlObject asthis andvalues as the argument values.
Otherwise, setR to the result of running themethod steps ofoperation,withidlObject asthis andvalues as the argument values.
ReturnR,converted to a JavaScript value.
R is assumed to be an IDL value of the typeop is declared to return.[whatwg/webidl Issue #674]
And then, ifan exceptionE was thrown:
Ifop has areturn type that is apromise type, then return!Call(
%Promise.reject%
,%Promise%
, «E»).Otherwise, end these steps and allow the exception to propagate.
LetF beCreateBuiltinFunction(steps, « »,realm).
PerformSetFunctionName(F,id).
Compute the effective overload set forregular operations (ifop is a regularoperation) or forstatic operations (ifop is a static operation) withidentifierid ontarget and with argument count 0, and letS be the result.
Letlength be the length of the shortest argument list in the entries inS.
PerformSetFunctionLength(F,length).
ReturnF.
3.7.7.1.Default operations
Aregular operationhas default method steps if itsidentifier appears in the first column of the following table. In that case, itsdefault method steps are those given by the algorithm linked from the second column ofthe table, and the operation must have the return type given in the third column of the table.
Identifier | Default method steps | Return type |
---|---|---|
"toJSON " | Thedefault toJSON steps | object |
Aregular operation that does nothave default method steps must not be declared with a[Default
]extended attribute.
3.7.7.1.1.Default toJSON operation
Thedefault toJSON steps for aninterfaceI are:
Letmap be a newordered map.
Letstack be the result ofcreating an inheritance stack forinterfaceI.
Invokecollect attribute values of an inheritance stack giventhis,stack, andmap.
Letresult beOrdinaryObjectCreate(
%Object.prototype%
).For eachkey →value ofmap,
Letk bekeyconverted to a JavaScript value.
Letv bevalueconverted to a JavaScript value.
Perform!CreateDataPropertyOrThrow(result,k,v).
Returnresult.
Tocollect attribute values of an inheritance stack given aplatform objectobject, astackstack, and anordered mapmap:
LetI be the result ofpopping fromstack.
Invokecollect attribute values givenobject,I, andmap.
Ifstackis not empty, then invokecollect attribute values of an inheritance stack givenobject,stack, andmap.
Tocollect attribute values given aplatform objectobject, aninterfaceI, and anordered mapmap:
If a
toJSON
operation with a [Default
]extended attribute is declaredonI, thenfor eachexposedregular attributeattr that is aninterface member ofI, in order:Letid be theidentifier ofattr.
Letvalue be the result of running thegetter steps ofattr withobject asthis.
Tocreate an inheritance stack forinterfaceI, run the following steps:
Onlyregular attributes ofinterfaces that declare atoJSON
operation with a [Default
]extended attribute are included, even if aninherited interface declares such atoJSON
operation. For example, consider the followingIDL fragment:
[Exposed=Window]interface A { [Default] object toJSON(); attribute DOMString a;};[Exposed=Window]interface B : A { attribute DOMString b;};[Exposed=Window]interface C : B { [Default] object toJSON(); attribute DOMString c;};
Calling thetoJSON()
method of an object implementing interfaceC
defined above would return the following JSON object:
{ "a" : "..." , "c" : "..." }
Calling thetoJSON()
method of an object implementing interfaceA
(orB
) defined above would return:
{ "a" : "..." }
AtoJSON
operation can also be declared on aninterface mixin (orpartial interface) and is equivalent to declaring it on the originalinterface. For example, consider the followingIDL fragment:
[Exposed=Window]interface D { attribute DOMString d;};interface mixin M { [Default] object toJSON(); attribute DOMString m;};D includes M;
Calling thetoJSON()
method of an object implementing interfaceD
defined above would return:
{ "d" : "..." , "m" : "..." }
3.7.8.Stringifiers
If theinterface has anexposedstringifier,then there must exist a property with the following characteristics:
The name of the property is "
toString
".If thestringifier isunforgeable on the interfaceor if the interface was declared with the [
Global
]extended attribute,then the property exists on every object thatimplements the interface.Otherwise, the property exists on theinterface prototype object.The property has attributes{ [[Writable]]:B, [[Enumerable]]:
true , [[Configurable]]:B },whereB isfalse if the stringifier isunforgeable on the interface,andtrue otherwise.The value of the property is abuilt-in function object, which behaves as follows:
LetthisValue be the
this value.IfOis a platform object,thenperform a security check, passing:
the platform objectO,
theidentifier of thestringifier, and
the type "
method
".
IfO does notimplement theinterface on which the stringifier was declared, thenthrow a
TypeError
.LetV be an uninitialized variable.
Depending on how
stringifier
was specified:- as a declaration
SetV to the result of performing thestringification behavior of the interface.
- on anattribute
SetV to the result of running thegetter steps of the attribute(or those listed in thegetter steps of the inherited attribute, if this attribute is declared toinherit its getter),withO asthis.
Return the result ofconvertingV to a String value.
The value of thefunction object’s
length
property is the Number value0 .The value of thefunction object’s
name
property is the String value "toString
".
3.7.9.Iterable declarations
Ifdefinition has anindexed property getter, then:
PerformDefineMethodProperty(target,
%Symbol.iterator%
,%Array.prototype.values%
, false).Ifdefinition has avalue iterator, then:
Perform!CreateDataPropertyOrThrow(target, "
entries
",%Array.prototype.entries%
).Perform!CreateDataPropertyOrThrow(target, "
keys
",%Array.prototype.keys%
).Perform!CreateDataPropertyOrThrow(target, "
values
",%Array.prototype.values%
).Perform!CreateDataPropertyOrThrow(target, "
forEach
",%Array.prototype.forEach%
).
Otherwise, ifdefinition has apair iterator, then:
Define the
%Symbol.iterator%
andentries
methods:Letsteps be the following series of steps:
IfjsValueis a platform object, thenperform a security check,passingjsValue, "
%Symbol.iterator%
", and "method
".IfjsValue does notimplementdefinition, thenthrow a
TypeError
.Return a newly createddefault iterator object fordefinition, withjsValue as itstarget, "
key+value
"as itskind, andindex set to 0.
LetF beCreateBuiltinFunction(steps, « »,realm).
PerformSetFunctionName(F, "
entries
").PerformSetFunctionLength(F, 0).
PerformDefineMethodProperty(target,
%Symbol.iterator%
,F, false).Perform!CreateDataPropertyOrThrow(target, "
entries
",F).
Define the
keys
method:Letsteps be the following series of steps:
IfjsValueis a platform object, thenperform a security check,passingjsValue, "
keys
", and "method
".IfjsValue does notimplementdefinition, thenthrow a
TypeError
.Return a newly createddefault iterator object fordefinition, withjsValue as itstarget, "
key
" as itskind, andindex set to 0.
LetF beCreateBuiltinFunction(steps, « »,realm).
PerformSetFunctionName(F, "
keys
").PerformSetFunctionLength(F, 0).
Perform!CreateDataPropertyOrThrow(target, "
keys
",F).
Define the
values
method:Letsteps be the following series of steps:
IfjsValueis a platform object, thenperform a security check,passingjsValue, "
values
", and "method
".IfjsValue does notimplementdefinition, thenthrow a
TypeError
.Return a newly createddefault iterator object fordefinition, withjsValue as itstarget, "
value
" as itskind, andindex set to 0.
LetF beCreateBuiltinFunction(steps, « »,realm).
PerformSetFunctionName(F, "
values
").PerformSetFunctionLength(F, 0).
Perform!CreateDataPropertyOrThrow(target, "
values
",F).
Define the
forEach
method:Letsteps be the following series of steps, given function argument valuescallback andthisArg:
IfjsValueis a platform object, thenperform a security check,passingjsValue, "
forEach
", and "method
".IfjsValue does notimplementdefinition, thenthrow a
TypeError
.LetidlObject be the IDLinterface type value that represents a referencetojsValue.
Letpairs beidlObject’s list ofvalue pairs to iterate over.
Leti be 0.
Whilei <pairs’ssize:
Letpair bepairs[i].
InvokeidlCallback with «pair’svalue,pair’skey,idlObject » and withthisArg as thecallback this value.
Setpairs toidlObject’s current list ofvalue pairs to iterate over. (It might have changed.)
Seti toi + 1.
LetF beCreateBuiltinFunction(steps, « »,realm).
PerformSetFunctionName(F, "
forEach
").PerformSetFunctionLength(F, 1).
Perform!CreateDataPropertyOrThrow(target, "
forEach
",F).
3.7.9.1.Default iterator objects
Adefault iterator object for a giveninterface, target and iteration kindis an object whose [[Prototype]]internal slot is theiterator prototype object for theinterface.
Adefault iterator object has three internal values:
itstarget, which is an object whose values are to beiterated,
itskind, which is the iteration kind,
itsindex, which is the current index into the valuesto be iterated.
Note: Default iterator objects are only used forpair iterators;value iterators, as they are currentlyrestricted to iterating over an object’ssupported indexed properties,use standard JavaScript Array iterator objects.
Note:Default iterator objects do not haveclass strings; whenObject.prototype.toString()
is called on adefault iterator object of a giveninterface, theclass string of theiterator prototype object of thatinterface is used.
3.7.9.2.Iterator prototype object
Theiterator prototype object for a giveninterface is an object that exists for every interface that has apair iterator. It serves as theprototype fordefault iterator objects for the interface.
The [[Prototype]]internal slot of aniterator prototype object must be%Iterator.prototype%
.
Letresult be a value determined by the value ofkind:
- "
key
" LetidlKey bepair’skey.
Letkey be the result ofconvertingidlKey to a JavaScript value.
result iskey.
- "
value
" LetidlValue bepair’svalue.
Letvalue be the result ofconvertingidlValue to a JavaScript value.
result isvalue.
- "
key+value
" LetidlKey bepair’skey.
LetidlValue bepair’svalue.
Letkey be the result ofconvertingidlKey to a JavaScript value.
Letvalue be the result ofconvertingidlValue to a JavaScript value.
Letarray be!ArrayCreate(2).
Perform!CreateDataPropertyOrThrow(array, "
0
",key).Perform!CreateDataPropertyOrThrow(array, "
1
",value).result isarray.
- "
ReturnCreateIteratorResultObject(result,
false ).
Aniterator prototype object must have anext
data property with attributes { [[Writable]]:
Letinterface be theinterface for which theiterator prototype object exists.
LetthisValue be the
this value.Ifobjectis a platform object,thenperform a security check, passing:
the platform objectobject,
the identifier "
next
", andthe type "
method
".
Ifobject is not adefault iterator object forinterface,thenthrow a
TypeError
.Letindex beobject’sindex.
Letkind beobject’skind.
Letvalues beobject’starget’svalue pairs to iterate over.
Letlen be the length ofvalues.
Ifindex is greater than or equal tolen, thenreturnCreateIteratorResultObject(
undefined ,true ).Letpair be the entry invalues at indexindex.
Setobject’s index toindex + 1.
Return theiterator result forpair andkind.
Theclass string of aniterator prototype object for a giveninterface is the result of concatenating theidentifier of theinterface and the string " Iterator
".
3.7.10.Asynchronous iterable declarations
Ifdefinition does not have an anasynchronously iterable declaration (of eithersort), then return.
Assert:definition does not have anindexed property getter or aniterable declaration.
Ifdefinition has apair asynchronously iterable declaration, then define the
%Symbol.asyncIterator%
andentries
methods:Letsteps be the following series of steps, given function argument valuesargs:
IfjsValueis a platform object, thenperform a security check, passingjsValue, "
%Symbol.asyncIterator%
", and "method
".IfjsValue does notimplementdefinition, thenthrow a
TypeError
.LetidlObject be the IDLinterface type value that represents a reference tojsValue.
LetidlArgs be the result ofconverting arguments for an asynchronous iterator method givenargs.
Letiterator be a newly createddefault asynchronous iterator object fordefinition withidlObject as itstarget, "
key+value
" as itskind, andis finished set to false.Run theasynchronous iterator initialization steps fordefinition withidlObject,iterator, andidlArgs, if any such steps exist.
Returniterator.
LetF beCreateBuiltinFunction(steps, « »,realm).
PerformSetFunctionName(F, "
entries
").PerformSetFunctionLength(F, 0).
PerformDefineMethodProperty(target,
%Symbol.asyncIterator%
,F, false).Perform!CreateDataPropertyOrThrow(target, "
entries
",F).
Ifdefinition has apair asynchronously iterable declaration, then define the
keys
method:Letsteps be the following series of steps, given function argument valuesargs:
IfjsValueis a platform object, thenperform a security check, passingjsValue, "
keys
", and "method
".IfjsValue does notimplementdefinition, thenthrow a
TypeError
.LetidlObject be the IDLinterface type value that represents a reference tojsValue.
LetidlArgs be the result ofconverting arguments for an asynchronous iterator method givenargs.
Letiterator be a newly createddefault asynchronous iterator object fordefinition withidlObject as itstarget, "
key
" as itskind, andis finished set to false.Run theasynchronous iterator initialization steps fordefinition withidlObject,iterator, andidlArgs, if any such steps exist.
Returniterator.
LetF beCreateBuiltinFunction(steps, « »,realm).
PerformSetFunctionName(F, "
keys
").PerformSetFunctionLength(F, 0).
Perform!CreateDataPropertyOrThrow(target, "
keys
",F).
Define the
values
, and possibly%Symbol.asyncIterator%
, methods:Letsteps be the following series of steps, given function argument valuesargs:
IfjsValueis a platform object, thenperform a security check, passingjsValue, "
values
", and "method
".IfjsValue does notimplementdefinition, thenthrow a
TypeError
.LetidlObject be the IDLinterface type value that represents a reference tojsValue.
LetidlArgs be the result ofconverting arguments for an asynchronous iterator method givenargs.
Letiterator be a newly createddefault asynchronous iterator object fordefinition withidlObject as itstarget, "
value
" as itskind, andis finished set to false.Run theasynchronous iterator initialization steps fordefinition withidlObject,iterator, andidlArgs, if any such steps exist.
Returniterator.
LetF beCreateBuiltinFunction(steps, « »,realm).
PerformSetFunctionName(F, "
values
").PerformSetFunctionLength(F, 0).
Perform!CreateDataPropertyOrThrow(target, "
values
",F).Ifdefinition has avalue asynchronously iterable declaration, then perform!DefineMethodProperty(target,
%Symbol.asyncIterator%
,F, false).
LetidlArgs be an empty list.
LetargCount be the number of arguments ofdefinition’sasynchronously iterable declaration, or 0 if theasynchronously iterable declaration does not have an argument list.
Leti be 0.
Whilei <argCount:
Ifi ≥args’ssize, or ifargs[i] is
undefined ,then:If the argument to theasynchronously iterable declaration at indexi isdeclared with adefault value, thenappend thatdefault value toidlArgs.
Otherwise,append toidlArgs the special value "missing".
Otherwise,append toidlArgs the result ofconvertingargs[i] to the IDL type given in theasynchronously iterable declaration’s argument list at indexi.
Seti toi + 1.
ReturnidlArgs.
This is essentially a hyper-specialization of theoverload resolution algorithm for the case where no overloads are allowed and all arguments are optional.
3.7.10.1.Default asynchronous iterator objects
Adefault asynchronous iteratorobject for a giveninterface, target and iteration kind is an object whose [[Prototype]]internal slot is theasynchronous iterator prototype object for theinterface.
Adefault asynchronous iterator object has internal values:
itstarget, which is an object whosevalues are to be iterated,
itskind, which is the iteration kind,
itsongoing promise, which is a
Promise
or null,itsis finished, which is a boolean.
Note:Default asynchronous iterator objects do not haveclass strings; whenObject.prototype.toString()
is called on adefault asynchronous iterator object of a giveninterface, theclass string of theasynchronous iterator prototype object of thatinterface is used.
3.7.10.2.Asynchronous iterator prototype object
Theasynchronous iterator prototype object for a giveninterface is an object that exists for every interface that has anasynchronously iterable declaration.It serves as the prototype fordefault asynchronous iterator objects for the interface.
The [[Prototype]]internal slot of anasynchronous iterator prototype object must be%AsyncIteratorPrototype%
.
Anasynchronous iterator prototype object must have anext
data property with attributes { [[Writable]]:
Letinterface be theinterface for which theasynchronous iterator prototype object exists.
LetthisValidationPromiseCapability be!NewPromiseCapability(
%Promise%
).LetthisValue be the
this value.Letobject beCompletion(ToObject(thisValue)).
IfAbruptRejectPromise(object,thisValidationPromiseCapability).
Ifobjectis a platform object, thenperform a security check, passing:
the platform objectobject,
the identifier "
next
", andthe type "
method
".
If this threw an exceptione, then:
Ifobject is not adefault asynchronous iterator object forinterface, then:
LetnextSteps be the following steps:
LetnextPromiseCapability be!NewPromiseCapability(
%Promise%
).Ifobject’sis finished is true, then:
Letresult beCreateIteratorResultObject(
undefined ,true ).Perform!Call(nextPromiseCapability.[[Resolve]],
undefined , «result »).ReturnnextPromiseCapability.[[Promise]].
Letkind beobject’skind.
LetnextPromise be the result ofgetting the next iteration result withobject’starget andobject.
LetfulfillSteps be the following steps, givennext:
Setobject’songoing promise tonull.
Ifnext isend of iteration, then:
Setobject’sis finished to true.
ReturnCreateIteratorResultObject(
undefined ,true ).
Otherwise, ifinterface has apair asynchronously iterable declaration:
Assert:next is avalue pair.
Return theiterator result fornext andkind.
Otherwise:
Assert:interface has avalue asynchronously iterable declaration.
Assert:next is a value of the type that appears in the declaration.
Letvalue benext,converted to a JavaScript value.
ReturnCreateIteratorResultObject(value,
false ).
LetonFulfilled beCreateBuiltinFunction(fulfillSteps, « »).
LetrejectSteps be the following steps, givenreason:
Setobject’songoing promise tonull.
Setobject’sis finished to true.
Throwreason.
LetonRejected beCreateBuiltinFunction(rejectSteps, « »).
PerformPerformPromiseThen(nextPromise,onFulfilled,onRejected,nextPromiseCapability).
ReturnnextPromiseCapability.[[Promise]].
LetongoingPromise beobject’songoing promise.
IfongoingPromise is not null, then:
LetafterOngoingPromiseCapability be!NewPromiseCapability(
%Promise%
).LetonSettled beCreateBuiltinFunction(nextSteps, « »).
PerformPerformPromiseThen(ongoingPromise,onSettled,onSettled,afterOngoingPromiseCapability).
Setobject’songoing promise toafterOngoingPromiseCapability.[[Promise]].
Otherwise:
Setobject’songoing promise to the result ofrunningnextSteps.
Returnobject’songoing promise.
If anasynchronous iterator return algorithm is defined for theinterface, then theasynchronous iterator prototype object must have areturn
data property with attributes { [[Writable]]:
Letinterface be theinterface for which theasynchronous iterator prototype object exists.
LetreturnPromiseCapability be!NewPromiseCapability(
%Promise%
).LetthisValue be the
this value.Letobject beCompletion(ToObject(thisValue)).
IfAbruptRejectPromise(object,returnPromiseCapability).
Ifobjectis a platform object, thenperform a security check, passing:
the platform objectobject,
the identifier "
return
", andthe type "
method
".
If this threw an exceptione, then:
Ifobject is not adefault asynchronous iterator object forinterface, then:
LetreturnSteps be the following steps:
LetreturnPromiseCapability be!NewPromiseCapability(
%Promise%
).Ifobject’sis finished is true, then:
Letresult beCreateIteratorResultObject(value,
true ).Perform!Call(returnPromiseCapability.[[Resolve]],
undefined , «result »).ReturnreturnPromiseCapability.[[Promise]].
Setobject’sis finished to true.
Return the result of running theasynchronous iterator return algorithm forinterface, givenobject’starget,object,andvalue.
LetongoingPromise beobject’songoing promise.
IfongoingPromise is not null, then:
LetafterOngoingPromiseCapability be!NewPromiseCapability(
%Promise%
).LetonSettled beCreateBuiltinFunction(returnSteps, « »).
PerformPerformPromiseThen(ongoingPromise,onSettled,onSettled,afterOngoingPromiseCapability).
Setobject’songoing promise toafterOngoingPromiseCapability.[[Promise]].
Otherwise:
Setobject’songoing promise to the result ofrunningreturnSteps.
LetfulfillSteps be the following steps:
ReturnCreateIteratorResultObject(value,
true ).
LetonFulfilled beCreateBuiltinFunction(fulfillSteps, « »).
PerformPerformPromiseThen(object’songoing promise,onFulfilled,
undefined ,returnPromiseCapability).ReturnreturnPromiseCapability.[[Promise]].
Theclass string of anasynchronous iterator prototype object for a giveninterface isthe result of concatenating theidentifier of theinterface and the string" AsyncIterator
".
3.7.11.Maplike declarations
If aninterfaceA is declared withamaplike declaration, thenthere exists a number of additional properties onA’sinterface prototype object.These additional properties are described in the sub-sections below.
3.7.11.1.size
There must exist asize
property onA’sinterface prototype object with the following characteristics:
The property has attributes{ [[Get]]:G, [[Enumerable]]:
true , [[Configurable]]:true },whereG is the interface’smap size getter,defined below.Themap size getter is abuilt-in function object whose behavior when invoked is as follows:
LetO be the
this value,implementation-checked againstA with identifier "size
" and type "getter
".Letmap be themap entries of the IDL valuethat represents a reference toO.
Returnmap’ssize,converted to a JavaScript value.
The value of thefunction object’s
length
property is the Number value0 .The value of thefunction object’s
name
property is the String value "get size
".
3.7.11.2.%Symbol.iterator%
There must exist a data property whose name is the%Symbol.iterator%
symbol onA’sinterface prototype object with attributes { [[Writable]]:entries
property.
key+value
", "key
", or "value
":Letclosure be a newAbstract Closure with no parametersthat capturesmap andkind and performs the following steps when called:
For eachkey →value ofmap:
Setkey andvalue to eachconverted to a JavaScript value.
Ifkind is "
key
", letresult bekey.Else ifkind is "
value
", letresult bevalue.Else, letresult beCreateArrayFromList(«key,value »).
Perform?GeneratorYield(CreateIteratorResultObject(result,
false )).
Note: Thesize ofmap, and the order of its entries,might have changed while execution of this abstract operationwas paused byYield.
Return
undefined .
ReturnCreateIteratorFromClosure(closure, "
%MapIteratorPrototype%
",%MapIteratorPrototype%
).
3.7.11.3.entries
There must exist anentries
data property onA’sinterface prototype object with the following characteristics:
The property has attributes { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }.The value of the property is abuilt-in function object whose behavior when invoked is as follows:
LetO be the
this value,implementation-checked againstA with identifier "entries
" and type "method
".Letmap be themap entries of the IDL valuethat represents a reference toO.
Return the result ofcreating a map iterator frommap with kind "
key+value
".
The value of thefunction object’slength
property is the Number value
The value of thefunction object’sname
property is the String value "entries
".
3.7.11.4.keys
There must exist akeys
data property onA’sinterface prototype object with the following characteristics:
The property has attributes { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }.The value of the property is abuilt-in function object whose behavior when invoked is as follows:
LetO be the
this value,implementation-checked againstA with identifier "keys
" and type "method
".Letmap be themap entries of the IDL valuethat represents a reference toO.
Return the result ofcreating a map iterator frommap with kind "
key
".
The value of thefunction object’slength
property is the Number value
The value of thefunction object’sname
property is the String value "keys
".
3.7.11.5.values
There must exist avalues
data property onA’sinterface prototype object with the following characteristics:
The property has attributes { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }.The value of the property is abuilt-in function object whose behavior when invoked is as follows:
LetO be the
this value,implementation-checked againstA with identifier "values
" and type "method
".Letmap be themap entries of the IDL valuethat represents a reference toO.
Return the result ofcreating a map iterator frommap with kind "
value
".
The value of thefunction object’slength
property is the Number value
The value of thefunction object’sname
property is the String value "values
".
3.7.11.6.forEach
There must exist aforEach
data property onA’sinterface prototype object with the following characteristics:
The property has attributes { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }.The value of the property is abuilt-in function object whose behavior when invoked is as follows:
LetO be the
this value,implementation-checked againstA with identifier "forEach
" and type "method
".Letmap be themap entries of the IDL valuethat represents a reference toO.
LetcallbackFn be the first argument passed to the function, or
undefined if not supplied.IfIsCallable(callbackFn) is
false ,throw aTypeError
.LetthisArg be the second argument passed to the function, or
undefined if not supplied.For eachkey →value ofmap:
LetjsKey andjsValue bekey andvalueconverted to a JavaScript value.
Return
undefined .
The value of thefunction object’slength
property is the Number value
The value of thefunction object’sname
property is the String value "forEach
".
3.7.11.7.get
There must exist aget
data property onA’sinterface prototype object with the following characteristics:
The property has attributes { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }.The value of the property is abuilt-in function object that behaves as follows when invoked:
LetO be the
this value,implementation-checked againstA with identifier "get
" and type "method
".Letmap be themap entries of the IDL valuethat represents a reference toO.
LetkeyType be the key type specified in themaplike declaration.
LetkeyArg be the first argument passed to this function, or
undefined if not supplied.Letkey bekeyArgconverted to an IDL value of typekeyType.
Ifkey is -0, setkey to +0.
Ifmap[key]exists, then returnmap[key],converted to a JavaScript value.
The value of thefunction object’slength
property is the Number value
The value of thefunction object’sname
property is the String value "get
".
3.7.11.8.has
There must exist ahas
data property onA’sinterface prototype object with the following characteristics:
The property has attributes { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }.The value of the property is abuilt-in function object that behaves as follows when invoked:
LetO be the
this value,implementation-checked againstA with identifier "has
" and type "method
".Letmap be themap entries of the IDL valuethat represents a reference toO.
LetkeyType be the key type specified in themaplike declaration.
LetkeyArg be the first argument passed to this function, or
undefined if not supplied.Letkey bekeyArgconverted to an IDL value of typekeyType.
Ifkey is -0, setkey to +0.
Ifmap[key]exists, then return
true ;otherwise returnfalse .
The value of thefunction object’slength
property is the Number value
The value of thefunction object’sname
property is the String value "has
".
3.7.11.9.set
IfA does not declare amember with identifier "set
",andA was declared with a read–write maplike declaration,then there must exist aset
data propertyonA’sinterface prototype object with the following characteristics:
The property has attributes { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }.The value of the property is abuilt-in function object that behaves as follows when invoked:
LetO be the
this value,implementation-checked againstA with identifier "set
" and type "method
".Letmap be themap entries of the IDL valuethat represents a reference toO.
LetkeyType be the key type specified in themaplike declaration, andvalueType be the value type.
LetkeyArg be the first argument passed to this function, or
undefined if not supplied.Letkey bekeyArgconverted to an IDL value of typekeyType.
Ifkey is -0, setkey to +0.
LetvalueArg be the second argument passed to this function, or
undefined if not supplied.Letvalue bevalueArgconverted to an IDL value of typevalueType.
Setmap[key] tovalue.
ReturnO.
The value of thefunction object’slength
property is the Number value
The value of thefunction object’sname
property is the String value "set
".
If the interface does declare aset
method,it should similarly map a -0 key to +0,and must returnthis.
3.7.11.10.delete
IfA does not declare amember with identifier "delete
",andA was declared with a read–write maplike declaration,then there must exist adelete
data propertyonA’sinterface prototype object with the following characteristics:
The property has attributes { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }.The value of the property is abuilt-in function object that behaves as follows when invoked:
LetO be the
this value,implementation-checked againstA with identifier "delete
" and type "method
".Letmap be themap entries of the IDL valuethat represents a reference toO.
LetkeyType be the key type specified in themaplike declaration.
LetkeyArg be the first argument passed to this function, or
undefined if not supplied.Letkey bekeyArgconverted to an IDL value of typekeyType.
Ifkey is -0, setkey to +0.
LetretVal be
true ifmap[key] exists,or elsefalse .Removemap[key].
ReturnretVal.
The value of thefunction object’slength
property is the Number value
The value of thefunction object’sname
property is the String value "delete
".
If the interface does declare adelete
method,it should similarly map a -0 key to +0,and must return aboolean
indicating whether the key was present or not.
3.7.11.11.clear
IfA does not declare amember with identifier "clear
",andA was declared with a read–write maplike declaration,then there must exist aclear
data propertyonA’sinterface prototype object with the following characteristics:
The property has attributes { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }.The value of the property is abuilt-in function object that behaves as follows when invoked:
LetO be the
this value,implementation-checked againstA with identifier "clear
" and type "method
".Letmap be themap entries of the IDL valuethat represents a reference toO.
Clearmap.
Note: Themap is preserved because there may be existingiterators, currently suspended, iterating over it.
Return
undefined .
The value of thefunction object’slength
property is the Number value
The value of thefunction object’sname
property is the String value "clear
".
If the interface does declare aclear
method,it must preserve themap entries object (rather than generating a new one)and must returnundefined
.
3.7.12.Setlike declarations
If aninterfaceA is declared with asetlike declaration,then there exists a number of additional properties onA’sinterface prototype object.These additional properties are described in the sub-sections below.
3.7.12.1.size
Asize
property must exist onA’sinterface prototype object with the following characteristics:
The property has attributes { [[Get]]:G, [[Enumerable]]:
true , [[Configurable]]:true },whereG is the interface’sset size getter,defined below.Theset size getter is abuilt-in function object whose behavior when invoked is as follows:
LetO be the
this value,implementation-checked againstA with identifier "size
" and type "getter
".Letset be theset entries of the IDL valuethat represents a reference toO.
Returnset’ssize,converted to a JavaScript value.
The value of thefunction object’s
length
property is the Number value0 .The value of thefunction object’s
name
property is the String value "get size
".
3.7.12.2.%Symbol.iterator%
There must exist a data property whose name is the%Symbol.iterator%
symbol onA’sinterface prototype object with attributes { [[Writable]]:values
property.
key+value
" or "value
":Letclosure be a newAbstract Closure with no parametersthat capturesset andkind and performs the following steps when called:
For eachentry ofset:
Setentry to beentryconverted to a JavaScript value.
Ifkind is "
value
", letresult beentry.Else, letresult beCreateArrayFromList(«entry,entry »).
Perform?GeneratorYield(CreateIteratorResultObject(result,
false )).
Note: Thesize ofset, and the order of its entries,might have changed while execution of this abstract operationwas paused byYield.
Return
undefined .
ReturnCreateIteratorFromClosure(closure, "
%SetIteratorPrototype%
",%SetIteratorPrototype%
).
3.7.12.3.entries
There must exist anentries
data property onA’sinterface prototype object with the following characteristics:
The property has attributes { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }.The value of the property is abuilt-in function object whose behavior when invoked is as follows:
LetO be the
this value,implementation-checked againstA with identifier "entries
" and type "method
".Letset be theset entries of the IDL valuethat represents a reference toO.
Return the result ofcreating a set iterator fromset with kind "
key+value
".
The value of thefunction object’slength
property isthe Number value
The value of thefunction object’sname
property isthe String value "entries
".
3.7.12.4.keys
Akeys
data property must existonA’sinterface prototype object with attributes { [[Writable]]:values
property.
3.7.12.5.values
There must exist avalues
data property onA’sinterface prototype object with the following characteristics:
The property has attributes { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }.The value of the property is abuilt-in function object whose behavior when invoked is as follows:
LetO be the
this value,implementation-checked againstA with identifier "values
" and type "method
".Letset be theset entries of the IDL valuethat represents a reference toO.
Return the result ofcreating a set iterator fromset with kind "
value
".
The value of thefunction object’slength
property isthe Number value
The value of thefunction object’sname
property isthe String value "values
".
3.7.12.6.forEach
There must exist aforEach
data property onA’sinterface prototype object with the following characteristics:
The property has attributes { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }.The value of the property is abuilt-in function object whose behavior when invoked is as follows:
LetO be the
this value,implementation-checked againstA with identifier "forEach
" and type "method
".Letset be theset entries of the IDL valuethat represents a reference toO.
LetcallbackFn be the first argument passed to the function, or
undefined if not supplied.IfIsCallable(callbackFn) is
false ,throw aTypeError
.LetthisArg be the second argument passed to the function, or
undefined if not supplied.For eachvalue ofset:
LetjsValue bevalueconverted to a JavaScript value.
Return
undefined .
The value of thefunction object’slength
property is the Number value
The value of thefunction object’sname
property is the String value "forEach
".
3.7.12.7.has
There must exist ahas
data property onA’sinterface prototype object with the following characteristics:
The property has attributes { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }.The value of the property is abuilt-in function object that behaves as follows when invoked:
LetO be the
this value,implementation-checked againstA with identifier "has
" and type "method
".Letset be theset entries of the IDL valuethat represents a reference toO.
LetvalueType be the value type specified in thesetlike declaration.
LetvalueArg be the first argument passed to this function, or
undefined if not supplied.Letvalue bevalueArgconverted to an IDL value of typevalueType.
Ifvalue is -0, setvalue to +0.
Ifsetcontainsvalue, then return
true ,otherwise returnfalse .
The value of thefunction object’slength
property is a Number value
The value of thefunction object’sname
property is the String value "has
".
3.7.12.8.add
IfA does not declare amember with identifier "add
",andA was declared with a read–write setlike declaration,then there must exist anadd
data propertyonA’sinterface prototype object with the following characteristics:
The property has attributes { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }.The value of the property is abuilt-in function object that behaves as follows when invoked:
LetO be the
this value,implementation-checked againstA with identifier "add
" and type "method
".Letset be theset entries of the IDL valuethat represents a reference toO.
LetvalueType be the value type specified in thesetlike declaration.
LetvalueArg be the first argument passed to this function, or
undefined if not supplied.Letvalue bevalueArgconverted to an IDL value of typevalueType.
Ifvalue is -0, setvalue to +0.
Appendvalue toset.
ReturnO.
The value of thefunction object’slength
property is the Number value
The value of thefunction object’sname
property is the String value "add
".
If the interface does declare anadd
method,it should similarly map a -0 value to +0,and must return the value that was set.
3.7.12.9.delete
IfA does not declare amember with identifier "delete
",andA was declared with a read–write setlike declaration,then there must exist adelete
data propertyonA’sinterface prototype object with the following characteristics:
The property has attributes { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }.The value of the property is abuilt-in function object that behaves as follows when invoked:
LetO be the
this value,implementation-checked againstA with identifier "delete
" and type "method
".Letset beO’sset entries.
LetvalueType be the value type specified in thesetlike declaration.
LetvalueArg be the first argument passed to this function, or
undefined if not supplied.Letvalue bevalueArgconverted to an IDL value of typevalueType.
Ifvalue is -0, setvalue to +0.
LetretVal be
true ifsetcontainsvalue, or elsefalse .Removevalue fromset.
ReturnretVal.
The value of thefunction object’slength
property is the Number value
The value of thefunction object’sname
property is the String value "delete
".
If the interface does declare adelete
method,it should similarly map a -0 value to +0,and must return aboolean
indicating whether the value was present or not.
3.7.12.10.clear
IfA does not declare amember with identifier "clear
",andA was declared with a read–write setlike declaration,then there must exist aclear
data propertyonA’sinterface prototype object with the following characteristics:
The property has attributes { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }.The value of the property is abuilt-in function object that behaves as follows when invoked:
LetO be the
this value,implementation-checked againstA with identifier "clear
" and type "method
".Letset be theset entries of the IDL valuethat represents a reference toO.
Emptyset.
Note: Theset is preserved because there may be existingiterators, currently suspended, iterating over it.
Return
undefined .
The value of thefunction object’slength
property is the Number value
The value of thefunction object’sname
property is the String value "clear
".
If the interface does declare aclear
method,it must preserve theset entries object (rather than generating a new one)and must returnundefined
.
3.8.Platform objects implementing interfaces
Specifications may reference the concept "object implementsinterface" in various ways, including "object is aninterface object".
Everyplatform object is associated with arealm, justas theinitial objects are.This realm is stored in theplatform object’s [[Realm]] slot.It is the responsibility of specifications using Web IDL to statewhich realm (or, by proxy, which global object) each platformobject is associated with.In particular, the algorithms below associate the newplatform object withthe realm given as an argument.
Return the result ofinternally creating a new object implementinginterface, withrealm and
undefined .
Assert:interface isexposed inrealm.
IfnewTarget is
undefined , then:Letprototype be theinterface prototype object forinterface inrealm.
Otherwise:
Assert:IsCallable(newTarget) is true.
Ifprototypeis not an Object, then:
LettargetRealm be?GetFunctionRealm(newTarget).
Setprototype to theinterface prototype object forinterface intargetRealm.
Letslots be « [[Prototype]], [[Extensible]], [[Realm]], [[PrimaryInterface]] ».
Ifinterface is
DOMException
, append [[ErrorData]] toslots.Letinstance beMakeBasicObject(slots).
Setinstance.[[Realm]] torealm.
Setinstance.[[PrimaryInterface]] tointerface.
Setinstance.[[Prototype]] toprototype.
Letinterfaces be theinclusive inherited interfaces ofinterface.
For everyinterfaceancestor interface ininterfaces:
Letunforgeables be the value of the [[Unforgeables]] slot of theinterface object ofancestor interface inrealm.
Letkeys be!unforgeables.[[OwnPropertyKeys]]().
For each elementkey ofkeys:
Letdescriptor be!unforgeables.[[GetOwnProperty]](key).
Perform!DefinePropertyOrThrow(instance,key,descriptor).
Ifinterface is declared with the [
Global
]extended attribute, then:Define the regular operations ofinterface oninstance, givenrealm.
Define the regular attributes ofinterface oninstance, givenrealm.
Define the iteration methods ofinterface oninstance givenrealm.
Define the asynchronous iteration methods ofinterface oninstance givenrealm.
Define the global property references oninstance, givenrealm.
Setinstance.[[SetPrototypeOf]] as defined in§ 3.8.1 [[SetPrototypeOf]].
Otherwise, ifinterfaces contains aninterface whichsupports indexed properties,named properties, or both:
Setinstance.[[GetOwnProperty]] as defined in§ 3.9.1 [[GetOwnProperty]].
Setinstance.[[Set]] as defined in§ 3.9.2 [[Set]].
Setinstance.[[DefineOwnProperty]] as defined in§ 3.9.3 [[DefineOwnProperty]].
Setinstance.[[Delete]] as defined in§ 3.9.4 [[Delete]].
Setinstance.[[PreventExtensions]] as defined in§ 3.9.5 [[PreventExtensions]].
Setinstance.[[OwnPropertyKeys]] as defined in§ 3.9.6 [[OwnPropertyKeys]].
Returninstance.
Letinterfaces be alist that contains everyinterface that isexposed inrealm.
Sortinterfaces in such a way that ifA andB areitems ofinterfaces,andAinherits fromB,A has a higher index ininterfaces thanB.
For everyinterface ofinterfaces:
Ifinterface is not declared with the [
LegacyNoInterfaceObject
] or[LegacyNamespace
]extended attributes, then:Letid beinterface’sidentifier.
LetinterfaceObject be the result ofcreatingan interface object forinterface withid inrealm.
PerformDefineMethodProperty(target,id,interfaceObject, false).
If theinterface is declared with a [
LegacyWindowAlias
]extended attribute,andtarget implements theWindow
interface, then:For everyidentifierid in[
LegacyWindowAlias
]'sidentifiers:PerformDefineMethodProperty(target,id,interfaceObject, false).
If theinterface is declared with a [
LegacyFactoryFunction
]extended attribute,then:For everyidentifierid in[
LegacyFactoryFunction
]'sidentifiers:LetlegacyFactoryFunction be the result ofcreating a legacy factory function withid forinterface inrealm.
PerformDefineMethodProperty(target,id,legacyFactoryFunction, false).
For everycallback interfaceinterface that isexposed inrealm and on whichconstants are defined:
Letid beinterface’sidentifier.
LetinterfaceObject be the result ofcreating a legacy callback interface object forinterface withid inrealm.
PerformDefineMethodProperty(target,id,interfaceObject, false).
For everynamespacenamespace that isexposed inrealm:
Letid benamespace’sidentifier.
LetnamespaceObject be the result ofcreating a namespace object fornamespace inrealm.
PerformDefineMethodProperty(target,id,namespaceObject, false).
Multipleplatform objects with differentglobal objects will share a reference to the sameinterface in their [[PrimaryInterface]] internal slots. For example, a page could 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 theimplements algorithm. Instead, eachinterface that theinterface mixin isincluded in has its own "copy" of eachmember of theinterface mixin, and the correspondingoperation function checks that the receiverimplements the particularinterface whichincludes theinterface mixin.
Therealm that a givenplatform object is associated with canchange after it has been created. Whentherealm associated with a platform object is changed, its[[Prototype]]internal slot must be immediatelyupdated to be theinterface prototype object of theprimary interface from theplatform object’s newly associatedrealm.
Additionally,platform objects which implement aninterface 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 aplatform objectO that implements aninterface with the [Global
]extended attribute is called with JavaScript language valueV, the following step is taken:
IfO’sassociated realm’sis global prototype chain mutable is true,return?OrdinarySetPrototypeOf(O,V).
Return?SetImmutablePrototype(O,V).
Note: ForWindow
objects, it is unobservable whether this is implemented, since the presence oftheWindowProxy
object ensures that [[SetPrototypeOf]] is never called on aWindow
objectdirectly. 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 theirindexed andnamed properties. These properties are not “real” ownproperties on the object, but are made to look like they are by being exposedby 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’ssupported property indices,then it is undefined what additional properties the object will appear tohave, or what its exact behavior will be with regard to its indexed properties.The same applies for named properties.
Theindexed property getter that is defined on the derived-most interface that thelegacy platform object implements is the one that defines the behaviorwhen indexing the object with anarray index. Similarly forindexed property setters.This way, the definitions of these special operations fromancestor interfaces can be overridden.
A property name is anunforgeable property name on agiven platform objectO if the object implements aninterface thathas aninterface member with that identifierand that interface member isunforgeable on any ofthe interfaces thatO implements.
Support forgetters is handled in§ 3.9.1 [[GetOwnProperty]],and forsetters 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 everylegacy platform objectO must behave as follows when called with property nameP:
Return?LegacyPlatformObjectGetOwnProperty(O,P,
false ).
3.9.2.[[Set]]
The [[Set]] internal method of everylegacy platform objectO must behave as follows when called with property nameP, valueV, and JavaScript language valueReceiver:
IfO andReceiver are the same object, then:
IfOimplements an interface with anindexed property setter andPis an array index, then:
Invoke the indexed property setter onO withP andV.
Return
true .
IfOimplements an interface with anamed property setter andPis a String, then:
Invoke the named property setter onO withP andV.
Return
true .
LetownDesc be?LegacyPlatformObjectGetOwnProperty(O,P,
true ).Perform?OrdinarySetWithOwnDescriptor(O,P,V,Receiver,ownDesc).
3.9.3.[[DefineOwnProperty]]
When the [[DefineOwnProperty]] internal method of alegacy platform objectO is called with property keyP andProperty DescriptorDesc, the following steps must be taken:
IfOsupports indexed properties andPis an array index, then:
If the result of callingIsDataDescriptor(Desc) is
false , then returnfalse .IfO does not implement an interface with anindexed property setter, then return
false .Invoke the indexed property setter onO withP andDesc.[[Value]].
Return
true .
IfOsupports named properties,O does not implement aninterface with the [
Global
]extended attribute,Pis a String,andP is not anunforgeable property name ofO, then:Letcreating be true ifP is not asupported property name, and false otherwise.
IfOimplements an interface with the [
LegacyOverrideBuiltIns
]extended attribute orO does not have an own propertynamedP, then:Ifcreating is false andO does not implement aninterface with anamed property setter, then return
false .IfOimplements an interface with anamed property setter, then:
If the result of callingIsDataDescriptor(Desc) is
false , then returnfalse .Invoke the named property setter onO withP andDesc.[[Value]].
Return
true .
Return!OrdinaryDefineOwnProperty(O,P,Desc).
3.9.4.[[Delete]]
The [[Delete]] internal method of everylegacy platform objectO must behave as follows when called with property nameP.
IfOsupports indexed properties andPis an array index, then:
Ifindex is not asupported property index, then return
true .Return
false .
IfOsupports named properties,O does not implement aninterface with the [
Global
]extended attribute and the result of calling thenamed property visibility algorithm with property nameP and objectO is true, then:IfO does not implement an interface with anamed property deleter, then return
false .Letoperation be the operation used to declare the named property deleter.
Ifoperation was defined without anidentifier, then:
Perform the steps listed in the interface description todelete an existing named property withP as the name.
If the steps indicated that the deletion failed, then return
false .
Otherwise,operation was defined with an identifier:
Performmethod steps ofoperation withO asthis and «P » as theargument values.
Ifoperation was declared with areturn type of
boolean
and the steps returnedfalse , then returnfalse .
Return
true .
IfO has an own property with nameP, then:
If the property is not configurable, then return
false .Otherwise, remove the property fromO.
Return
true .
3.9.5.[[PreventExtensions]]
When the [[PreventExtensions]] internal method of alegacy platform object is called, the following steps are taken:
Return
false .
Note: this keepslegacy platform objects extensible by making [[PreventExtensions]] fail for them.
3.9.6.[[OwnPropertyKeys]]
This document does not define a complete property enumeration orderforplatform objects implementinginterfaces (or forplatform objects representing exceptions).However, it does forlegacy platform objects by defining the [[OwnPropertyKeys]]internal method as follows.
When the [[OwnPropertyKeys]] internal method of alegacy platform objectO is called, the following steps are taken:
Letkeys be a new emptylist of JavaScript String and Symbol values.
IfOsupports indexed properties, thenfor eachindex ofO’ssupported property indices, in ascending numerical order,append!ToString(index) tokeys.
IfOsupports named properties, thenfor eachP ofO’ssupported property names that is visible according to thenamed property visibility algorithm,appendP tokeys.
For eachP ofO’s own property keys that is a String, in ascending chronological order ofproperty creation,appendP tokeys.
For eachP ofO’s own property keys that is a Symbol, in ascending chronological order ofproperty creation,appendP tokeys.
Assert:keys has no duplicate items.
Returnkeys.
3.9.7.Abstract operations
To determine if a property namePis anarray index, the following algorithm is applied:
IfPis not a String, then return
false .Letindex beCanonicalNumericIndexString(P).
Ifindex is
undefined , then returnfalse .IfIsInteger(index) is
false ,then returnfalse .Ifindex is −0, then return
false .Ifindex < 0, then return
false .Ifindex ≥ 232 − 1, then return
false .Note: 232 − 1 is the maximum array length allowed by JavaScript.
Return
true .
Thenamed 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 nameP and objectO:
IfP is not asupported property name ofO, then return false.
IfO has an own property namedP, then return false.
Note: This will include cases in whichO 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.
IfOimplements an interface that has the [
LegacyOverrideBuiltIns
]extended attribute, then return true.Letprototype beO.[[GetPrototypeOf]]().
Whileprototype is not null:
Ifprototype is not anamed properties object,andprototype has an own property namedP, then return false.
Setprototype toprototype.[[GetPrototypeOf]]().
Return true.
This ensures 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.
Toinvoke an indexed property setter on aplatform objectO with property nameP and JavaScript valueV, the following steps must be performed:
Letcreating be true ifindex is not asupported property index,and false otherwise.
Letoperation be the operation used to declare the indexed property setter.
LetT be the type of the second argument ofoperation.
Letvalue be the result ofconvertingV to an IDL value of typeT.
Ifoperation was defined without anidentifier, then:
Ifcreating is true, then perform the steps listed in the interface description toset the value of a new indexed property withindex as the index andvalue as the value.
Otherwise,creating is false. Perform the steps listed in the interface description toset the value of an existing indexed property withindex as the index andvalue as the value.
Otherwise,operation was defined with an identifier. Perform themethod steps ofoperation withO asthis and «index,value » as the argument values.
Toinvoke a named property setter on aplatform objectO with property nameP and JavaScript valueV, the following steps must be performed:
Letcreating be true ifP is not asupported property name, and false otherwise.
Letoperation be the operation used to declare the named property setter.
LetT be the type of the second argument ofoperation.
Letvalue be the result ofconvertingV to an IDL value of typeT.
Ifoperation was defined without anidentifier, then:
Ifcreating is true, then perform the steps listed in the interface description toset the value of a new named property withP as the name andvalue as the value.
Otherwise,creating is false. Perform the steps listed in the interface description toset the value of an existing named property withP as the name andvalue as the value.
Otherwise,operation was defined with an identifier. Perform themethod steps ofoperation withO asthis and «P,value » as the argument values.
TheLegacyPlatformObjectGetOwnProperty abstract operation performs the following steps when called with an objectO, a property nameP, and a booleanignoreNamedProps value:
IfOsupports indexed properties andPis an array index, then:
Ifindex is asupported property index, then:
Letoperation be the operation used to declare the indexed property getter.
Letvalue be an uninitialized variable.
Ifoperation was defined without anidentifier, thensetvalue to the result of performing the steps listed in the interface description todetermine the value of an indexed property withindex as the index.
Otherwise,operation was defined with an identifier. Setvalue to the resultof performing themethod steps ofoperation withO asthis and «index » as the argument values.
Letdesc be a newly createdProperty Descriptor with no fields.
Setdesc.[[Value]] to the result ofconvertingvalue to a JavaScript value.
IfOimplements an interface with anindexed property setter, then setdesc.[[Writable]] to
true , otherwise set it tofalse .Setdesc.[[Enumerable]] anddesc.[[Configurable]] to
true .Returndesc.
SetignoreNamedProps to true.
IfOsupports named properties andignoreNamedProps is false, then:
If the result of running thenamed property visibility algorithm withproperty nameP and objectO is true, then:
Letoperation be the operation used to declare the named property getter.
Letvalue be an uninitialized variable.
Ifoperation was defined without anidentifier, thensetvalue to the result of performing the steps listed in the interface description todetermine the value of a named property withP as the name.
Otherwise,operation was defined with an identifier. Setvalue to the resultof performing themethod steps ofoperation withO asthis and «P »as the argument values.
Letdesc be a newly createdProperty Descriptor with no fields.
Setdesc.[[Value]] to the result ofconvertingvalue to a JavaScript value.
IfOimplements an interface with anamed property setter, then setdesc.[[Writable]] to
true , otherwise set it tofalse .IfOimplements an interface with the[
LegacyUnenumerableNamedProperties
]extended attribute,then setdesc.[[Enumerable]] tofalse ,otherwise set it totrue .Setdesc.[[Configurable]] to
true .Returndesc.
ReturnOrdinaryGetOwnProperty(O,P).
3.10.Observable array exotic objects
Anobservable array exotic object is a specific type of JavaScriptProxy exotic object which is created using the proxy traps defined in this section. They aredefined in this manner because the JavaScript specification includes special treatment forProxy exotic objects that haveArray
instances as their proxy target, and we wantto ensure thatobservable array types are exposed to JavaScript code with this special treatmentintact.
The proxy traps used by observable array exotic objects work to ensure a number of invariants beyondthose of normalArray
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 thespecified Web IDL type, and noarray index properties will exist outside that range.The property descriptors for important properties cannot be changed from their defaultconfiguration; indexed properties always remain as configurable, enumerable, and writable dataproperties, 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()
.
LetinnerArray be!ArrayCreate(0).
Lethandler beOrdinaryObjectCreate(
null ,« [[Type]], [[SetAlgorithm]], [[DeleteAlgorithm]], [[BackingList]] »).Sethandler.[[Type]] toT.
Sethandler.[[SetAlgorithm]] tosetAlgorithm.
Sethandler.[[DeleteAlgorithm]] todeleteAlgorithm.
LetdefineProperty beCreateBuiltinFunction(the steps from§ 3.10.1 defineProperty, « »,realm).
Perform!CreateDataPropertyOrThrow(handler, "
defineProperty
",defineProperty).LetdeleteProperty beCreateBuiltinFunction(the steps from§ 3.10.2 deleteProperty, « »,realm).
Perform!CreateDataPropertyOrThrow(handler, "
deleteProperty
",deleteProperty).Letget beCreateBuiltinFunction(the steps from§ 3.10.3 get, « »,realm).
Perform!CreateDataPropertyOrThrow(handler, "
get
",get).LetgetOwnPropertyDescriptor beCreateBuiltinFunction(the steps from§ 3.10.4 getOwnPropertyDescriptor, « »,realm).
Perform!CreateDataPropertyOrThrow(handler, "
getOwnPropertyDescriptor
",getOwnPropertyDescriptor).Lethas beCreateBuiltinFunction(the steps from§ 3.10.5 has, « »,realm).
Perform!CreateDataPropertyOrThrow(handler, "
has
",has).LetownKeys beCreateBuiltinFunction(the steps from§ 3.10.6 ownKeys, « »,realm).
Perform!CreateDataPropertyOrThrow(handler, "
ownKeys
",ownKeys).LetpreventExtensions beCreateBuiltinFunction(the steps from§ 3.10.7 preventExtensions, « »,realm).
Perform!CreateDataPropertyOrThrow(handler, "
preventExtensions
",preventExtensions).Letset beCreateBuiltinFunction(the steps from§ 3.10.8 set, « »,realm).
Perform!CreateDataPropertyOrThrow(handler, "
set
",set).Return!ProxyCreate(innerArray,handler).
3.10.1.defineProperty
defineProperty
proxy trap forobservable array exotic objects, givenO,P, anddescriptorObj are as follows:Lethandler be the
this value.Letdescriptor be!ToPropertyDescriptor(descriptorObj).
IfP is "length", then:
IfIsAccessorDescriptor(descriptor) is
true , then returnfalse .Ifdescriptor.[[Configurable]] is present and has the value
true ,then returnfalse .Ifdescriptor.[[Enumerable]] is present and has the value
true ,then returnfalse .Ifdescriptor.[[Writable]] is present and has the value
false ,then returnfalse .Ifdescriptor.[[Value]] is present, then return the result ofsetting the length givenhandler anddescriptor.[[Value]].
Return
true .
IfPis an array index, then:
IfIsAccessorDescriptor(descriptor) is
true , then returnfalse .Ifdescriptor.[[Configurable]] is present and has the value
false ,then returnfalse .Ifdescriptor.[[Enumerable]] is present and has the value
false ,then returnfalse .Ifdescriptor.[[Writable]] is present and has the value
false ,then returnfalse .Ifdescriptor.[[Value]] is present, then return the result ofsetting the indexed value givenhandler,P, anddescriptor.[[Value]].
Return
true .
Return?O.[[DefineOwnProperty]](P,descriptor).
3.10.2.deleteProperty
deleteProperty
proxy trap forobservable array exotic objects, givenO andP, are as follows:Lethandler be the
this value.IfP is "length", then return
false .IfPis an array index, then:
Return?O.[[Delete]](P).
3.10.3.get
get
proxy trap forobservable array exotic objects, givenO,P, andReceiver, are as follows:Lethandler be the
this value.Letlength behandler.[[BackingList]]'ssize.
IfP is "length", then returnlength.
IfPis an array index, then:
Ifindex ≥length, then return
undefined .LetjsValue be the result ofconvertinghandler.[[BackingList]][index] to a JavaScript value.
Assert: the above step never throws an exception.
ReturnjsValue.
Return?O.[[Get]](P,Receiver).
3.10.4.getOwnPropertyDescriptor
getOwnPropertyDescriptor
proxy trap forobservable array exotic objects, givenO andP, are as follows:Lethandler be the
this value.Letlength behandler.[[BackingList]]'ssize.
IfP is "length", then return!FromPropertyDescriptor(PropertyDescriptor{[[Configurable]]:
false ,[[Enumerable]]:false , [[Writable]]:true ,[[Value]]:length }).IfPis an array index, then
Ifindex ≥length, then return
undefined .LetjsValue be the result ofconvertinghandler.[[BackingList]][index] to a JavaScript value.
Assert: the above step never throws an exception.
ReturnFromPropertyDescriptor(PropertyDescriptor{[[Configurable]]:
true , [[Enumerable]]:true , [[Writable]]:true , [[Value]]:jsValue }).
ReturnFromPropertyDescriptor(?O.[[GetOwnProperty]](P)).
3.10.5.has
has
proxy trap forobservable array exotic objects, givenO andP, are as follows:Lethandler be the
this value.IfP is "length", then return
true .IfPis an array index, then:
Return?O.[[HasProperty]](P).
3.10.6.ownKeys
ownKeys
proxy trap forobservable array exotic objects, givenO, are as follows:3.10.7.preventExtensions
preventExtensions
proxy trap forobservable array exotic objects are as follows:Return
false .
3.10.8.set
set
proxy trap forobservable array exotic objects, givenO,P,V, andReceiver, are as follows:Lethandler be the
this value.IfP is "length", then return the result ofsetting the length givenhandler andV.
IfPis an array index, then return the result ofsetting the indexed value givenhandler,P, andV.
Return?O.[[Set]](P,V,Receiver).
3.10.9.Abstract operations
Ifuint32Len ≠numberLen, then throw a
RangeError
exception.LetoldLen behandler.[[BackingList]]'ssize.
Ifuint32Len >oldLen, then return
false .LetindexToDelete beoldLen − 1.
WhileindexToDelete ≥uint32Len:
Perform the algorithm steps given byhandler.[[DeleteAlgorithm]], givenhandler.[[BackingList]][indexToDelete] andindexToDelete.
Remove the last item fromhandler.[[BackingList]].
SetindexToDelete toindexToDelete − 1.
Return
true .
LetoldLen behandler.[[BackingList]]'ssize.
Ifindex >oldLen, return
false .LetidlValue be the result ofconvertingV to the type given byhandler.[[Type]].
Ifindex <oldLen, then:
Perform the algorithm steps given byhandler.[[DeleteAlgorithm]], givenhandler.[[BackingList]][index] andindex.
Perform the algorithm steps given byhandler.[[SetAlgorithm]], givenidlValue andindex.
Ifindex =oldLen, thenappendidlValue tohandler.[[BackingList]].
Otherwise, sethandler.[[BackingList]][index] toidlValue.
Return
true .
3.11.Callback interfaces
As described in§ 2.12 Objects implementing interfaces,callback interfaces can beimplemented in script by any JavaScript object.The following cases explain how acallback interface’soperation is invoked on a givenobject:
If the object iscallable, then the implementation of the operation is thecallable object itself.
Otherwise, the implementation of the operation is calling the result of invoking theinternal [[Get]] method on the object with a property name that is theidentifier ofthe operation.
Note that JavaScript objects need not haveproperties corresponding toconstants on them to be considered asimplementingcallback interfaces that happento have constants declared on them.
AWeb IDL arguments list is alist of values each of which is either an IDL value orthe special value “missing”, which represents a missing optional argument.
LetjsArgs be an emptylist.
Leti be 0.
Letcount be 0.
Whilei <args’ssize:
Ifargs[i] is the special value “missing”, thenappend
undefined tojsArgs.Otherwise,args[i] is an IDL value:
LetconvertResult be the result ofconvertingargs[i] to a JavaScript value. Rethrow any exceptions.
AppendconvertResult tojsArgs.
Setcount toi + 1.
Seti toi + 1.
TruncatejsArgs to containcount items.
ReturnjsArgs.
Tocall a user object’s operation, given acallback interface type valuevalue, operation nameopName,Web IDL arguments listargs, and optionalcallback this valuethisArg, perform the following steps. These steps will either return an IDL value or throw an exception.
Letcompletion be an uninitialized variable.
IfthisArg was not given, letthisArg be
undefined .LetO be the JavaScript object corresponding tovalue.
Letrealm beO’sassociated realm.
Letrelevant settings berealm’ssettings object.
Letstored settings bevalue’scallback context.
Prepare to run script withrelevant settings.
Prepare to run a callback withstored settings.
LetX beO.
IfIsCallable(O) is false, then:
LetgetResult beCompletion(Get(O,opName)).
IfgetResult is anabrupt completion, setcompletion togetResult and jump to the step labeledreturn.
SetX togetResult.[[Value]].
IfIsCallable(X) is
false ,then setcompletion toCompletion Record { [[Type]]: throw, [[Value]]: anewly createdTypeError
object, [[Target]]: empty }, and jumpto the step labeledreturn.SetthisArg toO (overriding the provided value).
LetjsArgs be the result ofconvertingargs to a JavaScriptarguments list. If this throws an exception, setcompletion to the completion valuerepresenting the thrown exception and jump to the step labeledreturn.
LetcallResult beCompletion(Call(X,thisArg,jsArgs)).
IfcallResult is anabrupt completion, setcompletion tocallResult and jump to the step labeledreturn.
Setcompletion to the result ofconvertingcallResult.[[Value]] to an IDL value of the same type as the operation’sreturn type. If this throws an exception, setcompletion to the completion valuerepresenting the thrown exception.
Return: at thispointcompletion will be set to an IDL value or anabrupt completion.
Clean up after running a callback withstored settings.
Clean up after running script withrelevant settings.
Ifcompletion is an IDL value, returncompletion.
Ifcompletion is anabrupt completion and the operation has areturn type that isnot apromise type, throwcompletion.[[Value]].
LetrejectedPromise be!Call(
%Promise.reject%
,%Promise%
, «completion.[[Value]]»).Return the result ofconvertingrejectedPromise to the operation’s return type.
3.11.1.Legacy callback interface object
For everycallback interface that isexposed ina givenrealm and on whichconstants are defined,a corresponding property exists on therealm’sglobal object.The name of the property is theidentifier of thecallback interface,and its value is an object called thelegacy callback interface object.
Thelegacy callback interface object for a givencallback interface is abuilt-in function object.It has properties that correspond to theconstants defined on that interface,as described in sections§ 3.7.5 Constants.
Note: Since alegacy callback interface object is afunction object thetypeof
operator will return "function"when applied to alegacy callback interface object.
Thelegacy callback interface object for a givencallback interfaceinterface withidentifierid and inrealmrealm iscreated as follows:
Letsteps be the following steps:
LetF beCreateBuiltinFunction(steps, « »,realm).
PerformSetFunctionName(F,id).
PerformSetFunctionLength(F, 0).
Define the constants ofinterface onF givenrealm.
ReturnF.
3.12.Invoking callback functions
A JavaScriptcallable object that is beingused as acallback function value iscalled in a manner similar to howoperations oncallback interface values are called (asdescribed in the previous section).
Toinvoke acallback function type valuecallable with aWeb IDL arguments listargs, exception behaviorexceptionBehavior (either "report
" or "rethrow
"), and an optionalcallback this valuethisArg, perform the following steps. These steps will either return an IDL value or throw an exception.
TheexceptionBehavior argument must be supplied if, and only if,callable’sreturn type is not apromise type. Ifcallable’s return type is neitherundefined
norany
, it must be "rethrow
".
rethrow
".Letcompletion be an uninitialized variable.
IfthisArg was not given, letthisArg be
undefined .LetF be the JavaScript object corresponding tocallable.
IfIsCallable(F) is
false :Note: This is only possible when thecallback function came from an attributemarked with [
LegacyTreatNonObjectAsNull
].Return the result ofconverting
undefined to the callback function’s return type.
Letrealm beF’sassociated realm.
Letrelevant settings berealm’ssettings object.
Letstored settings becallable’scallback context.
Prepare to run script withrelevant settings.
Prepare to run a callback withstored settings.
LetjsArgs be the result ofconvertingargs to a JavaScriptarguments list. If this throws an exception, setcompletion to the completion valuerepresenting the thrown exception and jump to the step labeledreturn.
LetcallResult beCompletion(Call(F,thisArg,jsArgs)).
IfcallResult is anabrupt completion, setcompletion tocallResult and jump to the step labeledreturn.
Setcompletion to the result ofconvertingcallResult.[[Value]] to an IDL value of the same type ascallable’sreturn type. If this throws an exception, setcompletion to the completion valuerepresenting the thrown exception.
Return: at thispointcompletion will be set to an IDL value or anabrupt completion.
Clean up after running a callback withstored settings.
Clean up after running script withrelevant settings.
Ifcompletion is an IDL value, returncompletion.
Assert:completion is anabrupt completion.
IfexceptionBehavior is "
rethrow
", throwcompletion.[[Value]].Otherwise, ifexceptionBehavior is "
report
":Assert:callable’sreturn type is
undefined
orany
.Report an exceptioncompletion.[[Value]] forrealm’sglobal object.
Return the unique
undefined
IDL value.
Assert:callable’sreturn type is apromise type.
LetrejectedPromise be!Call(
%Promise.reject%
,%Promise%
, «completion.[[Value]]»).Return the result ofconvertingrejectedPromise to the callback function’s return type.
Some callback functions are instead used asconstructors. Such callback functions must not havea return type that is apromise type.
Toconstruct acallback function type valuecallable with aWeb IDL arguments listargs, perform the following steps. These steps will either return an IDL value or throw an exception.
Letcompletion be an uninitialized variable.
LetF be the JavaScript object corresponding tocallable.
IfIsConstructor(F) is
false , throw aTypeError
exception.Letrealm beF’sassociated realm.
Letrelevant settings berealm’ssettings object.
Letstored settings becallable’scallback context.
Prepare to run script withrelevant settings.
Prepare to run a callback withstored settings.
LetjsArgs be the result ofconvertingargs to a JavaScriptarguments list. If this throws an exception, setcompletion to the completion valuerepresenting the thrown exception and jump to the step labeledreturn.
LetcallResult beCompletion(Construct(F,jsArgs)).
IfcallResult is anabrupt completion, setcompletion tocallResult and jump to the step labeledreturn.
Setcompletion to the result ofconvertingcallResult.[[Value]] to an IDL value of the same type ascallable’sreturn type. If this throws an exception, setcompletion to the completion valuerepresenting the thrown exception.
Return: at thispointcompletion will be set to an IDL value or anabrupt completion.
Clean up after running a callback withstored settings.
Clean up after running script withrelevant settings.
Ifcompletion is anabrupt completion, throwcompletion.[[Value]].
Returncompletion.
3.13.Namespaces
For everynamespace that isexposed in a givenrealm,a corresponding property exists on therealm’sglobal object.The name of the property is theidentifier of the namespace, and its value is an objectcalled thenamespace 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 givennamespacenamespace andrealmrealm iscreated as follows:
LetnamespaceObject beOrdinaryObjectCreate(realm.[[Intrinsics]].[[
%Object.prototype%
]]).Define the regular attributes ofnamespace onnamespaceObject givenrealm.
Define the regular operations ofnamespace onnamespaceObject givenrealm.
Define the constants ofnamespace onnamespaceObject givenrealm.
For eachexposedinterfaceinterface which has the [
LegacyNamespace
] extendedattribute with the identifier ofnamespace as its argument,Letid beinterface’sidentifier.
LetinterfaceObject be the result ofcreating aninterface object forinterface withid inrealm.
PerformDefineMethodProperty(namespaceObject,id,interfaceObject, false).
ReturnnamespaceObject.
Theclass string of anamespace object is thenamespace’sidentifier.
3.14.Exceptions
3.14.1.DOMException
custom bindings
In the JavaScript binding, theinterface prototype object forDOMException
has its [[Prototype]]internal slot set to the intrinsic object%Error.prototype%
,as defined in thecreate an interface prototype object abstract operation.It also has an [[ErrorData]] slot, like all built-in exceptions.
Additionally, if an implementation gives nativeError
objects special powers ornonstandard properties (such as astack
property),it should also expose those onDOMException
objects.
3.14.2.Exception objects
Simple exceptions are representedby native JavaScript objects of the corresponding type.
ADOMException
is represented by aplatform object that implements theDOMException
interface.
3.14.3.Creating and throwing exceptions
Letmessage be animplementation-defined message appropriate for the exceptionalsituation. The calling specification may contain information to to help implementationsconstruct this message.
Implementations need to be cautious not to leak sensitive or secured information whenconstructing this message, e.g., by including the URL of a cross-origin frame, orinformation which could identify the user.
Letargs be «message ».
Letconstructor becurrent realm.[[Intrinsics]].[[%T%]].
DOMException
given a stringname:Assert:name appears in the
DOMException
names table.Letex be anew
DOMException
created in thecurrent realm.Setex’sname toname.
Setex’smessage to animplementation-defined message appropriate forthe exceptional situation. The calling specification may contain information to to helpimplementations construct this message.
Implementations need to be cautious not to leak sensitive or secured information whenconstructing this message, e.g., by including the URL of a cross-origin frame, orinformation which could identify the user.
Returnex.
DOMException
derived interface given theinterfaceidentifiertype and additional initialization instructions:Letex be anew instance of theinterface identified bytype, created in thecurrent realm.
Setex’sname totype.
Setex’smessage to animplementation-defined message appropriate forthe exceptional situation. The calling specification may contain information to to helpimplementations construct this message.
Implementations need to be cautious not to leak sensitive or secured information whenconstructing this message, e.g., by including the URL of a cross-origin frame, orinformation which could identify the user.
Perform any additional initialization onex as described by the caller.
Returnex.
The above algorithms restrictobjects representing exceptions propagating out of afunction object to be ones that are associated with therealm of thatfunction object (i.e., thecurrent 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 applycomputeSquareRoot
to aMathUtils
object from a differentrealm, then the exception thrown will be from therealm 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 JavaScript runtime semantics are invoked dueto requirements in this document andend due to an exception being thrown, that exceptionmust propagate to the caller, and ifnot caught there, to its caller, and so on.
PerDocument conventions, an algorithm specified in this document may intercept thrown exceptions, either by specifyingthe exact steps to take ifan exception was thrown, or by explicitly handlingabrupt completions.
The followingIDL fragment defines twointerfaces and anexception. ThevalueOf
attribute onExceptionThrower
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 a JavaScript 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 JavaScript 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.
4.Common definitions
This section specifies some common definitions that allconforming implementations must support.
4.1.ArrayBufferView
typedef (Int8Array or Int16Array or Int32Array or Uint8Array or Uint16Array or Uint32Array or Uint8ClampedArray or BigInt64Array or BigUint64Array or Float16Array or Float32Array or Float64Array or DataView )ArrayBufferView ;
TheArrayBufferView
typedef is used to representobjects that provide a view on to anArrayBuffer
orSharedArrayBuffer
(when [AllowShared
] is used).
4.2.BufferSource
typedef (ArrayBufferView or ArrayBuffer )BufferSource ;
TheBufferSource
typedef is used to represent objectsthat are either themselves anArrayBuffer
or whichprovide a view on to anArrayBuffer
.
Note: [AllowShared
] cannot be used withBufferSource
asArrayBuffer
does not support it.UseAllowSharedBufferSource
instead.
4.3.AllowSharedBufferSource
typedef (ArrayBuffer or SharedArrayBuffer or [AllowShared ]ArrayBufferView )AllowSharedBufferSource ;
TheAllowSharedBufferSource
typedef is used to represent objectsthat are either themselves anArrayBuffer
orSharedArrayBuffer
or whichprovide a view on to anArrayBuffer
orSharedArrayBuffer
.
4.4.DOMException
TheDOMException
type is aninterface type defined by the following IDLfragment:
[Exposed=*,Serializable ]interface DOMException { // but see below note about JavaScript 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 = 2;
DOMSTRING_SIZE_ERR const unsigned short HIERARCHY_REQUEST_ERR = 3;const unsigned short WRONG_DOCUMENT_ERR = 4;const unsigned short INVALID_CHARACTER_ERR = 5;const unsigned short = 6;
NO_DATA_ALLOWED_ERR 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 = 16;
VALIDATION_ERR 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 JavaScript binding imposes additionalrequirements beyond the normal ones forinterface types.
EachDOMException
object has an associatedname andmessage, bothstrings.
Thenew DOMException(message,name)
constructor steps are:
Thename
getter steps are to returnthis’sname.
Themessage
getter steps are toreturnthis’smessage.
Thecode
getter steps are to return the legacycode indicated in theDOMException
names table forthis’sname, or 0 if no such entry exists in the table.
DOMException
objects areserializable objects.
Theirserialization steps, givenvalue andserialized, are:
- Setserialized.[[Name]] tovalue’sname.
- Setserialized.[[Message]] tovalue’smessage.
- User agents should attach a serialized representation of any interesting accompanying data which are not yet specified, notably the
stack
property, toserialized.
Theirdeserialization steps, givenvalue andserialized, are:
- Setvalue’sname toserialized.[[Name]].
- Setvalue’smessage toserialized.[[Message]].
- If any other data is attached toserialized, then deserialize and attach it tovalue.
4.5.Function
callback Function =any (any ...);
arguments
TheFunction
callback function type is used for representing function values with no restriction on what argumentsare passed to it or what kind of value is returned from it.
4.6.VoidFunction
callback VoidFunction =undefined ();
TheVoidFunction
callback function type is used for representing function values that take no arguments and do notreturn any value.
5.Extensibility
This section is informative.
Extensions to language binding requirements can be specifiedusingextended attributes that do not conflict with those defined in this document. Extensions forprivate, project-specific use ought not be included inIDL fragments appearing in other specifications. It is recommended that extensionsthat are required for use in other specifications be coordinatedwith the group responsible for work onWeb IDL, whichat the time of writing is theW3C Web Platform Working Group,for possible inclusion in a future version of this document.
Extensions to any other aspect of the IDL language arestrongly discouraged.
6.Legacy constructs
This section is informative.
Legacy Web IDL constructs exist only so thatlegacy Web platform features can be specified.They are generally prefixed with the "Legacy
" string.It is strongly discouraged to use legacy Web IDL constructs in specificationsunless required to specify the behavior of legacy Web platform features,or for consistency with such features.Editors who wish to use legacy Web IDL constructs are strongly advised to discuss thisbyfiling 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 candidatefor future removal from this specification,whenever various heuristics indicate thatthe Web platform features it helps specify can be removed altogetheror can be modified to rely on non-legacy Web IDL constructs instead.
7.Referencing this specification
This section is informative.
It is expected that other specifications that define Web platform interfacesusing one or moreIDL fragments will reference this specification. It is suggestedthat those specifications include a sentence such as the following,to indicate that the IDL is to be interpreted as described in thisspecification:
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 forconforming sets of IDL fragments, as described in the “Web IDL” specification. [WEBIDL]
In addition, it is suggested that the conformance class for useragents in referencing specifications be linked to theconforming implementation class from this specification:
A conforming FooML user agent must also be aconforming 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 incorrectimplementation of this layer can lead to security issues.
This specification also provides the ability to use JavaScript values directly, through theany
andobject
IDL types. These values need to be handled carefully to avoid securityissues. 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 withSharedArrayBuffer
objects, which can beused to build timing attacks. Specifications that use these objects need to consider such attacks.
Acknowledgments
This section is informative.
The editors would like to thank the following people for contributingto this specification:Glenn Adams,David Andersson,Jake Archibald,Tab Atkins-Bittner,L. David Baron,Art Barstow,Nils Barth,Robin Berjon,David Bruant,Jan-Ivar Bruaroey,Marcos Cáceres,Giovanni Campagna,François Daoust,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,Raphael Kubo da Costa,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,Jeremy Roman,Tim Ruffles,Alex Russell,Takashi Sakamoto,Doug Schepers,Jonas Sicking,Garrett Smith,Sam Sneddon,Jungkee Song,Josh Soref,Maciej Stachowiak,Austin Sullivan,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 documentwhile the editor was unavailable to do so.
This standard is written by Edgar Chen (Mozilla,echen@mozilla.com) and Tiancheng "Timothy" Gu(timothygu99@gmail.com) with substantial contributions fromBoris Zbarsky (bzbarsky@mit.edu),Cameron McCormack (cam@mcc.id.au),andTobie Langel (tobie@unlockopen.com).
IDL grammar
This section defines an LL(1) grammar whose start symbol,
Each production in the grammar has on its right hand side either anon-zero sequence of terminal and non-terminal symbols, or anepsilon (ε) 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 terminalsymbols that are matched by the regular expressions (using Perl 5 regularexpression 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 ofscalar values.When tokenizing, the longest possible match must be used. For example, if the inputtext is “a1”, it is tokenized as a singlelong
",and “.” is tokenized as the terminal symbol
The IDL syntax is case sensitive, both for the monospaced terminal symbolsused in the grammar and the values used forA
" is distinct from one named "a
", and anextended attribute [legacyfactoryfunction
] will not be recognized asthe [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 InheritAttribute Inheritance ::: identifier εMixinRest ::mixin identifier { MixinMembers } ; MixinMembers ::ExtendedAttributeList MixinMember MixinMembers εMixinMember ::Const RegularOperation Stringifier OptionalReadOnly 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 ::AttributeRest InheritAttribute ::inherit AttributeRest AttributeRest ::attribute TypeWithExtendedAttributes AttributeName ; AttributeName ::AttributeNameKeyword identifier AttributeNameKeyword ::async required OptionalReadOnly ::readonly εDefaultValue ::ConstValue string [ ] { } null undefined Operation ::RegularOperation SpecialOperation RegularOperation ::Type 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 ::... εConstructor ::constructor ( ArgumentList ) ; Stringifier ::stringifier StringifierRest StringifierRest ::OptionalReadOnly AttributeRest ; StaticMember ::static StaticMemberRest StaticMemberRest ::OptionalReadOnly 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 Const 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 = Type ( 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 async iterable < TypeWithExtendedAttributes > Null object Null symbol Null BufferRelatedType Null FrozenArray < TypeWithExtendedAttributes > Null ObservableArray < TypeWithExtendedAttributes > Null RecordType Null undefined Null PrimitiveType ::UnsignedIntegerType UnrestrictedFloatType boolean byte octet bigint UnrestrictedFloatType ::unrestricted FloatType FloatType FloatType ::float double UnsignedIntegerType ::unsigned IntegerType IntegerType IntegerType ::short long OptionalLong OptionalLong ::long εStringType ::ByteString DOMString USVString PromiseType ::Promise < Type > RecordType ::record < StringType , TypeWithExtendedAttributes > Null ::? εBufferRelatedType ::ArrayBuffer SharedArrayBuffer DataView Int8Array Int16Array Int32Array Uint8Array Uint16Array Uint32Array Uint8ClampedArray BigInt64Array BigUint64Array Float16Array 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 bigint boolean byte double false float long null object octet or optional record sequence short symbol true unsigned undefined ArgumentNameKeyword BufferRelatedType OtherOrComma ::Other , IdentifierList ::identifier Identifiers Identifiers ::, identifier Identifiers εExtendedAttributeNoArgs ::identifier ExtendedAttributeArgList ::identifier ( ArgumentList ) ExtendedAttributeIdent ::identifier = identifier ExtendedAttributeWildcard ::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
JavaScript classes:
Map
JavaScript language types: Object
Code snippets:
a = b + obj.f()
Scalar values: U+0030 (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 arehighlighted.)
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 a JavaScript code block. window. onload= function () { window. alert( "loaded" ); };
The following conventions are used in the algorithms in this document:
Algorithms use theconventions of the JavaScript specification,including the! and? notation for unwrappingCompletion Records.
Algorithms sometimes treat returning/throwing values and returningCompletion Records interchangeably. That is, an algorithm that uses return/throw terminology may be treated asreturning aCompletion Record, while one that returns aCompletion Record may be treated asreturning a value or throwing an exception. Similarly, to catch exceptions, defining thebehavior to adopt whenan exception was thrown and checking if theCompletion Record’s[[Type]] field is “throw” are equivalent.
Completion Records are extended by allowing them to contain values that are not JavaScriptvalues, 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 ofIDL fragments is consideredto be aconforming set of IDL fragments if, taken together, they satisfy all of themust-,required- and shall-levelcriteria in this specification that apply to IDL fragments.
- conforming implementation
A user agent is considered to be aconforming implementation relative to aconforming set of IDL fragments if it satisfies all of the must-,required- and shall-levelcriteria in this specification that apply to implementations for all languagebindings that the user agent supports.
- conforming JavaScript implementation
A user agent is considered to be aconforming JavaScript implementation relative to aconforming set of IDL fragments if it satisfies all of the must-,required- and shall-levelcriteria in this specification that apply to implementations for the JavaScriptlanguage binding.
Intellectual property rights
Copyright © WHATWG (Apple, Google, Mozilla, Microsoft). This work is licensed under aCreative Commons Attribution 4.0International License. To the extent portions of it are incorporated into source code, suchportions in the source code are licensed under theBSD 3-Clause License instead.
This is the Living Standard. Thoseinterested in the patent-review version should view theLiving Standard Review Draft.