W3C

Web IDL

W3C Working Draft 21 October 2010

This Version:
http://www.w3.org/TR/2010/WD-WebIDL-20101021/
Latest Version:
http://www.w3.org/TR/WebIDL/
Previous Version:
http://www.w3.org/TR/2008/WD-WebIDL-20081219/
Editor:
Cameron McCormack, Mozilla Corporation <cam@mcc.id.au>

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 and Java execution environments is also detailed.

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 http://www.w3.org/TR/.

This document is the 21 October 2010 Working Draft of the Web IDL specification. Please send comments about this document to public-script-coord@w3.org (archived).

Previous discussion of this specification has taken place on two other mailing lists: public-webapps@w3.org (archive) and public-webapi@w3.org (archive).

Web IDL is intended to specify in detail the interface definition language used by W3C specifications to define 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 specifications, and that newly published specifications reference this document to ensure conforming implementations of interfaces are interoperable.

Previous working drafts of this document were called Language Bindings for DOM Specifications. Also note that this document is unrelated to Web Interface Definition Language, a W3C Member submission from some time ago [WIDLNOTE].

This document is produced by the Web Applications 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.

In addition to the issues marked by editorial notes in this document, there is a list of open bugs on the specification.

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.

Table of Contents

Editorial note

HTML 5 uses Date, so we'll need to decide what to do with that.

Current thoughts are to be able to state that an interface has a custom mapping to language bindings, and to map that type to a Date in ECMAScript and a java.util.Date in Java.

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 5th Edition and Java 5 are given.

2. Conformance

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”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY” and “OPTIONAL” in this document are to be interpreted as described in Key words for use in RFCs to Indicate Requirement Levels [RFC2119].

The following conformance classes are defined by this specification:

conforming IDL fragment

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.

conforming implementation

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.

conforming ECMAScript implementation

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.

conforming Java implementation

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.

Editorial note

Do we need to be able to “import” other IDL fragments? (Mail.)

3. Interface definition language

This section describes a language with which interfaces can be defined in a language independent manner.

Editorial note

There’s a request for an enum definition. (Mail.)

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 that are language binding agnostic are discussed in section 3.8, while those specific to the ECMAScript language binding are discussed in section 4.2.

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.

[1]DefinitionsExtendedAttributeList Definition Definitions
 | ε
[2]DefinitionModule
 | Interface
 | Exception
 | Typedef
 | ImplementsStatement

3.1. Names

Every module, interface, exception, typedef, constant, attribute and exception field has an identifier, as do some operations. The identifier is determined by an identifier terminal somewhere in the derivation of the non-terminal corresponding to the given construct:

Note

Operations can have no identifier when they are being used to declare a special kind of operation, such as a getter or setter.

The identifier terminal then determines the identifier as follows:

  • If the value of the identifier terminal begins with a U+005F LOW LINE ("_") character, then the identifier of the definition, interface member or exception member is the value of the identifier terminal without that leading U+005F LOW LINE ("_") character.
  • Otherwise, the value of the identifier terminal does not begin with a U+005F LOW LINE ("_") character. The identifier of the definition, interface member or exception member is the value of the identifier terminal.
Note

So the identifier is just the value of the relevant identifier terminal with any leading "_" character removed. A leading "_" is used to escape an identifier from looking like a reserved word terminal.

Every module, interface, exception and typedef also has a qualified name, determined as follows:

  • If the definition is declared at the outermost scope, then the qualified name of the definition is two consecutive U+003A COLON (":") characters followed by the identifier of the definition.
  • Otherwise, the definition is not declared at the outermost scope. The qualified name of the definition is the qualified name of the definition’s enclosing module followed by two consecutive U+003A COLON (":") characters followed by the identifier of the definition.

The qualified name of every module, interface, exception and typedef MUST NOT be the same as the qualified name of any other interface, exception or typedef.

Note

Multiple module declarations can have the same qualified name. When a subsequent module declaration for the same qualified name is encountered, this effectively re-opens the module for definitions. See section 3.2 below for details.

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:

  • If the scoped name is a relative scoped name, then the following steps gives the definition it resolves to:
    1. Let n be the qualified name of the module.
    2. While n is not the empty string:
      1. If there exists a definition whose qualified name is equal to the concatenation of n, two U+003A COLON (":") characters and the scoped name, then the scoped name resolves to that definition; end these steps.
      2. Remove the last name component from n (that is, from the second last U+003A COLON (":") character to the end of the string, inclusive).
    3. The scoped name does not resolve to a definition.
  • Otherwise, the scoped name is an absolute scoped name:
    • If there exists a definition whose qualified name is equal to the scoped name, then the scoped name resolves to that definition.
    • Otherwise, the scoped name does not resolve to a definition.
Example

The following IDL fragment demonstrates how identifiers and qualified names are given to definitions, interface members and exception members.

IDL
// Module identifier: "framework"
// Qualified name:    "::framework"
module framework {

  // Typedef identifier: "number"
  // Qualified name:    "::framework::number"
  typedef float number;

  // Exception identifier: "FrameworkException"
  // Qualified name:       "::framework::FrameworkException"
  exception FrameworkException {

    // Constant identifier: "ERR_NOT_FOUND"
    // Qualified name:      "::framework::FrameworkException::ERR_NOT_FOUND"
    const long ERR_NOT_FOUND = 1;

    // Exception field identifier: "code"
    long code;
  };

  // Interface identifier: "System"
  // Qualified name:       "::framework::System"
  interface System {

    // Operation identifier:          "createObject"
    // Operation argument identifier: "interface"
    object createObject(in DOMString _interface);

    // Operation has no identifier; it declares a getter.
    getter DOMString (in DOMString keyName);
  };

  // Module identifier: "gui"
  // Qualified name:    "::framework::gui"
  module gui {
    
    // Interface identifier: "TextField"
    // Qualified name:       "::framework::gui::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 quoted terminal symbol in the IDL grammar), it is still unescaped to obtain the attribute’s identifier.

[53]ScopedNameAbsoluteScopedName
 | RelativeScopedName
[54]AbsoluteScopedName"::" identifier ScopedNameParts
[55]RelativeScopedNameidentifier ScopedNameParts
[56]ScopedNameParts"::" identifier ScopedNameParts
 | ε

3.2. Modules

Editorial note

Should W3C specs place use modules at all? (Mail.)

A module is a definition that matches the Module non-terminal, and serves as a container for grouping together related definitions.

The enclosing module of a definition is defined as follows:

  • If the definition is declared at the outermost scope, then the definition has no enclosing module.
  • Otherwise, the definition is not declared at the outermost scope. The enclosing module of the definition is the closest Module ancestor of the non-terminal representing the definition in the IDL fragment’s parse tree.

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 name of that namespace can be based on the module’s prefixed name, which is defined as follows:

In the Java language binding, the name of the Java package is derived by taking the prefixed name and replacing occurrences of “::” with “.” (see section 5.3). It is expected that bindings for other languages that typically use reversed domain names for namespacing will also use the prefixed name of a module to determine namespace names.

The ECMAScript language binding allows a namespacing mechanism based on the scoped name of a module by using the [NamespaceObject] extended attribute.

The following extended attributes are applicable to modules: [NamespaceObject], [Prefix].

[3]Module"module" identifier "{" Definitions "}" ";"
Example

The following IDL fragment illustrates how related interfaces can be grouped together in modules:

IDL
module gfx {

  module geom {
    interface Shape { /* ... */ };
    interface Rectangle : Shape { /* ... */ };
    interface Path : Shape { /* ... */ };
  };

  interface GraphicsContext {
    void fillShape(in geom::Shape s);
    void strokeShape(in geom::Shape s);
  };
};

module gui {

  interface Widget { /* ... */  };

  interface Window : Widget {
    gfx::GraphicsContext getGraphicsContext();
  };

  interface Button : Widget { /* ... */  };
};

3.3. Interfaces

Editorial note

A request for static members. (Mail.)

An interface is a definition that matches the Interface non-terminal. 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 Interface. Objects implementing the interface will have members that correspond to each of the interface’s members.

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.

Editorial note

Multiple inheritance “might not be needed”. (Minutes.)

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.

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.

The following extended attributes are applicable to interfaces: [Callback], [Constructor], [NamedConstructor], [NoInterfaceObject], [PrototypeRoot].

[4]Interface"interface" identifier InterfaceInheritance "{" InterfaceMembers "}" ";"
[5]InterfaceInheritance":" ScopedNameList
 | ε
[6]InterfaceMembersExtendedAttributeList InterfaceMember InterfaceMembers
 | ε
[7]InterfaceMemberConst
 | AttributeOrOperation
[51]ScopedNameListScopedName ScopedNames
[52]ScopedNames"," ScopedName ScopedNames
 | ε
Example

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;
};

3.3.1. Constants

A constant is a declaration that matches the Const non-terminal, and is used to bind a constant value to a name. Constants can appear on interfaces and exceptions.

The identifier of a constant MUST NOT be the same as the identifier of another interface member defined on the same interface or another exception member defined on the same exception.

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 the "true" terminal is the boolean value true.
  • The value of the "false" terminal is the boolean value false.

The value of an integer terminal is an integer, and is determined as follows:

  1. Let S be the string value of the integer terminal.
  2. Let n be the length of S.
  3. Initialize mag to 0.
  4. Initialize sign to 1.
  5. Initialize base to 10.
  6. Initialize i to 0.
  7. If the first character of S is U+002D HYPHEN-MINUS ("-"), then:
    1. Set sign to −1.
    2. Set i to 1.
  8. If the ith zero-based character of S is U+0030 DIGIT ZERO ("0"), then:
    1. Set i to i + 1.
    2. If the ith zero-based character of S is U+0058 LATIN CAPITAL LETTER X ("X") or U+0078 LATIN SMALL LETTER X ("x"), then:
      1. Set i to i + 1.
      2. Set base to 16.
    3. Otherwise, set base to 8.
  9. While i < n:
    1. Let c be the ith zero-based character of S.
    2. Let digit be a value as follows, according to c:
      In the range U+0030 DIGIT ZERO ("0") to U+0039 DIGIT NINE ("9")
      The value is the Unicode codepoint of c minus 48.
      In the range U+0041 LATIN CAPITAL LETTER A ("A") to U+0046 LATIN CAPITAL LETTER F ("F")
      The value is the Unicode codepoint of c minus 65.
      In the range U+0061 LATIN SMALL LETTER A ("a") to U+0066 LATIN SMALL LETTER F ("f")
      The value is the Unicode codepoint of c minus 97.
    3. Set mag to mag * base + digit.
    4. Set i to i + 1.
  10. The value of the integer terminal is sign * mag.
Note

The algorithm above specifies nothing unexpected. It interprets strings that match the regular expressions ^-?0[Xx][0-9A-Fa-f]+$, ^-?0[0-7]+$ and ^-?[0-9]+$ as hexadecimal, octal and decimal integers, respectively. It differs from the Java java.lang.Long.parseLong(String) method only in that it can parse integers outside the range of a Java long.

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 value of a float terminal 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 it is being used as the value for, determined as follows:

  1. Let S be the string value of the float terminal.
  2. Let n be the length of S.
  3. Initialize mant to 0.
  4. Initialize sign to 1.
  5. Initialize exp1 to 0.
  6. Initialize exp2 to 0.
  7. Initialize expSign to 1.
  8. Initialize afterDot to false.
  9. Initialize i to 0.
  10. If the first character of S is U+002D HYPHEN-MINUS ("-"), then:
    1. Set sign to −1.
    2. Set i to 1.
  11. While i < n and the ith zero-based character of S is neither U+0045 LATIN CAPITAL LETTER E ("E") nor U+0045 LATIN SMALL LETTER E ("e"), then:
    1. If the ith zero-based character of S is U+002E FULL STOP ("."), then set afterDot to true.
    2. Otherwise:
      1. Let digit be the Unicode codepoint of the ith zero-based character of S minus 48.
      2. Set mant to mant * 10 + digit.
      3. If afterDot is true, set exp1 to exp1 − 1.
    3. Set i to i + 1.
  12. If i < n, then:
    1. If the ith zero-based character of S is U+002D HYPHEN-MINUS ("-"), then:
      1. Set expSign to −1.
      2. Set i to i + 1.
    2. If the ith zero-based character of S is U+002B PLUS SIGN ("+"), then set i to i + 1.
    3. While i < n:
      1. Let digit be the Unicode codepoint of the ith zero-based character of S minus 48.
      2. Set exp2 to exp2 * 10 + digit.
      3. Set i to i + 1.
  13. Let result be sign * mant * 10expSign * exp2 + exp1.
  14. If the float terminal is being used as the value for a float, then the value of the float terminal is the IEEE 754 single-precision floating point number closest to result. Otherwise, the float terminal is being used as the value for a double, and the value of the float terminal is the IEEE 754 double-precision floating point number closest to result. [IEEE-754]

It is not possible to specify an infinite or not-a-number float constant.

The type of a float terminal is the same as the type of the constant it is being used as the value of. The value of the float terminal MUST NOT lie outside the valid range of values for its type, as given in section 3.7 below.

The value assigned to a constant MUST have the same type as the type that the constant is declared to be.

No extended attributes are applicable to constants.

[12]Const"const" Type identifier "=" ConstExpr ";"
[13]ConstExprBooleanLiteral
 | integer
 | float
[14]BooleanLiteral"true"
 | "false"
Example

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 float AVOGADRO = 6.022e23;
};

exception Error {
  const short ERR_UNKNOWN = 0;
  const short ERR_OUT_OF_MEMORY = 1;

  short errorCode;
};

3.3.2. Attributes

An attribute is an interface member that matches an AttributeOrOperation non-terminal with an Attribute non-terminal in its derivation, and is used to declare that objects implementing the interface will have an attribute with the given identifier whose value can be retrieved and (in some cases) changed.

The identifier of an attribute MUST NOT be the same as the identifier of another interface member defined on the same interface.

The type of the attribute is given by the Type non-terminal. If the Type 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 or typedef.

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.

When the "stringifier" keyword is used in an attribute declaration, it indicates that objects implementing the interface will be stringified to the value of the attribute. See section 3.3.4.2 below for details.

If an implementation attempts to get or set the value of an attribute on an object implemented by user code (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 attributes: [PutForwards], [Replaceable], [TreatNullAs], [TreatUndefinedAs].

[15]AttributeOrOperation"stringifier" StringifierAttributeOrOperation
 | Attribute
 | Operation
[16]StringifierAttributeOrOperationAttribute
 | OperationRest
 | ";"
[17]AttributeReadOnly "attribute" Type identifier GetRaises SetRaises ";"
[18]ReadOnly"readonly"
 | ε
[19]GetRaises"getraises" ExceptionList
 | ε
[20]SetRaises"setraises" ExceptionList
 | ε
[28]ExceptionList"(" ScopedNameList ")"
Example

The following IDL fragment demonstrates how attributes can be declared on an interface:

IDL
exception InvalidName {
  DOMString reason;
};

exception NoSuchPet { };

interface Person {

  // A simple attribute that can be set to any value in the range an unsigned
  // short can take.
  attribute unsigned short age;

  // An attribute that can raise an exception if it is set to an invalid value.
  attribute DOMString name setraises (InvalidName);

  // An attribute whose value cannot be assigned to, and which can raise an
  // exception in some circumstances.
  readonly attribute DOMString petName getraises (NoSuchPet);
};

3.3.3. Operations

An operation is an interface member that matches an AttributeOrOperation non-terminal with no Attribute non-terminal in its derivation. There are two kinds of operation: regular operations, which are those used to declare that objects implementing the interface will have a method with the given identifier, and special operations, which are used to declare special behavior on objects implementing the interface, such as object indexing and stringification.

If an operation has an identifier, 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.3.4 below 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 MUST NOT be the same as the identifier of a constant or attribute defined on the same interface.

Note

The identifier can be the same as that of another operation on the interface, however. This is how operation overloading is specified.

Editorial note

Travis requests no operation overloading. (Mail).

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 Type 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 or typedef.

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 Type. If the Type 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 or typedef.

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 "in" keyword used in the declaration of each argument is optional. No other types of arguments (such as out or in-out arguments) can be specified with Web IDL.

Example

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;
};

exception NoPointerDevice { };

interface Button {

  // An operation that takes no arguments, returns a boolean, and could possibly
  // raise an exception.
  boolean isMouseOver() raises (NoPointerDevice);

  // Overloaded operations.
  void setDimensions(in Dimensions size);
  void setDimensions(in unsigned long width, in unsigned long height);
};

An operation is considered to be a variadic operation if the final argument uses the "..." terminal 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 "..." terminal unless it is the final argument in the operation’s argument list.

Example

The following IDL fragment defines an interface that has two variadic operations:

IDL
interface IntegerSet {
  readonly attribute unsigned long cardinality;

  void union(in long... ints);
  void intersection(in 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 an the argument value can be omitted when the operation is invoked. An argument MUST NOT be declared to be optional unless any subsequent arguments to the operation are also optional.

Example

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(in float v1, in float v2, in float v3, in optional float alpha);
};

It is equivalent to an interface that has two overloaded operations:

IDL
interface ColorCreator {

  object createColor(in float v1, in float v2, in float v3);
  object createColor(in float v1, in float v2, in float v3, in float alpha);
};

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.

If an implementation attempts to invoke an operation on an object implemented by user code (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 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: [TreatNullAs], [TreatUndefinedAs].

The following extended attributes are applicable to operation arguments: [AllowAny], [TreatNullAs], [TreatUndefinedAs].

[21]OperationOmittableSpecials OperationRest
[22]OmittableSpecials"omittable" Specials
 | Specials
[23]SpecialsSpecial Specials
 | ε
[24]Special"getter"
 | "setter"
 | "creator"
 | "deleter"
 | "caller"
[25]OperationRestReturnType OptionalIdentifier "(" ArgumentList ")" Raises ";"
[26]OptionalIdentifieridentifier
 | ε
[27]Raises"raises" ExceptionList
 | ε
[29]ArgumentListArgument Arguments
 | ε
[30]Arguments"," Argument Arguments
 | ε
[31]ArgumentExtendedAttributeList In Optional Type Ellipsis identifier
[32]In"in"
 | ε
[33]Optional"optional"
 | ε
[34]Ellipsis"..."
 | ε
[50]ReturnTypeType
 | "void"

3.3.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 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.
Creators "creator" Defines behavior for when an object is indexed for property creation.
Deleters "deleter" Defines behavior for when an object is indexed for property deletion.
Callers "caller" 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.

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.

Example

The following IDL fragment defines an interface with a getter and a setter:

IDL
interface Dictionary {
  readonly attribute unsigned long propertyCount;

  getter float (in DOMString propertyName);
  setter void (in DOMString propertyName, in float propertyValue);
};

In language bindings that do not support property getters and setters, objects implementing Dictionary will not have that special behavior. For example, in the Java language binding, the corresponding Java interface will have only a single method, long getPropertyCount().

Special operations can be declared using an operation that has an identifier and the "omittable" keyword to indicate that in language bindings that do not support that kind of special operation, the regular operation is to be available on the object for use instead. Such operations are known as omittable.

Example

The following IDL fragment declares special operations with identifiers and using the "omittable" keyword:

IDL
interface Dictionary {
  readonly attribute unsigned long propertyCount;

  omittable getter float getProperty(in DOMString propertyName);
  omittable setter void setProperty(in DOMString propertyName, in float propertyValue);
};

In language bindings that do not support property getters and setters, such as Java, objects implementing Dictionary will have getProperty and setProperty operations available. The corresponding Java interface would be:

Java
public interface Dictionary {

  long getPropertyCount();
  float getProperty(String propertyName);
  void setProperty(String propertyName, float propertyValue);
}

These operations will be omitted in language bindings that do support property getters and setters, such as ECMAScript, however.

ECMAScript
var dictionary = getDictionary();  // Get an instance of Dictionary.

dictionary.getProperty;            // Actually invokes the property getter with property name "getProperty".
dictionary.x = 1;                  // Invokes the property setter with property name "x" and value 1.

Defining a special operation without using the "omittable" keyword on an operation but giving the operation an identifier is equivalent to separating the special operation out into a separate declaration without an identifier. This approach is admitted to simplify prose descriptions of an interface’s operations.

Example

The following two interfaces are equivalent:

IDL
interface Dictionary {
  readonly attribute unsigned long propertyCount;

  getter float getProperty(in DOMString propertyName);
  setter void setProperty(in DOMString propertyName, in float propertyValue);
};
IDL
interface Dictionary {
  readonly attribute unsigned long propertyCount;

  float getProperty(in DOMString propertyName);
  void setProperty(in DOMString propertyName, in float propertyValue);

  getter float (in DOMString propertyName);
  setter void (in DOMString propertyName, in float propertyValue);
};

The "omittable" keyword MUST NOT appear on an operation that has no identifier.

A given special keyword MUST NOT appear twice on an operation.

Editorial note

There’s a resolution to remove unnamed getters/setters. (Minutes.)

Getters, setters, creators and deleters come in two varieties: ones that take a DOMString as a property name, known as name getters, name setters, name creators and name deleters, and ones that take an unsigned long as a property index, known as index getters, index setters, index creators and index deleters. See section 3.3.4.3 and section 3.3.4.4 for details.

On a given interface, there MUST exist at most one stringifier and at most one of each variety of getter, setter, creator and deleter. Multiple callers can exist on an interface to specify overloaded calling behavior.

Special operations declared using operations MUST NOT be variadic nor have any optional arguments.

If an object implements more than one interface that defines a given special operation, then it is undefined which (if any) special operation is invoked.

3.3.4.1. Callers

When an interface has one or more callers, it indicates that objects that implement the interface can be called as if they were functions. As mentioned above, callers can be specified using an operation declared with the "caller" keyword.

If multiple callers are specified on an interface, overload resolution is used to determine which caller is invoked when the object is called as if it were a function.

Example

The following IDL fragment defines an interface with a caller.

IDL
interface NumberQuadrupler {
  // This operation simply returns four times the given number x.
  caller float compute(in float x);
};

An ECMAScript implementation supporting this interface would allow a host 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.3.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.

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.

Example

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.

Example

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 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:

ECMAScript
var s = new Student();
s.id = 12345679;
s.familyName = 'Smithee';
s.givenName = 'Alan';

var greeting = 'Hi ' + s;  // Now greeting == 'Hi Alan Smithee'.
3.3.4.3. Indexed properties

An interface that defines an index getter, index setter, index creator and/or an index deleter 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.

Index getters and deleters MUST be declared to take a single unsigned long argument. Index setters and creators MUST be declared to take two arguments, where the first is an unsigned long.

The following requirements apply to the definitions of index getters, setters, creators and deleters:

  • If an index getter was specified using an operation with an identifier, then the value returned when indexing the object with a given index will be the value that is returned by invoking the operation, passing the index as its only argument. If the operation used to declare the index 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 index setter was specified using an operation with an identifier, then the behavior that occurs when indexing the object for property assignment with a given property index and value will be that 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 index 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 for a given property index and value.
  • If an index creator was specified using an operation with an identifier, then the behavior that occurs when indexing the object for property creation with a given property index and value will be that 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 index creator did not have an identifier, then the interface definition must be accompanied by a description of how to set the value of a new indexed property for a given property index and value.
  • If an index deleter was specified using an operation with an identifier, then the behavior that occurs when indexing the object for property deletion with a given property index will be that the operation is invoked, passing the index as the only argument. If the operation used to declare the index deleter did not have an identifier, then the interface definition must be accompanied by a description of how to delete an existing indexed property for a given property index.
Example

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(in unsigned long index);
  setter void setByIndex(in unsigned long index, in any value);
  deleter void removeByIndex(in unsigned long index);

  getter any get(in DOMString name);
  setter creator void set(in DOMString name, in any value);
  deleter void remove(in DOMString name);
};

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:

Objects implementing OrderedMap support index properties with indices in the range 0 ≤ index < OrderedMap::length.

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 section 4.5, an ECMAScript implementation would create properties on a host 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 host 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;   // If map.length > 1, then this will set the property named
                  // "1" on map to false, and then will do the equivalent of:
                  //
                  //   map.setByIndex(1, false)
                  //
                  // Otherwise, if map.length ≤ 1, then it will set the
                  // property but have no other effect (since an index creator
                  // was not specified).

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;  // Regardless of whether there exists a named property named
                  // "berry", this will set the "berry" property to 123, and
                  // then 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.3.4.4. Named properties

An interface that defines a name getter, name setter, name creator and/or a name deleter is said to support named properties.

If an interface supports named properties, then the interface definition MUST be accompanied by a description of what names the object can be indexed with at any given time. These names are called the supported property names.

Name getters and deleters MUST be declared to take a single DOMString argument. Index setters and creators MUST be declared to take two arguments, where the first is an DOMString.

The following requirements apply to the definitions of name getters, setters, creators and deleters:

  • If a name getter was specified using an operation with an identifier, then the value returned when indexing the object with a given name will be the value that is returned by invoking the operation, passing the name as its only argument. If the operation used to declare the name 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 name setter was specified using an operation with an identifier, then the behavior that occurs when indexing the object for property assignment with a given property name and value will be that 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 name 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 for a given property name and value.
  • If a name creator was specified using an operation with an identifier, then the behavior that occurs when indexing the object for property creation with a given property name and value will be that 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 name creator did not have an identifier, then the interface definition must be accompanied by a description of how to set the value of a new named property for a given property name and value.
  • If a name deleter was specified using an operation with an identifier, then the behavior that occurs when indexing the object for property deletion with a given property name will be that the operation is invoked, passing the name as the only argument. If the operation used to declare the name 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.

3.3.5. Overloading

If a regular operation defined on an interface has an identifier that is the same as the identifier of another operation on that interface, 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 callers defined on it, then those 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, callers and constructors can be specified to take, and in order to describe these restrictions, the notion of an effective overload set is used.

An effective overload set for a given identifier, argument count, interface and target language binding represents the allowable invocations in that language binding of operations or constructors (specified with [Constructor] and [NamedConstructor]) that have the specified identifier on that interface. The set is used to determine whether there are ambiguities in the overloaded operations or constructors specified on the interface. The effective overload set is stated to be “for regular operations”, “for constructors” or “for callers”, to distinguish between these three uses. Effective overload sets for callers do not use an identifier; only an argument count, interface and target language binding are needed.

The elements of an effective overload set are triples of the form <ftypesany>. If the effective overload set is for regular operations or for callers, then f is an operation, and if it is for constructors, then f is an extended attribute. In either case, types is a list of IDL types and any is a list of boolean values. Each triple represents an allowable invocation of the regular operation, constructor or caller with an argument value list of the given types. any specifies whether a particular argument has been annotated with the [AllowAny] extended attribute. 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 effective overload set for identifier A, argument count N, interface I and a given target language binding is derived as follows. Whenever an argument of an extended attribute is mentioned, it is referring to an argument of the extended attribute’s named argument list.

  1. Initialize S to ∅.
  2. 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 constructors
    The elements of F are the [NamedConstructor] extended attributes on interface I whose named argument lists’ identifiers are A. If A is the same as the identifier of interface I, then F also includes the [Constructor] extended attributes on I.
    For callers
    The elements of F are the callers defined on interface I.
  3. If the effective overload set is for regular operations, then:
    1. If the target language binding supports object indexing, then remove from F any operation that is declared to be an omittable getter, setter, creator or deleter.
    2. If the target language binding supports object calling, then remove from F any operation that is declared to be an omittable caller.
    3. If the target language binding supports object stringification, then remove from F any operation that is declared to be an omittable stringifier.
  4. Let maxarg be the maximum number of arguments the operations or constructor extended attributes in F are declared to take.
  5. Let m be the maximum of maxarg and N.
  6. For each operation or extended attribute X in F:
    1. Let n be the number of arguments X is declared to take.
    2. Let t0..n−1 be the types of the arguments X is defined to take.
    3. Let a0..n−1 be boolean values indicating whether each argument X is defined to take is declared with the [AllowAny] extended attribute.
    4. Add to S the triple <Xt0..n−1a0..n−1>.
    5. If n > 0 and X is declared to be variadic, then:
      1. Add to S the triple <Xt0..n−2a0..n−2>.
      2. For every integer i, such that n ≤ i ≤ m−1:
        1. Let u0..i be a list of types, where uj = tj (for j < n) and uj = tn−1 (for j ≥ n).
        2. Let b0..i be a list of booleans, where bj = aj (for j < n) and bj = an−1 (for j ≥ n).
        3. Add to S the triple <Xu0..ib0..i>.
    6. For every integer i, such that 0 < i < n:
      1. If argument i of X is optional, then add to S the triple <Xt0..i−1a0..i−1>.
    7. If n > 0 and the first argument of X is optional, then add to S the triple <X, (), ()> (where “()” represents the empty list).
  7. The effective overload set for identifier A and interface X is S.

For each pair of entries in an effective overload set at least one of the following MUST be true:

  • the type list lengths of the two entries are different, or
  • there is an index i such that the types in the two type lists at index i are distinguishable.

Two types are distinguishable if there is a “●” mark in the corresponding entry in the following table:

primitive primitive? DOMString DOMString? interface object sequence<T> sequence<T>? T[]
primitive
primitive?
DOMString
DOMString?
interface [1]
object
sequence<T>
sequence<T>?
T[]
Note

These restrictions on argument types reduce the possibility of resolution ambiguity in overloaded operations and constructors, but do not eliminate it. In the ECMAScript language binding, the restrictions still can result in overloaded operation and constructor invocations that cannot be distinguished solely based on the values passed to the corresponding function. For example, with the following interfaces:

IDL
interface A {
  // ...
};

interface B {
  // ...
};

interface C {
  void f(in A x);
  void f(in B x);
};

it is possible to pass an object that implements both A and B to f. Similarly, passing null to f would also be ambiguous. Since the ECMAScript language binding provides no way to disambiguate such calls, the interface description will need to describe which operation is invoked in these cases. (It is acceptable not to describe this if there is no observable difference in behavior for a particular choice of operation or constructor to disambiguate the call, or if no object will actually implement the two interfaces, for example.)

Example

For the following interface:

IDL
interface A {
  /* f1 */ void f(in DOMString a);
  /* f2 */ void f([AllowAny] in DOMString a, in DOMString b, in float... c);
  /* f3 */ void f();
  /* f4 */ void f(in long a, in DOMString b, in optional DOMString c, in float... d);
};

the effective overload set for identifier f with argument count 4 (for the ECMAScript language binding) is:

{ <f1, (DOMString), (false)>,
<f2, (DOMString, DOMString), (true, false)>,
<f2, (DOMString, DOMString, float), (true, false, false),
<f2, (DOMString, DOMString, float, float, (true, false, false, false))>,
<f3, (), ()>,
<f4, (long, DOMString), (false, fase)>,
<f4, (long, DOMString, DOMString), (false, false)>,
<f4, (long, DOMString, DOMString, float), (false, false, false, false)> }

There are thus no overloaded operation resolution ambiguities for the interface.

3.4. Exceptions

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 constants and exception fields declared on them (together known as exception members), rather than the three types of interface members.

Exception fields declared using the ExceptionField production. An exception field’s type is given by the Type non-terminal of the ExceptionField. If the Type is a scoped name, then it MUST resolve, with respect to the enclosing module of the exception on which the exception field is declared, to an interface or typedef.

The identifier of an exception field MUST not be the same as that of another exception member of a constant defined on the exception.

Exception fields 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 fields.

[8]Exception"exception" identifier "{" ExceptionMembers "}" ";"
[9]ExceptionMembersExtendedAttributeList ExceptionMember ExceptionMembers
 | ε
[35]ExceptionMemberConst
 | ExceptionField
[36]ExceptionFieldType identifier ";"
Example

See section 3.3.2 above for an example of an IDL fragment that declares exceptions.

3.5. Typedefs

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.

No extended attributes are applicable to typedefs.

[10]Typedef"typedef" Type identifier ";"
Example

The following IDL fragment demonstrates the use of typedefs to allow the use of a short identifier instead of a long scoped name or sequence type.

IDL
module gfx {
  module geom {
    module geom2d {

      interface Point {
        attribute float x;
        attribute float y;
      };

      typedef sequence<Point> PointSequence;

      interface Rect {
        attribute Point topleft;
        attribute Point bottomright;
      };
    };
  };
};

module gui {

  typedef gfx::geom::geom2d::Point Point;
  typedef gfx::geom::geom2d::PointSequence PointSequence;
  typedef gfx::geom::geom2d::Rect Rect;

  interface Widget {

    readonly attribute Rect bounds;

    boolean pointWithinBounds(in Point p);
    boolean allPointsWithinBounds(in PointSequence ps);
  };
};

3.6. Implements statements

An implements statement is a definition matching ImplementsStatement, which declares that all objects implementing an interface A (identified by the first scoped name) MUST also implement interface B (identified by the second scoped name).

Implements statements can appear on a module or at the outermost scope.

The two scoped names MUST resolve, with respect to the enclosing module of the implements statement, to an interface or typedef.

No extended attributes are applicable to implements statements.

[11]ImplementsStatementScopedName "implements" ScopedName ";"
Example

The following IDL fragment defines two interfaces, stating that one interface is always implemented on objects implementing the other.

IDL
module dom {
  interface Node {
    readonly attribute unsigned short nodeType;
    // ...
  };
};

module events {

  interface EventTarget {
    void addEventListener(in DOMString type,
                          in EventListener listener,
                          in boolean useCapture);
    // ...
  };

  dom::Node implements EventTarget;
};

An ECMAScript implementation would thus have an addEventListener property in the prototype chain of every Node:

ECMAScript
var n = getNode();          // Obtain an instance of Node.
typeof n.addEventListener;  // Evaluates to "function".

Similarly, in Java, any Node object could be cast to EventTarget:

Java
Node n = getNode();               // Obtain an instance of Node.
EventTarget et = (EventTarget) n; // This should never throw ClassCastException.

Note that it is not the case that all EventTarget objects implement Node.

3.7. Types

This section lists the types supported by the IDL, the set of values each type correspond to, and how constants of that type are represented.

The following types are known as primitive types: boolean, octet, short, unsigned short, long, unsigned long, long long, unsigned long long, float and double.

The object type and all interface types are known as object types.

Every type has a type name, which is a string, not necessarily unique, that identifies the type. Each sub-section below defines what the type name is for each type.

When conversions are made from language binding specific types to IDL types in order to invoke an operation or assign a value to an attribute, all conversions necessary will be performed before the operation is invoked or the attribute updated. If the conversion cannot be performed, then the operation will not be invoked 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.

[44]TypeNullableType
 | ScopedName
 | "any"
 | "object"
[45]NullableTypeUnsignedIntegerType Nullable
 | "boolean" Nullable
 | "octet" Nullable
 | "float" Nullable
 | "double" Nullable
 | "DOMString" Nullable
 | "sequence" "<" Type ">" Nullable
[46]UnsignedIntegerType"unsigned" IntegerType
 | IntegerType
[47]IntegerType"short"
 | "long" OptionalLong
[48]OptionalLong"long"
 | ε
[49]Nullable"?"
 | ε

3.7.1. any

The any type is the union of all other possible types. Its type name is “Any”.

3.7.2. boolean

The boolean type has two values: true and false.

boolean constant values in IDL are represented with the "true" and "false" terminals.

The type name of the boolean type is “Boolean”.

3.7.3. octet

Editorial note

Request for a signed 8-bit type. (Mail.)

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 type name of the octet type is “Octet”.

3.7.4. 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 terminals.

The type name of the short type is “Short”.

3.7.5. 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 terminals.

The type name of the unsigned short type is “UnsignedShort”.

3.7.6. 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 terminals.

The type name of the long type is “Long”.

3.7.7. 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 terminals.

The type name of the unsigned long type is “UnsignedLong”.

3.7.8. 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 terminals.

The type name of the long long type is “LongLong”.

3.7.9. 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 terminals.

The type name of the unsigned long long type is “UnsignedLongLong”.

3.7.10. float

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.

The type name of the float type is “Float”.

3.7.11. double

The double type is a floating point numeric type that corresponds to the set of possible double-precision 64 bit IEEE 754 floating point numbers. [IEEE-754]

double constant values in IDL are represented with float terminals.

The type name of the double type is “Double”.

3.7.12. DOMString

The DOMString type corresponds to the set of all possible sequences of 16 bit unsigned integer code units (to be interpreted as UTF-16 encoded strings [RFC2781]). 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, can be used.

There is no way to represent a DOMString constant value in IDL.

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. Authors of specifications using Web IDL might want to obtain a sequence of Unicode characters given a particular sequence of 16 bit unsigned integer code units, however. The following algorithm defines a way to convert a DOMString to a sequence of Unicode characters:

  1. Let S be the DOMString value.
  2. Let n be the length of S.
  3. Initialize i to 0.
  4. Initialize U to be an empty sequence of Unicode characters.
  5. While i < n:
    1. Let c be the code unit in S at index i.
    2. 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
      1. If i = n−1, then append to U a U+FFFD REPLACEMENT CHARACTER.
      2. Otherwise, i < n−1:
        1. Let d be the code unit in S at index i+1.
        2. If 0xDC00 ≤ d ≤ 0xDFFF, then:
          1. Let a be c & 0x3FF.
          2. Let b be d & 0x3FF.
          3. Append to U the Unicode character with code point 216+210a+b.
          4. Set i to i+1.
        3. Otherwise, d < 0xDC00 or d > 0xDFFF. Append to U a U+FFFD REPLACEMENT CHARACTER.
    3. Set i to i+1.
  6. Return U.

The type name of the DOMString type is “String”.

3.7.13. object

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.

The type name of the object type is “Object”.

3.7.14. Interface types

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 a constant value for interface types in IDL.

The type name of an interface type is the identifier of the interface.

3.7.15. 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. Only types that do not already allow null can have a nullable type created from them.

Nullable type constant values in IDL are represented in the same way as constant values of their inner type would be represented. There is no way to represent the null constant value, however.

The type name of a nullable type is the concatenation of the type name of the inner type T and the string “OrNull”.

Example

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 an attribute whose value can be a DOMString or the null value:

IDL
interface Node {
  readonly attribute DOMString? namespaceURI;
  // ...
};

It is not possible to have a type Node?, since interface types already allow the null value.

3.7.16. Sequences — sequence<T>

Editorial note

Do we need a ByteArray type defined somewhere? (For WebSocket and XHR2.)

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 user agent implemented object will not result in a reference to the sequence being kept by that object. Similarly, any sequence returned from a user agent implemented object will be a copy and modifications made to it will not be visible to the object.

There is no way to represent a sequence constant value in IDL.

The type name of a sequence type is the concatenation of the type name for T and the string “Sequence”.

Note

Since sequences are passed by value, a new copy of the object representing the sequence is returned every time an attribute of a sequence type is fetched. Thus, it usually is not appropriate to use a sequence type for an attribute. In the following example, a new Array object is allocated twice for every iteration of the loop (once in the loop test expression and once in the body of the loop):

IDL
interface X {
  readonly attribute sequence<long> numbers;
};
ECMAScript
var x = getX();  // Obtain an instance of X.
for (var i = 0; i < x.numbers.length; i++) {
  document.write(x.numbers[i] + '\n');
}

For attributes, it is recommended that a read only array is used instead.

3.7.17. Arrays — T[]

Editorial note

Arrays need to be in the grammar. (Mail.)

The T[] type is a parameterized type whose values are (possibly zero-length) arrays of values of type T or the special value null. Unlike sequences, arrays are passed by reference. Passing an array to a user agent implemented object could result in that array being modified by the object. An array returned from a user agent implemented object might also be modified by the object, and any modifications to the array performed by user code might be acted upon by the user agent implemented object.

Arrays can either be fixed length or variable length. Fixed length arrays cannot have their length changed by user code after they have been created, while variable length arrays can. Unless otherwise specified, arrays are fixed length.

Arrays can also be designated as being read only. User code cannot modify the values of read only array elements. If an array is read only, then it is also implicitly fixed length.

There is no way to represent an array constant value in IDL.

The type name of an array type is the concatenation of the type name for T and the string “Array”.

3.8. Extended attributes

Editorial note

A request to add a [DoNotCheckDomainSecurity]. (Mail.)

An extended attribute is an annotation that can appear on definitions, interface members, exception members and operation arguments, and is 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.

The ExtendedAttribute non-terminal matches nearly any sequence of tokens, however the extended attributes defined in this document only accept a more restricted syntax. Any extended attribute encountered in an IDL fragment is matched against the following five non-terminals to determine what form (or forms) it is in:

Non-terminal Form Example
ExtendedAttributeNoArg takes no argument [Replaceable]
ExtendedAttributeArgList takes an argument list [Constructor(in float x, in float y)]
ExtendedAttributeNamedArgList takes a named argument list [NamedConstructor=Image(in DOMString src)]
ExtendedAttributeIdent takes an identifier [PutForwards=name]
ExtendedAttributeScopedName takes a scoped name [Prefix=org::example]

This specification defines a number of extended attributes that are applicable to all language bindings, which are described in the sub-sections below. In addition, ECMAScript language binding specific extended attributes are defined in section 4.2. Each extended attribute definition will state which of the above five forms are allowed. Although ExtendedAttributeIdent and ExtendedAttributeScopedName are ambiguous, no extended attribute defined in this document can take both of those forms.

[37]ExtendedAttributeList"[" ExtendedAttribute ExtendedAttributes "]"
 | ε
[38]ExtendedAttributes"," ExtendedAttribute ExtendedAttributes
 | ε
[39]ExtendedAttribute "(" ExtendedAttributeInner ")" ExtendedAttributeRest
 | "[" ExtendedAttributeInner "]" ExtendedAttributeRest
 | "{" ExtendedAttributeInner "}" ExtendedAttributeRest
 | Other ExtendedAttributeRest
[40]ExtendedAttributeRestExtendedAttribute
 | ε
[41]ExtendedAttributeInner "(" ExtendedAttributeInner ")" ExtendedAttributeInner
 | "[" ExtendedAttributeInner "]" ExtendedAttributeInner
 | "{" ExtendedAttributeInner "}" ExtendedAttributeInner
 | OtherOrComma ExtendedAttributeInner
 | ε
[42]Other integer
 | float
 | identifier
 | string
 | other
 | "..."
 | ":"
 | "::"
 | ";"
 | "<"
 | "="
 | ">"
 | "?"
 | "false"
 | "object"
 | "true"
 | "any"
 | "attribute"
 | "boolean"
 | "caller"
 | "const"
 | "creator"
 | "deleter"
 | "double"
 | "exception"
 | "float"
 | "getraises"
 | "getter"
 | "implements"
 | "in"
 | "interface"
 | "long"
 | "module"
 | "octet"
 | "omittable"
 | "optional"
 | "raises"
 | "sequence"
 | "setraises"
 | "setter"
 | "short"
 | "DOMString"
 | "stringifier"
 | "typedef"
 | "unsigned"
 | "void"
[43]OtherOrCommaOther
 | ","
[57]ExtendedAttributeNoArgidentifier
[58]ExtendedAttributeArgListidentifier "(" ArgumentList ")"
[59]ExtendedAttributeIdentidentifier "=" identifier
[60]ExtendedAttributeScopedNameidentifier "=" ScopedName
[61]ExtendedAttributeNamedArgListidentifier "=" identifier "(" ArgumentList ")"

3.8.1. [Prefix]

If the [Prefix] extended attribute appears on a module, it affects the name of the language binding specific namespacing construct the module will correspond to. See the definition of a module’s prefixed name for details.

The [Prefix] extended attribute MUST take a scoped name.

Example

See section 5.3 for an example of the use of [Prefix].

4. ECMAScript binding

This section describes how definitions written with the IDL defined in section 3 correspond to particular constructs in ECMAScript 5th edition. Section numbers in this section refer to sections of ECMAScript Language Specification, 5th Edition [ECMA-262].

Objects defined in this section have internal properties as described in section 8.12 unless otherwise specified, in which case one or more of the following are redefined in accordance with the rules for host objects: [[Call]], [[DefineOwnProperty]], [[Delete]] and [[HasInstance]].

If a value for the internal property [[Class]] is not given for a particular object, its value is implementation specific.

Unless otherwise specified, the [[Extensible]] internal property of objects defined in this section has the value true.

Unless otherwise specified, the [[Prototype]] internal property of objects defined in this section is the Object prototype object.

Editorial note

We perhaps should specify which global object’s Object prototype object that is, and add spec hooks to allow cross-origin property accesses to effectively create separate prototype objects in the window that accesses the property. (Mail.)

If an object is defined to be a function object, then it has characteristics as follows:

Algorithms in this section use the conventions described in section 5.2 and the ToBoolean, ToNumber, ToUint16, ToInt32, ToUint32, ToString and ToObject operators referenced in this section are defined in section 9.

4.1. ECMAScript type mapping

This section describes how types in the IDL map to types in ECMAScript.

Each sub-section below describes how values of a given IDL type are represented in ECMAScript. For each IDL type, it is described how ECMAScript values are converted to an IDL value when passed to a host object expecting that type, and how IDL values of that type are converted to ECMAScript values when returned from a host object.

4.1.1. any

Since the IDL any type is the union of all other IDL types, it can correspond to any ECMAScript value type.

How to convert an ECMAScript value to an IDL any value depends on the type of the ECMAScript value:

The undefined value
The IDL value is an object reference to a special object that represents the ECMAScript undefined value.
The null value
The IDL value is the null object reference.
A Boolean value
The IDL value is the boolean value that represents the same truth value.
A Number value
The IDL value is that which is obtained by following the rules for converting the Number to an IDL double value, as described in section 4.1.12, below.
A String value
The IDL value is that which is obtained by following the rules for converting the String to an IDL DOMString value, as described in section 4.1.13, below.
An object value
The IDL value is an object value that references the same object.

An IDL any value is converted to an ECMAScript value as follows. If the value is an object reference to a special object that represents an ECMAScript undefined value, then it is converted to the ECMAScript undefined value. Otherwise, the rules for converting the specific type of the IDL value are performed.

4.1.2. void

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.

4.1.3. boolean

IDL boolean values are represented by ECMAScript Boolean values.

An ECMAScript value V is converted to an IDL boolean value by running the following algorithm:

  1. Let x be the result of computing ToBoolean(V).
  2. Return the IDL boolean value is the one that represents the same truth value as the ECMAScript Boolean value x.

The result of converting an IDL boolean value to an ECMAScript value is a Boolean that represents the same truth value as the IDL boolean value.

4.1.4. octet

IDL octet values are represented by integer ECMAScript Number values in the range [0, 255].

An ECMAScript value V is converted to an IDL octet value by running the following algorithm:

  1. Initialize x to ToNumber(V).
  2. If x is NaN, +0, −0, +∞, or −∞, then return the IDL octet value that represents 0.
  3. Set x to sign(x) * floor(abs(x)).
  4. Set x to x modulo 28.
  5. Return the IDL octet value that represents the same numeric value as x.

The result of converting an IDL octet value to an ECMAScript value is a Number that represents the same numeric value as the IDL octet value.

4.1.5. short

IDL short values are represented by integer ECMAScript Number values in the range [−32768, 32767].

An ECMAScript value V is converted to an IDL short value by running the following algorithm:

  1. Initialize x to ToNumber(V).
  2. If x is NaN, +0, −0, +∞, or −∞, then return the IDL short value that represents 0.
  3. Set x to sign(x) * floor(abs(x)).
  4. Set x to x modulo 216.
  5. If x ≥ 215, return the IDL short value that represents the same numeric value as x − 216. Otherwise, return the IDL short value that represents the same numeric value as x.

The result of converting an IDL short value to an ECMAScript value is a Number that represents the same numeric value as the IDL short value.

4.1.6. unsigned short

IDL unsigned short values are represented by integer ECMAScript Number values in the range [0, 65535].

An ECMAScript value V is converted to an IDL unsigned short value by running the following algorithm:

  1. Let x be ToUint16(V).
  2. Return the IDL unsigned short value that represents the same numeric value as x.

The result of converting an IDL unsigned short value to an ECMAScript value is a Number that represents the same numeric value as the IDL unsigned short value.

4.1.7. long

IDL long values are represented by integer ECMAScript Number values in the range [−2147483648, 2147483647].

An ECMAScript value V is converted to an IDL long value by running the following algorithm:

  1. Let x be ToInt32(V).
  2. Return the IDL long value that represents the same numeric value as x.

The result of converting an IDL long value to an ECMAScript value is a Number that represents the same numeric value as the IDL long value.

4.1.8. unsigned long

Editorial note

Change this (and unsigned short) according to IRC notes and mail.

IDL unsigned long values are represented by integer ECMAScript Number values in the range [0, 4294967295].

An ECMAScript value V is converted to an IDL unsigned long value by running the following algorithm:

  1. Let x be ToUint32(V).
  2. Return the IDL unsigned long value that represents the same numeric value as x.

The result of converting an IDL unsigned long value to an ECMAScript value is a Number that represents the same numeric value as the IDL unsigned long value.

4.1.9. long long

IDL long long values are represented by ECMAScript Number values.

An ECMAScript value V is converted to an IDL long long value by running the following algorithm:

  1. Initialize x to ToNumber(V).
  2. If x is NaN, +0, −0, +∞, or −∞, then return the IDL long long value that represents 0.
  3. Set x to sign(x) * floor(abs(x)).
  4. Set x to x modulo 264.
  5. If x is greater than or equal to 263, return the IDL long long value that represents the same numeric value as x − 264. Otherwise, return the IDL long long value that represents the same numeric value as x.

The result of converting an IDL long long value to an ECMAScript value is a Number value that represents the closest numeric value to the long long. If the long long is in the range (−(253 − 1), 253 − 1), then the Number will be able to represent exactly the same value as the long long.

4.1.10. unsigned long long

IDL unsigned long long values are represented by ECMAScript Number values.

An ECMAScript value V is converted to an IDL unsigned long long value by running the following algorithm:

  1. Initialize x to ToNumber(V).
  2. If x is NaN, +0, −0, +∞, or −∞, then return the IDL unsigned long long value that represents 0.
  3. Set x to sign(x) * floor(abs(x)).
  4. Compute x modulo 264.
  5. Return the IDL unsigned long long value that represents the same numeric value as x.

The result of converting an IDL unsigned long long value to an ECMAScript value is a Number value that represents the closest numeric value to the unsigned long long, choosing the numeric value with an even significand if there are two equally close values ([ECMA-262], section 8.5). If the unsigned long long is less than to 253 − 1, then the Number will be able to represent exactly the same value as the unsigned long long.

4.1.11. float

IDL float values are represented by ECMAScript Number values.

An ECMAScript value V is converted to an IDL float value by running the following algorithm:

  1. Let x be ToNumber(V).
  2. If x is NaN, then return the IDL float value that represents the IEEE 754 NaN value with the bit pattern 0x7fc00000 [IEEE-754].
  3. Let S be the set of finite IEEE 754 single-precision floating point values except −0, but with two special values added: 2128 and −2128.
  4. Let y be the number in S that is closest to x, selecting the number with an even significand if there are two equally close values ([ECMA-262], section 8.5). (The two special values 2128 and −2128 are considered to have even significands for this purpose.)
  5. If y is 2128, return +∞.
  6. If y is −2128, return −∞.
  7. If y is +0 and x is negative, return −0.
  8. Return y.

The result of converting an IDL float value to an ECMAScript value is a Number:

  • If the IDL float value is a NaN, then the Number value is NaN.
  • Otherwise, the Number value is the one that represents the same numeric value as the IDL float value.

4.1.12. double

IDL double values are represented by ECMAScript Number values.

An ECMAScript value V is converted to an IDL double value by running the following algorithm:

  1. Let x be ToNumber(V).
  2. If x is NaN, then return the IDL float value that represents the IEEE 754 NaN value with the bit pattern 0x7ff8000000000000 [IEEE-754].
  3. Let S be the set of finite IEEE 754 double-precision floating point values except −0, but with two special values added: 21024 and −21024.
  4. Let y be the number in S that is closest to x, selecting the number with an even significand if there are two equally close values ([ECMA-262], section 8.5). (The two special values 21024 and −21024 are considered to have even significands for this purpose.)
  5. If y is 21024, return +∞.
  6. If y is −21024, return −∞.
  7. If y is +0 and x is negative, return −0.
  8. Return y.

The result of converting an IDL double value to an ECMAScript value is a Number:

  • If the IDL double value is a NaN, then the Number value is NaN.
  • Otherwise, the Number value is the one that represents the same numeric value as the IDL double value.

4.1.13. DOMString

Editorial note

Make null default to the empty string? (IRC.)

IDL DOMString values are represented by ECMAScript String values.

An ECMAScript value V is converted to an IDL DOMString value by running the following algorithm:

  1. If V is null and the conversion to an IDL value is being performed due to any of the following: then return the DOMString value that represents the empty string.
  2. If V is undefined and the conversion to an IDL value is being performed due to any of the following: then return the DOMString value that represents the empty string.
  3. Let x be ToString(V).
  4. Return the IDL DOMString value that represents the same sequence of characters as the one the ECMAScript String value x represents.

The result of converting an IDL DOMString value to an ECMAScript value is the String value that represents the same sequence of 16 bit code units that the IDL DOMString represents.

4.1.14. object

IDL object values are represented by ECMAScript Object values.

An ECMAScript value V is converted to an IDL object value by running the following algorithm:

  1. If V is null or undefined, then return the IDL object value null.
  2. Let x be ToObject(V).
  3. Return the IDL object value that is a reference to the same object as x.

The result of converting an IDL object value to an ECMAScript value is:

  • If the IDL object value is null, then the ECMAScript value is the null value.
  • Otherwise, the ECMAScript value is an Object value that represents a reference to the same object that the IDL object represents.

4.1.15. Interface types

IDL interface type values are represented by ECMAScript Object values.

An ECMAScript value V is converted to an IDL interface type value by running the following algorithm (where I is the interface):

  1. If V is null or undefined, then return the IDL interface type value null.
  2. If V is a host object that implements I, then return the IDL interface type value that represents a reference to that host object.
  3. Let x be ToObject(V).
  4. If x is a native object that is considered to implement I according to the rules in section 4.6, then return the IDL interface type value that represents a reference to that native object.
  5. Throw a TypeError.

The result of converting an IDL interface type value to an ECMAScript value is:

  • If the IDL interface type value is null, then the ECMAScript value is the null value.
  • Otherwise, the ECMAScript value is an Object value that represents a reference to the same object that the IDL interface type value represents.

4.1.16. Nullable types — T?

Editorial note

Should interface types not include null and thus be nullable too? (Mail.)

IDL nullable type values are represented by values of either the ECMAScript type corresponding to the inner IDL type, or the ECMAScript null value.

An ECMAScript value V is converted to an IDL nullable type value as follows:

  1. If V is null, then return the IDL nullable type value null.
  2. Otherwise, if V is undefined and the IDL type being converted to is DOMString?, then:
    1. If the conversion to an IDL value is being performed due to any of the following: then:
      1. If the argument given to [TreatUndefinedAs] is EmptyString, then return the DOMString? value that represents the empty string.
      2. Otherwise, the argument given to [TreatUndefinedAs] is Null. Return the null DOMString? value.
  3. Otherwise, return the result of converting V to the inner IDL type.

The result of converting an IDL nullable type value to an ECMAScript value is:

4.1.17. Sequences — sequence<T>

IDL sequence<T> values are represented by ECMAScript Array values.

An ECMAScript value V is converted to an IDL sequence<T> value as follows:

  1. If V is null or undefined, then return a sequence of length zero.
  2. Let A be the result of calling ToObject(V).
  3. Let length be the result of calling [[Get]] on A with property name length.
  4. Let n be the result of calling ToUint32(length).
  5. Initialize S0..n−1 to be an IDL sequence with elements of type T, where each element is uninitialized.
  6. Initialize i to be 0.
  7. While i < n:
    1. Let P be the result of calling ToString(i).
    2. Let E be the result of calling [[Get]] on A with property name P.
    3. Set Si to the result of converting E to an IDL value of type T.
    4. Set i to i + 1.
  8. Return S.

An IDL sequence value S0..n−1 of type sequence<T> is converted to an ECMAScript Array object as follows:

  1. Let A be a new Array object created as if by the expression [].
  2. Initialize i to be 0.
  3. While i < n:
    1. Let E be the result of converting Si to an ECMAScript value.
    2. Let P be the result of calling ToString(i).
    3. Call [[Put]] on A with property name P and value E.
    4. Set i to i + 1.
  4. Return A.
Example

The following interface defines an attribute of a sequence type as well as an operation with an argument of a sequence type.

IDL
interface Canvas {

  readonly attribute sequence<DOMString> supportedImageCodecs;

  void drawPolygon(in sequence<float> coordinates);

  // ...
};

In an ECMAScript implementation of this interface, an Array object with elements of type String is used to represent a sequence<DOMString>, while an Array with elements of type Number represents a sequence<float>. The Array objects are effectively passed by value; every time the supportedImageCodecs property is fetched a new Array is returned, and whenever an Array is passed to drawPolygon a reference to it will never be kept.

ECMAScript

// Obtain an instance of Canvas.  Assume that the supportedImageCodecs
// IDL attribute is a sequence with two DOMString values: "image/png"
// and "image/svg+xml".
var canvas = getCanvas();

// An Array object of length 2.
canvas.supportedImageCodecs;

// Evaluates to "image/png".
canvas.supportedImageCodecs[0];

// Each time canvas.supportedImageCodecs is evaluated, it returns a
// new Array object.  Thus modifying the returned Array will not
// affect the sequence that is the value of the IDL attribute.
canvas.supportedImageCodecs[0] = "image/jpeg";

// Still evaluates to "image/png".
canvas.supportedImageCodecs[0];

// This evaluates to false.
canvas.supportedImageCodecs == canvas.supportedImageCodecs;


// An Array of Numbers...
var a = [0, 0, 100, 0, 50, 62.5];

// ...can be passed to a host object expecting a sequence<float>.
canvas.drawPolygon(a);

// Each element will be converted to a float by first calling ToNumber().
// So the following call is equivalent to the previous one, except that
// "hi" will be alerted before drawPolygon() returns.
canvas.drawPolygon
  ([false, '',
    { valueOf: function() { alert('hi'); return 100 } }, 0,
    '50', new Number(62.5)]);

// Modifying an Array that was passed to drawPolygon() is guaranteed not to
// have an effect on the Canvas, since the Array is effectively passed by value.
a[0] = 20;

4.1.18. Arrays — T[]

IDL array values are represented by references to objects known as array host objects, with particular characteristics that allow them to behave similarly to native Array objects.

The value of the internal [[Prototype]] property of an array host object MUST be the array host object prototype object, which is defined below.

The value of the internal [[Class]] property of an array host object MUST be the type name of the array type.

Array host objects MUST have a property named "length" whose value is a Number that is the length of the array. If the array is fixed length, then this property has attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }. Otherwise, the array is variable length, and the property has attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }.

Array host objects MUST always have a property named ToString(i) for every integer index 0 < i < n, where n is the length of the array. These properties have attributes { [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false } if the array is read only and { [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: false } otherwise. The values of these properties MUST be the result of converting the value of the array element at the corresponding index to an ECMAScript value.

Array host objects MUST have a property named "toString" with attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true } and whose value is an object with an internal [[Call]] method that behaves as follows:

  1. Let N be the result of invoking [[Get]] on this with "length" as the property name.
  2. Initialize i to 0.
  3. Initialize s to be an empty sequence of 16 bit code units.
  4. While i < ToUint32(N):
    1. If i ≠ 0, then append to the end of s the 16 bit code unit 0x002C (the UTF-16 encoding of the U+002C COMMA (",") character).
    2. Let V be the result of invoking [[Get]] on this with property name ToString(i).
    3. Append to the end of s the sequence of 16 bit code units that ToString(V) represents.
    4. Set i to be i + 1.
  5. Return the String value that represents the same sequence of 16 bit code units as s.

The "toString" object MUST itself have a property named "length" with attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false } whose value is the Number value 0.

Array host objects have an internal [[DefineOwnProperty]] method as defined in section 4.1.18.2 below.

An ECMAScript value V is converted to an IDL array value of type T[] as follows:

  • If V is an array host object, then the IDL array value is the array value that the array host object represents.
  • Otherwise, if V is null or undefined, then the IDL array value is null.
  • Otherwise, if V is a native object, then the IDL array value is determined as follows:
    1. Initialize n to be the result of calling [[Get]] on V with property name "length".
    2. Set n to ToUint32(n).
    3. Initialize E0..n to be a list of IDL values.
    4. Initialize i to be 0.
    5. While i < n:
      1. Let x be the result of calling [[Get]] on V with property name ToString(i).
      2. Set Ei to be the result of converting x to an IDL value of type T.
      3. Set i to i + 1.
    6. The IDL array value is a fixed length array of length n whose values are E0..n.
  • Otherwise, throw a TypeError.

An IDL array value V of type T[] is converted to an ECMAScript value as follows:

  • If V is null, then the ECMAScript value is the null value.
  • Otherwise, if V is already represented by an array host object, then the ECMAScript value is that array host object.
  • Otherwise, the ECMAScript value is a newly created array host object that represents V.
Editorial note

Should we somehow allow for the definition of constructors to create array host objects? E.g. like new UnsignedShortArray()?

Example

The following IDL defines an interface that has an unsigned short[] attribute.

IDL
[Constructor]
interface LotteryResults {
  readonly attribute unsigned short[] numbers;
};

Assuming that the array has a fixed length of 6, the following ECMAScript code illustrates how the array attribute in the above interface would behave:

ECMAScript
var results = new LotteryResults();  // results is a new host object
                                     // implementing the LotteryResults interface.

var a = [4, 8, 15, 16, 23, 42];      // Numbers can be assigned into the array.
for (var i = 0; i < 6; i++) {
  results.numbers[i] = a[i];
}

results.numbers = a;                 // This has no effect, since numbers is
                                     // read only.

a[0] = 5;                            // Change the array.
results.numbers[0];                  // Evaluates to 4, since results.numbers is
                                     // not a reference to 'a'.

results.numbers[0] = 5;              // Modifies the array stored in the host
                                     // object.
results.numbers[0];                  // Now evaluates to 5.

results.numbers[0] = 6.25;           // Assigns 6 to the first element of the array
                                     // since that is how 6.5 is converted to an
                                     // unsigned short.

results.numbers.length = 7;          // Has no effect, since numbers is
                                     // fixed length.
results.numbers[6];                  // Evaluates to undefined.

results.numbers.slice(0, 2);         // Evaluates to an Array [4, 8].

results.numbers.push(108);           // Has no effect, since the definition of
                                     // push() relies on calling [[Put]] on a
                                     // non-existent array index property
                                     // and on "length", both of which will
                                     // be silently ignored.

delete results.numbers[3];           // Has no effect and evaluates to false,
                                     // since the array index properties are
                                     // non-configurable.

If passing an Array object to a host object expecting an IDL array value, a new array host object will be created to represent an IDL array value determined from that Array. If the LotteryResults interface is instead defined as:

IDL
[Constructor]
interface LotteryResults {
  attribute unsigned short[] numbers;
};

then an Array object can be assigned to the numbers property. Unless the prose accompanying the interface said otherwise, this would result in a fixed length array of whatever length the Array has being assigned to the IDL attribute.

ECMAScript
var results = new LotteryResults();

results.numbers.length;       // Evaluates to 6.

var a = [1, 3, 5];

results.numbers = a;          // Assigns a fixed length IDL array of length 3 to
                              // the numbers attribute.

results.numbers;              // This now evaluates to an array host object
                              // that represents the fixed length IDL array,
                              // not the Array object assigned in the previous
                              // statement.

results.numbers.length;       // Evaluates to 3.
4.1.18.1. Array host object prototype object

The array host object prototype object is an object that is the prototype of every array host object. It allows functions from the Array prototype object to be called on array host objects.

The internal [[Prototype]] property of the array host object prototype object MUST be the Array prototype object.

Note

Note that some of the functions from the Array prototype object will not behave on a fixed length array host object as they do on an Array object, since attempting to assign to the length property will fail. Similarly, most of the functions from the Array prototype object will not perform any useful operation on read only arrays.

4.1.18.2. Array host object [[DefineOwnProperty]] method

The internal [[DefineOwnProperty]] method of every array host object A with element type T MUST behave as follows, assuming P is the property name, Desc is the Property Descriptor and Throw is a boolean:

Note

This algorithm does basically the same thing as the one defined for native array instances ([ECMA-262], section 15.4.5.1), with the exception of ensuring that arrays are never sparse and also that array element values are coerced to the array element type.

  1. Let oldLenDesc be the result of calling the [[GetOwnProperty]] internal method of A passing "length" as the argument.
  2. Initialize oldLen to oldLenDesc.[[Value]].
  3. If P is "length", then:
    1. If the [[Value]] field of Desc is absent, then:
      1. Return the result of calling the default [[DefineOwnProperty]] internal method ([ECMA-262], section 8.12.9) on A passing "length", Desc, and Throw as arguments.
    2. Let newLenDesc be a copy of Desc.
    3. Let newLen be ToUint32(Desc.[[Value]]).
    4. If newLen is not equal to ToNumber(Desc.[[Value]]), throw a RangeError exception.
    5. Set newLenDesc.[[Value]] to newLen.
    6. Reject if oldLenDesc.[[Writable]] is false and SameValue(newLen, oldLen) is false.
    7. If newLen > oldLen:
      1. Reject if the [[Extensible]] property of A is false.
      2. Update the IDL array value that A represents to have a length of newLen.
      3. Let idlValue be the result of converting undefined to type T.
      4. Let value be the result of converting idlValue to an ECMAScript value.
      5. While newLen > oldLen:
        1. Call the default [[DefineOwnProperty]] internal method ([ECMA-262], section 8.12.9) on A passing ToString(oldLen), Property Descriptor { [[Value]]: value, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }, and false as arguments.
        2. Set the IDL array element value at index oldLen to idlValue.
        3. Set oldLen to oldLen + 1.
      6. Call the default [[DefineOwnProperty]] internal method ([ECMA-262], section 8.12.9) on A passing "length", newLenDesc, and false as arguments.
      7. Return true.
    8. Initialize newWritable to true.
    9. If newLenDesc.[[Writable]] is false, then:
      1. Need to defer setting the [[Writable]] attribute to false in case any elements cannot be deleted.
      2. Set newWritable to false.
      3. Set newLenDesc.[[Writable]] to true.
    10. Let succeeded be the result of calling the default [[DefineOwnProperty]] internal method ([ECMA-262], section 8.12.9) on A passing "length", newLenDesc, and Throw as arguments.
    11. If succeeded is false, return false.
    12. While newLen < oldLen:
      1. Set oldLen to oldLen − 1.
      2. Let cannotDelete be the result of calling the [[Delete]] internal method of A passing ToString(oldLen) and false as arguments.
      3. If cannotDelete is true, then:
        1. Set newLenDesc.[[Value]] to oldLen + 1.
        2. If newWritable is false, set newLenDesc.[[Writable]] to false.
        3. Call the default [[DefineOwnProperty]] internal method ([ECMA-262], section 8.12.9) on A passing "length", newLenDesc, and false as arguments.
        4. Update the IDL array value that A represents to have a length of oldLen + 1.
        5. Reject.
    13. Update the IDL array value that A represents to have a length of newLen.
    14. If newWritable is false, then
      1. Call the default [[DefineOwnProperty]] internal method ([ECMA-262], section 8.12.9) on A passing "length", Property Descriptor { [[Writable]]: false }, and false as arguments. This call will always return true.
    15. Return true.
  4. Otherwise, if P is an array index ([ECMA-262], section 15.4), then:
    1. Let index be ToUint32(P).
    2. Reject if indexoldLen and oldLenDesc.[[Writable]] is false.
    3. Reject if IsDataDescriptor(Desc) is false.
    4. Let idlValue be the result of converting Desc.[[Value]] to type T.
    5. Let value be the result of converting idlValue to an ECMAScript value.
    6. Let newDesc be a copy of Desc.
    7. Set newDesc.[[Value]] to idlValue.
    8. Let succeeded be the result of calling the default [[DefineOwnProperty]] internal method (8.12.9) on A passing P, newDesc, and false as arguments.
    9. Reject if succeeded is false.
    10. If indexoldLen, then:
      1. Reject if the [[Extensible]] property of A is false.
      2. Reject if oldLenDesc.[[Writable]] is false and SameValue(newLen, oldLen) is false.
      3. Let idlValue be the result of converting undefined to type T.
      4. Let value be the result of converting idlValue to an ECMAScript value.
      5. Initialize i to oldLen.
      6. While i < index:
        1. Call the default [[DefineOwnProperty]] internal method ([ECMA-262], section 8.12.9) on A passing ToString(oldLen), Property Descriptor { [[Value]]: value, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }, and false as arguments.
        2. Set the IDL array element value at index i to idlValue.
        3. Set i to i + 1.
      7. Set oldLenDesc.[[Value]] to index + 1.
      8. Call the default [[DefineOwnProperty]] internal method ([ECMA-262], section 8.12.9) on A passing "length", oldLenDesc, and false as arguments. This call will always return true.
    11. Return true.
  5. Return the result of calling the default [[DefineOwnProperty]] internal method ([ECMA-262], section 8.12.9) on A passing P, Desc, and Throw as arguments.

4.2. ECMAScript-specific extended attributes

Editorial note

HTML 5 is using [Supplemental] to split interface definitions into multiple parts.

This section defines a number of extended attributes whose presence affects only the ECMAScript binding.

4.2.1. [AllowAny]

If the [AllowAny] extended attribute appears on an operation argument, it indicates that any ECMAScript value will be accepted as that argument’s value. Normally, as part of the overload resolution algorithm, a non-DOMString value will disqualify a given overloaded operation that is declared to take a DOMString for a given argument. When the [AllowAny] extended attribute is present on the argument, that disqualification is not performed.

The [AllowAny] extended attribute MUST take no argument.

Example

The following IDL fragment defines two interfaces, each with two overloaded operations. One uses [AllowAny] and one does not.

IDL
interface A {
  void f();
  void f(in A a);
  void f(in DOMString s);
};

interface B {
  void g();
  void g(in B b);
  void g([AllowAny] in DOMString s);
};

In an ECMAScript implementation of the above two interfaces, an A object will not allow a float value to be passed in as an argument, while a B object will:

ECMAScript
var a = getA();  // Obtain an instance of A.
var b = getB();  // Obtain an instance of B.

a.f(1.23);       // Throws a TypeError.
b.g(1.23);       // Equivalent to b.g("1.23").
b.g(a);          // Equivalent to calling b.g with ToString(a).

4.2.2. [Callback]

If the [Callback] extended attribute appears on an interface, it indicates that the interface can be implemented by an ECMAScript native object (see section 4.6 below), and such an object can be converted to an IDL value of that interface type. A native object implementing the interface is most often used to provide callback methods to a host object, hence the name of this extended attribute.

The [Callback] extended attribute MUST either take no argument or take the identifier FunctionOnly or PropertyOnly. If no argument is given, then any native object is considered to implement the interface. Otherwise, if the FunctionOnly argument is given, then only Function objects can be considered to implement the interface.

The [Callback] extended attribute MUST NOT be used on an interface that does not meet the criteria for an interface that can have native object implementations, as described in section 4.6 below. If the [Callback] extended attribute is used on an interface that has any attributes, has zero operations, or has multiple operations with different identifiers, then the extended attribute MUST take no argument.

Example

The following IDL fragment defines a simple callback interface and an interface for an object that expects an object that implements that callback:

IDL
[Callback] interface Listener {
  void eventOccurred();
};

interface Thing {
  void addListener(in Listener listener);
};

An ECMAScript implementation of the above two interfaces allows any native object to be passed to addListener:

ECMAScript
// Obtain an instance of Thing.
var t = getThing();

// The function is the implementation of the eventOccurred operation on the
// Listener interface.  If Listener had been declared with
// [Callback=PropertyOnly] this addListener() call would still succeed, but
// a TypeError would be thrown when the user agent attempts to invoke the
// callback.
t.addListener(function() { });

// This also works, but it is the function with /* 1 */ in it that is the
// implementation of eventOccurred.
var x = function() { /* 1 */ };                    
x.eventOccurred = function() { /* 2 */ };          
t.addListener(x);

// This works too, and the value of the eventOccurred property is the
// implementation of the operation.  If Listener had been declared with
// [Callback=FunctionOnly] however, this would have thrown a TypeError.
t.addListener({ eventOccurred: function() { } });

4.2.3. [Constructor]

If the [Constructor] extended attribute appears on an interface, it indicates that the interface object for this interface will have an [[Construct]] internal method, allowing objects implementing the interface to be constructed. Multiple [Constructor] extended attributes may appear on a given interface.

The [Constructor] extended attribute MUST either take no argument or take an argument list. The bare form, [Constructor], has the same meaning as using an empty argument list, [Constructor()]. For each [Constructor] extended attribute on the interface, there will be a way to construct an object that implements the interface by passing the specified arguments.

See section 4.4.1.1 below for details on how a constructor is to be implemented.

Example

The following IDL defines two interfaces. The second has the [Constructor] extended attribute, while the first does not.

IDL
interface NodeList {
  Node item(in unsigned long index);
  readonly attribute unsigned long length;
};

[Constructor,
 Constructor(in float radius)]
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. It would take either zero or one argument. The NodeList interface object would not have a [[Construct]] property.

ECMAScript
var x = new Circle();      // The uses the zero-argument constructor to create a
                           // reference to a host object that implements the
                           // Circle interface.

var y = new Circle(1.25);  // This also creates a Circle object, this time using
                           // the one-argument constructor.

var z = new NodeList();    // This would throw a TypeError, since no
                           // [Constructor] is declared.

4.2.4. [NamedConstructor]

If the [NamedConstructor] extended attribute appears on an interface, it indicates that the relevant namespace object for the interface (often, the ECMAScript global object) will have a property with the specified name whose value is a constructor function that can create objects that implement the interface. Multiple [NamedConstructor] extended attributes may appear on a given interface.

The [NamedConstructor] extended attribute MUST either take an identifier or take a named argument list. The first form, [NamedConstructor=identifier], has the same meaning as using an empty argument list, [NamedConstructor=identifier()]. For each [NamedConstructor] extended attribute on the interface, there will be a way to construct an object that implements the interface by passing the specified arguments to the constructor function that is the value of the aforementioned property.

The identifier used for the named constructor MUST NOT be the same as that used by an [NamedConstructor] extended attribute on another interface, and it MUST NOT be the same as an identifier of an interface (or exception) that has an interface object (or exception interface object).

See section 4.4.2 below for details on how named constructors are to be implemented.

Example

The following IDL defines an interface that uses the [NamedConstructor] extended attribute.

IDL
[NamedConstructor=Audio,
 NamedConstructor=Audio(in DOMString src)]
interface HTMLAudioElement : HTMLMediaElement {
  // ...
};

An ECMAScript implementation that supports this interface will allow the construction of HTMLAudioElement objects using the Audio constructor.

ECMAScript
typeof Audio;                   // Evaluates to 'function'.

var a1 = new Audio();           // Creates a new object that implements
                                // HTMLAudioElement, using the zero-argument
                                // constructor.

var a2 = new Audio('a.flac');   // Creates an HTMLAudioElement using the
                                // one-argument constructor.

4.2.5. [NamespaceObject]

If the [NamespaceObject] extended attribute appears on a module, it indicates that the hierarchy of that module and its descendant modules will be reflected as namespace objects. Interface objects and exception interface objects for interfaces and exceptions defined in a module annotated with [NamespaceObject] (or in a descendant of such a module) will be placed on a namespace object instead of the ECMAScript global object.

The [NamespaceObject] extended attribute MUST take no argument.

The [NamespaceObject] extended attribute MUST NOT be specified on a module if is specified on one of its ancestor modules.

Example

The following IDL fragment defines a module hierarchy where one of the modules is declared with the [NamespaceObject] extended attribute.

IDL
[NamespaceObject]
module acme {
  
  exception DeviceException { };

  module pim {

    [Constructor]
    interface Contact { };

    [Constructor,
     NamedConstructor=RecurringEvent(in long freq)]
    interface CalendarEvent { };
  };
};

In an ECMAScript implementation, there would exist namespace objects for the acme and pim modules. The property for the Device exception interface object would be on the acme namespace object and the properties for the Contact and CalendarEvent interface objects would be on the pim namespace object.

ECMAScript
acme;                             // A namespace object.
acme.pim;                         // Another namespace object.

acme.DeviceException;             // An exception interface object.
acme.pim.Contact;                 // An interface object.

new acme.pim.Contact();           // Creates an object implementing acme::pim::Contact.
new acme.pim.RecurringEvent(10);  // Creates an object implementing acme::pim::CalendarEvent.

4.2.6. [NoInterfaceObject]

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] extended attribute MUST take no argument.

If the [NoInterfaceObject] extended attribute is specified on an interface, then the [Constructor] extended attribute MUST NOT also be specified on that interface.

Example

The following IDL fragment defines two interfaces, one whose interface object is exposed on the ECMAScript global object, and one whose isn’t:

IDL
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.

ECMAScript
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

4.2.7. [OverrideBuiltins]

If the [OverrideBuiltins] extended attribute appears on an interface, it indicates that for a host object implementing the interface, corresponding named properties will exist on it, shadowing any properties that would otherwise be inherited from its prototype chain. This is in constrast to the usual behavior, which is for corresponding named properties to be created only if there is no property with the same name somehwere in the object’s prototype chain.

The [OverrideBuiltins] extended attribute MUST take no argument and MUST NOT appear on an interface that does not define a name getter.

Example

The following IDL fragment defines two interfaces, one that has a name getter and one that does not.

IDL
interface StringMap {
  readonly attribute unsigned long length;
  getter DOMString lookup(in DOMString key);
};

[OverrideBuiltins]
interface StringMap2 {
  readonly attribute unsigned long length;
  getter DOMString lookup(in DOMString key);
};

In an ECMAScript implementation of these two interfaces, getting certain properties on objects implementing the interfaces will result in different values:

ECMAScript
// Obtain an instance of StringMap.  Assume that it has "abc", "length" and
// "toString" as supported property names.
var map1 = getStringMap();  

// This invokes the name getter.
map1.abc;

// This fetches the "length" property on the object that corresponds to the
// length attribute.
map1.length;

// This fetches the "toString" property from the object's prototype chain.
map1.toString;


// Obtain an instance of StringMap2.  Assume that it also has "abc", "length"
// and "toString" as supported property names.
var map2 = getStringMap2();  

// This invokes the name getter.
map2.abc;

// This also invokes the name getter, despite the fact that the "length"
// property on the object corresponds to the length attribute.
map2.length;

// This too invokes the name getter, despite the fact that "toString" is
// a property in map2's prototype chain.
map2.toString;

4.2.8. [PrototypeRoot]

Editorial note

Ian suggests that [PrototypeRoot] might not need to exist. (Mail.)

If the [PrototypeRoot] extended attribute appears on an interface A, it indicates that it serves as the root of a prototype ancestor hierarchy. For any interface B that has A as an ancestor, each interface in the inheritance tree starting with an interface that B inherits from and ending with A will be a prototype ancestor of B. It also plays a role in determining the value of a host object’s internal [[Prototype]] property value when the object implements more than one interface. See section 4.4.3 and section 4.5 for details.

The [PrototypeRoot] extended attribute MUST take no argument, and MUST NOT appear on an interface that inherits from another interface. An interface inheritance hierarchy MUST NOT have multiple paths from one interface to another that has the [PrototypeRoot] extended attribute.

Example

The following IDL fragment defines a hierarchy of interfaces whose rootmost interface is annotated with the [PrototypeRoot] extended attribute. Other interfaces are defined to be implemented on objects that implement this prototype root interface, but properties for these other interfaces will be made available in the prototype chain through a mixin prototype object.

IDL
[PrototypeRoot]
interface Node {
  readonly attribute unsigned short nodeType;
};

interface Element : Node {
  void appendChild(in Node n);
  // ...
};

interface HTMLElement : Element {
  void focus();
  // ...
};

interface EventTarget {
  void addEventListener(/* ... */);
  // ...
};

Node implements EventTarget;

An ECMAScript implementation implementing these interfaces would have a prototype chain as follows, where E is an instance of HTMLElement:

The prototype of E is the mixin prototype object for E.  This mixin prototype object has an "addEventListener" property.  The prototype of the mixin prototype object is the HTMLElement prototype object, whose prototype is the Element prototype object, whose prototype is the Node prototype object, whose prototype is the Object prototype object.

4.2.9. [PutForwards]

If the [PutForwards] extended attribute appears on a read only attribute declaration whose type is an interface type, it indicates that assigning to the attribute will have specific behavior. Namely, the assignment is “forwarded” to the attribute (specified by the extended attribute argument) on the object that is currently referenced by the attribute being assigned to.

The [PutForwards] extended attribute MUST take an identifier. Assuming that:

then there MUST be another attribute B declared on J whose identifier is N. Assignment of a value to the attribute A on an object implementing I will result in that value being assigned to attribute B of the object that A references, instead.

Note that [PutForwards]-annotated attributes can be chained. That is, an attribute with the [PutForwards] extended attribute can refer to an attribute that itself has that extended attribute. There MUST NOT exist a cycle in a chain of forwarded assignments. A cycle exists if, when following the chain of forwarded assignments, a particular attribute on an interface is encountered more than once.

An attribute with the [PutForwards] extended attribute MUST NOT also be declared with the [Replaceable] extended attribute.

See the Attributes section below for how [PutForwards] is to be implemented.

Example

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:

IDL
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:

ECMAScript
var p = getPerson();           // Obtain an instance of Person.

p.name = 'John Citizen';       // This statement...
p.name.full = 'John Citizen';  // ...has the same behavior as this one.

4.2.10. [Replaceable]

If the [Replaceable] extended attribute appears on a read only attribute, it indicates that setting the corresponding property on the host object will result in that property being reconfigured to one that is unrelated to the attribute, and which has the value being assigned.

The [Replaceable] extended attribute MUST take no argument.

An attribute with the [READ_ERROR] extended attribute MUST NOT also be declared with the [PutForwards] extended attribute.

Example

The following IDL fragment defines an interface with an operation that increments a counter, and an attribute that exposes the counter’s value, which is initially 0:

IDL
interface Counter {
  [Replaceable] readonly attribute unsigned long value;
  void increment();
};

Assigning to the value property on a host object implementing Counter will sever the link between the property and the IDL attribute it initially corresponds to:

ECMAScript
var counter = getCounter();  // Obtain an instance of Counter.
counter.value;               // Evaluates to 0.

counter.increment();
counter.increment();
counter.value;               // Evaluates to 2.

counter.value = 'a';         // Replaces the property with one that is unrelated
                             // to Counter::value.

counter.increment();
counter.value;               // Evaluates to 'a'.

4.2.11. [TreatNullAs]

Editorial note

More testing required to see if the defaults for [TreatNullAs] and [TreatUndefinedAs] are correct. (Mail and action.)

If the [TreatNullAs] extended attribute appears on an attribute or operation argument whose type is DOMString, it indicates that a null value assigned to the attribute or passed as the operation argument will be handled differently from its default handling. Instead of being stringified to "null", which is the default, it will be converted to the empty string "".

If [TreatNullAs] is specified on an operation itself, then it indicates that a native object implementing the interface will have the return value of the function that implements the operation handled in the same way as for operation arguments and attributes, as above.

The [TreatNullAs] extended attribute MUST take the identifier EmptyString.

The [TreatNullAs] extended attribute MUST NOT be specified on an operation argument, attribute or operation return value whose type is not DOMString.

Example

The following IDL fragment defines an interface that has one attribute with the [TreatNullAs] extended attribute, and one operation with an argument that has the extended attribute:

IDL
interface Dog {
  attribute DOMString name;
  attribute DOMString owner;

  boolean isMemberOfBreed([TreatNullAs=EmptyString] in DOMString breedName);
};

An ECMAScript implementation implementing the Dog interface would convert a null value assigned to the name property or passed as the argument to the isMemberOfBreed function:

ECMAScript
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 "" to the isMemberOfBreed
                          // function.

4.2.12. [TreatUndefinedAs]

If the [TreatUndefinedAs] extended attribute appears on an attribute or operation argument whose type is DOMString or DOMString?, it indicates that an undefined value assigned to the corresponding property or passed as an argument to the corresponding function will be handled differently from its default handling, which is to stringify to "undefined":

  • If the argument to [TreatUndefinedAs] is EmptyString, then the value assigned to the attribute or passed as the operation argument will be the empty string, "".
  • Otherwise, if the argument to [TreatUndefinedAs] is Null, then the value assigned to the attribute or passed as the operation argument will be the null value.

If [TreatUndefinedAs] is specified on an operation itself, then it indicates that a native object implementing the interface will have the return value of the function that implements the operation handled in the same way as for operation arguments and attributes, as above.

The [TreatUndefinedAs] extended attribute MUST take an identifier: either EmptyString or Null.

[TreatUndefinedAs=Null] MUST NOT be specified on operation argument, attribute or operation return value whose type is not DOMString?, and [TreatUndefinedAs=EmptyString] MUST NOT be specified on operation argument, attribute or operation return value whose type is neither DOMString nor DOMString?.

Example

The following IDL fragment defines an interface that has one attribute with the [TreatUndefinedAs] extended attribute, and one operation with an argument that has the extended attribute:

IDL
interface Cat {
  attribute DOMString name;
  attribute DOMString owner;

  boolean isMemberOfBreed([TreatUndefinedAs=EmptyString] in DOMString breedName);
};

An ECMAScript implementation implementing the Cat interface would convert an undefined value assigned to the name or owner property to the string "undefined", and an undefined value passed as the argument to the isMemberOfBreed function would be converted to the empty string "":

ECMAScript
var c = getCat();              // Obtain an instance of Cat.

c.name = undefined;            // This assigns the string "undefined" to the
                               // .name property.

c.isMemberOfBreed(undefined);  // This passes the string "" to the
                               // isMemberOfBreed function.

4.3. Modules

The hierarchy of modules in an IDL fragment can, but need not be, reflected in an ECMAScript implementation. Whether a module hierarchy is reflected or not depends on the use of the [NamespaceObject] extended attribute.

For every module that is declared with the [NamespaceObject] extended attribute, and for every module that has an ancestor module declared with the [NamespaceObject] extended attribute, there exists a unique namespace object, which provides access to the interface objects and exception interface objects for the interfaces and exceptions declared in the module.

The relevant namespace object for a module, interface or exception A is determined as follows:

For every module that has a namespace object, a corresponding property MUST exist on the relevant namespace object for the module. The name of the property is the identifier of the module, its value is the namespace object for the module, and the property has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }.

4.4. Interfaces

For every interface that is not declared with the [NoInterfaceObject] extended attribute, a corresponding property MUST exist on the interface’s relevant namespace object. The name of the property is the identifier of the interface, and its value is an object called the interface object, which provides access to the constants, attributes and operations defined on the interface. The property has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }. The characteristics of an interface object is described in section 4.4.1 below.

In addition, for every [NamedConstructor] extended attribute on an interface, a corresponding property MUST exist on the interface’s relevant namespace object. The name of the property is the identifier that occurs directly after the “=”, and its value is an object called a named constructor, which allows construction of objects that implement the interface. The property has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }. The characteristics of a named constructor is described in section 4.4.2 below.

4.4.1. Interface object

There exists an interface object for every interface not declared with the [NoInterfaceObject] extended attribute. If the interface is declared with a [Constructor] extended attribute, then the interface object is a function object.

The [[Class]] property of the interface object MUST be the identifier of the interface.

The interface object also has properties that correspond to the constants defined on that interface, as described in section 4.4.4 below.

The interface object MUST also have a property named prototype with attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false } whose value is an object called the interface prototype object. This object has properties that correspond to the attributes and operations defined on the interface, and is described in more detail in section 4.4.3 below.

4.4.1.1. Interface object [[Call]] method

If the interface is declared with a [Constructor] extended attribute, then the interface object MUST have a [[Call]] internal property, which allows construction of objects that implement the given interface. In order to define how overloaded constructor invocations are resolved within the [[Call]] method, the overload resolution algorithm is defined. Its input is an effective overload set, S, and a list of ECMAScript values, arg0..n−1. The algorithm behaves as follows:

Editorial note

Need to test how implementations actually behave when passed too few or too many arguments. (Mail.)

  1. Initialize R to a set with the same values as S.
  2. Remove from R all entries whose type list is not equal to n.
  3. If R contains more than one entry:
    1. Initialize i to 0.
    2. While i < n:
      1. Initialize types to the set of IDL types { any }.
      2. Depending on the value of argi:
        An Undefined, Boolean or Number value
        Add to types the primitive types and nullable primitive types.
        A String value
        Add to types the DOMString and DOMString? types.
        null
        Add to types the object types, all nullable types and all array types.
        A array host object
        Add to types the object type and an array type that corresponds to the type of the IDL array the host array object represents.
        Any other host object
        Add to types the object type and an interface type for all interfaces that are equal to, or inherit from, at least one of the interfaces that the host object implements.
        A native Array object
        (That is, a native object whose [[Class]] is "Array".) Add to types the object type, an interface type for each interface annotated with the [Callback] extended attribute and all array types.
        Any other native object
        Add to types the object type and an interface type for each interface annotated with the [Callback] extended attribute.
      3. Remove from R all entries with type list t and boolean list a where ai is false and ti ∉ types.
      4. If there exists an entry in R with type list t where ti ∈ types, then remove from R all entries with type list t where ti ∉ types.
      5. Set i to i + 1.
  4. Return R.

The internal [[Call]] method of the interface object behaves as follows, assuming arg0..n−1 is the list of argument values passed to the constructor, and I is the interface:

  1. Let id be the identifier of interface I.
  2. Initialize S to the effective overload set for constructors with identifier id on interface I and with argument count n (for the ECMAScript language binding).
  3. Set S to the result of passing S and arg0..n−1 to the overload resolution algorithm.
  4. If S is empty, throw a TypeError.
  5. If S contains more than one entry, then the constructor call is ambiguous. Remove all but one entry from S according to rules specified in the description of interface I, or arbitrarily if no such rules exist.
  6. Let x be the extended attribute that represents the constructor and t0..m−1 be the type list of the single entry in S.
  7. Let idlarg0..m−1 be a list of IDL values, where idlargi is the result of converting argi to an IDL value.
  8. Let R be the result of performing the actions listed in the description of the constructor represented by x with idlarg0..m−1 as the argument values.
  9. If the actions performed in the previous step resulted in an exception being thrown, then allow that exception to propagate out from this algorithm. Otherwise, return the result of converting R to an ECMAScript interface type value I.

If the internal [[Call]] method of the interface object returns normally, then it MUST return an object that implements interface I.

Interface objects for interfaces declared with a [Constructor] extended attribute MUST have a property named "length" with attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false } whose value is a Number determined as follows:

  1. Let id be the identifier of interface I.
  2. Initialize S to the effective overload set for constructors with identifier id on interface I and with argument count 0 (for the ECMAScript language binding).
  3. Return the maximum argument list length of the constructors in the entries of S.
4.4.1.2. Interface object [[HasInstance]] method

The internal [[HasInstance]] method of every interface object A MUST behave as follows, assuming V is the object argument passed to [[HasInstance]]:

  1. If V is not an object, return false.
  2. Let O be the result of calling the [[Get]] method of A with property name "prototype".
  3. If O is not an object, throw a TypeError exception.
  4. If V is a host object that implements the interface for which O is the interface prototype object, return true.
  5. Repeat:
    1. Set V to the value of the [[Prototype]] internal property of V.
    2. If V is null, return false.
    3. If O and V refer to the same object, return true.

4.4.2. Named constructors

A named constructor that exists due to one or more [NamedConstructor] extended attributes with a given identifier is a function object. It MUST have a [[Call]] internal property, which allows construction of objects that implement the interface on which the [NamedConstructor] extended attributes appear. It behaves as follows, assuming arg0..n−1 is the list of argument values passed to the constructor, id is the identifier of the constructor specified in the extended attribute named argument list, and I is the interface on which the [NamedConstructor] extended attribute appears:

  1. Initialize S to the effective overload set for constructors with identifier id on interface I and with argument count n (for the ECMAScript language binding).
  2. Set S to the result of passing S and arg0..n−1 to the overload resolution algorithm.
  3. If S is empty, throw a TypeError.
  4. If S contains more than one entry, then the constructor call is ambiguous. Remove all but one entry from S according to rules specified in the description of interface I, or arbitrarily if no such rules exist.
  5. Let x be the extended attribute that represents the constructor, and t0..m−1 be the type list, of the single entry in S.
  6. Let idlarg0..m−1 be a list of IDL values, where idlargi is the result of converting argi to an IDL value.
  7. Let R be the result of performing the actions listed in the description of the constructor represented by x with idlarg0..m−1 as the argument values.
  8. If the actions performed in the previous step resulted in an exception being thrown, then allow that exception to propagate out from this algorithm. Otherwise, return the result of converting R to an ECMAScript interface type value I.

If the internal [[Call]] method of the named constructor returns normally, then it MUST return an object that implements interface I.

A named constructor MUST have a property named "length" with attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false } whose value is a Number determined as follows:

  1. Initialize S to the effective overload set for constructors with identifier id on interface I and with argument count 0 (for the ECMAScript language binding).
  2. Return the maximum argument list length of the constructors in the entries of S.

4.4.3. Interface prototype object

There MUST exist an interface prototype object for every interface defined, regardless of whether the interface was declared with the [NoInterfaceObject] extended attribute. The interface prototype object for a particular interface has properties that correspond to the attributes and operations defined on that interface. These properties are described in more detail in sections 4.4.5 and 4.4.6 below.

As with the interface object, the interface prototype object also has properties that correspond to the constants defined on that interface, described in section 4.4.4 below.

The interface prototype object MUST also have a property named constructor with attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true } whose value is a reference to the interface object for the interface.

The value of the internal [[Prototype]] property of the interface prototype object depends on the structure of the interface’s inheritance hierarchy — specifically, what the interface’s prototype parent is, and whether it has any mixin interfaces.

The prototype parent of an interface, A, is defined as follows. If interface A is declared to inherit from one or more other interfaces then the first interface identified by the InterfaceInheritance non-terminal that has an ancestor interface with the [PrototypeRoot] extended attribute is interface A’s prototype parent. Otherwise, interface A has no prototype parent. The prototype ancestors of A is the set of interfaces that includes A’s prototype parent (if it exists), and the prototype parent of any other prototype ancestor of A.

A mixin of an interface, A, is any interface that is not one of A’s prototype ancestors, and also:

  • is an explicit ancestor interface of A;
  • is identified by an implements statement as being implemented on all objects of type A;
  • is a mixin of any other of A’s mixins; or
  • is an explicit ancestor interface of any other of A’s mixins.

The value of the internal [[Prototype]] property of an interface’s interface prototype object is determined as follows:

  • If the interface has no mixins and no prototype parent, then the internal [[Prototype]] property’s value is a reference to the Object prototype object.
  • Otherwise, if the interface has no mixins but does have a prototype parent, then the internal [[Prototype]] property’s value is a reference to the interface prototype object of that prototype parent.
  • Otherwise, the interface does have mixins. The internal [[Prototype]] property’s value is a reference to the mixin prototype object for the interface (defined below).
4.4.3.1. Mixin prototype object
Editorial note

Travis requests no mixin prototype objects. (Mail).

The mixin prototype object for an interface is an object as follows:

  • The object has properties that are the union of all properties that exist on the interface’s mixinsinterface prototype objects. If there are multiple properties with the same name, then it is undefined which of those properties ends up on the mixin prototype object.
  • The object’s internal [[Prototype]] property value is a reference to the interface prototype object for the interface’s prototype parent, or, if the interface has no prototype parent, a reference to the Object prototype object.
Editorial note

Maybe the functions on mixin prototype objects should just call the relevant function on the original interface’s prototype object. That way you could overwrite EventTarget.prototype.addEventListener, for example, and the addEventListener in the prototype chain of a Node would end up calling that new function. (Mail.)

If two interfaces have the same set of mixins, and either both have the same prototype parent or both have no prototype parent, then their mixin prototype objects MUST be the same object.

4.4.4. Constants

For each constant defined on the interface, there MUST be a corresponding property on the interface object, if it exists, if the identifier of the constant is not “prototype”. The property has the following characteristics:

  • The name of the property is the identifier of the constant.
  • The value of the property is that which is obtained by converting the constant’s IDL value to an ECMAScript value.
  • The property has attributes { [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false }.

In addition, a property with the same characteristics MUST exist on the interface prototype object, unless:

4.4.5. Attributes

For each attribute defined on the interface whose identifier is not “constructor”, there MUST be a corresponding property on the interface prototype object, unless:

  • the identifier of the attribute is “constructor”; or
  • the identifier of the attribute is “toString” and the interface has a stringifier.

The characteristics of these properties are as follows:

  • The name of the property is the identifier of the attribute.
  • The property has attributes { [[Get]]: G, [[Set]]: S, [[Enumerable]]: true, [[Configurable]]: true }, where G is the attribute getter and S is the attribute setter, both of which are defined below.
  • The attribute getter is a Function object whose behavior when invoked is as follows:
    1. Let O be the result of calling ToObject on the this value.
    2. If O is not an instance of the interface on which the attribute was declared, then throw a TypeError.
    3. Let idlValue be the result of performing the actions listed in the description of the attribute that occur when getting, with O as the object.
    4. Let V be the result of converting the idlValue to an ECMAScript value.
    5. Return V.
    The value of the Function object’s length property is the Number value 0.
  • The attribute setter is undefined if the attribute is declared readonly and has neither a [PutForwards] nor a [Replaceable] extended attribute declared on it. Otherwise, it is a Function object whose behavior when invoked is as follows:
    1. Let O be the result of calling ToObject on the this value.
    2. If O is not an instance of the interface on which the attribute was declared, then throw a TypeError.
    3. Let V be the value of the first argument passed to the Function, or undefined is no arguments were passed.
    4. If the attribute is declared with a [PutForwards] extended attribute, then:
      1. Let Q be the result of calling the [[Get]] method on O using the identifier of the attribute as the property name.
      2. If Q is not an object, then throw a TypeError.
      3. Let A be the attribute identified by the [PutForwards] extended attribute.
      4. Call the [[Put]] method on Q using the identifier of A as the property name and V as the value.
      5. Return.
    5. If the attribute is declared with a [Replaceable] extended attribute, then:
      1. Let O be the result of calling ToObject on the this value.
      2. If O is not an instance of the interface on which the attribute was declared, then throw a TypeError.
      3. Let P be the identifier of the attribute.
      4. Call the [[DefineOwnProperty]] method of O passing property name P, Property Descriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }, and false.
      5. Return undefined.
    6. Let idlValue be the result of converting V to an IDL value.
    7. Perform the actions listed in the description of the attribute that occur when setting, with O as the object and idlValue as the value.
    8. Return undefined.
    The value of the Function object’s length property is the Number value 1.

4.4.6. Operations

For each unique identifier of a non-omittable operation defined on the interface, there MUST be a corresponding property on the interface prototype object, unless:

  • the effective overload set for that identifier and operation and with an argument count of 0 (for the ECMAScript language binding) has no entries;
  • the identifier of the operation is “constructor”; or
  • the identifier of the operation is “toString” and the interface has a stringifier.

The characteristics of such a corresponding property are as follows:

  • The name of the property is the identifier.
  • The property has attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }.
  • The value of the property is a Function object whose behavior is as follows, assuming id is the identifier, arg0..n−1 is the list of argument values passed to the function and I is the interface:
    1. Initialize S to the effective overload set for regular operations with identifier id on interface I and with argument count n (for the ECMAScript language binding).
    2. Set S to the result of passing S and arg0..n−1 to the overload resolution algorithm.
    3. If S is empty, throw a TypeError.
    4. If S contains more than one entry, then the operation call is ambiguous. Remove all but one entry from S according to rules specified in the description of interface I, or arbitrarily if no such rules exist.
    5. Let op be the operation and t0..m−1 be the type list of the single entry in S.
    6. Let idlarg0..m−1 be a list of IDL values, where idlargi is the result of converting argi to an IDL value.
    7. Let R be the result of performing the actions listed in the description of operation op with idlarg0..m−1 as the argument values.
    8. If the actions performed in the previous step resulted in an exception being thrown, then allow that exception to propagate out from this algorithm. Otherwise, return the result of converting R to an ECMAScript value of the type op is declared to return.
  • The value of the Function object’s length property is a Number determined as follows:
    1. Initialize S to the effective overload set for regular operations with identifier id on interface I and with argument count 0 (for the ECMAScript language binding).
    2. Return the maximum argument list length of the functions in the entries of S.

In addition, if the interface has a stringifier, then a property MUST exist on the interface prototype object whose name is toString and whose value is a Function object. If "stringifier" was specified on an attribute A, then the function, when invoked, MUST behave as follows:

  1. Let O be the result of calling ToObject on the this value.
  2. Let V be the result of invoking the [[Get]] method of O with P as the argument.
  3. Return ToString(V).

If "stringifier" was specified on an operation with an identifier P, then the function, when invoked, MUST behave as follows:

  1. Let O be the result of calling ToObject on the this value.
  2. Let F be the result of invoking the [[Get]] method of object O with P as the argument.
  3. If F is not callable, throw a TypeError.
  4. Let V be the result of invoking the [[Call]] method of F, using O as the this value and passing no arguments.
  5. Return ToString(V).

If "stringifier" was specified on an operation with no identifier, then the behavior of the function is the stringification behavior of the interface, as described in the prose for the interface.

4.5. Host objects implementing interfaces

The value of the internal [[Prototype]] property of a host object implementing one or more interfaces depends on exactly what interfaces it implements, and in particular what its primary prototype interface is.

If the host object implements an interface that has the [PrototypeRoot] extended attribute, then the interface the host object implements that has the largest prototype ancestor set is deemed to be the primary prototype interface of the host object. (If there are multiple such sets, then it is undefined what value the internal [[Prototype]] property has.) Otherwise, the host object has no primary prototype interface.

The value of the host object’s internal [[Prototype]] property is determined as follows:

  • If the host object implements no interfaces, then its internal [[Prototype]] property value is a reference to the Object prototype object.
  • If the host object implements a single interface, then its internal [[Prototype]] property is a reference to the interface prototype object of that interface.
  • Otherwise, if the host object has a primary prototype interface and implements no interfaces other than its primary prototype interface and all of its ancestors, then the value of the internal [[Prototype]] property is a reference to the interface prototype object for the host object’s primary prototype interface.
  • Otherwise, the host object implements at least two interfaces, and has no primary prototype interface or implements some interfaces other than its primary prototype interface and all of its ancestors. The value of the internal [[Prototype]] property is a reference to the host object mixin prototype object for the host object (defined below).

The value of the internal [[Class]] property of a host object is determined as follows:

  • If the host object implements a single interface, then the value of the internal [[Class]] property MUST be the identifier of that interface.
  • Otherwise, if the host object has a primary prototype interface, then the value of the internal [[Class]] property MUST be the identifier of that interface.
  • Otherwise, no particular value is required to be used for the value of the internal [[Class]] property.
Editorial note

Should there be more restrictions on the [[Class]]? (Mail.)

4.5.1. Host object mixin prototype object

The host object mixin prototype object for a given host object is an object as follows:

  • The object has properties that are the union of all properties that exist on the interfaces that the host object implements and which are not the host object’s primary prototype interface or one of its ancestors.
  • The object’s internal [[Prototype]] property value is a reference to the interface prototype object for the host object’s primary prototype interface, or, if the host object has no primary prototype interface, a reference to the Object prototype object.

If two host objects implement the same set of interfaces and have references to host object mixin prototype objects as their internal [[Prototype]] property values, then these host object mixin prototype objects MUST be the same object.

4.5.2. Indexed properties

If a host object implements an interface that supports indexed properties, the object will have additional properties that correspond to the object’s indexed properties. If the host object implements multiple interfaces that support indexed properties, then it is undefined what additional properties will exist due to these indexed properties.

Whenever a given index N becomes supported property index on the host object the following steps MUST be followed:

  1. Let O be the host object.
  2. Let I be the interface O implements that supports indexed properties.
  3. If the [[Extensible]] property of O is false, return.
  4. Let P be ToString(N).
  5. Let hasProp be the result of calling [[HasProperty]] on O with P as the property name.
  6. If hasProp is true and I is not declared with the [OverrideBuiltins] extended attribute, return.
  7. Let get be the indexed property getter for interface I and index N.
  8. Let set be the indexed property setter for interface I and index N if I declares an index setter, and false otherwise.
  9. Let configurable be true if I declares an index deleter, and false otherwise.
  10. Call the [[DefineOwnProperty]] method of O passing P, Property Descriptor { [[Get]]: get, [[Set]]: set, [[Enumerable]]: true, [[Configurable]]: configurable }, and false as arguments.

The property created by the above steps, if it was created, is called the corresponding indexed property. Its name is an array index property name, which is a property name for which the following algorithm returns true:

  1. Let i be ToUint32(P).
  2. Let s be ToString(i).
  3. If sP or i = 232 − 1, return false.
  4. Return true.

The indexed property getter for a given interface I and index N is a Function object that, when invoked, behaves as follows:

  1. Let O be the result of calling ToObject with the this value.
  2. If O does not implement I, throw a TypeError.
  3. If N is not currently the supported property index on O, then throw a TypeError.
  4. Let idlValue be an uninitialized variable.
  5. If the index getter was defined using an operation with an identifier, then:
    1. Let T be the return type of the operation.
    2. Let F be the result of calling [[Get]] on O with the identifier of the operation as the property name.
    3. If F is not a callable object, throw a TypeError.
    4. Let V be the result of calling [[Call]] on F, providing O as the this value and with ToString(N) as the only argument.
    5. Set idlValue to the result of converting V to an IDL value of type T.
  6. Otherwise, the index getter was defined using an operation without an identifier:
    1. Set idlValue to the result of performing the steps listed in the description of the interface to determine the value of an indexed property for the index given by N.
  7. Set finalValue to the result of converting idlValue to an ECMAScript value.
  8. Return finalValue.

The length property of an indexed property getter is the Number value 0.

The indexed property setter for a given interface I and index N is a Function object that, when invoked, behaves as follows:

  1. Let O be the result of calling ToObject with the this value.
  2. If O does not implement I, throw a TypeError.
  3. If N is not currently the supported property index on O, then throw a TypeError.
  4. Let T be the return type of the operation used to declare the index setter.
  5. Let V be the value of the first argument passed to the Function, or undefined if no arguments were passed.
  6. Let idlValue be the result of converting V to an IDL value of type T.
  7. If the index getter was defined using an operation without an identifier, then:
    1. Perform the steps listed in the interface description to set the value of an existing indexed property with N as the index and idlValue as the value.
  8. Otherwise, the index setter was defined using an operation with an identifier:
    1. Let F be the result of calling [[Get]] on O with the identifier of the operation as the property name.
    2. If F is not a callable object, throw a TypeError.
    3. Let finalValue be the result of converting idlValue to an ECMAScript value.
    4. Call the [[Call]] method of F, providing O as the this value and finalValue as the only argument.

The length property of an indexed property setter is the Number value 1.

As soon as an index N stops being a supported property index, then its corresponding indexed property, if it exists, MUST be removed from the host object.

Support for index creators is handled by the host object [[DefineOwnProperty]] method defined in section 4.5.4, and support for index deleters is handled by the host object [[Delete]] method defined in section 4.5.5.

4.5.3. Named properties

If a host object implements an interface that supports named properties, the object will have additional properties that correspond to the object’s named properties. If the host object implements multiple interfaces that support named properties, then it is undefined what additional properties will exist due to these named properties.

Whenever a given string N becomes a supported property name on the host object the following steps MUST be followed:

  1. Let O be the host object.
  2. Let I be the interface O implements that supports indexed properties.
  3. If the [[Extensible]] property of O is false, return.
  4. If I supports indexed properties and N is a array index property name, return.
  5. Let hasProp be the result of calling [[HasProperty]] on O with P as the property name.
  6. If hasProp is true and I is not declared with the [OverrideBuiltins] extended attribute, return.
  7. Let get be the named property getter for interface I and name N.
  8. Let set be the named property setter for interface I and name N if I declares a name setter, and false otherwise.
  9. Let configurable be true if I declares an index deleter, and false otherwise.
  10. Call the [[DefineOwnProperty]] method of O passing P, Property Descriptor { [[Get]]: get, [[Set]]: set, [[Enumerable]]: true, [[Configurable]]: configurable }, and false as arguments.

The property created by the above steps, if it was created, is called the corresponding named property.

The named property getter for a given interface I and name N is a Function object that, when invoked, behaves as follows:

  1. Let O be the result of calling ToObject with the this value.
  2. If O does not implement the interface that defined the name getter, throw a TypeError.
  3. If N is not currently the supported named property on O, then throw a TypeError.
  4. Let idlValue be an uninitialized variable.
  5. If the name getter was defined using an operation with an identifier, then:
    1. Let T be the return type of the operation.
    2. Let F be the result of calling [[Get]] on O with the identifier of the operation as the property name.
    3. If F is not a callable object, throw a TypeError.
    4. Let V be the result of calling [[Call]] on F, providing O as the this value and with N as the only argument.
    5. Set idlValue to the result of converting V to an IDL value of type T.
  6. Otherwise, the name getter was defined using an operation without an identifier:
    1. Set idlValue to the result of performing the steps listed in the description of the interface to determine the value of a named property for the name given by N.
  7. Set finalValue to the result of converting idlValue to an ECMAScript value.
  8. Return finalValue.

The length property of an named property getter is the Number value 0.

The named property setter for a given interface I and name N is a Function object that, when invoked, behaves as follows:

  1. Let O be the result of calling ToObject with the this value.
  2. If O does not implement the interface that defined the name setter, throw a TypeError.
  3. If L is not currently the supported property name on O, then throw a TypeError.
  4. Let T be the return type of the operation used to declare the name setter.
  5. Let V be the value of the first argument passed to the Function, or undefined if no arguments were passed.
  6. Let idlValue be the result of converting V to an IDL value of type T.
  7. If the name getter was defined using an operation without an identifier, then:
    1. Perform the steps listed in the interface description to set the value of an existing named property with N as the name and idlValue as the value.
  8. Otherwise, the name setter was defined using an operation with an identifier:
    1. Let F be the result of calling [[Get]] on O with the identifier of the operation as the property name.
    2. If F is not a callable object, throw a TypeError.
    3. Let finalValue be the result of converting idlValue to an ECMAScript value.
    4. Call the [[Call]] method of F, providing O as the this value and finalValue as the only argument.

The length property of an named property setter is the Number value 1.

As soon as a given string N stops being supported property name, then its corresponding named property, if it exists, MUST be removed from the host object.

Support for name creators is handled by the host object [[DefineOwnProperty]] method defined in section 4.5.4, and support for name deleters is handled by the host object [[Delete]] method defined in section 4.5.5.

4.5.4. Host object [[DefineOwnProperty]] method

The internal [[DefineOwnProperty]] method of every host object O that implements an interface with a creator MUST behave as follows, assuming P is the property name and V is the property value passed to [[Put]]:

  1. If O implements an interface with an index creator and P is an array index property name, then:
    1. Let T be the return type of the operation used to declare the index creator.
    2. Let idlValue be the result of converting V to an IDL value of type T.
    3. If the index creator was defined using an operation without an identifier, then:
      1. Perform the steps listed in the interface description to set the value of a new indexed property with ToUint32(P) as the index and idlValue as the value.
    4. Otherwise, the index creator was defined using an operation with an identifier:
      1. Let F be the result of calling [[Get]] on O with the identifier of the operation.
      2. If F is not a callable object, throw a TypeError.
      3. Let finalValue be the result of converting idlValue to an ECMAScript value.
      4. Invoke the [[Call]] method of F, providing O as the this value and with ToUint32(P) and finalValue as the two argument values.
    5. Return.
  2. If O implements an interface with a name creator, then:
    1. Let T be the return type of the operation used to declare the name creator.
    2. Let idlValue be the result of converting V to an IDL value of type T.
    3. If the name creator was defined using an operation without an identifier, then:
      1. Perform the steps listed in the interface description to set the value of a new named property with P as the name and idlValue as the value.
    4. Otherwise, the name creator was defined using an operation with an identifier:
      1. Let F be the result of calling [[Get]] on O with the identifier of the operation.
      2. If F is not a callable object, throw a TypeError.
      3. Let finalValue be the result of converting idlValue to an ECMAScript value.
      4. Invoke the [[Call]] method of F, providing O as the this value and with P and finalValue as the two argument values.
    5. Return.
  3. Call the default [[DefineOwnProperty]] internal method ([ECMA-262], section 8.12.9) on O passing P, Desc, and Throw as arguments.

4.5.5. Host object [[Delete]] method

The internal [[Delete]] method of every host object O that implements an interface with a deleter MUST behave as follows, assuming P is the property name passed to [[Delete]]:

  1. Let desc be the result of calling [[GetOwnProperty]] internal method of O with property name P.
  2. If desc is undefined, then return true.
  3. If desc.[[Configurable]] is false, then:
    1. If Throw is true, then throw a TypeError.
    2. Otherwise, return false.
  4. If desc is the descriptor for a corresponding indexed property, and O implements an interface with an index deleter, then:
    1. If the index deleter was defined using an operation without an identifier, then:
      1. Perform the steps listed in the interface description to delete an existing indexed property with ToUint32(P) as the index.
      2. If the steps indicated that the deletion failed, return false.
      3. Return true.
    2. Otherwise, the index deleter was defined using an operation with an identifier:
      1. Let F be the result of calling [[Get]] on O with the operation's identifier as the property name.
      2. If F is not a callable object, throw a TypeError.
      3. Let B be the result of invoking the [[Call]] method of F, providing O as the this value and with ToUint32(P) as the argument.
      4. Return ToBoolean(B), or true if the operation was declared to return void.
  5. If desc is the descriptor for a corresponding named property, and O implements an interface with an name deleter, then:
    1. If the name deleter was defined using an operation without an identifier, then:
      1. Perform the steps listed in the interface description to delete an existing named property with P as the name.
      2. If the steps indicated that the deletion failed, return false.
      3. Return true.
    2. Otherwise, the name deleter was defined using an operation with an identifier:
      1. Let F be the result of calling [[Get]] on O with the operation's identifier as the property name.
      2. If F is not a callable object, throw a TypeError.
      3. Let B be the result of invoking the [[Call]] method of F, providing O as the this value and with P as the argument.
      4. Return ToBoolean(B), or true if the operation was declared to return void.
  6. Remove the own property with name P from O.
  7. Return true.

4.5.6. Host object [[Call]] method

The internal [[Call]] method of every host object O that implements an interface I with at least one caller MUST behave as follows, assuming arg0..n−1 is the list of argument values passed to [[Call]]:

  1. Initialize S to the effective overload for callers on I and with argument count n (for the ECMAScript language binding).
  2. Set S to be the result of passing S and arg0..n−1 to the overload resolution algorithm.
  3. If S is empty, throw a TypeError.
  4. If S contains more than one entry, then the call is ambiguous. Remove all but one entry from S according to the rules specified in the description of interface I, or arbitrarily if no such rules exist.
  5. Let op be the operation and t0..m−1 be the type list of the single entry in S.
  6. Let idlarg0..m−1 be a list of IDL values, where idlargi is the result of converting argi to an IDL value.
  7. Perform the actions listed in the description of caller op with idlarg0..m−1 as the argument values.
  8. If the actions performed in the previous step resulted in an exception being thrown, then allow that exception to propagate out from this algorithm.
  9. Otherwise, return the result of converting the return value from those actions to an ECMAScript value of the type op is declared to return (or undefined if op is declared to return void).

4.6. Native objects implementing interfaces

Some interfaces can be implemented in script by an ECMAScript native object. Only interfaces with the following characteristics can have native object implementations:

The following cases determine whether and how a given native object implements an interface with the above characteristics:

  • If the interface is declared with one or more operations that all have the same identifier, the [Callback] extended attribute on the interface has the FunctionOnly argument and there are no attributes on the interface, then the native object is considered to implement that interface if it is a Function object. The native object itself is the implementation of the operation.
  • Otherwise, if the interface is declared with one or more operations that all have the same identifier but the [Callback] extended attribute on the interface does not have the FunctionOnly argument, then any native object is considered to implement that interface. If the native object is a Function object, the [Callback] extended attribute does not have the PropertyOnly argument and the interface has no attributes, then the function itself is the implementation of the operation. Otherwise, the implementation of the operation is the result of invoking [[Get]] on the native object with a property name that is the identifier of the operation.
  • Otherwise, the operations declared on the interface have zero or more than one distinct identifiers or the interface has attributes declared on it. Any native object is considered to implement the interface. For each operation declared on the interface, the implementation of that operation is the result of invoking [[Get]] on the native object with a property name that is the identifier of the operation.

A user agent calls a native object’s operation implementation with a list of IDL argument values idlarg0..n−1 by following the algorithm below. The callback this value is the value to use as the this value when calling the native object’s operation implementation [[Call]] method. By default, the native object itself is used as the callback this value, however this MAY be overridden by other specifications.

  1. Let O be the native object.
  2. Let X be the implementation of the operation.
  3. If Type(X) is not Object, throw a TypeError exception.
  4. If X does not implement the internal [[Call]] method, throw a TypeError exception.
  5. Let arg0..n−1 be a list of ECMAScript values, where argi is the result of converting idlargi to an ECMAScript value.
  6. Let R be the result of invoking the [[Call]] method of X, providing the callback this value as the this value and arg0..n−1 as the argument values.
  7. If the operation’s return type is void, return.
  8. Return the result of converting R to an IDL value of the same type as the operation’s return type.

Note that while an interface with constants can be implemented by a native object, no properties corresponding to those constants need be on the object.

A user agent retrieves the value of a native object’s attribute using the following algorithm:

  1. Let O be the native object.
  2. Let P be the identifier of the attribute.
  3. Let R be the result of invoking the [[Get]] method of O with property name P.
  4. Return the result of converting R to an IDL value of the same type as the attribute’s type.

A user agent sets the value of a native object’s attribute using the following algorithm:

  1. Let O be the native object.
  2. Let P be the identifier of the attribute.
  3. Let V be the IDL value to be assigned to the attribute.
  4. Let W be the result of converting V to an ECMAScript value.
  5. Invoke the [[Put]] method of O with property name P and value W.

4.7. Exceptions

For every exception that is not declared with the [NoInterfaceObject] extended attribute, a corresponding property MUST exist on the exception’s relevant namespace object. The name of the property is the identifier of the exception, and its value is an object called the exception interface object, which provides access to any constants that have been associated with the exception. The property has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }.

4.7.1. Exception interface object

The exception interface object for a particular exception MUST have an internal [[Prototype]] object whose value is the Object prototype object.

If any constants have been declared on the exception, then the exception interface object will have properties corresponding to these constants as described in section 4.7.3 below.

The exception interface object MUST also have a property named prototype with attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false } whose value is an object called the exception interface prototype object. This object also provides access to the constants that are declared on the exception.

4.7.1.1. Exception interface object [[HasInstance]] method

The internal [[HasInstance]] method of every exception interface object E MUST behave as follows, assuming V is the object argument passed to [[HasInstance]]:

  1. If V is not an object, return false.
  2. If V is a host object that is an exception whose exception interface object is E, return true.
  3. Return false.

4.7.2. Exception interface prototype object

There MUST exist an exception interface prototype object for every exception defined, regardless of whether the exception was declared with the [NoInterfaceObject] extended attribute. The exception interface prototype object for a particular exception has properties that correspond to the constants and exception members defined on the exception. These properties are described in more detail in sections 4.7.3 and 4.7.4, below.

4.7.3. Constants

For each constant defined on the exception, there MUST be a corresponding property on the exception interface object, if it exists, if the identifier of the constant is not “prototype”. The property has the following characteristics:

  • The name of the property is the identifier of the constant.
  • The value of the property is the ECMAScript value that is equivalent to the constant’s IDL value, according to the rules in section 4.1 above.
  • The property has attributes { [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false }.

In addition, a property with the same characteristics MUST exist on the exception interface prototype object, if the identifier of the constant is not “constructor”.

4.7.4. Exception members

For each exception member whose identifier is not “constructor” that is defined on the exception, there MUST be a corresponding property on the exception interface prototype object, whose characteristics are as follows:

  • The name of the property is the identifier of the exception member.
  • The property has attributes { [[Get]]: G, [[Enumerable]]: true, [[Configurable]]: true }, where G is the exception member getter, defined below.
  • The exception member getter is a Function object whose behavior when invoked is as follows:
    1. Let O be the result of calling ToObject on the this value.
    2. If O is not a host exception object for the exception on which the exception member was declared, then throw a TypeError.
    3. Let idlValue be the IDL value of O’s exception member.
    4. Let V be the result of converting the idlValue to an ECMAScript value.
    5. Return V.
    The value of the Function object’s length property is the Number value 0.

4.8. Host exception objects

A host exception object is a host object that represents a given exception. The behavior of a host object that represents more than one exception, or one that represents an exception as well as implements an interface, is not defined.

The value of the internal [[Prototype]] property of the host exception object MUST be the exception interface prototype object.

The value of the internal [[Class]] property of the host exception object MUST be the identifier of the exception.

4.9. Handling exceptions

None of the algorithms or processing requirements in the ECMAScript language binding catch ECMAScript exceptions. Whenever an ECMAScript Function is invoked due to requirements in this section and that Function ends due to an exception being thrown, that exception MUST propagate to the caller, and if not caught there, to its caller, and so on.

Example

The following IDL fragment defines two interfaces and an exception. The valueOf attribute on ExceptionThrower is defined to throw an exception whenever an attempt is made to get its value.

IDL
interface Dahut {
  attribute DOMString type;
};

exception SomeException {
};

interface ExceptionThrower {
  // This attribute always throws a SomeException and never returns a value.
  attribute long valueOf getraises(SomeException);
};

Assuming an ECMAScript implementation supporting this interface, the following code demonstrates how exceptions are handled:

ECMAScript
var d = getDahut();              // Obtain an instance of Dahut.
var et = getExceptionThrower();  // Obtain an instance of ExceptionThrower.

try {
  d.type = { toString: function() { throw "abc" } };
} catch (e) {
  // The string "abc" is caught here, since as part of the conversion
  // from the native object to a string, the anonymous function
  // was invoked, and none of the [[DefaultValue]], ToPrimitive or
  // ToString algorithms are defined to catch the exception.
}

try {
  d.type = { toString: { } };
} catch (e) {
  // An exception is caught here, since an attempt is made to invoke
  // [[Call]] on the native object that is the value of toString
  // property.
}

d.type = et;
// An uncaught SomeException exception is thrown here, since the
// [[DefaultValue]] algorithm attempts to get the value of the
// "valueOf" property on the ExceptionThrower object.  The exception
// propagates out of this block of code.

5. Java binding

This section describes how definitions written with the IDL defined in section 3 correspond to particular constructs in Java 5 [JLS3].

5.1. Names

Since Java has a number of reserved words in the language, some identifiers of Java constructs corresponding to IDL definitions need to be escaped to avoid conflicts. A name is Java escaped as follows:

  • If the name is a Java reserved word, then the Java escaped name is the name prefixed with a U+005F LOW LINE ("_") character.
  • Otherwise, the name is not a Java reserved word. The Java escaped name is simply the name.
Note

At the time of publication, the list of Java reserved words is the following: abstract, assert, boolean, break, byte, case, catch, char, class, const, continue, default, do, double, else, enum, extends, final, finally, float, for, goto, if, implements, import, instanceof, int, interface, long, native, new, package, private, protected, public, return, short, static, strictfp, super, switch, synchronized, this, throw, throws, transient, try, void, volatile, while.

5.2. Java type mapping

This section describes how types in the IDL map to types in Java.

Each sub-section below describes how values of a given IDL type are represented in Java. For each IDL type, it is described how Java values are converted to an IDL value when passed as an argument to a Java method (corresponding to an operation or attribute). Conversely, it is described how IDL values of that type are converted to Java values when being used as the value of a Java final variable (corresponding to a constant) or when returned from a Java method (corresponding to an operation, attribute or exception member).

5.2.1. any

The any IDL type corresponds to a Java java.lang.Object value.

How to convert a Java value to an IDL any value depends on the type of the Java value:

A java.lang.Boolean object
The IDL value is obtained by converting the result of calling the booleanValue() method on the java.lang.Boolean object to an IDL boolean value.
A java.lang.Byte object
The IDL value is obtained by converting the result of calling the byteValue() method on the java.lang.Byte object to an IDL octet value.
A java.lang.Short object
The IDL value is obtained by converting the result of calling the shortValue() method on the java.lang.Short object to an IDL short value.
A java.lang.Integer object
The IDL value is obtained by converting the result of calling the intValue() method on the java.lang.Integer object to an IDL long value.
A java.lang.Long object
The IDL value is obtained by converting the result of calling the longValue() method on the java.lang.Long object to an IDL long long value.
A java.lang.Float object
The IDL value is obtained by converting the result of calling the floatValue() method on the java.lang.Float object to an IDL float value.
A java.lang.Double object
The IDL value is obtained by converting the result of calling the doubleValue() method on the java.lang.Double object to an IDL float value.
A java.lang.String object
The IDL value is obtained by converting the java.lang.String object to an IDL DOMString value.
An array object
The IDL value is the IDL sequence obtained by converting the Java array object to a sequence, as described in section 5.2.17 below.
An object that implements a Java array interface
The IDL value is the IDL array obtained by converting the Java object to an array, as described in section 5.2.18 below.
An object of any other class
The IDL value is an object value that references the same object.
null
The IDL value is the null object value.

How to convert an IDL any value to a Java java.lang.Object value depends on the actual type of the IDL value:

A value of a primitive type

The Java value is the result of converting the IDL value of the given type to a Java value, and then passing that value to the static method according to the following table:

IDL type Method
boolean java.lang.Boolean.valueOf(boolean)
octet java.lang.Byte.valueOf(byte)
short java.lang.Short.valueOf(short)
unsigned short java.lang.Short.valueOf(short)
long java.lang.Integer.valueOf(int)
unsigned long java.lang.Integer.valueOf(int)
long long java.lang.Long.valueOf(long)
unsigned long long java.lang.Long.valueOf(long)
float java.lang.Float.valueOf(float)
double java.lang.Double.valueOf(double)
An IDL value of any other type
The Java value is the result of converting the IDL value to a Java value.

5.2.2. void

The only place that the void type may appear in IDL is as the return type of an operation. Methods on Java objects that implement an operation whose IDL specifies a void return type MUST be declared to have a return type of void.

5.2.3. boolean

IDL boolean values are represented by Java boolean values.

The result of converting a Java boolean value to an IDL value is the IDL boolean that represents the same truth value as the Java boolean.

The result of converting an IDL boolean value to a Java value is the Java boolean that represents the same truth value as the IDL boolean.

5.2.4. octet

IDL octet values are represented by Java byte values. Note that while the IDL octet type is unsigned, with a range of [0, 255], the Java byte type is signed, with a range of [−128, 127].

Conversion of an octet value to a byte is performed as follows:

  1. Let x be the octet value to convert.
  2. If x < 128, return the byte whose value is x.
  3. Otherwise x ≥ 128. Return the byte whose value is x − 256.
Note

In Java this is the same as having the octet value stored in an int and casting it to a byte.

Conversion of a byte to an octet is performed as follows:

  1. Let x be the byte value to decode.
  2. If x ≥ 0, return the octet whose value is x.
  3. Otherwise x < 0. Return the octet whose value is x + 256.
Note

In Java this is the same as performing a bit-wise AND of the byte value with the int constant 0xff.

5.2.5. short

IDL short values are represented by Java short values.

The result of converting a Java short value to an IDL value is the IDL short that represents the same numeric value as the Java short.

The result of converting an IDL short value to a Java value is the Java short that represents the same numeric value as the IDL short.

5.2.6. unsigned short

IDL unsigned short values are represented by Java short values. Note that while the IDL unsigned short type is unsigned, with a range of [0, 65535], the Java short type is signed, with a range of [−32768, 32767].

Conversion of an IDL unsigned short value to a Java short is performed as follows:

  1. Let x be the IDL unsigned short value to convert.
  2. If x < 32768, return the Java short whose value is x.
  3. Otherwise x ≥ 32768. Return the Java short whose value is x − 65536.
Note

In Java this is the same as having the unsigned short value stored in an int and casting it to a short.

Conversion of a Java short to an IDL unsigned short value is performed as follows:

  1. Let x be the Java short value to decode.
  2. If x ≥ 0, return the IDL unsigned short whose value is x.
  3. Otherwise x < 0. Return the IDL unsigned short whose value is x + 65536.
Note

In Java this is the same as performing a bit-wise AND of the short value with the int constant 0xffff.

5.2.7. long

IDL long values are represented by Java int values.

The result of converting a Java int value to an IDL value is the IDL long that represents the same numeric value as the Java int.

The result of converting an IDL long value to a Java value is the Java int that represents the same numeric value as the IDL short.

5.2.8. unsigned long

IDL unsigned long values are represented by Java int values. Note that while the IDL unsigned long type is unsigned, with a range of [0, 4294967295], the Java int type is signed, with a range of [−2147483648, 2147483647].

Conversion of an IDL unsigned long value to a Java int is performed as follows:

  1. Let x be the IDL unsigned long value to convert.
  2. If x < 2147483648, return the Java int whose value is x.
  3. Otherwise x ≥ 2147483648. Return the Java int whose value is x − 4294967296.
Note

In Java this is the same as having the unsigned long value stored in a Java long and casting it to an int.

Conversion of a Java int to an IDL unsigned long value is performed as follows:

  1. Let x be the Java int value to decode.
  2. If x ≥ 0, return the IDL unsigned long whose value is x.
  3. Otherwise x < 0. Return the IDL unsigned long whose value is x + 4294967296.
Note

In Java this is the same as performing a bit-wise AND of the int value with the long constant 0xffffffffL.

5.2.9. long long

IDL long long values are represented by Java long values.

The result of converting a Java long value to an IDL value is the IDL long long that represents the same numeric value as the Java long.

The result of converting an IDL long long value to a Java value is the Java long that represents the same numeric value as the IDL long long.

5.2.10. unsigned long long

IDL unsigned long long values are represented by Java long values. Note that while the IDL unsigned long long type is unsigned, with a range of [0, 18446744073709551615], the Java long type is signed, with a range of [−9223372036854775808, 9223372036854775807].

Conversion of an IDL unsigned long long value to a Java long is performed as follows:

  1. Let x be the IDL unsigned long long value to convert.
  2. If x < 18446744073709551616, return the Java long whose value is x.
  3. Otherwise x ≥ 18446744073709551616. Return the Java long whose value is x − 18446744073709551615.

Conversion of a Java long to an IDL unsigned long long value is performed as follows:

  1. Let x be the Java long value to decode.
  2. If x ≥ 0, return the IDL unsigned long long whose value is x.
  3. Otherwise x < 0. Return the IDL unsigned long long whose value is x + 18446744073709551615.

5.2.11. float

IDL float values are represented by Java float values.

The result of converting a Java float value to an IDL value is the IDL float that represents the same numeric value as the Java float.

The result of converting an IDL float value to a Java value is the Java float that represents the same numeric value as the IDL float.

5.2.12. double

IDL double values are represented by Java double values.

The result of converting a Java double value to an IDL value is the IDL double that represents the same numeric value as the Java double.

The result of converting an IDL double value to a Java value is the Java double that represents the same numeric value as the IDL double.

5.2.13. DOMString

IDL DOMString values are represented by Java java.lang.String reference values.

A Java java.lang.String reference value is converted to an IDL DOMString value as follows:

  • If the value is null, then throw a java.lang.NullPointerException.
  • Otherwise, return the IDL DOMString value that represents the same sequence of 16 bit code units as the one the Java java.lang.String value represents.

The result of converting an IDL DOMString value to a Java java.lang.String value is a java.lang.String object that represents the same sequence of characters that the IDL DOMString represents.

5.2.14. object

IDL object values are represented by Java java.lang.Object reference values.

The result of converting a Java java.lang.Object reference value to an IDL value is the IDL object that is a reference to the same object, or the null value if the java.lang.Object is null.

The result of converting an IDL object value to a Java value is a Java java.lang.Object value that is a reference to the same object, or null if the object is the null value.

5.2.15. Interface types

IDL interface type values are represented by Java references of the corresponding Java interface type. (See section 5.4 below for how IDL interfaces have corresponding Java interfaces.)

Conversions to and from IDL interface type values are performed in the same way as that for the IDL object type.

5.2.16. Nullable types — T?

IDL nullable type values are represented with Java object references of a particular class, as determined by the table below:

Nullable type Java class
boolean? java.lang.Boolean
octet? java.lang.Byte
short? java.lang.Short
unsigned short? java.lang.Short
long? java.lang.Integer
unsigned long? java.lang.Integer
long long? java.lang.Long
unsigned long long? java.lang.Long
float? java.lang.Float
double? java.lang.Double
DOMString? java.lang.String

How to convert a Java value of one of the above classes to an IDL nullable type value depends on its value:

null
The IDL value is the null value.
A java.lang.Byte object
The IDL value is an octet? whose value is obtained by converting the result of calling the byteValue() method on the java.lang.Byte object to an octet.
A java.lang.Short object
The IDL value is a short? whose value is obtained by converting the result of calling the shortValue() method on the java.lang.Short object to a short.
A java.lang.Integer object
The IDL value is a long? whose value is obtained by converting the result of calling the intValue() method on the java.lang.Integer object. to a long.
A java.lang.Long object
The IDL value is a long long? whose value is obtained by converting the result of calling the longValue() method on the java.lang.Long object to a long long.
A java.lang.Float object
The IDL value is a float? whose value is obtained by converting the result of calling the floatValue() method on the java.lang.Float object to a float.
A java.lang.Double object
The IDL value is a double? whose value is obtained by converting the result of calling the doubleValue() method on the java.lang.Double object to a double.
A java.lang.String object
The IDL value is a DOMString? whose value is obtained by converting the java.lang.String object to a DOMString
An array object
The IDL value is a nullable IDL sequence obtained by converting the Java array object to a sequence, as described in section 5.2.17 below.

How to convert an IDL nullable type value to a Java value depends on its value and the inner type:

The null value
The Java value is null.
A non-null nullable primitive value

The Java value is the result of converting the IDL inner type to a Java value, and then passing that value to the static method according to the following table, where T is the IDL inner type:

T Method
boolean java.lang.Boolean.valueOf(boolean)
octet java.lang.Byte.valueOf(byte)
short java.lang.Short.valueOf(short)
unsigned short java.lang.Short.valueOf(short)
long java.lang.Integer.valueOf(int)
unsigned long java.lang.Integer.valueOf(int)
long long java.lang.Long.valueOf(long)
unsigned long long java.lang.Long.valueOf(long)
float java.lang.Float.valueOf(float)
double java.lang.Double.valueOf(double)
A non-null DOMString? value
The Java value is a java.lang.String object representing the same sequence of 16 bit code units as the DOMString? value.
A non-null sequence<T>? value
The Java value is the result of converting the IDL sequence value to a Java array object, as described in section 5.2.17 below.

5.2.17. Sequences — sequence<T>

IDL sequence<T> values are represented by Java arrays of type U, where U is the Java type used to represent the IDL type T.

A Java array A of type U is converted to an IDL sequence<T> as follows:

  1. If A is null, then throw a java.lang.NullPointerException.
  2. Let n be the length of the array A.
  3. Initialize S0..n−1 to be an IDL sequence with elements of type T, where each element is uninitialized.
  4. Initialize i to be 0.
  5. While i < n:
    1. Let E be the value value of A at index i.
    2. Set Si to the result of converting E to an IDL value of type T.
    3. Set i to i + 1.
  6. Return S.

An IDL sequence value S0..n−1 of type sequence<T> is converted to a Java array of type U object as follows:

  1. Let A be a new Java array object with element type U and length n.
  2. Initialize i to be 0.
  3. While i < n:
    1. Let E be the result of converting Si to a Java value of type U.
    2. Set element i of the array A to the value E.
    3. Set i to i + 1.
  4. Return A.

A Java object implementing an interface with an operation declared to return a sequence<T> value MUST NOT return null from the corresponding method. Similarly, a getter method for an IDL attribute MUST NOT return null if the attribute is declared to be of type sequence<T>.

5.2.18. Arrays — T[]

IDL T[] values are represented by Java objects implementing a particular interface, known as the Java array interface, depending on the type T.

For each of the primitive types there MUST exist a corresponding Java array interface of the following form:

Java
package org.w3c.dom;

public interface PrimitiveNameArray {
  int getLength();
  void setLength(int length);
  PrimitiveType getElement(int index);
  void setElement(int index, PrimitiveType value);
}

where PrimitiveName is the type name of the primitive type and PrimitiveType is the Java type used to represent it.

Example

For example, the Java array interface for the octet[] type is:

Java
package org.w3c.dom;

public interface OctetArray {
  int getLength();
  void setLength(int length);
  byte getElement(int index);
  void setElement(int index, byte value);
}

There MUST also exist the following interface, org.w3c.dom.ObjectArray<E>:

Java
package org.w3c.dom;

public interface ObjectArray<E> {
  int getLength();
  void setLength(int length);
  E getElement(int index);
  void setElement(int index, E value);
}

This interface, parameterized by the Java type used to represent array element type T, is the corresponding Java array interface for T.

Example

For example, the Java array interface for the sequence<DOMString?>[] type is org.w3c.dom.ObjectArray<java.lang.String[]>.

A Java object that implements a Java array interface represents a given IDL array value of type T[]. The methods on the object that implement that interface MUST behave as follows:

getLength()

This method returns the current length of the IDL array value.

setLength(length)

When called on an object representing a variable length array, this method sets the length of the array to length. When the array is lengthened, the new elements are set to the IDL value that results from converting to an IDL value the default value of the Java type that T corresponds to ([JLS3], section 4.12.5).

When called on an object representing a fixed length array, this method throws a java.lang.UnsupportedOperationException.

getElement(index)

This method returns the IDL value of type T at the represented array’s index index converted to a Java value.

setElement(index, value)

When called on an object representing an array that is not read only, this method sets the IDL value at the represented array’s index index to the result of converting value to an IDL value of type T.

When called on an object representing an array that is read only, this method throws a java.lang.UnsupportedOperationException.

A Java reference value O for an object implementing a Java array interface is converted to an IDL array value as follows:

  • If O is null, then the IDL array value is null.
  • Otherwise, if O is an object implementing a Java array interface corresponding to a primitive type, then the IDL array value is the array value that O represents. The type of the IDL array value is T[], where T is the primitive type.
  • Otherwise, if O is an object implementing org.w3c.dom.ObjectArray<E>, then the IDL array value is the array value that O represents. The type of the IDL array value is the IDL type that E corresponds to.

An IDL array value A of type T[] is converted to a Java value whose type is an object implementing the Java array interface corresponding to T, as follows:

  • If A is null, then the Java value is null.
  • Otherwise, if A is already represented by an object implementing a Java array interface, then the Java value is that object.
  • Otherwise, the Java value is newly created object implementing the Java array interface that corresponds to T.

5.3. Modules

Every IDL module corresponds to a Java package, whose name is the result of taking the module’s prefixed name, replacing every occurrence of the string “::” with “.”, and then removing the leading “.”.

Definitions inside an IDL module correspond to Java constructs declared to be in the package for that module.

Example

The following IDL fragment will result in four Java interfaces existing: org.w3c.dom.Document, org.w3c.dom.html.HTMLDocument, org.foo.FooDocument and org.foo.ext.ExtendedFooDocument.

IDL
module dom {
  interface Document {
    // ...
  };
};

module html {
  interface HTMLDocument {
    // ...
  };
};

[Prefix=org]
module foo {
  interface FooDocument {
    // ...
  };

  module ext {
    interface ExtendedFooDocument {
      // ...
    };
  };
};

5.4. Interfaces

A conforming Java implementation MUST have a public Java interface corresponding to to every IDL interface that is supported, whose name is the Java escaped identifier of the IDL interface and which resides in the Java package corresponding to the interface’s enclosing module (or the default package, if there is no enclosing module).

The Java interface MUST be declared to extend every Java interface that corresponds to an interface from which this IDL interface inherits.

5.4.1. Constants

For each constant defined on the IDL interface, there MUST be a corresponding constant declared on the Java interface with the following characteristics:

  • The constant has no modifiers.
  • The type of the constant is the Java type that corresponds to the type of the IDL constant, according to the rules in section 5.2 above.
  • The name of the constant is the Java escaped identifier of the constant.
  • The value of the constant is the result of converting the constant’s IDL value to a Java value, according to the rules in section 5.2 above.

5.4.2. Operations

Each operation defined on the IDL interface, I, will result in one or more methods being declared on the Java interface.

For each unique identifier id of an operation declared on I:

  • For each entry <optypesany> in the effective overload set for regular operations with identifier id on I and with argument count 0 (for the Java language binding), there MUST exist a method on the Java interface with the following characteristics:
    • The method has no modifiers.
    • The return type of the method is the Java type that corresponds to the operation return type, according to the rules in section 5.2 above.
    • The tenative name of the method is the Java escaped identifier of the operation. The name of the method is the tenative name of the method prefixed with the smallest number of U+005F LOW LINE ("_") characters required to make the name not equal to the name of a constant declared on the Java interface or one of the methods on the java.lang.Object class.
    • The method has an argument for each type, in order, that is in types. The type of method argument j is the Java type that corresponds to the IDL type typesj, according to the rules in section 5.2 above. If the length of types is the length of the argument list op is declared with, and op is a variadic operation, then the method is a variable arity method ([JLS3], section 8.4.1).
    • If op has IDL exceptions listed in the Raises clause, then the method SHOULD have a throws clause specifying all of the Java exception classes that correspond to those IDL exceptions, and no others. Otherwise, if op has no exceptions listed in the Raises clause, then the method SHOULD NOT have a throws clause.
    • An implementation of this method MUST perform the following steps:
      1. Let arg0..n−1 be the list of Java argument values passed to the method.
      2. Let idlarg0..n−1 be a list of IDL values, where idlargi is the result of converting argi to an IDL value of the type that the ith argument is declared to be.
      3. Let R be the result of performing the actions listed in the description of the operation op with idlarg0..n−1 as the argument values.
      4. If the actions performed in the previous step resulted in an exception being thrown, then allow that exception to propagate out from this algorithm. Otherwise, return the result of converting R to a Java value of the type op is declared to return.

5.4.3. Attributes

For each attribute defined on the IDL interface, there MUST be a corresponding getter method declared on the Java interface with the following characteristics:

  • The method has no modifiers.
  • The return type of the method is the Java type that corresponds to the attribute type, according to the rules in section 5.2 above.
  • The tentative name of the method is a U+0067 LATIN SMALL G ("g") character, followed by a U+0065 LATIN SMALL E ("e") character, followed by a U+0074 LATIN SMALL T ("t") character, followed by the first character of the identifier of the attribute uppercased (as if passed to the java.lang.Character.toUpperCase() method), followed by the remaining characters from the identifier of the attribute. The name of the method is the Java escaped tenative name of the method prefixed with the smallest number of U+005F LOW LINE ("_") characters required to make the name not equal to the name of a constant or method declared on the Java interface or one of the methods on the java.lang.Object class.
  • The method has no arguments.
  • An implementation of this method MUST perform the following steps:
    1. Let V be the IDL value that results from performing the actions listed for getting the corresponding attribute in the description of the interface.
    2. If the actions performed in the previous step resulted in an exception being thrown, then allow that exception to propagate out from this algorithm. Otherwise, return the result of converting V to a Java value of the type op is declared to return.

In addition, the method SHOULD have a throws clause specifying all of the Java exception classes that correspond to the IDL exceptions that are listed in the GetRaises clause of the attribute, and no others.

For each attribute defined on the IDL interface that is not read only, there MUST be a corresponding setter method declared on the Java interface with the following characteristics:

  • The method has no modifiers.
  • The return type of the method is void.
  • The tentative name of the method is a U+0073 LATIN SMALL S ("s") character, followed by a U+0065 LATIN SMALL E ("e") character, followed by a U+0074 LATIN SMALL T ("t") character, followed by the first character of the identifier of the attribute uppercased (as if passed to the java.lang.Character.toUpperCase() method), followed by the remaining characters from the identifier of the attribute. The name of the method is the Java escaped tenative name of the method prefixed with the smallest number of U+005F LOW LINE ("_") characters required to make the name not equal to the name of a constant or method declared on the Java interface or one of the methods on the java.lang.Object class.
  • The method has a single argument whose type is the Java type that corresponds to the attribute type, according to the rules in section 5.2 above.
  • An implementation of this method MUST perform the following steps:
    1. Let arg be the Java value that was passed as the argument to the method.
    2. Let idlarg be the result of converting arg to an IDL value of the type the attribute is declared to be.
    3. Perform the actions for setting the corresponding attribute with the value idlarg listed in the description of the interface.
    4. If the actions performed in the previous step resulted in an exception being thrown, then allow that exception to propagate out from this algorithm.

In addition, the method SHOULD have a throws clause specifying all of the Java exception classes that correspond to the IDL exceptions that are listed in the SetRaises clause of the attribute, and no others.

5.5. Objects implementing interfaces

A Java object that implements an IDL interface MUST be of a Java class that implements the Java interface that corresponds to the IDL interface.

If the IDL interface has a stringifier, the String toString() method MUST be overridden to allow stringification of the object as required by the IDL interface. If the "stringifier" keyword was used on an attribute A, then, assuming O is the object on which the method was invoked, the behavior of the overridden toString method MUST be as follows:

  1. Let R be the result of invoking the getter method on O that corresponds to the IDL attribute A.
  2. Return R.

Otherwise, if the "stringifier" keyword was used on an operation O with an identifier, then, assuming O is the object on which the method was invoked, the behavior of the overridden toString method MUST be as follows:

  1. Let R be the result of invoking the method on O that corresponds to the IDL operation O, passing no arguments.
  2. Return R.

Otherwise, if the "stringifier" keyword was used on an operation without an identifier, then the behavior of the overridden toString() method is the stringification behavior of the IDL interface, as described in the prose for the IDL interface.

5.6. Exceptions

A conforming Java implementation MUST have a Java class corresponding to every IDL exception that is supported, whose name is the Java escaped identifier of the IDL exception and which resides in the Java package corresponding to the exception’s enclosing module.

The Java class MUST have only the public modifier, and be declared to extend java.lang.RuntimeException.

5.6.1. Constants

For each constant defined on the exception, there MUST be a corresponding constant declared on the Java class with the following characteristics:

  • The constant has no modifiers.
  • The type of the constant is the Java type that corresponds to the type of the IDL constant, according to the rules in section 5.2 above.
  • The name of the constant is the Java escaped identifier of the constant.
  • The value of the constant is the result of converting the constant’s IDL value to a Java value, according to the rules in section 5.2 above.

5.6.2. Exception members

For each exception member defined on the exception, there MUST be a corresponding instance variable declared on the Java class with the following characteristics:

  • The instance variable has only the modifier public.
  • The type of the instance variable is the Java type that corresponds to the type of the IDL exception member, according to the rules in section 5.2 above.
  • The name of the instance variable is the Java escaped identifier of the exception member.
  • The instance variable is not declared with an initializer.

6. Extensibility

This section is informative.

Extensions to language binding requirements can be specified using extended attributes that do not conflict with those defined in this document. Extensions for private, project-specific use should not be included in IDL fragments appearing in other specifications. It is recommended that extensions that are required for use in other specifications be coordinated with the group responsible for work on Web IDL, which at the time of writing is the W3C Web Applications Working Group, for possible inclusion in a future version of this document.

Extensions to any other aspect of the IDL language are strongly discouraged.

7. Referencing this specification

This section is informative.

It is expected that other specifications that define DOM interfaces using a conforming IDL fragment will reference this specification. It is suggested that those specifications include a sentence such as the following, to indicate that the IDL is to be interpreted as described in this specification:

The IDL fragment in Appendix A of this specification must be interpreted as required for conforming IDL fragments, as described in the “Web IDL” specification. [WEBIDL]

In addition, it is suggested that the conformance class for user agents in referencing specifications be linked to the conforming implementation class from this specification:

A conforming FooML user agent must also be a conforming implementation of the IDL fragment in Appendix A of this specification, as described in the “Web IDL” specification. [WEBIDL]

8. Acknowledgements

This section is informative.

The editor would like to thank the following people for contributing to this specification: David Andersson, L. David Baron, Robin Berjon, Giovanni Campagna, Brendan Eich, Gorm Haug Eriksen, Marcin Hanclik, Jed Hartman, Ian Hickson, Björn Höhrmann, Dimitry Golubovsky, Kartikaya Gupta, James Graham, Magnus Kristiansen, Marcin Hanclik, Mark Miller, Lachlan Hunt, Oliver Hunt, Jim Jewett, Anne van Kesteren, Jim Ley, Travis Leithead, 岡坂 史紀 (Shiki Okasaka), Simon Pieters, Andrei Popescu, Jonas Sicking, Garrett Smith, Sam Sneddon, Maciej Stachowiak, Jeff Walden, Collin Xu, Boris Zbarsky.

Special thanks also go to Sam Weinig for maintaining this document while the editor was unavailable to do so.

A. IDL grammar

This section defines an LL(1) grammar whose start symbol, Definitions, matches an entire IDL fragment.

Each production in the grammar has on its right hand side either a non-zero sequence of terminal and non-terminal symbols, or an epsilon (ε) which indicates no symbols. Symbols that begin with an uppercase letter are non-terminal symbols. Symbols within quotes are terminal symbols that are matched with the exact text between the quotes. Symbols that begin with a lowercase letter are terminal symbols that are matched by the regular expressions (using Perl 5 regular expression syntax [PERLRE]) as follows:

integer = -?0([0-7]*|[Xx][0-9A-Fa-f]+)|[1-9][0-9]*
float = -?([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+
identifier = [A-Z_a-z][0-9A-Z_a-z]*
string = "[^"]*"
whitespace = [\t\n\r ]+|[\t\n\r ]*((//.*|/\*.*?\*/)[\t\n\r ]*)+
other = [^\t\n\r 0-9A-Z_a-z]

The tokenizer operates on a sequence of Unicode characters [UNICODE40]. When tokenizing, the longest possible match MUST be used. For example, if the input text is “a1”, it is tokenized as a single identifier, and not as a separate identifier and integer. If the longest possible match could match both an identifier and one of the quoted terminal symbols from the grammar, it MUST be tokenized as the quoted terminal symbol. Thus, the input text “in” is tokenized as the quoted terminal symbol "in" rather than an identifier called “in”.

The IDL syntax is case sensitive, both for the quoted terminal symbols used in the grammar and the values used for identifier terminals. Thus, for example, the input text “Getraises” is tokenized as an identifier rather than the quoted terminal symbol "getraises", an interface with identifier “A” is distinct from one named “a”, and an extended attribute [constructor] will not be recognized as the the [Constructor] extended attribute.

Implicitly, the whitespace terminal is allowed between every terminal in the input text being parsed. Such whitespace terminals, which actually encompass both whitespace and comments, are ignored while parsing.

The following LL(1) grammar, starting with Definitions, matches an IDL fragment:

Editorial note

Add a ConstType non-terminal. (Mail.)

[1]DefinitionsExtendedAttributeList Definition Definitions
 | ε
[2]DefinitionModule
 | Interface
 | Exception
 | Typedef
 | ImplementsStatement
[3]Module"module" identifier "{" Definitions "}" ";"
[4]Interface"interface" identifier InterfaceInheritance "{" InterfaceMembers "}" ";"
[5]InterfaceInheritance":" ScopedNameList
 | ε
[6]InterfaceMembersExtendedAttributeList InterfaceMember InterfaceMembers
 | ε
[7]InterfaceMemberConst
 | AttributeOrOperation
[8]Exception"exception" identifier "{" ExceptionMembers "}" ";"
[9]ExceptionMembersExtendedAttributeList ExceptionMember ExceptionMembers
 | ε
[10]Typedef"typedef" Type identifier ";"
[11]ImplementsStatementScopedName "implements" ScopedName ";"
[12]Const"const" Type identifier "=" ConstExpr ";"
[13]ConstExprBooleanLiteral
 | integer
 | float
[14]BooleanLiteral"true"
 | "false"
[15]AttributeOrOperation"stringifier" StringifierAttributeOrOperation
 | Attribute
 | Operation
[16]StringifierAttributeOrOperationAttribute
 | OperationRest
 | ";"
[17]AttributeReadOnly "attribute" Type identifier GetRaises SetRaises ";"
[18]ReadOnly"readonly"
 | ε
[19]GetRaises"getraises" ExceptionList
 | ε
[20]SetRaises"setraises" ExceptionList
 | ε
[21]OperationOmittableSpecials OperationRest
[22]OmittableSpecials"omittable" Specials
 | Specials
[23]SpecialsSpecial Specials
 | ε
[24]Special"getter"
 | "setter"
 | "creator"
 | "deleter"
 | "caller"
[25]OperationRestReturnType OptionalIdentifier "(" ArgumentList ")" Raises ";"
[26]OptionalIdentifieridentifier
 | ε
[27]Raises"raises" ExceptionList
 | ε
[28]ExceptionList"(" ScopedNameList ")"
[29]ArgumentListArgument Arguments
 | ε
[30]Arguments"," Argument Arguments
 | ε
[31]ArgumentExtendedAttributeList In Optional Type Ellipsis identifier
[32]In"in"
 | ε
[33]Optional"optional"
 | ε
[34]Ellipsis"..."
 | ε
[35]ExceptionMemberConst
 | ExceptionField
[36]ExceptionFieldType identifier ";"
[37]ExtendedAttributeList"[" ExtendedAttribute ExtendedAttributes "]"
 | ε
[38]ExtendedAttributes"," ExtendedAttribute ExtendedAttributes
 | ε
[39]ExtendedAttribute "(" ExtendedAttributeInner ")" ExtendedAttributeRest
 | "[" ExtendedAttributeInner "]" ExtendedAttributeRest
 | "{" ExtendedAttributeInner "}" ExtendedAttributeRest
 | Other ExtendedAttributeRest
[40]ExtendedAttributeRestExtendedAttribute
 | ε
[41]ExtendedAttributeInner "(" ExtendedAttributeInner ")" ExtendedAttributeInner
 | "[" ExtendedAttributeInner "]" ExtendedAttributeInner
 | "{" ExtendedAttributeInner "}" ExtendedAttributeInner
 | OtherOrComma ExtendedAttributeInner
 | ε
[42]Other integer
 | float
 | identifier
 | string
 | other
 | "..."
 | ":"
 | "::"
 | ";"
 | "<"
 | "="
 | ">"
 | "?"
 | "false"
 | "object"
 | "true"
 | "any"
 | "attribute"
 | "boolean"
 | "caller"
 | "const"
 | "creator"
 | "deleter"
 | "double"
 | "exception"
 | "float"
 | "getraises"
 | "getter"
 | "implements"
 | "in"
 | "interface"
 | "long"
 | "module"
 | "octet"
 | "omittable"
 | "optional"
 | "raises"
 | "sequence"
 | "setraises"
 | "setter"
 | "short"
 | "DOMString"
 | "stringifier"
 | "typedef"
 | "unsigned"
 | "void"
[43]OtherOrCommaOther
 | ","
[44]TypeNullableType
 | ScopedName
 | "any"
 | "object"
[45]NullableTypeUnsignedIntegerType Nullable
 | "boolean" Nullable
 | "octet" Nullable
 | "float" Nullable
 | "double" Nullable
 | "DOMString" Nullable
 | "sequence" "<" Type ">" Nullable
[46]UnsignedIntegerType"unsigned" IntegerType
 | IntegerType
[47]IntegerType"short"
 | "long" OptionalLong
[48]OptionalLong"long"
 | ε
[49]Nullable"?"
 | ε
[50]ReturnTypeType
 | "void"
[51]ScopedNameListScopedName ScopedNames
[52]ScopedNames"," ScopedName ScopedNames
 | ε
[53]ScopedNameAbsoluteScopedName
 | RelativeScopedName
[54]AbsoluteScopedName"::" identifier ScopedNameParts
[55]RelativeScopedNameidentifier ScopedNameParts
[56]ScopedNameParts"::" identifier ScopedNameParts
 | ε
[57]ExtendedAttributeNoArgidentifier
[58]ExtendedAttributeArgListidentifier "(" ArgumentList ")"
[59]ExtendedAttributeIdentidentifier "=" identifier
[60]ExtendedAttributeScopedNameidentifier "=" ScopedName
[61]ExtendedAttributeNamedArgListidentifier "=" identifier "(" ArgumentList ")"
Note

The choices listed for the Other non-terminal are all of the terminal symbols except for "(", ")", "[", "]", "{", "}" and ",".

While the ExtendedAttribute non-terminal matches any non-empty sequence of terminal symbols (as long as any parentheses, square brackets or braces are balanced, and the "," token appears only within those balanced brackets), only a subset of those possible sequences are used by the extended attributes defined in this specification — see section 3.8 for the syntaxes that are used by these extended attributes.

B. References

B.1. Normative references

[ECMA-262]
ECMAScript Language Specification, 5th Edition, P. Lakshman and A. Wirfs-Brock, Editors. Ecma International, December 2009. Available at http://www.ecma-international.org/publications/standards/Ecma-262.htm.
[IEEE-754]
IEEE Standard for Binary Floating-Point Arithmetic (ANSI/IEEE Std 754-1985). Institute of Electrical and Electronics Engineers, 1985.
[JLS3]
The Java Language Specification, Third Edition. J. Gosling, et al. Upper Saddle River, New Jersey, Addison-Wesley, 2005. Available at http://java.sun.com/docs/books/jls/.
[PERLRE]
Perl regular expressions (Perl 5.8.8). The Perl Foundation, February 2006. Available at http://www.perl.com/doc/manual/html/pod/perlre.html.
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels, S. Bradner. IETF, March 1997. Available at http://www.ietf.org/rfc/rfc2119.
[RFC2781]
UTF-16, an encoding of ISO 10646, P. Hoffmann and F. Yergeau. IETF, February 2000. Available at http://www.ietf.org/rfc/rfc2781.
[UNICODE40]
The Unicode Standard, Version 4.0 or later. The Unicode Consortium. Boston, Massachusetts, Addison-Wesley, 2003. ISBN 0-321-18578-1. Available at http://www.unicode.org/versions/Unicode4.0.0/.

B.2. Informative references

[DOM3CORE]
Document Object Model (DOM) Level 3 Core Specification. A. Le Hors, et al., Editors. World Wide Web Consortium, April 2004. Available at http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/.
[OMGIDL]
CORBA 3.1 – OMG IDL Syntax and Semantics chapter. Object Management Group, January 2008. Available at http://www.omg.org/cgi-bin/doc?formal/08-01-04.pdf.
[WIDLNOTE]
Web Interface Definition Language (WIDL). P. Merrick and C. Allen. World Wide Web Consortium, September 1997. Available at http://www.w3.org/TR/NOTE-widl-970922.

C. Changes

The following is a list of substantial changes to the document on each publication.

21 October 2010 – WD
  • Made constructors due to [Constructor] and [NamedConstructor] callable. Their behavior when called is the same as when used in a new expression.

  • Updated the ECMAScript language binding to target ECMAScript 5th edition, the biggest part of which is that now interface attributes are implemented as accessor properties.

  • Ensure that corresponding properties do not exist for constants, attributes and operations named “constructor” or “toString” if they would conflict with other requirements to have properties with those names.

  • Moved properties corresponding to attributes from host object instances to their interface prototype objects. Similarly, moved properties corresponding to exception members from host exception objects to their exception interface prototype objects.

  • Disallow both [PutForwards] and [Replaceable] appearing on the same attribute.

  • Required that callable objects corresponding to operations be Function objects.

  • Changed the constructor property on interface prototype objects to be writable.

  • Changed the prototype property on interface and exception objects be non-enumerable.

  • Allowed callers to be overloaded.

  • Defined the length property on Function objects that correspond to operations and constructors.

  • Changed sequences to be passed by value, and added an array type for ordered lists of values that are passed by reference.

  • Removed interface forward declarations and the requirement that interfaces be declared before use.

  • Made the "in" keyword in argument lists optional.

  • Changed the "Object", "TRUE" and "FALSE" keywords to be all lowercase.

  • Dropped [Optional] and [Variadic] in favor of optional and ... syntax.

  • Dropped [ImplementedOn] in favor of an implements statement.

  • Dropped [ExceptionConsts] in favor of allowing constants to be defined directly on exceptions. Defining constants on modules is now disallowed.

  • Changed [Constructor] and [PutForwards] to be an ECMAScript-specific extended attribute.

  • Turned [Callable], [IndexGetter], [IndexSetter], [IndexCreator], [IndexDeleter], [NameGetter], [NameSetter], [NameCreator], [NameDeleter] and [Stringifies] into real Web IDL syntax using caller, getter, setter, creator, deleter and stringifier. Dropped [NoIndexingOperations] in favor of an omittable keyword that can be used on the above six special operations.

  • Removed boxed valuetypes and replaced them with the concept of nullable types.

  • Added [NamespaceObject] to allow reflecting module hierarchies in ECMAScript.

  • Disallowed specifying [Callback] on interfaces that do not match the criteria for interfaces that can be implemented by native objects, and disallowed the use of the FunctionOnly and PropertyOnly identifiers unless the interface has only a single operation (or multiple operations, as long as they all have the same identifier).

  • Made corresponding indexed properties and ECMAScript properties for operations enumerable.

  • Outlawed having both [NoInterfaceObject] and [Constructor] on an interface.

  • Required that identical mixin prototype objects are in fact the same object.

  • Renamed [Null] and [Undefined] to [TreatNullAs] and [TreatUndefinedAs]. They are now honored when values are returned from native object implemented operations and attributes.

  • Added algorithms for getting and setting values of attributes on native object implementations of interfaces.

  • Added [OverrideBuiltins], which makes name getters prefer named properties instead of properties on the object itself.

  • Fixed bugs in the host object [[Put]] algorithm (now [[DefineOwnProperty]]) so that name and index creators are actually invoked, and restructured it as well as the host object [[Delete]] algorithm so that they are easier to read.

  • Provided language binding independent advice on handling user implemented interfaces that throw exceptions or return values of inappropriate types.

  • Renamed the awkwardly worded “object implementing an interface” type to “interface type”.

  • Added an [AllowAny] ECMAScript-specific extended attribute on operation arguments, which indicates that any type of ECMAScript value is allowed to be passed to that argument.

  • Changed the definition of the effective overload set to take into account the number of arguments passed, so that it can be used to resolve overloaded calls properly in the presence of variadic operations.

  • Removed DOMString from the list of primitive types, removed null from its set of values, and allowed it to be distinguished from primitive types in the overload resolution algorithm. The [Callback] extended attribute is now also taken into account when a native object is passed as an argument.

  • Defined exception handling for algorithms that call in to user ECMAScript code.

  • Added an algorithm for converting a sequence of 16 bit unsigned integer code units into a sequence of Unicode characters.

  • Added a double type for double precision floating point numbers.

  • Define [[Class]] for host objects that implement a single interface, regardless of whether it is annotated with [PrototypeRoot].

19 December 2008 – WD
  • Added a [NoIndexingOperations] extended attribute to indicate that operations annotated with named property or indexed property extended attributes won’t result in functions, if the language binding supports object indexing.

  • Changed the way extended attributes are parsed in the grammar and filled out the Extensibility section to mention how extended attributes not defined in this document can be used.

  • Fixed some bugs in the rules for converting float and unsigned long long to ECMAScript Number values, and vice versa.

  • Added [Prefix] to change the default mapping of modules to language binding namespacing constructs.

  • Allowed interfaces with constants to be implemented by ECMAScript native objects. This specifically allows implementation of a DOM Level 2 Traversal NodeFilter object in script.

  • Added a [Callable] extended attribute, which can be used to indicate the behavior of calling an object as a function.

  • Removed a bogus requirement that [PutForwards] identify an attribute whose type is the same as the attribute that has the [PutForwards], and disallowed cycles of forwarding assignments.

  • Added a [Replaceable] extended attribute that can be placed on an attribute to indicate that the corresponding ECMAScript property can be replaced.

  • Added a requirement that [Stringifies] not be specified on an interface that also declares an interface member named toString.

  • Changed the DOMString type to be a sequence of 16 bit code units, rather than a sequence of Unicode characters.

  • Reworded the ECMAScript type mapping section so that it can be more easily referenced from other sections of the document.

  • Renamed [NativeObject] to [Callback], and gave it an additional PropertyOnly argument.

  • Added an [Optional] extended attribute to make certain kinds of operation overloading able to be specified more succinctly.

  • Reworked operation overloading in IDL so that it is much more restrictive. Updated the overloaded operation and constructor resolution in ECMAScript accordingly.

  • Specified the behavior of index and name getters in ECMAScript as being in terms of additional properties that are placed on the host object. Added [IndexCreator], [IndexDeleter], [NameCreator] and [NameDeleter] to handle more aspects of these properties. The definition of [[Get]] for host objects is removed, but [[Put]] is expanded to handle index and name creators/setters, and [[Delete]] is now specified to handle index and name deleters.

  • Specified the value of [[Class]] for host objects.

  • Removed the suggestion to perform tricksy multiple inheritance simulation in ECMAScript with a mandated way to map multiple inheritance into a single inheritance prototype chain. Added [ImplementedOn] and [PrototypeRoot] to help with this.

  • Made an explicit mention of the Web Interface Definition Language (WIDL) W3C Member submission in the Status of this Document section.

29 August 2008 – WD
  • Added an [NamedConstructor] extended attribute to handle peculiarities like HTML 5’s Image constructor.

  • [Constructor] extended attributes may now take an argument list, and more than one can be used on an interface.

  • Added a [NativeObject] extended attribute that restricts which interfaces may be implemented by ECMAScript native objects, and updated the “Native objects implementing interfaces” section to be more restricted and precise.

  • Moved [NoInterfaceObject] into the ECMAScript-specific extended attributes section.

  • Fixed errors in a couple of algorithms that were introduced by steps being renumbered.

  • Properties corresponding to IDL constants are now ReadOnly.

  • Removed [NoNull], and added [Null] and [Undefined] in its place.

  • Made DOMString an intrinsic type, but still allow it to be defined as a boxed sequence of unsigned shorts for compatibility with already published IDL fragments.

  • ECMAScript host object constructors (specified with [Constructor]) now must return an object that implements the interface.

  • Tweaked the abstract and introduction so that it is clear that Web IDL can be used for specifications that define not only a DOM, but any interface.

  • Clarified the behavior of passing a non-null, non-Object value to a host object that expects a boxed valuetype.

  • Renamed document to Web IDL.

10 April 2008 – WD
  • Restricted boxed valuetypes to boxing only types that cannot already have null.

  • Reworked how operation overloading is specified (the [Overloads] extended attribute is no longer needed), and how ECMAScript disambiguates calls to overloaded operations.

  • Filled in the “Host exception objects” section.

  • Added an exception interface prototype object for constants to live in. Added constants to interface objects, interface prototype objects, exception interface objects and exception interface prototype objects.

  • Tweaked the behavior of sequences in ECMAScript.

  • Added an editorial note about the possibility of somehow specifying HTML 5’s Image constructor.

  • Added a [NoInterfaceObject] extended attribute, which prevents an ECMAScript interface object being created for the interface on which it appears.

  • Added a [Stringifies] extended attribute.

  • Fixed small bugs in [[HasProperty]], [[Get]] and [[Put]] algorithms for ECMAScript host objects.

  • Added an editorial note about the possibility of an extended attribute that specifies what properties get enumerated in a for..in loop in ECMAScript.

17 October 2007 – FPWD
  • Initial publication.