Blink‎ > ‎Web IDL in Blink‎ > ‎

Blink IDL Extended Attributes

Contents

  1. 1 Naming
  2. 2 Special cases
    1. 2.1 Constants
    2. 2.2 Overloaded methods
    3. 2.3 Special operations (methods)
    4. 2.4 Partial interfaces
    5. 2.5 implements
    6. 2.6 Inheritance
  3. 3 Standard Web IDL Extended Attributes
    1. 3.1 [Clamp] (a, p)
    2. 3.2 [Constructor] (i)
    3. 3.3 [DeprecateAs] (m, a)
    4. 3.4 [EnforceRange] (a,p)
    5. 3.5 [NamedConstructor] (i)
    6. 3.6 [NoInterfaceObject] (i)
    7. 3.7 [Global] and [PrimaryGlobal] (i)
    8. 3.8 [Exposed] (i)
    9. 3.9 [OverrideBuiltins] (i)
    10. 3.10 [PutForwards] (a)
    11. 3.11 [Replaceable] (a)
    12. 3.12 [TreatNullAs] (a,p), [TreatUndefinedAs] (a,p)
    13. 3.13 [Unforgeable] (m,a)
  4. 4 Common Blink-specific IDL Extended Attributes
    1. 4.1 [ActiveDOMObject] (i)
    2. 4.2 [PerWorldBindings] (m, a)
    3. 4.3 [LogActivity] (m, a)
    4. 4.4 [CallWith] (m, a)
    5. 4.5 [SetterCallWith] (a)
    6. 4.6 [ConstructorCallWith] (i)
      1. 4.6.1 [CallWith=ActiveWindow&FirstWindow] (m) (a*)
      2. 4.6.2 [CallWith=ThisValue] (m)
      3. 4.6.3 [ConstructorCallWith] (i)
    7. 4.7 [Custom] (i, m, s, a)
      1. 4.7.1 [Custom=PropertyQuery|PropertyEnumerator] (s)
      2. 4.7.2 [Custom=LegacyCallAsFunction] (i) deprecated
      3. 4.7.3 [Custom=ToV8] (i)
      4. 4.7.4 [Custom=VisitDOMWrapper] (i)
      5. 4.7.5 [Custom=Wrap] (i)
    8. 4.8 [CustomElementCallbacks] (m, a)
    9. 4.9 [Default] (p)
    10. 4.10 [DependentLifetime] (i)
    11. 4.11 [EventConstructor] (i)
    12. 4.12 [InitializedByEventConstructor] (a)
    13. 4.13 [MeasureAs] (m, a)
    14. 4.14 [NotEnumerable] (m, a, s)
    15. 4.15 [ReadOnly] (m)
    16. 4.16 [RaisesException] (i, m, a)
    17. 4.17 [Reflect] (a)
    18. 4.18 [ReflectEmpty="value"] (a)
    19. 4.19 [ReflectInvalid="value"] (a)
    20. 4.20 [ReflectMissing="value"] (a)
    21. 4.21 [ReflectOnly=<list>] (a)
    22. 4.22 [RuntimeEnabled] (i, m, a, c)
    23. 4.23 [SetWrapperReferenceFrom] (i)
    24. 4.24 [TypeChecking] (i, m, a)
    25. 4.25 [TreatReturnedNullStringAs] (m, a)
  5. 5 Rare Blink-specific IDL Extended Attributes
    1. 5.1 [CachedAttribute] (a)
    2. 5.2 [CheckSecurity] (i, m, a)
    3. 5.3 [DoNotCheckSecurity] (m, a)
    4. 5.4 [CustomConstructor] (i)
    5. 5.5 [KeepAttributeAliveForGC] (a)
    6. 5.6 [PerContextEnabled] (m, a)
    7. 5.7 [SpecialWrapFor] (i)
    8. 5.8 [URL] (a)
  6. 6 Temporary Blink-specific IDL Extended Attributes
    1. 6.1 [LegacyTreatAsPartialInterface] (i)
  7. 7 Discouraged Blink-specific IDL Extended Attributes
    1. 7.1 [DoNotCheckConstants] (i)
    2. 7.2 [ImplementedAs] (i, m, s, a)
  8. 8 Deprecated Blink-specific IDL Extended Attributes
    1. 8.1 [Conditional] (i,m,a) deprecated
    2. 8.2 [Immutable] (m, a), [DoNotCheckSignature] (m) possibly deprecated
  9. 9 Internal-use Blink-specific IDL Extended Attributes
    1. 9.1 [PartialInterfaceImplementedAs] (m, a, c)
  10. 10 Undocumented Blink-specific IDL Extended Attributes

The main interest in extended attributes are their semantics: Blink implements many more extended attributes than the Web IDL standard, to specify various behavior.

The authoritative list of allowed extended attributes and values is bindings/IDLExtendedAttributes.txt. This is complete but not necessarily precise (there may be unused extended attributes or values), since validation is run on build, but coverage isn't checked.

Syntactically, Blink IDL extended attributes differ from standard Web IDL extended attributes in three main ways:

  • trailing commas are allowed (for convenience),
  • key=value pairs can also be a list, separated by | or & as in: key=value1|value2 or key=value1&value2
  • the value of a key=value pair can be a string literal, not just an identifier: key="foo"
Blink IDL also does not support certain recent features of the Web IDL grammar:
  • Extended attribute value lists surrounded by parentheses and separated by commas are not supported (Web IDL production ExtendedAttributeIdentList); we've been using | or & as separators (without parentheses), but grammar has recently changed (see W3C bug 24959).
  • Values that are not identifiers or strings are not supported (the Other production): any non-identifier should simply be quoted (this could be changed to remove the need for quotes, but requires rather lengthy additions to the parser).
Semantically, only certain extended attributes allow lists, and whether
| or & is used depends on the extended attribute in question, depending on which is considered clearer; Conditional uses either | and & for OR/AND conditionals. To avoid confusion, these cannot be mixed: A|B|C and A&B&C are syntactically valid, but A|B&C is not. Similarly, only certain extended attributes allow string literals.

Extended attributes either take no value, take a required value, or take an optional value.

In the following explanations, (i), (m), (s), (a), (p), and (c) means that a given extended attribute can be specified on interfaces, methods, special operations, attributes, parameters, and constants, respectively. For example, (a,p) means that the IDL attribute can be specified on attributes and parameters.

Note that these restrictions are not enforced by the parser: extended attributes used in unsupported contexts will simply be ignored.

Naming

Extended attributes are named in UpperCamelCase, and are conventionally written as the name of the attribute within brackets, as [ExampleExtendedAttribute], per Web IDL typographic conventions.

There are a few rules in naming extended attributes:

  • Names should be aligned with the Web IDL spec as much as possible.
  • Extended attributes for custom bindings are prefixed by "Custom".

Lastly, please do not confuse "extended attributes", which go inside [...] and modify various IDL elements, and "attributes", which are of the form attribute foo and are interface members.

Special cases

Constants

Only the following (Blink-only) extended attributes apply to constants: [RuntimeEnabled] and [Reflect], and the interface extended attribute [DoNotCheckConstants] affects constants. [DeprecateAs] and [MeasureAs] do not work (Bug 358506).

Overloaded methods

Extended attributes mostly work normally on overloaded methods, affecting only that method (not other methods with the same name), but there are a few exceptions, due to all the methods sharing a single callback.

[RuntimeEnabled] works correctly on overloaded methods, both on individual overloads or (if specified on all method with that name) on the entire method (Bug 339000).

Note that while [DeprecateAs], [MeasureAs] only affect callback for non-overloaded methods, the logging code is instead put in the method itself for overloaded methods, so these can be placed on the method to log in question.

Extended attributes that affect the callback must be on the last overloaded method, though it is safest to put them on all the overloaded methods, for consistency (and in case they are rearranged or deleted). The source is bindings/templates/methods.cpp, and currently the only extended attribute that affect the callback (even for overloaded methods) is [PerWorldBindings] (affects callback and C++ method).

[PerContextEnabled] currently cannot be applied to individual overloaded methods; this is very rarely used, but if necessary should be easy to support in the same way as [RuntimeEnabled] (Bug 339000).

Special operations (methods)

Extended attributes on special operations (methods) are largely the same as those on methods generally, though many fewer are used.

Extended attributes that apply to the whole property (not a specific operation) must be put on the getter, since this is always present. There are currently two of these:
[Custom=PropertyQuery|PropertyEnumerator] and [NotEnumerable].
Anonymous special operations default to being implemented by a function named anonymousIndexedGetter etc.
[ImplementedAs] can be used if there is an existing Blink function to use to implement the operation, but you do not wish to expose a named operation. Otherwise you can simply put the special keyword in the line of the exposed normal operation.

For example:
[ImplementedAs=item] getter DOMString (unsigned long index);  // Does not add item() to the interface: only an indexed property getter
or:
getter DOMString item(unsigned long index);  // Use existing method item() to implement indexed property getter

[ImplementedAs] is also useful if you want an indexed property or named property to use an attribute. For example:    
attribute DOMString item;
[ImplementedAs=item] getter DOMString (unsigned long index);
[ImplementedAs=setItem] setter DOMString (unsigned long index);

There is one interface extended attribute that only affects special operations: [OverrideBuiltins].
The following extended attributes are used on special operations, as on methods generally: [RaisesException] and [TreatReturnedNullStringAs].

Partial interfaces

Extended attributes on partial interface members work as normal. However, only the following 4 extended attributes can be used on the partial interface itself; otherwise extended attributes should appear on the main interface definition:
[Conditional], [ImplementedAs], [PerContextEnabled] and [RuntimeEnabled]
3 of these are used to allow the entire partial interface to be selectively enabled or disabled: [Conditional], [PerContextEnabled] and [RuntimeEnabled], and function as if the extended attribute were applied to each member (methods, attributes, and constants). Style-wise, if the entire partial interface should be enabled or disabled, these extended attributes should be used on the partial interface, not on each individual member; this clarifies intent and simplifies editing. However:
  • If some members should not be disabled, this cannot be used on the partial interface; this is often the case for constants.
  • If different members should be controlled by different flags, this must be specified individually.
  • If a flag obviously applies to only one member of a single-member interface (i.e., it is named after that member), the extended attribute should be on the member.
The remaining extended attribute, [ImplementedAs], allows the implementation of the partial interface to be different than the implementation of the main interface; for members of the partial interface, this acts as if this [ImplementedAs=...] were specified on the interface, for only these members (overriding any existing value). This is stored internally via [PartialInterfaceImplementedAs] (see below).

implements

Extended attributes on members of an implemented interface work as normal. However, only the following 4 extended attributes can be used on the implemented interface itself; otherwise extended attributes should appear on the main (implementing) interface definition:
[ImplementedAs], [LegacyTreatAsPartialInterface],
[NoInterfaceObject]
and [RuntimeEnabled]
[LegacyTreatAsPartialInterface] is part of an ongoing change, as implemented interfaces used to be treated internally as partial interfaces.
[ImplementedAs] is only necessary for these legacy files: otherwise the class (C++) implementing (IDL) implemented interfaces does not need to be specified, as this is handled in Blink C++.

[RuntimeEnabled] behaves as for partial interfaces.
[NoInterfaceObject] is always specified on implemented interfaces.

Inheritance

Extended attributes are generally not inherited: only extended attributes on the interface itself are consulted. However, there are a handful of extended attributes that are inherited (applying them to an ancestor interface applies them to the descendants). These are extended attributes that affect memory management, and currently consists of [ActiveDOMObject] and [DependentLifetime]; the up-to-date list is compute_dependencies.INHERITED_EXTENDED_ATTRIBUTES.

Standard Web IDL Extended Attributes

These are defined in the ECMAScript-specific extended attributes section of the Web IDL spec, and alter the binding behavior.
Unsupported: [ArrayClass], [ImplicitThis], [LenientThis], [NamedPropertiesObject], [TreatNonCallableAsNull]

[Clamp] (a, p)

Summary: [Clamp] indicates that when an ECMAScript Number is converted to the IDL type, out of range values will be clamped to the range of valid values, rather than using the operators that use a modulo operation (ToInt32, ToUint32, etc.).

Usage: The [Clamp] extended attribute MUST NOT appear on a read only attribute, or an attribute, operation argument or dictionary member that is not of an integer type.

[Clamp] can be specified on writable attributes:

interface XXX {
    [Clamp] attribute unsigned short attributeName;
};

[Clamp] can be specified on extended attributes or methods arguments:

interface GraphicsContext {
    void setColor(octet red, octet green, octet blue);
    void setColorClamped([Clamp] octet red, [Clamp] octet green, [Clamp] octet blue);
};

Calling the non-[Clamp] version of setColor() uses ToUint8 to coerce the Numbers to octets. Hence calling context.setColor(-1, 255, 257) is equivalent to calling setColor(255, 255, 1).

Calling the [Clamp] version of setColor() uses clampTo() to coerce the Numbers to octets. Hence calling context.setColor(-1, 255, 257) is equivalent to calling setColorClamped(0, 255, 255).

[Constructor] (i)

Standard: ​The spec of Constructor

Summary: [Constructor] indicates that the interface should have a constructor, i.e. "new XXX()". 

Note: The Blink-specific [CallWith] and [RaisesException] extended attributes, specified on an interface, add information when the constructor callback is called.

Usage: [Constructor] can be specified on interfaces:

[
    Constructor(float x, float y, DOMString str),
]
interface XXX {
    ...
};

In the above, [Constructor(float x, float y, DOMString str)] means that the interface has a constructor and the constructor signature is (float x, float y, DOMString str). Specifically, JavaScript can create a DOM object of type XXX by the following code:

var x = new XXX(1.0, 2.0, "hello");

The Blink implementation must have the following method as a constructor callback:

PassRefPtr<XXX> XXX::create(float x, float y, String str)
{
    ...;
}

As shorthand, a constructor with no arguments can be written as [Constructor] instead of [Constructor()].

Whether you should allow an interface to have constructor depends on the spec of the interface.

Note: Currently [Constructor(...)] does not yet support optional arguments w/o defaults. It just supports optional [Default=Undefined] or optional [Default=NullString].

[DeprecateAs] (m, a)

Summary: Measures usage of a deprecated feature via UseCounter, and notifies developers about deprecation via a console warning.

[DeprecateAs] can be considered an extended form of [MeasureAs]: it both measures the feature's usage via the same UseCounter mechanism, and also sends out a warning to the console (optionally with a message) in order to inform developers that the code they've written will stop working at some point in the relatively near future.

Usage: [DeprecateAs] can be specified on methods and attributes; it does not work on constants (Bug 358506).

    [DeprecateAs=DeprecatedPrefixedAttribute] attribute Node prefixedAttribute;
    [DeprecateAs=DeprecatedPrefixedMethod] Node prefixedGetInterestingNode();
The deprecation message show on the console can be specified via the UseCounter::deprecationMessage method.

[EnforceRange] (a,p)

Standard: ​The spec of EnforceRange

Summary: [EnforceRange] indicates that when an ECMAScript Number is converted to the IDL type, out of range values will result in a TypeError exception being thrown.

Usage: The [EnforceRange] extended attribute MUST NOT appear on a read only attribute, or an attribute, operation argument or dictionary member that is not of an integer type.

[EnforceRange] can be specified on writable attributes:

interface XXX {
    [EnforceRange] attribute unsigned short attributeName;
};
[EnforceRange] can be specified on extended attributes on methods arguments:
interface GraphicsContext {
    void setColor(octet red, octet green, octet blue);
    void setColorEnforced([EnforceRange] octet red, [EnforceRange] octet green, [EnforceRange] octet blue);
};
Calling the non-[EnforceRange] version of setColor() uses ToUint8 to coerce the Numbers to octets. Hence calling context.setColor(-1, 255, 257) is equivalent to calling setColor(255, 255, 1).

Calling the [EnforceRange] version of setColorEnforced() with an out of range value, such as -1, 256, or Infinity will result in a TypeError exception.


[NamedConstructor] (i)

Standard: ​The spec of [NamedConstructor]

Summary: If you want to allow JavaScript to create a DOM object of XXX using a different name constructor (i.e. allow JavaScript to create an XXX object using "new YYY()", where YYY != XXX), you can use [NamedConstructor].

Usage: The possible usage is [NamedConstructor=YYY(...)]. Just as with constructors, an empty argument list can be omitted, as: [NamedConstructor=YYY][NamedConstructor] can be specified on interfaces. The spec allows multiple named constructors, but the Blink IDL compiler currently only supports at most one.

[
    NamedConstructor=Audio(DOMString data),
] interface HTMLAudioElement {
    ...
};

The semantics are the same as [Constructor], except that the name changes: JavaScript can make a DOM object by new Audio() instead of by new HTMLAudioElement().

Whether you should allow an interface to have a named constructor or not depends on the spec of each interface.

[NoInterfaceObject] (i)

Standard: The spec of NoInterfaceObject

Summary: 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. See also the standard [Exposed=xxx] extended attribute; these two do not change the generated code for the interface itself.

Note that every interface has a corresponding property on the ECMAScript global object, except:

  • callback interfaces with no constants, and
  • non-callback interface with the [NoInterfaceObject] extended attribute,

Usage: [NoInterfaceObject] can be specified on interfaces.

[
    NoInterfaceObject,
] interface XXX {
    ...
};

Note that [NoInterfaceObject] MUST be specified on testing interfaces, as follows:

[
    NoInterfaceObject, // testing interfaces do not appear on global objects
] interface TestingInterfaceX {
    ...
};

[Global] and [PrimaryGlobal] (i)

Spec: [Global]

Summary: The [Global] and [PrimaryGlobal] extended attributes can be used to give a name to one or more global interfaces, which can then be referenced by the [Exposed] extended attribute.

These extended attributes must either take no arguments or take an identifier list.

If the [Global] or [PrimaryGlobal] extended attribute is declared with an identifier list argument, then those identifiers are the interface’s global names; otherwise, the interface has a single global name, which is the interface's identifier.

[Exposed] (i)

Spec: [Exposed]

Summary: Indicates on which global object or objects (e.g., Window, WorkerGlobalScope) the interface property is generated, i.e., in which global scope or scopes an interface exists. This is primarily of interest for the constructor, i.e., the interface object Call method. Global context defaults to Window (the primary global scope) if not present, overridden by standard extended attribute [NoInterfaceObject] (the value of the property on the global object corresponding to the interface is called the interface object), which results in no interface property being generated.

As with [NoInterfaceObject] does not affect generated code for the interface itself, only the code for the corresponding global object. A partial interface is generated at build time, containing an attribute for each interface property on that global object.

All non-callback interfaces without [NoInterfaceObject] have a corresponding interface property on the global object. Note that in the Web IDL spec, callback interfaces with constants also have interface properties, but in Blink callback interfaces only have methods (no constants or attributes), so this is not applicable. [Exposed] can be used with different values to indicate on which global object or objects the property should be generated. Valid values are:

It is possible to have the global constructor generated on several interfaces by specifying several interface names and separating them with a '&', for e.g. [Exposed=Window&WorkerGlobalScope].

Usage: [Exposed] can be specified on interfaces that do not have the [NoInterfaceObject] extended attribute.

[
    Exposed=DedicatedWorker,
] interface XXX {
    ...
};

[
    Exposed=Window&Worker,
] interface YYY {
    ...
};

[OverrideBuiltins] (i)


Summary: Affects named property operations, making named properties shadow built-in properties of the object.

[PutForwards] (a)

Standard: The spec of PutForwards

Summary: Indicates that assigning to the attribute will have specific behavior. Namely, the assignment is “forwarded” to the attribute (specified by the extended attribute argument) on the object that is currently referenced by the attribute being assigned to.

Usage: Can be specified on readonly attributes:

[PutForwards=href] readonly attribute Location location;
On setting the location attribute, the assignment will be forwarded to the Location.href attribute.

[Replaceable] (a)

Standard: ​The spec of Replaceable

Summary: [Replaceable] controls if a given read only regular attribute is "replaceable" or not.

Usage: [Replaceable] can be specified on attributes:

interface DOMWindow {
    [Replaceable] readonly attribute long screenX;
};

[Replaceable] is incompatible with [Custom] and [Custom=Setter] (because replaceable attributes have a single interface-level setter callback, rather than individual attribute-level callbacks); if you need custom binding for a replaceable attribute, remove [Replaceable] and readonly.

Intuitively, "replaceable" means that you can set a new value to the attribute without overwriting the original value. If you delete the new value, then the original value still remains.

Specifically, a writable attribute, without [Replaceable], behaves as follows: 

window.screenX; // Evaluates to 0 
window.screenX = "foo"; 
window.screenX; // Evaluates to "foo" 
delete window.screenX; 
window.screenX; // Evaluates to undefined. 0 is lost.

A read only attribute, with [Replaceable], behaves as follows: 

window.screenX; // Evaluates to 0 
window.screenX = "foo"; 
window.screenX; // Evaluates to "foo" 
delete window.screenX; 
window.screenX; // Evaluates to 0. 0 remains.

Whether [Replaceable] should be specified or not depends on the spec of each attribute.

[TreatNullAs] (a,p), [TreatUndefinedAs] (a,p)

Standard: ​The spec of TreatNullAsTreatUndefinedAs has been been removed from the spec.

Summary: They control the behavior when a JavaScript null or undefined is passed to a DOMString attribute or parameter.

Implementation: Non-standard: Web IDL specifies the EmptyString identifier for both these extended attributes, and Null and Missing for TreatUndefinedAsBlink uses the NullString identifier instead of EmptyString which yields a Blink null string, corresponding to JavaScript null, for which both String::IsEmpty() and String::IsNull() return true, instead of the empty string "", which is empty but not null. This is for performance reasons; see Strings in Blink for reference. It also does not implement TreatUndefinedAs=Null or TreatUndefinedAs=Missing.

Further, both extended attributes are both overloaded for indexed setters and named setters, in which case they take a method name (?), though this usage is rare.

Usage: The possible usage is [TreatNullAs=NullString] or [TreatNullAs=NullString, TreatUndefinedAs=NullString]. They can be specified on DOMString attributes or DOMString parameters only:

[TreatNullAs=NullString] attribute DOMString str;
void func([TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString str);
[TreatNullAs=NullString] indicates that if a JavaScript null is passed to the attribute or parameter, then it is converted to a Blink null string, for which both String::IsEmpty() and String::IsNull() will return true. Without [TreatNullAs=NullString], a JavaScript null is converted to a Blink string "null".

[TreatNullAs=NullString] in Blink corresponds to [TreatNullAs=EmptyString] in the Web IDL spec. Unless the spec specifies [TreatNullAs=EmptyString], you should not specify [TreatNullAs=NullString] in Blink.

[TreatUndefinedAs=NullString] indicates that if a JavaScript undefined is passed to the attribute or parameter, then it is converted to a Blink null string, for which both String::IsEmpty() and String::IsNull() will return true. Without [TreatUndefinedAs=NullString], a JavaScript undefined is converted to a Blink string "undefined".

[TreatUndefinedAs=NullString] in Blink corresponds to [TreatUndefinedAs=EmptyString] in the Web IDL spec. Unless the spec specifies [TreatUndefinedAs=EmptyString], you should not specify [TreatUndefinedAs=NullString] in Blink.

Note: The sole usage of [TreatUndefinedAs=NullString] is not supported. [TreatUndefinedAs=NullString] must be used with [TreatNullAs=NullString], i.e. [TreatNullAs=NullString, TreatUndefinedAs=NullString].

[Unforgeable] (m,a)

Standard: ​The spec of Unforgeable

Summary: Controls where a getter/setter of a given attribute is defined.

Usage: Can be specified on methods or attributes:

[Unforgeable] void func();
[Unforgeable] attribute DOMString str;

By default, attribute getters/setters are defined on a DOM object, and methods are defined on a prototype chain (although the Web IDL spec requires that both attribute getters/setters and methods should be defined on a prototype chain).

If you want to explicitly control where an attribute getter/setter or a method is defined in V8, you can use [Unforgeable] to indicate that an attribute getter/setter or a method should be defined on a DOM object.

Note: As explained above, the current implementation of V8 is wrong with the Web IDL spec, and [Unforgeable] is used for hack. You should not use unless you have a strong reason.

Common Blink-specific IDL Extended Attributes

These extended attributes are widely used.

[ActiveDOMObject] (i)

Summary: [ActiveDOMObject] indicates that a given DOM object should be kept alive as long as the DOM object has pending activities.

Usage: [ActiveDOMObject] can be specified on interfaces, and is inherited:

[
    ActiveDOMObject,
] interface Foo {
    ...
};

If an interface X has [ActiveDOMObject] and an interface Y inherits the interface X, then the interface Y will also have [ActiveDOMObject]. For example

[
    ActiveDOMObject,
] interface Foo {};

interface Bar : Foo {};  // inherits [ActiveDOMObject] from Foo

If a given DOM object needs to be kept alive as long as the DOM object has pending activities, you need to specify [ActiveDOMObject]. For example, [ActiveDOMObject] can be used when the DOM object is expecting events to be raised in the future.

If you use [ActiveDOMObject], the corresponding Blink class needs to inherit ActiveDOMObject. For example, in case of XMLHttpRequest, core/xml/XMLHttpRequest.h would look like this: 

class XMLHttpRequest : public ActiveDOMObject
{
    ...; 
};

Then you need to implement the virtual methods of the ActiveDOMObject class, e.g. contextDestroyed(), canSuspend(), suspend(), resume() and stop().

[PerWorldBindings] (m, a)

Summary: Generates faster bindings code by avoiding check for isMainWorld().

This optimization only makes sense for wrapper-types (i.e. types that have a corresponding IDL interface), as we don't need to check in which world we are for other types. Note that this optimization works by generating 2 separate code paths for the main world and for isolated worlds. As a consequence, using this extended attribute will increase binary size and we should refrain from overusing it.

[LogActivity] (m, a)

Summary: logs activity, using V8PerContextData::activityLogger. Widely used. Interacts with [PerWorldBindings], [LogAllWorlds].

Usage:
Valid values for attributes are:
GetterOnly, SetterOnly, (no value)
Valid values for methods are:
(no value)
For methods all calls are logged, and by default for attributes all access (calls to getter or setter) are logged, but this can be restricted to just read (getter) or just write (setter).

[CallWith] (m, a)

[SetterCallWith] (a)

[ConstructorCallWith] (i)

Summary: [CallWith] indicates that the bindings code calls the Blink implementation with additional information.
Each value changes the signature of the Blink methods by adding an additional parameter to the head of the parameter list, such as &state for [CallWith=ScriptState].
Multiple values can be specified e.g. [CallWith=ScriptState|ScriptArguments]. The order of the values in the IDL file doesn't matter: the generated parameter list is always in a fixed order (specifically &state, scriptContext, scriptArguments.release(), if present, corresponding to ScriptState, ScriptExecutionContext, ScriptArguments, respectively).
There are also three rarely used values: ActiveWindow, FirstWindow, ThisValue.
[SetterCallWith] applies to attributes, and only affects the signature of the setter; this is only used in Location.idl, with ActiveWindow&FirstWindow.

Syntax:
CallWith=ScriptState|ScriptExecutionContext|ScriptArguments|ActiveWindow|FirstWindow|ThisValue

[CallWith=ScriptState] (m) (a*)

[CallWith=ScriptState] is used in a number of places for methods.

[CallWith=ScriptState] can be used for attributes, but is not used in real IDL files.

IDL example:

interface Example {
    [CallWith=ScriptState] attribute DOMString str;
    [CallWith=ScriptState] DOMString func(boolean a, boolean b);
};    
C++ Blink function signatures:
String Example::str(ScriptState* state);
String Example::func(ScriptState* state, bool a, bool b); 

[CallWith=ScriptExecutionContext] (m,a)

IDL example:

interface Example {
    [CallWith=ScriptExecutionContext] attribute DOMString str;
    [CallWith=ScriptExecutionContext] DOMString func(boolean a, boolean b);
};    
C++ Blink function signatures:
String Example::str(ScriptExecutionContext* context);
String Example::func(ScriptExecutionContext* context, bool a, bool b);

You can retrieve the document and frame from a ScriptExecutionContext*.

[CallWith=ScriptArguments] (m)

IDL example:

interface Example {
    [CallWith=ScriptState] DOMString func(boolean a, boolean b);
};    
C++ Blink function signature:
String Example::func(ScriptArguments* arguments, bool a, bool b); 
(rare CallWith values)

[CallWith=ActiveWindow&FirstWindow] (m) (a*)

FIXME: document!

Used only in one place (Location.idl), for methods and in [SetterCallWith]. Generally used together.

[CallWith=ThisValue] (m)

[CallWith=ThisValue] only applies to methods in callback interfaces, and is used in only one place (CSSVariablesMapForEachCallback.idl).

IDL example:

callback interface Example {
    [CallWith=ThisValue] boolean func(boolean a, boolean b);
};    
C++ Blink function signature:
bool Example::func(ScriptValue thisValue, bool a, bool b);

Note that [CallWith=...] arguments are added at the head of XXX::create(...)'s arguments, and the ExceptionCode argument is added at the tail of XXX::create(...)'s arguments.

[ConstructorCallWith] (i)

Analogous to [CallWith], but applied to interfaces with constructors, and takes different values.

If [Constructor] is specified on an interface, [ConstructorCallWith] can be also specified to refine the arguments passed to the callback:

[
    Constructor(float x, float y, DOMString str),
    ConstructorCallWith=Document|ExecutionContext,
]
interface XXX {
    ...
};

Then XXX::create(...) can have the following signature FIXME outdated:

PassRefPtr<XXX> XXX::create(ScriptExecutionContext* context, ScriptState* state, float x, float y, String str)
{
    ...;
}

You can retrieve document or frame from ScriptExecutionContext.

[Custom] (i, m, s, a)

Summary: They allow you to write bindings code manually as you like: full bindings for methods and attributes, certain functions for interfaces.

Custom bindings are strongly discouraged. They are likely to be buggy, a source of security holes, and represent a significant maintenance burden. Before using [Custom], you should doubly consider if you really need custom bindings. You are recommended to modify code generators and add specialized extended attributes or special cases if necessary to avoid using [Custom].

Usage: [Custom] can be specified on methods or attributes. [Custom=Getter] and [Custom=Setter] can be specified on attributes. [Custom=A|B] can be specified on interfaces, with various values (see below).

On read only attributes (that are not [Replaceable]), [Custom] is equivalent to [Custom=Getter] (since there is no setter) and [Custom=Getter] is preferred.

The bindings generator largely ignores the specified type information of [Custom] members (signature of methods and type of attributes), but they must be valid types. It is best if the signature exactly matches the spec, but if one of the types is an interface that is not implemented, you can use object as the type instead, to indicate "unspecified object type".

[Replaceable] is incompatible with [Custom] and [Custom=Setter] (because replaceable attributes have a single interface-level setter callback, rather than individual attribute-level callbacks); if you need custom binding for a replaceable attribute, remove [Replaceable] and readonly.

[Custom] void func();
[Custom] attribute DOMString str1;
[Custom=Getter] readonly attribute DOMString str2;
[Custom=Setter] attribute DOMString str3;

Before explaining the details, let us clarify the relationship of these IDL attributes.

  • [Custom] on a method indicates that you can write V8 custom bindings for the method.
  • [Custom=Getter] or [Custom=Setter] on an attribute means custom bindings for the attribute getter or setter.
  • [Custom] on an attribute means custom bindings for both the getter and the setter
You can write custom bindings in Source/bindings/v8/custom/V8XXXCustom.cpp:
 v8::Handle<v8::Value> V8XXX::funcCallback(const v8::Arguments& args)
 {
     ...;
 }
Attribute getter:
interface XXX {
    [Custom=Getter] attribute DOMString str;
};
You can write custom bindings in Source/bindings/v8/custom/V8XXXCustom.cpp:
v8::Handle<v8::Value> V8XXX::strAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
{
    ...;
}
Attribute setter:
interface XXX {
    [Custom=Setter] attribute DOMString str;
};

You can write custom bindings in Source/bindings/v8/custom/V8XXXCustom.cpp:

void V8XXX::strAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
 {
 ...;
 }
[Custom] may also be specified on special operations:
interface XXX {  // anonymous special operations
    [Custom] getter Node (unsigned long index);
    [Custom] setter Node (unsigned long index, Node value);
    [Custom] deleter boolean (unsigned long index);

    [Custom] getter Node (DOMString name);
    [Custom] setter Node (DOMString name, Node value);
    [Custom] deleter boolean (DOMString name);
}
interface YYY {  // special operations with identifiers
    [Custom] getter Node item(unsigned long index);
    [Custom] getter Node namedItem(DOMString name);
}

[Custom=PropertyQuery|PropertyEnumerator] (s)

Summary: [Custom=PropertyEnumerator] allows you to write custom bindings for the case where properties of a given interface are enumerated; a custom named enumerator. There is currently only one use, and in that case it is used with [Custom=PropertyQuery], since the query is also custom.

Usage: Can be specified on named property getters:

interface XXX {
    [Custom=PropertyQuery|PropertyEnumerator] getter Foo (DOMString name);
};

If the property getter itself should also be custom, specify [Custom=PropertyGetter] (this is the default, if no arguments are given).

interface XXX {
    [Custom=PropertyGetter|PropertyQuery|PropertyEnumerator] getter Foo (DOMString name);
};

You can write custom bindings as V8XXX::namedPropertyQuery(...) and V8XXX::namedPropertyEnumerator(...) in Source/bindings/v8/custom/V8XXXCustom.cpp:

v8::Handle<v8::Integer> V8XXX::namedPropertyQuery(v8::Local<v8::String> name, const v8::AccessorInfo& info)
{
    ...;
}

v8::Handle<v8::Array> V8XXX::namedPropertyEnumerator(const v8::AccessorInfo& info)
{
    ...;
}

[Custom=LegacyCallAsFunction] (i) deprecated

Summary: [Custom=LegacyCallAsFunction] allows you to write custom bindings for call(...) of a given interface.

Usage: [Custom=LegacyCallAsFunction] can be specified on interfaces:

[
    Custom=LegacyCallAsFunction,
] interface XXX {
    ...
};

If you want to write custom bindings for XXX.call(...), you can use [Custom=LegacyCallAsFunction].

You can write custom V8XXX::callAsFunctionCallback(...) in Source/bindings/v8/custom/V8XXXCustom.cpp:

v8::Handle<v8::Value> V8XXX::callAsFunctionCallback(const v8::Arguments& args)
{
    ...;
}

[Custom=ToV8] (i)

FIXME: Lets you specify a Custom ::toV8 function.

[Custom=VisitDOMWrapper] (i)

Summary: Allows you to write custom code for visitDOMWrapper: like [SetWrapperReferenceFrom], but does not generate the function. One use (Nodelist.idl).

Usage:

[
    Custom=VisitDOMWrapper,
] interface XXX {
    ...
};

And then in V8XXXCustom.cpp:

void V8XXX::visitDOMWrapper(DOMDataStore* store, void* object, v8::Persistent<v8::Object> wrapper)
{
    ...
}

[Custom=Wrap] (i)

FIXME: Lets you specify a Custom ::wrap function.

[CustomElementCallbacks] (m, a)

Summary: Wraps the method/accessor with a Custom Elements "callback delivery scope" which will dispatch Custom Element callbacks (createdCallback, attributeChangedCallback, etc.) before returning to script.

If the method/accessor creates elements or modifies DOM nodes in any way, it should be tagged with this extended attribute. Even if you're not a Node, this may apply to you! For example DOMTokenList.toggle can be reflected in the attribute of its associated element, so it needs to be tagged with CustomElementCallbacks. If the method/accessor only calls something that may modify the DOM (for example, it runs user script as a callback) you don't need to tag your method with [CustomElementCallbacks]; that is the responsibility of the binding that actually modifies the DOM. In general over-applying this extended attribute is safe, with one caveat:
  • This extended attribute MUST NOT be used on members that operate on non-main threads, because the callback delivery scope accesses statics.
  • Basically: Don't apply this extended attribute to anything that can be called from a worker.
  • This criterion (accessible by workers) depends on implementation and cannot easily be checked from the IDL or C++ headers (it includes obvious cases like [Exposed=Worker], where there is a constructor on the (JS) global object, but also cases where the C++ creates or accesses methods internally), so please be careful.
Usage: [CustomElementCallbacks] takes no arguments.

[Default] (p)

Summary: [Default] allows one to specify the default values for optional arguments. This removes the need to have C++ overloads in the Blink implementation. 

Standard: In Web IDL, default values for optional arguments are written as "optional type identifier = value", as in optional DOMString? str = null but Blink does not support this yet (Bug 258153), and instead you need to write [Default=NullString].

Usage: The possible usages are [Default=Undefined] or [Default=NullString][Default=Undefined] can be specified on any optional parameter. [Default=NullString] can be specified on DOMString parameters only:

interface HTMLFoo {
    void func1(int a, int b, optional int c, optional int d);
    void func2(int a, int b, [Default=Undefined] optional int c);
    void func3(int a, int b, [Default=Undefined] optional DOMString c, [Default=NullString] optional DOMString d);
}; 

The parameters marked with the standard Web IDL optional qualifier are optional, and JavaScript can omit the parameters. Obviously, if parameter X is marked with optional then all subsequent parameters of X should be marked with optional

The difference between optional and [Default=Undefined] optional is whether the Blink implementation has overloaded methods or not, as explained below: without a default value, the Blink implementation must have overloaded C++ functions, while with a default value, the Blink implementation only needs a single C++ function.

In case of func1(...), if JavaScript calls func1(100, 200), then HTMLFoo::func1(int a, int b) is called in Blink. If JavaScript calls func1(100, 200, 300), then HTMLFoo::func1(int a, int b, int c) is called in Blink. If JavaScript calls func1(100, 200, 300, 400), then HTMLFoo::func1(int a, int b, int c, int d) is called in Blink. In other words, if the Blink implementation has overloaded methods, you can use optional.

In case of func2(...) which adds [Default=Undefined]if JavaScript calls func2(100, 200), then it behaves as if JavaScript called func2(100, 200, undefined). Consequently, HTMLFoo::func2(int a, int b, int c) is called in Blink. 100 is passed to a, 200 is passed to b, and 0 is passed to c. (A JavaScript undefined is converted to 0, following the value conversion rule in the Web IDL spec.) In this way, Blink needs to just implement func2(int a, int b, int c) and needs not to implement both func2(int a, int b) and func2(int a, int b, int c).

The difference between [Default=Undefined] and [Default=NullString] appears only when the parameter type is DOMString. In [Default=Undefined]  the "supplemented" JavaScript undefined is converted to a Blink string "undefined". On the other hand, in [Default=NullString] the "supplemented" JavaScript undefined is converted to a Blink null string. For example, if JavaScript calls func3(100, 200), then HTMLFoo::func3(int a, int b, String c, String d) is called in Blink. At this point, 100 is passed to a, 200 is passed to b, a Blink string "undefined" is passed to c, and a Blink null string is passed to d. d.IsEmpty() and d.IsNull() return true.

[DependentLifetime] (i)

Summary: [DependentLifetime] means objects of this class are treated as dependent DOM objects.

Usage: [DependentLifetime] can be specified on interfaces, and is inherited:

[
    DependentLifetime,
] interface Foo { ... };

interface Bar : Foo { ... };  // inherits [DependentLifetime]

[EventConstructor] (i)

[InitializedByEventConstructor] (a)

Summary: They are used for Event constructors.

Usage: The possible usage is [EventConstructor] on the interface (Event interfaces only, meaning inherits Event, directly or indirectly (or is Event itself)), followed by [InitializedByEventConstructor] on some attributes:

[
    EventConstructor,
] interface FooEvent : Event {
    attribute DOMString str1;
    [InitializedByEventConstructor] attribute DOMString str2;
};

Since constructors for Event interfaces require special bindings, you need to use [EventConstructor] instead of normal [Constructor].

If you specify [EventConstructor] on FooEvent, JavaScript can create a DOM object of FooEvent in the following code:

var e = new FooEvent("type", { bubbles: true, cancelable: true });

Then FooEvent::create(...) is called in Blink. Specifically, Blink needs to implement the following method as a constructor callback:

PassRefPtr<FooEvent> FooEvent::create(const AtomicString& type, const FooEventInit& initializer) { ...; }

[InitializedByEventConstructor] should be specified on all the attributes that needs to be initialized by the constructor. Which attributes need initialization is defined in the spec of each Event interface. For example, look at ​the spec of Event. The EventInit dictionary has bubbles and cancelable, and thus bubbles and cancelable are the only attributes that need to be initialized by the Event constructor. In other words, in case of Event, you should specify [InitializedByEventConstructor] on bubbles and cancelable.

[MeasureAs] (m, a)

Summary: Measures usage of a specific feature via UseCounter.

In order to measure usage of specific features, Chrome submits anonymous statistics through the Histogram recording system for users who opt-in to sharing usage statistics. This extended attribute hooks up a specific feature to this measurement system. This is similar to the standard [DeprecateAs] extended attribute, but does not display a deprecation warning.

Usage: [MeasureAs] can be specified on methods and attributes; it does not work on constants (Bug 358506). The value must match one of the enumeration values in UseCounter::Feature (in core/frame/UseCounter.h).

[MeasureAs=AttributeWeAreInterestedIn] attribute Node interestingAttribute;
[MeasureAs=MethodsAreInterestingToo] Node getInterestingNode();

[NotEnumerable] (m, a, s)

[ReadOnly] (m)

FIXME: docs out of date!
Specification: ​The spec of Writable, Enumerable and Configurable (Section 8.6.1) - not standard Web IDL extended attributes.

Summary: They control Writability, Enumerability and Configurability of methods and attributes.

Usage: [NotEnumerable] can be specified on methods and attributes; [ReadOnly] can be specified on methods (MEANING??? Methods are not settable!), while for attributes the readonly keyword should be used instead.

[NotEnumerable] attribute DOMString str;
[NotEnumerable] void foo();
[ReadOnly] void bar();
  • [NotEnumerable] indicates that the method or attribute is not enumerable.
  • [ReadOnly] indicates that the method is read only
[NotEnumerable] is common, while [ReadOnly] is only used for a few attributes in Location.idl.

[RaisesException] (i, m, a)

Summary: Tells the code generator to append an ExceptionCode& argument when calling the Blink implementation.

Implementations may assign a DOMException code to this reference parameter, and the generated binding code will create and throw the appropriate exception type.

Usage: [RaisesException] can be specified on methods and attributes, [RaisesException=Getter] and [RaisesException=Setter] can be specified on attributes, and [RaisesException=Constructor] can be specified on interfaces where [Constructor] is also specified. On methods and attributes, the IDL looks like:

interface XXX {
    [RaisesException] attribute long count;
    [RaisesException=Getter] attribute long count1;
    [RaisesException=Setter] attribute long count2;
    [RaisesException] void foo();
};


And the Blink implementations would look like:
long XXX::count(ExceptionCode& ec) {
    if (...) {
        ec = TYPE_MISMATCH_ERROR;
        return;
    }
    ...;
}

void XXX::setCount(long value, ExceptionCode& ec) {
    if (...) {
        ec = TYPE_MISMATCH_ERROR;
        return;
    }
    ...;
}

void XXX::foo(ExceptionCode& ec) {
    if (...) {
        ec = TYPE_MISMATCH_ERROR;
        return;
    }
    ...;
};
If [RaisesException=Constructor] is specified on an interface and [Constructor] is also specified then an ExceptionCode& argument is added when calling the XXX::create(...) constructor callback.
[
Constructor(float x), RaisesException=Constructor, ] interface XXX { ... };

Blink needs to implement the following method as a constructor callback:

PassRefPtr<XXX> XXX::create(float x, ExceptionCode& ec)
{
    ...;
    if (...) {
        ec = TYPE_MATCH_ERR;
        return 0;
    }
    ...;
}

[Reflect] (a)

Specification: ​The spec of Reflect - defined in spec prose, not as an IDL extended attribute.

Summary: [Reflect] indicates that a given attribute should reflect the values of a corresponding content attribute.

Usage: The possible usage is [Reflect] or [Reflect=X], where X is the name of a corresponding content attribute. [Reflect] can be specified on attributes:

interface Element {
    [Reflect] attribute DOMString id;
    [Reflect=class] attribute DOMString className;
};

(Informally speaking,) a content attribute means an attribute on an HTML tag: <div id="foo" class="fooClass"></div>

Here 'id' and 'class' are content attributes.

If a given attribute in an IDL file is marked as [Reflect], it indicates that the attribute getter returns the value of the corresponding content attribute and that the attribute setter sets the value of the corresponding content attribute. In the above example, 'div.id' returns 'foo', and 'div.id = "bar"' sets "bar" to the 'id' content attribute.

If the name of the corresponding content attribute is different from the attribute name in an IDL file, you can specify the content attribute name by [Reflect=X]. For example, in case of [Reflect=class], if 'div.className="barClass"' is evaluated, then "barClass" is set to the 'class' content attribute.

Whether [Reflect] should be specified or not depends on the spec of each attribute.

[ReflectEmpty="value"] (a)

Specification: Enumerated attributes - defined in spec prose, not as an IDL extended attribute.

Summary: [ReflectEmpty="value"] gives the attribute keyword value to reflect when an attribute is present, but without a value; it supplements [ReflectOnly] and [Reflect].

Usage: The possible usage is [ReflectEmpty="value"] in combination with [ReflectOnly]:

interface HTMLMyElement {
    [Reflect, ReflectOnly="for"|"against", ReflectEmpty="for"] attribute DOMString vote;
};

The [ReflectEmpty] extended attribute specifies the value that an IDL getter for the 'vote' attribute should return when the content attribute is present, but without a value (e.g., return "for" when accessing the "vote" IDL attribute on "<my-element vote/>".) Its (string) literal value must be one of the possible values that the [ReflectOnly] extended attribute lists.

[ReflectEmpty] should be used if the specification for the content attribute has an empty attribute value mapped to some attribute state. For HTML, this applies to enumerated attributes only.

[ReflectInvalid="value"] (a)

Specification: Limited value attributes - defined in spec prose, not as an IDL extended attribute.

Summary: [ReflectInvalid="value"] gives the attribute keyword value to reflect when an attribute has an invalid/unknown value. It supplements [ReflectOnly] and [Reflect].

Usage: The possible usage is [ReflectInvalid="value"] in combination with [ReflectOnly]:

interface HTMLMyElement {
    [Reflect, ReflectOnly="left"|"right", ReflectInvalid="left"] attribute DOMString direction;
};

The [ReflectInvalid] extended attribute specifies the value that an IDL getter for the 'direction' attribute should return when the content attribute has an unknown value (e.g., return "left" when accessing the "direction" IDL attribute on "<my-element direction=dont-care />".) Its (string) literal value must be one of the possible values that the [ReflectOnly] extended attribute lists.

[ReflectInvalid] should be used if the specification for the content attribute has an invalid value state defined. For HTML, this applies to enumerated attributes only.

[ReflectMissing="value"] (a)

Specification: Limited value attributes - defined in spec prose, not as an IDL extended attribute.

Summary: [ReflectMissing="value"] gives the attribute keyword value to reflect when an attribute isn't present. It supplements [ReflectOnly] and [Reflect].

Usage: The possible usage is [ReflectMissing="value"] in combination with [ReflectOnly]:

interface HTMLMyElement {
    [Reflect, ReflectOnly="ltr"|"rtl"|"auto", ReflectMissing="auto"] attribute DOMString preload;
};

The [ReflectMissing] extended attribute specifies the value that an IDL getter for the 'direction' attribute should return when the content attribute is missing (e.g., return "auto" when accessing the "preload" IDL attribute on "<my-element>".) Its (string) literal value must be one of the possible values that the [ReflectOnly] extended attribute lists.

[ReflectMissing] should be used if the specification for the content attribute has a missing value state defined. For HTML, this applies to enumerated attributes only.

[ReflectOnly=<list>] (a)

Specification: ​Limited value attributes - defined in spec prose, not as an IDL extended attribute.

Summary: [ReflectOnly=<list>] indicates that a reflected string attribute should be limited to a set of allowable values; it supplements [Reflect].

Usage: The possible usage is [ReflectOnly="A1"|...|"An"] where A1 (up to n) are the attribute values allowed. [ReflectOnly=<list>] is used in combination with [Reflect]:

interface HTMLMyElement {
    [Reflect, ReflectOnly="on"] attribute DOMString toggle;
    [Reflect=q, ReflectOnly="first"|"second"|"third"|"fourth"] attribute DOMString quarter;
};

The ReflectOnly attribute limits the range of values that the attribute getter can return from its reflected attribute. If the content attribute has a value that is a case-insensitive match for one of the values given in the ReflectOnly's list (using "|" as separator), then it will be returned. To allow attribute values that use characters that go beyond what IDL identifiers may contain, string literals are used. This is a Blink syntactic extension to extended attributes.

If there is no match, the empty string will be returned. As required by the specification, no such checking is performed when the reflected IDL attribute is set.

[ReflectOnly=<list>] should be used if the specification for a reflected IDL attribute says it is "limited to only known values".

[RuntimeEnabled] (i, m, a, c)

Summary: [RuntimeEnabled] wraps the generated code with if (RuntimeEnabledFeatures::FeatureNameEnabled) { ...code... }.

Usage: [RuntimeEnabled=FeatureName]. FeatureName must be included in RuntimeEnabledFeatures.in.
[
    RuntimeEnabled=Media,
] interface HTMLAudioElement : HTMLMediaElement {};
Only when the feature is enabled at runtime (using a command line flag, for example, or when it is enabled only in certain platforms), the binding would be exposed to the web.

[RuntimeEnabled] cannot be applied to arguments, as this changes signatures and method resolution and is both very confusing to reason about and implement. For example, what does it mean to mark a required argument as [RuntimeEnabled]? You probably want to apply it only to optional arguments, which are equivalent to overloads. Thus instead apply [RuntimeEnabled] to the method, generally splitting a method in two. For example, instead of:
foo(long x, [RuntimeEnabled=FeatureName] optional long y); // Don't do this!
do:
// Overload can be replaced with optional if [RuntimeEnabled] is removed
foo(long x);
[RuntimeEnabled=FeatureName] foo(long x, long y);

For more information, see RuntimeEnabledFeatures.

[SetWrapperReferenceFrom] (i)

Summary: This generates code that allows you to set up implicit references between wrappers which can be used to keep wrappers alive during GC.

Usage: [SetWrapperReferenceFrom] can be specified on an interface. Use [Custom=VisitDOMWrapper] instead if want to write a custom function.

[
    SetWrapperReferenceFrom=element,
] interface XXX {
    ...
};

The code generates a function called XXX::visitDOMWrapper which is called by V8GCController before GC. The function adds implicit references to the wrapper which keeps it alive.

The extended attribute takes a value, which is the function to call to get the object that determines whether the object is reachable or not. The currently valid values are: document, element, owner, ownerNode

[TypeChecking] (i, m, a)

Summary: Implements type checking per spec (ECMAScript type mapping). By default Blink bindings do not perform type checking on values passed as arguments or when setting, and even assume that returned values from methods and setters may always be null! (Bug 321518). This extended attribute forces (some) type checking, per spec, raising TypeError on failure.

Usage: [TypeChecking] can be specified on interfaces, attributes, and methods. If on an interface, it applies to all members; if on an attribute, it applies to getter and setter; if on a method, it applies to all parameters and the return value. Valid values are Interface, Nullable, and Unrestricted (in progress: Bug 354298):

[TypeChecking=Interface|Nullable] attribute Foo? x;
[TypeChecking=Unrestricted] attribute double d;
[TypeChecking=Interface|Nullable] Foo f(Bar? x);
[TypeChecking=Unrestricted] void g(double d);

[TreatReturnedNullStringAs] (m, a)

Summary: [TreatReturnedNullStringAs] controls the behavior when a Blink null string is returned from the Blink implementation.

Usage: The possible usage is [TreatReturnedNullStringAs=Null], [TreatReturnedNullStringAs=Undefined]. They can be specified on DOMString attributes or methods that return a DOMString value:

[TreatReturnedNullStringAs=Null] attribute DOMString str;
[TreatReturnedNullStringAs=Undefined] DOMString func();
  • [TreatReturnedNullStringAs=Null] indicates that if the returned DOMString is a Blink null string, the returned value is treated as a JavaScript null.
  • [TreatReturnedNullStringAs=Undefined] indicates that if the returned DOMString is a Blink null string, the returned value is treated as a JavaScript undefined.

Without [TreatReturnedNullStringAs=...], if the returned DOMString is a Blink null string, then the returned value is treated as a JavaScript empty string.

Note that what should be specified on [TreatReturnedNullStringAs=...] depends on the spec of each attribute or method.

Rare Blink-specific IDL Extended Attributes

These extended attributes are rarely used, generally only in one or two places. These are often replacements for [Custom] bindings, and may be candidates for deprecation and removal.

[CachedAttribute] (a)

Summary: For performance optimization, [CachedAttribute] indicates that a wrapped object should be cached on a DOM object. Rarely used (only by IndexDB).

Usage: [CachedAttribute] can be specified on attributes, and takes a required value, generally called is*Dirty (esp. isValueDirty):

interface HTMLFoo {
    [CachedAttribute=isKeyDirty] attribute DOMString key;
    [CachedAttribute=isValueDirty] attribute SerializedScriptValue serializedValue;
};

Without [CachedAttribute], the key getter works in the following way:

  1. HTMLFoo::key() is called in Blink.
  2. The result of HTMLFoo::key() is passed to toV8(), and is converted to a wrapped object.
  3. The wrapped object is returned.

In case where HTMLFoo::key() or the operation to wrap the result is costly, you can cache the wrapped object onto the DOM object. With CachedAttribute, the key getter works in the following way:

  1. If the wrapped object is cached, the cached wrapped object is returned. That's it.
  2. Otherwise, HTMLFoo::key() is called in Blink.
  3. The result of HTMLFoo::key() is passed to toV8(), and is converted to a wrapped object.
  4. The wrapped object is cached.
  5. The wrapped object is returned.

[CachedAttribute] is particularly useful for serialized values, since deserialization can be costly. Without [CachedAttribute], the serializedValue getter works in the following way:

  1. HTMLFoo::serializedValue() is called in Blink.
  2. The result of HTMLFoo::serializedValue() is deserialized.
  3. The deserialized result is passed to toV8(), and is converted to a wrapped object.
  4. The wrapped object is returned.

In case where HTMLFoo::serializedValue(), the deserialization or the operation to wrap the result is costly, you can cache the wrapped object onto the DOM object. With [CachedAttribute], the serializedValue getter works in the following way:

  1. If the wrapped object is cached, the cached wrapped object is returned. That's it.
  2. Otherwise, HTMLFoo::serializedValue() is called in Blink.
  3. The result of HTMLFoo::serializedValue() is deserialized.
  4. The deserialized result is passed to toJS() or toV8(), and is converted to a wrapped object.
  5. The wrapped object is cached.
  6. The wrapped object is returned.

Note that you should cache attributes if and only if it is really important for performance. Not only does caching increase the DOM object size, but also it increases the overhead of "cache-miss"ed getters. In addition, setters always need to invalidate the cache.

[CachedAttribute] takes a required parameter which the name of a method to call on the implementation object. The method should take void and return bool. Before the cached attribute is used, the method will be called. If the method returns true the cached value is not used, which will result in the accessor being called again. This allows the implementation to both gain the performance benefit of caching (when the conversion to a script value can be done lazily) while allowing the value to be updated. The typical use pattern is:

// Called internally to update value
void Object::setValue(Type data)
{
    m_data = data;
    m_attributeDirty = true;
}

// Called by generated binding code
bool Object::isAttributeDirty()
{
    return m_attributeDirty;
}

// Called by generated binding code if no value cached or isAttributeDirty() returns true
ScriptValue Object::attribute(ScriptExecutionContext* context)
{
    m_attributeDirty = false;
    return convertDataToScriptValue(m_data);
}

[CheckSecurity] (i, m, a)

[DoNotCheckSecurity] (m, a)

Summary: Check whether a given access is allowed or not, in terms of the same-origin security policy. Used in Location.idl, Window.idl, and a few HTML*Element.idl.

If the security check is necessary, you should specify [CheckSecurity]. This is very important for security.

Usage: [CheckSecurity=Frame] can be specified on interfaces, which enables a frame security check for all members (methods and attributes) of the interface. This can then be selectively disabled with [DoNotCheckSecurity]; this is only done in Location.idl and Window.idl. On attributes, [DoNotCheckSecurity] takes an optional identifier, as [DoNotCheckSecurity=Setter] (used only one place, Location.href, since setting href changes the page, which is ok, but reading href leaks information).

  • [DoNotCheckSecurity] on a method disables the security check for the method.
  • [DoNotCheckSecurity] on an attribute disables the security check for a getter and setter of the attribute; for read only attributes this is just the getter.
  • [DoNotCheckSecurity=Setter] on an attribute disables the security check for a setter of the attribute, but not the getter.

[
    CheckSecurity=Frame,
] interface DOMWindow {
    attribute DOMString str1;
    [DoNotCheckSecurity] attribute DOMString str2;
    [DoNotCheckSecurity=Setter] attribute DOMString str3;
    void func1();
    [DoNotCheckSecurity] void func2();
};
Consider the case where you access window.parent from inside an iframe that comes from a different origin. While it is allowed to access window.parent, it is not allowed to access window.parent.document. In such cases, you need to specify [CheckSecurity] in order to check whether a given DOM object is allowed to access the attribute or method, in terms of the same-origin security policy.

[CheckSecurity=Node] can be specified on methods and attributes, which enables a node security check on that member. In practice all attribute uses are read only, and method uses all also have [RaisesException]:
[CheckSecurity=Node] readonly attribute Document contentDocument;
[CheckSecurity=Node] SVGDocument getSVGDocument();
In terms of the same-origin security policy, node.contentDocument should return undefined if the parent frame and the child frame are from different origins.

[CustomConstructor] (i)

Summary: They allow you to write custom bindings for constructors.

Usage: They can be specified on interfaces. Strongly discouraged. As with [Custom], it is generally better to modify the code generator. Incompatible with [Constructor] – you cannot mix custom constructors and generated constructors.

[
    CustomConstructor(float x, float y, optional DOMString str),
] interface XXX {
    ...
};

Note that the arguments of the constructor MUST be specified so that the length property of the interface object is properly set, even though they do not affect the signature of the custom Blink code. Multiple [CustomConstructor] extended attributes are allowed; if you have overloading, this is good style, as it documents the interface, though the only effect on generated code is to change length (you need to write overload resolution code yourself).

Consider the following example:
[
    CustomConstructor(float x, float y, optional DOMString str),
] interface XXX {
    ...
};

Then you can write custom bindings in Source/bindings/v8/custom/V8XXXConstructorCustom.cpp:

v8::Handle<v8::Value> V8XXX::constructorCallback(const v8::Arguments& args)
{
   ...;
}

[KeepAttributeAliveForGC] (a)

Summary: [KeepAttributeAliveForGC] forces the attribute wrapper to be kept alive. Used in only one place, may be removed when we implement [ReachableFrom] and [ReachableTo].

This behavior is default for read only attributes of wrapper type (interface types, with some exceptions), with some exceptions.
For performance reasons we keep the attribute wrapper alive while the owner wrapper is alive, because the attribute never changes.

Usage: Applies to attributes, takes no arguments.

[PerContextEnabled] (m, a)

Summary: [PerContextEnabled] allows one to enable or disable given features for extensions or apps.

Valid values for [PerContextEnabled] are Context Features, in the ContextFeatures::FeatureType enumeration in ContextFeatures.h. Note that there is some overlap of Context Features with Runtime Enabled Features, but Context Features are not a subset of Runtime Enabled Features.

Usage: Applies to methods or attributes, takes one argument (a Context Feature name).

[SpecialWrapFor] (i)

Summary: [SpecialWrapFor] allows a base class to specialize its wrap() method to return subclass wrappers.

Usage: [SpecialWrapFor] can be specified on interfaces. It takes a list of other IDL interfaces as arguments:

[
    SpecialWrapFor=HTMLDocument|SVGDocument,
] interface Document : Node {
    ...
};
It requires that the interface it's being applied to (in this case Document) has methods of the form isSpecifiedInterface() (in this case, isHTMLDocument and isSVGDocument) which return true iff the instance is of that subtype. This allows IDL attributes that return objects with the base interface's type to be wrapped properly without custom code.

[URL] (a)

Summary: [URL] indicates that a given DOMString represents a URL.

Usage: [URL] can be specified on DOMString attributes that have [Reflect] extended attribute specified only:

[Reflect, URL] attribute DOMString url;

You need to specify [URL] if a given DOMString represents a URL, since getters of URL attributes need to be realized in a special routine in Blink, i.e. Element::getURLAttribute(...). If you forgot to specify [URL], then the attribute getter might cause a bug.

Only used in some HTML*ELement.idl files and one other place.

Temporary Blink-specific IDL Extended Attributes

These extended attributes are temporary and are only in use while some change is in progress. Unless you are involved with the change, you can generally ignore them, and should not use them.
  • [ExposeJSAccessors] – used in transition to expose accessors on the JS objects, as part of moving to prototype chain (haraken@)

[LegacyTreatAsPartialInterface] (i)

Summary: [LegacyTreatAsPartialInterface] on an interface that is the target of an implements statement means that the interface is treated as a partial interface, meaning members are accessed via static member functions in a separate class, rather than as instance methods on the instance object *impl or class methods on the C++ class implementing the (main) interface. This is legacy from original implementation of implements, and is being removed (Bug 360435, nbarth@).

Discouraged Blink-specific IDL Extended Attributes

These extended attributes are discouraged – they are not deprecated, but they should be avoided and removed if possible.

[DoNotCheckConstants] (i)

Summary: [DoNotCheckConstants] indicates that constant values in an IDL file can be different from constant values in Blink implementation.

Usage: [DoNotCheckConstants] can be specified on interfaces:

[
    DoNotCheckConstants,
] interface XXX {
    const unsigned short NOT_FOUND_ERR = 12345;
    const unsigned short SYNTAX_ERR = 12346;
};

By default (i.e. without [DoNotCheckConstants]), compile-time assertions are inserted to check if the constant values defined in IDL files are equal to the constant values in Blink implementation. In the above example, if NOT_FOUND_ERR were implemented as 100 in Blink, the build will fail.

Note that basically all constant values are defined in the spec, and thus the values in Blink implementation should be equal to the values defined in the spec. If you really want to introduce non-speced constant values and allow different values between IDL files and Blink implementation, you can specify [DoNotCheckConstants] to skip the compile-time assertions.

[ImplementedAs] (i, m, s, a)

Summary: [ImplementedAs] specifies a method name in Blink, if the method name in an IDL file and the method name in Blink are different.

[ImplementedAs] is discouraged. Please use only if absolutely necessary: rename Blink internal names to align with IDL.

Usage: The possible usage is [ImplementedAs=XXX], where XXX is a method name in Blink. [ImplementedAs] can be specified on interfaces, methods and attributes.

[
    ImplementedAs=DOMPath,
] interface Path {
    [ImplementedAs=classAttribute] attribute int class;
    [ImplementedAs=deleteFunction] void delete();
}; 

Method names in Blink default to being the same as the name in an IDL file. In some cases this is not possible, e.g., delete is a C++ reserved word. In such cases, you can explicitly specify the method name in Blink by [ImplementedAs]. Generally the [ImplementedAs] name should be in lowerCamelCase. You should not use [ImplementedAs] simply to avoid renaming Blink methods.

Deprecated Blink-specific IDL Extended Attributes

These extended attributes are deprecated, or are under discussion for deprecation. They should be avoided.

[Conditional] (i,m,a) deprecated

FIXME: Should remove this extended attribute in favor of runtime flag control

Summary: [Conditional] inserts "#if ENABLE(SOME_FLAG) ... #endif" into the generated code.

Usage: [Conditional] can be specified on interfaces, methods and attributes.

[Conditional] is inherited: if [Conditional] is specified on an interface, it means that [Conditional] is specified on all attributes and methods of the interface.

Multiple values can be combined by either & or | (meaning AND or OR, as usual), as in [Conditional=Foo&Bar] (used one place: NavigatorContentUtils.idl:[Conditional=NAVIGATOR_CONTENT_UTILS&CUSTOM_SCHEME_HANDLER]), or [Conditional=Foo|Bar], which is not in actual use.

[
    Conditional=INDEXED_DATABASE,
] interface XXX {
    ...
};
interface XXX {
    [Conditional=INDEXED_DATABASE] attribute DOMString str;
    [Conditional=INDEXED_DATABASE] void open();
};

[Conditional] is used to enable or disable the generated code based on a "flag". If a given flag is enabled, the generated code is compiled. Otherwise, the generated code is not compiled. Whether a flag is enabled or disabled is controlled (mostly) by Tools/Scripts/build-webkit.

[Immutable] (m, a), [DoNotCheckSignature] (m) possibly deprecated

Might be deprecated. Discussion is on-going.
[Immutable] is only used 3 places: WebKitCSSMatrix (m), SVGMatrix (m), and SVGZoomEvent (a).
[DoNotCheckSignature] is used only 1 place: Window.

Internal-use Blink-specific IDL Extended Attributes

These extended attributes are added internally by the compiler, and not intended to be literally included in .idl files; they are documented here for clarity and completeness.

[PartialInterfaceImplementedAs] (m, a, c)

Added to members of a partial interface definition (and implemented interfaces with [LegacyTreatAsPartialInterface], due to Bug 360435) when merging .idl files for two reasons. Firstly, these members are implemented in a separate class from the class for the (main) interface definition, so this name data is needed. This is most clearly written as an extended attribute on the partial interface definition, but this is discarded during merging (only the members are merged, into flat lists of methods, attributes, and constants), and thus this extended attribute is put on the members. Secondly, members of partial interface definitions are called differently (via static member functions of the separate class, not instance methods or class methods of the main class), and thus there needs to be a flag indicating that the member comes from a partial interface definition.

Undocumented Blink-specific IDL Extended Attributes

FIXME: The following need documentation:
  • [PerWorldBindings] :: interacts with [LogActivity]
  • [OverrideBuiltins] :: used on named accessors
  • [SetWrapperReferenceTo] :: ??

Derived from: http://trac.webkit.org/wiki/WebKitIDL Licensed under BSD:

BSD License

Copyright (C) 2009 Apple Inc. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 

Comments