W3C

Web IDL

W3C Working Draft 19 December 2008

This Version:
http://www.w3.org/TR/2008/WD-WebIDL-20081219/
Latest Version:
http://www.w3.org/TR/WebIDL/
Previous Version:
http://www.w3.org/TR/2008/WD-WebIDL-20080829/
Editor:
Cameron McCormack, Invited Expert <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 19 December 2008 Working Draft of the Web IDL specification. Please send comments about this document to public-webapps@w3.org (archived) with “[WebIDL]” at the start of the subject line.

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

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

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 that is a syntactic subset of OMG IDL version 3.0 (with some small deviations) for use by specifications that define interfaces. A number of extensions are given to the IDL to support common functionality that previously must have been written in prose. In addition, precise language bindings for ECMAScript 3rd Edition and Java 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”, “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.

3. Interface definition language

This section describes a language with which interfaces can be defined in a language independent manner. This language is based on the Object Management Group’s Interface Definition Language [OMGIDL], and its syntax closely matches that of OMG IDL.

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.

A definition has been declared previously, relative to a given scoped name that resolved to the definition, if:

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

3.1. Names

The first identifier terminal in a derivation of a Definition, InterfaceMember or ExceptionMember determines the identifier of that definition, interface member or exception member (respectively) as follows:

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

The identifier of a definition MUST be locally unique to the module in which the definition occurred.

Every definition also has a qualified name, which MUST be globally unique to the IDL fragment in which it is defined. The qualified name of a definition is defined as follows:

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

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 has “::DOMString” as a suffix, then the scoped name does not resolve to a definition. (This is for compatibility with already-published OMG IDL fragments — see section 3.5 and section 3.6.)
  • Otherwise, 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: "string"
  // Qualified name:    "::framework::string"
  typedef DOMString string;

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

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

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

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

    // Operation identifier:          "createObject"
    // Operation argument identifier: "interface"
    Object createObject(in string _interface);
  };

  // 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 string _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.

[45]ScopedName"::" ScopedNameAfterColon
 | identifier ScopedNameParts
[46]ScopedNameAfterColonidentifier ScopedNameParts
 | "DOMString"
[47]ScopedNameParts"::" ScopedNamePartsAfterColon
 | ε
[48]ScopedNamePartsAfterColonidentifier ScopedNameParts
 | "DOMString"

3.2. Modules

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 is 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). The ECMAScript language binding does not have a namespacing mechanism, and thus does not use a module’s prefixed name.

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

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]Module"module" identifier "{" Definitions "}" ";"

3.3. Interfaces

An interface is a definition that matches the Interface non-terminal whose InterfaceBody is not empty (that is, it is not the case that InterfaceBody ⇒ ε). An interface is a specification of a set of interface members, which are the constants, attributes and operations given by the InterfaceMembers part of the InterfaceBody. Objects implementing the interface will have members that correspond to each of the interface’s members.

An interface inherits from another if there is a scoped name in the ScopedNameList that, with respect to the enclosing module of the interface, resolves to that inherited interface. Every scoped name in the ScopedNameList MUST resolve to an interface whose definition occurs before the definition of the inheriting interface. An object that implements an interface that inherits from another also implements that inherited interface. The object therefore will also have members that correspond to the interface members from the inherited interface.

Each interface member can be preceded by a list of extended attributes (matching ExtendedAttributeList), which can control how the interface member will be handled in language bindings.

The relevant language binding determines how interfaces correspond to constructs in the language. Many object-oriented languages support interfaces, in which case the mapping of IDL interfaces to language interfaces is simple.

An interface forward declaration is a definition that matches the Interface non-terminal whose InterfaceBody is empty (that is, InterfaceBody ⇒ ε). A forward declaration is used to introduce an interface name to allow for the definition of mutually recursive interfaces, since scoped names need to resolve to types that have been declared previously.

Example

The following IDL fragment demonstrates the use of an interface forward declaration to allow the definition of 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 Dog;

interface Human : Animal {
  attribute Dog pet;
};

interface Dog : Animal {
  attribute Human owner;
};

The following extended attributes are applicable to interfaces: [Callable], [Callback], [Constructor], [ImplementedOn], [IndexCreator], [IndexDeleter], [IndexGetter], [IndexSetter], [NamedConstructor], [NameCreator], [NameDeleter], [NameGetter], [NameSetter], [NoIndexingOperations], [NoInterfaceObject], [PrototypeRoot], [Stringifies].

[4]Interface"interface" identifier InterfaceBody ";"
[5]InterfaceInheritance":" ScopedNameList
 | ε
[6]InterfaceBodyInterfaceInheritance "{" InterfaceMembers "}"
 | ε
[7]InterfaceMembersExtendedAttributeList InterfaceMember InterfaceMembers
 | ε
[8]InterfaceMemberConst
 | Attribute
 | Operation
[43]ScopedNameListScopedName ScopedNames
[44]ScopedNames"," ScopedName ScopedNames
 | ε

3.3.1. Constants

A constant is a definition that matches the Const non-terminal, and is used to bind a constant value to a name. Constants can appear on interfaces and also at the module or outermost scope.

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

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 not U+002D HYPHEN-MINUS ("-"), then go to step 10.
  8. Set sign to −1.
  9. Set i to 1.
  10. If the ith zero-based character of S is not U+0030 DIGIT ZERO ("0"), then go to step 16.
  11. Set base to 8.
  12. Set i to i + 1.
  13. If the ith zero-based character of S is not U+0058 LATIN CAPITAL LETTER X ("X") or U+0078 LATIN SMALL LETTER X ("x"), then go to step 16.
  14. Set base to 16.
  15. Set i to i + 1.
  16. Let digit be the value obtained by looking up the ith zero-based character of S in the table below:
    CharacterValue of digit
    U+0030 DIGIT ZERO ("0")0
    U+0031 DIGIT ONE ("1")1
    U+0032 DIGIT TWO ("2")2
    U+0033 DIGIT THREE ("3")3
    U+0034 DIGIT FOUR ("4")4
    U+0035 DIGIT FIVE ("5")5
    U+0036 DIGIT SIX ("6")6
    U+0037 DIGIT SEVEN ("7")7
    U+0038 DIGIT EIGHT ("8")8
    U+0039 DIGIT NINE ("9")9
    U+0041 LATIN CAPITAL LETTER A ("A")10
    U+0042 LATIN CAPITAL LETTER B ("B")11
    U+0043 LATIN CAPITAL LETTER C ("C")12
    U+0044 LATIN CAPITAL LETTER D ("D")13
    U+0045 LATIN CAPITAL LETTER E ("E")14
    U+0046 LATIN CAPITAL LETTER F ("F")15
    U+0061 LATIN SMALL LETTER A ("a")10
    U+0062 LATIN SMALL LETTER B ("b")11
    U+0063 LATIN SMALL LETTER C ("c")12
    U+0064 LATIN SMALL LETTER D ("d")13
    U+0065 LATIN SMALL LETTER E ("e")14
    U+0066 LATIN SMALL LETTER F ("f")15
  17. Set mag to mag * base + digit.
  18. Set i to i + 1.
  19. If i < n, go to step 16.
  20. 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 type of a float terminal is float, and its value is the IEEE 754 single-precision floating pointer number 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 not U+002D HYPHEN-MINUS ("-"), then go to step 14.
  11. Set sign to −1.
  12. Set i to 1.
  13. If the ith zero-based character of S is U+0045 LATIN CAPITAL LETTER E ("E") or U+0045 LATIN SMALL LETTER E ("e"), then go to step 23.
  14. If the ith zero-based character of S is not U+002E FULL STOP ("."), then go to step 17.
  15. Set afterDot to true.
  16. Go to step 20.
  17. Let digit be the Unicode codepoint of the ith zero-based character of S minus 48.
  18. Set mant to mant * 10 + digit.
  19. If afterDot is true, set exp1 to exp1 − 1.
  20. Set i to i + 1.
  21. If i < n, go to step 13.
  22. Go to step 32.
  23. Set i to i + 1.
  24. If the ith zero-based character of S is not U+002D HYPHEN-MINUS ("-"), then go to step 27.
  25. Set expSign to −1.
  26. Set i to i + 1.
  27. If the ith zero-based character of S is U+002B PLUS SIGN ("+"), then set i to i + 1.
  28. Let digit be the Unicode codepoint of the ith zero-based character of S minus 48.
  29. Set exp2 to exp2 * 10 + digit.
  30. Set i to i + 1.
  31. If i < n, go to step 28.
  32. The value of the float terminal is the IEEE 754 single-precision floating point number closest to sign * mant * 10expSign * exp2 + exp1. [IEEE-754]
    Editorial note

    This should probably do some extra trickery like the definition for the “number value” in ECMA-262. Waiting on a reply to this mail.

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

Example

The following IDL fragment demonstrates how constants of the above types can be defined.

IDL
const boolean DEBUG = FALSE;
const octet LF = 10;
const short DELTA = -1;
const unsigned long BIT_MASK = 0x0000fc00;
const float AVOGADRO = 6.022e23;

No extended attributes are applicable to constants.

[15]Const"const" DeclarationType identifier "=" ConstExpr ";"
[16]ConstExprBooleanLiteral
 | integer
 | float
[17]BooleanLiteral"TRUE"
 | "FALSE"

3.3.2. Attributes

An attribute is an interface member that matches the Attribute non-terminal, and is used to declare that objects implementing the interface will have an attribute with the given identifier 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 DeclarationType non-terminal. If the DeclarationType is a scoped name, then it MUST resolve, with respect to the enclosing module of the interface on which the attribute is defined, to an interface, typedef or boxed valuetype that has been declared previously.

The attribute is read only if the "readonly" terminal is used in the definition. An object that implements the interface on which a read only attribute is defined will not allow assignment to that attribute. It is language binding specific whether assignment is simply disallowed by the language, ignored or an exception is thrown.

The GetRaises and SetRaises clauses are used to declare the possible exceptions that can be thrown when retrieving the value of and assigning a value to the attribute, respectively. Each scoped name in the GetRaises and SetRaises clauses MUST resolve, with respect to the enclosing module of the interface on which the attribute is defined, to an exception that has been declared previously.

The following extended attributes are applicable to attributes: [Null], [PutForwards], [Undefined].

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);
};
[18]AttributeReadOnly "attribute" DeclarationType identifier GetRaises SetRaises ";"
[19]ReadOnly"readonly"
 | ε
[20]GetRaises"getraises" ExceptionList
 | ε
[21]SetRaises"setraises" ExceptionList
 | ε
[24]ExceptionList"(" ScopedNameList ")"

3.3.3. Operations

An operation is an interface member that matches the Operation non-terminal, and is used to declare that objects implementing the interface will have a method with the given identifier.

The identifier of an operation MUST NOT be the same as the identifier of a constant or attribute defined on the same interface.

The return type of the operation is given by the ReturnType non-terminal. A return type of "void" indicates that the operation returns no value. If the DeclarationType is a scoped name, then it MUST resolve, with respect to the enclosing module of the interface on which the operation is defined, to an interface, typedef or boxed valuetype that has been declared previously.

The ArgumentList non-terminal gives the list of arguments for the operation. The identifier of an argument is given by the identifier terminal in the Argument, and the type of the argument is given by the DeclarationType. If the DeclarationType is a scoped name, then it MUST resolve, with respect to the enclosing module of the interface on which the operation is defined, to an interface, typedef or boxed valuetype that has been declared previously.

Each argument can be preceded by a list of extended attributes (matching ExtendedAttributeList), which can control how a value passed as the argument will be handled in language bindings.

The Raises clause is used to declare the possible exceptions that can be thrown when invoking the operation. Each scoped name in the Raises clause MUST resolve, with respect to the enclosing module of the interface on which the operation is defined, to an exception that has been declared previously.

If an 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. There are some restrictions on the arguments that overloaded operations 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, 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 either “for operations” or “for constructors”, to distinguish between these two uses.

The elements of an effective overload set are pairs of the form <ftypes>. If the effective overload set is for operations, 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. Each pair represents an allowable invocation of the operation or constructor with an argument value list of the given types. Due to the use of optional arguments and variadic operations and constructors (see the definitions of [Optional] and [Variadic]), there may be multiple entries in an effective overload set identifying the same operation or constructor.

The effective overload set for identifier A, 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 operations
    The elements of F are the 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.
  3. If the interface I is annotated with the [NoIndexingOperations] extended attribute, then remove from F any function annotated with an [IndexCreator], [IndexDeleter], [IndexGetter], [IndexSetter], [NameCreator], [NameDeleter], [NameGetter] or [NameSetter] extended attribute, if the target language binding supports indexing objects in the manner represented by that extended attribute.
  4. Let m be the maximum number of arguments the operations or constructor extended attributes in F are declared to take.
  5. 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. Add to S the pair <Xt0..n−1>.
    4. If n > 0 and the final argument of X is annotated with the [Variadic] extended attribute, then:
      1. Add to S the pair <Xt0..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. Add to S the pair <Xu0..i>.
    5. For every integer i, such that 0 < i < n:
      1. If argument i of X is annotated with the [Optional] extended attribute, then add to S the pair <Xt0..i−1>.
    6. If n > 0 and the first argument of X is annotated with the [Optional] extended attribute, then add to S the pair <X, ()> (where “()” represents the empty list).
  6. 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 length lists at index i are distinguishable.

Two types, t and u, are distinguishable if both are objects implementing an interface (where two different interfaces are identified) or if one is an object implementing an interface and the other is a primitive type.

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(in DOMString a, in DOMString b, [Variadic] in float c);
  /* f3 */ void f([Optional] in long a, in DOMString b,
                  [Optional] in DOMString c, [Variadic] in float d);
};

the effective overload set for identifier f (for the ECMAScript language binding) is:

{ <f1, (DOMString)>,
<f2, (DOMString, DOMString)>,
<f2, (DOMString, DOMString, float)>,
<f2, (DOMString, DOMString, float, float)>,
<f3, ()>,
<f3, (long, DOMString)>,
<f3, (long, DOMString, DOMString)>,
<f3, (long, DOMString, DOMString, float)> }

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

The following extended attributes are applicable to operations: [IndexCreator], [IndexDeleter], [IndexGetter], [IndexSetter], [NameCreator], [NameDeleter], [NameGetter], [NameSetter].

The following extended attributes are applicable to operation arguments: [Null], [Optional], [Undefined], [Variadic].

Example

The following IDL fragment demonstrates how 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);
};
[22]OperationReturnType identifier "(" ArgumentList ")" Raises ";"
[23]Raises"raises" ExceptionList
 | ε
[25]ArgumentListArgument Arguments
 | ε
[26]Arguments"," Argument Arguments
 | ε
[27]ArgumentExtendedAttributeList "in" DeclarationType identifier
[42]ReturnTypeDeclarationType
 | "void"

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 exception members (matching ExceptionMember) declared on them, rather than the three types of interface members. An exception member’s type is given by the DeclarationType non-terminal of the ExceptionMember. If the DeclarationType is a scoped name, then it MUST resolve, with respect to the enclosing module of the exception on which the exception member is declared, to an interface, typedef or boxed valuetype that has been declared previously.

The identifier of an exception member MUST be unique within the exception on which it is defined.

Exception members are similar to attributes in that they will correspond to attributes of the same name and type on exception objects that are thrown by implementations.

The following extended attributes are applicable to exceptions: [NoInterfaceObject].

No extended attributes are applicable to exception members.

Example

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

[9]Exception"exception" identifier "{" ExceptionMembers "}" ";"
[10]ExceptionMembersExtendedAttributeList ExceptionMember ExceptionMembers
 | ε
[28]ExceptionMemberDeclarationType identifier ";"

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.

Using a typedef is the only way to utilize the sequence<T> type, since interface members, exception members and operation return types and argument types must be specified with a DeclarationType, which does not allow a sequence<T>.

For backwards compatibility with already published IDL fragments, a typedef definition whose derivation has "DOMString" as its third-last or second-last terminal symbol is ignored and does not declare a new name for a type. This allows definitions such as the following to be ignored:

IDL
typedef dom::DOMString DOMString;
Example

The following IDL fragment demonstrates the use of typedefs for two purposes: to allow the use of a short identifier instead of a long scoped name, and to give a name to a sequence type so that it can be used as an operation argument 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);
  };
};
[11]Typedef"typedef" Type TypedefRest
[12]TypedefRestidentifier ";"
 | "DOMString" ";"

3.6. Valuetypes

Valuetypes in OMG IDL are used to define types similar to structs in C. That is, they define composite types that can have zero or more member variables that are passed by value. OMG IDL valuetypes have the additional feature of allowing null to be passed in place of an object with those member variables. An OMG IDL boxed valuetype is a special case, where the valuetype has a single member.

The IDL defined in this specification supports only boxed valuetypes, which are definitions that match the Valuetype non-terminal. The identifier of the valuetype is given by the identifier terminal, and the type being boxed is given by the BoxedType non-terminal. If the BoxedType is a ScopedName, then it MUST refer to a type that does not allow null as a value (i.e., boolean, octet, short, unsigned short, unsigned long, long long, unsigned long long, float or sequence<T>.

Boxed valuetypes are essentially used just for allowing a null value to be used where normally a non-null value could only be used.

For backwards compatibility with already published IDL fragments, a valuetype definition whose derivation has "DOMString" as its second terminal symbol is ignored and does not define a new boxed valuetype with the identifier "DOMString". This allows the following definition to be included in an IDL fragment and ignored:

IDL
valuetype DOMString sequence<unsigned short>;
Example

The following IDL fragment demonstrates the use of boxed valuetypes:

IDL
valuetype OptionalFloat float;

interface Person {

  // This attribute can be a float or null.  In this case, null might be used
  // to represent the case where the height of the person is unknown.
  readonly attribute OptionalFloat height;
};
[13]Valuetype"valuetype" ValuetypeRest
[14]ValuetypeRestidentifier BoxedType ";"
 | "DOMString" "sequence" "<" "unsigned" "short" ">" ";"

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

[36]DeclarationTypeUnsignedIntegerType
 | ScopedName
 | "any"
 | "boolean"
 | "octet"
 | "float"
 | "DOMString"
 | "Object"
[37]BoxedTypeUnsignedIntegerType
 | ScopedName
 | "boolean"
 | "octet"
 | "float"
 | "sequence" "<" Type ">"
[38]TypeDeclarationType
 | "sequence" "<" Type ">"
[39]UnsignedIntegerType"unsigned" IntegerType
 | IntegerType
[40]IntegerType"short"
 | "long" OptionalLong
[41]OptionalLong"long"
 | ε

3.7.1. any

The any type is the union of all other possible types.

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.

3.7.3. octet

The octet type is an unsigned integer type that has values in the range [0, 255].

octet constant values in IDL are represented with integer terminals.

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.

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.

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.

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.

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.

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.

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.

3.7.11. 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]) plus the special value null, which indicates no string. 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 it to be an intrinsic type so as to avoid special casing that sequence type in various situations where a string is required.

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

3.7.12. sequence<T>

Editorial note

This section to be rewritten.

The sequence<T> type is a parameterized type whose values are (possibly zero-length) sequences of values of type T. Sequences can have an arbitrary length that is immutable. However, sequence element values are mutable.

Editorial note

Should sequences really be immutable? Is there any advantage to disallowing resizing sequences here, rather than selectively by the interface designer? The sequence section in the ECMAScript bindings below assume it is mutable.

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

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.

3.7.14. Object implementing an interface

A scoped name that resolves to an interface is used to refer to a type that corresponds to the set of all possible references to objects that implement that interface, plus the special value null, which indicates no object reference.

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

3.7.15. Boxed valuetype

A scoped name that resolves to a boxed valuetype is used to refer to a type that corresponds to the set of values for the type being boxed, plus the special value null, which indicates no value.

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

3.8. Extended attributes

An extended attribute is an annotation that can appear on definitions, interface members, exception members and operation arguments, and are used to control how language bindings will handle those constructs. Extended attributes are specified with an ExtendedAttributeList, which is a square bracket enclosed, comma separated list of ExtendedAttributes.

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 [Optional]
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 [Stringifies=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.

[29]ExtendedAttributeList"[" ExtendedAttribute ExtendedAttributes "]"
 | ε
[30]ExtendedAttributes"," ExtendedAttribute ExtendedAttributes
 | ε
[31]ExtendedAttribute "(" ExtendedAttributeInner ")" ExtendedAttributeRest
 | "[" ExtendedAttributeInner "]" ExtendedAttributeRest
 | "{" ExtendedAttributeInner "}" ExtendedAttributeRest
 | Other ExtendedAttributeRest
[32]ExtendedAttributeRestExtendedAttribute
 | ε
[33]ExtendedAttributeInner "(" ExtendedAttributeInner ")" ExtendedAttributeInner
 | "[" ExtendedAttributeInner "]" ExtendedAttributeInner
 | "{" ExtendedAttributeInner "}" ExtendedAttributeInner
 | OtherOrComma ExtendedAttributeInner
 | ε
[34]Other integer
 | float
 | identifier
 | string
 | other
 | ":"
 | "::"
 | ";"
 | "<"
 | "="
 | ">"
 | "DOMString"
 | "FALSE"
 | "Object"
 | "TRUE"
 | "any"
 | "attribute"
 | "boolean"
 | "const"
 | "exception"
 | "float"
 | "getraises"
 | "in"
 | "interface"
 | "long"
 | "module"
 | "octet"
 | "raises"
 | "sequence"
 | "setraises"
 | "short"
 | "typedef"
 | "unsigned"
 | "valuetype"
[35]OtherOrCommaOther
 | ","
[49]ExtendedAttributeNoArgidentifier
[50]ExtendedAttributeArgListidentifier "(" ArgumentList ")"
[51]ExtendedAttributeIdentidentifier "=" identifier
[52]ExtendedAttributeScopedNameidentifier "=" ScopedName
[53]ExtendedAttributeNamedArgListidentifier "=" identifier "(" ArgumentList ")"

3.8.1. [Callable]

If the [Callable] extended attribute appears on an interface, it indicates that objects that implement this interface can be called as if they were a function, for languages that support such object calling.

The [Callable] extended attribute MUST take an identifier. The identifier MUST be the identifier of a non-overloaded operation defined on the interface. Calling the object as a function will result in the same behavior as invoking the operation.

If an object implements more than one [Callable]-annotated interface, then it is undefined which (if any) operation determines the behavior when calling the object as a function.

Example

The following IDL fragment defines an interface with a [Callable] extended attribute.

IDL
[Callable=compute]
interface NumberQuadrupler {
  // This operation simply returns four times the given number x.
  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.8.2. [Constructor]

If the [Constructor] extended attribute appears on an interface, it indicates that there will be a way to construct objects that implement this interface. How such objects can be constructed is specific to the language binding. 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.

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.

3.8.3. [ExceptionConsts]

If the [ExceptionConsts] extended attribute appears on a module, it indicates that any constants declared on that module are intended to exist on the language construct that corresponds to the exception given by the extended attribute’s argument (for languages that support constants on exceptions). Exactly how these constants are exposed is language binding specific.

The [ExceptionConsts] extended attribute MUST take an identifier that is the identifier of an exception defined in that module, on which the constants declared at the module scope should live.

Example

The following IDL fragment declares an exception and a number of constants at the module scope:

IDL
[ExceptionConsts=FileIOException]
module fileio {

  exception FileIOException {
    unsigned short code;
  };

  const unsigned short FILE_NOT_FOUND = 1;
  const unsigned short READ_ERROR = 2;
  const unsigned short WRITE_ERROR = 3;
};

In the ECMAScript binding, this will result in properties on the exception interface object for each of the constants:

ECMAScript
typeof FileIOException;          // evaluates to "object"
FileIOException.FILE_NOT_FOUND;  // evaluates to 1

3.8.4. [ImplementedOn]

If the [ImplementedOn] extended attribute appears on an interface, it indicates that the interface is implemented by all objects that implement certain other interfaces.

The [ImplementedOn] extended attribute MUST take a scoped name, where the scoped name MUST resolve, with respect to the enclosing module of the interface that it appears on, to an interface that has been declared previously. Any object that implements the interfaces identified by the scoped name argument will implement the interface the [ImplementedOn] extended attribute appears on.

Example

The following IDL fragment defines two interfaces, and uses the [ImplementedOn] extended attribute to require that any object implementing the first must also implement the second.

IDL
interface Node {
  // …
};

[ImplementedOn=Node]
interface EventTarget {
  void addEventListener(in DOMString type, in EventListener l, in bool capture);
  // …
};

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.

3.8.5. [IndexCreator], [IndexDeleter], [IndexGetter] and [IndexSetter]

The [IndexCreator], [IndexDeleter], [IndexGetter] and [IndexSetter] extended attributes are used to specify that objects implementing an interface can be indexed with an unsigned long to (depending on which extended attribute is used) get, set, create or delete an indexed property, if the particular language binding supports indexing objects in this manner. Such an interface is said to support indexed properties.

The four indexed property extended attributes MUST all take no argument.

If an object implements more than one interface with a given indexed property extended attribute, then it is undefined which (if any) indexing behavior is invoked.

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 indices of the supported indexed properties.

If any of [IndexCreator], [IndexDeleter] or [IndexSetter] are used, then [IndexGetter] MUST appear on the interface or one of its operations.

The [IndexGetter] extended attribute indicates that an object implementing the interface can be indexed to retrieve the value of an existing indexed property. If it appears on the interface itself, then the interface definition MUST be accompanied by a description of what value will be returned when the object is indexed for property retrieval. If instead the extended attribute appears on an operation, then the value returned will be the value that is returned by invoking the operation, passing the index as its only argument. Such an operation MUST be declared to take a single argument of type unsigned long.

The [IndexSetter] extended attribute indicates that an object implementing the interface can be indexed to set the value of an existing indexed property. If it appears on the interface itself, then the interface definition MUST be accompanied by a description of what behavior occurs when the object is indexed for property modification. If instead the extended attribute appears on an operation, then the behavior that occurs is the invocation of that operation, passing the index as the first argument and the new indexed property value as the second. Such an operation MUST be declared to take a two arguments, the first of type unsigned long.

The [IndexCreator] extended attribute indicates that an object implementing the interface can be indexed to create a new indexed property with a particular value. If it appears on the interface itself, then the interface definition MUST be accompanied by a description of what behavior occurs when the object is indexed for property creation. If instead the extended attribute appears on an operation, then the behavior that occurs is the invocation of that operation, passing the new property’s index as the first argument and the value as the second. Such an operation MUST be declared to take a two arguments, the first of type unsigned long.

The [IndexDeleter] extended attribute indicates that an object implementing the interface can be indexed to delete an existing indexed property. If it appears on the interface itself, then the interface definition MUST be accompanied by a description of what behavior occurs when the object is indexed for property deletion. If instead the extended attribute appears on an operation, then the behavior that occurs is the invocation of that operation, passing the property’s index as the only argument. Such an operation MUST be declared to take a single argument of type unsigned long.

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;

  [IndexGetter] any getByIndex(in unsigned long index);
  [IndexSetter] void setByIndex(in unsigned long index, in any value);
  [IndexDeleter] void removeByIndex(in unsigned long index);

  [NameGetter] any get(in DOMString name);
  [NameSetter, NameCreator] void set(in DOMString name, in any value);
  [NameDeleter] void remove(in DOMString name);
};

Since none of the name or index property set extended attributes are placed directly on the interface, 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 ≤ key < 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 4.4.2, 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 [IndexCreator]
                  // 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
                  // "banana", 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.8.6. [NameCreator], [NameDeleter], [NameGetter] and [NameSetter]

The [NameCreator], [NameDeleter], [NameGetter] and [NameSetter] extended attributes are used to specify that objects implementing an interface can be indexed with a DOMString to (depending on which extended attribute is used) get, set, create or delete a named property, if the particular language binding supports indexing objects in this manner. Such an interface is said to support named properties.

The four named property extended attributes MUST all take no argument.

If an object implements more than one interface with a given named property extended attribute, then it is undefined which (if any) indexing behavior is invoked.

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 names of the supported named properties.

The [NameGetter] extended attribute indicates that an object implementing the interface can be indexed to retrieve the value of an existing named property. If it appears on the interface itself, then the interface definition MUST be accompanied by a description of what value will be returned when the object is indexed for property retrieval. If instead the extended attribute appears on an operation, then the value returned will be the value that is returned by invoking the operation, passing the name as its only argument. Such an operation MUST be declared to take a single argument of type DOMString.

The [NameSetter] extended attribute indicates that an object implementing the interface can be indexed to set the value of an existing named property. If it appears on the interface itself, then the interface definition MUST be accompanied by a description of what behavior occurs when the object is indexed for property modification. If instead the extended attribute appears on an operation, then the behavior that occurs is the invocation of that operation, passing the name as the first argument and the new named property value as the second. Such an operation MUST be declared to take a two arguments, the first of type DOMString.

The [NameCreator] extended attribute indicates that an object implementing the interface can be indexed to create a new named property with a particular value. If it appears on the interface itself, then the interface definition MUST be accompanied by a description of what behavior occurs when the object is indexed for property creation. If instead the extended attribute appears on an operation, then the behavior that occurs is the invocation of that operation, passing the new property’s name as the first argument and the value as the second. Such an operation MUST be declared to take a two arguments, the first of type DOMString.

The [NameDeleter] extended attribute indicates that an object implementing the interface can be indexed to delete an existing named property. If it appears on the interface itself, then the interface definition MUST be accompanied by a description of what behavior occurs when the object is indexed for property deletion. If instead the extended attribute appears on an operation, then the behavior that occurs is the invocation of that operation, passing the property’s name as the only argument. Such an operation MUST be declared to take a single argument of type DOMString.

Example

See section 3.8.5 for an example of the use of the named property extended attributes.

3.8.7. [NoIndexingOperations]

If the [NoIndexingOperations] extended attribute appears on an interface, it indicates that any operation on the interface that is annotated with an indexing extended attribute (that is, [IndexCreator], [IndexDeleter], [IndexGetter], [IndexSetter], [NameCreator], [NameDeleter], [NameGetter] or [NameSetter]) will not correspond to a function on objects that implement the interface, if the given kind of indexing is supported in the language binding.

The [NoIndexingOperations] extended attribute MUST take no argument.

Example

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

IDL
[NoIndexingOperations]
interface Dictionary {
  unsigned long getNumberOfEntries();
  [NameGetter] DOMString lookUpEntry(in DOMString key);
  [NameSetter] void setEntry(in DOMString key, in DOMString value);
};

Since the ECMAScript language binding does support indexing of objects with strings for getting and setting, the interface prototype object for the Dictionary interface would not have properties named lookUpEntry or setEntry. It would, however, still have a property named getNumberOfEntries.

ECMAScript
var d = getDictionary();  // Obtain an instance of Dictionary.

d.getNumberOfEntries();   // Evaluates to an unsigned long value.

d.abc;                    // Evaluates to a DOMString, assuming d has a named
                          // property called "abc".

d.lookUpEntry("abc");     // Throws a TypeError.

The equivalent Java interface would have three methods corresponding to the three operations, since Java does not support object indexing.

Java
interface Dictionary {
  long getNumberOfEntries();
  String lookUpString(String key);
  void setEntry(String key, String value);
}

3.8.8. [Null]

If the [Null] 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 (which is to be stringified to "null").

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

However, if the [Null] extended attribute does not appear on an attribute or operation argument whose type is DOMString, then a null value assigned to the attribute or passed as the operation argument will first be converted to the string "null".

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

Example

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

IDL
interface Dog {
  attribute DOMString name;
  [Null=Null] attribute DOMString owner;

  boolean isMemberOfBreed([Null=Empty] 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.owner = null;           // This assigns the null value to the .owner property.

d.isMemberOfBreed(null);  // This passes the string "" to the isMemberOfBreed
                          // function.

3.8.9. [Optional]

If the [Optional] extended attribute appears on an operation argument, it indicates that the operation can be invoked by passing values only for the those arguments appearing before the [Optional]-annotated argument in the operation’s argument list, for language bindings that support such invocation. If the extended attribute appears on an operation’s first argument, then the operation can be invoked with zero arguments.

Specifying [Optional] on an operation argument is equivalent to using operation overloading to declare one operation that takes all of the arguments and another that takes only those preceding the [Optional]-annotated argument.

The [Optional] extended attribute MUST take no argument.

Example

The following IDL fragment defines an interface with a single operation that can be invoked with three different argument list lengths:

IDL
interface ColorCreator {
  Object createColor(in float v1, [Optional] in float v2, in float v3,
                     [Optional] in float alpha);
};

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

IDL
interface ColorCreator {

  Object createColor(in float v1);
  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);
};

3.8.10. [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].

3.8.11. [PutForwards]

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

It is language binding specific what behavior occurs when assigning to such an attribute whose value is null.

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.

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.

3.8.12. [Stringifies]

If the [Stringifies] extended attribute appears on an interface, it indicates that, for language bindings that support object stringification, an object that implements the interface will stringify in a non-default manner.

The [Stringifies] extended attribute MUST either take no argument or take an identifier. If the identifier is present, it MUST be the identifier of an attribute of type DOMString on the interface, whose value will be used as the result of the stringification. If the identifier is not supplied, the stringification behavior MUST be described in prose.

The [Stringifies] extended attribute MUST NOT appear on an interface that has an interface member whose identifier is toString.

Example

The following IDL fragment defines an interface that will stringify to the value of its name attribute:

IDL
[Constructor, Stringifies=name]
interface Student {
  attribute unsigned long id;
  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, Stringifies]
interface Student {
  attribute unsigned long id;
  [Null=Null] attribute DOMString familyName;
  attribute DOMString givenName;
};

Thus, prose is required to explain the stringification behavior, such as the following paragraph:

Objects that implement the Student interface must stringify as follows. If the value of the familyName attribute is null, the stringification of the object is the value of the givenName attribute. Otherwise, if the value of the familyName attribute is not null, the stringification of the object is the concatenation of the the value of the givenName attribute, the string " " and the value of the familyName attribute.

An ECMAScript implementation of the IDL would behave as follows:

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

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

3.8.13. [Variadic]

If the [Variadic] extended attribute appears on the final argument of an operation, it indicates that the operation is variadic, and can be passed zero or more arguments after the regular arguments. Each of these extra arguments will have to be of the type specified by that final argument. How such arguments are passed is specific to the language binding.

The [Variadic] extended attribute MUST take no argument.

Example

The following IDL fragment defines an interface that has a variadic operation:

IDL
interface IntegerSet {
  readonly unsigned long cardinality;

  void union([Variadic] in long ints);
  void intersection([Variadic] 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 may specify that an explicit array or list of integers be passed to such an operation.

4. ECMAScript binding

This section describes how definitions written with the IDL defined in section 3 correspond to particular constructs in ECMAScript 3rd edition.

Unless otherwise specified, every object described in this section has internal properties [[Get]], [[Put]], [[CanPut]], [[HasProperty]], [[Delete]] and [[DefaultValue]] with the same behavior as specified for native objects, as described in section 8.6.2 of the ECMAScript Language Specification, 3rd Edition [ECMA-262].

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

Algorithms in this section use the conventions described in section 5.2 of ECMAScript Language Specification, 3rd Edition, and the ToBoolean, ToNumber, ToUint16, ToInt32, ToUint32, ToString and ToObject operators referenced in this section are defined in section 9 of that document [ECMA-262].

4.1. ECMAScript type mapping

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

Passing a value to a host object expecting type T is used in this sub-section to describe passing an ECMAScript value as an argument to a function whose corresponding operation in the IDL specifies that the argument is of type T, or assigning to a property whose corresponding attribute or exception member in the IDL is of type T. Conversely, returning a value of type T from a host object is used to describe obtaining the ECMAScript return value from a function whose corresponding operation in the IDL specifies a return type T, or retrieving a property whose corresponding attribute or exception member in the IDL is of type T.

Each sub-section below describes how 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 float value, as described in section 4.1.11, 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.12, 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 is converted to an IDL boolean value by running the following algorithm (where V is the ECMAScript value):

  1. Compute ToBoolean(V).
  2. Return the IDL boolean value is the one that represents the same truth value as the ECMAScript Boolean value Result(1).

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 is converted to an IDL octet value by running the following algorithm (where V is the ECMAScript value):

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

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 is converted to an IDL short value by running the following algorithm (where V is the ECMAScript value):

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

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 is converted to an IDL unsigned short value by running the following algorithm (where V is the ECMAScript value):

  1. Compute ToUint16(V).
  2. Return the IDL unsigned short value that represents the same numeric value as Result(1).

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 is converted to an IDL long value by running the following algorithm (where V is the ECMAScript value):

  1. Compute ToInt32(V).
  2. Return the IDL long value that represents the same numeric value as Result(1).

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

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

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

  1. Compute ToUint32(V).
  2. Return the IDL unsigned long value that represents the same numeric value as Result(1).

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 is converted to an IDL long long value by running the following algorithm (where V is the ECMAScript value):

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

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 is converted to an IDL unsigned long long value by running the following algorithm (where V is the ECMAScript value):

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

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 is converted to an IDL float value by running the following algorithm (where V is the ECMAScript value):

  1. Compute ToNumber(V).
  2. If Result(1) 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 V be the number in S that is closest to Result(1), 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 V is 2128, return +∞.
  6. If V is −2128, return −∞.
  7. If V is +0 and Result(1) is negative, return −0.
  8. Return V.

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

IDL DOMString values are represented by ECMAScript String values and the null value.

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

  1. If V is null:
    1. If the conversion to an IDL value is being performed due to V being passed as an operation argument that is annotated with the [Null] extended attribute, or due to V being assigned to an attribute with [Null]:
      1. If the [Null] extended attribute took an identifier argument Empty, then return the DOMString value that represents the empty string (an empty sequence of 16 bit code units).
      2. Otherwise, the [Null] extended attribute took an identifier argument Null. Return the DOMString value null.
  2. If V is undefined:
    1. If the conversion to an IDL value is being performed due to V being passed as an operation argument that is annotated with the [Undefined] extended attribute, or due to V being assigned to an attribute with [Undefined]:
      1. If the [Undefined] extended attribute took an identifier argument Empty, then return the DOMString value that represents the empty string (an empty sequence of 16 bit code units).
      2. Otherwise, the [Undefined] extended attribute took an identifier argument Null. Return the DOMString value null.
  3. Compute ToString(V).
  4. Return the IDL DOMString value that represents the same sequence of characters as the one the ECMAScript String value Result(3) represents.

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

  • If the IDL DOMString value is null, then the ECMAScript value is the null value.
  • Otherwise, the ECMAScript value is the String value that represents the same sequence of characters that the IDL DOMString represents.

4.1.13. sequence<T>

Editorial note

To section is to be rewritten, once sequences are fixed up.

IDL sequence<T> values are represented by ECMAScript Object values with special properties.

Values passed to a host object expecting a sequence<T> MUST be objects with a length property whose value, after being converted to a Number by the ToUint32 operator, is a non-negative integer that specifies the number of elements in the sequence. This number MUST also be equal to the result of passing the original length property value to the ToNumber algorithm. Assigning to the length property a non-negative integer Number MUST change the length of the sequence to be the given number. If the sequence is lengthened, new elements MUST be given the value that the undefined value is converted to when handling it according to the rules in this section for the type T. If the sequence is shortened, the values beyond the new length of the sequence are lost. The object representing the sequence MUST return the element in the sequence at position n when its [[Get]] internal method is invoked with n as its argument.

Note that an ECMAScript Array is an object that matches this description. Implementations are free, however, to use a host object to implement the sequence in the interests of efficiency.

When the host object gets an element of the sequence using the [[Get]] method, the returned value MUST first be handled according to the rules in this section for the type T.

If a host object expecting a sequence<T> is passed a value which is not an object that conforms to the above rules (for example, it does not have a length property), then a TypeError exception MUST be thrown.

While sequences are passed by reference (being objects), it is of course up to the interface designer whether, for example, after assigning a sequence to a property on a host object that same seqence object is returned when getting the property. The behavior of storing sequences in the host object in this manner should be made clear in prose describing the interface.

Editorial note

Should there be a way to declare a sequence whose length cannot be changed from script?

Example

The following IDL defines an interface that has a sequence<unsigned short> attribute.

IDL
typedef sequence<unsigned short> Integers;

[Constructor]
interface LotteryResults {
  attribute Integers numbers;
};

The following paragraph is used to clarify the behavior of assigning a value to the numbers property:

In the ECMAScript language binding, assigning an array-like object to the numbers property results in a copy of those values being stored in the LotteryResults object. The array-like object returned when the numbers property is retrieved, however, will not change over the lifetime of the LotteryResults object.

The following ECMAScript code illustrates how the sequence 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];      // An object that can serve as a
                                     // sequence<unsigned short>.

results.numbers = a;                 // Assign the sequence, resulting in the
                                     // values being copied into the host
                                     // object.

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 sequence stored in the host
                                     // object.
results.numbers[0];                  // Now evaluates to 5.

results.length = 7;                  // Increase the length of the sequence.
results.numbers[6];                  // Evaluates to 0, since that is how
                                     // 'undefined' is converted to an
                                     // 'unsigned short'.

4.1.14. Object

IDL Object values are represented by ECMAScript Object values.

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

  1. If V is null, then return the IDL Object value null.
  2. Compute ToObject(V).
  3. Return the IDL Object value that is a reference to the same object as Result(2).

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. Object implementing an interface

IDL object implementing an interface values are represented by ECMAScript Object values.

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

  1. If V is null, then return the IDL object implementing an interface value null.
  2. If V is a host object that implements I, then return the IDL object implementing an interface value that represents a reference to that host object.
  3. Compute ToObject(V).
  4. If Result(3) is a native object that is considered to implement I according to the rules in section 4.5, then return the IDL object implementing an interface value that represents a reference to that native object.
  5. Throw a TypeError.

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

4.1.16. Boxed valuetype

IDL boxed valuetype values are represented by values of either the ECMAScript type corresponding to the IDL type being boxed, or the ECMAScript null value.

An ECMAScript value is converted to an IDL boxed valuetype value as follows:

  • If the ECMAScript value is null, then the IDL boxed valuetype value is null.
  • Otherwise, the ECMAScript value is not null. The IDL boxed valuetype value is obtained by converting the ECMAScript value to the IDL type being boxed.

The result of converting an IDL boxed valuetype value to an ECMAScript value is:

4.2. ECMAScript-specific extended attributes

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

4.2.1. [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.5 below), and such an object can be passed to a host object expecting an object that implements the interface. 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.

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.2. [NamedConstructor]

If the [NamedConstructor] extended attribute appears on an interface, it indicates 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).

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.3. [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.

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.4. [PrototypeRoot]

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.3.3 and section 4.4 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();
  // …
};

[ImplementedOn=Node]
interface EventTarget {
  void addEventListener(…);
  // …
};

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 protoype 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.5. [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 removed and a new one created that is unrelated to the attribute, and which has the value being assigned.

The [Replaceable] extended attribute MUST take no argument.

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 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.6. [Undefined]

If the [Undefined] extended attribute appears on an attribute or operation argument whose type is DOMString, it indicates that an undefined value assigned to the corresponding property or passed as an argument to the corresponding function will first be converted to a non-null string. The argument to the extended attribute determines what string to use:

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

However, if the [Undefined] extended attribute does not appear on an attribute or operation argument whose type is DOMString, then an undefined value assigned to the corresponding property or passed as an argument to the corresponding function will first be converted to the string "undefined".

The [Undefined] extended attribute MUST take an identifier: either Empty or Null.

Example

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

IDL
interface Cat {
  attribute DOMString name;
  [Undefined=Null, Null=Null] attribute DOMString owner;

  boolean isMemberOfBreed([Undefined=Empty] in DOMString breedName);
};

An ECMAScript implementation implementing the Cat interface would convert an undefined value assigned to the name or owner property or passed as the argument to the isMemberOfBreed function:

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

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

c.owner = undefined;           // This assigns null to the .owner property.

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

4.3. Interfaces

For every interface that is not declared with the [NoInterfaceObject] extended attribute, a corresponding property MUST exist on the ECMAScript global object whose name is the identifier of the interface. The value of this property is an object called the interface object, which provides access to the constants and operations defined on the interface. The property has the attributes { DontDelete, DontEnum }. The characteristics of an interface object is described in section 4.3.1 below.

In addition, for every [NamedConstructor] extended attribute on an interface, a corresponding property MUST exist on the ECMAScript global object whose name is the identifier that occurs directly after the “=”. The value of this property is an object called an named constructor object, which allows construction of objects that implement the interface. The property has the attributes { DontDelete, DontEnum }. The characteristics of a named constructor object is described in section 4.3.2 below.

4.3.1. Interface object

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

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

The interface object MUST also have a property named prototype with attributes { DontDelete, ReadOnly } whose value is an object called the interface prototype object. This object provides access to the functions that correspond to the operations defined on the interface, and is described in more detail in section 4.3.3 below.

4.3.1.1. Interface object [[Construct]] method

If the interface is declared with a [Constructor] extended attribute, then the interface object MUST also have a [[Construct]] internal property, which allows construction of objects that implement the given interface. In order to define how overloaded constructor invocations are resolved within the [[Construct]] 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:

  1. Initialize R to a set with the same values as S.
  2. Remove from R all entries whose type list is longer than n.
  3. If R contains more than one entry:
    1. Let m be the maximum length of the type lists of the entries in R.
    2. Initialize i to 0.
    3. While i < m:
      1. Initialize b to true.
      2. For each pair of entries <entry1entry2> in R:
        1. Let t be the type list of entry1.
        2. Let u be the type list of entry2.
        3. If ti and ui are not distinguishable, set b to false.
      3. If b is true:
        1. If argi is an Undefined, Boolean, String or Number value, then remove from R all entries with type list t where ti is not a primitive type.
        2. If argi is null or an object (whether a host object or a native object), then remove from R all entries with type list t where ti is not an object implementing an interface.
      4. Set i to i + 1.
  4. Return R.

The internal [[Construct]] 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 (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. Perform 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 Result(8) to an ECMAScript object implementing interface I.

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

4.3.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. Call the [[Get]] method of A with property name "prototype".
  3. Let O be Result(2).
  4. If O is not an object, throw a TypeError exception.
  5. If V is a host object that implements the interface for which O is the interface prototype object, return true.
  6. Let V be the value of the [[Prototype]] property of V.
  7. If V is null, return false.
  8. If O and V refer to the same object or if they refer to objects joined to each other (see section 13.1.2 of the ECMAScript Language Specification, 3rd Edition [ECMA-262]), return true.
  9. Go to step 6.

4.3.2. Named constructors

A named constructor object that exists due to one or more [NamedConstructor] extended attributes with a given identifier MUST have a [[Construct]] 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 (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. Perform 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 Result(7) to an ECMAScript object implementing interface I.

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

4.3.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 operations defined on that interface. These properties are described in more detail in section 4.3.5 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.3.4 below.

The interface prototype object MUST also have a property named constructor with attributes { DontEnum, ReadOnly } 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 [ImplementedOn] extended attribute 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.3.3.1. Mixin prototype object

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.

4.3.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 { DontDelete, ReadOnly }.

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

4.3.5. Operations

For each unique identifier of an 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 (for the ECMAScript language binding) has no entries. The characteristics of such a corresponding property are as follows:

  • The name of the property is the identifier.
  • The property has attributes { DontEnum }.
  • The value of the property is an object whose internal [[Call]] method behaves as follows, assuming id is the identifier, arg0..n−1 is the list of argument values passed to [[Call]] and I is the interface:
    1. Initialize S to the effective overload set for operations with identifier id on interface I (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 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 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 Result(7) to an ECMAScript value of the type op is declared to return.

In addition, if the interface is declared with the [Stringifies] extended attribute, a property MUST exist on the interface prototype object whose name is toString and whose value is a callable object. If the [Stringifies] extended attribute on the interface took an identifier argument P, assuming O is the object on which the function was invoked, then the internal [[Call]] method of the object MUST behave as follows:

  1. Invoke the [[Get]] method of object O with P as the argument.
  2. Compute ToString(Result(1)).
  3. Return Result(2).

If the [Stringifies] extended attribute on the interface took no argument, then the behavior of the internal [[Call]] method of the object is the stringification behavior of the interface, as described in the prose for the interface.

4.4. Host objects implementing interfaces

If a host object implements an interface, then for each attribute defined on the interface, there MUST be a corresponding property on the host object:

  • The name of the property is the identifier of the attribute.
  • If the attribute is declared readonly, the property has attributes { DontDelete, ReadOnly }. Otherwise, the property has attributes { DontDelete }.
  • When getting the property, the value returned is the result of converting the attribute’s IDL value to an ECMAScript value.
  • If the attribute is not declared readonly, then when setting the property to a particular ECMAScript value, the IDL value assigned to the attribute is the result of converting the ECMAScript value to an IDL value.

If a host object implements more than one interface with an attribute of a given name, it is implementation specific which attribute the property corresponds to.

The value of the internal [[Prototype]] property of the host object depends on 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).

If a host object has a primary prototype interface, then the value of the internal [[Class]] property MUST be the identifier of that interface. Otherwise, if the host object has no primary prototype interface, the value of the internal [[Class]] property is implementation specific.

Editorial note

Is there a need to specify the value of [[Class]] of interface objects and interface prototype objects? Or is there a need to allow the value of [[Class]] to be specified exactly in an extended attribute?

4.4.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 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.4.2. Indexed and named properties

If a host object that 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.

As soon as an index I begins being able to be used to index the host object, a property called the corresponding indexed property MUST be created on on the host object, but only if:

  • the host object does not have a property named ToString(I), and
  • none of the objects in the host object’s prototype chain have a property named ToString(I).

The name of the corresponding indexed property is ToString(I). This name is an array index property name, which is a property name for which the following algorithm returns true:

  1. Compute ToUint32(P).
  2. Compute ToString(Result(1)).
  3. If Result(2) is not equal to P or Result(1) is equal to 232 − 1, return false.
  4. Return true.

If the [IndexSetter] extended attribute was not used, then the corresponding indexed property will have the ReadOnly attribute, and if the [IndexDeleter] extended attribute was not used, then the property will also have the DontDelete attribute.

If [IndexGetter] was specified on the interface, then the value of the corresponding indexed property whenever it is retrieved MUST be as specified in the interface description. If [IndexGetter] was specified on an operation then the value of the property whenever it is retrieved MUST be the value that would be returned by invoking the operation, passing the property name as the only argument. It is undefined what value the property has if the operation does not complete properly (if it throws an uncaught exception, for example).

Similarly, 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.

As soon as a name N begins being able to be used to index the host object, a property called the corresponding named property MUST be created on the host object, but only if:

  • the host object does not already have a property named N,
  • none of the objects in the host object’s prototype chain have a property named N, and
  • the host object does not also implement an interface that supports indexed properties or N is not an array index property name.

The name of the corresponding named property is N and will have the DontEnum attribute. In addition, if the [NameSetter] extended attribute was not used, then the property will also have the ReadOnly attribute, and if the [NameDeleter] extended attribute was not used, then the property will also have the DontDelete attribute.

If [NameGetter] was specified on the interface, then the value of the property whenever it is retrieved MUST be as specified in the interface description. If [NameGetter] was specified on an operation then the value of the property whenever it is retrieved MUST be the value that would be returned by invoking the operation, passing the property name as the only argument. It is undefined what value the property has if the operation does not complete properly (if it throws an uncaught exception, for example).

Editorial note

What about if the [NameGetter]-annotated operation has side effects? Maybe it would be better to put back a [[Get]] method that requires calling the getter method every time the property is fetched, and at that time modify the value of the IDL attribute.

Support for [NameCreator], [NameSetter], [IndexCreator] and [IndexSetter] is handled by the host object [[Put]] method defined in section 4.4.3, and support for [IndexDeleter] and [NameDeleter] is handled by the host object [[Delete]] method defined in section 4.4.4.

4.4.3. Host object [[Put]] method

The internal [[Put]] method of every host object O that implements at least one IDL interface MUST behave as follows, assuming P is the property name and V is the property value passed to [[Put]]:

Editorial note

This looks terribly long and confusing. It might be best to turn this into a structured algorithm, instead of the flat style of ECMA-262.

  1. If P is not the name of a supported named property, then go to step 15.
  2. If O has a property that is the corresponding named property for the named property P, then go to step 9.
  3. If O does not implement a [NameCreator]-annotated interface, then go to step 6.
  4. Perform the behavior for creating a named property as specified by the description of the [NameCreator]-annotated interface.
  5. Return.
  6. Determine a callable object that corresponds to a [NameCreator]-annotated operation on an interface that O implements. If there is no such operation, then go to step 15.
  7. Invoke the [[Call]] method of Result(6), providing O as the this value and with P and V as the two argument values.
  8. Return.
  9. If O does not implement a [NameSetter]-annotated interface, then go to step 12.
  10. Perform the behavior for setting a named property as specified by the description of the [NameSetter]-annotated interface.
  11. Return.
  12. Determine a callable object that corresponds to a [NameSetter]-annotated operation on an interface that O implements. If there is no such operation, then go to step 15.
  13. Invoke the [[Call]] method of Result(12), providing O as the this value and with P and V as the two argument values.
  14. Return.
  15. If P is not the index of a supported indexed property, then go to step 29.
  16. If O has a property that is the corresponding indexed property for the indexed property P, then go to step 23.
  17. If O does not implement an [IndexCreator]-annotated interface, then go to step 20.
  18. Perform the behavior for creating an indexed property as specified by the description of the [IndexCreator]-annotated interface.
  19. Return.
  20. Determine a callable object that corresponds to an [IndexCreator]-annotated operation on an interface that O implements. If there is no such operation, then go to step 29.
  21. Invoke the [[Call]] method of Result(20), providing O as the this value and with P and V as the two argument values.
  22. Return.
  23. If O does not implement an [IndexSetter]-annotated interface, then go to step 26.
  24. Perform the behavior for setting an indexed property as specified by the description of the [IndexSetter]-annotated interface.
  25. Return.
  26. Determine a callable object that corresponds to an [IndexSetter]-annotated operation on an interface that O implements. If there is no such operation, then go to step 29.
  27. Invoke the [[Call]] method of Result(26), providing O as the this value and with P and V as the two argument values.
  28. Return.
  29. If O does not have a property with name P, then go to step 34.
  30. If the property on O with name P does not correspond to an attribute declared with a [PutForwards] extended attribute, then go to step 34.
  31. Call the [[Get]] method of O with name P.
  32. Call the [[Put]] method of Result(31) with the property name being the argument to the [PutForwards] extended attribute, and value V.
  33. Return.
  34. If O does not have a property named P that is the property corresponding to an attribute and which is annotated with the [Replaceable] extended attribute, then go to step 37.
  35. Remove the property with name P from O.
  36. Go to step 42.
  37. Call the [[CanPut]] method of O with name P.
  38. If Result(34) is false, return.
  39. If O doesn’t have a property with name P, go to step 42.
  40. Set the value of the property to V. The attributes of the property are not changed.
  41. Return.
  42. Create a property with name P, set its value to V and give it empty attributes.
  43. Return.

4.4.4. Host object [[Delete]] method

The internal [[Delete]] method of every host object O that implements at least one IDL interface MUST behave as follows, assuming P is the property name passed to [[Delete]]:

  1. If O doesn’t have a property with name P, return true.
  2. If O has the DontDelete attribute, return false.
  3. If the property with name P on object O is not a corresponding named property, then go to step 11.
  4. If O does not implement a [NameDeleter]-annotated interface, then go to step 8.
  5. Perform the behavior for deleting a named property as specified by the description of the [NameDeleter]-annotated interface.
  6. If the behavior specified for deleting a named property indicated that the deletion failed, return false.
  7. Return true.
  8. Determine a callable object that corresponds to a [NameDeleter]-annotated operation on an interface that O implements.
  9. Invoke the [[Call]] method of Result(8), providing O as the this value and with P as the argument value.
  10. If the [NameDeleter]-annotated operation is declared to return a value of type boolean, then return ToBoolean(Result(9)). Otherwise, return true.
  11. If the property with name P on object O is not a corresponding indexed property, then go to step 19.
  12. If O does not implement a [IndexDeleter]-annotated interface, then go to step 16.
  13. Perform the behavior for deleting an indexed property as specified by the description of the [IndexDeleter]-annotated interface.
  14. If the behavior specified for deleting an indexed property indicated that the deletion failed, return false.
  15. Return true.
  16. Determine a callable object that corresponds to a [IndexDeleter]-annotated operation on an interface that O implements.
  17. Invoke the [[Call]] method of Result(16), providing O as the this value and with P as the argument value.
  18. If the [IndexDeleter]-annotated operation is declared to return a value of type boolean, then return ToBoolean(Result(17)). Otherwise, return true.
  19. Remove the property with name P from O.
  20. Return true.

Note that assigning a value to a property that corresponds to an attribute results in that value being converted to an IDL value and assigned to the attribute, as described in section 4.4.

4.4.5. Host object [[Call]] method

The internal [[Call]] method of every host object O that implements an IDL interface that is annotated with the [Callable] extended attribute MUST behave as follows:

  1. Determine the callable object that corresponds to the operation that the [Callable] extended attribute identifies.
  2. Invoke the [[Call]] method of Result(1), providing O as the this value and providing the same argument list that was passed to this [[Call]] method invocation.
  3. Return Result(2).

4.5. 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. Invoke the [[Call]] method of X, providing the callback this value as the this value and arg0..n−1 as the argument values.
  7. Return the result of converting Result(6) to an IDL value.

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.

4.6. Exceptions

For every exception that is not declared with the [NoInterfaceObject] extended attribute, a corresponding property MUST exist on the ECMAScript global object whose name is the identifier of the exception. The value of this property 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 { DontDelete, DontEnum }.

4.6.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 associated with the exception through the [ExceptionConsts] extended attribute, then the exception interface object will have properties corresponding to these constants as described in section 4.6.3 below.

The exception interface object MUST also have a property named prototype with attributes { DontDelete, ReadOnly } whose value is an object called the exception interface prototype object. This object also provides access to the constants that are associated with the exception through the [ExceptionConsts] extended attribute.

4.6.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.6.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 associated with the exception with the [ExceptionConsts] extended attribute. These properties are described in more detail in section 4.6.3 below.

4.6.3. Constants

If the enclosing module of the exception has an [ExceptionConsts] extended attribute whose argument is the identifier of the exception, then there MUST be a property, corresponding to each constant defined on the enclosing module, on the exception interface object (if it exists) and the exception interface prototype object:

  • 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 { DontDelete, ReadOnly }.

4.7. Host exception objects

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

A host exception object MUST have a property for each exception member declared on the exception:

  • The name of the property is the identifier of the exception member.
  • The property has attributes { DontDelete }.

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.

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 the boolean obtained by converting to an IDL value the result of calling the booleanValue() method on the java.lang.Boolean object.
A java.lang.Byte object
The IDL value is the octet obtained by converting to an IDL value the result of calling the byteValue() method on the java.lang.Byte object.
A java.lang.Short object
The IDL value is the short obtained by converting to an IDL value the result of calling the shortValue() method on the java.lang.Short object.
A java.lang.Integer object
The IDL value is the long obtained by converting to an IDL value the result of calling the intValue() method on the java.lang.Integer object.
A java.lang.Long object
The IDL value is the long long obtained by converting to an IDL value the result of calling the longValue() method on the java.lang.Long object.
A java.lang.Float object
The IDL value is the float obtained by converting to an IDL value the result of calling the floatValue() method on the java.lang.Float object.
An object of any other class
The IDL value is an Object value that references the same object.
[something for sequences]
Editorial note

TBD, once sequences are fixed up.

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 (except DOMString)

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)
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. sequence<T>

Editorial note

This section to be rewritten, once sequences are fixed up.

The IDL sequence<T> type corresponds to a Java array of type T.

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

A Java object implementing an interface with an operation declared to take an argument of type sequence<T> MUST throw a NullPointerException exception if null is passed as the corresponding argument to the corresponding method. Similarly, a setter method for an IDL attribute MUST throw a NullPointerException exception if the attribute is declared to be of type sequence<T>.

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 by running the following algorithm (where V is the Java value):

  1. If V is null:
    1. If the conversion to an IDL value is being performed due to V being passed as an operation argument that is annotated with the [Null] extended attribute, or due to V being assigned to an attribute with [Null]:
      1. If the [Null] extended attribute took an identifier argument Empty, then return the DOMString value that represents the empty string (an empty sequence of 16 bit code units).
      2. Otherwise, the [Null] extended attribute took an identifier argument Null. Return the DOMString value null.
  2. Return the IDL DOMString value that represents the same sequence of characters as the one the Java java.lang.String value V represents.

The result of converting an IDL DOMString value to an Java java.lang.String value is:

  • If the IDL DOMString value is null, then the Java value is null.
  • Otherwise, the Java 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. Object implementing an interface

IDL object implementing an interface 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 object implementing an interface values are performed in the same way as that for the IDL Object type.

5.2.16. Boxed valuetype

IDL boxed valuetype values are represented with Java object references of a particular class, depending on the type being boxed. If T is the type being boxed, then the table below lists the Java class that the boxed valuetype maps to:

T 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

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

A java.lang.Boolean object
The IDL value is a boxed boolean whose value is obtained by converting to an IDL value the result of calling the booleanValue() method on the java.lang.Boolean object.
A java.lang.Byte object
The IDL value is a boxed octet whose value is obtained by converting to an IDL value the result of calling the byteValue() method on the java.lang.Byte object.
A java.lang.Short object
The IDL value is a boxed short whose value is obtained by converting to an IDL value the result of calling the shortValue() method on the java.lang.Short object.
A java.lang.Integer object
The IDL value is a boxed long whose value is obtained by converting to an IDL value the result of calling the intValue() method on the java.lang.Integer object.
A java.lang.Long object
The IDL value is a boxed long long whose value is obtained by converting to an IDL value the result of calling the longValue() method on the java.lang.Long object.
A java.lang.Float object
The IDL value is a boxed float whose value is obtained by converting to an IDL value the result of calling the floatValue() method on the java.lang.Float object.
[something for sequences]
Editorial note

TBD, once sequences are fixed up.

null
The IDL value is the null value.

How to convert an IDL boxed valuetype value to a Java value depends on its value and the type being boxed:

A boxed primitive value (except DOMString)

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

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)
[something for sequences]
Editorial note

TBD, once sequences are fixed up.

The null value
The Java value is null.

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 <optypes> in the effective overload set for id on I (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 has a final argument that is declared with the [Variadic] extended attribute, 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. Perform 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 Result(3) 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 Result(1) 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.

For each attribute defined on the IDL interface that is read only and is declared with the [PutForwards] extended attribute, 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 type of the attribute identified by the [PutForwards] extended attribute on the interface type that this attribute is declared to be of, 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 forwarded-to 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 identified by the [PutForwards] extended attribute on the interface type that this attribute is declared to be of, 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 is declared with the [Stringifies] extended attribute, the String toString() method MUST be overridden to allow stringification of the object as required by the IDL interface. If the [Stringifies] extended attribute on the IDL interface has an identifier argument A, assuming O is the object on which the method was invoked, the behavior of the overridden toString method MUST be as follows:

  1. Invoke the getter method on O that corresponds to the IDL attribute A.
  2. Return Result(1).

If the [Stringifies] extended attribute on the IDL interface was not given an argument, 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 enclosing module of the IDL exception, where that module has been declared with the [ExceptionConsts] extended attribute, 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, Robin Berjon, Gorm Haug Eriksen, Ian Hickson, Björn Höhrmann, Kartikaya Gupta, Magnus Kristiansen, Lachlan Hunt, Anne van Kesteren, Jim Ley, Simon Pieters, Jonas Sicking, Garrett Smith, Maciej Stachowiak, Collin Xu, Boris Zbarsky.

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 [optional] will not be recognized as the the [Optional] 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:

[1]DefinitionsExtendedAttributeList Definition Definitions
 | ε
[2]DefinitionModule
 | Interface
 | Exception
 | Typedef
 | Valuetype
 | Const
[3]Module"module" identifier "{" Definitions "}" ";"
[4]Interface"interface" identifier InterfaceBody ";"
[5]InterfaceInheritance":" ScopedNameList
 | ε
[6]InterfaceBodyInterfaceInheritance "{" InterfaceMembers "}"
 | ε
[7]InterfaceMembersExtendedAttributeList InterfaceMember InterfaceMembers
 | ε
[8]InterfaceMemberConst
 | Attribute
 | Operation
[9]Exception"exception" identifier "{" ExceptionMembers "}" ";"
[10]ExceptionMembersExtendedAttributeList ExceptionMember ExceptionMembers
 | ε
[11]Typedef"typedef" Type TypedefRest
[12]TypedefRestidentifier ";"
 | "DOMString" ";"
[13]Valuetype"valuetype" ValuetypeRest
[14]ValuetypeRestidentifier BoxedType ";"
 | "DOMString" "sequence" "<" "unsigned" "short" ">" ";"
[15]Const"const" DeclarationType identifier "=" ConstExpr ";"
[16]ConstExprBooleanLiteral
 | integer
 | float
[17]BooleanLiteral"TRUE"
 | "FALSE"
[18]AttributeReadOnly "attribute" DeclarationType identifier GetRaises SetRaises ";"
[19]ReadOnly"readonly"
 | ε
[20]GetRaises"getraises" ExceptionList
 | ε
[21]SetRaises"setraises" ExceptionList
 | ε
[22]OperationReturnType identifier "(" ArgumentList ")" Raises ";"
[23]Raises"raises" ExceptionList
 | ε
[24]ExceptionList"(" ScopedNameList ")"
[25]ArgumentListArgument Arguments
 | ε
[26]Arguments"," Argument Arguments
 | ε
[27]ArgumentExtendedAttributeList "in" DeclarationType identifier
[28]ExceptionMemberDeclarationType identifier ";"
[29]ExtendedAttributeList"[" ExtendedAttribute ExtendedAttributes "]"
 | ε
[30]ExtendedAttributes"," ExtendedAttribute ExtendedAttributes
 | ε
[31]ExtendedAttribute "(" ExtendedAttributeInner ")" ExtendedAttributeRest
 | "[" ExtendedAttributeInner "]" ExtendedAttributeRest
 | "{" ExtendedAttributeInner "}" ExtendedAttributeRest
 | Other ExtendedAttributeRest
[32]ExtendedAttributeRestExtendedAttribute
 | ε
[33]ExtendedAttributeInner "(" ExtendedAttributeInner ")" ExtendedAttributeInner
 | "[" ExtendedAttributeInner "]" ExtendedAttributeInner
 | "{" ExtendedAttributeInner "}" ExtendedAttributeInner
 | OtherOrComma ExtendedAttributeInner
 | ε
[34]Other integer
 | float
 | identifier
 | string
 | other
 | ":"
 | "::"
 | ";"
 | "<"
 | "="
 | ">"
 | "DOMString"
 | "FALSE"
 | "Object"
 | "TRUE"
 | "any"
 | "attribute"
 | "boolean"
 | "const"
 | "exception"
 | "float"
 | "getraises"
 | "in"
 | "interface"
 | "long"
 | "module"
 | "octet"
 | "raises"
 | "sequence"
 | "setraises"
 | "short"
 | "typedef"
 | "unsigned"
 | "valuetype"
[35]OtherOrCommaOther
 | ","
[36]DeclarationTypeUnsignedIntegerType
 | ScopedName
 | "any"
 | "boolean"
 | "octet"
 | "float"
 | "DOMString"
 | "Object"
[37]BoxedTypeUnsignedIntegerType
 | ScopedName
 | "boolean"
 | "octet"
 | "float"
 | "sequence" "<" Type ">"
[38]TypeDeclarationType
 | "sequence" "<" Type ">"
[39]UnsignedIntegerType"unsigned" IntegerType
 | IntegerType
[40]IntegerType"short"
 | "long" OptionalLong
[41]OptionalLong"long"
 | ε
[42]ReturnTypeDeclarationType
 | "void"
[43]ScopedNameListScopedName ScopedNames
[44]ScopedNames"," ScopedName ScopedNames
 | ε
[45]ScopedName"::" ScopedNameAfterColon
 | identifier ScopedNameParts
[46]ScopedNameAfterColonidentifier ScopedNameParts
 | "DOMString"
[47]ScopedNameParts"::" ScopedNamePartsAfterColon
 | ε
[48]ScopedNamePartsAfterColonidentifier ScopedNameParts
 | "DOMString"
[49]ExtendedAttributeNoArgidentifier
[50]ExtendedAttributeArgListidentifier "(" ArgumentList ")"
[51]ExtendedAttributeIdentidentifier "=" identifier
[52]ExtendedAttributeScopedNameidentifier "=" ScopedName
[53]ExtendedAttributeNamedArgListidentifier "=" identifier "(" ArgumentList ")"
Note

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

While the ExtendedAttribute 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, 3rd Edition, M. Cowlishaw, Editor. Ecma International, December 1999. 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.0 – OMG IDL Syntax and Semantics chapter. Object Management Group, June 2002. Available at http://www.omg.org/cgi-bin/apps/doc?formal/02-06-39.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.

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.