Copyright © 2008 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C liability, trademark and document use rules apply.
This specification defines an Interface Definition Language (IDL) to be used by specifications that define a Document Object Model (DOM). How interfaces described with this IDL correspond to constructs within ECMAScript and Java execution environments is also detailed.
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 http://www.w3.org/TR/.
This document is the 10 April 2008 Working Draft of the “Language Bindings for DOM Specifications” specification. Please send comments about this document to public-webapi@w3.org (archived) with “[Bindings]” at the start of the subject line.
“Language Bindings for DOM Specifications” is intended to specify in detail the IDL language used by W3C specifications to define DOM interfaces, and to provide precise conformance requirements for ECMAScript and Java bindings of such interfaces. It is expected that this document acts as a guide to implementors of already-published DOM specifications, and that newly published DOM specifications reference this document to ensure conforming implementations of DOM interfaces are interoperable.
This document is produced by the Web API Working Group, part of the Rich Web Clients Activity in the W3C Interaction Domain. Changes made to this document can be found in the W3C public CVS server.
Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
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 section is informative.
Specifications published by the W3C that include Document Object Model (DOM) interfaces are typically 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 specifications 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 a subset of OMG IDL version 3.0 for use by DOM specifications. 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 3rd Edition and Java are given.
Everything in this specification is normative except for diagrams, examples, notes and sections marked as being informative.
The keywords “must“, “must not”, “required”, “shall”, “shall not”, “recommended”, “may” and “optional” in this document are to be interpreted as described in [RFC2119].
The following conformance classes are defined by this specification:
An IDL fragment is considered to be a conforming IDL fragment if it satisfies all of the must-, required- and shall-level criteria in this specification that apply to IDL fragments.
A user agent is considered to be a conforming implementation with respect to a conforming IDL fragment 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.
A user agent is considered to be a conforming ECMAScript implementation with respect to a conforming IDL fragment if it satisfies all of the must-, required- and shall-level criteria in this specification that apply to implementations for the ECMAScript language binding.
A user agent is considered to be a conforming Java implementation with respect to a conforming IDL fragment if it satisfies all of the must-, required- and shall-level criteria in this specification that apply to implementations for the Java language binding.
This section describes a language with which interfaces can be defined in a language independent manner. This language is based on the Object Management Group’s Interface Definition Language [OMGIDL], and is syntactically a subset thereof.
An IDL fragment is a sequence of definitions that matches the Definitions non-terminal in the grammar. See Appendix A for the complete grammar and an explanation of the notation used.
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 are discussed in section 3.8 below.
A definition is said to be declared at the outermost scope if there is no Module ancestor of the non-terminal representing the definition in the parse tree for the IDL fragment. Conforming IDL fragments should not have any non-module definitions declared at the outermost scope.
A definition has been declared previously, relative to a given scoped name that resolved to the definition, if:
| [1] | Definitions | → | ExtendedAttributeList Definition Definitions | ε |
| [2] | Definition | → | Module | Interface | Exception | Typedef | Valuetype | Const |
Each of the sections below needs examples.
The first identifier terminal in a derivation of a Definition, InterfaceMember or ExceptionMember determines the identifier of that definition, interface member or exception member (respectively) as follows:
The identifier of a definition must be locally unique to the module in which the definition occurred.
Every definition also has a qualified name, which must be globally unique to the IDL fragment in which it is defined. The qualified name of a definition is defined as follows:
A scoped name is a string formed from the concatenation of the terminal values (removing any leading U+005F LOW LINE ("_") characters from the value of identifier terminals, as in the rules for identifiers) in the derivation of a ScopedName non-terminal. The scoped name is an absolute scoped name if it begins with two consecutive U+003A COLON (":") characters, or a relative scoped name if it does not.
A scoped name can be resolved, with respect to a given module, to a definition as follows:
| [41] | ScopedName | → | "::" identifier ScopedNameParts | identifier ScopedNameParts |
| [42] | ScopedNameParts | → | "::" identifier ScopedNameParts | ε |
A module is a definition that matches the Module non-terminal, and serves as a container for other definitions.
The enclosing module of a definition is defined as follows:
The relevant language binding determines how modules affect the naming of constructs that correspond to definitions in the language. If the language supports some form of namespacing mechanism, then a module will correspond to a namespace.
The following extended attributes are applicable to modules: [ExceptionConsts].
| [3] | Module | → | "module" identifier "{" Definitions "}" ";" |
An interface is a definition that matches the Interface non-terminal whose InterfaceBody is not empty (that is, it is not the case that InterfaceBody ⇒ ε). An interface is a specification of a set of interface members, which are the constants, attributes and operations given by the InterfaceMembers part of the InterfaceBody. Objects implementing the interface will have members that correspond to each of the interface’s members.
The identifier of an interface member is given by the first identifier terminal in a derivation of the non-terminal that represents the interface member. The identifier of an interface member (except for operations, which can be overloaded) must be unique within the interface on which it is defined.
An interface inherits from another if there is a scoped name in the ScopedNameList that, with respect to the enclosing module of the interface, resolves to that inherited interface. Every scoped name in the ScopedNameList must resolve to an interface whose definition occurs before the definition of the inheriting 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.
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.
The relevant language binding determines how interfaces correspond to constructs in the language. Many object-oriented languages support interfaces, in which case the mapping of IDL interfaces to language interfaces is simple.
An interface forward declaration is a definition that matches the Interface non-terminal whose InterfaceBody is empty (that is, InterfaceBody ⇒ ε). A forward declaration is used to introduce an interface name to allow for the definition of mutually recursive interfaces, since scoped names need to resolve to types that have been declared previously.
The following extended attributes are applicable to interfaces: [Constructor], [NoInterfaceObject], [Stringifies].
Should there be a way to define constructors on the interface with
particular names, to support HTML 5’s Audio,
Image and Option constructors?
| [4] | Interface | → | "interface" identifier InterfaceBody ";" |
| [5] | InterfaceInheritance | → | ":" ScopedNameList | ε |
| [6] | InterfaceBody | → | InterfaceInheritance "{" InterfaceMembers "}" | ε |
| [7] | InterfaceMembers | → | ExtendedAttributeList InterfaceMember InterfaceMembers | ε |
| [8] | InterfaceMember | → | Const | Attribute | Operation |
| [39] | ScopedNameList | → | ScopedName ScopedNames |
| [40] | ScopedNames | → | "," ScopedName ScopedNames | ε |
A constant is a definition that matches the Const non-terminal, and is used to bind a constant value to a name. Constants can appear on interfaces and also at the module or outermost scope.
The ConstExpr part of a constant definition gives the value of the constant, which can be one of the two boolean literal terminals ("TRUE" and "FALSE"), an integer terminal or a float terminal.
The value of the boolean literal terminals are as follows:
The value of an integer terminal is determined as follows:
| Character | Value of digit |
|---|---|
| U+0030 DIGIT ZERO ("0") | 0 |
| U+0031 DIGIT ONE ("1") | 1 |
| U+0032 DIGIT TWO ("2") | 2 |
| U+0033 DIGIT THREE ("3") | 3 |
| U+0034 DIGIT FOUR ("4") | 4 |
| U+0035 DIGIT FIVE ("5") | 5 |
| U+0036 DIGIT SIX ("6") | 6 |
| U+0037 DIGIT SEVEN ("7") | 7 |
| U+0038 DIGIT EIGHT ("8") | 8 |
| U+0039 DIGIT NINE ("9") | 9 |
| U+0041 LATIN CAPITAL LETTER A ("A") | 10 |
| U+0042 LATIN CAPITAL LETTER B ("B") | 11 |
| U+0043 LATIN CAPITAL LETTER C ("C") | 12 |
| U+0044 LATIN CAPITAL LETTER D ("D") | 13 |
| U+0045 LATIN CAPITAL LETTER E ("E") | 14 |
| U+0046 LATIN CAPITAL LETTER F ("F") | 15 |
| U+0061 LATIN SMALL LETTER A ("a") | 10 |
| U+0062 LATIN SMALL LETTER B ("b") | 11 |
| U+0063 LATIN SMALL LETTER C ("c") | 12 |
| U+0064 LATIN SMALL LETTER D ("d") | 13 |
| U+0065 LATIN SMALL LETTER E ("e") | 14 |
| U+0066 LATIN SMALL LETTER F ("f") | 15 |
The type of an integer terminal is the same as the type of the constant it is being used as the value of. The value of the integer terminal must not lie outside the valid range of values for its type, as given in section 3.7 below.
The type of a float terminal is float, and its value is determined as follows:
A constant must be assigned a value of the same type that the constant is declared to be.
No extended attributes are applicable to constants.
| [13] | Const | → | "const" DeclarationType identifier "=" ConstExpr ";" |
| [14] | ConstExpr | → | BooleanLiteral | integer | float |
| [15] | BooleanLiteral | → | "TRUE" | "FALSE" |
An attribute is an interface member that matches the Attribute non-terminal, and is used to declare that objects implementing the interface will have an attribute with the given identifier that can be assigned and retrieved.
The type of the attribute is given by the DeclarationType non-terminal. If the DeclarationType is a scoped name, then it must resolve, with respect to the enclosing module of the interface on which the attribute is defined, to an interface, typedef or boxed valuetype that has been declared previously.
The attribute is read only if the "readonly" terminal is used in the definition. 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.
The GetRaises and SetRaises clauses are used to declare the possible exceptions that can be thrown when retrieving the value of and assigning a value to the attribute, respectively. Each scoped name in the GetRaises and SetRaises clauses must resolve, with respect to the enclosing module of the interface on which the attribute is defined, to an exception that has been declared previously.
Should conforming implementations have a requirement that they must not raise an exception (that was defined in the IDL) that is not in the getraises/setraises list?
The following extended attributes are applicable to attributes: [NoNull], [PutForwards].
| [16] | Attribute | → | ReadOnly "attribute" DeclarationType identifier GetRaises SetRaises ";" |
| [17] | ReadOnly | → | "readonly" | ε |
| [18] | GetRaises | → | "getraises" ExceptionList | ε |
| [19] | SetRaises | → | "setraises" ExceptionList | ε |
| [22] | ExceptionList | → | "(" ScopedNameList ")" |
An operation is an interface member that matches the Operation non-terminal, and is used to declare that objects implementing the interface will have a method with the given identifier.
The return type of the operation is given by the ReturnType non-terminal. A return type of "void" indicates that the operation returns no value. If the DeclarationType is a scoped name, then it must resolve, with respect to the enclosing module of the interface on which the operation is defined, to an interface, typedef or boxed valuetype that has been declared previously.
The ArgumentList non-terminal gives the list of arguments for the operation. The identifier of an argument is given by the identifier terminal in the Argument, and the type of the argument is given by the DeclarationType. If the DeclarationType is a scoped name, then it must resolve, with respect to the enclosing module of the interface on which the operation is defined, to an interface, typedef or boxed valuetype that has been declared previously.
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.
The Raises clause is used to declare the possible exceptions that can be thrown when invoking the operation. Each scoped name in the Raises clause must resolve, with respect to the enclosing module of the interface on which the operation is defined, to an exception that has been declared previously.
The following extended attributes are applicable to operations: [IndexGetter], [IndexSetter], [NameGetter], [NameSetter], [NoNull].
The following extended attributes are applicable to operation arguments: [NoNull], [Variadic].
| [20] | Operation | → | ReturnType identifier "(" ArgumentList ")" Raises ";" |
| [21] | Raises | → | "raises" ExceptionList | ε |
| [23] | ArgumentList | → | Argument Arguments | ε |
| [24] | Arguments | → | "," Argument Arguments | ε |
| [25] | Argument | → | ExtendedAttributeList "in" DeclarationType identifier |
| [38] | ReturnType | → | DeclarationType | "void" |
An exception is a definition that matches the Exception non-terminal, and is used to declare a type of exception that can be thrown by implementations. The identifier of the exception is given by the identifier terminal.
Exceptions are different from interfaces in that they can have only exception members (matching ExceptionMember) declared on them, rather than the three types of interface members. An exception member’s type is given by the DeclarationType non-terminal of the ExceptionMember. If the DeclarationType is a scoped name, then it must resolve, with respect to the enclosing module of the exception on which the exception member is declared, to an interface, typedef or boxed valuetype that has been declared previously.
The identifier of an exception member is given by the first identifier terminal in a derivation of ExceptionMember. The identifier of an exception member must be unique within the exception on which it is defined.
Exception members are similar to attributes in that they will correspond to attributes of the same name and type on exception objects that are thrown by implementations.
The following extended attributes are applicable to exceptions: [NoInterfaceObject].
No extended attributes are applicable to exception members.
| [9] | Exception | → | "exception" identifier "{" ExceptionMembers "}" ";" |
| [10] | ExceptionMembers | → | ExtendedAttributeList ExceptionMember ExceptionMembers | ε |
| [26] | ExceptionMember | → | DeclarationType identifier ";" |
A typedef is a definition that matches the Typedef non-terminal, and is used to declare a new name for a type.
The type is given by the Type non-terminal, and the new name for the type is the identifier of the typedef, as given by the identifier terminal.
Using a typedef is the only way to utilize the sequence<T> type, since interface members, exception members and operation return types and argument types must be specified with a DeclarationType, which does not allow a sequence<T>.
| [11] | Typedef | → | "typedef" Type identifier ";" |
Valuetypes in OMG IDL are used to define types similar to structs in C. That is, they define composite types that can have zero or more member variables that are passed by value. OMG IDL valuetypes have the additional feature of allowing null to be passed in place of an object with those member variables. An OMG IDL boxed valuetype is a special case, where the valuetype has a single member.
The IDL defined in this specification supports only boxed valuetypes, which are definitions that match the Valuetype non-terminal. The identifier of the valuetype is given by the identifier terminal, and the type being boxed is given by the BoxedType non-terminal. If the BoxedType is a ScopedName, then it must refer to a type that does not allow null as a value (i.e., boolean, octet, short, unsigned short, unsigned long, long long, unsigned long long, float or sequence<T>.
Boxed valuetypes are essentially used just for allowing a null value to be used where normally a non-object value could only be used.
| [12] | Valuetype | → | "valuetype" identifier BoxedType ";" |
This section lists the types supported by the IDL.
| [32] | DeclarationType | → | UnsignedIntegerType | ScopedName | "any" | "boolean" | "octet" | "float" | "Object" |
| [33] | BoxedType | → | UnsignedIntegerType | ScopedName | "boolean" | "octet" | "float" | "sequence" "<" Type ">" |
| [34] | Type | → | DeclarationType | "sequence" "<" Type ">" |
| [35] | UnsignedIntegerType | → | "unsigned" IntegerType | IntegerType |
| [36] | IntegerType | → | "short" | "long" OptionalLong |
| [37] | OptionalLong | → | "long" | ε |
The any type is the union of all other possible types.
The boolean type has two values: true and false.
boolean constant values in IDL are represented with the "TRUE" and "FALSE" terminals.
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 terminals.
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 terminals.
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 terminals.
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 terminals.
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 terminals.
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 terminals.
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 terminals.
The float type is a floating point numeric type that corresponds to the set of possible single-precision 32 bit IEEE 754 floating point numbers. [IEEE-754]
float constant values in IDL are represented with float terminals.
Do we need to mention anything about different NaNs, zeroes, infinities or denormalised numbers?
The sequence<T> type is a parameterized type whose values are (possibly zero-length) sequences of values of type T. Sequences can have an arbitrary length that is immutable. However, sequence element values are mutable.
Should sequences really be immutable? Is there any advantage to disallowing resizing sequences here, rather than selectively by the interface designer? The sequence section in the ECMAScript bindings below assume it is mutable.
There is no way to represent a sequence constant value in IDL.
The Object type corresponds to the set of all possible object references, plus the special value null, which indicates no object reference.
There is no way to represent an Object constant value in IDL.
A scoped name that resolves to an interface is used to refer to a type that corresponds to the set of all possible references to objects that implement that interface, plus the special value null, which indicates no object reference.
There is no way to represent an Object constant value in IDL.
A scoped name that resolves to a boxed valuetype is used to refer to a type that corresponds to the set of values for the type being boxed, plus the special value null, which indicates no value.
There is no way to represent a boxed valuetype constant value in IDL.
An extended attribute is an annotation that can appear on definitions, interface members, exception members and operation arguments, and are used to control how language bindings will handle those constructs. Extended attributes are specified with an ExtendedAttributeList, which is a square bracket enclosed, comma separated list of ExtendedAttributes.
An extended attribute is specified as an identifier. Some extended attributes are defined to take an argument. The argument is given by following the identifier with a "=" terminal and the identifier argument.
This specification defines a number of extended attributes, which are listed in the sub-sections below.
Have an extended attribute that specifies what properties get enumerated in a for..in loop?
If the [Constructor] extended attribute appears on an interface, it indicates that there must be a way to construct objects that implement this interface. How such objects can be constructed is specific to the language binding.
The [Constructor] extended attribute must take no argument.
The following IDL defines two interfaces. The second has the [Constructor] extended attribute, while the first does not.
interface NodeList {
Node item(in unsigned long index);
readonly attribute unsigned long length;
};
[Constructor]
interface Circle {
attribute float r;
attribute float cx;
attribute float cy;
readonly attribute float circumference;
};An ECMAScript implementation supporting these interfaces would have a [[Construct]] property on the Circle interface object which would return a new object that implements the interface. The NodeList interface object would not have a [[Construct]] property.
var x = new Circle(); // x is now a reference to a host object that implements the Circle interface.
var y = new NodeList(); // This would throw a TypeError.This doesn’t allow for constructors which take arguments, and that’s probably something that will be wanted. Maybe the extended attribute should be on operations instead, e.g.:
interface Circle {
attribute float r;
attribute float cx;
attribute float cy;
readonly attribute float circumference;
[Constructor] Circle createCircle(in float r, in float cx, in float cy);
};For ES, such operations map to a [[Construct]] property with a function that takes the given arguments. For other languages, this could perhaps map to a static method somewhere.
If the [ExceptionConsts] extended attribute appears on a module, it indicates that any constants declared on that module are intended to exist on the language construct that corresponds to the exception given by the extended attribute’s argument (for languages that support constants on exceptions). Exactly how these constants are exposed is language binding specific.
The [ExceptionConsts] must take a single argument, an identifier, which must be the identifier of an exception defined in that module, on which the constants declared at the module scope should live.
The following IDL fragment declares an exception and a number of constants at the module scope:
[ExceptionConsts=FileIOException]
module fileio {
exception FileIOException {
unsigned short code;
};
const unsigned short FILE_NOT_FOUND = 1;
const unsigned short READ_ERROR = 2;
const unsigned short WRITE_ERROR = 3;
};In the ECMAScript binding, this will result in properties on the exception interface object for each of the constants:
typeof FileIOException; // evaluates to "object"
FileIOException.FILE_NOT_FOUND; // evaluates to 1If the [IndexGetter] extended attribute appears on an operation with a single unsigned long argument, it indicates that an object that implements the interface can be indexed with an unsigned long, resulting in the same effect as calling the operation with the given index (for languages that support such object indexing). If an object implements interfaces such that it has more than one operation annotated with [IndexGetter], then which operation is invoked when an object is indexed with an unsigned long value is undefined.
The [IndexGetter] extended attribute must take no argument.
The following IDL fragment defines an interface OrderedMap which allows retrieving and setting values by name or by index number:
valuetype DOMString sequence<unsigned short>;
interface OrderedMap {
readonly attribute unsigned long size;
[IndexGetter] any getByIndex(in unsigned long index);
[IndexSetter] void setByIndex(in unsigned long index, in any value);
[NameGetter] any get(in DOMString name);
[NameSetter] void set(in DOMString name, in any value);
};An ECMAScript implementation would have an internal [[Get]] method that allows values to be retrieved from the map as properties, and a corresponding [[Put]] method for setting values in the map:
var map = getOrderedMap(); // Assume map is a host object implementing the OrderedMap interface.
var x, y;
x = map[0]; // Same as: x = map.getByIndex(0)
map[1] = false; // Same as: map.setByIndex(1, false)
y = map.apple; // Same as: y = map.get('apple')
map.banana = 123; // Same as: map.set('banana', 123)If the [IndexSetter] extended attribute appears on an operation with two arguments, the first of which is unsigned long, it indicates that an object that implements the interface can be indexed with an unsigned long for assignment, resulting in the same effect as calling the operation with the given index and value to assign (for languages that support such object indexing). If an object implements interfaces such that it has more than one operation annotated with [IndexSetter], then which operation is invoked when an object is indexed with an unsigned long value for assignment is undefined.
The [IndexSetter] extended attribute must take no argument.
See section 3.8.3 for an example of the use of [IndexSetter].
If the [NoInterfaceObject] extended attribute appears on an interface, it indicates that an interface object will not exist for the interface in the ECMAScript binding. Similarly, if it appears on an exception it indicates that an exception interface object will not exist for the exception in the ECMAScript binding.
The [NoInterfaceObject] must take no argument.
Should this be [InterfaceObject] instead, and default to not having one?
The following IDL fragment defines two interfaces, one whose interface object is exposed on the ECMAScript global object, and one whose isn’t:
interface Storage {
void addEntry(in unsigned long key, in any value);
};
[NoInterfaceObject]
interface Query {
any lookupEntry(in unsigned long key);
};An ECMAScript implementation of the above IDL would allow manipulation of Storage’s prototype, but not Query’s.
typeof Storage; // evaluates to "object"
// Add some tracing alert() call to Storage.addEntry.
var fn = Storage.prototype.addEntry;
Storage.prototype.addEntry = function(key, value) {
alert('Calling addEntry()');
return fn.call(this, key, value);
};
typeof Query; // evaluates to "undefined"
var fn = Query.prototype.lookupEntry; // exception, Query isn’t defined
If the [NameGetter] extended attribute appears on an operation with a single sequence<unsigned short> valuetype argument, it indicates that an object that implements the interface can be indexed with a string, resulting in the same effect as calling the operation with the given index name (for languages that support such object indexing). If an object has both a [NameGetter]- and [IndexGetter]-annotated operation, then which operation is invoked when an object is indexed is language binding specific.
The [NameGetter] extended attribute must take no argument.
See section 3.8.3 for an example of the use of [NameGetter].
I’m somewhat uncomfortable giving sequence<unsigned short> such special status here.
Perhaps the language should special case DOMString to make it always refer to a string, but still allow it to be typedefed to sequence<unsigned short> for compatibility?
If the [NameSetter] extended attribute appears on an operation with two arguments, the first of which is a sequence<unsigned short> boxed valuetype, it indicates that an object that implements the interface can be indexed with a string for assignment, resulting in the same effect as calling the operation with the given index and value to assign (for languages that support such object indexing). If an object implements interfaces such that it has more than one operation annotated with [NameSetter], then which operation is invoked when an object is indexed with a boxed sequence<unsigned short> value for assignment is undefined.
The [NameSetter] extended attribute must take no argument.
See section 3.8.3 for an example of the use of [NameSetter].
If the [NoNull] extended attribute appears on an attribute, an operation or an operation argument, whose type is a boxed valuetype, it indicates that a null value is not expected and will never be returned. How implementations treat the assignment of a null value to an attribute with the [NoNull] extended attribute, or passing a null value as a [NoNull] operation argument, is specific to the language binding.
The [NoNull] extended attribute must take no argument.
The following IDL fragment defines an interface that has one attribute with the [NoNull] extended attribute, and one operation with an argument that has the extended attribute:
valuetype DOMString sequence<unsigned short>;
interface Dog {
[NoNull] attribute DOMString name;
attribute DOMString shortName;
boolean isMemberOfBreed([NoNull] in DOMString breedName);
};An ECMAScript implementation implementing the Dog interface would not allow the null value to be assigned to the name property or passed as the argument to the isMemberOfBreed function:
var d = getDog(); // Assume d is a host object implementing the Dog interface.
d.name = null; // This assigns the string "null" to the .name property.
d.isMemberOfBreed(null); // This passes the string "null" to the isMemberOfBreed function.Perhaps instead of having a [NoNull] extended attribute on DOMString arguments/attributes, different types could be used, e.g.:
typedef sequence<unsigned short> DOMString;
valuetype DOMStringOrNull DOMString;If the [PutForwards] extended attribute appears on a read only attribute declaration whose type is an object implementing an interface, it indicates that assigning to the attribute will have specific behavior. Namely, the assignment is “forwarded” to the attribute (specified by the extended attribute argument) on the object that is currently the value of the attribute being assigned to.
It is language binding specific what behavior occurs when assigning to such an attribute when its value is null.
The [PutForwards] extended attribute must take a single argument, an identifier, which must be the identifier of an attribute that exists on the interface that is the type of this attribute, which is the attribute that assignments will be forward to.
The following IDL fragment defines interfaces for names and people. The [PutForwards] extended attribute is used on the name attribute of the Person interface to indicate that assignments to that attribute result in assignments to the full attribute of the Person object:
valuetype DOMString sequence<unsigned short>;
interface Name {
attribute DOMString full;
attribute DOMString family;
attribute DOMString given;
};
interface Person {
[PutForwards=full] readonly attribute Name name;
attribute unsigned short age;
};In the ECMAScript binding, this would allow assignments to the name property:
var p = getPerson(); // Assume p is a host object implementing the Person interface.
p.name = 'John Citizen'; // This statement...
p.name.full = 'John Citizen'; // ...has the same behavior as this one.If the [Stringifies] extended attribute appears on an interface, it indicates that, for language bindings that support object stringification, an object that implements the interface will stringify in a non-default manner.
The [Stringifies] extended attribute may take a single argument, an identifier, which identifies an attribute on the interface whose value will be used as the result of the stringification. If the argument is not supplied, the stringification behavior must be described in prose.
The following IDL fragment defines an interface that will stringify to the value of its name attribute:
[Constructor, Stringifies=name]
interface Student {
unsigned long id;
DOMString name;
};In the ECMAScript binding, using a Student object in a context where a string is expected will result in the value of the object’s name property being used:
var s = new Student();
s.id = 12345678;
s.name = '周杰倫';
var greeting = 'Hello, ' + s + '!'; // Now greeting == 'Hello, 周杰倫!'.The following IDL fragment defines an interface that has custom stringification behavior that is not specified in the IDL itself.
[Constructor, Stringifies]
interface Student {
unsigned long id;
DOMString familyName;
[NoNull] DOMString givenName;
};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 the value of the givenName attribute, the string " " and the value of the familyName attribute.
An ECMAScript implementation of the IDL would behave as follows:
var s = new Student();
s.id = 12345679;
s.familyName = 'Smithee';
s.givenName = 'Alan';
var greeting = 'Hi ' + s; // Now greeting == 'Hi Alan Smithee'.If the [Variadic] extended attribute appears on the final argument of an operation, it indicates that the operation is variadic, and can be passed zero or more arguments after the regular arguments. Each of these extra arguments will have to be of the type specified by that final argument. How such arguments are passed is specific to the language binding.
The [Variadic] extended attribute must take no argument.
The following IDL fragment defines an interface that has a variadic operation:
interface IntegerSet {
readonly unsigned long cardinality;
void union([Variadic] in long integers);
void intersection([Variadic] in long integers);
};In the ECMAScript binding, variadic operations are implemented by functions that can accept the subsequent arguments:
var s = getIntegerSet(); // Assume s is a host object implementing the IntegerSet interface.
s.union(); // Passing no arguments corresponding to 'integers'.
s.union(1, 4, 7); // Passing three arguments corresponding to 'integers'.A binding for a language that does not support variadic functions may specify that an explicit array or list of integers be passed to such an operation.
This section describes how definitions written with the IDL in section 3 correspond to particular constructs in ECMAScript 3rd edition.
Unless otherwise specified, every object described in this section has internal properties [[Get]], [[Put]], [[CanPut]], [[HasProperty]], [[Delete]] and [[DefaultValue]] with the same behavior as specified for native objects, as described in section 8.6.2 of [ECMA-262].
If a value for the internal property [[Class]] is not given for a particular object, its value is implementation specific.
This section describes how types in the IDL map to types in ECMAScript.
Passing a value to a host object expecting type T is used in this sub-section to describe passing an ECMAScript value as an argument to a function whose corresponding operation in the IDL specifies that the argument is of type T, or assigning to a property whose corresponding attribute or exception member in the IDL is of type T. Conversely, returning a value of type T from a host object is used to describe obtaining the ECMAScript return value from a function whose corresponding operation in the IDL specifies a return type T, or retrieving a property whose corresponding attribute or exception member in the IDL is of type T.
Each sub-section below describes how a values of a given IDL type are represented in ECMAScript. For each IDL type, it is described how ECMAScript values are converted to an IDL value when passed to a host object expecting that type, and how IDL values of that type are converted to ECMAScript values when returned from a host object.
The IDL any type can correspond to any ECMAScript type.
Since there is no ECMAScript value that does correspond to an IDL value, no conversion is performed when passing an ECMAScript value to a host object expecting any, or when a host object returns a value of type any.
The only place that the void type may appear in IDL is as the return type of an operation. Functions on host objects that implement an operation whose IDL specifies a void return type must return the undefined value.
ECMAScript functions that implement an operation whose IDL specifies a void return type may return any value, which will be discarded.
IDL boolean values are represented by ECMAScript Boolean values.
Values passed to a host object expecting a boolean must first be converted to an ECMAScript Boolean value by the ToBoolean operator defined in section 9.2 of [ECMA-262].
boolean values returned from a host object must be ECMAScript Boolean values.
IDL octet values are represented by integer ECMAScript Number values in the range [0, 255].
Values passed to a host object expecting an octet must first be converted to an ECMAScript Number value by the ToUint8 operator, which functions (analogously to the ToUint32 operator defined in section 9.6 of [ECMA-262]) as follows:
octet values returned from a host object must be integer ECMAScript Number values in the range [0, 255].
IDL short values are represented by integer ECMAScript Number values in the range [−32768, 32767].
Values passed to a host object expecting a short must first be converted to an ECMAScript Number value by the ToInt16 operator, which functions (analogously to the ToInt32 operator defined in section 9.5 of [ECMA-262]) as follows:
short values returned from a host object must be integer ECMAScript Number values in the range [−32768, 32767].
IDL unsigned short values are represented by integer ECMAScript Number values in the range [0, 65535].
Values passed to a host object expecting an unsigned short must first be converted to an ECMAScript Number value by the ToUint16 operator defined in section 9.7 of [ECMA-262].
unsigned short values returned from a host object must be integer ECMAScript Number values in the range [0, 65535].
IDL long values are represented by integer ECMAScript Number values in the range [−2147483648, 2147483647].
Values passed to a host object expecting an long must first be converted to an ECMAScript Number value by the ToInt32 operator defined in section 9.5 of [ECMA-262].
long values returned from a host object must be integer ECMAScript Number values in the range [−2147483648, 2147483647].
IDL unsigned long values are represented by integer ECMAScript Number values in the range [0, 4294967295].
Values pas