Information contained in a WebIDL file

When writing documentation about an API, the sources of information are many: the specifications describe what should be implemented as well as the model, and the implementations describe what has actually been put in the browsers. WebIDL files are a very condensed way of giving a lot, but not all, of the information about the API. This document provides a reference to help understand WebIDL syntax.

IDL stands for Interface Definition Language and it is designed to describe APIs. In the wider world of computing there are several kinds of IDL. In the world of browsers, the IDL we use is called WebIDL. Two kinds of WebIDL are available: the one given in the WebIDL spec, and the one implemented in browsers. The spec is the canonical reference, and the browser WebIDL describes what is actually implemented in a particular browser, and contains additional things such as annotations and information about non-standard elements.

Where to find WebIDL files

WebIDL can be found in multiple locations:

  • Each specification contains WebIDL inside the text: it is a very convenient way to convey precise definition. These describe the syntax of the API. Though the canonical reference, we have to keep in mind that they may differ from the actual implementation. On the MDN we want to be practical and document what the Web platform really is, not what it ideally should be. So double check what is there with implementations (and don't hesitate to file bugs if you discover incoherence).
  • Three browser engines use (modified) WebIDL as part as their toolchain: Gecko, Chromium/Blink, and WebCore/WebKit. Edge uses it internally, but these are unfortunately not public (it would have helped us a lot).

Different dialects of WebIDL

WebIDL is defined in its specification. But it has been designed to be extended to convey more information, and browser vendors have done so:

  • For Gecko, MDN has the documentation of its dialectal WebIDL.
  • For Chromium, Google also created a document to describe its extensions.
  • For WebCore, Apple also made available a page for its dialect.

Note: We describe here only the subset of WebIDL useful for creating documentation. There are many more annotations useful for implementers; refer to the four documents linked above to have a complete overview.

Interfaces

This section explains the WebIDL syntax that describes overall API features.

Name of the interface

The interface name is the string that appears after the keyword interface and before the next opening bracket ('{') or colon (':').

interface URL {};

Each WebIDL interface, being a true interface or a mixin, has its own page in the documentation, listing every constructor, property and method defined for it.

Inheritance chain

The parent, if any, of a given interface is defined after the interface name, following a colon (':'). There can be only one parent per interface.

interface HTMLMediaElement : HTMLElement {…}

The inheritance chain is listed automatically in the sidebar (using the {{APIRef}} macro). It can also be added as an SVG image via the macro {{InheritanceDiagram}}.

Mixins

Some properties or methods are available to several interfaces. To prevent redefinition they are defined in special WebIDL interfaces called mixins. In the WebIDL, they are prefixed using the [NoInterfaceObject] annotation. The name of a mixin, Body in the following example, doesn't appear in JavaScript.

[NoInterfaceObject]
   interface Body {…}

For documentation purposes, we create a mixin page, with the same structure as an interface page. As they are not true interfaces, the word interface is not used — mixin is used instead.

Mixin methods and properties are listed in the same way as regular methods and properties:

  • They have their own pages, prefixed with the mixin name. E.g Body.bodyUsed or Body.blob().
  • They are listed on the interface page when the interface implements the mixin. Unlike regular properties and methods, they are prefixed with the mixin name and not the interface name. You can see Body properties and methods listed on both Request and Response interfaces, as they both implement the Body mixin.

Mixins implemented on an interface are defined using the implements keyword.

Request implements Body;
Response implements Body;

Note: Mixin names do not appear in a Web developer console. We shouldn't show them, but we currently do this as it saves us from duplicating content, which would lead to a maintenance issue. We do this if the mixin is only used in one interface (such cases are bugs in the relevant specs — they shouldn't be defined as mixins, but as partial interfaces.)

Availability in workers

Availability in Web workers (of any type) and on the Window scope is defined using an annotation: [Exposed=(Window,Worker)]. The annotation applies to the partial interface it is listed with. If no annotation is available, the default value is Window.

[Exposed=(Window,Worker)]
interface Performance {
   [DependsOn=DeviceState, Affects=Nothing]
   DOMHighResTimeStamp now();
};

[Exposed=Window]
partial interface Performance {
   [Constant]
   readonly attribute PerformanceTiming timing;
   [Constant]
   readonly attribute PerformanceNavigation navigation;

   jsonifier;
};

In this case Performance.now() is available on the Window scope and to any worker, while Performance.timing, Performance.navigation and Performance.toJSON() are not available to Web workers.

The most current values for the [Exposed] are:

Window
The partial interface is available to the Window global scope.
Worker
The partial interface is available to any kind of worker, that is if the global scope is a descendant of WorkerGlobalScopeDedicatedWorkerGlobalScope, SharedWorkerGlobalScope, or ServiceWorkerGlobalScope (It also is available to ChromeWorker, but we don't document this as they are not visible on the Web and are internal to Firefox.)
DedicatedWorker
The partial interface is available to the DedicatedWorkerGlobalScope only.
SharedWorker
The partial interface is available to the SharedWorkerGlobalScope only.
ServiceWorker
The partial interface is available to the ServiceWorkerGlobalScope only.

Another value is possible, like System, but this has a special meaning and doesn't need to be documented.

Note that these possible values are themselves defined in WebIDL files. Interfaces may have a [Global=xyz] annotation. It means that when an object of this type is used as a global scope, any interface, property or method, with xyz as a value of [Exposed] is available.

[Global=(Worker,DedicatedWorker), Exposed=DedicatedWorker]
interface DedicatedWorkerGlobalScope : WorkerGlobalScope {…}

Here, it is defined that when the global scope is of type DedicatedWorkerGlobalScope, that is if we are in a dedicated worker, any interface, property or method exposed – using the [Exposed] annotation – to Worker or DedicatedWorker is available.

Even the primary global is defined in WebIDL. The primary global is the value of an [Exposed] annotation when not present. This is defined using the [PrimaryGlobal] annotation and is present on Window:

[PrimaryGlobal, NeedResolve]
/*sealed*/ interface Window : EventTarget {…}

Preferences

Note: this information is specific to Gecko and should only be used in the Browser compatibility section.

In Gecko, the availability of a partial interface, including its constructor, properties and methods may be controlled by a preference (usually called a "pref"). This is marked in the WebIDL too.

[Pref="media.webspeech.synth.enabled"]
interface SpeechSynthesis {
   readonly attribute boolean pending;
   readonly attribute boolean speaking;
   readonly attribute boolean paused;
};

Here media.webspeech.synth.enabled controls the SpeechSynthesis interface and its properties (the full listing has more than 3.)

Note: the default value of the preference is not available directly in the WebIDL (it can be different from one product using Gecko to another.)

Properties

You can recognize the definition of a property by the presence of the attribute keyword.

Name of the property

readonly attribute MediaError? error;

In the above example the name of the property is error; in the docs we will refer to it as HTMLMediaElement.error as it belongs to the HTMLMediaElement interface. Linking to the page is either done with the interface prefix using {{domxref('HTMLMediaElement.error')}} or without the prefix using {{domxref('HTMLMediaElement.error', 'error')}} when the context is obvious and unambiguous.

Type of the property

readonly attribute MediaError? error;

The property value is an object of type MediaError. The question mark ('?') indicates that it can take a value of null, and the documentation must explain when this may occur. If no question mark is present, the error property can't be null.

Writing permissions on the property

readonly attribute MediaError? error;

If the keyword readonly is present, the property can't be modified. It must be marked as read-only:

  • In the interface, by adding the {{ReadOnlyInline}} macro next to its definition term.
  • In the first sentence of its own page, by starting the description with: The read-only HTMLMediaElement.error property…
  • By adding the Read-only tag to its own page.
  • By starting its description in the interface page with Returns…

Note: Only read-only properties can be described as 'returning' a value. Non read-only properties can also be used to set a value.

Throwing exceptions

[SetterThrows]
            attribute DOMString src;

In some cases, like when some values are illegal, setting a new value can lead to an exception being raised. This is marked using the [SetterThrows] annotation. When this happens, the Syntax section of the property page must have an Exceptions subsection. The list of exceptions and the conditions to have them thrown are listed, as textual information, in the specification of that API.

Note that some exceptions are not explicitly marked but are defined by the JavaScript bindings. Trying to set an illegal enumerated value (mapped to a JavaScript String) raises a TypeError exception. This must be documented, but is only implicitly marked in the WebIDL document.

It is uncommon to have getters throwing exceptions, though it happens in a few cases. In this case the [GetterThrows] annotation is used. Here also, the Syntax section of the property page must have an Exceptions subsection.

partial interface Blob {
  [GetterThrows]
  readonly attribute unsigned long long size;
};

Not throwing exceptions

When the semantics of Webidl is not followed, an exception is often thrown, even without [SetterThrows] or [GetterThrows] set. For example, in strict mode, if we try to set a read-only property to a new value, that is to call its implicit setter, a read-only property will throw in strict mode.

Mostly for compatibility purpose, this behavior is sometimes annoying. To prevent this by creating a no-op setter (that is by silently ignoring any attempt to set the property to a new value), the [LenientSetter] annotation can be used.

partial interface Document {
  [LenientSetter]
  readonly attribute boolean fullscreen;
  [LenientSetter]
  readonly attribute boolean fullscreenEnabled;
};

In these cases, an extra sentence is added to the description of the property. E.g

Although this property is read-only, it will not throw if it is modified (even in strict mode); the setter is a no-operation and it will be ignored.

New objects or references

The return value of a property can be either a copy of an internal object, a newly created synthetic object, or a reference to an internal object.

Basic objects with types like String (being an IDL DOMString, or other), Number (being an IDL byte, octet, unsigned int, or other), and Boolean are always copied and nothing special has to be noted about them (it is natural behavior expected by a JavaScript developer.)

For interface objects, the default is to return a reference to the internal object. This has to be mentioned both in the short description in the interface page, and in the description in the specific sub-pages.

Note: The keyword readonly used with a property returning an object applies to the reference (the internal object cannot be changed.) The properties of the returned object can be changed, even if they are marked as read-only in the relevant interface.

Sometimes an API must return a new object, or a copy of an internal one. This case is indicated in the WebIDL using the [NewObject] annotation.

[NewObject]
   readonly attribute TimeRanges buffered;

In this case, each call to buffered returns a different object: changing it will not change the internal value, and a change in the internal value will not affect each object instance. In the documentation, we will mark it by using the adjective new next to object:

The HTMLMediaElement.buffered read-only property returns a new {{domxref("TimeRanges")}} object that…

and

{{domxref("HTMLMediaElement.buffered")}}{{readonlyinline}}
Returns a new {{domxref("TimeRanges")}} object that …

In the case of a reference to a collection object (like HTMLCollection, HTMLFormElementsCollection, or HTMLOptionsCollection, always without [NewObject]), we make it explicit that changes to the underlying object will be available via the returned reference. To mark this, we qualify the collection as a live HTMLCollection (or HTMLFormElementsCollections, or HTMLOptionsCollection), both in the interface description and in the subpage.

E.g.

{{domxref("HTMLFormElement.elements")}}{{readonlyinline}}
Returns a live {{domxref("HTMLFormControlsCollection")}} containing…

Availability in workers

Individual property availability in workers is also found in the WebIDL. For a property, the default is the same availability as the interface (that is available to Window context only if nothing special is marked) or as the partial interface it is defined in.

For documentation, the sub-page must contain a sentence indicating if it is available or not in Web workers, right before the Syntax section. In the interface page, we mark the property with {{NotAvailableInWorkerInline}}, but only if this is different than the interface as a whole (This is really rare.)

Preferences

Note: this information is specific to Gecko and should only be used in the Browser compatibility section.

In Gecko, the availability of some properties may be controlled by a preference. This is marked in the WebIDL too.

[Pref="media.webvtt.enabled"]
    readonly attribute TextTrackList? textTracks;

Here media.webvtt.enabled controls the textTracks property.

Note: the default value of the preference is not available directly in the WebIDL (it can be different from one product using Gecko to another.)

Methods

You can recognize the definition of a method by the presence of parentheses after the name.

Name of the property

DOMString canPlayType(DOMString type);

The name of the method is canPlayType, and we will refer to it as HTMLMediaElement.canPlayType() (with the parenthesis that indicate that it is a method) in the docs, as it belongs to the HTMLMediaElement interface. Linking to the page is either done with the interface prefix using {{domxref('HTMLMediaElement.canPlayType()')}}, or without the prefix using {{domxref('HTMLMediaElement.canPlayType', 'canPlayType()')}} when the context is obvious and unambiguous. The parenthesis should always be included.

Parameters

TextTrack addTextTrack(TextTrackKind kind, 
                       optional DOMString label = "", 
                       optional DOMString language = "");

The parameters of a method are listed in the Syntax section of the method sub-page. They are listed in the WebIDL in order, between the parenthesis, as a comma-separated list. Each parameter has a name (indicated above) and a type (e.g. a '?' means that the null value is valid.) If marked optional, the parameter is optional to include in a method call and must have the {{OptionalInline}} flag included when it is listed in the Syntax section. The parameter's default value is listed after the equality sign ('=').

Type of the return value

DOMString canPlayType(DOMString type);

The return value type is indicated first inside the parentheses — in the above case the value is an object of type DOMString. if followed by a question mark ('?'), a value of null can be returned too, and the documentation must explain when this may happen. If no question mark is present, like here,  the return value can't be null.

The keyword void means that there is no return value. It is not a return value type. If the WebIDL entry reads void, the Return value section in the docs should contain only a simple None.

Throwing exceptions

[Throws]
   void fastSeek(double time);

Some methods can throw exceptions. This is marked using the [Throws] annotation. When this happens, the Syntax section of the method page must have an Exceptions subsection. The list of exceptions and the conditions to have them thrown are listed, as textual information, in the specification of that API.

Note that some exceptions are not explicitly marked but are defined by the JavaScript bindings. Trying to set an illegal enumerated value (mapped to a JavaScript String) as a parameter will raise a TypeError exception. This must be documented, but it is only implicitly marked in the WebIDL document.

Have a look at one of these Exceptions sections.

Availability in workers

Individual method availability in workers is also found in the WebIDL. For a method, the default is the same availability as the interface (that is available to Window context only if nothing special is marked) or as the partial interface it is defined it.

For the documentation, the sub-page must contain a sentence indicating if it is available in Web workers, right before the Syntax section. In the interface page, we mark the method with {{NotAvailableInWorkerInline}}, but only if this is different than the interface as a whole (This is really rare.)

Preferences

Note: this information is specific to Gecko and should only be used in the Browser compatibility section.

In Gecko, the availability of some properties may be controlled by a preference. This is marked in the WebIDL too.

[Pref="media.webvtt.enabled"]
   TextTrack addTextTrack(TextTrackKind kind,
                          optional DOMString label = "",
                          optional DOMString language = "");

Here media.webvtt.enabled controls the addTextTrack() method.

Note: The default value of the preference is not available directly in the WebIDL (it can be different from one product using Gecko to another.)

Iterator-like methods

An interface may be defined as iterable, meaning that it will have the following methods: entries(), keys(), values() and forEach(). They also supports the use of for...of on an object implementing this interface.

There are two kinds of iteration possible: the value iterator and the pair iterator.

Value iterator

iterable<valueType>

The iterator will iterate over values of type valueType. The generated methods will be:

  • entries() that returns an iterator on the indexes (that are unsigned long).
  • values() that returns an iterator on the values.
  • keys() that returns an iterator on the keys, that are its indexes (that are unsigned long). In the case of value iterators, keys() and entries() are identical.
  • Once bug 1216751 lands, forEach().

Such an iterator allows to use the syntax for (var p in object) as a shorthand of for (var p in object.entries()). We add a sentence about it in the interface description.

Note: the value pairs to iterate over can be defined in two different ways:

  1. Outside the webidl file, in the prose accompanying it. Such a prose is in the spec and usually starts with: "The values to iterate over…".
  2. In the webidl file, implicitly, if the interface supports indexed properties, that is when the interface has a getter methods with a parameter of type unsigned long.

Pair iterator

iterable<keyType, valueType>

The iterator will iterate over values of type valueType, with keys of type keyType. The generated methods will be:

Such an iterator allows to use the syntax for (var p in object) as a shorthand of for (var p in object.entries()). We add a sentence about it in the interface description. E.g. FormData.

Note: the value pairs to iterate over are not defined in the webidl file, but in the prose accompanying it. Such a prose is in the spec and usually starts with: "The value pairs to iterate over…"
E.g, for FormData you find in the spec: "The value pairs to iterate over are the entries with the key being the name and the value the value. "

Set-like methods

An interface may be defined as set-like, meaning that it represents an ordered set of values will have the following methods: entries(), keys()values(), forEach(), and has() (it also has the size property). They also supports the use of for...of on an object implementing this interface. The set-like can be prefixed readonly or not. If not read-only, the methods to modify the set are also implemented: add(), clear(), and delete().

setlike<valueType>

The generated properties will be:

In the case, the set-like declaration is not prefixed by read-only, the following methods are also generated:

Such an set interface also allows to use the syntax for (var p in object) as a shorthand of for (var p in object.entries()). We add a sentence about it in the interface description. E.g. FontFaceSet.

Specials methods: toString() and toJSON()

Two methods are not listed as regular methods in WebIDL but as special keywords; they are then translated to specific JavaScript methods.

A stringifier is mapped to toString() and defined as:

stringifier;

The toString() method is listed just like any other method of the interface and has its own sub-page (E.g. Range.toString())

A jsonifier is mapped to toJSON() and defined as:

jsonifier; // Gecko version
serializer; // Standard version

The toJSON() method is listed just like any other method of the interface and has its own sub-page (E.g. Performance.toJSON())

Note: the WebIDL specification uses serializer instead of jsonifier. This is not used in Gecko — only the non-standard likely early proposal jsonifier is found in mozilla-central.

Constructors

Constructors are a little bit hidden in WebIDL: they are listed as annotations of the main interface.

Unnamed constructors

This is the most common case for constructors. The constructor of a given interface A, can be used as a = new A(parameters);

 [Constructor, Func="MessageChannel::Enabled",
  Exposed=(Window,Worker)]
    interface MessageChannel {…};

A constructor with the same interface is defined using the Constructor annotation on the interface. There can be parenthesis and a list of parameters or not (like in the above example.) We document all the unnamed constructors on a sub-page — for example the above is given the slug Web/API/MessageChannel/MessageChannel and the title MessageChannel().

Another example of an unnamed constructor, with parameters:

[Constructor(DOMString type, optional MessageEventInit eventInitDict),
 Exposed=(Window,Worker,System)]
   interface MessageEvent : Event {…};

There can also be several unnamed constructors, differing by their parameter lists. All syntax is documented in one single sub-page.

[Constructor(DOMString url, URL base),
 Constructor(DOMString url, optional DOMString base),
 Exposed=(Window,Worker)]
    interface URL {};

Named constructors

[NamedConstructor=Image(optional unsigned long width, optional unsigned long height)]
    interface HTMLImageElement : HTMLElement {…

A named constructor is a constructor that has a different name than that of its interface. For example new Image(…) creates a new HTMLImageElement object. They are defined in the WebIDL using the NamedConstructor annotation on the interface, followed by the name of the constructor after the equality sign ('=') and the parameter inside the parenthesis, in the same format as you'll see for methods.

There can be several named constructors for a specific interface, but this is extremely rare; in such a case we include one sub-page per name.

Availability in workers

Constructors have the same availability as the interface, or partial interface, they are defined on. The sub-page provides this information in the same way as for a method.

Preferences

Constructors are controlled by the same preference as the interface, or partial interface, they are defined on. The sub-page provides this information in the same way as for a method.

Document Tags and Contributors

 Contributors to this page: teoli, Bzbarsky, overholt, markg, jswisher, jryans, chrisdavidmills
 Last updated by: teoli,