W3C

Web IDL

W3C Working Draft 29 August 2008

This Version:
http://www.w3.org/TR/2008/WD-WebIDL-20080829/
Latest Version:
http://www.w3.org/TR/WebIDL/
Previous Version:
http://www.w3.org/TR/2008/WD-DOM-Bindings-20080410/
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 29 August 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.

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 a syntactic subset of OMG IDL version 3.0 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 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 is syntactically a subset thereof.

An IDL fragment is a sequence of definitions that matches the Definitions non-terminal in the grammar. See Appendix A for the complete grammar and an explanation of the notation used.

Each definition (matching Definition) can be preceded by a list of extended attributes (matching ExtendedAttributeList), which can control how the definition will be handled in language bindings. The extended attributes defined by this specification are discussed in section 3.8 below.

A definition is said to be declared at the outermost scope if there is no Module ancestor of the non-terminal representing the definition in the parse tree for the IDL fragment. Conforming IDL fragments SHOULD NOT have any non-module definitions declared at the outermost scope.

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

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

Each of the sections below needs examples.

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.
  • Otherwise, if the scoped name is a relative scoped name, then:
    • If there exists a definition whose qualified name is equal to the concatenation of the qualified name of the module, two U+003A COLON (":") characters and the scoped name, then the scoped name resolves to that definition.
    • Otherwise, if there exists a definition whose qualified name is equal to the concatenation of two U+003A COLON (":") characters and the scoped name, then the scoped name resolves to that definition.
    • Otherwise, 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.
[44]ScopedName"::" ScopedNameAfterColon
 | identifier ScopedNameParts
[45]ScopedNameAfterColonidentifier ScopedNameParts
 | "DOMString"
[46]ScopedNameParts"::" ScopedNamePartsAfterColon
 | ε
[47]ScopedNamePartsAfterColonidentifier ScopedNameParts
 | "DOMString"

3.2. Modules

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

The enclosing module of a definition is defined as follows:

  • 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 following extended attributes are applicable to modules: [ExceptionConsts].

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

The identifier of an interface member is given by the first identifier terminal in a derivation of the non-terminal that represents the interface member. The identifier of an interface member (except for operations, which can be overloaded) MUST be unique within the interface on which it is defined.

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

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

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

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

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

[4]Interface"interface" identifier InterfaceBody ";"
[5]InterfaceInheritance":" ScopedNameList
 | ε
[6]InterfaceBodyInterfaceInheritance "{" InterfaceMembers "}"
 | ε
[7]InterfaceMembersExtendedAttributeList InterfaceMember InterfaceMembers
 | ε
[8]InterfaceMemberConst
 | Attribute
 | Operation
[42]ScopedNameListScopedName ScopedNames
[43]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 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 a value of type boolean: true.
  • The value of the "FALSE" terminal is a value of type boolean: 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.

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 an 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]

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

No extended attributes are applicable to constants.

[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 that can be assigned and retrieved.

The type of the attribute is given by the DeclarationType non-terminal. If the DeclarationType is a scoped name, then it MUST resolve, with respect to the enclosing module of the interface on which the attribute is defined, to an interface, typedef or boxed valuetype that has been declared previously.

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

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

Editorial note

Should conforming implementations have a requirement that they must not raise an exception (that was defined in the IDL) that is not in the getraises/setraises list?

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

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

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

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

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

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

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

[22]OperationReturnType identifier "(" ArgumentList ")" Raises ";"
[23]Raises"raises" ExceptionList
 | ε
[25]ArgumentListArgument Arguments
 | ε
[26]Arguments"," Argument Arguments
 | ε
[27]ArgumentExtendedAttributeList "in" DeclarationType identifier
[41]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 is given by the first identifier terminal in a derivation of ExceptionMember. The identifier of an exception member MUST be unique within the exception on which it is defined.

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

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

No extended attributes are applicable to exception members.

[9]Exception"exception" identifier "{" ExceptionMembers "}" ";"
[10]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;
[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>;
[13]Valuetype"valuetype" ValuetypeRest
[14]ValuetypeRestidentifier BoxedType ";"
 | "DOMString" "sequence" "<" "unsigned" "short" ">" ";"

3.7. Types

This section lists the types supported by the IDL.

[35]DeclarationTypeUnsignedIntegerType
 | ScopedName
 | "any"
 | "boolean"
 | "octet"
 | "float"
 | "DOMString"
 | "Object"
[36]BoxedTypeUnsignedIntegerType
 | ScopedName
 | "boolean"
 | "octet"
 | "float"
 | "sequence" "<" Type ">"
[37]TypeDeclarationType
 | "sequence" "<" Type ">"
[38]UnsignedIntegerType"unsigned" IntegerType
 | IntegerType
[39]IntegerType"short"
 | "long" OptionalLong
[40]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.

Editorial note

Do we need to mention anything about different NaNs, zeroes, infinities or denormalised numbers?

3.7.11. DOMString

The DOMString type corresponds to the set of all possible strings of Unicode characters, 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>

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.

An extended attribute is specified as an identifier, optionally followed by some additional information. There are four forms an extended attribute may have:

  • [TheExtendedAttribute], where it takes no argument;
  • [TheExtendedAttribute(ArgumentList)], where it takes an argument list;
  • [TheExtendedAttribute=identifier], where it takes an identifier; and,
  • [TheExtendedAttribute=identifier(ArgumentList)], where it takes a named argument list.

This specification defines a number of extended attributes, which are listed in the sub-sections below. Each definition will state which of the above four forms are allowed.

Editorial note

Have an extended attribute that specifies what properties get enumerated in a for..in loop?

[29]ExtendedAttributeList"[" ExtendedAttribute ExtendedAttributes "]"
 | ε
[30]ExtendedAttributes"," ExtendedAttribute ExtendedAttributes
 | ε
[31]ExtendedAttributeidentifier ExtendedAttributeDetails
[32]ExtendedAttributeDetails"=" ExtendedAttributeAssignment
 | "(" ArgumentList ")"
 | ε
[33]ExtendedAttributeAssignmentidentifier ExtendedAttributeAssignmentArguments
[34]ExtendedAttributeAssignmentArguments"(" ArgumentList ")"
 | ε

3.8.1. [Constructor]

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

If the [IndexGetter] extended attribute appears on an operation with a single unsigned long argument, it indicates that an object that implements the interface can be indexed with an unsigned long, resulting in the same effect as calling the operation with the given index (for languages that support such object indexing). If an object implements interfaces such that it has more than one operation annotated with [IndexGetter], then which operation is invoked when an object is indexed with an unsigned long value is undefined.

The [IndexGetter] extended attribute MUST take no argument.

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

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

An ECMAScript implementation would have an internal [[Get]] method that allows values to be retrieved from the map as properties, and a corresponding [[Put]] method for setting values in the map:

ECMAScript
var map = getOrderedMap();  // Assume map is a host object implementing the OrderedMap interface.
var x, y;

x = map[0];                 // Same as: x = map.getByIndex(0)
map[1] = false;             // Same as: map.setByIndex(1, false)

y = map.apple;              // Same as: y = map.get('apple')
map.banana = 123;           // Same as: map.set('banana', 123)

3.8.4. [IndexSetter]

If the [IndexSetter] extended attribute appears on an operation with two arguments, the first of which is unsigned long, it indicates that an object that implements the interface can be indexed with an unsigned long for assignment, resulting in the same effect as calling the operation with the given index and value to assign (for languages that support such object indexing). If an object implements interfaces such that it has more than one operation annotated with [IndexSetter], then which operation is invoked when an object is indexed with an unsigned long value for assignment is undefined.

The [IndexSetter] extended attribute MUST take no argument.

Example

See section 3.8.3 for an example of the use of [IndexSetter].

3.8.5. [NameGetter]

If the [NameGetter] extended attribute appears on an operation with a single DOMString argument, it indicates that an object that implements the interface can be indexed with a string, resulting in the same effect as calling the operation with the given index name (for languages that support such object indexing). If an object has both a [NameGetter]- and [IndexGetter]-annotated operation, then which operation is invoked when an object is indexed is language binding specific.

The [NameGetter] extended attribute MUST take no argument.

Example

See section 3.8.3 for an example of the use of [NameGetter].

3.8.6. [NameSetter]

If the [NameSetter] extended attribute appears on an operation with two arguments, the first of which is a DOMString, it indicates that an object that implements the interface can be indexed with a string for assignment, resulting in the same effect as calling the operation with the given index and value to assign (for languages that support such object indexing). If an object implements interfaces such that it has more than one operation annotated with [NameSetter], then which operation is invoked when an object is indexed with a string value for assignment is undefined.

The [NameSetter] extended attribute MUST take no argument.

Example

See section 3.8.3 for an example of the use of [NameSetter].

3.8.7. [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.8. [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 the value of the attribute being assigned to.

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

The [PutForwards] extended attribute MUST take an identifier that is the identifier of an attribute that exists on the interface and which has the same type as this attribute. Assignments to the attribute with [PutForwards] will be forwarded to that identified attribute.

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();           // Assume p is a host object implementing the Person interface.

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

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

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.10. [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 integers);
  void intersection([Variadic] in long integers);
};

In the ECMAScript binding, variadic operations are implemented by functions that can accept the subsequent arguments:

ECMAScript
var s = getIntegerSet();  // Assume s is a host object implementing the IntegerSet interface.

s.union();                // Passing no arguments corresponding to 'integers'.
s.union(1, 4, 7);         // Passing three arguments corresponding to 'integers'.

A binding for a language that does not support variadic functions may specify that an explicit array or list of integers be passed to such an operation.

4. ECMAScript binding

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

Unless otherwise specified, every object described in this section has internal properties [[Get]], [[Put]], [[CanPut]], [[HasProperty]], [[Delete]] and [[DefaultValue]] with the same behavior as specified for native objects, as described in section 8.6.2 of 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.

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 a values of a given IDL type are represented in ECMAScript. For each IDL type, it is described how ECMAScript values are converted to an IDL value when passed to a host object expecting that type, and how IDL values of that type are converted to ECMAScript values when returned from a host object.

Editorial note

There should be a definition here for how to coerce an ECMAScript value according to the IDL type expected. This definition should then be explicitly referenced in the [[Get]], [[Put]] and function calling definitions below, rather than the current wording "must be handled according to the rules in section 4.1".

4.1.1. any

The IDL any type can correspond to any ECMAScript type.

Since there is no ECMAScript value that does correspond to an IDL value, no conversion is performed when passing an ECMAScript value to a host object expecting any, or when a host object returns a value of type any.

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.

Values passed to a host object expecting a boolean MUST first be converted to an ECMAScript Boolean value by the ToBoolean operator defined in section 9.2 of the ECMAScript Language Specification, 3rd Edition [ECMA-262].

boolean values returned from a host object MUST be ECMAScript Boolean values.

4.1.4. octet

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

Values passed to a host object expecting an octet MUST first be converted to an ECMAScript Number value by the ToUint8 operator, which functions (analogously to the ToUint32 operator defined in section 9.6 of the ECMAScript Language Specification, 3rd Edition [ECMA-262]) as follows:

  1. Call ToNumber on the input argument.
  2. If Result(1) is NaN, +0, −0, +∞, or −∞, return +0.
  3. Compute sign(Result(1)) * floor(abs(Result(1))).
  4. Compute Result(3) modulo 28.
  5. Return Result(4).

octet values returned from a host object MUST be integer ECMAScript Number values in the range [0, 255].

4.1.5. short

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

Values passed to a host object expecting a short MUST first be converted to an ECMAScript Number value by the ToInt16 operator, which functions (analogously to the ToInt32 operator defined in section 9.5 of the ECMAScript Language Specification, 3rd Edition [ECMA-262]) as follows:

  1. Call ToNumber on the input argument.
  2. If Result(1) is NaN, +0, −0, +∞, or −∞, return +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 Result(4) − 216. Otherwise, return Result(4).

short values returned from a host object MUST be integer ECMAScript Number values in the range [−32768, 32767].

4.1.6. unsigned short

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

Values passed to a host object expecting an unsigned short MUST first be converted to an ECMAScript Number value by the ToUint16 operator defined in section 9.7 of the ECMAScript Language Specification, 3rd Edition [ECMA-262].

unsigned short values returned from a host object MUST be integer ECMAScript Number values in the range [0, 65535].

4.1.7. long

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

Values passed to a host object expecting an long MUST first be converted to an ECMAScript Number value by the ToInt32 operator defined in section 9.5 of the ECMAScript Language Specification, 3rd Edition [ECMA-262].

long values returned from a host object MUST be integer ECMAScript Number values in the range [−2147483648, 2147483647].

4.1.8. unsigned long

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

Values passed to a host object expecting an unsigned long MUST first be converted to an ECMAScript Number value by the ToUint32 operator defined in section 9.5 of the ECMAScript Language Specification, 3rd Edition [ECMA-262].

unsigned long values returned from a host object MUST be integer ECMAScript Number values in the range [0, 4294967295].

4.1.9. long long

IDL long long values are represented by ECMAScript Number values.

Values passed to a host object expecting a long long MUST first be converted to an ECMAScript Number value by the ToInt64 operator, which functions (analogously to the ToInt32 operator defined in section 9.5 of the ECMAScript Language Specification, 3rd Edition [ECMA-262]) as follows:

  1. Call ToNumber on the input argument.
  2. If Result(1) is NaN, +0, −0, +∞, or −∞, return +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 Result(4) − 264. Otherwise, return Result(4).

long long values returned from a host object MUST be ECMAScript Number values. If the long long value cannot be represented exactly by a Number value (i.e., it is less than or equal to −253 or greater than or equal to 253), the Number value returned MUST be the number representable by a Number closest to the given long long.

Editorial note

Should check that range of signed integers representable in a double.

4.1.10. unsigned long long

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

Values passed to a host object expecting an unsigned long long MUST first be converted to an ECMAScript Number value by the ToUint64 operator, which functions (analogously to the ToUint32 operator defined in section 9.6 of the ECMAScript Language Specification, 3rd Edition [ECMA-262]) as follows:

  1. Call ToNumber on the input argument.
  2. If Result(1) is NaN, +0, −0, +∞, or −∞, return +0.
  3. Compute sign(Result(1)) * floor(abs(Result(1))).
  4. Compute Result(3) modulo 264.
  5. Return Result(4).

unsigned long long values returned from a host object MUST be ECMAScript Number values. If the unsigned long long value cannot be represented exactly by a Number value (i.e., it is greater than or equal to 253), the Number value returned MUST be the number representable by a Number closest to the given unsigned long long.

Editorial note

Should we do something other than choosing the closest double value to represent the long long?

4.1.11. float

IDL float values are represented by ECMAScript Number values.

Values passed to a host object expecting a float MUST first be converted to an ECMAScript Number value by the ToNumber operator defined in section 9.3 of the ECMAScript Language Specification, 3rd Edition [ECMA-262].

float values returned from a host object MUST be ECMAScript Number values.

4.1.12. DOMString

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

Values passed to a host object expecting a DOMString value MUST first be converted to an ECMAScript String value by the ToString operator defined in section 9.8 of the ECMAScript Language Specification, 3rd Edition [ECMA-262], unless it is the null value, in which case the value passed to the host object is null.

A DOMString value returned from a host object MUST be either an ECMAScript String value or the ECMAScript null.

4.1.13. sequence<T>

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.

If a host object expecting an Object is passed the null value, then that value MUST passed without modification. Otherwise, the value being passed MUST first be converted to an ECMAScript Object value by the ToObject operator defined in section 9.9 of the ECMAScript Language Specification, 3rd Edition [ECMA-262].

If a host object returns an Object that is null, then the ECMAScript null value MUST be returned. Otherwise, an ECMAScript Object value MUST be returned.

4.1.15. Object implementing an interface

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

If a host object expecting an object that implements an interface A is passed the null value, then that value MUST passed without modification. Otherwise, the value being passed MUST first be converted to an ECMAScript Object value by the ToObject operator defined in section 9.9 of the ECMAScript Language Specification, 3rd Edition [ECMA-262]. If after that conversion the object is not one that implements A (either intrinsically for a host object, or as described in section 4.5 below for a native object), then a TypeError MUST be thrown.

If a host object returns an object that implements an interface A that is null, then the ECMAScript null value MUST be returned. Otherwise, an ECMAScript Object value that implements A MUST be returned.

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.

If a host object expecting a boxed valuetype is passed an ECMAScript value other than the null value, the value MUST first be handled according to the rules in this section corresponding to the IDL type being boxed.

If a host object returns a boxed valuetype that is null, then the ECMAScript null value MUST be returned. If the value returned is not null, it MUST first be handled according to the rules in this section corresponding to the IDL type being boxed.

4.2. ECMAScript-specific extended attributes

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

4.2.1. [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 must 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.2. [NativeObject]

If the [NativeObject] 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.

The [NativeObject] extended attribute MUST either take no argument or take the identifier FunctionOnly. 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
[NativeObject] 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
var t = getThing();                                // Assume t is a host object implementing the Thing interface.

t.addListener(function() { });                     // The function is the implementation of the eventOccurred
                                                   // operation on the Listener interface.

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

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

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.

Editorial note

Should this be [InterfaceObject] instead, and default to not having one?

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. [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();         // Assume c is a host object implementing the Cat interface.

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, which allows construction of objects that implement the interface. The property has the attributes { DontDelete, DontEnum }. The characteristics of a named constructor 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.

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. The behavior of this [[Construct]] method is not necessarily the same as that described for Function objects in section 13.2.2 of the ECMAScript Language Specification, 3rd Edition [ECMA-262], but it MUST return an object that implements the given interface if it returns normally (that is, if it does not throw an exception).

Editorial note

Specify here how multiple constructors are handled (like operation overloading).

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

An interface will have a named constructor for each unique identifier used in an [NamedConstructor] extended attribute on that interface. This named constructor MUST have a [[Construct]] internal property, which allows construction of objects that implement the interface. The behavior of this [[Construct]] method is not necessarily the same as that described for Function objects in section 13.2.2 of the ECMAScript Language Specification, 3rd Edition [ECMA-262], but it MUST return an object that implements the given interface if it returns normally (that is, if it does not throw an exception).

Editorial note

Specify named constructor overloading here.

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.

If the interface is declared with the [Constructor] extended attribute, the interface prototype object MUST also have a property named constructor with attributes { DontEnum } whose value is a reference to the interface object for the interface.

Editorial note

Haven’t checked what attributes browsers use on the constructor property.

Also, should the constructor property exist even for non-constructable objects?

No particular value must be used for the internal [[Prototype]] property of the interface prototype object. However, it MUST be an object that provides access to the properties corresponding to the operations and constants defined on the interfaces from which this interface inherits. Changes made to the interface prototype objects of superinterfaces MUST be reflected through this object, as with normal prototype-based single inheritance in ECMAScript. If more than one superinterface has a given property, it is implementation specific which one is accessed.

Example

Assume the following IDL:

IDL
interface A {
  void f();
};

interface B {
  void g();
};

interface C : A, B {
  void f();
};

interface D : C {
  void h();
};

The following is one way for an implementation to set up the prototype chain for the interface objects:

  • The [[Prototype]] internal property of the interface prototype objects for A and B is the Object prototype object, since neither of these interfaces has a superinterface.
  • The [[Get]], [[CanPut]] and [[HasProperty]] internal methods of the interface prototype object for A are the standard ones defined in section 8.6.2 of the ECMAScript Language Specification, 3rd Edition [ECMA-262].
  • The [[Prototype]] internal prototype of the interface prototype object for C is null.
  • The [[Get]] internal method of the interface prototype object for C behaves as follows (where O is the object and P is the property name):
    1. If O doesn’t have a property with name P, go to step 4.
    2. Get the value of the property.
    3. Return Result(2).
    4. Call the [[HasProperty]] method of the interface prototype object for A with property name P.
    5. If Result(4) is false, go to step 8.
    6. Call the [[Get]] method of the interface prototype object for A with property name P.
    7. Return Result(6).
    8. Call the [[HasProperty]] method of the interface prototype object for B with property name P.
    9. If Result(8) is false, go to step 12.
    10. Call the [[Get]] method of the interface prototype object for B with property name P.
    11. Return Result(10).
    12. Return undefined.
  • The [[CanPut]] internal method of the interface prototype object for C behaves as follows (where O is the object and P is the property name):
    1. If O doesn’t have a property with name P, go to step 4.
    2. If the property has the ReadOnly attribute, return false.
    3. Return true.
    4. Call the [[CanPut]] method of the interface prototype object for A with property name P.
    5. If Result(4) is false, return false.
    6. Call the [[CanPut]] method of the interface prototype object for B with property name P.
    7. If Result(6) is false, return false.
    8. Return true.
  • The [[HasProperty]] internal method of the interface prototype object for C behaves as follows (where O is the object and P is the property name):
    1. If O has a property with name P, return true.
    2. Call the [[HasProperty]] method of the interface prototype object for A with property name P.
    3. If Result(3) is true, return true.
    4. Call the [[HasProperty]] method of the interface prototype object for B with property name P.
    5. If Result(5) is true, return true.
    6. Return false.
  • The [[Prototype]] internal property of the interface prototype object for D is the interface prototype object for C, since D has only a single superinterface.
  • The [[Get]], [[CanPut]] and [[HasProperty]] internal methods of the interface prototype object for D are the standard ones defined in section 8.6.2 of the ECMAScript Language Specification, 3rd Edition [ECMA-262].
Editorial note

The above example algorithm is broken according to David Andersson, so this will probably change to using C3 as suggested.

Editorial note

Should the prototype chain and internal methods given in the example above be mandated, or just left as an example of how to do it?

4.3.4. Constants

For each constant defined on the interface, there MUST be a corresponding property on the interface object (if it exists) and the 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.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:

  • The name of the property is the identifier.
  • The property has attributes { DontEnum }.
  • The value of the property is a Function object that behaves as follows, assuming id is the identifier:
    1. Initialize O to null.
    2. Initialize arity to 0.
    3. Let n be the number of arguments passed to the function.
    4. Let arg0‥n−1 be the arguments passed to the function.
    5. If id identifies a single operation:
      1. Set O to the operation that id identifies.
      2. Set arity to the number of arguments that O is declared with.
      3. If the final argument of O has the [Variadic] extended attribute, set arity to arity − 1.
    6. Otherwise, if id identifies more than one operation:
      1. Let m be the number of operations id identifies.
      2. Let P1‥m be the operations that id identifies.
      3. Let score1‥m be a score calculated for each operation in P1‥m, as follows:
        1. Let Q be the operation for which a score is being calculated.
        2. Set arity to the number of arguments that Q is declared with.
        3. If the final argument of Q has the [Variadic] extended attribute, set arity to arity − 1.
        4. Initialize s to 0.
        5. If n < arity, set s to ∞.
        6. Otherwise, if n ≥ arity:
          1. Initialize i to 0.
          2. While i < arity:
            1. Let dt be the IDL type of argument i that Q is declared with.
            2. Let at be the ECMAScript type of argi.
            3. Let x be the value determined by looking up the score table below.
            4. If x ≠ 0, set s to s + (arity + 2)x.
            5. Set i to i + 1.
          3. If the final argument of Q has the [Variadic] extended attribute:
            1. Let dt be the IDL type of the final argument that Q is declared with.
            2. While i < n:
              1. Let at be the ECMAScript type of argi.
              2. Let x be the value determined by looking up the score table below.
              3. If x = ∞, set s to ∞.
              4. Set i to i + 1.
        7. The calculated score is s.
      4. If the minimum score in score1‥m is ∞, then there is no appropriate overloaded operation to invoke. Throw a TypeError and end the function.
      5. Set O to the operation in P1‥m whose corresponding score in score1‥m is the minimum. If multiple operations have the minimum score, it is undefined which is chosen. (Interface designers may specify in prose how operations are disambiguated at this point.)
    7. Perform the actions listed in the description of O with arg0‥n−1 as the argument values.
    Score table
    atdtx
    Undefined(any type)0
    Booleanboolean*1
    any1
    sequence<T> *
    Object implementing an interface
    (any other type)2
    Numberfloat *1
    octet *1
    short *1
    unsigned short *1
    long *1
    unsigned long *1
    long long *1
    unsigned long long *1
    any1
    sequence<T> *
    Object implementing an interface
    (any other type)2
    Stringsequence<unsigned short> *1
    any1
    sequence<T> (where T ≠ unsigned short) *
    Object implementing an interface
    (any other type)2
    NullObject1
    Object implementing an interface1
    Boxed valuetype of any type1
    any1
    sequence<T> *
    (any other type)2
    ObjectObject1
    Object implementing interface A (if the object implements A)1
    sequence<T> *1
    any1
    Object implementing interface A (if the object does not implement A)
    (any other type)2
    * The specified type or a boxed valuetype of the specified type.
    Editorial note

    Should there be a way for script to explicitly disambiguate function calls? For example, something like the “Explicit Method Specification” in LiveConnect 3. That could allow:

    IDL
    [Constructor]
    interface Ambiguity {
    
      void f(in octet x);
      void f(in long x);
    
      void g(in Node n);
      void g(in Document n);
    };
    ECMAScript
    var a = new Ambiguity();
    
    a.f(5);              // undefined which f() is called
    a['f(octet)'](5);    // explicitly call the first f()
    a['f(long)'](5);     // explicitly call the second f()
    
    a.g(document);                      // undefined which g() is called, since 'document' implements Node and Document
    a['g(::dom::Node)'](document);      // explicitly call the first g()
    a['g(::dom::Document)'](document);  // explicitly call the second g()
    

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 Function object. If the [Stringifies] extended attribute on the interface has an identifier argument P, assuming O is the object on which the function was invoked, the behavior of the toString function is 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 was not given an argument, then the behavior of the toString function is the stringification behavior of the interface, as described in the prose for the interface.

Editorial note

Should say what happens if [Stringifies] is used on an interface that also has a toString operation.

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

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.

No particular value must be used for the internal [[Prototype]] property of the host object. However, it MUST be an object that provides access to the properties corresponding to the operations and constants defined on all interfaces the host object implements. Changes made to the interface prototype objects of interfaces implemented by the host object MUST be reflected through this object. If more than one interface prototype object has a given property, it is implementation specific which one is accessed.

Example

Assume the IDL and interface prototype objects given in the section 4.3.3 example.

Now assume that ab is a host object that implements A and B and d is a host object that implements D. The following is one way for an implementation to connect the host objects to the interface prototype objects:

  • The [[Prototype]] internal property of the host object ab is an object that provides access to the properties from the interface prototype objects for both A and B:
    • The [[Prototype]] internal property of the [[Prototype]] object for ab is null.
    • The [[Get]] internal method of the [[Prototype]] object for ab behaves as follows (where O is the object and P is the property name):
      1. If O doesn’t have a property with name P, go to step 4.
      2. Get the value of the property P on object O.
      3. Return Result(2).
      4. Call the [[HasProperty]] method of the interface prototype object for A with property name P.
      5. If Result(4) is false, go to step 8.
      6. Call the [[Get]] method of the interface prototype object for A with property name P.
      7. Return Result(6).
      8. Call the [[HasProperty]] method of the interface prototype object for B with property name P.
      9. If Result(8) is false, go to step 12.
      10. Call the [[Get]] method of the interface prototype object for B with property name P.
      11. Return Result(10).
      12. Return undefined.
    • The [[CanPut]] internal method of the [[Prototype]] object for ab behaves as follows (where O is the object and P is the property name):
      1. If O doesn’t have a property with name P, go to step 4.
      2. If the property has the ReadOnly attribute, return false.
      3. Return true.
      4. Call the [[CanPut]] method of the interface prototype object for A with property name P.
      5. If Result(4) is false, return false.
      6. Call the [[CanPut]] method of the interface prototype object for B with property name P.
      7. If Result(6) is false, return false.
      8. Return true.

      Note that this method shouldn’t strictly be required, since there would be no way for script to get access to the [[Prototype]] object for ab.

    • The [[HasProperty]] internal method of the [[Prototype]] object for ab behaves as follows (where O is the object and P is the property name):
      1. If O has a property with name P, return true.
      2. Call the [[HasProperty]] method of the interface prototype object for A with property name P.
      3. If Result(2) is true, return true.
      4. Call the [[HasProperty]] method of the interface prototype object for B with property name P.
      5. If Result(5) is true, return true.
      6. Return false.
  • The [[Prototype]] internal property of the host object d is the interface prototype object for D, since D is the only interface the object directly implements.

4.4.1. Host object [[Get]] method

The internal [[Get]] 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 [[Get]]:

  1. Determine the name of an [IndexGetter]-annotated operation on the interfaces that O implements. If there is no such operation, go to step 8.
  2. Compute ToUint32(P).
  3. Compute ToString(Result(2)).
  4. If Result(3) is not equal to P or Result(2) is equal to 232 − 1, go to step 8.
  5. Invoke the [[Get]] method of object O with Result(1) as the argument.
  6. Invoke the [[Call]] method of Result(5), providing O as the this value and Result(2) as the single argument value.
  7. Return Result(6).
  8. Determine the name of a [NameGetter]-annotated operation on the interfaces that O implements. If there is no such operation, go to step 14.
  9. Invoke the [[HasProperty]] method of object O with P as the argument.
  10. If Result(9) is true, go to step 14.
  11. Invoke the [[Get]] method of object O with Result(8) as the argument.
  12. Invoke the [[Call]] method of Result(11), providing O as the this value and P as the single argument value.
  13. Return Result(12).
  14. If O doesn’t have a property with name P, go to step 17.
  15. Get the value of the property.
  16. Return Result(15).
  17. If the [[Prototype]] of O is null, return undefined.
  18. Call the [[Get]] method of [[Prototype]] with property name P.
  19. Return Result(18).

4.4.2. 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]]:

  1. Determine the name of an [IndexSetter]-annotated operation on the interfaces that O implements. If there is no such operation, go to step 8.
  2. Compute ToUint32(P).
  3. Compute ToString(Result(2)).
  4. If Result(3) is not equal to P or Result(2) is equal to 232 − 1, go to step 8.
    Editorial note

    Do we need to disallow 232 − 1 as an index number, just like Array does? Host objects with index setters won’t necessarily have a length property.

  5. Invoke the [[Get]] method of object O with Result(1) as the argument.
  6. Invoke the [[Call]] method of Result(5), providing O as the this value and Result(2) and V as the two argument values.
  7. Return.
  8. Determine the name of a [NameSetter]-annotated operation on the interfaces that O implements. If there is no such operation, go to step 14.
  9. Invoke the [[HasProperty]] method of object O with P as the argument.
  10. If Result(9) is true, go to step 14.
  11. Invoke the [[Get]] method of object O with Result(8) as the argument.
  12. Invoke the [[Call]] method of Result(11), providing O as the this value and P and V as the two argument values.
  13. Return.
  14. If O does not have a property with name P, then go to step 19.
  15. If the property on O with name P does not correspond to an attribute declared with a [PutForwards] extended attribute, then go to step 19.
  16. Call the [[Get]] method of O with name P.
  17. Call the [[Put]] method of Result(16) with the property name being the argument to the [PutForwards] extended attribute, and value V.
  18. Return.
  19. Call the [[CanPut]] method of O with name P.
  20. If Result(19) is false, return.
  21. If O doesn’t have a property with name P, go to step 24.
  22. Set the value of the property to V. The attributes of the property are not changed.
  23. Return.
  24. Create a property with name P, set its value to V and give it empty attributes.
  25. Return.

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 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 and the [NativeObject] extended attribute on the interface has the FunctionOnly argument, 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 [NativeObject] 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, 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, and 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 an argument list L as follows:

  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. Call the [[Call]] method of X, providing O as the this value and L as the argument values.
  6. Return Result(5).
Editorial note

HTML will want to override the this value for native object EventListener implementations to be the object the listener was added to, when the native object is a Function object. Do we need to add anything here for this?

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.

5. Java binding

This section describes how definitions written with the IDL in section 3 correspond to particular constructs in Java.

5.1. Names

Since Java has a number of reserved words in the language, 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.

5.2.1. any

The any IDL type corresponds to a Java java.lang.Object value. Values of IDL types that correspond to Java primitive types MUST be represented with an object according to the following table:

IDL type Java class
boolean java.lang.Boolean
octet java.lang.Byte
short java.lang.Short
unsigned short java.lang.Short
long java.lang.Integer
unsigned long java.lang.Integer
long long java.lang.Long
unsigned long long java.lang.Long
float java.lang.Float

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

The IDL boolean type maps exactly to the Java boolean type.

5.2.4. octet

The IDL octet type corresponds to the Java byte type. 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].

To encode an octet value in a byte, the following steps MUST be followed:

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

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

To decode an octet value from a byte, the following steps MUST be followed:

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

Note that 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

The IDL short type maps exactly to the Java short type.

5.2.6. unsigned short

The IDL unsigned short type corresponds to the Java short type. 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].

To encode an IDL unsigned short value in a Java short, the following steps MUST be followed:

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

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

To decode an IDL unsigned short value from a Java short, the following steps MUST be followed:

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

Note that 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

The IDL long type maps exactly to the Java int type.

5.2.8. unsigned long

The IDL unsigned long type corresponds to the Java int type. 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].

To encode an IDL unsigned long value in a Java int, the following steps MUST be followed:

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

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

To decode an IDL unsigned long value from a Java int, the following steps MUST be followed:

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

Note that 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

The IDL long long type maps exactly to the Java long type.

5.2.10. unsigned long long

The IDL unsigned long long type corresponds to the Java long type. 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].

To encode an IDL unsigned long long value in a Java long, the following steps MUST be followed:

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

To decode an IDL unsigned long long value from a Java long, the following steps MUST be followed:

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

5.2.11. float

The IDL float type maps exactly to the Java float type.

5.2.12. sequence<T>

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

Editorial note

Should mention what to do with null values in nested sequences (e.g. sequence<sequence<short>>).

5.2.13. DOMString

A DOMString is represented by a Java String object.

Editorial note

Fix this to refer to new xattrs controlling null/etc. passed as a DOMString.

A Java object implementing an interface with an operation declared to return a DOMString 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<unsigned short>.

A Java object implementing an interface with an operation declared to take an argument of type DOMString 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<unsigned short>.

5.2.14. Object

The IDL Object type maps exactly to the Java java.lang.Object type.

5.2.15. Object implementing an interface

The IDL interface type maps exactly to the corresponding Java interface type.

5.2.16. Boxed valuetype

A boxed valuetype is represented differently depending on the type being boxed. Let T be the type being boxed.

If T maps to a Java object value, which is the case for any, DOMString, sequence<T>, Object and interface types, then a boxed valuetype is represented by the Java null value (if the value of the boxed valuetype is null) or by a value as described in this section for the mapping for T (if the value of the boxed valuetype is not null). Thus, a Java object whose method implements an operation declared to take an argument of a sequence type MUST NOT throw an exception simply for being passed a null value.

If T does not map to a Java object value, then the boxed valuetype maps to a Java class as specified in the table below:

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

If the value of the boxed valuetype is not null, then the value stored inside the object of the given class MUST be as specified by the rules in this section for type T.

5.3. Modules

Every IDL module corresponds to a Java package, whose name is derived as follows:

  • If the module has been declared at the outermost scope, then the name of the corresponding Java package is the Java escaped identifier of the module.
  • Otherwise, the module has not been declared at the outermost scope. The name of the corresponding Java package is the name of the Java package corresponding to the enclosing module of this module, followed by a U+002E FULL STOP ("."), followed by the Java escaped identifier of the module.

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

Example

The following IDL will cause a Java interface named HTMLDocument in package org.w3c.dom.html to exist:

IDL
[Prefix="org::w3c::dom"]
module html {
  interface HTMLDocument {
    // …
  };
};
Java
package org.w3c.dom.html;

interface HTMLDocument {
  // …
}
Editorial note

The example uses [Prefix] and doesn’t match the prose above. Is [Prefix] a reasonable way to map modules to Java packages? It seems to me that just using the module structure to map to the package name is more natural:

IDL
module org {
  module w3c {
    module dom {
      module html {
        // …
      };
    };
  };
};

But that’s pretty verbose. In C++ you can skip steps in one go, so something similar in IDL would be:

IDL
module org::w3c::dom::html {
  // …
};

But that is not syntactically compatible with OMG IDL.

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.

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 Java value that is equivalent to the constant’s IDL value, according to the rules in section 5.2 above.

5.4.2. Operations

For each operation defined on the IDL interface, there MUST be a corresponding 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 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 argument on the operation. The type of the method argument is as follows. Let T be the Java type that corresponds to the operation argument type according to the rules in section 5.2 above. If the argument is the final argument on the operation, and it is declared with the [Variadic] extended attribute, then the type of the method argument will be an array of T (i.e., T[]). Otherwise, the type of the method argument will be T.
Editorial note

Recent versions of Java can actually do varargs.

Editorial note

Some overloaded operations in the IDL can correspond to a single method. This needs to be taken into account in this section. For example:

IDL
interface A {

  void f(in Object x);
  void f(in any x);
};

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 Raises clause of the operation, and no others.

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.

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.

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.

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.

Editorial note

Should say what happens if [Stringifies] is used on an interface that also has a toString operation.

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 Java value that is equivalent to the constant’s IDL 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.

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, Magnus Kristiansen, Lachlan Hunt, Anne van Kesteren, Jim Ley, Simon Pieters, Jonas Sicking, Maciej Stachowiak, 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]*
whitespace = [\t\n\r ]+|[\t\n\r ]*((//.*|/\*.*?\*/)[\t\n\r ]*)+
Editorial note

Should we require quoting (with an underscore) of identifiers that would match keywords used in OMG IDL 3.0 but not in this IDL?

When tokenizing, the longest possible match must be used. For example, if the input text is “a1”, it should be 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”.

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 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]ExtendedAttributeidentifier ExtendedAttributeDetails
[32]ExtendedAttributeDetails"=" ExtendedAttributeAssignment
 | "(" ArgumentList ")"
 | ε
[33]ExtendedAttributeAssignmentidentifier ExtendedAttributeAssignmentArguments
[34]ExtendedAttributeAssignmentArguments"(" ArgumentList ")"
 | ε
[35]DeclarationTypeUnsignedIntegerType
 | ScopedName
 | "any"
 | "boolean"
 | "octet"
 | "float"
 | "DOMString"
 | "Object"
[36]BoxedTypeUnsignedIntegerType
 | ScopedName
 | "boolean"
 | "octet"
 | "float"
 | "sequence" "<" Type ">"
[37]TypeDeclarationType
 | "sequence" "<" Type ">"
[38]UnsignedIntegerType"unsigned" IntegerType
 | IntegerType
[39]IntegerType"short"
 | "long" OptionalLong
[40]OptionalLong"long"
 | ε
[41]ReturnTypeDeclarationType
 | "void"
[42]ScopedNameListScopedName ScopedNames
[43]ScopedNames"," ScopedName ScopedNames
 | ε
[44]ScopedName"::" ScopedNameAfterColon
 | identifier ScopedNameParts
[45]ScopedNameAfterColonidentifier ScopedNameParts
 | "DOMString"
[46]ScopedNameParts"::" ScopedNamePartsAfterColon
 | ε
[47]ScopedNamePartsAfterColonidentifier ScopedNameParts
 | "DOMString"
Editorial note

Still not sure how we should handle extensibility of 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.
[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.

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.

C. Changes

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

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.