wiki:WebKitIDL

Version 36 (modified by haraken@chromium.org, 12 years ago) (diff)

--

Overview

The Web IDL is a language that defines how WebCore interfaces are bound to external languages such as JavaScriptCore, V8, ObjC, GObject and CPP. We need to write IDL files (e.g. XMLHttpRequest.idl, Element.idl, etc) to expose WebCore interfaces to those external languages. When WebKit is built, the IDL files are parsed, and the code to bind WebCore implementations and JavaScriptCore/V8/ObjC/GObject/CPP interfaces is automatically generated.

This page describes practical information about how the IDL binding works and how we can write IDL files in WebKit. The syntax of IDL files is fairly well documented in the Web IDL spec, but it is too formal to read:-) and there are several differences between the Web IDL spec and the WebKit IDL due to implementation issues.

Basics of the IDL

How the IDL bindings work

By reading this document, you can know how IDL attributes work. However, the best practice to understand IDL attributes is to use some IDL attributes and watch the bindings code actually generated.

If you touch any IDL file, all IDL files are rebuilt. The code generation is done at the very early phase of the ./webkit-build command, and you can find the generated code in 1 minute.

In case of XXX.idl, the bindings code is generated in the following files in the Release build ("Release" becomes "Debug" in the Debug build).

  • JavaScriptCore: WebKitBuild/Release/DerivedSources/WebCore/JSXXX.h, WebKitBuild/Release/DerivedSources/WebCore/JSXXX.cpp
  • V8: out/Release/obj/gen/webkit/bindings/V8XXX.h, out/Release/obj/gen/webcore/bindings/V8XXX.cpp
  • ObjC: WebKitBuild/Release/DerivedSources/WebCore/DOMXXX.h, WebKitBuild/Release/DerivedSources/WebCore/DOMXXX.cpp
  • GObject: WebKitBuild/Release/DerivedSources/webkit/WebKitDOMXXX.h, WebKitBuild/Release/DerivedSources/webkit/WebKitDOMXXX.cpp
  • CPP:

IDL attributes

Basic naming rules

IDL attributes around methods, attributes and parameters

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

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

Summary: They control the behavior when a JavaScript null or undefined is passed to DOMString attributes/parameters.

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

    attribute [TreatNullAs=NullString] DOMString str;
    void func(in [TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString str);

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

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

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

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

Note: For now the sole usage of [TreatUndefinedAs=NullString] is not allowed in WebKit. [TreatUndefinedAs=NullString] must be used with [TreatNullAs=NullString], i.e. [TreatNullAs=NullString, TreatUndefinedAs=NullString].

* [TreatReturnedNullStringAs](m,a)

Summary: It controls the behavior when a WebKit null string is returned.

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

    attribute [TreatReturnedNullStringAs=Null] DOMString str;
    [TreatReturnedNullStringAs=Undefined] DOMString func();

[TreatReturnedNullStringAs=Null] indicates that if the returned string is a WebKit null string, the returned value is converted to a JavaScript null.

[TreatReturnedNullStringAs=Undefined] indicates that if the returned string is a WebKit null string, the returned value is converted to a JavaScript undefined.

[TreatReturnedNullStringAs=False] indicates that if the returned string is a WebKit null string, the returned value is converted to a JavaScript false.

Without [TreatReturnedNullStringAs=...], if the returned string is a WebKit null string, the returned value becomes a JavaScript empty string . Note that what should be specified depends on the spec of each attribute or method.

* [Optional](p)

Summary: It allows method overloading for methods whose argument count are different with each other.

Usage: The possible usage is [Optional], [Optional=DefaultIsUndefined] or [Optional=DefaultIsNullString]. [Optional] and [Optional=DefaultIsUndefined] can be specified on parameters. [Optional=DefaultIsNullString] can be specified on DOMString parameters:

    interface HTMLFoo {
        void func1(in int a, in int b, in [Optional] int c, in [Optional] int d);
        void func2(in int a, in int b, in [Optional=DefaultIsUndefined] int c);
        void func3(in int a, in int b, in [Optional=DefaultIsUndefined] DOMString c, in [Optional=DefaultIsNullString] DOMString d);
    }

The parameters marked with [Optional=...] are optional, and JavaScript can omit the parameters. Obviously, if parameter X is marked with [Optional=...], then all subsequent parameters of X must be marked with [Optional=...]. The difference between [Optional] and [Optional=DefaultIsUndefined] is whether your WebCore implementation has overloaded methods or not, as explained below.

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

In case of func2(...), if JavaScript calls func2(100, 200), then it behaves as if JavaScript called func2(100, 200, undefined, undefined). Consequently, HTMLFoo::func1(int a, int b, int c, int d) is called in WebCore. 100 is passed to a, 200 is passed to b, 0 is passed to c, and 0 is passed to d. (A JavaScript undefined is converted to 0, following the value conversion rule in the Web IDL spec.) In this way, WebCore needs to implement func2(int a, int b, int c, int d) only, and needs not to implement overloaded methods like func2(int a, int b) or func2(int a, int b, int c).

The difference between [Optional=DefalutIsUndefined] and [Optional=DefaultIsNullString] appears only when the parameter type is DOMString. While in [Optional=DefalutIsUndefined] the "supplemented" JavaScript undefined is converted to a WebKit string "undefined", in [Optional=DefaultIsNullString] the "supplemented" JavaScript undefined is converted to a WebKit null string. Specifically, if JavaScript calls func3(100, 200), then HTMLFoo::func3(int a, int b, String c, String d) is called in WebCore. Here 100 is passed to a, 200 is passed to b, a WebKit string "undefined" is passed to c, and a WebKit null string is passed to d.

* [Callback](i,p) FIXME

Summary: ADD SUMMARY

Usage: [Callback] can be specified on interfaces and parameters:

    interface [
        Callback
    ] HTMLFoo {
        void func(in int a, in [Callback] int b);
    }

ADD EXPLANATIONS

* [Custom](m,a), [JSCustom](m,a), [V8Custom](m,a), [CustomGetter](a), [JSCustomGetter](a), [V8CustomGetter](a), [CustomSetter](a), [JSCustomSetter](a), [V8CustomSetter](a)

Summary: If your bindings require special (i.e. "custom") handling, you can write the bindings code as you like.

Usage: [Custom], [JSCustom] and [V8Custom] can be specified on methods or attributes. [CustomGetter], [JSCustomGetter], [V8CustomGetter], [CustomSetter], [JSCustomSetter], [V8CustomSetter] can be specified on attributes:

    [Custom] void func();
    attribute [CustomGetter, JSCustomSetter] DOMString str;

We should minimize the number of custom bindings as less as possible. Before using [Custom], you should doubly consider if you really need custom bindings. You are recommended to modify code generators to avoid using [Custom].

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

  • [JSCustom] on a method indicates that you want to write JavaScriptCore custom bindings for the method.
  • [V8Custom] on a method indicates that you want to write V8 custom bindings for the method.
  • [Custom] on a method is equivalent to [JSCustom, V8Custom].
  • [JSCustomGetter] or [JSCustomSetter] on an attribute indicates that you want to write JavaScriptCore custom bindings for the attribute getter or setter.
  • [V8CustomGetter] or [V8CustomSetter] on an attribute indicates that you want to write V8 custom bindings for the attribute getter or setter.
  • [JSCustom] on an attribute is equivalent to [JSCustomGetter, JSCustomSetter].
  • [V8Custom] on an attribute is equivalent to [V8CustomGetter, V8CustomSetter].
  • [Custom] on an attribute is equivalent to [JSCustom, V8Custom], i.e. [JSCustomGetter, JSCustomSetter, V8CustomGetter, V8CustomSetter].

For example, if you want to write custom bindings only for an attribute getter of JavaScriptCore and V8 and an attribute setter of JavaScriptCore, you can specify [CustomGetter, JSCustomSetter].

How to write custom bindings are different between JavaScriptCore and V8 or between a method and an attribute getter/setter.

Consider the following example:

    interface XXX {
        [JSCustom] void func(in int a, in int b);
    }

You need to prepare WebCore/bindings/js/JSXXXCustom.cpp and write custom bindings:

    JSValue JSXXX::func(ExecState* exec)
    {
        ...;
    }

Refer to WebCore/bindings/js/JSXXXCustom.cpp for more details.

Consider the following example:

    interface XXX {
        attribute [JSCustomGetter] DOMString str;
    }

You need to prepare WebCore/bindings/js/JSXXXCustom.cpp and write custom bindings:

    JSValue JSXXX::str(ExecState* exec) const
    {
        ...;
    }

Refer to WebCore/bindings/js/JSXXXCustom.cpp for more details.

Consider the following example:

    interface XXX {
        attribute [JSCustomSetter] DOMString str;
    }

You need to prepare WebCore/bindings/js/JSXXXCustom.cpp and write custom bindings:

    void JSXXX::setStr(ExecState*, JSValue value)
    {
        ...;
    }

Refer to WebCore/bindings/js/JSXXXCustom.cpp for more details.

  • V8 method

Consider the following example:

    interface XXX {
        [V8Custom] void func(in int a, in int b);
    }

You need to prepare WebCore/bindings/v8/custom/V8XXXCustom.cpp and write custom bindings in the following signature:

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

Refer to WebCore/bindings/v8/custom/V8XXXCustom.cpp for more details.

  • V8 attribute getter

Consider the following example:

    interface XXX {
        attribute [V8CustomGetter] DOMString str;
    }

You need to prepare WebCore/bindings/v8/custom/V8XXXCustom.cpp and write custom bindings in the following signature:

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

Refer to WebCore/bindings/v8/custom/V8XXXCustom.cpp for more details.

  • V8 attribute setter

Consider the following example:

    interface XXX {
        attribute [V8CustomSetter] DOMString str;
    }

You need to prepare WebCore/bindings/v8/custom/V8XXXCustom.cpp and write custom bindings in the following signature:

    void V8XXX::eventAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
    {
        ...;
    }

Refer to WebCore/bindings/v8/custom/V8XXXCustom.cpp for more details.

Note: ObjC, GObject and CPP bindings do not support custom bindings.

* [CallWith](i,m,a)

Summary: It calls a WebCore method with additional information.

Usage: The possible usage is [CallWith=X1|X2|X3|...], where X1, X2, X3, ... is "ScriptExecutionContext", "ScriptState", "ScriptArguments" or "CallStack". "ScriptExecutionContext", "ScriptState" and "CallStack" can be specified on methods or attributes, but "ScriptArguments" can be specified on methods only:

    interface HTMLFoo {
        attribute [CallWith=ScriptExecutionContext] DOMString str;
        [CallWith=ScriptExecutionContext] void func1(in int a, in int b);
        [CallWith=ScriptState] void func2(in int a, in int b);
        [CallWith=ScriptArguments|CallStack] void func3(in int a, in int b);
        [CallWith=CallStack|ScriptArguments] void func4(in int a, in int b);
    }

[CallWith] can be specified on interfaces but it has a different meaning. Refer to the [Constructor] section for [CallWith] on interfaces.

In case of func1(...), HTMLFoo::func1(ScriptExecutionContext* context, int a, int b) is called. Thus, in HTMLFoo::func1(...) you can retrieve document or window through context.

In case of func2(...), HTMLFoo::func2(ScriptState* state, int a, int b) is called.

In case of func3(...), HTMLFoo::func3(ScriptArguments* arguments, ScriptCallStack* callstack, int a, int b) is called.

In this way, the additional information is added at the head of normal arguments. The order of additional information is "ScriptExecutionContext", "ScriptState", "ScriptArguments", and then "CallStack", despite the order of [CallWith=X1|X2|X3|...]. Thus, in case of func4(...), HTMLFoo::func3(ScriptArguments* arguments, ScriptCallStack* callstack, int a, int b) is called.

* [CheckAccessToNode](m,a)

Summary: It checks if a given Node access is allowed in terms of security.

Usage: [CheckAccessToNode] can be specified on methods and attributes:

    attribute [CheckAccessToNode] Node contentDocument;
    [CheckAccessToNode] SVGDocument getSVGDocument();

In terms of security, node.contentDocument should return undefined if the parent frame and the child frame are from different origins. If the security check is needed, you should specify [CheckAccessToNode]. This is really important for security.

* [StrictTypeChecking](m,a) FIXME

Summary: ADD SUMMARY

Usage: [StrictTypeChecking] can be specified on methods and attributes:

    attribute [StringTypeChecking] float x;
    [StrictTypeChecking] DOMString func();

ADD EXPLANATIONS

* [ReturnNewObject](m,a)

Summary: It controls whether WebCore can return a cached wrapper object or not.

Usage: [ReturnNewObject] can be specified on methods or attributes:

    attribute [ReturnNewObject] Node node;
    [ReturnNewObject] Node createTextNode();

Without [ReturnNewObject], JavaScriptCore and V8 cache a wrapper object for performance. For example, consider the case where node.firstChild is accessed:

  • Node::firstChild() is called
  • The result is passed to toJS() or toV8()
  • toJS() or toV8() checks if a wrapper object of the result is already cached on the node
  • If cached, the cached wrapper object is returned
  • Otherwise, toJS() or toV8() creates the wrapper object of the result
  • The created wrapper object is cached on the node
  • The wrapper object is returned

On the other hand, if you do not want to cache the wrapper object and want to create the wrapper object every time, you can specify [ReturnNewObject].

* [ImplementedAs](m)

Summary: It specifies a method name in WebCore implementation, if the IDL method name and the WebCore method name are different.

Usage: The possible usage is [ImplementedAs=XXX], where XXX is a method name of the WebCore implementation. [ImplementedAs] can be specified on methods:

    [ImplementedAs=deleteFunction] void delete();

Basically, the WebCore method name should be equal to the IDL method name. That being said, sometimes you cannot use the same method name; e.g. "delete" is a C++ keyword. In such cases, you can explicitly specify the WebCore method name by [ImplementedAs]. You should avoid using [ImplementedAs] as much as possible though.

* [Reflect](a) FIXME

Summary: ADD SUMMARY

Usage: [Reflect] can be specified on attributes.

    attribute [Reflect] DOMString str;

ADD EXPLANATIONS

* [Replaceable](a)

Summary: It controls if a given attribute is "replaceable" or not.

Usage: [Replaceable] can be specified on attributes:

    interface DOMWindow {
        attribute [Replaceable] screenX;
    }

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

Specifically, without [Replaceable], the attribute behaves as follows:

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

With [Replaceable], the attribute behaves as follows:

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

Whether you should specify [Replaceable] or not depends on the spec of each attribute.

* [Deletable](a), [NotEnumerable](a), [V8ReadOnly](a)

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

Usage: They can be specified on attributes:

    attribute [NotEnumerable, Deletable] DOMString str;
    readonly attribute DOMString readonlyStr;
    attribute [V8ReadOnly] DOMString readonlyStrOnV8;

By default, non-"readonly" attributes are enumerable, writable and not deletable. "readonly" attributes are enumerable, not writable and not deletable. You can change the default behavior using [Deletable], [NotEnumerable] or [V8ReadOnly].

[Deletable] indicates that the attribute is deletable. [NotEnumerable] indicates that the attribute is not enumerable. [V8ReadOnly] indicates that the attribute is readonly in V8 even if the attribute is not prefixed by "readonly".

* [CachedAttribute](a)

Summary: For performance optimization, it indicates to cache a wrapped object in a DOM object.

Usage: [CachedAttribute] can be specified on attributes:

    interface HTMLFoo {
        attribute [CachedAttribute] DOMString normalValue;
        attribute [CachedAttribute] SerializedScriptValue serializedValue;
    }

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

  • HTMLFoo::normalValue() is called.
  • The result is passed to toJS() or toV8(), and is converted to a wrapper object.
  • The wrapper object is returned.

In case where HTMLFoo::normalValue() and wrapping the result is weight, you can cache the wrapped object in the DOM object by using [CachedAttribute]. With [CachedAttribute], the normalValue getter works in the following way:

  • If the wrapper object is cached, the cached wrapper object is returned.
  • Otherwise, HTMLFoo::normalValue() is called.
  • The result is passed to toJS() or toV8(), and is converted to a wrapped object.
  • The wrapped object is cached.
  • The wrapped object is returned.

In particular, [CachedAttribute] will be helpful for serialized values. Without [CachedAttribute], the serializedValue getter works in the following way:

  • HTMLFoo::serializedValue() is called.
  • The result is deserialized.
  • The deserialized result is passed to toJS() or toV8(), and is converted to a wrapped object.
  • The wrapped object is returned.

In case where HTMLFoo::serializedValue(), deserializing and wrapping the result is weight, you can cache the wrapped object to the DOM object by specifying [CachedAttribute]. With [CachedAttribute], the serializedValue getter works in the following way:

  • If the wrapper object is cached, the cached wrapper object is returned.
  • Otherwise, HTMLFoo::serializedValue() is called.
  • The result is deserialized.
  • The deserialized result is passed to toJS() or toV8(), and is converted to a wrapped object.
  • The wrapped object is cached.
  • 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 and setters (Setters always need to invalidate the caches).

* [V8Unforgeable](m,a), [V8OnProto](m,a)

Summary: They control where a given attribute getter/setter is defined.

Usage: They can be specified on attributes:

    attribute [V8Unforgeable] DOMString str1;
    attribute [V8OnProto] DOMString str2;

By default in JSC and V8, 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 [V8Unforgeable] or [V8OnProto]. [V8Unforgeable] indicates that the attribute getter/setter or the method should be defined on a DOM object. On the other hand, [V8OnProto] indicates that the attribute getter/setter or the method should be defined on a chain.

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

* [URL](a)

Summary: It indicates that a given DOMString is a URL.

Usage: [URL] can be specified on DOMString attributes:

    attribute [Reflect, V8URL] DOMString url;

You must specify [URL] if the DOMString represents URL, since URL attribute getters are realized in a special routine in WebKit, i.e. Element::getURLAttribute(). If you forgot to specify [URL], then the attribute getter might cause a bug.

* [JSWindowEventListener](a) FIXME

Summary: ADD SUMMARY

Usage: [JSWindowEventListener] can be specified on EventListener attributes.

    attribute [JSWindowEventListener] EventListener onload;

ADD EXPLANATIONS

IDL attributes around interfaces

* [Supplemental](i)

Summary: [Supplemental] helps WebKit modularization. [Supplemental] makes it possible to add XXX's APIs (e.g. XXX=WebAudio, WebSocket, Blob, GamePad, ...etc) without modifying code outside of WebCore/Modules/XXX/. This helps make XXX a "self-contained module".

Usage: The possible usage is

    interface [Supplemental=YYY] XXX { ... }

where XXX implements YYY. [Supplemental] can be specified on interfaces.

Here is an example. Without [Supplemental], if we want to add XXX's attributes or methods to DOMWindow,

  • we need to modify WebCore/page/DOMWindow.idl to add the XXX's attributes or methods
  • we need to modify WebCore/page/DOMWindow.{h,cpp} to add the C++ implementation of the attribute getters and setters or the method callbacks.

On the other hand, in the modularized world with [Supplemental], we just need to modify the code under WebCore/Modules/XXX/:

  • WebCore/Modules/XXX/DOMWindowXXX.idl
       interface [
           Conditional=XXX,
           Supplemental=DOMWindow    // The attributes and methods of this interface are exposed as those of DOMWindow.
       ] DOMWindowXXX {
           attribute foo;
           void bar();
       };
    
  • WebCore/Modules/XXX/DOMWindowXXX.h
       DOMWindowXXX::foo(...) { ... }   // The C++ implementation of the foo attribute getter.
       DOMWindowXXX::setFoo(...) { ... }   // The C++ implementation of the foo attribute setter.
       DOMWindowXXX::bar(...) { ... }   // The C++ implementation of the bar method callback.
    

As shown above, [Supplemental=DOMWindow] indicates that all the attributes and methods of DOMWindowXXX should be exposed on DOMWindow, but should be implemented in DOMWindowXXX. In this way, we can implement the attributes and methods without modifying code of DOMWindow.{h,cpp,idl}.

If you want to add APIs whose implementations are likely to be independent from WebCore, it is strongly recommended to put the APIs and .h/.cpp files into WebCore/Modules/XXX/ using [Supplemental].

* [Constructor](i), [CallWith](i,m,a), [ConstructorRaisesException](i)

Summary: It indicates that the interface should have constructor "new XXX()".

Usage: [Constructor], [CallWith] and [ConstructorRaisesException] can be specified on interfaces:

    interface [
        Constructor(in float x, in float y, in DOMString str),
        ConstructorRaisesException,
        CallWith=ScriptExecutionContext|ScriptState
    ] XXX {
    }

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

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

Then XXX::create(float x, float y, String str) is called in WebCore. Specifically, WebCore needs to implement the following method:

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

[Constructor()] is equivalent to [Constructor].

If the WebCore method can throw Exception, you can use [ConstructorRaisesException]. With [ConstructorRaisesException], an ExceptionCode argument is added to the tail argument of XXX::create(...).

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

If the WebCore method needs additional information like ScriptExecutionContext and ScriptState, you can specify it by [CallWith=ScriptExecutionContext|ScriptState]. Then the WebCore method can have the following signature:

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

You can retrieve document or frame from ScriptExecutionContext. Please see another [CallWith] section for more details.

Note that [CallWith=...] arguments are added at the head of the WebCore method arguments, and the ExceptionCode argument is added at the tail of the WebCore method arguments.

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

* [ConstructorTemplate](i), [InitializedByEventConstructor](a)

Summary: They are used for Event constructors.

Usage: The possible usage is [ConstructorTemplate=Event]. [ConstructorTemplate=Event] can be specified on Event interfaces. [InitializedByEventConstructor] can be specified on attributes in the Event interfaces:

    interface [
        ConstructorTemplate=Event
    ] FooEvent {
        attribute DOMString str1;
        attribute [InitializedByEventConstructor] DOMString str2;
    }

Since constructors for Event interfaces require special binding, you need to use [ConstructorTemplate=Event] instead of normal [Constructor].

If you specify [ConstructorTemplate=Event] on FooEvent, JavaScript can make a DOM object of FooEvent in the following code:

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

Then FooEvent::create(...) is called in WebCore. Specifically, WebCore needs to implement the following method:

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

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

* [NamedConstructor](i)

Summary: If the interface name XXX and "new YYY()" name are different (i.e. XXX != YYY), you can use [NamedConstructor].

Usage: The possible usage of [NamedConstructor] is [NamedConstructor=YYY]. [NamedConstructor] can be specified on interfaces:

    interface [
        NamedConstructor=Audio()
    ] HTMLAudioElement {
    }

The semantics is the same as [Constructor], except that JavaScript can make a DOM object not by "new HTMLAudioElement(...)" but by "Audio()".

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

* [CustomConstructor](i), [JSCustomConstructor](i), [V8CustomConstructor](i), [ConstructorParameters](i)

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

Usage: They can specified on interfaces. Regarding [ConstructorParameters], the possible usage is [ConstructorParameters=X], where X is the maximum number of arguments of the constructor:

    interface [
        CustomConstructor,
        ConstractorParameters=4
    ] XXX {
    }

We should minimize the number of custom bindings as less as possible. Before using [CustomConstructor], you should doubly consider if you really need custom bindings. You are recommended to modify code generators to avoid using [Custom].

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

  • [JSCustomConstructor] on an interface indicates that you want to write JavaScriptCore custom bindings for the constructor.
  • [V8CustomConstructor] on an interface indicates that you want to write V8 custom bindings for the constructor.
  • [CustomConstructor] is equivalent to [JSCustomConstructor, V8CustomConstructor].

For example, if you specify [Constructor, JSCustomConstructor], then the constructor is generated only for V8 and you need to write JavaScriptCore custom bindings for the constructor.

How to write custom bindings are different between JavaScriptCore and V8.

Consider the following example:

    interface [
        CustomConstructor,
        ConstructorParameters=2
    ] XXX {
    }

You need to prepare WebCore/bindings/js/JSXXXCustom.cpp and write custom bindings:

    EncodedJSValue JSC_HOST_CALL JSXXXConstructor::constructJSSharedWorker(ExecState* exec)
    {
        ...;
    }

Refer to WebCore/bindings/js/JSXXXCustom.cpp for more details.

  • V8

Consider the following example:

    interface [
        CustomConstructor,
        ConstructorParameters=2
    ] XXX {
    }

You need to prepare WebCore/bindings/v8/custom/V8XXXConstructor.cpp and write custom bindings:

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

Refer to WebCore/bindings/v8/custom/V8XXXConstructor.cpp for more details.

X of [ConstructorParameters=X] is the maximum number of arguments, including optional arguments. For example, if the constructor signature is [Constructor(in int a, in int b, in [Optional] int c, in [Optional] int d)], then X is 4. You do not need to specify [ConstructorParameters] if the interface does not have any of [JSCustomConstructor], [V8CustomConstructor] or [CustomConstructor].

* [Conditional](i,m,a)

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

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

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

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

If [Conditional] is specified on an interface, it means that [Conditional] is specified on all attributes and methods on the interface.

* [V8EnabledAtRuntime](i,m,a)

Summary: In Chromium/V8, we can enable/disable a flag at runtime.

Usage: The possible usage is [V8EnabledAtRuntime] or [V8EnabledAtRuntime=X], where X is an arbitrary string which you want to use for identifying the flag getter. [V8EnabledAtRuntime] can be specified on interfaces, methods and attributes:

    interface [
        V8EnabledAtRuntime
    ] XXX {
    }
    interface XXX {
        attribute [V8EnabledAtRuntime] DOMString str1;
        attribute [V8EnabledAtRuntime=foo] DOMString str2;
        [V8EnabledAtRuntime] void open1();
        [V8EnabledAtRuntime=foo] void open2();
    }

In Chromium/V8, we can enable/disable flags in the about:flags page. To make interfaces/methods/attributes controllable through about:flags, you can specify [V8EnabledAtRuntime].

If [V8EnabledAtRuntime] is specified on an interface, it means that [V8EnabledAtRuntime] is specified on all attributes and methods on the interface....;

If you add [V8EnabledAtRuntime], you need to write "flag-binding" code in WebCore/bindings/generic/RuntimeEnabledFeatures.h, WebCore/bindings/generic/RuntimeEnabledFeatures.cpp and WebKit/chromium/src/WebRuntimeFeatures.cpp.

The method name of a flag getter in WebCore/bindings/generic/RuntimeEnabledFeatures.h is determined by the name of interfaces/methods/attributes. You can change the method name by using [V8EnabledAtRuntime=X]. Refer to WebCore/bindings/generic/RuntimeEnabledFeatures.h, WebCore/bindings/generic/RuntimeEnabledFeatures.cpp and WebKit/chromium/src/WebRuntimeFeatures.cpp for more details.

* [CustomToJSObject](i), [JSCustomToJSObject](i), [V8CustomToJSObject](i)

Summary: They allow us to write custom toJS() or toV8().

Usage: They can be specified on interfaces:

    interface [
        CustomToJSObject
    ] XXX {
    }
  • [JSCustomToJSObject] on an interface indicates that you want to write custom toJS().
  • [V8CustomToJSObject] on an interface indicates that you want to write custom toV8().
  • [CustomToJSObject] is equivalent to [JSCustomToJSObject, V8CustomToJSObject].

By default, toJS() and toV8() are automatically generated in JSXXX.h and JSXXX.cpp or V8XXX.h and V8XXX.cpp. With [CustomToJSObject] or [JSCustomToJSObject], you can write custom toJS() WebCore/bindings/js/JSXXXCustom.cpp:

    JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, XXX* impl)
    {
        ...;
    }

With [CustomToJSObject] or [V8CustomToJSObject], you can write custom toV8() WebCore/bindings/v8/custom/V8XXXCustom.cpp:

    v8::Handle<v8::Value> toV8(XXX* impl, bool forceNewObject)
    {
        ...;
    }

* [CheckAccessToFrame](i), [DoNotCheckAccessToFrame](m,a), [DoNotCheckAccessToFrameOnGetter](a), [DoNotCheckAccessToFrameOnSetter](a)

Summary: It checks if a given Frame access is allowed or not, in terms of security.

Usage: [CheckAccessToFrame] can be specified on interfaces. [DoNotCheckAccessToFrame] can be specified on methods or attributes which belong to interfaces which have [CheckAccessToFrame]. [DoNotCheckAccessToFrameOnGetter] and [DoNotCheckAccessToFrameOnSetter] can be specified on attributes which belong to interfaces which have [CheckAccessToFrame]:

    interface [
        CheckAccessToFrame
    ] DOMWindow {
        attribute DOMString str1;
        attribute [DoNotCheckAccessToFrame] DOMString str2:
        attribute [DoNotCheckAccessToFrameOnGetter] DOMString str3:
        attribute [DoNotCheckAccessToFrameOnSetter] DOMString str4:
        void func1();
        [DoNotCheckAccessToFrame] void func2();
    }

Consider the case where you access window.parent from inside iframe which 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 [CheckAccessToFrame] in order to check whether a given Frame is allowed to access the attribute or method. This is really important for security.

If you specify [CheckAccessToFrame] on an interface, the security check is enabled on all the attributes and methods in the interface. To disable the security check for some attribute or method, you can use [DoNotCheckAccessToFrame], [DoNotCheckAccessToFrameOnGetter] or [DoNotCheckAccessToFrameOnSetter].

  • [DoNotCheckAccessToFrame] on a method disables the security check for the method.
  • [DoNotCheckAccessToFrame] on an attribute disables the security check for a getter and setter of the attribute.
  • [DoNotCheckAccessToFrameOnGetter] on an attribute disables the security check for a getter of the attribute.
  • [DoNotCheckAccessToFrameOnSetter] on an attribute disables the security check for a setter of the attribute.
  • [DoNotCheckAccessToFrame] on an attribute is equivalent to [DoNotCheckAccessToFrameOnGetter, DoNotCheckAccessToFrameOnSetter].

* [IndexedGetter](i)

Summary: [IndexedGetter] means that a given interface should have a getter of indexed properties.

Usage: [IndexedGetter] can be specified on interfaces:

    interface [
        IndexedGetter
    ] XXX {
    }

Indexed getters define the behavior when XXX[i] is evaluated. The bindings code is generated automatically so that XXX[i] behaves equivalent to XXX.item(i).

* [CustomIndexedSetter](i)

Summary: [CustomIndexedSetter] allows us to write custom bindings for a setter of indexed properties.

Usage: [CustomIndexedSetter] can be specified on interfaces:

    interface [
        CustomIndexedSetter
    ] XXX {
    }

Indexed setters define the behavior when "XXX[i] = ..." is evaluated. [CustomIndexedSetter] allows us to write the custom bindings.

  • In JavaScriptCore, you can write JSXXX::indexSetter(...) in WebCore/bindings/js/JSXXXCustom.cpp:
        void JSXXX::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value)
        {
            ...;
        }
    
  • In V8, you can write V8XXX::indexedPropertyGetter(...) in WebCore/bindings/v8/custom/V8XXXCustom.cpp:
        v8::Handle<v8::Value> V8XXX::indexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info)
        {
            ...;
        }
    

* [NamedGetter](i)

Summary: [NamedGetter] means that a given interface should have a getter of named properties.

Usage: [NamedGetter] can be specified on interfaces:

    interface [
        NamedGetter
    ] XXX {
    }

Named getters define the behavior when XXX.foooooooo is evaluated, where foooooooo is not an attribute of a given interface. The bindings code is generated automatically so that XXX.foooooooo behaves equivalent to XXX.namedItem(i).

[CustomNamedGetter](i), [CustomNamedSetter](i)

Summary: [CustomNamedGetter]/[CustomNamedSetter] allows us to write custom bindings for a getter/setter of named properties.

Usage: They can be specified on interfaces:

    interface [
        CustomNamedGetter,
        CustomNamedSetter
    ] XXX {
    }

Named getters define the behavior when XXX.foooooooo is evaluated, where foooooooo is not an attribute of a given interface. Named setters define the behavior when "XXX.foooooooo = ..." is evaluated. [CustomNamedGetter] and [CustomNamedSetter] allow us to write the custom bindings.

  • With [CustomNamedGetter] in JavaScriptCore, you can write JSXXX::canGetItemsForName(...) and JSXXX::nameGetter(...) in WebCore/bindings/js/JSXXXCustom.cpp:
        bool JSXXX::canGetItemsForName(ExecState*, XXX* impl, const Identifier& propertyName)
        {
            ...;
        }
    
        JSValue JSXXX::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
        {
            ...;
        }
    
  • With [CustomNamedGetter] in V8, you can write V8XXX::namedPropertyGetter(...) in WebCore/bindings/v8/custom/V8XXXCustom.cpp:
        v8::Handle<v8::Value> V8XXX::namedPropertyGetter(v8::Local<v8::String>, v8::Local<v8::Value>, const v8::AccessorInfo&)
        {
            ...;
        }
    
  • With [CustomNamedSetter] in JavaScriptCore, you can write JSXXX::putDelegate(...) in WebCore/bindings/js/JSXXXCustom.cpp:
        bool JSXXX::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot&)
        {
            ...;
        }
    
  • With [CustomNamedSetter] in V8, you can write V8XXX::namedPropertySetter(...) in WebCore/bindings/v8/custom/V8XXXCustom.cpp:
        v8::Handle<v8::Value> V8XXX::namedPropertySetter(v8::Local<v8::String>, v8::Local<v8::Value>, const v8::AccessorInfo&)
        {
            ...;
        }
    

* [EventTarget](i) FIXME

Summary: ADD SUMMARY

Usage: [EventTarget] can be specified on interfaces.

    interface [
        EventTarget
    ] XXX {
    }

ADD EXPLANATIONS

* [DoNotCheckConstants](i)

Summary: [DoNotCheckConstants] stops inserting compile-time assertions for constants of a given interface.

Usage: [DoNotCheckConstants] can be specified on interfaces:

    interface [
        DoNotCheckConstants
    ] XXX {
        const unsigned short NOT_FOUND_ERR = 123;
        const unsigned short SYNTAX_ERR = 124;
    }

Without [DoNotCheckConstants], compile-time assertions are generated to check if the constant values defined in IDL files are equal to the constant values in WebKit implementation. In the above example, if NOT_FOUND_ERR were 100 in WebKit implementation, the build will fail. Basically values of all constants are defined in the spec, and thus the values defined in IDL files and the values in WebKit implementations should be equal to the values defined in the spec.

If you want to introduce non-speced constant values and allow different values between IDL files and WebKit implementation, you can specify [DoNotCheckConstants] on the interface to skip the compile-time assertions.

* [ActiveDOMObject](i)

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

Usage: [ActiveDOMObject] can be specified on interfaces:

    interface [
        ActiveDOMObject
    ] XMLHttpRequest {
    }

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.

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

* [V8DependentLifeTime](i) FIXME

Summary: ADD SUMMARY

Usage: [V8DependentLifeTime] can be specified on interfaces.

    interface [
        V8DependentLifeTime
    ] XXX {
    }

ADD EXPLANATIONS

* [CustomEnumerateProperty](i), [CustomDeleteProperty](i)

Summary: [CustomEnumerateProperty] allows us to write custom bindings for the case where properties of a given interface are enumerated. [CustomDeleteProperty] allows us to write custom bindings for the case where a property of a given interface is deleted.

Usage: They can be specified on interfaces:

    interface [
        CustomEnumerateProperty,
        CustomDeleteProperty
    ] XXX {
    }

With [CustomEnumerateProperty], you can write custom bindings when properties of XXX are enumerated. Specifically, you can write JSXXX::getOwnPropertyNames(...) in WebCore/bindings/js/JSXXXCustom.cpp:

    void JSXXX::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
    {
        ...;
    }

and V8XXX::namedPropertyQuery(...) and V8XXX::namedPropertyEnumerator(...) in WebCore/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)
    {
        ...;
    }

With [CustomDeleteProperty], you can write custom bindings for the case where a property of XXX is deleted. Specifically, you can write JSXXX::deleteProperty(...) in WebCore/bindings/js/JSXXXCustom.cpp:

    bool JSXXX::deleteProperty(JSCell* cell, ExecState* exec, const Identifier& propertyName)
    {
        ...;
    }

and V8XXX::namedPropertyDeleter(...) in WebCore/bindings/v8/custom/V8XXXCustom.cpp:

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

* [IsWorkerContext](i)

Summary: It indicates that the interface is a WorkerContext-related interface.

Usage: [IsWorkerContext] can be specified on WorkerContext-related interfaces:

    interface [
        IsWorkerContext
    ] SharedWorkerContext {
        ...;
    }

* [CustomCall](i)

Summary: [CustomCall] allows us to write custom bindings for call(...) of a given interface.

Usage: [CustomCall] can be specified on interfaces:

    interface [
        CustomCall
    ] XXX {
    }

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

  • In JavaScriptCore, you can write JSXXX::getCallData(...) in WebCore/bindings/js/JSXXXCustom.cpp:
        JSC::CallType JSXXX::getCallData(JSC::JSCell* cell, JSC::CallData& callData)
        {
            ...;
        }
    
  • In V8, you can write V8XXX::callAsFunctionCallback(...) in WebCore/bindings/v8/custom/V8XXXCustom.cpp:
        v8::Handle<v8::Value> V8XXX::callAsFunctionCallback(const v8::Arguments& args)
        {
            ...;
        }
    

* [JSCustomToNativeObject](i), [JSCustomFinalize](i), [JSCustomIsReachable](i), [JSCustomMarkFunction](i), [JSCustomNamedGetterOnPrototype](i), [JSCustomPushEventHandlerScope](i), [JSCustomDefineOwnProperty](i), [JSCustomDefineOwnPropertyOnPrototype](i), [JSCustomGetOwnPropertySlotAndDescriptor](i)

Summary: They allow us to write custom code for the JavaScriptCore code which would be generated automatically by default.

Usage: They can be specified on interfaces:

    interface [
        JSCustomToNativeObject,
        JSCustomFinalize,
        JSCustomIsReachable,
        JSCustomMarkFunction,
        JSCustomNamedGetterOnPrototype,
        JSCustomPushEventHandlerScope,
        JSCustomDefineOwnProperty,
        JSCustomDefineOwnPropertyOnPrototype,
        JSCustomGetOwnPropertySlotAndDescriptor
    ] XXX {
    }

You can write the following custom code in WebCore/bindings/js/JSXXXCustom.cpp. Refer to use cases in WebCore/bindings/js/JSXXXCustom.cpp for more details.

  • With [JSCustomToNativeObject], you can write custom toXXX(...):
        PassRefPtr<XXX> toXXX(JSGlobalData& globalData, JSValue value)
        {
            ...;
        }
    
  • With [JSCustomFinalize], you can write custom JSXXXOwner::finalize(...):
        void JSXXXOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context)
        {
            ...;
        }
    
  • With [JSCustomIsReachable], you can write custom JSXXXOwner::isReachableFromOpaqueRoots(...):
        bool JSXXXOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void* context, SlotVisitor& visitor)
        {
            ...;
        }
    
  • With [JSCustomMarkFunction], you can write custom JSXXX::visitChildren(...):
        void JSXXX::visitChildren(JSCell* cell, SlotVisitor& visitor)
        {
            ...;
        }
    
  • With [JSCustomNamedGetterOnPrototype], you can write custom JSXXX::putDelegate(...):
        bool JSXXX::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
        {
            ...;
        }
    
  • With [JSCustomPushEventHandlerScope], you can write custom JSXXX::pushEventHandlerScope(...):
        ScopeChainNode* JSXXX::pushEventHandlerScope(ExecState* exec, ScopeChainNode* node) const
        {
            ...;
        }
    
  • With [JSCustomDefineOwnProperty], you can write custom JSXXX::defineOwnProperty(...):
        bool JSXXX::defineOwnProperty(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor, bool throwException)
        {
            ...;
        }
    
  • With [JSCustomDefineOwnPropertyOnPrototype], you can write custom JSXXXPrototype::defineOwnProperty(...):
        bool JSXXXPrototype::defineOwnProperty(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor, bool throwException)
        {
            ...;
        }
    
  • With [JSCustomGetOwnPropertySlotAndDescriptor], you can write custom JSXXX::getOwnPropertySlotDelegate(...) and JSXXX::getOwnPropertyDescriptorDelegate(...):
        bool JSXXX::getOwnPropertySlotDelegate(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
        {
            ...;
        }
    
        bool JSXXX::getOwnPropertyDescriptorDelegate(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
        {
            ...;
        }
    

* [JSGenerateToJSObject](i), [JSGenerateIsReachable](i), [JSGenerateToNativeObject](i)

Summary: They force JavaScriptCore bindings to generate JavaScriptCore specific methods even if a given interface has a parent interface.

Usage: They can be specified on interfaces which do not have a parent interface:

    interface [
        JSGenerateToJSObject,
        JSGenerateIsReachable,
        JSGenerateToNativeObject
    ] XXX {
    }

toJS(...), isReachableFromOpaqueRoots(...) or toXXX() are not generated if the interface has a parent interface. If you want to generate it even if the interface does not have a parent interface, you can specify [JSGenerateToJSObject], [JSGenerateIsReachable] or [JSGenerateToNativeObject], respectively.

* [JSCustomHeader](i)

Summary: It allows us to write a custom header for a given interface.

Usage: [JSCustomHeader] can be specified on interfaces:

    interface [
        JSCustomHeader
    ] XXX {
    }

By default, JSXXX.h and JSXXX.cpp are generated automatically, and if you need, you can write custom bindings in WebCore/bindings/js/JSXXXCustom.cpp. On the other hand, [JSCustomHeader] allows us to write WebCore/bindings/js/JSXXXCustom.h, which is included by JSXXX.h.

* [JSLegacyParent](i)

Summary: It explicitly controls the parent interface of a given interface.

Usage: [JSLegacyParent] can be specified on interfaces:

    interface [
        JSLegacyParent=JSDOMWindowBase
    ] DOMWindow {
    }

Even if a given interface does not have a parent interface, you can specify a parent interface using [JSLegacyParent].

* [JSInlineGetOwnPropertySlot](i)

Summary: It makes getOwnPropertySlot(...) and getOwnPropertyDescriptor(...) an inline method for performance.

Usage: [JSInlineGetOwnPropertySlot] can be specified on interfaces:

    interface [
        JSInlineGetOwnPropertySlot
    ] XXX {
    }

* [JSNoStaticTables](i) FIXME

Summary: ADD SUMMARY

Usage: [JSNoStaticTables] can be specified on interfaces.

    interface [
        JSNoStaticTables
    ] XXX {
    }

ADD EXPLANATIONS

IDL attributes used by ObjC, GObject and CPP bindings only

* [ObjCProtocol](i), [ObjCPolymorphic](i), [ObjCLegacyUnnamedParameters](m), [ObjCUseDefaultView](m), [ObjCImplementedAsUnsignedLongLong](a)

Used by ObjC bindings only.

* [CPPPureInterface](i)

Used by CPP bindings only.

* [CustomReturn](p)

Used by ObjC, GObject and CPP bindings only.

IDL attributes which might be deprecated

* [OmitConstructor], [Immutable], [MasqueradesAsUndefined]

Might be deprecated. Discussion is on-going.

* [CustomGetOwnPropertySlot], [ReplaceableConstructor], [ExtendsDOMGlobalObject], [IsIndex], [V8DoNotCheckSignature], [NumericIndexedGetter]

Will be deprecated. Discussion is on-going.