Copyright © 2013 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved. W3C liability, trademark and document use rules apply.
This specification describes the method for enabling the author to define and use new types of DOM elements in a document.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
Publication as a First Public Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
This document was published by the Web Applications Working Group as an Editor's Draft. If you wish to make comments regarding this document, please send them to public-webapps@w3.org (subscribe, archives). All feedback is welcome.
Publication as an Editor's Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
All diagrams, examples, notes, are non-normative, as well as sections explicitly marked as non-normative. Everything else in this specification is normative.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in the normative parts of this document are to be interpreted as described in RFC2119. For readability, these words do not appear in all uppercase letters in this specification.
Any point, at which a conforming UA must make decisions about the state or reaction to the state of the conceptual model, is captured as algorithm. The algorithms are defined in terms of processing equivalence. The processing equivalence is a constraint imposed on the algorithm implementors, requiring the output of the both UA-implemented and the specified algorithm to be exactly the same for all inputs.
This document relies on the following specifications:
Custom element is platform object whose interface is defined by the author. This interface must inherit from the Element
interface. The interface prototype object of a custom element's interface is called the custom element prototype.
The custom element name identifies a custom element and is a sequence of alphanumeric ASCII characters that must match the NCName production and contain a U+002D HYPHEN-MINUS character. The custom element name must not be one of the following values:
annotation-xml
color-profile
font-face
font-face-src
font-face-uri
font-face-format
font-face-name
missing-glyph
The element definition is an association of a custom element name, local name and a namespace with a custom element prototype, and lifecycle callbacks.
A custom element can go through these changes during its lifetime:
A custom element can optionally implement several callbacks that are invoked when the element goes through some of these changes. These callbacks are stored internally as a collection of key-value pairs and called lifecycle callbacks.
To transfer a callback named name from an object property named property to lifecycle callbacks, the user agent must run the following steps:
To retrieve a callback named name for an element, the user agent must run the following steps:
Each unit of related similar-origin browsing contexts has an associated lifecycle callbacks queue, which is initially empty. Each item in the queue consists of the callback and the callback this value.
Also, each unit of related similar-origin contexts has a running lifecycle callbacks flag, which must initially be false. It is used to prevent reentrant invocation of the algorithm to invoke lifecycle callbacks.
To invoke lifecycle callbacks, a conforming user agent must run the following steps or their equivalent:
The following callbacks are recognized:
Element registration is a process of associating an element definition with a document. An element definition can only be registered with one document. Once registered, the custom element's interface must be the element interface for local name and namespace values of custom element name and the namespace in custom element definition, respectively.
Because element registration can occur at any time, a custom element could be created before it is registered. Such custom element instances are called unresolved elements. When an unresolved element is created, and if its element interface was not defined by HTML or other applicable specifications, the unresolved element's element interface must be:
HTMLElement
, if the namespace is HTML Namespace;SVGElement
, if namespace is SVG Namespace; orEach browsing context has an associated map of all instances of unresolved elements for a given pair of custom element name and namespace. This data structure is called the upgrade candidates map and is initially empty.
Whenever an unresolved element is created, it must be added to the upgrade candidates map.
As an element definition is registered, all corresponding unresolved elements are upgraded using the element upgrade algorithm, which must be equivalent to running these steps:
[[Prototype]]
internal property of ELEMENT to PROTOTYPEThe register
method of the Document interface provides a way to register a custom element and returns its custom element constructor.
partial interface Document {
Function register(DOMString name, optional ElementRegistrationOptions options);
};
dictionary ElementRegistrationOptions {
object? prototype = null;
};
When called, the register
method must run these steps:
InvalidCharacterError
and stop.Object.create
with HTMLElement
's interface prototype object as only argumentNotSupportedError
and stop.SVGElement
, set NAMESPACE to SVG NamespaceHTMLElement
, throw a NamespaceError
and stop.HTMLElement
or SVGElement
, let NAME be the local name, associated with BASE element interfaceNotSupportedError
and stop.ElementRegistrationOptions
is an abstraction that enables using function objects and ES6 classes as the second argument of document.register
method.
The element upgrade and invoking lifecycle callbacks is intentionally decoupled to provide slightly more sensible outcomes of callbacks trying to access methods and properties of custom elements of the same kind. Also, because of when lifecycle callbacks are added to the lifecycle callbacks queue, the queue should be empty when document.register
is invoked.
In order to register a custom element with a prototype, other than HTMLElement
or SVGElement
, the caller of document.register
has to first build a proper prototype object that inherits from HTMLElement
. Here's a simple example of how one could do this:
document.register('x-foo', {
prototype: Object.create(HTMLParagraphElement.prototype, {
firstMember: {
get: function() { return foo; },
enumerable: true,
configurable: true
},
// specify more members for your prototype.
// ...
})
});
The :unresolved
pseudoclass must match all unresolved elements.
The :unresolved
pseudoclass could be used to mitigate the Flash of Unstyled Content (FOUC) issues with custom elements.
The custom element name is given to a custom element at the time of its instantation in one of the two ways:
is
attribute of the custom element. Custom element names given this way are called type extensions.After a custom element is instantiated, changing the value of the is
attribute must not affect this element's custom element name.
If both types of custom element names are provided at the time of element's instantiation, the custom tag must win over the type extension.
All custom elements must be constructable with a function object, called custom element constructor. This constructor must be created with the custom element constructor generation algorithm, which must be equivalent to running these steps:
constructor
, throw a NotSupportedError
and stop.is
attribute to TYPETo allow creating both custom tag and type extension-style custom elements, the createElement
or createElementNS
methods have an optional typeExtension
argument:
partial interface Document {
Element createElement(DOMString localName, optional DOMString typeExtension);
Element createElementNS(DOMString? namespace, DOMString qualifiedName, optional DOMString typeExtension);
};
Instead of step 3 in createElement
and step 9 in createElementNS
(the steps that determine element interface, both methods must run the following
steps:
createElement
)Additionally, both createElement
or createElementNS
methods must run the following steps just before returning the result:
is
attribute to TYPEThe element initialization algorithm must be equivalent to running these steps:
null
, invoke READY callback with callback this value of ELEMENTTo enable instantiating custom elements during tree construction, a conforming UA must run these steps when creating an element for a token:
is
attribute for the token or NAME, if this attribute is not presentThis modification to creating an element for a token has the consequence of custom elements being created when parsing HTML documents or fragments.
In addition, just before the user agent is to perform a microtask checkpoint, the user agent must invoke lifecycle callbacks for the unit of related similar-origin browsing contexts to which the scripts' browsing context belongs.
The custom elements must be serialized like any HTML elements.
Specify how custom elements are defined declaratively.
David Hyatt developed XBL 1.0, and Ian Hickson co-wrote XBL 2.0. These documents provided tremendous insight into the problem of behavior attachment and greatly influenced this specification.
Alex Russell and his considerable forethought triggered a new wave of enthusiasm around the subject of behavior attachment and how it can be applied practically on the Web.
Dominic Cooney, Hajime Morrita, and Roland Steiner worked tirelessly to scope the problem within the confines of the Web platform and provided a solid foundation for this document.
The editor would also like to thank Alex Komoroske, Anne van Kesteren, Boris Zbarsky, Daniel Buchner, Edward O'Connor, Erik Arvidsson, Elliott Sprehn, Hayato Ito, Jonas Sicking, Olli Pettay, Rafael Weinstein, Scott Miles, Steve Orvell, Tab Atkins, and William Chen for their comments and contributions to this specification.
This list is too short. There's a lot of work left to do. Please contribute by reviewing and filing bugs—and don't forget to ask the editor to add your name into this section.