Abstract
This document defines an interface definition language, Web IDL, that can be used to describe interfaces that are intended to be implemented in web browsers. Web IDL is an IDL variant with a number of features that allow the behavior of common script objects in the web platform to be specified more readily. How interfaces described with Web IDL correspond to constructs within ECMAScript execution environments is also detailed in this document. It is expected that newly published specifications reference this document to ensure conforming implementations of interfaces are interoperable.
Status of This Document
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at https://www.w3.org/TR/.
This is the "Level 1" Version of WebIDL, it contains parts of the main Editor's copy [WEBIDL] that are considered stable, implemented and tested. Implementors who do not need to reference a stable version of WebIDL should defer to the Editor's copy [WEBIDL] only, as it may contain updated algorithm and definitions; this specification is suitable for reference by other specification authors in so far as it wholly contains the syntax definitions used in the citing document. New syntax definitions will be added in the next Level of WebIDL.
It is important to note that parts of this specification highlight future changes. Some features might become deprecated and new features will be added. Readers of this specification should also read the Editor's Copy and subsequent Levels of this specification to ensure that what they use is still matching implementations.
This document is produced by the Web Platform Working Group in the W3C Interaction Domain. Changes made to this document can be found in the specification’s commit log on GitHub: recent changes, older changes.
There is a bug tracker for the specification, but look at the Editor's copy to ensure that possible bugs are not yet addressed.
This document was published by the Web Platform Working Group as a Recommendation. If you wish to make comments regarding this document, please send them to public-script-coord@w3.org (subscribe, archives). All comments are welcome.
Please see the Working Group's implementation report.
This document has been reviewed by W3C Members, by software developers, and by other W3C groups and interested parties, and is endorsed by the Director as a W3C Recommendation. It is a stable document and may be used as reference material or cited from another document. W3C's role in making the Recommendation is to draw attention to the specification and to promote its widespread deployment. This enhances the functionality and interoperability of the Web.
This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
This document is governed by the 1 September 2015 W3C Process Document.
Table of Contents
- 1. Introduction
- 2. Conformance
- 3. Interface definition language
- 3.1 Names
- 3.2 Interfaces
- 3.3 Dictionaries
- 3.4 Exceptions
- 3.5 Enumerations
- 3.6 Callback functions
- 3.7 Typedefs
- 3.8 Implements statements
- 3.9 Objects implementing interfaces
- 3.10 Types
- 3.10.1 any
- 3.10.2 boolean
- 3.10.3 byte
- 3.10.4 octet
- 3.10.5 short
- 3.10.6 unsigned short
- 3.10.7 long
- 3.10.8 unsigned long
- 3.10.9 long long
- 3.10.10 unsigned long long
- 3.10.11 float
- 3.10.12 unrestricted float
- 3.10.13 double
- 3.10.14 unrestricted double
- 3.10.15 DOMString
- 3.10.16 ByteString
- 3.10.17 USVString
- 3.10.18 object
- 3.10.19 Interface types
- 3.10.20 Dictionary types
- 3.10.21 Enumeration types
- 3.10.22 Callback function types
- 3.10.23 Nullable types — T?
- 3.10.24 Sequences — sequence<T>
- 3.10.25 Promise types — Promise<T>
- 3.10.26 Union types
- 3.10.27 Error
- 3.10.28 DOMException
- 3.10.29 Buffer source types
- 3.11 Extended attributes
- 4. ECMAScript binding
- 4.1 ECMAScript environment
- 4.2 ECMAScript type mapping
- 4.2.1 any
- 4.2.2 void
- 4.2.3 boolean
- 4.2.4 byte
- 4.2.5 octet
- 4.2.6 short
- 4.2.7 unsigned short
- 4.2.8 long
- 4.2.9 unsigned long
- 4.2.10 long long
- 4.2.11 unsigned long long
- 4.2.12 float
- 4.2.13 unrestricted float
- 4.2.14 double
- 4.2.15 unrestricted double
- 4.2.16 DOMString
- 4.2.17 ByteString
- 4.2.18 USVString
- 4.2.19 object
- 4.2.20 Interface types
- 4.2.21 Dictionary types
- 4.2.22 Enumeration types
- 4.2.23 Callback function types
- 4.2.24 Nullable types — T?
- 4.2.25 Sequences — sequence<T>
- 4.2.26 Promise types — Promise<T>
- 4.2.27 Union types
- 4.2.28 Error
- 4.2.29 DOMException
- 4.2.30 Buffer source types
- 4.3 ECMAScript-specific extended attributes
- 4.3.1 [Clamp]
- 4.3.2 [Constructor]
- 4.3.3 [EnforceRange]
- 4.3.4 [Exposed]
- 4.3.5 [Global] and [PrimaryGlobal]
- 4.3.6 [LenientThis]
- 4.3.7 [NamedConstructor]
- 4.3.8 [NewObject]
- 4.3.9 [NoInterfaceObject]
- 4.3.10 [OverrideBuiltins]
- 4.3.11 [PutForwards]
- 4.3.12 [Replaceable]
- 4.3.13 [SameObject]
- 4.3.14 [TreatNonObjectAsNull]
- 4.3.15 [TreatNullAs]
- 4.3.16 [Unforgeable]
- 4.4 Security
- 4.5 Overload resolution algorithm
- 4.6 Interfaces
- 4.7 Implements statements
- 4.8 Platform objects implementing interfaces
- 4.8.1 Indexed and named properties
- 4.8.2 The PlatformObjectGetOwnProperty abstract operation
- 4.8.3 Platform object [[GetOwnProperty]] method
- 4.8.4 Invoking a platform object indexed property setter
- 4.8.5 Invoking a platform object named property setter
- 4.8.6 Platform object [[Set]] method
- 4.8.7 Platform object [[DefineOwnProperty]] method
- 4.8.8 Platform object [[Delete]] method
- 4.8.9 Platform object [[Call]] method
- 4.8.10 Property enumeration
- 4.9 User objects implementing callback interfaces
- 4.10 Invoking callback functions
- 4.11 Exceptions
- 4.12 Exception objects
- 4.13 Creating and throwing exceptions
- 4.14 Handling exceptions
- 5. Common definitions
- 6. Extensibility
- 7. Referencing this specification
- 8. Acknowledgements
- A. IDL grammar
- B. References
1. Introduction
This section is informative.
Technical reports published by the W3C that include programming language interfaces have typically been described using the Object Management Group’s Interface Definition Language (IDL) [ OMGIDL]. The IDL provides a means to describe these interfaces in a language independent manner. Usually, additional language binding appendices are included in such documents which detail how the interfaces described with the IDL correspond to constructs in the given language.
However, the bindings in these specifications for the language most commonly used on the web, ECMAScript, are consistently specified with low enough precision as to result in interoperability issues. In addition, each specification must describe the same basic information, such as DOM interfaces described in IDL corresponding to properties on the ECMAScript global object, or the unsigned long IDL type mapping to the Number type in ECMAScript.
This specification defines an IDL language similar to OMG IDL for use by specifications that define interfaces for Web APIs. A number of extensions are given to the IDL to support common functionality that previously must have been written in prose. In addition, precise language bindings for ECMAScript Edition 6 are given.
1.1 Typographic conventions
The following typographic conventions are used in this document:
- Defining instances of terms: example term
- Links to terms defined in this document: example term
- Links to terms defined in other documents: example term
- Grammar symbols: ExampleGrammarSymbol
- IDL and ECMAScript types: ExampleType
- Code snippets:
a = b + obj.f() - Unicode characters: U+0030 DIGIT ZERO ("0")
- Extended attributes: [ExampleExtendedAttribute]
- Variable names in prose and algorithms: exampleVariableName.
- IDL informal syntax examples:
interface identifier { interface-members… };(Red text is used to highlight specific parts of the syntax discussed in surrounding prose.) - IDL grammar snippets:
(Each grammar rule is assigned a number for reference, shown on the left.)[5] ExampleGrammarSymbol → OtherSymbol "sometoken"
| AnotherSymbol
| ε - Non-normative notes:
Note
This is a note.
- Non-normative examples:
This is an example.
- Normative warnings:
Warning
This is a warning.
- Code blocks:
IDL
// This is an IDL code block. interface Example { attribute long something; };ECMAScript
// This is an ECMAScript code block. window.onload = function() { window.alert("loaded"); };
2. Conformance
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words MAY, MUST, MUST NOT, REQUIRED, SHALL, SHOULD, and SHOULD NOT are to be interpreted as described in [RFC2119].
The following conformance classes are defined by this specification:
- conforming set of IDL fragments
-
A set of IDL fragments is considered to be a conforming set of IDL fragments if, taken together, they satisfy all of the MUST-, REQUIRED- and SHALL-level criteria in this specification that apply to IDL fragments.
- conforming implementation
-
A user agent is considered to be a conforming implementation relative to a conforming set of IDL fragments if it satisfies all of the MUST-, REQUIRED- and SHALL-level criteria in this specification that apply to implementations for all language bindings that the user agent supports.
- conforming ECMAScript implementation
-
A user agent is considered to be a conforming ECMAScript implementation relative to a conforming set of IDL fragments if it satisfies all of the MUST-, REQUIRED- and SHALL-level criteria in this specification that apply to implementations for the ECMAScript language binding.
3. Interface definition language
This section describes a language, Web IDL, which can be used to define interfaces for APIs in the Web platform. A specification that defines Web APIs can include one or more IDL fragments that describe the interfaces (the state and behavior that objects can exhibit) for the APIs defined by that specification. An IDL fragment is a sequence of definitions that matches the Definitions grammar symbol. The set of IDL fragments that an implementation supports is not ordered. See Appendix A. for the complete grammar and an explanation of the notation used.
The different kinds of definitions that can appear in an IDL fragment are: interfaces, partial interface definitions, dictionaries, partial dictionary definitions, typedefs and implements statements. These are all defined in the following sections.
Each definition (matching Definition) can be preceded by a list of extended attributes (matching ExtendedAttributeList), which can control how the definition will be handled in language bindings. The extended attributes defined by this specification that are language binding agnostic are discussed in section 3.11 , while those specific to the ECMAScript language binding are discussed in section 4.3 .
[extended-attributes]
interface identifier {
interface-members…
};
| [1] | Definitions | → | ExtendedAttributeList Definition Definitions | ε |
| [2] | Definition | → | CallbackOrInterface | Partial | Dictionary | Enum | Typedef | ImplementsStatement |
| [3] | CallbackOrInterface | → | "callback" CallbackRestOrInterface | Interface |
The following is an example of an IDL fragment.
IDL
interface Paint { };
interface SolidColor : Paint {
attribute double red;
attribute double green;
attribute double blue;
};
interface Pattern : Paint {
attribute DOMString imageURL;
};
[Constructor]
interface GraphicalWindow {
readonly attribute unsigned long width;
readonly attribute unsigned long height;
attribute Paint currentPaint;
void drawRectangle(double x, double y, double width, double height);
void drawText(double x, double y, DOMString text);
};Here, four interfaces are being defined. The GraphicalWindow interface has two read only attributes, one writable attribute, and two operations defined on it. Objects that implement the GraphicalWindow interface will expose these attributes and operations in a manner appropriate to the particular language being used.
In ECMAScript, the attributes on the IDL interfaces will be exposed as accessor properties and the operations as Function-valued data properties on a prototype object for all GraphicalWindow objects; each ECMAScript object that implements GraphicalWindow will have that prototype object in its prototype chain.
The [Constructor] that appears on GraphicalWindow is an extended attribute. This extended attribute causes a constructor to exist in ECMAScript implementations, so that calling new GraphicalWindow() would return a new object that implemented the interface.
3.1 Names
Every interface, partial interface definition, dictionary, partial dictionary definition, enumeration, callback function and typedef (together called named definitions ) and every constant, attribute, and dictionary member has an identifier , as do some operations. The identifier is determined by an identifier token somewhere in the declaration:
-
For named definitions, the identifier token that appears directly after the
interface,dictionary,enumorcallbackkeyword determines the identifier of that definition.interface interface-identifier { interface-members… }; partial interface interface-identifier { interface-members… }; dictionary dictionary-identifier { dictionary-members… }; partial dictionary dictionary-identifier { dictionary-members… }; enum enumeration-identifier { enumeration-values… }; callback callback-identifier = callback-signature; -
For attributes,
typedefs and dictionary members, the final identifier token before the semicolon at the end of the declaration determines the identifier.
interface identifier { attribute type attribute-identifier; }; typedef type typedef-identifier; dictionary identifier { type dictionary-member-identifier; }; -
For constants, the identifier token before the equals sign determines the identifier.
const type constant-identifier = value; -
For operations, the
identifier token that appears after the return type but before the opening parenthesis (that is, one that is matched as part of the OptionalIdentifier grammar symbol in an OperationRest) determines the identifier of the operation. If there is no such identifier token, then the operation does not have an identifier.
return-type operation-identifier(arguments…);
Note
Operations can have no identifier when they are being used to declare a special kind of operation, such as a getter or setter.
For all of these constructs, the identifier is the value of the identifier token with any leading U+005F LOW LINE ("_") character (underscore) removed.
Note
A leading "_" is used to escape an identifier from looking like a reserved word so that, for example, an interface named “interface” can be defined. The leading "_" is dropped to unescape the identifier.
Operation arguments can take a slightly wider set of identifiers. In an operation declaration, the identifier of an argument is specified immediately after its type and is given by either an identifier token or by one of the keywords that match the ArgumentNameKeyword symbol. If one of these keywords is used, it need not be escaped with a leading underscore.
return-type operation-identifier(argument-type argument-identifier, …);
| [71] | ArgumentNameKeyword | → |
"attribute" | "callback" | "const" | "deleter" | "dictionary" | "enum" | "getter" | "implements" | "inherit" | "interface" | "iterable" | "legacycaller" | "partial" | "required" | "serializer" | "setter" | "static" | "stringifier" | "typedef" | "unrestricted" |
If an identifier token is used, then the identifier of the operation argument is the value of that token with any leading U+005F LOW LINE ("_") character (underscore) removed. If instead one of the ArgumentNameKeyword keyword token is used, then the identifier of the operation argument is simply that token.
The identifier of any of the abovementioned IDL constructs MUST NOT be “constructor”, “toString”, “toJSON”, or begin with a U+005F LOW LINE ("_") character. These are known as reserved identifiers .
Note
Further restrictions on identifier names for particular constructs may be made in later sections.
Within the set of IDL fragments that a given implementation supports, the identifier of every interface, dictionary, enumeration, callback function and typedef MUST NOT be the same as the identifier of any other interface, dictionary, enumeration, callback function or typedef.
Within an IDL fragment, a reference to a definition need not appear after the declaration of the referenced definition. References can also be made across IDL fragments.
Therefore, the following IDL fragment is valid:
IDL
interface B : A {
void f(SequenceOfLongs x);
};
interface A {
};
typedef sequence<long> SequenceOfLongs;The following IDL fragment demonstrates how identifiers are given to definitions and interface members.
IDL
// Typedef identifier: "number"
typedef double number;
// Interface identifier: "System"
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"
interface TextField {
// Attribute identifier: "const"
attribute boolean _const;
// Attribute identifier: "value"
attribute DOMString? _value;
};Note that while the second attribute on the TextField interface need not have been escaped with an underscore (because “value” is not a keyword in the IDL grammar), it is still unescaped to obtain the attribute’s identifier.
3.2 Interfaces
IDL fragments are used to describe object oriented systems. In such systems, objects are entities that have identity and which are encapsulations of state and behavior. An interface is a definition (matching Interface or "callback" Interface) that declares some state and behavior that an object implementing that interface will expose.
interface identifier {
interface-members…
};
An interface is a specification of a set of interface members (matching InterfaceMembers), which are the constants, attributes, operations and other declarations that appear between the braces in the interface declaration. Attributes describe the state that an object implementing the interface will expose, and operations describe the behaviors that can be invoked on the object. Constants declare named constant values that are exposed as a convenience to users of objects in the system.
Interfaces in Web IDL describe how objects that implement the interface behave. In bindings for object oriented languages, it is expected that an object that implements a particular IDL interface provides ways to inspect and modify the object's state and to invoke the behavior described by the interface.
An interface can be defined to inherit from another interface. If the identifier of the interface is followed by a U+003A COLON (":") character and an identifier, then that identifier identifies the inherited interface. An object that implements an interface that inherits from another also implements that inherited interface. The object therefore will also have members that correspond to the interface members from the inherited interface.
interface identifier : identifier-of-inherited-interface {
interface-members…
};
The order that members appear in has no significance except in the case of overloading.
Interfaces may specify an interface member that has the same name as one from an inherited interface. Objects that implement the derived interface will expose the member on the derived interface. It is language binding specific whether the overridden member can be accessed on the object.
Consider the following two interfaces.
IDL
interface A {
void f();
void g();
};
interface B : A {
void f();
void g(DOMString x);
};In the ECMAScript language binding, an instance of B will have a prototype chain that looks like the following:
[Object.prototype: the Object prototype object] ↑ [A.prototype: interface prototype object for A] ↑ [B.prototype: interface prototype object for B] ↑ [instanceOfB]
Calling instanceOfB.f() in ECMAScript will invoke the f defined on B. However, the f from A can still be invoked on an object that implements B by calling A.prototype.f.call(instanceOfB).
The inherited interfaces of a given interface A is the set of all interfaces that A inherits from, directly or indirectly. If A does not inherit from another interface, then the set is empty. Otherwise, the set includes the interface B that A inherits from and all of B’s inherited interfaces.
An interface MUST NOT be declared such that its inheritance hierarchy has a cycle. That is, an interface A cannot inherit from itself, nor can it inherit from another interface B that inherits from A, and so on.
Note that general multiple inheritance of interfaces is not supported, and objects also cannot implement arbitrary sets of interfaces. Objects can be defined to implement a single given interface A, which means that it also implements all of A’s inherited interfaces. In addition, an implements statement can be used to define that objects implementing an interface will always also implement another interface.
Each interface member can be preceded by a list of extended attributes (matching ExtendedAttributeList), which can control how the interface member will be handled in language bindings.
interface identifier {
[extended-attributes]
const type identifier = value;
[extended-attributes]
attribute type identifier;
[extended-attributes]
return-type identifier(arguments…);
};
A callback interface is an interface that uses the callback keyword at the start of its definition. Callback interfaces are ones that can be implemented by user objects and not by platform objects, as described in section 3.9 .
callback interface identifier {
interface-members…
};
Note
See also the similarly named callback function definition.
Callback interfaces MUST NOT inherit from any non-callback interfaces, and non-callback interfaces MUST NOT inherit from any callback interfaces. Callback interfaces MUST NOT have any consequential interfaces.
Static attributes and static operations MUST NOT be defined on a callback interface.
Warning
Specification authors SHOULD NOT define callback interfaces that have only a single operation, unless required to describe the requirements of existing APIs. Instead, a callback function SHOULD be used.
The definition of EventListener as a callback interface is an example of an existing API that needs to allow user objects with a given property (in this case “handleEvent”) to be considered to implement the interface. For new APIs, and those for which there are no compatibility concerns, using a callback function will allow only a Function object (in the ECMAScript language binding).
Note
Specification authors wanting to define APIs that take ECMAScript objects as “property bag” like function arguments are suggested to use dictionary types rather than callback interfaces.
For example, instead of this:
IDL
callback interface Options {
attribute DOMString? option1;
attribute DOMString? option2;
attribute long? option3;
};
interface A {
void doTask(DOMString type, Options options);
};to be used like this:
ECMAScript
var a = getA(); // Get an instance of A.
a.doTask("something", { option1: "banana", option3: 100 });instead write the following:
IDL
dictionary Options {
DOMString? option1;
DOMString? option2;
long? option3;
};
interface A {
void doTask(DOMString type, Options options);
};The IDL for interfaces can be split into multiple parts by using partial interface definitions (matching "partial" PartialInterface). The identifier of a partial interface definition MUST be the same as the identifier of an interface definition. All of the members that appear on each of the partial interfaces are considered to be members of the interface itself.
interface SomeInterface {
interface-members…
};
partial interface SomeInterface {
interface-members…
};
Note
Partial interface definitions are intended for use as a specification editorial aide, allowing the definition of an interface to be separated over more than one section of the document, and sometimes multiple documents.
The order of appearance of an interface definition and any of its partial interface definitions does not matter.
Note
A partial interface definition cannot specify that the interface inherits from another interface. Inheritance must be specified on the original interface definition.
Extended attributes can be specified on partial interface definitions, with some limitations. The following extended attributes MUST NOT be specified on partial interface definitions: [Constructor], [NamedConstructor], [NoInterfaceObject].
Note
The above list of extended attributes is all of those defined in this document that are applicable to interfaces except for [Exposed], [Global], [OverrideBuiltins], [PrimaryGlobal] and [Unforgeable].
Any extended attribute specified on a partial interface definition is considered to appear on the interface itself.
The relevant language binding determines how interfaces correspond to constructs in the language.
The following extended attributes are applicable to interfaces: [Constructor], [Exposed], [Global], [NamedConstructor], [NoInterfaceObject], [OverrideBuiltins]. [PrimaryGlobal], [Unforgeable].
| [3] | CallbackOrInterface | → | "callback" CallbackRestOrInterface | Interface |
| [4] | CallbackRestOrInterface | → | CallbackRest | Interface |
| [5] | Interface | → | "interface" identifier Inheritance "{" InterfaceMembers "}" ";" |
| [6] | Partial | → | "partial" PartialDefinition |
| [7] | PartialDefinition | → | PartialInterface | PartialDictionary |
| [8] | PartialInterface | → | "interface" identifier "{" InterfaceMembers "}" ";" |
| [9] | InterfaceMembers | → | ExtendedAttributeList InterfaceMember InterfaceMembers | ε |
| [10] | InterfaceMember | → | Const | Operation | Serializer | Stringifier | StaticMember | Iterable | ReadOnlyMember | ReadWriteAttribute |
| [18] | Inheritance | → | ":" identifier | ε |
The following IDL fragment demonstrates the definition of two mutually referential interfaces. Both Human and Dog inherit from Animal. Objects that implement either of those two interfaces will thus have a name attribute.
IDL
interface Animal {
attribute DOMString name;
};
interface Human : Animal {
attribute Dog? pet;
};
interface Dog : Animal {
attribute Human? owner;
};The following IDL fragment defines simplified versions of a few DOM interfaces, one of which is a callback interface.
IDL
interface Node {
readonly attribute DOMString nodeName;
readonly attribute Node? parentNode;
Node appendChild(Node newChild);
void addEventListener(DOMString type, EventListener listener);
};
callback interface EventListener {
void handleEvent(Event event);
};Since the EventListener interface is annotated callback interface, user objects can implement it:
ECMAScript
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 a user object to implement Node, however:
ECMAScript
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.3.2.1 Constants
A constant is a declaration (matching Const) used to bind a constant value to a name. Constants can appear on interfaces.
Warning
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. Specification authors who wish to define constants are strongly advised to discuss this on the public-script-coord@w3.org mailing list before proceeding.
const type identifier = value;
The identifier of a constant MUST NOT be the same as the identifier of another interface member defined on the same interface. The identifier also MUST NOT be “length”, “name” or “prototype”.
Note
These three names are the names of properties that exist on all Function objects.
The type of a constant (matching ConstType) MUST NOT be any type other than a primitive type or a nullable primitive type. If an identifier is used, it MUST reference a typedef whose type is a primitive type or a nullable primitive type.
The ConstValue part of a constant declaration gives the value of the constant, which can be one of the two boolean literal tokens (true and false), the null token, an
integer token, a float token, or one of the three special floating point constant values (-Infinity, Infinity and NaN).
Note
These values – in addition to strings and the empty sequence – can also be used to specify the
default value
of a dictionary member or of
an optional argument. Note that strings and the empty sequence [] cannot be used as the value of a
constant.
The value of the boolean literal tokens true and
false are the IDL boolean values
true and false.
The value of an integer token is an integer whose value is determined as follows:
- Let S be the sequence of characters matched by the integer token.
- Let sign be −1 if S begins with U+002D HYPHEN-MINUS ("-"), and 1 otherwise.
- Let base be the base of the number based on the characters that follow the optional leading U+002D HYPHEN-MINUS ("-") character:
- U+0030 DIGIT ZERO ("0"), U+0058 LATIN CAPITAL LETTER X ("X")
- U+0030 DIGIT ZERO ("0"), U+0078 LATIN SMALL LETTER X ("x")
- The base is 16.
- U+0030 DIGIT ZERO ("0")
- The base is 8.
- Otherwise
- The base is 10.
- Let number be the result of interpreting all remaining characters following the optional leading U+002D HYPHEN-MINUS ("-") character and any characters indicating the base as an integer specified in base base.
- Return sign × number.
The type of an integer token is the same as the type of the constant, dictionary member or optional argument it is being used as the value of. The value of the integer token MUST NOT lie outside the valid range of values for its type, as given in section 3.10 .
The value of a float token is either an IEEE 754 single-precision floating point number or an IEEE 754 double-precision floating point number, depending on the type of the constant, dictionary member or optional argument it is being used as the value for, determined as follows:
- Let S be the sequence of characters matched by the float token.
- Let value be the Mathematical Value that would be obtained if S were parsed as an ECMAScript NumericLiteral ( [ ECMA-262] , section 11.8.3).
- If the float token is being used as the value for a float or unrestricted float, then the value of the float token is the IEEE 754 single-precision floating point number closest to result. Otherwise, the float token is being used as the value for a double or unrestricted double, and the value of the float token is the IEEE 754 double-precision floating point number closest to result. [ IEEE-754]
The value of a constant value specified as
Infinity, -Infinity or NaN is either an IEEE 754 single-precision floating point number or an IEEE 754 double-precision floating point number, depending on the type of the constant, dictionary member or optional argument is is being used as the value for:
- Type unrestricted float, constant value
Infinity - The value is the IEEE 754 single-precision positive infinity value.
- Type unrestricted double, constant value
Infinity - 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 value
NaN - The value is the IEEE 754 single-precision NaN value with the bit pattern 0x7fc00000.
- Type unrestricted double, constant value
NaN - The value is the IEEE 754 double-precision NaN value with the bit pattern 0x7ff8000000000000.
The type of a float token is the same as the type of the constant, dictionary member or optional argument it is being used as the value of. The value of the
float token MUST NOT lie outside the valid range of values for its type, as given in
section 3.10 . Also, Infinity, -Infinity and NaN MUST NOT be used as the value of a float or double.
The value of the null token is the special
null value that is a member of the
nullable types. The type of the null token is the same as the type of the constant, dictionary member or optional argument it is being used as the value of.
If VT is the type of the value assigned to a constant, and DT is the type of the constant, dictionary member or optional argument itself, then these types MUST be compatible, which is the case if DT and VT are identical, or DT is a nullable type whose inner type is VT.
Constants are not associated with particular instances of the interface on which they appear. It is language binding specific whether constants are exposed on instances.
Note
The ECMAScript language binding does however allow constants to be accessed through objects implementing the IDL interfaces on which the constants are declared. For example, with the following IDL:
IDL
interface A {
const short rambaldi = 47;
};
the constant value can be accessed in ECMAScript
either as
A.rambaldi or instanceOfA.rambaldi.
The following extended attributes are applicable to constants: [Exposed].
| [26] | Const | → | "const" ConstType identifier "=" ConstValue ";" |
| [27] | ConstValue | → | BooleanLiteral | FloatLiteral | integer | "null" |
| [28] | BooleanLiteral | → | "true" | "false" |
| [29] | FloatLiteral | → | float | "-Infinity" | "Infinity" | "NaN" |
| [80] | ConstType | → | PrimitiveType Null | identifier Null |
The following IDL fragment demonstrates how constants of the above types can be defined.
IDL
interface Util {
const boolean DEBUG = false;
const octet LF = 10;
const unsigned long BIT_MASK = 0x0000fc00;
const double AVOGADRO = 6.022e23;
};3.2.2 Attributes
An attribute is an interface member (matching "inherit" ReadOnly AttributeRest, "static" ReadOnly AttributeRest, "stringifier" ReadOnly AttributeRest, or ReadOnly AttributeRest) that is used to declare data fields with a given type and identifier whose value can be retrieved and (in some cases) changed. There are two kinds of attributes:
- regular attributes, which are those used to declare that objects implementing the interface will have a data field member with the given identifier
attribute type identifier; - static attributes, which are used to declare attributes that are not associated with a particular object implementing the interface
static attribute type identifier;
If an attribute has no static keyword, then it declares a
regular attribute . Otherwise, it declares a static attribute.
The identifier of an attribute MUST NOT be the same as the identifier of another interface member defined on the same interface. The identifier of a static attribute MUST NOT be “prototype”.
The type of the attribute is given by the type (matching Type) that appears after the attribute keyword. If the Type is an
identifier or an identifier followed by ?, then the identifier MUST identify an interface, enumeration,
callback function or typedef.
The type of the attribute, after resolving typedefs, MUST NOT be a nullable or non-nullable version of any of the following types:
- a sequence type
- a dictionary
- a union type that has a nullable or non-nullable sequence type or dictionary as one of its flattened member types
The attribute is read only if the
readonly keyword is used before the attribute keyword. An object that implements the interface on which a read only attribute is defined will not allow assignment to that attribute. It is language binding specific whether assignment is simply disallowed by the language, ignored or an exception is thrown.
readonly attribute type identifier;
A regular attribute that is not read only can be declared to inherit its getter from an ancestor interface. This can be used to make a read only attribute in an ancestor interface be writable on a derived interface. An attribute
inherits its getter if its declaration includes inherit in the declaration. The read only attribute from which the attribute inherits its getter is the attribute with the same identifier on the closest ancestor interface of the one on which the inheriting attribute is defined. The attribute whose getter is being inherited MUST be of the same type as the inheriting attribute, and inherit
MUST NOT appear on a read only attribute or a static attribute.
interface Ancestor {
readonly attribute TheType theIdentifier;
};
interface Derived : Ancestor {
inherit attribute TheType theIdentifier;
};
When the stringifier keyword is used in a regular attribute declaration, it indicates that objects implementing the interface will be stringified to the value of the attribute. See
section 3.2.4.2 for details.
stringifier attribute DOMString identifier;
If an implementation attempts to get or set the value of an attribute on a user object (for example, when a callback object has been supplied to the implementation), and that attempt results in an exception being thrown, then, unless otherwise specified, that exception will be propagated to the user code that caused the implementation to access the attribute. Similarly, if a value returned from getting the attribute cannot be converted to an IDL type, then any exception resulting from this will also be propagated to the user code that resulted in the implementation attempting to get the value of the attribute.
The following extended attributes are applicable to regular and static attributes: [Clamp], [EnforceRange], [Exposed], [SameObject], [TreatNullAs].
The following extended attributes are applicable only to regular attributes: [LenientThis], [PutForwards], [Replaceable], [Unforgeable].
| [39] | ReadOnlyMember | → | "readonly" ReadOnlyMemberRest |
| [40] | ReadOnlyMemberRest | → | AttributeRest |
| [41] | ReadWriteAttribute | → | "inherit" ReadOnly AttributeRest | AttributeRest |
| [42] | AttributeRest | → | "attribute" Type AttributeName ";" |
| [43] | AttributeName | → | AttributeNameKeyword | identifier |
| [44] | AttributeNameKeyword | → | "required" |
| [45] | Inherit | → | "inherit" | ε |
| [46] | ReadOnly | → | "readonly" | ε |
The following IDL fragment demonstrates how attributes can be declared on an interface:
IDL
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;
};
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;
};3.2.3 Operations
An operation is an interface member (matching "static" OperationRest, "stringifier" OperationRest, "serializer" OperationRest, ReturnType OperationRest or SpecialOperation) that defines a behavior that can be invoked on objects implementing the interface. There are three kinds of operation:
- regular operations, which are those used to declare that objects implementing the
interface will have a method with the given identifier
return-type identifier(arguments…);
- special operations, which are used to declare special behavior on objects implementing the interface, such as object indexing and stringification
special-keywords… return-type identifier(arguments…); special-keywords… return-type (arguments…);
- static operations, which are used to declare operations that are not associated with a particular object implementing the interface
static return-type identifier(arguments…);
If an operation has an identifier but no static keyword, then it declares a regular operation . If the operation has one or more
special keywords used in its declaration (that is, any keyword matching
Special, or the stringifier keyword), then it declares a special operation. A single operation can declare both a regular operation and a special operation; see
section 3.2.4 for details on special operations.
If an operation has no identifier, then it MUST be declared to be a special operation using one of the special keywords.
The identifier of a regular operation or static operation MUST NOT be the same as the identifier of a constant or attribute defined on the same interface. The identifier of a static operation MUST NOT be “prototype”.
Note
The identifier can be the same as that of another operation on the interface, however. This is how operation overloading is specified.
The identifier of a static operation also MUST NOT be the same as the identifier of a regular operation defined on the same interface.
The return type of the operation is given by the type (matching ReturnType) that appears before the operation’s optional identifier. A return type of void indicates that the operation returns no value. If the return type is an
identifier followed by ?, then the identifier MUST identify an interface, dictionary, enumeration,
callback function or typedef.
An operation’s arguments (matching ArgumentList) are given between the parentheses in the declaration. Each individual argument is specified as a type (matching Type) followed by an identifier (matching ArgumentName).
Note
For expressiveness, the identifier of an operation argument can also be specified as one of the keywords matching the ArgumentNameKeyword symbol without needing to escape it.
If the Type of an operation argument is an identifier followed by ?, then the identifier MUST identify an interface,
enumeration, callback function or typedef. If the operation argument type is an identifier not followed by ?, then the identifier MUST identify any one of those definitions or a dictionary.
return-type identifier(type identifier, type identifier, …);
The identifier of each argument MUST NOT be the same as the identifier of another argument in the same operation declaration.
Each argument can be preceded by a list of extended attributes (matching ExtendedAttributeList), which can control how a value passed as the argument will be handled in language bindings.
return-type identifier([extended-attributes] type identifier, [extended-attributes] type identifier, …);
The following IDL fragment demonstrates how regular operations can be declared on an interface:
IDL
interface Dimensions {
attribute unsigned long width;
attribute unsigned long height;
};
interface Button {
// An operation that takes no arguments and returns a boolean.
boolean isMouseOver();
// Overloaded operations.
void setDimensions(Dimensions size);
void setDimensions(unsigned long width, unsigned long height);
};
An operation is considered to be variadic if the final argument uses the ... token just after the argument type. Declaring an operation to be variadic indicates that the operation can be invoked with any number of arguments after that final argument. Those extra implied formal arguments are of the same type as the final explicit argument in the operation declaration. The final argument can also be omitted when invoking the operation. An argument MUST NOT be declared with the ... token unless it is the final argument in the operation’s argument list.
return-type identifier(type... identifier); return-type identifier(type identifier, type... identifier);
Extended attributes that take an argument list ([Constructor] and
[NamedConstructor], of those defined in this specification) and callback functions are also considered to be variadic when the ... token is used in their argument lists.
The following IDL fragment defines an interface that has two variadic operations:
IDL
interface IntegerSet {
readonly attribute unsigned long cardinality;
void union(long... ints);
void intersection(long... ints);
};In the ECMAScript binding, variadic operations are implemented by functions that can accept the subsequent arguments:
ECMAScript
var s = getIntegerSet(); // Obtain an instance of IntegerSet.
s.union(); // Passing no arguments corresponding to 'ints'.
s.union(1, 4, 7); // Passing three arguments corresponding to 'ints'.A binding for a language that does not support variadic functions might specify that an explicit array or list of integers be passed to such an operation.
An argument is considered to be an optional argument if it is declared with the optional keyword. The final argument of a variadic operation is also considered to be an optional argument. Declaring an argument to be optional indicates that the argument value can be omitted when the operation is invoked. The final argument in an operation MUST NOT explicitly be declared to be optional if the operation is variadic.
return-type identifier(type identifier, optional type identifier);
Optional arguments can also have a default value specified. If the argument’s identifier is followed by a U+003D EQUALS SIGN ("=") and a value (matching DefaultValue), then that gives the optional argument its default value. The implicitly optional final argument of a variadic operation MUST NOT have a default value specified. The default value is the value to be assumed when the operation is called with the corresponding argument omitted.
return-type identifier(type identifier, optional type identifier = value);
Warning
It is strongly suggested not to use default value of true for boolean-typed arguments, as this can be confusing for authors who might otherwise expect the default conversion of undefined to be used (i.e., false).
If the type of an argument is a dictionary type or a union type that has a dictionary type as one of its flattened member types, and that dictionary type and its ancestors have no required members, and the argument is either the final argument or is followed only by optional arguments, then the argument MUST be specified as optional. Such arguments are always considered to have a default value of an empty dictionary, unless otherwise specified.
Note
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.
Dictionary types cannot have a default value specified explicitly, so the “unless otherwise specified” clause above can only be invoked for a union type that has a dictionary type as one of its flattened member types.
When a boolean literal token (true or false), the null token, an integer token, a
float token or one of the three special floating point literal values (Infinity,
-Infinity or NaN) is used as the
default value, it is interpreted in the same way as for a constant.
Optional argument default values can also be specified using a string token, whose value is a string type determined as follows:
- Let S be the sequence of Unicode scalar values matched by the string token with its leading and trailing U+0022 QUOTATION MARK ('"') characters removed.
- Depending on the type of the argument:
- DOMString
- an enumeration type
- The value of the string token is the sequence of 16 bit unsigned integer code units (hereafter referred to just as code units ) corresponding to the UTF-16 encoding of S.
- ByteString
- The value of the string token is the sequence of 8 bit unsigned integer code units corresponding to the UTF-8 encoding of S.
- USVString
- The value of the string token is S.
If the type of the optional argument is an enumeration, then its default value if specified MUST be one of the enumeration’s values.
Optional argument default values can also be specified using the two token value [], which represents an empty sequence value. The type of this value is the same the type of the optional argument it is being used as the default value of. That type
MUST be a
sequence type or a
nullable type.
The following IDL fragment defines an interface with a single operation that can be invoked with two different argument list lengths:
IDL
interface ColorCreator {
object createColor(double v1, double v2, double v3, optional double alpha);
};It is equivalent to an interface that has two overloaded operations:
IDL
interface ColorCreator {
object createColor(double v1, double v2, double v3);
object createColor(double v1, double v2, double v3, double alpha);
};If an implementation attempts to invoke an operation on a user object (for example, when a callback object has been supplied to the implementation), and that attempt results in an exception being thrown, then, unless otherwise specified, that exception will be propagated to the user code that caused the implementation to invoke the operation. Similarly, if a value returned from invoking the operation cannot be converted to an IDL type, then any exception resulting from this will also be propagated to the user code that resulted in the implementation attempting to invoke the operation.
The following extended attributes are applicable to operations: [Exposed], [NewObject], [TreatNullAs], [Unforgeable].
The following extended attributes are applicable to operation arguments: [Clamp], [EnforceRange], [TreatNullAs].
| [17] | DefaultValue | → | ConstValue | string | "[" "]" |
| [47] | Operation | → | ReturnType OperationRest | SpecialOperation |
| [48] | SpecialOperation | → | Special Specials ReturnType OperationRest |
| [49] | Specials | → | Special Specials | ε |
| [50] | Special | → | "getter" | "setter" | "deleter" | "legacycaller" |
| [51] | OperationRest | → | OptionalIdentifier "(" ArgumentList ")" ";" |
| [52] | OptionalIdentifier | → | identifier | ε |
| [53] | ArgumentList | → | Argument Arguments | ε |
| [54] | Arguments | → | "," Argument Arguments | ε |
| [55] | Argument | → | ExtendedAttributeList OptionalOrRequiredArgument |
| [56] | OptionalOrRequiredArgument | → | "optional" Type ArgumentName Default | Type Ellipsis ArgumentName |
| [57] | ArgumentName | → | ArgumentNameKeyword | identifier |
| [58] | Ellipsis | → | "..." | ε |
| [71] | ArgumentNameKeyword | → |
"attribute" | "callback" | "const" | "deleter" | "dictionary" | "enum" | "getter" | "implements" | "inherit" | "interface" | "iterable" | "legacycaller" | "partial" | "required" | "serializer" | "setter" | "static" | "stringifier" | "typedef" | "unrestricted" |
| [89] | ReturnType | → | Type | "void" |
3.2.4 Special operations
A special operation is a declaration of a certain kind of special behavior on objects implementing the interface on which the special operation declarations appear. Special operations are declared by using one or more special keywords in an operation declaration.
There are six kinds of special operations. The table below indicates for a given kind of special operation what special keyword is used to declare it and what the purpose of the special operation is:
| Special operation | Keyword | Purpose |
|---|---|---|
| Getters | getter |
Defines behavior for when an object is indexed for property retrieval. |
| Setters | setter |
Defines behavior for when an object is indexed for property assignment or creation. |
| Deleters | deleter |
Defines behavior for when an object is indexed for property deletion. |
| Legacy callers | legacycaller |
Defines behavior for when an object is called as if it were a function. |
| Stringifiers | stringifier |
Defines how an object is converted into a DOMString. |
| Serializers | serializer |
Defines how an object is converted into a serialized form. |
Not all language bindings support all of the six kinds of special object behavior. When special operations are declared using operations with no identifier, then in language bindings that do not support the particular kind of special operations there simply will not be such functionality.
The following IDL fragment defines an interface with a getter and a setter:
IDL
interface Dictionary {
readonly attribute unsigned long propertyCount;
getter double (DOMString propertyName);
setter void (DOMString propertyName, double propertyValue);
};In language bindings that do not support property getters and setters, objects implementing Dictionary will not have that special behavior.
Defining a special operation with an identifier is equivalent to separating the special operation out into its own declaration without an identifier. This approach is allowed to simplify prose descriptions of an interface’s operations.
The following two interfaces are equivalent:
IDL
interface Dictionary {
readonly attribute unsigned long propertyCount;
getter double getProperty(DOMString propertyName);
setter void setProperty(DOMString propertyName, double propertyValue);
};IDL
interface Dictionary {
readonly attribute unsigned long propertyCount;
double getProperty(DOMString propertyName);
void setProperty(DOMString propertyName, double propertyValue);
getter double (DOMString propertyName);
setter void (DOMString propertyName, double propertyValue);
};A given special keyword MUST NOT appear twice on an operation.
Getters and setters come in two varieties: ones that take a DOMString as a property name, known as named property getters and named property setters , and ones that take an unsigned long as a property index, known as indexed property getters and indexed property setters . There is only one variety of deleter: named property deleters . See section 3.2.4.4 and section 3.2.4.5 for details.
On a given interface, there MUST exist at most one stringifier, at most one serializer, at most one named property deleter, and at most one of each variety of getter and setter. Multiple legacy callers can exist on an interface to specify overloaded calling behavior.
If an interface has a setter of a given variety, then it MUST also have a getter of that variety. If it has a named property deleter, then it MUST also have a named property getter.
Special operations declared using operations MUST NOT be variadic nor have any optional arguments.
Special operations MUST NOT be declared on callback interfaces.
If an object implements more than one interface that defines a given special operation, then it is undefined which (if any) special operation is invoked for that operation.
3.2.4.1 Legacy callers
When an interface has one or more
legacy callers, it indicates that objects that implement the interface can be called as if they were functions. As mentioned above, legacy callers can be specified using an operation declared with the legacycaller keyword.
legacycaller return-type identifier(arguments…); legacycaller return-type (arguments…);
If multiple legacy callers are specified on an interface, overload resolution is used to determine which legacy caller is invoked when the object is called as if it were a function.
Legacy callers MUST NOT be defined to return a promise type.
Warning
Legacy callers are universally recognised as an undesirable feature. They exist only so that legacy Web platform features can be specified. Legacy callers SHOULD NOT be used in specifications unless required to specify the behavior of legacy APIs, and even then this should be discussed on the public-script-coord@w3.org mailing list before proceeding.
The following IDL fragment defines an interface with a legacy caller.
IDL
interface NumberQuadrupler {
// This operation simply returns four times the given number x.
legacycaller double compute(double x);
};An ECMAScript implementation supporting this interface would allow a platform object that implements NumberQuadrupler to be called as a function:
ECMAScript
var f = getNumberQuadrupler(); // Obtain an instance of NumberQuadrupler.
f.compute(3); // This evaluates to 12.
f(3); // This also evaluates to 12.3.2.4.2 Stringifiers
When an interface has a
stringifier, it indicates that objects that implement the interface have a non-default conversion to a string. As mentioned above, stringifiers can be specified using an operation declared with the stringifier keyword.
stringifier DOMString identifier(); stringifier DOMString ();
If an operation used to declare a stringifier does not have an identifier, then prose accompanying the interface MUST define the stringification behavior of the interface. If the operation does have an identifier, then the object is converted to a string by invoking the operation to obtain the string.
Stringifiers declared with operations MUST be declared to take zero arguments and return a DOMString.
As a shorthand, if the stringifier keyword is declared using an operation with no identifier, then the operation’s return type and argument list can be omitted.
stringifier;
The following two interfaces are equivalent:
IDL
interface A {
stringifier DOMString ();
};IDL
interface A {
stringifier;
};
The stringifier keyword can also be placed on an attribute. In this case, the string to convert the object to is the value of the attribute. The stringifier keyword
MUST NOT be placed on an attribute unless it is declared to be of type DOMString or USVString. It also MUST NOT be placed on a static attribute.
stringifier attribute DOMString identifier;
The following IDL fragment defines an interface that will stringify to the value of its name attribute:
IDL
[Constructor]
interface Student {
attribute unsigned long id;
stringifier attribute DOMString name;
};In the ECMAScript binding, using a Student object in a context where a string is expected will result in the value of the object’s “name” property being used:
ECMAScript
var s = new Student();
s.id = 12345678;
s.name = '周杰倫';
var greeting = 'Hello, ' + s + '!'; // Now greeting == 'Hello, 周杰倫!'.The following IDL fragment defines an interface that has custom stringification behavior that is not specified in the IDL itself.
IDL
[Constructor]
interface Student {
attribute unsigned long id;
attribute DOMString? familyName;
attribute DOMString givenName;
stringifier DOMString ();
};Thus, prose is required to explain the stringification behavior, such as the following paragraph:
Objects that implement the Student interface must stringify as follows. If the value of the familyName attribute is null, the stringification of the object is the value of the givenName attribute. Otherwise, if the value of the familyName attribute is not null, the stringification of the object is the concatenation of the value of the givenName attribute, a single space character, and the value of the familyName attribute.
An ECMAScript implementation of the IDL would behave as follows:
ECMAScript
var s = new Student();
s.id = 12345679;
s.familyName = 'Smithee';
s.givenName = 'Alan';
var greeting = 'Hi ' + s; // Now greeting == 'Hi Alan Smithee'.3.2.4.3 Serializers
Warning
The NodeFilterSerializers will be simplified soon, please see discussions in Issue 188
When an interface has a
serializer, it indicates that objects provide a way for them to be converted into a serialized form. Serializers can be declared using the serializer keyword:
serializer;
Prose accompanying an interface that declares a serializer in this way MUST define the serialization behavior of the interface. Serialization behavior is defined as returning a serialized value of one of the following types:
- a map of key–value pairs, where the keys are DOMString values (unique in the map) and the values are serialized values
- a list of serialized values
- a DOMString value
- an unrestricted double value
- a boolean value
- the null value
How the serialization behavior is made available on an object in a language binding, and how exactly the abstract serialized value is converted into an appropriate concrete value, is language binding specific.
Note
In the ECMAScript language binding,
serialization behavior is exposed as a toJSON method which returns the
serialized value converted into an ECMAScript value that can be serialized to JSON by the
JSON.stringify function. See section 4.6.8.2 for details.
Serialization behavior can also be specified directly in IDL, rather than separately as prose. This is done by following the serializer keyword with a U+003D EQUALS SIGN ("=") character and a serialization pattern , which can take one of the following six forms:
-
A map with entries corresponding to zero or more attributes from the interface, and optionally attributes from an inherited interface:
serializer = { attribute-identifier, attribute-identifier, … }; serializer = { inherit, attribute-identifier, attribute-identifier, … };Each identifier MUST be the identifier of an attribute declared on the interface. The identified attributes all MUST have a serializable type.
The
inheritkeyword MUST NOT be used unless the interface inherits from another that defines a serializer, and the closest such interface defines its serializer using this serialization pattern form or the following form (i.e.{ attribute }).The serialization behavior for this form of serialization pattern is as follows:
- Let map be an empty map.
- If the
inheritkeyword was used, then set map to be the result of the serialization behavior of the closest inherited interface that declares a serializer. - For each attribute identifier i in the serialization pattern, in order:
- Remove any entry in map with key name i.
- Let V be the value of the attribute with identifier i.
- Add an entry to map whose key name is i and whose value is result of converting V to a serialized value.
- Return map.
-
A map with entries corresponding to all attributes from the interface that have a serializable type, and optionally attributes from an inherited interface:
serializer = { attribute }; serializer = { inherit, attribute };The
inheritkeyword MUST NOT be used unless the interface inherits from another that defines a serializer, and the closest such interface defines its serializer using this serialization pattern form or the previous form.The serialization behavior for this form of serialization pattern is as follows:
- Let map be an empty map.
- If the
inheritkeyword was used, then set map to be the result of the serialization behavior of the closest inherited interface that declares a serializer. - For each identifier i of an attribute on the interface whose type is a serializable type, in the order they appear on the interface:
- Remove any entry in map with key name i.
- Let V be the value of the attribute with identifier i.
- Add an entry to map whose key name is i and whose value is result of converting V to a serialized value.
- Return map.
-
A map with entries corresponding to the named properties:
serializer = { getter };This form MUST NOT be used unless the interface or one it inherits from supports named properties and the return type of the named property getter is a serializable type.
The serialization behavior for this form of serialization pattern is as follows:
- Let map be an empty map.
- For each supported property name n on the object, in order:
- Let V be the value of the named property with name n.
- Add an entry to map whose key name is i and whose value is result of converting V to a serialized value.
- Return map.
-
A list of value of zero or more attributes on the interface:
serializer = [ attribute-identifier, attribute-identifier, … ];
Each identifier MUST be the identifier of an attribute declared on the interface. The identified attributes all MUST have a serializable type.
The serialization behavior for this form of serialization pattern is as follows:
- Let list be an empty list.
- For each attribute identifier i in the serialization pattern:
- Let V be the value of the attribute with identifier i.
- Append to list the value that is the result of converting V to a serialized value.
- Return list.
-
A list with entries corresponding to the indexed properties:
serializer = [ getter ];
This form MUST NOT be used unless the interface or one it inherits from supports indexed properties and the return type of the indexed property getter is a serializable type.
The serialization behavior for this form of serialization pattern is as follows:
- Let list be an empty list.
- Let i be 0.
- While i is less than or equal to the greatest supported property index on the object:
- Let V be the value of the indexed property with index i if i is a supported property index, or null otherwise.
- Append to list the value that is the result of converting V to a serialized value.
- Set i to i + 1.
- Return map.
-
A single attribute:
serializer = attribute-identifier;
The identifier MUST be the identifier of an attribute declared on the interface, and this attribute MUST have a serializable type.
The serialization behavior for this form of serialization pattern is as follows:
- Let V be the value of the attribute with the specified identifier.
- Return the result of converting V to a serialized value.
Note
Entries are added to maps in a particular order so that in the ECMAScript language binding it is defined what order properties are added to objects. This is because this order can influence the serialization that JSON.stringify can produce.
The list of serializable types and how they are converted to serialized values is as follows:
- long long
- converted by choosing the closest equivalent double value (as when converting a long long to an ECMAScript Number value)
- unsigned long long
- converted by choosing the closest equivalent double value (as when converting a unsigned long long to an ECMAScript Number value)
- any other integer type
- float
- converted by choosing the equivalent double value
- double
- boolean
- DOMString
- the same value of the respective type
- an enumeration type
- the equivalent DOMString value
- a USVString
- the DOMString produced by encoding the given sequence of Unicode scalar values in UTF-16
- a ByteString
- the equivalent DOMString value where each code unit has the same value as the corresponding byte value
- a nullable serializable type
- converted to null if that is its value, otherwise converted as per its inner type
- a union type where all of its member types are serializable types
- converted as per its specific type
- a sequence type that has a serializable type as its element type
- converted to a list where each element is the result of converting its corresponding sequence element to a serialized value
- a dictionary where all of its members have serializable types
- converted to a map consisting of an entry for each dictionary member that is present, where the entry’s key is the identifier of the dictionary member and its value is the result of converting the dictionary member’s value to a serializable type
- an interface type that has a serializer
- converted by invoking the object’s serializer
Serializers can also be specified using an operation with the serializer keyword:
serializer type identifier();
Serializers declared with operations MUST be declared to take zero arguments and return a serializable type.
The serialization behavior of the interface with a serializer declared with an operation is the result of converting the value returned from invoking the operation to a serialized value.
| [30] | Serializer | → | "serializer" SerializerRest |
| [31] | SerializerRest | → | OperationRest | "=" SerializationPattern ";" | ";" |
| [32] | SerializationPattern | → | "{" SerializationPatternMap "}" | "[" SerializationPatternList "]" | identifier |
| [33] | SerializationPatternMap | → | "getter" | "inherit" Identifiers | identifier Identifiers | ε |
| [34] | SerializationPatternList | → | "getter" | identifier Identifiers | ε |
| [91] | Identifiers | → | "," identifier Identifiers | ε |
The following IDL fragment defines an interface Transaction that has a serializer defines in prose:
IDL
interface Transaction {
readonly attribute Account from;
readonly attribute Account to;
readonly attribute double amount;
readonly attribute DOMString description;
readonly attribute unsigned long number;
serializer;
};
interface Account {
DOMString name;
unsigned long number;
};The serializer could be defined as follows:
The serialization behavior of the Transaction interface is to run the following algorithm, where O is the object that implements Transaction:
- Let map be an empty map.
- Add an entry to map whose key is “from” and whose value is the serialized value of the
numberattribute on the Account object referenced by thefromattribute on O.- Add an entry to map whose key is “to” and whose value is the serialized value of the
numberattribute on the Account object referenced by thefromattribute on O.- For both of the attributes
amountanddescription, add an entry to map whose key is the identifier of the attribute and whose value is the serialized value of the value of the attribute on O.- Return map.
If it was acceptable for Account objects to be serializable on their own, then serialization patterns could be used to avoid having to define the serialization behavior in prose:
IDL
interface Transaction {
readonly attribute Account from;
readonly attribute Account to;
readonly attribute double amount;
readonly attribute DOMString description;
readonly attribute unsigned long number;
serializer = { from, to, amount, description };
};
interface Account {
DOMString name;
unsigned long number;
serializer = number;
};
In the ECMAScript language binding, there would exist a toJSON method on
Transaction objects:
ECMAScript
// Get an instance of Transaction.
var txn = getTransaction();
// Evaluates to an object like this:
// {
// from: 1234
// to: 5678
// amount: 110.75
// description: "dinner"
// }
txn.toJSON();
// Evaluates to a string like this:
// '{"from":1234,"to":5678,"amount":110.75,"description":"dinner"}'
JSON.stringify(txn);3.2.4.4 Indexed properties
An interface that defines an indexed property getter is said to support indexed properties .
If an interface supports indexed properties, then the interface definition MUST be accompanied by a description of what indices the object can be indexed with at any given time. These indices are called the supported property indices .
Indexed property getters MUST be declared to take a single unsigned long argument. Indexed property setters MUST be declared to take two arguments, where the first is an unsigned long.
getter type identifier(unsigned long identifier); setter type identifier(unsigned long identifier, type identifier); getter type (unsigned long identifier); setter type (unsigned long identifier, type identifier);
The following requirements apply to the definitions of indexed property getters and setters:
- If an indexed property getter was specified using an operation with an identifier, then the value returned when indexing the object with a given supported property index is the value that would be returned by invoking the operation, passing the index as its only argument. If the operation used to declare the indexed property getter did not have an identifier, then the interface definition must be accompanied by a description of how to determine the value of an indexed property for a given index.
- If an indexed property setter was specified using an operation with an identifier, then the behavior that occurs when indexing the object for property assignment with a given supported property index and value is the same as if the operation is invoked, passing the index as the first argument and the value as the second argument. If the operation used to declare the indexed property setter did not have an identifier, then the interface definition must be accompanied by a description of how to set the value of an existing indexed property and how to set the value of a new indexed property for a given property index and value.
Note
Note that if an indexed property getter or setter is specified using an operation with an identifier, then indexing an object with an integer that is not a supported property index does not necessarily elicit the same behavior as invoking the operation with that index. The actual behavior in this case is language binding specific.
In the ECMAScript language binding, a regular property lookup is done. For example, take the following IDL:
IDL
interface A {
getter DOMString toWord(unsigned long index);
};Assume that an object implementing A has supported property indices in the range 0 ≤ index < 2. Also assume that toWord is defined to return its argument converted into an English word. The behavior when invoking the operation with an out of range index is different from indexing the object directly:
ECMAScript
var a = getA();
a.toWord(0); // Evalautes to "zero".
a[0]; // Also evaluates to "zero".
a.toWord(5); // Evaluates to "five".
a[5]; // Evaluates to undefined, since there is no property "5".The following IDL fragment defines an interface OrderedMap which allows retrieving and setting values by name or by index number:
IDL
interface OrderedMap {
readonly attribute unsigned long size;
getter any getByIndex(unsigned long index);
setter void setByIndex(unsigned long index, any value);
getter any get(DOMString name);
setter void set(DOMString name, any value);
};
Since all of the special operations are declared using operations with identifiers, the only additional prose that is necessary is that which describes what keys those sets have. Assuming that the get() operation is defined to return null if an attempt is made to look up a non-existing entry in the
OrderedMap, then the following two sentences would suffice:
An object map implementing OrderedMap supports indexed properties with indices in the range 0 ≤ index <
map.size.Such objects also support a named property for every name that, if passed to
get(), would return a non-null value.
As described in section 4.8 , an ECMAScript implementation would create properties on a platform object implementing OrderedMap that correspond to entries in both the named and indexed property sets. These properties can then be used to interact with the object in the same way as invoking the object’s methods, as demonstrated below:
ECMAScript
// Assume map is a 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")
3.2.4.5 Named properties
An interface that defines a named property getter is said to support named properties .
If an interface supports named properties, then the interface definition MUST be accompanied by a description of the ordered set of names that can be used to index the object at any given time. These names are called the supported property names .
Named property getters and deleters MUST be declared to take a single DOMString argument. Named property setters MUST be declared to take two arguments, where the first is a DOMString.
getter type identifier(DOMString identifier); setter type identifier(DOMString identifier, type identifier); deleter type identifier(DOMString identifier); getter type (DOMString identifier); setter type (DOMString identifier, type identifier); deleter type (DOMString identifier);
The following requirements apply to the definitions of named property getters, setters and deleters:
- If a named property getter was specified using an operation with an identifier, then the value returned when indexing the object with a given supported property name is the value that would be returned by invoking the operation, passing the name as its only argument. If the operation used to declare the named property getter did not have an identifier, then the interface definition must be accompanied by a description of how to determine the value of a named property for a given property name.
- If a named property setter was specified using an operation with an identifier, then the behavior that occurs when indexing the object for property assignment with a given supported property name and value is the same as if the operation is invoked, passing the name as the first argument and the value as the second argument. If the operation used to declare the named property setter did not have an identifier, then the interface definition must be accompanied by a description of how to set the value of an existing named property and how to set the value of a new named property for a given property name and value.
- If a named property deleter was specified using an operation with an identifier, then the behavior that occurs when indexing the object for property deletion with a given supported property name is the same as if the operation is invoked, passing the name as the only argument. If the operation used to declare the named property deleter did not have an identifier, then the interface definition must be accompanied by a description of how to delete an existing named property for a given property name.
Note
As with indexed properties, if an named property getter, setter or deleter is specified using an operation with an identifier, then indexing an object with a name that is not a supported property name does not necessarily elicit the same behavior as invoking the operation with that name; the behavior is language binding specific.
3.2.5 Static attributes and operations
Static attributes and
static operations are ones that are not associated with a particular instance of the
interface on which it is declared, and is instead associated with the interface itself. Static attributes and operations are declared by using the
static keyword in their declarations.
It is language binding specific whether it is possible to invoke a static operation or get or set a static attribute through a reference to an instance of the interface.
Static attributes and operations MUST NOT be declared on callback interfaces.
The following IDL fragment defines an interface Circle that has a static operation declared on it:
IDL
interface Point { /* ... */ };
interface Circle {
attribute double cx;
attribute double cy;
attribute double radius;
static readonly attribute long triangulationCount;
static Point triangulate(Circle c1, Circle c2, Circle c3);
};
In the ECMAScript language binding, the Function object for
triangulate and the accessor property for triangulationCount will exist on the interface object for Circle:
ECMAScript
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);3.2.6 Overloading
If a regular operation or static operation defined on an interface has an identifier that is the same as the identifier of another operation on that interface of the same kind (regular or static), then the operation is said to be overloaded . When the identifier of an overloaded operation is used to invoke one of the operations on an object that implements the interface, the number and types of the arguments passed to the operation determine which of the overloaded operations is actually invoked. If an interface has multiple legacy callers defined on it, then those legacy callers are also said to be overloaded. In the ECMAScript language binding, constructors can be overloaded too. There are some restrictions on the arguments that overloaded operations, legacy callers and constructors can be specified to take, and in order to describe these restrictions, the notion of an effective overload set is used.
Operations and legacy callers MUST NOT be overloaded across interface and partial interface definitions.
Note
For example, the overloads for both f and g are disallowed:
IDL
interface A {
void f();
};
partial interface A {
void f(double x);
void g();
};
partial interface A {
void g(DOMString x);
};Note that the [Constructor] and [NamedConstructor] extended attributes are disallowed from appearing on partial interface definitions, so there is no need to also disallow overloading for constructors.
An effective overload set represents the allowable invocations for a particular operation, constructor (specified with [Constructor] or [NamedConstructor]), legacy caller or callback function. The algorithm to compute an effective overload set operates on one of the following six types of IDL constructs, and listed with them below are the inputs to the algorithm needed to compute the set.
- For regular operations
- For static operations
-
- the interface on which the operations are to be found
- the identifier of the operations
- the number of arguments to be passed
- For legacy callers
-
- the interface on which the legacy callers are to be found
- the number of arguments to be passed
- For constructors
-
- the interface on which the [Constructor] extended attributes are to be found
- the number of arguments to be passed
- For named constructors
-
- the interface on which the [NamedConstructor] extended attributes are to be found
- the identifier of the named constructors
- the number of arguments to be passed
- For callback functions
-
- the callback function
- the number of arguments to be passed
An effective overload set is used, among other things, to determine whether there are ambiguities in the overloaded operations, constructors and callers specified on an interface.
The elements of an effective overload set are tuples of the form < callable, type list, optionality list>. If the effective overload set is for regular operations, static operations or legacy callers, then callable is an operation; if it is for constructors or named constructors, then callable is an extended attribute; and if it is for callback functions, then callable is the callback function itself. In all cases, type list is a list of IDL types, and optionality list is a list of three possible optionality values – “required”, “optional” or “variadic” – indicating whether the argument at a given index was declared as being optional or corresponds to a variadic argument. Each tuple represents an allowable invocation of the operation, constructor, legacy caller or callback function with an argument value list of the given types. Due to the use of optional arguments and variadic operations and constructors, there may be multiple entries in an effective overload set identifying the same operation or constructor.
The algorithm below describes how to compute an effective overload set. The following input variables are used, if they are required:
- the identifier of the operation or named constructor is A
- the argument count is N
- the interface is I
- the callback function is C
Whenever an argument of an extended attribute is mentioned, it is referring to an argument of the extended attribute’s named argument list.
- Initialize S to ∅.
- Let F be a set with elements as follows, according to the kind of effective overload set:
- For regular operations
- The elements of F are the regular operations with identifier A defined on interface I.
- For static operations
- The elements of F are the static operations with identifier A defined on interface I.
- For constructors
- The elements of F are the [Constructor] extended attributes on interface I.
- For named constructors
- The elements of F are the [NamedConstructor] extended attributes on interface I whose named argument lists’ identifiers are A.
- For legacy callers
- The elements of F are the legacy callers defined on interface I.
- For callback functions
- The single element of F is the callback function itself, C.
-
Let maxarg be the maximum number of arguments the operations, constructor extended attributes or callback functions in F are declared to take. For variadic operations and constructor extended attributes, the argument on which the ellipsis appears counts as a single argument.
Note
So
void f(long x, long... y);is considered to be declared to take two arguments. - Let m be the maximum of maxarg and N.
- For each operation, extended attribute or callback function X in F:
- Let n be the number of arguments X is declared to take.
- Let t0..n−1 be a list of types, where ti is the type of X’s argument at index i.
- Let o0..n−1 be a list of optionality values, where oi is “variadic” if X’s argument at index i is a final, variadic argument, “optional” if the argument is optional, and “required” otherwise.
- Add to S the tuple <X, t0..n−1, o0..n−1>.
- If X is declared to be variadic, then:
- Add to S the tuple <X, t0..n−2, o0..n−2>.
Note
This leaves off the final, variadic argument.
- For every integer i, such that n ≤ i ≤ m−1:
- Let u0..i be a list of types, where uj = tj (for j < n) and uj = tn−1 (for j ≥ n).
- Let p0..i be a list of optionality values, where pj = oj (for j < n) and pj = “variadic” (for j ≥ n).
- Add to S the tuple <X, u0..i, p0..i>.
- Add to S the tuple <X, t0..n−2, o0..n−2>.
- Initialize i to n−1.
- While i ≥ 0:
- If argument i of X is not optional, then break this loop.
- Otherwise, add to S the tuple <X, t0..i−1, o0..i−1>.
- Set i to i−1.
- The effective overload set is S.
For the following interface:
IDL
interface A {
/* f1 */ void f(DOMString a);
/* f2 */ void f(Node a, DOMString b, double... c);
/* f3 */ void f();
/* f4 */ void f(Event a, DOMString b, optional DOMString c, double... d);
};
assuming Node and Event are two other interfaces of which no object can implement both, the effective overload set for regular operations with identifier f and argument count 4 is:
{ <f1, (DOMString), (required)>,
<f2, (Node, DOMString), (required, required)>,
<f2, (Node, DOMString, double), (required, required, variadic)>,
<f2, (Node, DOMString, double, double), (required, required, variadic, variadic)>,
<f3, (), ()>,
<f4, (Event, DOMString), (required, required)>,
<f4, (Event, DOMString, DOMString), (required, required, optional)>,
<f4, (Event, DOMString, DOMString, double), (required, required, optional, variadic)> }
Two types are distinguishable if at most one of the two includes a nullable type or is a dictionary type, and at least one of the following three conditions is true:
-
The two types (taking their inner types if they are nullable types) appear in the following table and there is a “●” mark in the corresponding entry or there is a letter in the corresponding entry and the designated additional requirement below the table is satisfied:
boolean numeric types string types interface object callback
functiondictionary sequence<T> exception types buffer source types boolean ● ● ● ● ● ● ● ● ● numeric types ● ● ● ● ● ● ● ● string types ● ● ● ● ● ● ● interface (a) (b) (b) ● ● ● object callback function ● ● ● dictionary ● ● ● sequence<T> ● ● exception types ● buffer source types - The two identified interfaces are not the same, it is not possible for a single platform object to implement both interfaces, and it is not the case that both are callback interfaces.
- The interface type is not a callback interface.
- One type is a union type or nullable union type, the other is neither a union type nor a nullable union type, and each member type of the first is distinguishable with the second.
- Both types are either a union type or nullable union type, and each member type of the one is distinguishable with each member type of the other.
Note
Promise types do not appear in the above table, and as a consequence are not distinguishable with any other type.
If there is more than one entry in an effective overload set that has a given type list length, then for those entries there MUST be an index i such that for each pair of entries the types at index i are distinguishable . The lowest such index is termed the distinguishing argument index for the entries of the effective overload set with the given type list length.
Consider the effective overload set shown in the previous example. There are multiple entries in the set with type lists 2, 3 and 4. For each of these type list lengths, the distinguishing argument index is 0, since Node and Event are distinguishable.
The following use of overloading however is invalid:
IDL
interface B {
void f(DOMString x);
void f(double x);
};In addition, for each index j, where j is less than the distinguishing argument index for a given type list length, the types at index j in all of the entries’ type lists MUST be the same and the booleans in the corresponding list indicating argument optionality MUST be the same.
The following is invalid:
IDL
interface B {
/* f1 */ void f(DOMString w);
/* f2 */ void f(long w, double x, Node y, Node z);
/* f3 */ void f(double w, double x, DOMString y, Node z);
};For argument count 4, the effective overload set is:
{ <f1, (DOMString), (required)>,
<f2, (long, double, Node, Node), (required, required, required, required)>,
<f3, (double, double, DOMString, Node), (required, required, required, required)> }
Looking at entries with type list length 4, the distinguishing argument index is 2, since Node and DOMString are distinguishable. However, since the arguments in these two overloads at index 0 are different, the overloading is invalid.
3.2.7 Iterable declarations
An interface can be declared to be iterable by using an iterable declaration (matching Iterable) in the body of the interface.
iterable<value-type>; iterable<key-type, value-type>;
Objects implementing an interface that is declared to be iterable support being iterated over to obtain a sequence of values.
Note
In the ECMAScript language binding, an interface that is iterable will have “entries”, “forEach”, “keys”, “values” and @@iterator properties on its interface prototype object.
If a single type parameter is given, then the interface has a value iterator and provides values of the specified type. If two type parameters are given, then the interface has a pair iterator and provides value pairs, where the first value is a key and the second is the value associated with the key.
A value iterator MUST only be declared on an interface that supports indexed properties and has an integer-typed attribute named “length”. The value-type of the value iterator MUST be the same as the type returned by the indexed property getter. A value iterator is implicitly defined to iterate over the object’s indexed properties.
A pair iterator MUST NOT be declared on an interface that supports indexed properties. Prose accompanying an interface with a pair iterator MUST define what the list of value pairs to iterate over is.
Note
The ECMAScript forEach method that is generated for a value iterator invokes its callback like Array.prototype.forEach does, and the forEach method for a pair iterator invokes its callback like Map.prototype.forEach does.
Since value iterators are currently allowed only on interfaces that support indexed properties, it makes sense to use an Array-like forEach method. There may be a need for value iterators (a) on interfaces that do not support indexed properties, or (b) with a forEach method that instead invokes its callback like Set.protoype.forEach (where the key is the same as the value). If you’re creating an API that needs such a forEach method, please send a request to public-script-coord@w3.org.
Note
Interfaces with iterable declarations MUST NOT have any interface members named “entries”, “forEach”, “keys” or “values”, or have any inherited or consequential interfaces that have interface members with these names.
Consider the following interface SessionManager, which allows access to a number of Session objects:
IDL
interface SessionManager {
Session getSessionForUser(DOMString username);
readonly attribute unsigned long sessionCount;
iterable<Session>;
};
interface Session {
readonly attribute DOMString username;
// ...
};The behavior of the iterator could be defined like so:
The values to iterate over are the open Session objects on the SessionManager sorted by username.
In the ECMAScript language binding, the interface prototype object for the SessionManager interface has a values method that is a function, which, when invoked, returns an iterator object that itself has a next method that returns the next value to be iterated over. It has values and entries methods that iterate over the indexes of the list of session objects and [index, session object] pairs, respectively. It also has a @@iterator method that allows a SessionManager to be used in a for..of loop:
ECMAScript
// 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 alert "anna" and then "brian".
for (;;) {
let result = it.next();
if (result.done) {
break;
}
let session = result.value;
window.alert(session.username);
}
// This loop will also alert "anna" and then "brian".
for (let session of sm) {
window.alert(session.username);
}An interface MUST NOT have more than one iterable declaration. The inherited and consequential interfaces of an interface with an iterable declaration MUST NOT also have an iterable declaration.
The following extended attributes are applicable to iterable declarations: [Exposed].
| [59] | Iterable | → | "iterable" "<" Type OptionalType ">" ";" |
| [60] | OptionalType | → | "," Type | ε |
3.3 Dictionaries
A dictionary is a definition (matching Dictionary) used to define an associative array data type with a fixed, ordered set of key–value pairs, termed dictionary members , where keys are strings and values are of a particular type specified in the definition.
dictionary identifier {
dictionary-members…
};
Dictionaries are always passed by value. In language bindings where a dictionary is represented by an object of some kind, passing a dictionary to a platform object will not result in a reference to the dictionary being kept by that object. Similarly, any dictionary returned from a platform object will be a copy and modifications made to it will not be visible to the platform object.
A dictionary can be defined to inherit from another dictionary. If the identifier of the dictionary is followed by a colon and a identifier, then that identifier identifies the inherited dictionary. The identifier MUST identify a dictionary.
A dictionary MUST NOT be declared such that its inheritance hierarchy has a cycle. That is, a dictionary A cannot inherit from itself, nor can it inherit from another dictionary B that inherits from A, and so on.
dictionary Base {
dictionary-members…
};
dictionary Derived : Base {
dictionary-members…
};
The inherited dictionaries of a given dictionary D is the set of all dictionaries that D inherits from, directly or indirectly. If D does not inherit from another dictionary, then the set is empty. Otherwise, the set includes the dictionary E that D inherits from and all of E’s inherited dictionaries.
A dictionary value of type D can have key–value pairs corresponding to the dictionary members defined on D and on any of D’s inherited dictionaries. On a given dictionary value, the presence of each dictionary member is optional, unless that member is specified as required. When specified in the dictionary value, a dictionary member is said to be present , otherwise it is not present. Dictionary members can also optionally have a default value , which is the value to use for the dictionary member when passing a value to a platform object that does not have a specified value. Dictionary members with default values are always considered to be present.
Warning
As with operation argument default values, is strongly suggested not to use of true as the default value for boolean-typed dictionary members, as this can be confusing for authors who might otherwise expect the default conversion of undefined to be used (i.e., false).
Each dictionary member (matching
DictionaryMember) is specified as a type (matching Type) followed by an
identifier (given by an identifier token following the type). The identifier is the key name of the key–value pair. If the Type is an identifier followed by ?, then the identifier
MUST identify an interface, enumeration,
callback function or typedef. If the dictionary member type is an identifier not followed by ?, then the identifier MUST identify any one of those definitions or a dictionary.
dictionary identifier {
type identifier;
};
If the identifier is followed by a U+003D EQUALS SIGN ("=") and a value (matching DefaultValue), then that gives the dictionary member its default value.
dictionary identifier {
type identifier = value;
};
When a boolean literal token (true or false), the null token, an integer token, a
float token, one of the three special floating point literal values (Infinity,
-Infinity or NaN), a string token or the two token sequence [] used as the
default value, it is interpreted in the same way as for an operation’s
optional argument default value.
If the type of the dictionary member is an enumeration, then its default value if specified MUST be one of the enumeration’s values.
If the type of the dictionary member is preceded by the
required keyword, the member is considered a
required dictionary member and must be present on the dictionary. A
required dictionary
member MUST NOT have a default value.
dictionary identifier {
required type identifier;
};
The type of a dictionary member MUST NOT include the dictionary it appears on. A type includes a dictionary D if at least one of the following is true:
- the type is D
- the type is a dictionary that inherits from D
- the type is a nullable type whose inner type includes D
- the type is a sequence type whose element type includes D
- the type is a union type, one of whose member types includes D
- the type is a dictionary, one of whose members or inherited members has a type that includes D
As with interfaces, the IDL for dictionaries can be split into multiple parts by using partial dictionary definitions (matching "partial" Dictionary). The identifier of a partial dictionary definition MUST be the same as the identifier of a dictionary definition. All of the members that appear on each of the partial dictionary definitions are considered to be members of the dictionary itself.
dictionary SomeDictionary {
dictionary-members…
};
partial dictionary SomeDictionary {
dictionary-members…
};
Note
As with partial interface definitions, partial dictionary definitions are intended for use as a specification editorial aide, allowing the definition of an interface to be separated over more than one section of the document, and sometimes multiple documents.
The order of the dictionary members on a given dictionary is such that inherited dictionary members are ordered before non-inherited members, and the dictionary members on the one dictionary definition (including any partial dictionary definitions) are ordered lexicographically by the Unicode codepoints that comprise their identifiers.
Note
For example, with the following definitions:
IDL
dictionary B : A {
long b;
long a;
};
dictionary A {
long c;
long g;
};
dictionary C : B {
long e;
long f;
};
partial dictionary A {
long h;
long d;
};the order of the dictionary members of a dictionary value of type C is c, d, g, h, a, b, e, f.
Dictionaries are required to have their members ordered because in some language bindings the behavior observed when passing a dictionary value to a platform object depends on the order the dictionary members are fetched. For example, consider the following additional interface:
IDL
interface Something {
void f(A a);
};and this ECMAScript code:
ECMAScript
var something = getSomething(); // Get an instance of Something.
var x = 0;
var dict = { };
Object.defineProperty(dict, "d", { get: function() { return ++x; } });
Object.defineProperty(dict, "c", { get: function() { return ++x; } });
something.f(dict);The order that the dictionary members are fetched in determines what values they will be taken to have. Since the order for A is defined to be c then d, the value for c will be 1 and the value for d will be 2.
The identifier of a dictionary member MUST NOT be the same as that of another dictionary member defined on the dictionary or on that dictionary’s inherited dictionaries.
Dictionaries MUST NOT be used as the type of an attribute or constant.
The following extended attributes are applicable to dictionaries: [Constructor], [Exposed].
The following extended attributes are applicable to dictionary members: [Clamp], [EnforceRange].
| [6] | Partial | → | "partial" PartialDefinition |
| [7] | PartialDefinition | → | PartialInterface | PartialDictionary |
| [11] | Dictionary | → | "dictionary" identifier Inheritance "{" DictionaryMembers "}" ";" |
| [12] | DictionaryMembers | → | ExtendedAttributeList DictionaryMember DictionaryMembers | ε |
| [13] | DictionaryMember | → | Required Type identifier Default ";" |
| [15] | PartialDictionary | → | "dictionary" identifier "{" DictionaryMembers "}" ";" |
| [16] | Default | → | "=" DefaultValue | ε |
| [17] | DefaultValue | → | ConstValue | string | "[" "]" |
| [18] | Inheritance | → | ":" identifier | ε |
One use of dictionary types is to allow a number of optional arguments to an operation without being constrained as to the order they are specified at the call site. For example, consider the following IDL fragment:
IDL
[Constructor]
interface Point {
attribute double x;
attribute double y;
};
dictionary PaintOptions {
DOMString? fillPattern = "black";
DOMString? strokePattern = null;
Point position;
};
interface GraphicsContext {
void drawRectangle(double width, double height, optional PaintOptions options);
};In an ECMAScript implementation of the IDL, an Object can be passed in for the optional PaintOptions dictionary:
ECMAScript
// Get an instance of GraphicsContext.
var ctx = getGraphicsContext();
// Draw a rectangle.
ctx.drawRectangle(300, 200, { fillPattern: "red", position: new Point(10, 10) });Both fillPattern and strokePattern are given default values, so if they are omitted, the definition of drawRectangle can assume that they have the given default values and not include explicit wording to handle their non-presence.
3.4 Exceptions
An exception is a type of object that represents an error and which can be thrown or treated as a first class value by implementations. Web IDL does not allow exceptions to be defined, but instead has a number of pre-defined exceptions that specifications can reference and throw in their definition of operations, attributes, and so on. Exceptions have an error name , a DOMString, which is the type of error the exception represents, and a message , which is an optional, user agent-defined value that provides human readable details of the error.
There are two kinds of exceptions available to be thrown from specifications. The first is a simple exception , which is identified by one of the following names:
- Error
- EvalError
- RangeError
- ReferenceError
- TypeError
- URIError
These correspond to all of the ECMAScript error objects ( [ ECMA-262] , section 19.5) (apart from SyntaxError, which is deliberately omitted as it is for use only by the ECMAScript parser). The meaning of each simple exception matches its corresponding Error object in the ECMAScript specification.
The second kind of exception is a DOMException , which is an exception that encapsulates a name and an optional integer code, for compatibility with historically defined exceptions in the DOM.
For simple exceptions, the error name is the name of the exception. For a DOMException, the error name MUST be one of the names listed in the error names table below. The table also indicates the DOMException's integer code for that error name, if it has one.
There are two types that can be used to refer to exception objects: Error, which encompasses all exceptions, and DOMException which includes just DOMException objects. This allows for example an operation to be declared to have a DOMException return type or an attribute to be of type Error.
Exceptions can be created by providing its error name. Exceptions can also be thrown , by providing the same details required to create one.
The resulting behavior from creating and throwing an exception is language binding-specific.
Note
See section 4.13 for details on what creating and throwing an exception entails in the ECMAScript language binding.
Here is are some examples of wording to use to create and throw exceptions. To throw a new simple exception named TypeError:
Throw a TypeError.
To throw a new DOMException with error name IndexSizeError:
Throw an IndexSizeError.
To create a new DOMException with error name SyntaxError:
Let object be a newly created SyntaxError.
3.4.1 Error names
The error names table below lists all the allowed error names for DOMExceptions, a description, and legacy code values.
Note
If an error name is not listed here, please file a bug as indicated at the top of this specification and it will be addressed shortly. Thanks!
| Name | Description | Legacy code name and value |
|---|---|---|
" IndexSizeError " |
The index is not in the allowed range. | INDEX_SIZE_ERR (1) |
" HierarchyRequestError " |
The operation would yield an incorrect node tree. | HIERARCHY_REQUEST_ERR (3) |
" WrongDocumentError " |
The object is in the wrong document. | 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. | INUSE_ATTRIBUTE_ERR (10) |
" InvalidStateError " |
The object is in an invalid state. | INVALID_STATE_ERR (11) |
" SyntaxError " |
The string did not match the expected pattern. | SYNTAX_ERR (12) |
" InvalidModificationError " |
The object can not be modified in this way. | INVALID_MODIFICATION_ERR (13) |
" NamespaceError " |
The operation is not allowed by Namespaces in XML. [XMLNS] | NAMESPACE_ERR (14) |
" InvalidAccessError " |
The object does not support the operation or argument. | INVALID_ACCESS_ERR (15) |
" SecurityError " |
The operation is insecure. | SECURITY_ERR (18) |
" NetworkError " |
A network error occurred. | NETWORK_ERR (19) |
" AbortError " |
The operation was aborted. | ABORT_ERR (20) |
" URLMismatchError " |
The given URL does not match another URL. | URL_MISMATCH_ERR (21) |
" QuotaExceededError " |
The quota has been exceeded. | QUOTA_EXCEEDED_ERR (22) |
" TimeoutError " |
The operation timed out. | TIMEOUT_ERR (23) |
" InvalidNodeTypeError " |
The supplied node is incorrect or has an incorrect ancestor for this operation. | INVALID_NODE_TYPE_ERR (24) |
" DataCloneError " |
The object can not be cloned. | DATA_CLONE_ERR (25) |
" EncodingError " |
The encoding operation (either encoded or decoding) failed. | — |
" NotReadableError " |
The I/O read operation failed. | — |
" UnknownError " |
The operation failed for an unknown transient reason (e.g. out of memory). | — |
" ConstraintError " |
A mutation operation in a transaction failed because a constraint was not satisfied. | — |
" DataError " |
Provided data is inadequate. | — |
" TransactionInactiveError " |
A request was placed against a transaction which is currently not active, or which is finished. | — |
" ReadOnlyError " |
The mutating operation was attempted in a "readonly" transaction. | — |
" VersionError " |
An attempt was made to open a database using a lower version than the existing version. | — |
" OperationError " |
The operation failed for an operation-specific reason. | — |
3.5 Enumerations
An enumeration is a definition (matching Enum) used to declare a type whose valid values are a set of predefined strings. Enumerations can be used to restrict the possible DOMString values that can be assigned to an attribute or passed to an operation.
enum identifier { enumeration-values… };
The enumeration values are specified as a comma-separated list of string literals. The list of enumeration values MUST NOT include duplicates.
Warning
It is strongly suggested that enumeration values be all lowercase, and that multiple words be separated using dashes or not be separated at all, unless there is a specific reason to use another value naming scheme. For example, an enumeration value that indicates an object should be created could be named
"createobject" or 'create-object". Consider related uses of enumeration values when deciding whether to dash-separate or not separate enumeration value words so that similar APIs are consistent.
The behavior when a string value that is not one a valid enumeration value is used when assigning to an attribute, or passed as an operation argument, whose type is the enumeration, is language binding specific.
Note
In the ECMAScript binding, assignment of an invalid string value to an attribute is ignored, while passing such a value as an operation argument results in an exception being thrown.
No extended attributes defined in this specification are applicable to enumerations.
| [19] | Enum | → | "enum" identifier "{" EnumValueList "}" ";" |
| [20] | EnumValueList | → | string EnumValueListComma |
| [21] | EnumValueListComma | → | "," EnumValueListString | ε |
| [22] | EnumValueListString | → | string EnumValueListComma | ε |
The following IDL fragment defines an enumeration that is used as the type of an attribute and an operation argument:
IDL
enum MealType { "rice", "noodles", "other" };
interface Meal {
attribute MealType type;
attribute double size; // in grams
void initialize(MealType type, double size);
};An ECMAScript implementation would restrict the strings that can be assigned to the type property or passed to the initializeMeal function to those identified in the enumeration.
ECMAScript
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.3.6 Callback functions
A callback function is a definition (matching "callback" CallbackRest) used to declare a function type.
callback identifier = return-type (arguments…);
Note
See also the similarly named callback interfaces.
The identifier on the left of the equals sign gives the name of the callback function and the return type and argument list (matching ReturnType and ArgumentList) on the right side of the equals sign gives the signature of the callback function type.
Callback functions MUST NOT be used as the type of a constant.
The following extended attribute is applicable to callback functions: [TreatNonObjectAsNull].
| [3] | CallbackOrInterface | → | "callback" CallbackRestOrInterface | Interface |
| [4] | CallbackRestOrInterface | → | CallbackRest | Interface |
| [23] | CallbackRest | → | identifier "=" ReturnType "(" ArgumentList ")" ";" |
The following IDL fragment defines a callback function used for an API that invokes a user-defined function when an operation is complete.
IDL
callback AsyncOperationCallback = void (DOMString status);
interface AsyncOperations {
void performOperation(AsyncOperationCallback whenFinished);
};In the ECMAScript language binding, a Function object is passed as the operation argument.
ECMAScript
var ops = getAsyncOperations(); // Get an instance of AsyncOperations.
ops.performOperation(function(status) {
window.alert("Operation finished, status is " + status + ".");
});3.7 Typedefs
A typedef is a definition (matching Typedef) used to declare a new name for a type. This new name is not exposed by language bindings; it is purely used as a shorthand for referencing the type in the IDL.
typedef type identifier;
The type being given a new name is specified after the typedef keyword (matching Type), and the
identifier token following the type gives the name.
The Type MUST NOT identify the same or another typedef.
No extended attributes defined in this specification are applicable to typedefs.
| [24] | Typedef | → | "typedef" Type identifier ";" |
The following IDL fragment demonstrates the use of typedefs to allow the use of a short identifier instead of a long sequence type.
IDL
interface Point {
attribute double x;
attribute double y;
};
typedef sequence<Point> Points;
interface Widget {
boolean pointWithinBounds(Point p);
boolean allPointsWithinBounds(Points ps);
};3.8 Implements statements
An implements statement is a definition (matching ImplementsStatement) used to declare that all objects implementing an interface A (identified by the first identifier) MUST additionally implement interface B (identified by the second identifier), including all other interfaces that B inherits from.
identifier-A implements identifier-B;
Transitively, if objects implementing B are declared with an implements statement to additionally implement interface C, then all objects implementing A do additionally implement interface C.
The two identifiers MUST identify two different interfaces.
The interface identified on the left-hand side of an implements statement MUST NOT inherit from the interface identifier on the right-hand side, and vice versa. Both identified interfaces also MUST NOT be callback interfaces.
If each implements statement is considered to be an edge in a directed graph, from a node representing the interface on the left-hand side of the statement to a node representing the interface on the right-hand side, then this graph MUST NOT have any cycles.
Interfaces that a given object implements are partitioned into those that are considered and those that are not. An interface A is considered to be a supplemental interface of an object O if:
- O implements a different interface B, and the IDL states that
B implements A; or - O implements a different supplemental interface C, and C inherits from A.
Note
Specification authors are discouraged from writing implements statements where the interface on the left-hand side is a supplemental interface. For example, if author 1 writes:
IDL
interface Window { ... };
interface SomeFunctionality { ... };
Window implements SomeFunctionality;and author 2 later writes:
IDL
interface Gizmo { ... };
interface MoreFunctionality { ... };
SomeFunctionality implements MoreFunctionality;
Gizmo implements SomeFunctionality;
then it might be the case that author 2 is unaware of exactly which interfaces already are used on the left-hand side of an
implements SomeFunctionality statement, and so has required more objects implement MoreFunctionality than he or she expected.
Better in this case would be for author 2 to write:
IDL
interface Gizmo { ... };
interface MoreFunctionality { ... };
Gizmo implements SomeFunctionality;
Gizmo implements MoreFunctionality;The consequential interfaces of an interface A are:
- each interface B where the IDL states
A implements B; - each interface that a consequential interface of A inherits from; and
- each interface D where the IDL states that
C implements D, where C is a consequential interface of A.
For a given interface, there MUST NOT be any member defined on any of its consequential interfaces whose identifier is the same as any other member defined on any of those consequential interfaces or on the original interface itself.
Note
For example, that precludes the following:
IDL
interface A { attribute long x; };
interface B { attribute long x; };
A implements B; // B::x would clash with A::x
interface C { attribute long y; };
interface D { attribute long y; };
interface E : D { };
C implements E; // D::y would clash with C::y
interface F { };
interface H { attribute long z; };
interface I { attribute long z; };
F implements H;
F implements I; // H::z and I::z would clash when mixed in to FNo extended attributes defined in this specification are applicable to implements statements.
| [25] | ImplementsStatement | → | identifier "implements" identifier ";" |
The following IDL fragment defines two interfaces, stating that one interface is always implemented on objects implementing the other.
IDL
interface Entry {
readonly attribute unsigned short entryType;
// ...
};
interface Observable {
void addEventListener(DOMString type,
EventListener listener,
boolean useCapture);
// ...
};
Entry implements Observable;An ECMAScript implementation would thus have an “addEventListener” property in the prototype chain of every Entry:
ECMAScript
var e = getEntry(); // Obtain an instance of Entry.
typeof e.addEventListener; // Evaluates to "function".Note that it is not the case that all Observable objects implement Entry.
3.9 Objects implementing interfaces
In a given implementation of a set of IDL fragments, an object can be described as being a platform object , a user object , or neither. There are two kinds of object that are considered to be platform objects:
- objects that implement a non-callback interface;
- objects representing IDL DOMExceptions.
In a browser, for example, the browser-implemented DOM objects (implementing interfaces such as Node and Document) that provide access to a web page’s contents to ECMAScript running in the page would be platform objects. These objects might be exotic objects, implemented in a language like C++, or they might be native ECMAScript objects. Regardless, an implementation of a given set of IDL fragments needs to be able to recognize all platform objects that are created by the implementation. This might be done by having some internal state that records whether a given object is indeed a platform object for that implementation, or perhaps by observing that the object is implemented by a given internal C++ class. How exactly platform objects are recognised by a given implementation of a set of IDL fragments is implementation specific.
All other objects in the system would not be treated as platform objects. For example, assume that a web page opened in a browser loads an ECMAScript library that implements DOM Core. This library would be considered to be a different implementation from the browser provided implementation. The objects created by the ECMAScript library that implement the Node interface will not be treated as platform objects that implement Node by the browser implementation.
User objects are those that authors would create, implementing callback interfaces that the Web APIs use to be able to invoke author-defined operations or to send and receive values to the author’s program through manipulating the object’s attributes. In a web page, an ECMAScript object that implements the EventListener interface, which is used to register a callback that the DOM Events implementation invokes, would be considered to be a user object.
Note that user objects can only implement callback interfaces and platform objects can only implement non-callback interfaces.
3.10 Types
This section lists the types supported by Web IDL, the set of values corresponding to each type, and how constants of that type are represented.
The following types are known as integer types : byte, octet, short, unsigned short, long, unsigned long, long long and unsigned long long.
The following types are known as numeric types : the integer types, float, unresticted float, double and unrestricted double.
The primitive types are boolean and the numeric types.
The string types are DOMString, all enumeration types, ByteString and USVString.
The exception types are Error and DOMException.
The typed array types are Int8Array, Int16Array, Int32Array, Uint8Array, Uint16Array, Uint32Array, Uint8ClampedArray, Float32Array and Float64Array.
The buffer source types are ArrayBuffer, DataView, and the typed array types.
The object type, all interface types and the exception types are known as object types .
Every type has a type name , which is a string, not necessarily unique, that identifies the type. Each sub-section below defines what the type name is for each type.
When conversions are made from language binding specific types to IDL types in order to invoke an operation or assign a value to an attribute, all conversions necessary will be performed before the specified functionality of the operation or attribute assignment is carried out. If the conversion cannot be performed, then the operation will not run or the attribute will not be updated. In some language bindings, type conversions could result in an exception being thrown. In such cases, these exceptions will be propagated to the code that made the attempt to invoke the operation or assign to the attribute.
| [73] | Type | → | SingleType | UnionType Null |
| [74] | SingleType | → | NonAnyType | "any" |
| [75] | UnionType | → | "(" UnionMemberType "or" UnionMemberType UnionMemberTypes ")" |
| [76] | UnionMemberType | → | NonAnyType | UnionType Null |
| [77] | UnionMemberTypes | → | "or" UnionMemberType UnionMemberTypes | ε |
| [78] | NonAnyType | → | PrimitiveType Null | PromiseType Null | "ByteString" Null | "DOMString" Null | "USVString" Null | identifier Null | "sequence" "<" Type ">" Null | "object" Null | "Error" Null | "DOMException" Null | BufferRelatedType Null |
| [80] | ConstType | → | PrimitiveType Null | identifier Null |
| [81] | PrimitiveType | → | UnsignedIntegerType | UnrestrictedFloatType | "boolean" | "byte" | "octet" |
| [82] | UnrestrictedFloatType | → | "unrestricted" FloatType | FloatType |
| [83] | FloatType | → | "float" | "double" |
| [84] | UnsignedIntegerType | → | "unsigned" IntegerType | IntegerType |
| [85] | IntegerType | → | "short" | "long" OptionalLong |
| [86] | OptionalLong | → | "long" | ε |
| [87] | PromiseType | → | "Promise" "<" ReturnType ">" |
| [88] | Null | → | "?" | ε |
3.10.1 any
The any type is the union of all other possible non- union types. Its type name is “Any”.
The any type is like a discriminated union type, in that each of its values has a specific non-any type associated with it. For example, one value of the any type is the unsigned long 150, while another is the long 150. These are distinct values.
The particular type of an any value is known as its specific type . (Values of union types also have specific types.)
3.10.2 boolean
The boolean type has two values: true and false.
boolean constant values in IDL are represented with the true and
false tokens.
3.10.3 byte
The byte type is a signed integer type that has values in the range [−128, 127].
byte constant values in IDL are represented with integer tokens.
3.10.4 octet
The octet type is an unsigned integer type that has values in the range [0, 255].
octet constant values in IDL are represented with integer tokens.
3.10.5 short
The short type is a signed integer type that has values in the range [−32768, 32767].
short constant values in IDL are represented with integer tokens.
3.10.6 unsigned short
The unsigned short type is an unsigned integer type that has values in the range [0, 65535].
unsigned short constant values in IDL are represented with integer tokens.
The type name of the unsigned short type is “UnsignedShort”.
3.10.7 long
The long type is a signed integer type that has values in the range [−2147483648, 2147483647].
long constant values in IDL are represented with integer tokens.
3.10.8 unsigned long
The unsigned long type is an unsigned integer type that has values in the range [0, 4294967295].
unsigned long constant values in IDL are represented with integer tokens.
The type name of the unsigned long type is “UnsignedLong”.
3.10.9 long long
The long long type is a signed integer type that has values in the range [−9223372036854775808, 9223372036854775807].
long long constant values in IDL are represented with integer tokens.
3.10.10 unsigned long long
The unsigned long long type is an unsigned integer type that has values in the range [0, 18446744073709551615].
unsigned long long constant values in IDL are represented with integer tokens.
The type name of the unsigned long long type is “UnsignedLongLong”.
3.10.11 float
The float type is a floating point numeric type that corresponds to the set of finite single-precision 32 bit IEEE 754 floating point numbers. [IEEE-754]
float constant values in IDL are represented with float tokens.
3.10.12 unrestricted float
The unrestricted float type is a floating point numeric type that corresponds to the set of all possible single-precision 32 bit IEEE 754 floating point numbers, finite and non-finite. [IEEE-754]
unrestricted float constant values in IDL are represented with float tokens.
The type name of the unrestricted float type is “UnrestrictedFloat”.
3.10.13 double
The double type is a floating point numeric type that corresponds to the set of finite double-precision 64 bit IEEE 754 floating point numbers. [IEEE-754]
double constant values in IDL are represented with float tokens.
3.10.14 unrestricted double
The unrestricted double type is a floating point numeric type that corresponds to the set of all possible double-precision 64 bit IEEE 754 floating point numbers, finite and non-finite. [IEEE-754]
unrestricted double constant values in IDL are represented with float tokens.
The type name of the unrestricted double type is “UnrestrictedDouble”.
3.10.15 DOMString
The DOMString type corresponds to the set of all possible sequences of code units. Such sequences are commonly interpreted as UTF-16 encoded strings [RFC2781] although this is not required. While DOMString is defined to be an OMG IDL boxed sequence<unsigned short> valuetype in DOM Level 3 Core ([ DOM3CORE], section 1.2.1), this document defines DOMString to be an intrinsic type so as to avoid special casing that sequence type in various situations where a string is required.
Note
Note also that null is not a value of type DOMString. To allow null, a
nullable DOMString, written as DOMString? in IDL, needs to be used.
Nothing in this specification requires a DOMString value to be a valid UTF-16 string. For example, a DOMString value might include unmatched surrogate pair characters. However, authors of specifications using Web IDL might want to obtain a sequence of Unicode scalar values given a particular sequence of code units. The following algorithm defines a way to convert a DOMString to a sequence of Unicode scalar values :
- Let S be the DOMString value.
- Let n be the length of S.
- Initialize i to 0.
- Initialize U to be an empty sequence of Unicode characters.
- While i < n:
- Let c be the code unit in S at index i.
- Depending on the value of c:
- c < 0xD800 or c > 0xDFFF
- Append to U the Unicode character with code point c.
- 0xDC00 ≤ c ≤ 0xDFFF
- Append to U a U+FFFD REPLACEMENT CHARACTER.
- 0xD800 ≤ c ≤ 0xDBFF
-
- If i = n−1, then append to U a U+FFFD REPLACEMENT CHARACTER.
- Otherwise, i < n−1:
- Let d be the code unit in S at index i+1.
- If 0xDC00 ≤ d ≤ 0xDFFF, then:
- Let a be c & 0x3FF.
- Let b be d & 0x3FF.
- Append to U the Unicode character with code point 216+210a+b.
- Set i to i+1.
- Otherwise, d < 0xDC00 or d > 0xDFFF. Append to U a U+FFFD REPLACEMENT CHARACTER.
- Set i to i+1.
- Return U.
There is no way to represent a constant DOMString value in IDL, although DOMString dictionary member and operation optional argument default values can be specified using a string literal.
3.10.16 ByteString
The ByteString type corresponds to the set of all possible sequences of bytes. Such sequences might be interpreted as UTF-8 encoded strings [RFC3629] or strings in some other 8-bit-per-code-unit encoding, although this is not required.
There is no way to represent a constant ByteString value in IDL.
The type name of the ByteString type is “ByteString”.
Warning
Specifications SHOULD only use ByteString for interfacing with protocols that use bytes and strings interchangably, such as HTTP. In general, strings SHOULD be represented with DOMString values, even if it is expected that values of the string will always be in ASCII or some 8 bit character encoding. Sequences or Typed Arrays with octet or byte elements SHOULD be used for holding 8 bit data rather than ByteString. [ TYPEDARRAYS]
3.10.17 USVString
The USVString type corresponds to the set of all possible sequences of Unicode scalar values, which are all of the Unicode code points apart from the surrogate code points.
There is no way to represent a constant USVString value in IDL, although USVString dictionary member and operation optional argument default values can be specified using a string literal.
The type name of the USVString type is “USVString”.
Warning
Specifications SHOULD only use USVString for APIs that perform text processing and need a string of Unicode scalar values to operate on. Most APIs that use strings should instead be using DOMString, which does not make any interpretations of the code units in the string. When in doubt, use DOMString.
3.10.18 object
The object type corresponds to the set of all possible non-null object references.
There is no way to represent a constant object value in IDL.
To denote a type that includes all possible object references plus the null value, use the nullable type object?.
3.10.19 Interface types
An identifier that identifies an interface is used to refer to a type that corresponds to the set of all possible non-null references to objects that implement that interface.
For non-callback interfaces, an IDL value of the interface type is represented just by an object reference. For callback interfaces, an IDL value of the interface type is represented by a tuple of an object reference and a callback context . The callback context is a language binding specific value, and is used to store information about the execution context at the time the language binding specific object reference is converted to an IDL value.
Note
For ECMAScript objects, the callback context is used to hold a reference to the incumbent script [ HTML5] at the time the Object value is converted to an IDL callback interface type value. See section 4.2.20 .
There is no way to represent a constant object reference value for a particular interface type in IDL.
To denote a type that includes all possible references to objects implementing the given interface plus the null value, use a nullable type.
The type name of an interface type is the identifier of the interface.
3.10.20 Dictionary types
An identifier that identifies a dictionary is used to refer to a type that corresponds to the set of all dictionaries that adhere to the dictionary definition.
There is no way to represent a constant dictionary value in IDL.
The type name of a dictionary type is the identifier of the dictionary.
3.10.21 Enumeration types
An identifier that identifies an enumeration is used to refer to a type whose values are the set of strings (sequences of code units, as with DOMString) that are the enumeration’s values.
Like DOMString, there is no way to represent a constant enumeration value in IDL, although enumeration-typed dictionary member default values can be specified using a string literal.
The type name of an enumeration type is the identifier of the enumeration.
3.10.22 Callback function types
An identifier that identifies a callback function is used to refer to a type whose values are references to objects that are functions with the given signature.
An IDL value of the callback function type is represented by a tuple of an object reference and a callback context.
Note
As with callback interface types, the callback context is used to hold a reference to the incumbent script [ HTML5] at the time an ECMAScript Object value is converted to an IDL callback function type value. See section 4.2.23 .
There is no way to represent a constant callback function value in IDL.
The type name of a callback function type is the identifier of the callback function.
3.10.23 Nullable types — T?
A nullable type is an IDL type constructed from an existing type (called the inner type ), which just allows the additional value null to be a member of its set of values. Nullable types are represented in IDL by placing a U+003F QUESTION MARK ("?") character after an existing type. The inner type MUST NOT be any, another nullable type, or a union type that itself has includes a nullable type or has a dictionary type as one of its flattened member types.
Note
Although dictionary types can in general be nullable, they cannot when used as the type of an operation argument or a dictionary member.
Nullable type constant values in IDL are represented in the same way that constant values of their inner type would be represented, or with the null token.
The type name of a nullable type is the concatenation of the type name of the inner type T and the string “OrNull”.
For example, a type that allows the values true, false and null is written as boolean?:
IDL
interface MyConstants {
const boolean? ARE_WE_THERE_YET = false;
};The following interface has two attributes: one whose value can be a DOMString or the null value, and another whose value can be a reference to a Node object or the null value:
IDL
interface Node {
readonly attribute DOMString? namespaceURI;
readonly attribute Node? parentNode;
// ...
};3.10.24 Sequences — sequence<T>
The sequence<T> type is a parameterized type whose values are (possibly zero-length) sequences of values of type T.
Sequences are always passed by value. In language bindings where a sequence is represented by an object of some kind, passing a sequence to a platform object will not result in a reference to the sequence being kept by that object. Similarly, any sequence returned from a platform object will be a copy and modifications made to it will not be visible to the platform object.
There is no way to represent a constant sequence value in IDL.
Sequences MUST NOT be used as the type of an attribute or constant.
Note
This restriction exists so that it is clear to specification writers and API users that sequences are copied rather than having references to them passed around. Instead of a writable attribute of a sequence type, it is suggested that a pair of operations to get and set the sequence is used.
The type name of a sequence type is the concatenation of the type name for T and the string “Sequence”.
3.10.25 Promise types — Promise<T>
A promise type is a parameterized type whose values are references to objects that “is used as a place holder for the eventual results of a deferred (and possibly asynchronous) computation result of an asynchronous operation” [ECMA-262]. See section 25.4 of the ECMAScript specification for details on the semantics of promise objects.
There is no way to represent a promise value in IDL.
The type name of a promise type is the concatenation of the type name for T and the string “Promise”.
3.10.26 Union types
A union type is a type whose set of values is the union of those in two or more other types. Union types (matching
UnionType) are written as a series of types separated by the or keyword with a set of surrounding parentheses. The types which comprise the union type are known as the union’s <