Group: WHATWG H1: DOM Shortname: dom Text Macro: TWITTER thedomstandard Text Macro: LATESTRD 2026-06 Abstract: DOM defines a platform-neutral model for events, aborting activities, and node trees. Translation: ja https://triple-underscore.github.io/DOM4-ja.html Translation: zh-Hans https://htmlspecs.com/dom/ Translation: ko https://ko.htmlspecs.com/dom/ Translate IDs: slottable slotable Indent: 1
urlPrefix: https://www.w3.org/TR/xml/#NT-; spec: XML type: dfn text: Name; url: Name; for: XML urlPrefix: https://www.w3.org/TR/xml-stylesheet/#; spec: XML-STYLESHEET type: dfn text: rules for parsing pseudo-attributes from a string; url: dt-parsing text: parsing result; url: dt-parsing-result text: pseudo-attribute; url: dt-pseudo-attribute text: name; url: dt-name; for: pseudo-attribute text: value; url: dt-value; for: pseudo-attribute url: https://w3c.github.io/DOM-Parsing/#dom-range-createcontextualfragment type: method; text: createContextualFragment(); for: Range type: interface url: https://w3c.github.io/touch-events/#idl-def-touchevent text: TouchEvent url: https://w3c.github.io/deviceorientation/spec-source-orientation.html#devicemotion text: DeviceMotionEvent text: DeviceOrientationEvent urlPrefix: https://tc39.es/ecma262/#; spec: ECMASCRIPT text: Construct; url: sec-construct; type: abstract-op type: dfn text: current realm; url: current-realm text: realm; url: realm text: surrounding agent; url: surrounding-agent urlPrefix: https://w3c.github.io/hr-time/#; spec: HR-TIME type:typedef; urlPrefix: dom-; text: DOMHighResTimeStamp type:dfn; text: current high resolution time; url: dfn-current-high-resolution-time type:dfn; text: relative high resolution coarse time; url: dfn-relative-high-resolution-coarse-time
spec:html; type:element text: head text: script text: title
This specification depends on the Infra Standard. [[!INFRA]]
Some of the terms used in this specification are defined in Encoding, Selectors, Trusted Types, Web IDL, XML, Namespaces in XML, and Associating Style Sheets with XML documents. [[!ENCODING]] [[!SELECTORS4]] [[!TRUSTED-TYPES]] [[!WEBIDL]] [[!XML]] [[!XML-NAMES]] [[!XML-STYLESHEET]]
When extensions are needed, the DOM Standard can be updated accordingly, or a new standard can be written that hooks into the provided extensibility hooks for applicable specifications.
A tree is a finite hierarchical tree structure. In tree order is preorder, depth-first traversal of a tree.
An object that participates in a tree has a parent, which is either null or an object, and has children, which is an ordered set of objects. An object A whose parent is object B is a child of B.
The root of an object is itself, if its parent is null, or else it is the root of its parent. The root of a tree is any object participating in that tree whose parent is null.
An object A is called a descendant of an object B, if either A is a child of B or A is a child of an object C that is a descendant of B.
An inclusive descendant is an object or one of its descendants.
An object A is called an ancestor of an object B if and only if B is a descendant of A.
An inclusive ancestor is an object or one of its ancestors.
An object A is called a sibling of an object B, if and only if B and A share the same non-null parent.
An inclusive sibling is an object or one of its siblings.
An object A is preceding an object B if A and B are in the same tree and A comes before B in tree order.
An object A is following an object B if A and B are in the same tree and A comes after B in tree order.
The first child of an object is its first child or null if it has no children.
The last child of an object is its last child or null if it has no children.
The previous sibling of an object is its first preceding sibling or null if it has no preceding sibling.
The next sibling of an object is its first following sibling or null if it has no following sibling.
The index of an object is its number of preceding siblings, or 0 if it has none.
The ordered set parser takes a string input and then runs these steps:
Let inputTokens be the result of splitting input on ASCII whitespace.
Let tokens be a new ordered set.
The ordered set serializer takes a set and returns the concatenation of set using U+0020 SPACE.
To scope-match a selectors string given a string selectors against a node node:
Let selector be the result of parse a selector selectors. [[!SELECTORS4]]
If selector is failure, then throw a "{{SyntaxError!!exception}}" {{DOMException}}.
Return the result of match a selector against a tree with selector and node's root using scoping root node. [[!SELECTORS4]].
Support for namespaces within selectors is not planned and will not be added.
A [=string=] is a valid namespace prefix if its [=string/length=] is at least 1 and it does not contain [=ASCII whitespace=], U+0000 NULL, U+002F (/), or U+003E (>).
A [=string=] is a valid attribute local name if its [=string/length=] is at least 1 and it does not contain [=ASCII whitespace=], U+0000 NULL, U+002F (/), U+003D (=), or U+003E (>).
A [=string=] |name| is a valid element local name if the following steps return true:
If |name|'s [=string/length=] is 0, then return false.
If |name|'s 0th [=code point=] is an [=ASCII alpha=]:
If |name| contains [=ASCII whitespace=], U+0000 NULL, U+002F (/), or U+003E (>), then return false.
Return true.
If |name|'s 0th [=code point=] is not U+003A (:), U+005F (_), or in the range U+0080 to U+10FFFF, inclusive, then return false.
If |name|'s subsequent [=code points=], if any, are not [=ASCII alphas=], [=ASCII digits=], U+002D (-), U+002E (.), U+003A (:), U+005F (_), or in the range U+0080 to U+10FFFF, inclusive, then return false.
Return true.
This concept is used to validate [=/element=] [=Element/local names=], when constructed by DOM APIs. The intention is to allow any name that is possible to construct using the HTML parser (the branch where the first [=code point=] is an [=ASCII alpha=]), plus some additional possibilities. For those additional possibilities, the ASCII range is restricted for historical reasons, but beyond ASCII anything is allowed.
The following JavaScript-compatible regular expression is an implementation of [=valid element local name=]:
/^(?:[A-Za-z][^\0\t\n\f\r\u0020/>]*|[:_\u0080-\u{10FFFF}][A-Za-z0-9-.:_\u0080-\u{10FFFF}]*)$/u
A [=string=] is a valid doctype name if it does not contain [=ASCII whitespace=], U+0000 NULL, or U+003E (>).
The empty string is a [=valid doctype name=].
To validate and extract a namespace and qualifiedName, given a context:
If namespace is the empty string, then set it to null.
Let prefix be null.
Let localName be qualifiedName.
If qualifiedName contains a U+003A (:):
Set prefix to the part of qualifiedName before the first U+003A (:).
Set localName to the part of qualifiedName after the first U+003A (:).
If prefix is not a [=valid namespace prefix=], then [=throw=] an "{{InvalidCharacterError}}" {{DOMException}}.
Assert: prefix is either null or a [=valid namespace prefix=].
If context is "attribute" and localName is not a
[=valid attribute local name=], then [=throw=] an "{{InvalidCharacterError}}" {{DOMException}}.
If context is "element" and localName is not a
[=valid element local name=], then [=throw=] an "{{InvalidCharacterError}}" {{DOMException}}.
If prefix is non-null and namespace is null, then throw a "{{NamespaceError!!exception}}" {{DOMException}}.
If prefix is "xml" and namespace is not the
XML namespace, then throw a "{{NamespaceError!!exception}}" {{DOMException}}.
If either qualifiedName or prefix is "xmlns" and
namespace is not the XMLNS namespace, then throw a
"{{NamespaceError!!exception}}" {{DOMException}}.
If namespace is the XMLNS namespace and neither qualifiedName
nor prefix is "xmlns", then throw a "{{NamespaceError!!exception}}"
{{DOMException}}.
Return (namespace, prefix, localName).
Various APIs in this specification used to validate namespace prefixes, attribute local names, element local names, and doctype names more strictly. This was done in a way that aligned with various XML-related specifications. (Although not all rules from the those specifications were enforced.)
This was found to be annoying for web developers, especially since it meant there were some names that could be created by the HTML parser, but not by DOM APIs. So, the validations have been loosened to just those described above.
obj.addEventListener("load", imgFetched)
function imgFetched(ev) {
// great success
…
}
Event listeners can be removed
by utilizing the
{{EventTarget/removeEventListener()}}
method, passing the same arguments.
Alternatively, event listeners can be removed by passing an {{AbortSignal}} to
{{EventTarget/addEventListener()}} and calling {{AbortController/abort()}} on the controller
owning the signal.
Events are objects too and implement the
{{Event}} interface (or a derived interface). In the example above
ev is the event. ev is
passed as an argument to the
event listener's callback
(typically a JavaScript Function as shown above).
Event listeners key off the
event's
{{Event/type}} attribute value
("load" in the above example). The
event's
{{Event/target}} attribute value returns the
object to which the event was
dispatched
(obj above).
Although events are typically dispatched by the user agent as the result of user interaction or the completion of some task, applications can dispatch events themselves by using what are commonly known as synthetic events:
// add an appropriate event listener
obj.addEventListener("cat", function(e) { process(e.detail) })
// create and dispatch the event
var event = new CustomEvent("cat", {"detail":{"hazcheeseburger":true}})
obj.dispatchEvent(event)
Apart from signaling, events are
sometimes also used to let an application control what happens next in an
operation. For instance as part of form submission an
event whose
{{Event/type}} attribute value is
"submit" is
dispatched. If this
event's
{{Event/preventDefault()}} method is
invoked, form submission will be terminated. Applications who wish to make
use of this functionality through events
dispatched by the application
(synthetic events) can make use of the return value of the
{{EventTarget/dispatchEvent()}} method:
if(obj.dispatchEvent(event)) {
// event was not canceled, time for some magic
…
}
When an event is dispatched to an object that participates in a tree (e.g., an element), it can reach event listeners on that object's ancestors too. Effectively, all the object's inclusive ancestor event listeners whose capture is true are invoked, in tree order. And then, if event's {{Event/bubbles}} is true, all the object's inclusive ancestor event listeners whose capture is false are invoked, now in reverse tree order.
Let's look at an example of how events work in a tree:
<!doctype html>
<html>
<head>
<title>Boring example</title>
</head>
<body>
<p>Hello <span id=x>world</span>!</p>
<script>
function test(e) {
debug(e.target, e.currentTarget, e.eventPhase)
}
document.addEventListener("hey", test, {capture: true})
document.body.addEventListener("hey", test)
var ev = new Event("hey", {bubbles:true})
document.getElementById("x").dispatchEvent(ev)
</script>
</body>
</html>
The debug function will be invoked twice. Each time the event's
{{Event/target}} attribute value will be the span element. The first time
{{Event/currentTarget}} attribute's value will be the document, the second time the
body element. {{Event/eventPhase}} attribute's value switches from
{{Event/CAPTURING_PHASE}} to {{Event/BUBBLING_PHASE}}. If an event listener was registered
for the span element, {{Event/eventPhase}} attribute's value would have
been {{Event/AT_TARGET}}.
[Exposed=*]
interface Event {
constructor(DOMString type, optional EventInit eventInitDict = {});
readonly attribute DOMString type;
readonly attribute EventTarget? target;
readonly attribute EventTarget? srcElement; // legacy
readonly attribute EventTarget? currentTarget;
sequence<EventTarget> composedPath();
const unsigned short NONE = 0;
const unsigned short CAPTURING_PHASE = 1;
const unsigned short AT_TARGET = 2;
const unsigned short BUBBLING_PHASE = 3;
readonly attribute unsigned short eventPhase;
undefined stopPropagation();
attribute boolean cancelBubble; // legacy alias of .stopPropagation()
undefined stopImmediatePropagation();
readonly attribute boolean bubbles;
readonly attribute boolean cancelable;
attribute boolean returnValue; // legacy
undefined preventDefault();
readonly attribute boolean defaultPrevented;
readonly attribute boolean composed;
[LegacyUnforgeable] readonly attribute boolean isTrusted;
readonly attribute DOMHighResTimeStamp timeStamp;
undefined initEvent(DOMString type, optional boolean bubbles = false, optional boolean cancelable = false); // legacy
};
dictionary EventInit {
boolean bubbles = false;
boolean cancelable = false;
boolean composed = false;
};
An {{Event}} object is simply named an event. It allows for signaling that something has occurred, e.g., that an image has completed downloading.
A potential event target is null or an {{EventTarget}} object.
An event has an associated target (a potential event target). Unless stated otherwise it is null.
An event has an associated relatedTarget (a potential event target). Unless stated otherwise it is null.
Other specifications use relatedTarget to define a
relatedTarget attribute. [[UIEVENTS]]
An event has an associated touch target list (a list of zero or more potential event targets). Unless stated otherwise it is the empty list.
The touch target list is for the exclusive use of defining the {{TouchEvent}} interface and related interfaces. [[TOUCH-EVENTS]]
An event has an associated path. A path is a list of event path items. An event path item is a struct consisting of an invocation target (an {{EventTarget}} object), an invocation-target-in-shadow-tree (a boolean), a shadow-adjusted target (a potential event target), a relatedTarget (a potential event target), a touch target list (a list of potential event targets), a root-of-closed-tree (a boolean), and a slot-in-closed-tree (a boolean). A path is initially the empty list.
event = new Event(type [, eventInitDict])
event . {{Event/type}}
click", "hashchange", or
"submit".
event . {{Event/target}}
event . {{Event/currentTarget}}
event . {{Event/composedPath()}}
closed" that are not reachable from event's
{{Event/currentTarget}}.
event . {{Event/eventPhase}}
event . stopPropagation()
event . stopImmediatePropagation()
event . {{Event/bubbles}}
event . {{Event/cancelable}}
event . preventDefault()
event . {{Event/defaultPrevented}}
event . {{Event/composed}}
event . {{Event/isTrusted}}
event . {{Event/timeStamp}}
The type attribute must return the value it was
initialized to. When an event is created the attribute must be initialized to the empty
string.
The target getter steps are to return this's
target.
The srcElement getter steps are to return
this's target.
The currentTarget attribute must return the value it
was initialized to. When an event is created the attribute must be initialized to null.
The composedPath() method steps are:
Let composedPath be an empty list.
If path is empty, then return composedPath.
Let currentTarget be this's {{Event/currentTarget}} attribute value.
Assert: currentTarget is an {{EventTarget}} object.
Append currentTarget to composedPath.
Let currentTargetIndex be 0.
Let currentTargetHiddenSubtreeLevel be 0.
Let index be path's size − 1.
While index is greater than or equal to 0:
If path[index]'s root-of-closed-tree is true, then increase currentTargetHiddenSubtreeLevel by 1.
If path[index]'s invocation target is currentTarget, then set currentTargetIndex to index and break.
If path[index]'s slot-in-closed-tree is true, then decrease currentTargetHiddenSubtreeLevel by 1.
Decrease index by 1.
Let currentHiddenLevel and maxHiddenLevel be currentTargetHiddenSubtreeLevel.
Set index to currentTargetIndex − 1.
While index is greater than or equal to 0:
If path[index]'s root-of-closed-tree is true, then increase currentHiddenLevel by 1.
If currentHiddenLevel is less than or equal to maxHiddenLevel, then prepend path[index]'s invocation target to composedPath.
If path[index]'s slot-in-closed-tree is true:
Decrease currentHiddenLevel by 1.
If currentHiddenLevel is less than maxHiddenLevel, then set maxHiddenLevel to currentHiddenLevel.
Decrease index by 1.
Set currentHiddenLevel and maxHiddenLevel to currentTargetHiddenSubtreeLevel.
Set index to currentTargetIndex + 1.
While index is less than path's size:
If path[index]'s slot-in-closed-tree is true, then increase currentHiddenLevel by 1.
If currentHiddenLevel is less than or equal to maxHiddenLevel, then append path[index]'s invocation target to composedPath.
If path[index]'s root-of-closed-tree is true:
Decrease currentHiddenLevel by 1.
If currentHiddenLevel is less than maxHiddenLevel, then set maxHiddenLevel to currentHiddenLevel.
Increase index by 1.
Return composedPath.
The eventPhase attribute must return the value it was
initialized to, which must be one of the following:
Initially the attribute must be initialized to {{Event/NONE}}.
Each event has the following associated flags that are all initially unset:
The stopPropagation() method steps are to set
this's stop propagation flag.
The cancelBubble getter steps are to return true if
this's stop propagation flag is set; otherwise false.
The {{Event/cancelBubble}} setter steps are to set this's stop propagation flag if the given value is true; otherwise do nothing.
The stopImmediatePropagation() method steps are to set
this's stop propagation flag and this's
stop immediate propagation flag.
The bubbles and
cancelable attributes must return the values they were
initialized to.
To set the canceled flag, given an event event, if event's {{Event/cancelable}} attribute value is true and event's in passive listener flag is unset, then set event's canceled flag, and do nothing otherwise.
The returnValue getter steps are to return false if
this's canceled flag is set; otherwise true.
The {{Event/returnValue}} setter steps are to set the canceled flag with this if the given value is false; otherwise do nothing.
The preventDefault() method steps are to
set the canceled flag with this.
There are scenarios where invoking {{Event/preventDefault()}} has no effect. User agents are encouraged to log the precise cause in a developer console, to aid debugging.
The defaultPrevented getter steps are to return true
if this's canceled flag is set; otherwise false.
The composed getter steps are to return true if
this's composed flag is set; otherwise false.
The isTrusted attribute must return the value it was
initialized to. When an event is created the attribute must be initialized to false.
{{Event/isTrusted}} is a convenience that indicates whether an event is dispatched by the user agent (as opposed to using {{EventTarget/dispatchEvent()}}). The sole legacy exception is {{HTMLElement/click()}}, which causes the user agent to dispatch an event whose {{Event/isTrusted}} attribute is initialized to false.
The timeStamp attribute must return the value it was
initialized to.
To initialize an event, with type, bubbles, and cancelable, run these steps:
Set event's initialized flag.
Unset event's stop propagation flag, stop immediate propagation flag, and canceled flag.
Set event's {{Event/isTrusted}} attribute to false.
Set event's target to null.
Set event's {{Event/type}} attribute to type.
Set event's {{Event/bubbles}} attribute to bubbles.
Set event's {{Event/cancelable}} attribute to cancelable.
The
initEvent(type, bubbles, cancelable)
method steps are:
If this's dispatch flag is set, then return.
Initialize this with type, bubbles, and cancelable.
{{Event/initEvent()}} is redundant with event constructors and incapable of setting {{Event/composed}}. It has to be supported for legacy content.
partial interface Window {
[Replaceable] readonly attribute (Event or undefined) event; // legacy
};
Each {{Window}} object has an associated current event (undefined or an {{Event}} object). Unless stated otherwise it is undefined.
The event getter steps are to return this's
current event.
Web developers are strongly encouraged to instead rely on the {{Event}} object passed to event listeners, as that will result in more portable code. This attribute is not available in workers or worklets, and is inaccurate for events dispatched in shadow trees.
[Exposed=*]
interface CustomEvent : Event {
constructor(DOMString type, optional CustomEventInit eventInitDict = {});
readonly attribute any detail;
undefined initCustomEvent(DOMString type, optional boolean bubbles = false, optional boolean cancelable = false, optional any detail = null); // legacy
};
dictionary CustomEventInit : EventInit {
any detail = null;
};
Events using the
{{CustomEvent}} interface can be used to carry custom data.
event = new CustomEvent(type [, eventInitDict])
event . {{CustomEvent/detail}}
The detail attribute must return the value it
was initialized to.
The
initCustomEvent(type, bubbles, cancelable, detail)
method steps are:
If this's dispatch flag is set, then return.
Initialize this with type, bubbles, and cancelable.
Set this's {{CustomEvent/detail}} attribute to detail.
This construct can be used by {{Event}} subclasses that have a more complex structure than a simple 1:1 mapping between their initializing dictionary members and IDL attributes.
When a constructor of the {{Event}} interface, or of an interface that inherits from the {{Event}} interface, is invoked, these steps must be run, given the arguments type and eventInitDict:
Let event be the result of running the inner event creation steps with this interface, null, now, and eventInitDict.
Initialize event's {{Event/type}} attribute to type.
Return event.
To create an event using eventInterface, which must be either {{Event}} or an interface that inherits from it, and optionally given a realm realm, run these steps:
If realm is not given, then set it to null.
Let dictionary be the result of converting the JavaScript value undefined to the dictionary type accepted by eventInterface's constructor. (This dictionary type will either be {{EventInit}} or a dictionary that inherits from it.)
This does not work if members are required; see whatwg/dom#600.
Let event be the result of running the inner event creation steps with eventInterface, realm, the time of the occurrence that the event is signaling, and dictionary.
In macOS the time of the occurrence for input
actions is available via the timestamp property of NSEvent objects.
Initialize event's {{Event/isTrusted}} attribute to true.
Return event.
Create an event is meant to be used by other specifications which need to separately create and dispatch events, instead of simply firing them. It ensures the event's attributes are initialized to the correct defaults.
The inner event creation steps, given an eventInterface, realm, time, and dictionary, are as follows:
Let event be the result of creating a new object using eventInterface. If realm is non-null, then use that realm; otherwise, use the default behavior defined in Web IDL.
As of the time of this writing Web IDL does not yet define any default behavior; see whatwg/webidl#135.
Set event's initialized flag.
Initialize event's {{Event/timeStamp}} attribute to the relative high resolution coarse time given time and event's relevant global object.
For each member → value of dictionary: if event has an attribute whose identifier is member, then initialize that attribute to value.
Run the event constructing steps with event and dictionary.
Return event.
init*Event()
methods as they are redundant with constructors. Interfaces that inherit
from the {{Event}} interface that have such a method only have it
for historical reasons.
[Exposed=*]
interface EventTarget {
constructor();
undefined addEventListener(DOMString type, EventListener? callback, optional (AddEventListenerOptions or boolean) options = {});
undefined removeEventListener(DOMString type, EventListener? callback, optional (EventListenerOptions or boolean) options = {});
boolean dispatchEvent(Event event);
};
callback interface EventListener {
undefined handleEvent(Event event);
};
dictionary EventListenerOptions {
boolean capture = false;
};
dictionary AddEventListenerOptions : EventListenerOptions {
boolean passive;
boolean once = false;
AbortSignal signal;
};
An {{EventTarget}} object represents a target to which an event can be dispatched when something has occurred.
Each {{EventTarget}} object has an associated event listener list (a list of zero or more event listeners). It is initially the empty list.
An event listener can be used to observe a specific event and consists of:
Although callback is an {{EventListener}} object, an event listener is a broader concept as can be seen above.
Each {{EventTarget}} object also has an associated get the parent algorithm, which takes an event event, and returns an {{EventTarget}} object. Unless specified otherwise it returns null.
Nodes, shadow roots, and documents override the get the parent algorithm.
Each {{EventTarget}} object can have an associated activation behavior algorithm. The activation behavior algorithm is passed an event, as indicated in the dispatch algorithm.
This exists because user agents perform certain actions for certain
{{EventTarget}} objects, e.g., the <{area}> element, in response to synthetic {{MouseEvent}}
events whose {{Event/type}} attribute is click. Web compatibility prevented it
from being removed and it is now the enshrined way of defining an activation of something. [[!HTML]]
Each {{EventTarget}} object that has activation behavior, can additionally have both (not either) a legacy-pre-activation behavior algorithm and a legacy-canceled-activation behavior algorithm.
These algorithms only exist for checkbox and radio <{input}> elements and are not to be used for anything else. [[!HTML]]
target = new EventTarget();
Creates a new {{EventTarget}} object, which can be used by developers to dispatch and listen for events.
target . addEventListener(type, callback [, options])
Appends an event listener for events whose {{Event/type}} attribute value is type. The callback argument sets the callback that will be invoked when the event is dispatched.
The options argument sets listener-specific options. For compatibility this can be a boolean, in which case the method behaves exactly as if the value was specified as options's {{EventListenerOptions/capture}}.
When set to true, options's {{EventListenerOptions/capture}} prevents callback from being invoked when the event's {{Event/eventPhase}} attribute value is {{Event/BUBBLING_PHASE}}. When false (or not present), callback will not be invoked when event's {{Event/eventPhase}} attribute value is {{Event/CAPTURING_PHASE}}. Either way, callback will be invoked if event's {{Event/eventPhase}} attribute value is {{Event/AT_TARGET}}.
When set to true, options's {{AddEventListenerOptions/passive}} indicates that the callback will not cancel the event by invoking {{Event/preventDefault()}}. This is used to enable performance optimizations described in [[#observing-event-listeners]].
When set to true, options's {{AddEventListenerOptions/once}} indicates that the callback will only be invoked once after which the event listener will be removed.
If an {{AbortSignal}} is passed for options's {{AddEventListenerOptions/signal}}, then the event listener will be removed when signal is aborted.
The event listener is appended to target's event listener list and is not appended if it has the same type, callback, and capture.
target . removeEventListener(type, callback [, options])
Removes the event listener in target's event listener list with the same type, callback, and options.
target . dispatchEvent(event)
Dispatches a synthetic event event to target and returns true if either event's {{Event/cancelable}} attribute value is false or its {{Event/preventDefault()}} method was not invoked; otherwise false.
To flatten options, run these steps:
If options is a boolean, then return options.
Return |options|["{{EventListenerOptions/capture}}"].
To flatten more options, run these steps:
Let capture be the result of flattening options.
Let once be false.
Let |passive| and |signal| be null.
If |options| is a dictionary:
Set |once| to |options|["{{AddEventListenerOptions/once}}"].
If |options|["{{AddEventListenerOptions/passive}}"] [=map/exists=], then set |passive| to |options|["{{AddEventListenerOptions/passive}}"].
If |options|["{{AddEventListenerOptions/signal}}"] [=map/exists=], then set |signal| to |options|["{{AddEventListenerOptions/signal}}"].
Return capture, passive, once, and signal.
The new EventTarget()
constructor steps are to do nothing.
Because of the defaults stated elsewhere, the returned {{EventTarget}}'s get the parent algorithm will return null, and it will have no activation behavior, legacy-pre-activation behavior, or legacy-canceled-activation behavior.
In the future we could allow custom get the parent algorithms. If this would be useful, support issue #583. For now, all author-created {{EventTarget}}s do not participate in a tree structure.
The default passive value, given an event type |type| and an {{EventTarget}} |eventTarget|, is determined as follows:
Return true if all of the following are true:
|type| is one of "touchstart", "touchmove",
"wheel", or "mousewheel". [[TOUCH-EVENTS]] [[UIEVENTS]]
|eventTarget| is a {{Window}} object, or is a node whose node document is |eventTarget|, or is a node whose node document's document element is |eventTarget|, or is a node whose node document's body element is |eventTarget|. [[!HTML]]
Return false.
To add an event listener, given an {{EventTarget}} object eventTarget and an event listener listener, run these steps:
If eventTarget is a {{ServiceWorkerGlobalScope}} object, its service worker's script resource's has ever been evaluated flag is set, and listener's type matches the {{Event/type}} attribute value of any of the service worker events, then report a warning to the console that this might not give the expected results. [[!SERVICE-WORKERS]]
If listener's signal is non-null and is [=AbortSignal/aborted=], then return.
If listener's callback is null, then return.
If listener's passive is null, then set it to the default passive value given listener's type and eventTarget.
If eventTarget's event listener list does not contain an event listener whose type is listener's type, callback is listener's callback, and capture is listener's capture, then append listener to eventTarget's event listener list.
If listener's signal is non-null, then add the following abort steps to it:
The add an event listener concept exists to ensure event handlers use the same code path. [[HTML]]
The
addEventListener(type, callback, options)
method steps are:
Let capture, passive, once, and signal be the result of flattening more options.
Add an event listener with this and an event listener whose type is type, callback is callback, capture is capture, passive is passive, once is once, and signal is signal.
To remove an event listener, given an {{EventTarget}} object eventTarget and an event listener listener, run these steps:
If eventTarget is a {{ServiceWorkerGlobalScope}} object and its service worker's set of event types to handle contains listener's type, then report a warning to the console that this might not give the expected results. [[!SERVICE-WORKERS]]
Set listener's removed to true and remove listener from eventTarget's event listener list.
HTML needs this to define event handlers. [[HTML]]
To remove all event listeners, given an {{EventTarget}} object eventTarget: for each listener of eventTarget's event listener list: remove an event listener with eventTarget and listener.
HTML needs this to define document.open(). [[HTML]]
The
removeEventListener(type, callback, options)
method steps are:
Let capture be the result of flattening options.
If this's event listener list contains an event listener whose type is type, callback is callback, and capture is capture, then remove an event listener with this and that event listener.
The event listener list will not contain multiple event listeners with equal type, callback, and capture, as add an event listener prevents that.
The dispatchEvent(event) method steps
are:
If event's dispatch flag is set, or if its initialized flag is not set, then throw an "{{InvalidStateError!!exception}}" {{DOMException}}.
Initialize event's {{Event/isTrusted}} attribute to false.
Return the result of dispatching event to this.
In general, developers do not expect the presence of an event listener to be observable. The impact of an event listener is determined by its callback. That is, a developer adding a no-op event listener would not expect it to have any side effects.
Unfortunately, some event APIs have been designed such that implementing them efficiently requires observing event listeners. This can make the presence of listeners observable in that even empty listeners can have a dramatic performance impact on the behavior of the application. For example, touch and wheel events which can be used to block asynchronous scrolling. In some cases this problem can be mitigated by specifying the event to be {{Event/cancelable}} only when there is at least one non-{{AddEventListenerOptions/passive}} listener. For example, non-{{AddEventListenerOptions/passive}} {{TouchEvent}} listeners must block scrolling, but if all listeners are {{AddEventListenerOptions/passive}} then scrolling can be allowed to start in parallel by making the {{TouchEvent}} uncancelable (so that calls to {{Event/preventDefault()}} are ignored). So code dispatching an event is able to observe the absence of non-{{AddEventListenerOptions/passive}} listeners, and use that to clear the {{Event/cancelable}} property of the event being dispatched.
Ideally, any new event APIs are defined such that they do not need this property. (Use whatwg/dom for discussion.)
To legacy-obtain service worker fetch event listener callbacks given a {{ServiceWorkerGlobalScope}} global, run these steps. They return a list of {{EventListener}} objects.
To dispatch an event event to an {{EventTarget}} object target, with an optional legacy target override flag and an optional legacyOutputDidListenersThrowFlag:
Set event's dispatch flag.
Let targetOverride be target, if legacy target override flag
is not given, and target's associated Document otherwise.
[[!HTML]]
legacy target override flag is only used by HTML and only when target is a {{Window}} object.
Let activationTarget be null.
Let relatedTarget be the result of retargeting event's relatedTarget against target.
Let clearTargets be false.
If target is not relatedTarget or target is event's relatedTarget:
Let touchTargets be a new list.
For each touchTarget of event's touch target list: append the result of retargeting touchTarget against target to touchTargets.
Append to an event path with event, target, targetOverride, relatedTarget, touchTargets, and false.
Let isActivationEvent be true, if event is a {{MouseEvent}} object
and event's {{Event/type}} attribute is "click"; otherwise false.
If isActivationEvent is true and target has activation behavior, then set activationTarget to target.
Let slottable be target, if target is a slottable and is assigned, and null otherwise.
Let slotInClosedTree be false.
Let parent be the result of invoking target's get the parent with event.
While parent is non-null:
If slottable is non-null:
Assert: parent is a slot.
Set slottable to null.
If parent's root is a shadow root whose
mode is "closed", then set slotInClosedTree
to true.
If parent is a slottable and is assigned, then set slottable to parent.
Let relatedTarget be the result of retargeting event's relatedTarget against parent.
Let touchTargets be a new list.
For each touchTarget of event's touch target list: append the result of retargeting touchTarget against parent to touchTargets.
If parent is a {{Window}} object, or parent is a node and target's root is a shadow-including inclusive ancestor of parent:
If isActivationEvent is true, event's {{Event/bubbles}} attribute is true, activationTarget is null, and parent has activation behavior, then set activationTarget to parent.
Append to an event path with event, parent, null, relatedTarget, touchTargets, and slotInClosedTree.
Otherwise, if parent is relatedTarget, then set parent to null.
Otherwise:
Set target to parent.
If isActivationEvent is true, activationTarget is null, and target has activation behavior, then set activationTarget to target.
Append to an event path with event, parent, target, relatedTarget, touchTargets, and slotInClosedTree.
If parent is non-null, then set parent to the result of invoking parent's get the parent with event.
Set slotInClosedTree to false.
Let clearTargetsItem be the last event path item in event's path whose shadow-adjusted target is non-null.
If clearTargetsItem's shadow-adjusted target, clearTargetsItem's relatedTarget, or an {{EventTarget}} object in clearTargetsItem's touch target list is a node whose root is a shadow root: set clearTargets to true.
If activationTarget is non-null and activationTarget has legacy-pre-activation behavior, then run activationTarget's legacy-pre-activation behavior.
For each item of event's path, in reverse order:
If item's shadow-adjusted target is non-null, then set event's {{Event/eventPhase}} attribute to {{Event/AT_TARGET}}.
Otherwise, set event's {{Event/eventPhase}} attribute to {{Event/CAPTURING_PHASE}}.
Invoke with item, event, "capturing", and
legacyOutputDidListenersThrowFlag if given.
For each item of event's path:
If item's shadow-adjusted target is non-null, then set event's {{Event/eventPhase}} attribute to {{Event/AT_TARGET}}.
Otherwise:
If event's {{Event/bubbles}} attribute is false, then continue.
Set event's {{Event/eventPhase}} attribute to {{Event/BUBBLING_PHASE}}.
Invoke with item, event, "bubbling", and
legacyOutputDidListenersThrowFlag if given.
Set event's {{Event/eventPhase}} attribute to {{Event/NONE}}.
Set event's {{Event/currentTarget}} attribute to null.
Set event's path to the empty list.
Unset event's dispatch flag, stop propagation flag, and stop immediate propagation flag.
If clearTargets is true:
Set event's target to null.
Set event's relatedTarget to null.
Set event's touch target list to the empty list.
If activationTarget is non-null:
If event's canceled flag is unset, then run activationTarget's activation behavior with event.
Otherwise, if activationTarget has legacy-canceled-activation behavior, then run activationTarget's legacy-canceled-activation behavior.
Return false if event's canceled flag is set; otherwise true.
To append to an event path, given an event event, an {{EventTarget}} object invocationTarget, a potential event target shadowAdjustedTarget, a potential event target relatedTarget, a list of potential event targets touchTargets, and a boolean slotInClosedTree:
Let invocationTargetInShadowTree be false.
If invocationTarget is a node and its root is a shadow root, then set invocationTargetInShadowTree to true.
Let rootOfClosedTree be false.
If invocationTarget is a shadow root whose mode
is "closed", then set rootOfClosedTree to true.
Append a new event path item to event's path whose invocation target is invocationTarget, invocation-target-in-shadow-tree is invocationTargetInShadowTree, shadow-adjusted target is shadowAdjustedTarget, relatedTarget is relatedTarget, touch target list is touchTargets, root-of-closed-tree is rootOfClosedTree, and slot-in-closed-tree is slotInClosedTree.
To invoke, given an event path item pathItem, an event event, a string phase, and an optional legacyOutputDidListenersThrowFlag:
Let targetItem be pathItem.
While targetItem's shadow-adjusted target is null: set targetItem to the event path item preceding targetItem in event's path.
Set event's target to targetItem's shadow-adjusted target.
Set event's relatedTarget to pathItem's relatedTarget.
Set event's touch target list to pathItem's touch target list.
If event's stop propagation flag is set, then return.
Initialize event's {{Event/currentTarget}} attribute to pathItem's invocation target.
Let listeners be a clone of event's {{Event/currentTarget}} attribute value's event listener list.
This avoids event listeners added after this point from being run. Note that removal still has an effect due to the removed field.
Let invocationTargetInShadowTree be pathItem's invocation-target-in-shadow-tree.
Let found be the result of running inner invoke with event, listeners, phase, invocationTargetInShadowTree, and legacyOutputDidListenersThrowFlag if given.
If found is false and event's {{Event/isTrusted}} attribute is true:
Let originalEventType be event's {{Event/type}} attribute value.
If event's {{Event/type}} attribute value is a match for any of the strings in the first column in the following table, set event's {{Event/type}} attribute value to the string in the second column on the same row as the matching string, and return otherwise.
| Event type | Legacy event type |
|---|---|
"animationend" | "webkitAnimationEnd"
|
"animationiteration" | "webkitAnimationIteration"
|
"animationstart" | "webkitAnimationStart"
|
"transitionend" | "webkitTransitionEnd"
|
Inner invoke with event, listeners, phase, invocationTargetInShadowTree, and legacyOutputDidListenersThrowFlag if given.
Set event's {{Event/type}} attribute value to originalEventType.
To inner invoke, given an event event, a list of event listeners listeners, a string phase, a boolean invocationTargetInShadowTree, and an optional legacyOutputDidListenersThrowFlag:
Let found be false.
For each listener of listeners, whose removed is false:
If event's {{Event/type}} attribute value is not listener's type, then continue.
Set found to true.
If phase is "capturing" and listener's
capture is false, then continue.
If phase is "bubbling" and listener's
capture is true, then continue.
If listener's once is true, then remove an event listener given event's {{Event/currentTarget}} attribute value and listener.
Let targetGlobal be event's {{Event/currentTarget}}'s node document's relevant global object if event's {{Event/currentTarget}} is a node; otherwise event's {{Event/currentTarget}}'s relevant global object.
Let listenerGlobal be listener callback's associated realm's global object.
If targetGlobal or listenerGlobal is a {{Window}} object whose
associated Document is not fully active, then
continue.
Let currentEvent be undefined.
If listenerGlobal is a {{Window}} object:
Set currentEvent to listenerGlobal's current event.
If invocationTargetInShadowTree is false, then set listenerGlobal's current event to event.
If listener's passive is true, then set event's in passive listener flag.
If listenerGlobal is a {{Window}} object, then record timing info for event listener given event and listener.
Call a user object's operation with listener's
callback, "handleEvent", « event », and
event's {{Event/currentTarget}} attribute value. If this throws an exception
exception:
Report exception for listener's callback's corresponding JavaScript object's associated realm's global object.
Set legacyOutputDidListenersThrowFlag if given.
The legacyOutputDidListenersThrowFlag is only used by Indexed Database API. [[INDEXEDDB]]
Unset event's in passive listener flag.
If listenerGlobal is a {{Window}} object, then set listenerGlobal's current event to currentEvent.
If event's stop immediate propagation flag is set, then break.
Return found.
To fire an event named e at target, optionally using an eventConstructor, with a description of how IDL attributes are to be initialized, and a legacy target override flag, run these steps:
Let recordingTimingAsTask be the result of calling start recording task time if needed given target's relevant settings object.
If eventConstructor is not given, then let eventConstructor be {{Event}}.
Let event be the result of creating an event given eventConstructor, in the relevant realm of target.
Initialize event's {{Event/type}} attribute to e.
Initialize any other IDL attributes of event as described in the invocation of this algorithm.
This also allows for the {{Event/isTrusted}} attribute to be set to false.
Let result be the result of dispatching event at target, with legacy target override flag set if set.
If recordingTimingAsTask is true:
Record task end time given the unsafe shared current time and target's relevant settings object.
Return result.
Fire in the context of DOM is short for creating, initializing, and dispatching an event. Fire an event makes that process easier to write down.
If the event needs its {{Event/bubbles}} or {{Event/cancelable}} attribute initialized,
one could write "fire an event named submit at target with its
{{Event/cancelable}} attribute initialized to true".
Or, when a custom constructor is needed, "fire an event named click at
target using {{MouseEvent}} with its {{UIEvent/detail}} attribute initialized to 1".
Occasionally the return value is important:
Let doAction be the result of firing an event named
like at target.
If doAction is true, then …
An event signifies an occurrence, not an action. Phrased differently, it represents a notification from an algorithm and can be used to influence the future course of that algorithm (e.g., through invoking {{Event/preventDefault()}}). Events must not be used as actions or initiators that cause some algorithm to start running. That is not what they are for.
This is called out here specifically because previous iterations of the DOM had a concept of "default actions" associated with events that gave folks all the wrong ideas. Events do not represent or cause actions, they can only be used to influence an ongoing one.
Though promises do not have a built-in aborting mechanism, many APIs using them require abort semantics. {{AbortController}} is meant to support these requirements by providing an {{AbortController/abort()}} method that toggles the state of a corresponding {{AbortSignal}} object. The API which wishes to support aborting can accept an {{AbortSignal}} object, and use its state to determine how to proceed.
APIs that rely upon {{AbortController}} are encouraged to respond to {{AbortController/abort()}} by rejecting any unsettled promise with the {{AbortSignal}}'s [=AbortSignal/abort reason=].
A hypothetical doAmazingness({ ... }) method could accept an {{AbortSignal}} object
to support aborting as follows:
const controller = new AbortController();
const signal = controller.signal;
startSpinner();
doAmazingness({ ..., signal })
.then(result => ...)
.catch(err => {
if (err.name == 'AbortError') return;
showUserErrorMessage();
})
.then(() => stopSpinner());
// …
controller.abort();
doAmazingness could be implemented as follows:
function doAmazingness({signal}) {
return new Promise((resolve, reject) => {
signal.throwIfAborted();
// Begin doing amazingness, and call resolve(result) when done.
// But also, watch for signals:
signal.addEventListener('abort', () => {
// Stop doing amazingness, and:
reject(signal.reason);
});
});
}
APIs that do not return promises can either react in an equivalent manner or opt to not surface the {{AbortSignal}}'s [=AbortSignal/abort reason=] at all. {{EventTarget/addEventListener()}} is an example of an API where the latter made sense.
APIs that require more granular control could extend both {{AbortController}} and {{AbortSignal}} objects according to their needs.
[Exposed=*]
interface AbortController {
constructor();
[SameObject] readonly attribute AbortSignal signal;
undefined abort(optional any reason);
};
controller = new AbortController()
controller . signal
controller . abort(reason)
An {{AbortController}} object has an associated signal (an {{AbortSignal}} object).
The
new AbortController()
constructor steps are:
The signal getter steps are to return
this's signal.
The abort(reason) method steps are
to signal abort on this with reason if it is given.
To signal abort on an {{AbortController}} controller with an optional reason, signal abort on controller's signal with reason if it is given.
[Exposed=*]
interface AbortSignal : EventTarget {
[NewObject] static AbortSignal abort(optional any reason);
[Exposed=(Window,Worker), NewObject] static AbortSignal timeout([EnforceRange] unsigned long long milliseconds);
[NewObject] static AbortSignal _any(sequence<AbortSignal> signals);
readonly attribute boolean aborted;
readonly attribute any reason;
undefined throwIfAborted();
attribute EventHandler onabort;
};
AbortSignal . abort(reason)
AbortSignal . any(signals)
AbortSignal . timeout(milliseconds)
signal . aborted
signal . reason
signal . throwIfAborted()
An {{AbortSignal}} object has an associated abort reason (a JavaScript value), which is initially undefined.
An {{AbortSignal}} object has associated abort algorithms, (a set of algorithms which are to be executed when it is [=AbortSignal/aborted=]), which is initially empty.
The [=AbortSignal/abort algorithms=] enable APIs with complex requirements to react in a reasonable way to {{AbortController/abort()}}. For example, a given API's [=AbortSignal/abort reason=] might need to be propagated to a cross-thread environment, such as a service worker.
An {{AbortSignal}} object has a dependent (a boolean), which is initially false.
An {{AbortSignal}} object has associated source signals (a weak set of {{AbortSignal}} objects that the object is dependent on for its [=AbortSignal/aborted=] state), which is initially empty.
An {{AbortSignal}} object has associated dependent signals (a weak set of {{AbortSignal}} objects that are dependent on the object for their [=AbortSignal/aborted=] state), which is initially empty.
The static abort(reason) method steps
are:
Let signal be a new {{AbortSignal}} object.
Set signal's [=AbortSignal/abort reason=] to reason if it is given; otherwise to a new "{{AbortError!!exception}}" {{DOMException}}.
The static timeout(milliseconds) method
steps are:
Let signal be a new {{AbortSignal}} object.
Let global be signal's relevant global object.
Run steps after a timeout given global, "AbortSignal-timeout",
milliseconds, and the following step:
Queue a global task on the timer task source given global to signal abort given signal and a new "{{TimeoutError!!exception}}" {{DOMException}}.
For the duration of this timeout, if signal has any event listeners registered for its {{AbortSignal/abort}} event, there must be a strong reference from global to signal.
Return signal.
The static any(signals) method
steps are to return the result of creating a dependent abort signal from signals
using {{AbortSignal}} and the current realm.
The aborted getter steps are to return true if this is [=AbortSignal/aborted=]; otherwise false.
The reason getter steps are to return this's abort reason.
The throwIfAborted() method steps are to throw this's abort reason, if this is [=AbortSignal/aborted=].
This method is primarily useful for when functions accepting {{AbortSignal}}s want to throw (or
return a rejected promise) at specific checkpoints, instead of passing along the {{AbortSignal}}
to other methods. For example, the following function allows aborting in between each attempt to
poll for a condition. This gives opportunities to abort the polling process, even though the
actual asynchronous operation (i.e., await func()) does not
accept an {{AbortSignal}}.
async function waitForCondition(func, targetValue, { signal } = {}) {
while (true) {
signal?.throwIfAborted();
const result = await func();
if (result === targetValue) {
return;
}
}
}
The onabort attribute is an
event handler IDL attribute for the onabort
event handler, whose event handler event type is
abort.
Changes to an {{AbortSignal}} object represent the wishes of the corresponding {{AbortController}} object, but an API observing the {{AbortSignal}} object can choose to ignore them. For instance, if the operation has already completed.
An {{AbortSignal}} object is aborted when its [=AbortSignal/abort reason=] is not undefined.
To add an algorithm algorithm to an {{AbortSignal}} object signal:
If signal is [=AbortSignal/aborted=], then return.
Append algorithm to signal's abort algorithms.
To remove an algorithm algorithm from an {{AbortSignal}} signal, remove algorithm from signal's abort algorithms.
To signal abort, given an {{AbortSignal}} object signal and an optional reason:
If signal is [=AbortSignal/aborted=], then return.
Set signal's [=AbortSignal/abort reason=] to reason if it is given; otherwise to a new "{{AbortError!!exception}}" {{DOMException}}.
Let dependentSignalsToAbort be a new list.
For each dependentSignal of signal's [=AbortSignal/dependent signals=]:
If dependentSignal is not [=AbortSignal/aborted=]:
Set dependentSignal's [=AbortSignal/abort reason=] to signal's [=AbortSignal/abort reason=].
Append dependentSignal to dependentSignalsToAbort.
Run the abort steps for signal.
For each dependentSignal of dependentSignalsToAbort, run the abort steps for dependentSignal.
To run the abort steps for an {{AbortSignal}} signal:
For each algorithm of signal's [=AbortSignal/abort algorithms=]: run algorithm.
Empty signal's abort algorithms.
[=Fire an event=] named {{AbortSignal/abort}} at signal.
To create a dependent abort signal from a list of {{AbortSignal}} objects signals, using signalInterface, which must be either {{AbortSignal}} or an interface that inherits from it, and a realm:
Let resultSignal be a new object implementing signalInterface using realm.
For each signal of signals: if signal is [=AbortSignal/aborted=], then set resultSignal's [=AbortSignal/abort reason=] to signal's [=AbortSignal/abort reason=] and return resultSignal.
Set resultSignal's [=AbortSignal/dependent=] to true.
For each signal of signals:
If signal's [=AbortSignal/dependent=] is false:
Otherwise, for each sourceSignal of signal's [=AbortSignal/source signals=]:
Return resultSignal.
A non-[=AbortSignal/aborted=] [=AbortSignal/dependent=] {{AbortSignal}} object must not be garbage collected while its [=AbortSignal/source signals=] is non-empty and it has registered event listeners for its {{AbortSignal/abort}} event or its [=AbortSignal/abort algorithms=] is non-empty.
Any web platform API using promises to represent operations that can be aborted must adhere to the following:
signal dictionary member.
The method steps for a promise-returning method doAmazingness(options)
could be as follows:
Let |global| be [=this=]'s [=relevant global object=].
Let |p| be [=a new promise=].
If |options|["signal"] exists:
Let |signal| be |options|["signal"].
If |signal| is [=AbortSignal/aborted=], then [=reject=] |p| with |signal|'s [=AbortSignal/abort reason=] and return |p|.
[=AbortSignal/Add|Add the following abort steps=] to |signal|:
Stop doing amazing things.
[=Reject=] |p| with |signal|'s [=AbortSignal/abort reason=].
Run these steps [=in parallel=]:
Let |amazingResult| be the result of doing some amazing things.
[=Queue a global task=] on the amazing task source given |global| to [=/resolve=] |p| with |amazingResult|.
Return |p|.
APIs not using promises should still adhere to the above as much as possible.
Each such document is represented as a node tree. Some of the nodes in a tree can have children, while others are always leaves. To illustrate, consider this HTML document:
<!DOCTYPE html> <html class=e> <head><title>Aliens?</title></head> <body>Why yes.</body> </html>It is represented as follows:
html
html class="e"
head
title
body
Note that, due to the magic that is HTML parsing, not all ASCII whitespace were turned into {{Text}} nodes, but the general concept is clear. Markup goes in, a tree of nodes comes out.
The most excellent Live DOM Viewer can be used to explore this matter in more detail.
Nodes are objects that implement {{Node}}. Nodes participate in a tree, which is known as the node tree.
In practice you deal with more specific objects.
Objects that implement {{Node}} also implement an inherited interface: {{Document}}, {{DocumentType}}, {{DocumentFragment}}, {{Element}}, {{CharacterData}}, or {{Attr}}.
Objects that implement {{DocumentFragment}} sometimes implement {{ShadowRoot}}.
Objects that implement {{Element}} also typically implement an inherited interface, such as {{HTMLAnchorElement}}.
Objects that implement {{CharacterData}} also implement an inherited interface: {{Text}}, {{ProcessingInstruction}}, or {{Comment}}.
Objects that implement {{Text}} sometimes implement {{CDATASection}}.
Thus, every [=/node=]'s [=primary interface=] is one of: {{Document}}, {{DocumentType}}, {{DocumentFragment}}, {{ShadowRoot}}, {{Element}} or an inherited interface of {{Element}}, {{Attr}}, {{Text}}, {{CDATASection}}, {{ProcessingInstruction}}, or {{Comment}}.
For brevity, this specification refers to an object that implements {{Node}} and an
inherited interface NodeInterface, as a
NodeInterface node.
A node tree is constrained as follows, expressed as a relationship between a node and its potential children:
In tree order:
Zero or more {{Element}} or {{CharacterData}} nodes.
No children.
{{Attr}} nodes participate in a tree for historical reasons; they never have a (non-null) parent or any children and are therefore alone in a tree.
To determine the length of a node node, run these steps:
If node is a {{DocumentType}} or {{Attr}} node, then return 0.
If node is a {{CharacterData}} node, then return node's data's length.
Return the number of node's children.
A node is considered empty if its length is 0.
A document tree is a node tree whose root is a document.
The document element of a document is the element whose parent is that document, if it exists; otherwise null.
Per the node tree constraints, there can be only one such element.
A node is in a document tree if its root is a document.
A node is in a document if it is in a document tree. The term in a document is no longer supposed to be used. It indicates that the standard using it has not been updated to account for shadow trees.
A shadow tree is a node tree whose root is a shadow root.
A shadow root is always attached to another node tree through its host. A shadow tree is therefore never alone. The node tree of a shadow root's host is sometimes referred to as the light tree.
A shadow tree's corresponding light tree can be a shadow tree itself.
A node is connected if its shadow-including root is a document.
A shadow tree contains zero or more elements that are slots.
A slot can only be created through HTML's <{slot}> element.
A slot has an associated name (a string). Unless stated otherwise it is the empty string.
Use these attribute change steps to update a slot's name:
If element is a slot, localName is name, and
namespace is null:
If value is oldValue, then return.
If value is null and oldValue is the empty string, then return.
If value is the empty string and oldValue is null, then return.
If value is null or the empty string, then set element's name to the empty string.
Otherwise, set element's name to value.
Run assign slottables for a tree with element's root.
The first slot in a shadow tree, in tree order, whose name is the empty string, is sometimes known as the "default slot".
A slot has an associated assigned nodes (a list of slottables). Unless stated otherwise it is empty.
{{Element}} and {{Text}} nodes are slottables.
A slottable has an associated name (a string). Unless stated otherwise it is the empty string.
Use these attribute change steps to update a slottable's name:
If localName is slot and namespace is null:
If value is oldValue, then return.
If value is null and oldValue is the empty string, then return.
If value is the empty string and oldValue is null, then return.
If value is null or the empty string, then set element's name to the empty string.
Otherwise, set element's name to value.
If element is assigned, then run assign slottables for element's assigned slot.
Run assign a slot for element.
A slottable has an associated assigned slot (null or a slot). Unless stated otherwise it is null. A slottable is assigned if its assigned slot is non-null.
A slottable has an associated manual slot assignment (null or a slot). Unless stated otherwise, it is null.
A slottable's manual slot assignment can be implemented using a weak reference to the slot, because this variable is not directly accessible from script.
To find a slot for a given slottable slottable and an optional boolean open (default false):
If slottable's parent is null, then return null.
Let shadow be slottable's parent's shadow root.
If shadow is null, then return null.
If open is true and shadow's mode is not
"open", then return null.
If shadow's slot assignment is "manual", then
return the slot in shadow's descendants whose
manually assigned nodes contains slottable, if any; otherwise
null.
Return the first slot in tree order in shadow's descendants whose name is slottable's name, if any; otherwise null.
To find slottables for a given slot slot:
Let result be « ».
Let root be slot's root.
If root is not a shadow root, then return result.
Let host be root's host.
If root's slot assignment is "manual":
For each slottable slottable of slot's manually assigned nodes, if slottable's parent is host, append slottable to result.
Otherwise, for each slottable child slottable of host, in tree order:
Let foundSlot be the result of finding a slot given slottable.
If foundSlot is slot, then append slottable to result.
Return result.
To find flattened slottables for a given slot slot:
Let result be « ».
If slot's root is not a shadow root, then return result.
Let slottables be the result of finding slottables given slot.
If slottables is the empty list, then append each slottable child of slot, in tree order, to slottables.
For each node of slottables:
If node is a slot whose root is a shadow root:
Let temporaryResult be the result of finding flattened slottables given node.
Append each slottable in temporaryResult, in order, to result.
Otherwise, append node to result.
Return result.
To assign slottables for a slot slot:
Let slottables be the result of finding slottables for slot.
If slottables and slot's assigned nodes are not identical, then run signal a slot change for slot.
Set slot's assigned nodes to slottables.
For each slottable of slottables: set slottable's assigned slot to slot.
To assign slottables for a tree, given a node root, run assign slottables for each slot of root's inclusive descendants, in tree order.
To assign a slot, given a slottable slottable:
Let slot be the result of finding a slot with slottable.
If slot is non-null, then run assign slottables for slot.
Each similar-origin window agent has signal slots (a set of slots), which is initially empty. [[!HTML]]
To signal a slot change, for a slot slot:
Append slot to slot's relevant agent's signal slots.
To ensure pre-insert validity given a node node, a node parent, null or a node child, and a list of nodes childrenToExclude:
If parent is not a {{Document}}, {{DocumentFragment}}, or {{Element}} node, then throw a "{{HierarchyRequestError!!exception}}" {{DOMException}}.
If node is a host-including inclusive ancestor of parent, then throw a "{{HierarchyRequestError!!exception}}" {{DOMException}}.
If child is non-null and its parent is not parent, then throw a "{{NotFoundError!!exception}}" {{DOMException}}.
If node is not a {{DocumentFragment}}, {{DocumentType}}, {{Element}}, or {{CharacterData}} node, then throw a "{{HierarchyRequestError!!exception}}" {{DOMException}}.
If parent is not a document:
If node is a {{Text}} node, then throw a "{{HierarchyRequestError!!exception}}" {{DOMException}}.
If node is a {{CharacterData}} node, then return.
If node is a {{DocumentFragment}} node:
If node is a {{DocumentFragment}} or {{Element}} node:
If any of the following are true:
parent has a doctype child that childrenToExclude does not contain;
child is null and parent has an element child that childrenToExclude does not contain,
then throw a "{{HierarchyRequestError!!exception}}" {{DOMException}}.
To pre-insert a node node into a node parent before null or node child:
Ensure pre-insert validity given node, parent, child, and « ».
Let referenceChild be child.
If referenceChild is node, then set referenceChild to node's next sibling.
Insert node into parent before referenceChild.
Return node.
Specifications may define insertion steps for all or some nodes. The algorithm is passed insertedNode, as indicated in the insert algorithm below. These steps must not modify the node tree that insertedNode participates in, create browsing contexts, fire events, or otherwise execute JavaScript. These steps may [=queue a global task|queue tasks=] to do these things asynchronously, however.
While the insertion steps cannot execute JavaScript (among other things), they will indeed have script-observable consequences. Consider the below example:
const h1 = document.querySelector('h1');
const fragment = new DocumentFragment();
const script = fragment.appendChild(document.createElement('script'));
const style = fragment.appendChild(document.createElement('style'));
script.innerText= 'console.log(getComputedStyle(h1).color)'; // Logs 'rgb(255, 0, 0)'
style.innerText = 'h1 {color: rgb(255, 0, 0);}';
document.body.append(fragment);
The script in the above example logs 'rgb(255, 0, 0)' because
the following happen in order:
The insert algorithm runs, which will insert the <{script}> and
style elements in order.
The HTML Standard's insertion steps run for the <{script}> element; they do nothing. [[!HTML]]
The HTML Standard's insertion steps run for the
style element; they immediately apply its style rules to the
document. [[!HTML]]
The HTML Standard's post-connection steps run for the <{script}> element; they run the script, which immediately observes the style rules that were applied in the above step. [[!HTML]]
Specifications may also define post-connection steps for all or some nodes. The algorithm is passed connectedNode, as indicated in the insert algorithm below.
The purpose of the post-connection steps is to provide an opportunity for nodes to perform any connection-related operations that modify the node tree that connectedNode participates in, create browsing contexts, or otherwise execute JavaScript. These steps allow a batch of nodes to be inserted atomically with respect to script, with all major side effects occurring after the batch insertions into the node tree is complete. This ensures that all pending node tree insertions completely finish before more insertions can occur.
Specifications may define children changed steps for all or some nodes. The algorithm is passed no argument and is called from insert, remove, and replace data.
To insert a node node into a node parent before null or a node child, with an optional boolean suppressObservers (default false):
Let nodes be node's children, if node is a {{DocumentFragment}} node; otherwise « node ».
Let count be nodes's size.
If count is 0, then return.
If node is a {{DocumentFragment}} node:
Remove its children with suppressObservers set to true.
Queue a tree mutation record for node with « », nodes, null, and null.
This step intentionally does not pay attention to suppressObservers.
If child is non-null:
For each live range whose start node is parent and start offset is greater than child's index: increase its start offset by count.
For each live range whose end node is parent and end offset is greater than child's index: increase its end offset by count.
Let previousSibling be child's previous sibling or parent's last child if child is null.
For each node in nodes, in tree order:
Adopt node into parent's node document.
Otherwise, insert node into parent's children before child's index.
If parent is a shadow host whose shadow root's
slot assignment is "named" and node is a
slottable, then assign a slot for node.
If parent's root is a shadow root, and parent is a slot whose assigned nodes is the empty list, then run signal a slot change for parent.
Run assign slottables for a tree with node's root.
For each shadow-including inclusive descendant inclusiveDescendant of node, in shadow-including tree order:
Run the insertion steps with inclusiveDescendant.
If inclusiveDescendant is an element and inclusiveDescendant's custom element registry is non-null:
If inclusiveDescendant's custom element registry's is scoped is true, then append inclusiveDescendant's node document to inclusiveDescendant's custom element registry's scoped document set.
If inclusiveDescendant is custom, then
enqueue a custom element callback reaction with inclusiveDescendant,
callback name "connectedCallback", and « ».
Otherwise, try to upgrade inclusiveDescendant.
If this successfully upgrades inclusiveDescendant, its
connectedCallback will be enqueued automatically during the
upgrade an element algorithm.
Otherwise, if inclusiveDescendant is a shadow root, inclusiveDescendant's custom element registry is non-null, and inclusiveDescendant's custom element registry's is scoped is true, then append inclusiveDescendant's node document to inclusiveDescendant's custom element registry's scoped document set.
If suppressObservers is false, then queue a tree mutation record for parent with nodes, « », previousSibling, and child.
Run the children changed steps for parent.
Let staticNodeList be a list of nodes, initially « ».
We collect all nodes before calling the post-connection steps on any one of them, instead of calling the post-connection steps while we're traversing the node tree. This is because the post-connection steps can modify the tree's structure, making live traversal unsafe, possibly leading to the post-connection steps being called multiple times on the same node.
For each node of nodes, in tree order:
For each shadow-including inclusive descendant inclusiveDescendant of node, in shadow-including tree order: append inclusiveDescendant to staticNodeList.
For each node of staticNodeList: if node is connected, then run the post-connection steps with node.
To append a node node to a node parent: pre-insert node into parent before null.
Specifications may define moving steps for all or some nodes. The algorithm is passed a node movedNode, a boolean isSubtreeRoot, and a node oldAncestor as indicated in the move algorithm below. Like the insertion steps, these steps must not modify the node tree that movedNode participates in, create browsing contexts, fire events, or otherwise execute JavaScript. These steps may queue tasks to do these things asynchronously, however.
To move a node node into a node newParent before null or a node child:
If newParent's shadow-including root is not the same as node's shadow-including root, then throw a "{{HierarchyRequestError!!exception}}" {{DOMException}}.
This has the side effect of ensuring that a move is only performed if newParent's connected is node's connected.
If node is a host-including inclusive ancestor of newParent, then throw a "{{HierarchyRequestError!!exception}}" {{DOMException}}.
If child is non-null and its parent is not newParent, then throw a "{{NotFoundError!!exception}}" {{DOMException}}.
If node is not an {{Element}} or a {{CharacterData}} node, then throw a "{{HierarchyRequestError!!exception}}" {{DOMException}}.
If node is a {{Text}} node and newParent is a document, then throw a "{{HierarchyRequestError!!exception}}" {{DOMException}}.
If newParent is a document, node is an {{Element}} node, and either newParent has an element child, child is a doctype, or child is non-null and a doctype is following child then throw a "{{HierarchyRequestError!!exception}}" {{DOMException}}.
Let oldParent be node's parent.
Assert: oldParent is non-null.
Run the live range pre-remove steps, given node.
For each {{NodeIterator}} object iterator whose
root's node document is node's
node document: run the NodeIterator pre-remove steps given
node and iterator.
Let oldPreviousSibling be node's previous sibling.
Let oldNextSibling be node's next sibling.
If node is assigned, then run assign slottables for node's assigned slot.
If oldParent's root is a shadow root, and oldParent is a slot whose assigned nodes is empty, then run signal a slot change for oldParent.
If node has an inclusive descendant that is a slot:
Run assign slottables for a tree with oldParent's root.
Run assign slottables for a tree with node.
Add transient registered observers given node and oldParent.
If child is non-null:
For each live range whose start node is newParent and start offset is greater than child's index: increase its start offset by 1.
For each live range whose end node is newParent and end offset is greater than child's index: increase its end offset by 1.
Let newPreviousSibling be child's previous sibling if child is non-null, and newParent's last child otherwise.
Otherwise, insert node into newParent's children before child's index.
If newParent is a shadow host whose shadow root's
slot assignment is "named" and node is a
slottable, then assign a slot for node.
If newParent's root is a shadow root, and newParent is a slot whose assigned nodes is empty, then run signal a slot change for newParent.
Run assign slottables for a tree with node's root.
For each shadow-including inclusive descendant inclusiveDescendant of node, in shadow-including tree order:
Let isSubtreeRoot be true if inclusiveDescendant is node; otherwise false.
Run the moving steps with inclusiveDescendant, isSubtreeRoot, and oldParent.
Because the move algorithm is a separate primitive from insert and remove, it does not invoke the insertion steps or removing steps for inclusiveDescendant.
If inclusiveDescendant is custom and newParent is
connected, then enqueue a custom element callback reaction with
inclusiveDescendant, callback name "connectedMoveCallback", and « ».
Queue a tree mutation record for oldParent with « », « node », oldPreviousSibling, and oldNextSibling.
Queue a tree mutation record for newParent with « node », « », newPreviousSibling, and child.
To replace a node child with a node node within a node parent:
Ensure pre-insert validity given node, parent, child, and « child ».
Let referenceChild be child's next sibling.
If referenceChild is node, then set referenceChild to node's next sibling.
Let previousSibling be child's previous sibling.
Let removedNodes be the empty set.
Adopt node into parent's node document.
If child's parent is non-null:
Set removedNodes to « child ».
Remove child with suppressObservers set to true.
The above can only be false if child is node.
Let nodes be node's children if node is a {{DocumentFragment}} node; otherwise « node ».
Insert node into parent before referenceChild with suppressObservers set to true.
Queue a tree mutation record for parent with nodes, removedNodes, previousSibling, and referenceChild.
Return child.
To replace all with a node or null node within a node parent:
Let removedNodes be parent's children.
Let addedNodes be the empty set.
If node is a {{DocumentFragment}} node, then set addedNodes to node's children.
Otherwise, if node is non-null, set addedNodes to « node ».
Remove all parent's children, in tree order, with suppressObservers set to true.
If node is non-null, then insert node into parent before null with suppressObservers set to true.
If either addedNodes or removedNodes is not empty, then queue a tree mutation record for parent with addedNodes, removedNodes, null, and null.
This algorithm does not make any checks with regards to the node tree constraints. Specification authors need to use it wisely.
Specifications may define removing steps for all or some nodes. The algorithm is passed a node removedNode, a boolean isSubtreeRoot, and a node oldAncestor as indicated in the remove algorithm below.
To remove a node node, with an optional boolean suppressObservers (default false):
Let parent be node's parent.
Assert: parent is non-null.
Run the live range pre-remove steps, given node.
For each {{NodeIterator}} object iterator whose
root's node document is node's
node document: run the NodeIterator pre-remove steps given
node and iterator.
Let oldPreviousSibling be node's previous sibling.
Let oldNextSibling be node's next sibling.
If node is assigned, then run assign slottables for node's assigned slot.
If parent's root is a shadow root, and parent is a slot whose assigned nodes is the empty list, then run signal a slot change for parent.
If node has an inclusive descendant that is a slot:
Run assign slottables for a tree with parent's root.
Run assign slottables for a tree with node.
Run the removing steps with node, true, and parent.
Let isParentConnected be parent's connected.
If node is custom and isParentConnected is true, then
enqueue a custom element callback reaction with node, callback name
"disconnectedCallback", and « ».
It is intentional for now that custom elements do not get parent passed. This might change in the future if there is a need.
For each shadow-including descendant descendant of node, in shadow-including tree order:
Run the removing steps with descendant, false, and parent.
If descendant is custom and isParentConnected
is true, then enqueue a custom element callback reaction with descendant,
callback name "disconnectedCallback", and « ».
Add transient registered observers given node and parent.
If suppressObservers is false, then queue a tree mutation record for parent with « », « node », oldPreviousSibling, and oldNextSibling.
Run the children changed steps for parent.
Web compatibility prevents the {{NonElementParentNode/getElementById()}} method from being exposed on elements (and therefore on {{ParentNode}}).
interface mixin NonElementParentNode {
Element? getElementById(DOMString elementId);
};
Document includes NonElementParentNode;
DocumentFragment includes NonElementParentNode;
node . getElementById(elementId)
Returns the first element within node's descendants whose ID is elementId.
To get an element by ID, given a node node and a string elementId, return the first element, in tree order, within node's descendants, whose ID is elementId; otherwise, if there is no such element, null.
The getElementById(elementId)
method steps are to return the result of getting an element by ID given this and
elementId.
interface mixin DocumentOrShadowRoot {
readonly attribute CustomElementRegistry? customElementRegistry;
};
Document includes DocumentOrShadowRoot;
ShadowRoot includes DocumentOrShadowRoot;
registry = documentOrShadowRoot . {{DocumentOrShadowRoot/customElementRegistry}}
Returns documentOrShadowRoot's {{CustomElementRegistry}} object, if any; otherwise null.
The customElementRegistry getter steps
are:
If this is a document, then return this's custom element registry.
Return this's custom element registry.
The {{DocumentOrShadowRoot}} mixin is also expected to be used by other standards that want to define APIs shared between documents and shadow roots.
To convert nodes into a node, given a list of nodes and strings nodes, and document document:
Replace each string in nodes with the result of creating a text node given document and the string.
If nodes's size is 1, then return nodes[0].
Let fragment be the result of creating a document fragment given document.
For each node of nodes: append node to fragment.
Return fragment.
interface mixin ParentNode {
[SameObject] readonly attribute HTMLCollection children;
readonly attribute Element? firstElementChild;
readonly attribute Element? lastElementChild;
readonly attribute unsigned long childElementCount;
[CEReactions, Unscopable] undefined prepend((Node or DOMString)... nodes);
[CEReactions, Unscopable] undefined append((Node or DOMString)... nodes);
[CEReactions, Unscopable] undefined replaceChildren((Node or DOMString)... nodes);
[CEReactions] undefined moveBefore(Node node, Node? child);
Element? querySelector(DOMString selectors);
[NewObject] NodeList querySelectorAll(DOMString selectors);
};
Document includes ParentNode;
DocumentFragment includes ParentNode;
Element includes ParentNode;
collection = node . {{ParentNode/children}}
element = node . {{ParentNode/firstElementChild}}
element = node . {{ParentNode/lastElementChild}}
node . prepend(nodes)
Inserts nodes before the first child of node, while replacing strings in nodes with equivalent {{Text}} nodes.
Throws a "{{HierarchyRequestError!!exception}}" {{DOMException}} if the constraints of the node tree are violated.
node . append(nodes)
Inserts nodes after the last child of node, while replacing strings in nodes with equivalent {{Text}} nodes.
Throws a "{{HierarchyRequestError!!exception}}" {{DOMException}} if the constraints of the node tree are violated.
node . replaceChildren(nodes)
Replace all children of node with nodes, while replacing strings in nodes with equivalent {{Text}} nodes.
Throws a "{{HierarchyRequestError!!exception}}" {{DOMException}} if the constraints of the node tree are violated.
node . moveBefore(movedNode, child)
Moves, without first removing, movedNode into node after child if child is non-null; otherwise after the last child of node. This method preserves state associated with movedNode.
Throws a "{{HierarchyRequestError!!exception}}" {{DOMException}} if the constraints of the node tree are violated, or the state associated with the moved node cannot be preserved.
node . querySelector(selectors)
Returns the first element that is a descendant of node that matches selectors.
node . querySelectorAll(selectors)
Returns all element descendants of node that match selectors.
The children getter steps are to return an
{{HTMLCollection}} collection rooted at this matching only element
children.
The firstElementChild getter steps are to return
the first child that is an element; otherwise null.
The prepend(nodes) method steps are:
Let node be the result of converting nodes into a node given nodes and this's node document.
Pre-insert node into this before this's first child.
The append(nodes) method steps are:
Let node be the result of converting nodes into a node given nodes and this's node document.
The replaceChildren(nodes) method steps
are:
Let node be the result of converting nodes into a node given nodes and this's node document.
Ensure pre-insert validity given node, this, null, and this's children.
Replace all with node within this.
The moveBefore(node, child)
method steps are:
Let referenceChild be child.
If referenceChild is node, then set referenceChild to node's next sibling.
The querySelector(selectors) method
steps are to return the first result of running scope-match a selectors string
selectors against this, if the result is not an empty list; otherwise null.
The querySelectorAll(selectors) method
steps are to return the static result of running
scope-match a selectors string selectors against this.
Web compatibility prevents the {{previousElementSibling}} and {{nextElementSibling}} attributes from being exposed on doctypes (and therefore on {{ChildNode}}).
interface mixin NonDocumentTypeChildNode {
readonly attribute Element? previousElementSibling;
readonly attribute Element? nextElementSibling;
};
Element includes NonDocumentTypeChildNode;
CharacterData includes NonDocumentTypeChildNode;
element = node . {{previousElementSibling}}
element = node . {{nextElementSibling}}
The previousElementSibling getter
steps are to return the first preceding sibling that is an
element; otherwise null.
The nextElementSibling getter
steps are to return the first following sibling that is an
element; otherwise null.
interface mixin ChildNode {
[CEReactions, Unscopable] undefined before((Node or DOMString)... nodes);
[CEReactions, Unscopable] undefined after((Node or DOMString)... nodes);
[CEReactions, Unscopable] undefined replaceWith((Node or DOMString)... nodes);
[CEReactions, Unscopable] undefined remove();
};
DocumentType includes ChildNode;
Element includes ChildNode;
CharacterData includes ChildNode;
node . {{before(...nodes)}}
Inserts nodes just before node, while replacing strings in nodes with equivalent {{Text}} nodes.
Throws a "{{HierarchyRequestError!!exception}}" {{DOMException}} if the constraints of the node tree are violated.
node . {{after(...nodes)}}
Inserts nodes just after node, while replacing strings in nodes with equivalent {{Text}} nodes.
Throws a "{{HierarchyRequestError!!exception}}" {{DOMException}} if the constraints of the node tree are violated.
node . {{replaceWith(...nodes)}}
Replaces node with nodes, while replacing strings in nodes with equivalent {{Text}} nodes.
Throws a "{{HierarchyRequestError!!exception}}" {{DOMException}} if the constraints of the node tree are violated.
node . {{ChildNode/remove()}}
The before(nodes) method steps are:
If parent is null, then return.
Let viablePreviousSibling be this's first preceding sibling not in nodes; otherwise null.
Let node be the result of converting nodes into a node, given nodes and this's node document.
If viablePreviousSibling is null, then set it to parent's first child; otherwise to viablePreviousSibling's next sibling.
Pre-insert node into parent before viablePreviousSibling.
The after(nodes) method steps are:
If parent is null, then return.
Let viableNextSibling be this's first following sibling not in nodes; otherwise null.
Let node be the result of converting nodes into a node, given nodes and this's node document.
Pre-insert node into parent before viableNextSibling.
The replaceWith(nodes) method steps are:
If parent is null, then return.
Let viableNextSibling be this's first following sibling not in nodes; otherwise null.
Let node be the result of converting nodes into a node, given nodes and this's node document.
If this's parent is parent, replace this with node within parent.
This could have been inserted into node.
Otherwise, pre-insert node into parent before viableNextSibling.
interface mixin Slottable {
readonly attribute HTMLSlotElement? assignedSlot;
};
Element includes Slottable;
Text includes Slottable;
The assignedSlot
getter steps are to return the result of find a slot given this and true.
A {{NodeList}} object is a collection of nodes.
[Exposed=Window]
interface NodeList {
getter Node? item(unsigned long index);
readonly attribute unsigned long length;
iterable<Node>;
};
The object's supported property indices are the numbers in the range zero to one less than the number of nodes represented by the collection. If there are no such elements, then there are no supported property indices.
The length attribute must return the number of nodes represented by the collection.
The item(index) method must return the
indexth node in the collection. If there is no
indexth node in the collection, then the method must
return null.
[Exposed=Window, LegacyUnenumerableNamedProperties]
interface HTMLCollection {
readonly attribute unsigned long length;
getter Element? item(unsigned long index);
getter Element? namedItem(DOMString name);
};
An {{HTMLCollection}} object is a collection of elements.
{{HTMLCollection}} is a historical artifact we cannot rid the web of.
While developers are of course welcome to keep using it, new API standard designers ought not to use
it (use sequence<T> in IDL instead).
The object's supported property indices are the numbers in the range zero to one less than the number of elements represented by the collection. If there are no such elements, then there are no supported property indices.
The length getter steps are to return the
number of nodes represented by the collection.
The item(index) method steps are to
return the indexth element in the collection. If there
is no indexth element in the collection, then the method
must return null.
The supported property names are the values from the list returned by these steps:
Let result be an empty list.
For each element represented by the collection, in tree order:
If element has an ID which is not in result, append element's ID to result.
If element is in the HTML namespace and has
a name attribute whose value is neither
the empty string nor is in result, append element's
name attribute value to
result.
Return result.
The namedItem(key) method steps are:
If key is the empty string, return null.
Return the first element in the collection for which at least one of the following is true:
name attribute whose value is
key;
or null if there is no such element.
Each similar-origin window agent has a mutation observer microtask queued (a boolean), which is initially false. [[!HTML]]
Each similar-origin window agent also has pending mutation observers (a set of zero or more {{MutationObserver}} objects), which is initially empty.
Each similar-origin window agent also has a mutation observer counter (a number), which is initially 0.
To queue a mutation observer microtask:
If the surrounding agent's mutation observer microtask queued is true, then return.
Set the surrounding agent's mutation observer microtask queued to true.
To notify mutation observers:
Set the surrounding agent's mutation observer microtask queued to false.
Let notifyList be the result of sorting the surrounding agent's pending mutation observers in ascending order, with a being less than b if a's creation index is less than b's creation index.
Let signalSet be a clone of the surrounding agent's signal slots.
Empty the surrounding agent's signal slots.
For each mo of notifyList:
Let records be a clone of mo's record queue.
Empty mo's record queue.
If records is not empty, then invoke
mo's callback with « records, mo »
and "report", and with callback this value mo.
For each slot of signalSet: fire an event named slotchange, with its {{Event/bubbles}} attribute set to true, at slot.
Each node has a registered observer list (a list of zero or more registered observers), which is initially empty.
A registered observer consists of an observer (a {{MutationObserver}} object) and options (a {{MutationObserverInit}} dictionary).
A transient registered observer is a registered observer that also consists of a source (a registered observer that is not a transient registered observer).
Transient registered observers are used to track mutations within a given node's descendants after node has been removed or moved so they do not get lost when {{MutationObserverInit/subtree}} is set to true on node's former parent. They are removed the next time mutation observers are notified.
To add transient registered observers given a node node and a node parent:
For each inclusive ancestor inclusiveAncestor of parent, and then for each registered of inclusiveAncestor's registered observer list:
If registered's options["{{MutationObserverInit/subtree}}"] is false, then continue.
Let observer be registered's observer.
Let source be registered's source if registered is a transient registered observer; otherwise registered.
If node's registered observer list contains a transient registered observer whose source is source, then continue.
Append a new transient registered observer whose observer is observer, options is source's options, and source is source to node's registered observer list.
Append a weak reference to node to observer's transient node set.
Append observer to the surrounding agent's pending mutation observers.
This ensures node's transient registered observers are removed the next time mutation observers are notified, even if no {{MutationRecord}} object is queued for observer.
To remove transient registered observers for a {{MutationObserver}} object observer:
For each node of observer's transient node set: remove all transient registered observers whose observer is observer from node's registered observer list.
Empty observer's transient node set.
[Exposed=Window]
interface MutationObserver {
constructor(MutationCallback callback);
undefined observe(Node target, optional MutationObserverInit options = {});
undefined disconnect();
sequence<MutationRecord> takeRecords();
};
callback MutationCallback = undefined (sequence<MutationRecord> mutations, MutationObserver observer);
dictionary MutationObserverInit {
boolean childList = false;
boolean attributes;
boolean characterData;
boolean subtree = false;
boolean attributeOldValue;
boolean characterDataOldValue;
sequence<DOMString> attributeFilter;
};
A {{MutationObserver}} object can be used to observe mutations to the tree of nodes.
Each {{MutationObserver}} object has these associated concepts:
observer = new {{MutationObserver(callback)}}
observer . {{observe(target, options)}}
observer . {{disconnect()}}
observer . {{takeRecords()}}
The
new MutationObserver(callback)
constructor steps are:
Set this's creation index to this's relevant agent's mutation observer counter.
Increase this's relevant agent's mutation observer counter by 1.
The
observe(target, options)
method steps are:
If either options["{{MutationObserverInit/attributeOldValue}}"] or options["{{MutationObserverInit/attributeFilter}}"] exists, and options["{{MutationObserverInit/attributes}}"] does not exist, then set options["{{MutationObserverInit/attributes}}"] to true.
If options["{{MutationObserverInit/characterDataOldValue}}"] exists and options["{{MutationObserverInit/characterData}}"] does not exist, then set options["{{MutationObserverInit/characterData}}"] to true.
If none of options["{{MutationObserverInit/childList}}"],
options["{{MutationObserverInit/attributes}}"], and
options["{{MutationObserverInit/characterData}}"] is true, then throw a
TypeError.
If options["{{MutationObserverInit/attributeOldValue}}"] is true and
options["{{MutationObserverInit/attributes}}"] is false, then throw a
TypeError.
If options["{{MutationObserverInit/attributeFilter}}"] [=map/exists=] and
options["{{MutationObserverInit/attributes}}"] is false, then throw a
TypeError.
If options["{{MutationObserverInit/characterDataOldValue}}"] is true and
options["{{MutationObserverInit/characterData}}"] is false, then throw a
TypeError.
Let registered be the registered observer in target's registered observer list that is not a transient registered observer and whose observer is this, if any; otherwise null.
If target was in a subtree that this observes and was removed or moved, target's registered observer list can also contain transient registered observers whose observer is this. These are ignored, as they are removed the next time mutation observers are notified.
If registered is non-null:
For each node of this's transient node set: remove all transient registered observers whose source is registered from node's registered observer list.
Set registered's options to options.
Otherwise:
Append a new registered observer whose observer is this and options is options to target's registered observer list.
The disconnect() method steps are:
For each node of this's node list: remove any registered observer from node's registered observer list for which this is the observer.
The takeRecords() method steps are:
Let records be a clone of this's record queue.
Return records.
To queue a mutation record of type for target with name, namespace, oldValue, addedNodes, removedNodes, previousSibling, and nextSibling:
Let interestedObservers be an empty map.
Let nodes be the inclusive ancestors of target.
For each node of nodes, and then for each registered of node's registered observer list:
Let options be registered's options.
If none of the following are true
attributes" and
options["{{MutationObserverInit/attributes}}"] either does not exist
or is false
attributes",
options["{{MutationObserverInit/attributeFilter}}"] exists, and
options["{{MutationObserverInit/attributeFilter}}"] does not contain
name or namespace is non-null
characterData" and
options["{{MutationObserverInit/characterData}}"] either does not
exist or is false
childList" and
options["{{MutationObserverInit/childList}}"] is false
then:
Let mo be registered's observer.
If interestedObservers[mo] does not exist, then set interestedObservers[mo] to null.
If either type is "attributes" and
options["{{MutationObserverInit/attributeOldValue}}"] is true, or type is
"characterData" and
options["{{MutationObserverInit/characterDataOldValue}}"] is true, then
set interestedObservers[mo] to oldValue.
If interestedObservers is empty, then return.
For each observer → mappedOldValue of interestedObservers:
Let record be a new {{MutationRecord}} object with its {{MutationRecord/type}} set to type, {{MutationRecord/target}} set to target, {{MutationRecord/attributeName}} set to name, {{MutationRecord/attributeNamespace}} set to namespace, {{MutationRecord/oldValue}} set to mappedOldValue, {{MutationRecord/addedNodes}} set to addedNodes, {{MutationRecord/removedNodes}} set to removedNodes, {{MutationRecord/previousSibling}} set to previousSibling, and {{MutationRecord/nextSibling}} set to nextSibling.
Enqueue record to observer's record queue.
Append observer to the surrounding agent's pending mutation observers.
To queue a tree mutation record for target with addedNodes, removedNodes, previousSibling, and nextSibling:
Assert: either addedNodes or removedNodes is not empty.
Queue a mutation record of "childList" for target with
null, null, null, addedNodes, removedNodes, previousSibling,
and nextSibling.
[Exposed=Window]
interface MutationRecord {
readonly attribute DOMString type;
[SameObject] readonly attribute Node target;
[SameObject] readonly attribute NodeList addedNodes;
[SameObject] readonly attribute NodeList removedNodes;
readonly attribute Node? previousSibling;
readonly attribute Node? nextSibling;
readonly attribute DOMString? attributeName;
readonly attribute DOMString? attributeNamespace;
readonly attribute DOMString? oldValue;
};
record . {{MutationRecord/type}}
attributes" if it was an
attribute mutation.
"characterData" if it was a mutation to a
{{CharacterData}} node. And
"childList" if it was a mutation to the
tree of
nodes.
record . {{MutationRecord/target}}
attributes", it is the
element whose
attribute changed. For
"characterData", it is the {{CharacterData}}
node. For "childList",
it is the node whose
children changed.
record . {{MutationRecord/addedNodes}}
record . {{MutationRecord/removedNodes}}
record . {{MutationRecord/previousSibling}}
record . {{MutationRecord/nextSibling}}
record . {{MutationRecord/attributeName}}
record . {{MutationRecord/attributeNamespace}}
record . {{MutationRecord/oldValue}}
attributes", it is the
value of the
changed attribute before the change.
For "characterData", it is the
data of the changed
node before the change. For
"childList", it is null.
The type, target, addedNodes, removedNodes, previousSibling, nextSibling, attributeName, attributeNamespace, and oldValue attributes must return the values they were initialized to.
[Exposed=Window]
interface Node : EventTarget {
const unsigned short ELEMENT_NODE = 1;
const unsigned short ATTRIBUTE_NODE = 2;
const unsigned short TEXT_NODE = 3;
const unsigned short CDATA_SECTION_NODE = 4;
const unsigned short ENTITY_REFERENCE_NODE = 5; // legacy
const unsigned short ENTITY_NODE = 6; // legacy
const unsigned short PROCESSING_INSTRUCTION_NODE = 7;
const unsigned short COMMENT_NODE = 8;
const unsigned short DOCUMENT_NODE = 9;
const unsigned short DOCUMENT_TYPE_NODE = 10;
const unsigned short DOCUMENT_FRAGMENT_NODE = 11;
const unsigned short NOTATION_NODE = 12; // legacy
readonly attribute unsigned short nodeType;
readonly attribute DOMString nodeName;
readonly attribute USVString baseURI;
readonly attribute boolean isConnected;
readonly attribute Document? ownerDocument;
Node getRootNode(optional GetRootNodeOptions options = {});
readonly attribute Node? parentNode;
readonly attribute Element? parentElement;
boolean hasChildNodes();
[SameObject] readonly attribute NodeList childNodes;
readonly attribute Node? firstChild;
readonly attribute Node? lastChild;
readonly attribute Node? previousSibling;
readonly attribute Node? nextSibling;
[CEReactions] attribute DOMString? nodeValue;
[CEReactions] attribute DOMString? textContent;
[CEReactions] undefined normalize();
[CEReactions, NewObject] Node cloneNode(optional boolean subtree = false);
boolean isEqualNode(Node? otherNode);
boolean isSameNode(Node? otherNode); // legacy alias of ===
const unsigned short DOCUMENT_POSITION_DISCONNECTED = 0x01;
const unsigned short DOCUMENT_POSITION_PRECEDING = 0x02;
const unsigned short DOCUMENT_POSITION_FOLLOWING = 0x04;
const unsigned short DOCUMENT_POSITION_CONTAINS = 0x08;
const unsigned short DOCUMENT_POSITION_CONTAINED_BY = 0x10;
const unsigned short DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;
unsigned short compareDocumentPosition(Node other);
boolean contains(Node? other);
DOMString? lookupPrefix(DOMString? namespace);
DOMString? lookupNamespaceURI(DOMString? prefix);
boolean isDefaultNamespace(DOMString? namespace);
[CEReactions] Node insertBefore(Node node, Node? child);
[CEReactions] Node appendChild(Node node);
[CEReactions] Node replaceChild(Node node, Node child);
[CEReactions] Node removeChild(Node child);
};
dictionary GetRootNodeOptions {
boolean composed = false;
};
{{Node}} is an abstract interface that is used by all nodes. You cannot get a direct instance of it.
Each node has an associated node document, set upon creation, that is a document.
A node's node document can be changed by the adopt algorithm.
A node's get the parent algorithm, given an event, returns the node's assigned slot, if node is assigned; otherwise node's parent.
Each node also has a registered observer list.
To create a node that implements an interface interface, given a document document:
Assert: interface is neither {{Document}} nor an interface that inherits from {{Document}}. To create a document, use create a document instead.
Return a new node that implements interface, in document's relevant realm, with its node document set to document.
node . {{Node/nodeType}}
Returns a number appropriate for the type of node, as follows:
{{Node}} . {{Node/ELEMENT_NODE}} (1).
{{Node}} . {{Node/ATTRIBUTE_NODE}} (2).
Text node
{{Node}} . {{Node/TEXT_NODE}} (3).
{{Node}} . {{Node/CDATA_SECTION_NODE}} (4).
{{Node}} . {{Node/PROCESSING_INSTRUCTION_NODE}} (7).
{{Node}} . {{Node/COMMENT_NODE}} (8).
{{Node}} . {{Node/DOCUMENT_NODE}} (9).
{{Node}} . {{Node/DOCUMENT_TYPE_NODE}} (10).
{{Node}} . {{Node/DOCUMENT_FRAGMENT_NODE}} (11).
node . {{Node/nodeName}}
Returns a string appropriate for the type of node, as follows:
Text node
#text".
#cdata-section".
#comment".
#document".
#document-fragment".
The nodeType getter steps are to return the first matching statement, switching on the interface this implements:
Text node
The nodeName getter steps are to return the first matching statement, switching on the interface this implements:
Text node
#text".
#cdata-section".
#comment".
#document".
#document-fragment".
node . {{Node/baseURI}}
The baseURI getter steps are:
Let baseURL be the result of running this's node document's get the base URL algorithm.
If baseURL is null, then set baseURL to this's node document's URL.
Return baseURL, serialized.
node . {{Node/isConnected}}
Returns true if node is connected; otherwise false.
node . {{Node/ownerDocument}}
node . {{Node/getRootNode()}}
node . getRootNode({ composed:true })
node . {{Node/parentNode}}
node . {{Node/parentElement}}
node . {{Node/hasChildNodes()}}
node . {{Node/childNodes}}
node . {{Node/firstChild}}
node . {{Node/lastChild}}
node . {{Node/previousSibling}}
node . {{Node/nextSibling}}
The isConnected getter steps are to return true,
if this is connected; otherwise false.
The ownerDocument getter steps are to return null,
if this is a document; otherwise this's node document.
The node document of a document is that document itself. All nodes have a node document at all times.
The getRootNode(options) method steps are to
return this's shadow-including root if
options["{{GetRootNodeOptions/composed}}"] is true; otherwise this's
root.
The parentNode getter steps are to return
this's parent.
The parentElement getter steps are to return
this's parent element.
The hasChildNodes() method steps are to return true if
this has children; otherwise false.
The childNodes getter steps are to return a
{{NodeList}} rooted at this matching only children.
The firstChild getter steps are to return
this's first child.
The lastChild getter steps are to return this's
last child.
The previousSibling getter steps are to return
this's previous sibling.
The nextSibling getter steps are to return
this's next sibling.
The nodeValue getter steps are to return the following, switching on the interface this implements:
The {{Node/nodeValue}} setter steps are to, if the given value is null, act as if it was the empty string instead, and then do as described below, switching on the interface this implements:
Set an existing attribute value with this and the given value.
Replace data of this with 0, this's length, and the given value.
Do nothing.
To get text content with a node node, return the following, switching on the interface node implements:
The textContent getter steps are to
return the result of running get text content with this.
To string replace all with a string string within a node parent, run these steps:
Let node be null.
If string is not the empty string, then set node to the result of creating a text node given parent's node document and string.
Replace all with node within parent.
To set text content with a node node and a string value, do as defined below, switching on the interface node implements:
String replace all with value within node.
Set an existing attribute value with node and value.
Replace data of node with 0, node's length, and value.
Do nothing.
The {{Node/textContent}} setter steps are to, if the given value is null, act as if it was the empty string instead, and then run set text content with this and the given value.
node . {{Node/normalize()}}
Text nodes and concatenates the
data of remaining contiguous exclusive Text nodes
into the first of their nodes.
The normalize() method steps are to run these steps for
each descendant exclusive Text node node of
this:
Let length be node's length.
If length is zero, then remove node and continue with the
next exclusive Text node, if any.
Let data be the concatenation of the
data of node's
contiguous exclusive Text nodes (excluding itself), in tree order.
Replace data of node with length, 0, and data.
Let currentNode be node's next sibling.
While currentNode is an exclusive Text node:
For each live range whose start node is currentNode: add length to its start offset and set its start node to node.
For each live range whose end node is currentNode: add length to its end offset and set its end node to node.
For each live range whose start node is currentNode's parent and start offset is currentNode's index: set its start node to node and its start offset to length.
For each live range whose end node is currentNode's parent and end offset is currentNode's index: set its end node to node and its end offset to length.
Add currentNode's length to length.
Set currentNode to its next sibling.
Remove node's contiguous exclusive Text nodes
(excluding itself), in tree order.
node . cloneNode([subtree = false])
node . isEqualNode(otherNode)
HTML defines cloning steps for several elements, such as <{input}>, <{script}>, and <{template}>. SVG ought to do the same for its <{script}> elements, but does not.
To clone a node given a node node and an optional document document (default node's node document), boolean subtree (default false), node-or-null parent (default null), and null or a {{CustomElementRegistry}} object fallbackRegistry (default null):
Let copy be the result of cloning a single node given node, document, and fallbackRegistry.
Run any cloning steps defined for node in other applicable specifications and pass node, copy, and subtree as parameters.
If parent is non-null, then append copy to parent.
If subtree is true, then for each child of node's children, in tree order: clone a node given child with document set to document, subtree set to subtree, parent set to copy, and fallbackRegistry set to fallbackRegistry.
If node is an element, node is a shadow host, and node's shadow root's clonable is true:
Assert: copy is not a shadow host.
Let shadowRootRegistry be node's shadow root's custom element registry.
If shadowRootRegistry is a global custom element registry, then set shadowRootRegistry to document's custom element registry's effective global custom element registry.
Attach a shadow root with copy, node's shadow root's mode, node's shadow root's delegates focus, node's shadow root's serializable, node's shadow root's slot assignment, true, and shadowRootRegistry.
Set copy's shadow root's declarative to node's shadow root's declarative.
Set copy's shadow root's keep custom element registry null to node's shadow root's keep custom element registry null.
For each child of node's shadow root's children, in tree order: clone a node given child with document set to document, subtree set to true, and parent set to copy's shadow root.
This intentionally does not pass the fallbackRegistry argument.
Return copy.
To clone a single node given a node node, document document, and null or a {{CustomElementRegistry}} object fallbackRegistry:
Let copy be null.
If node is an element:
Let registry be node's custom element registry.
If registry is null, then set registry to fallbackRegistry.
If registry is a global custom element registry, then set registry to document's custom element registry's effective global custom element registry.
Set copy to the result of creating an element, given
document, node's local name, node's
namespace, node's namespace prefix,
node's is value, false, and registry.
For each attribute of node's attribute list:
Let copyAttribute be the result of cloning a single node given attribute, document, and null.
Append copyAttribute to copy.
Otherwise, if node is a document, set copy to the result of creating a document that implements the same interfaces as node, given document's relevant realm.
Otherwise, set copy to the result of creating a node that implements the same interfaces as node, given document.
Fulfill these additional requirements, switching on the interface node implements:
Set copy's encoding, content type, URL, origin, type, mode, and allow declarative shadow roots, to those of node.
Set copy's base URL override to the result of running node's get the base URL.
If node's custom element registry's is scoped is true, then set copy's custom element registry to node's custom element registry.
Set copy's namespace, namespace prefix, local name, and value to those of node.
Set copy's data to that of node.
Do nothing.
If node is a document, then set document to copy.
Set copy's node document to document.
Return copy.
The cloneNode(subtree) method steps are:
If this is a shadow root, then throw a "{{NotSupportedError!!exception}}" {{DOMException}}.
Return the result of cloning a node given this with subtree set to subtree.
A node A equals a node B if all of the following conditions are true:
A and B implement the same interfaces.
The following are equal, switching on the interface A implements:
If A is an element, each attribute in its attribute list equals an attribute in B's attribute list.
A and B have the same number of children.
Each child of A equals the child of B at the identical index.
The isEqualNode(otherNode) method steps are to
return true if otherNode is non-null and this equals
otherNode; otherwise false.
The isSameNode(otherNode) method steps are to
return true if otherNode is this; otherwise false.
node . {{compareDocumentPosition(other)}}
{{Node}} . {{Node/DOCUMENT_POSITION_DISCONNECTED}} (1)
{{Node}} . {{Node/DOCUMENT_POSITION_PRECEDING}} (2)
{{Node}} . {{Node/DOCUMENT_POSITION_FOLLOWING}} (4)
{{Node}} . {{Node/DOCUMENT_POSITION_CONTAINS}} (8)
{{Node}} . {{Node/DOCUMENT_POSITION_CONTAINED_BY}} (16, 10 in hexadecimal)
node . {{Node/contains(other)}}
These are the constants {{compareDocumentPosition()}} returns as mask:
The compareDocumentPosition(other) method
steps are:
If this is other, then return zero.
Let node1 be other and node2 be this.
Let attr1 and attr2 be null.
If node1 is an attribute, then set attr1 to node1 and node1 to attr1's element.
If node2 is an attribute:
Set attr2 to node2 and node2 to attr2's element.
If attr1 and node1 are non-null, and node2 is node1:
For each attr of node2's attribute list:
If node1 or node2 is null, or node1's root is not node2's root, then return the result of adding {{Node/DOCUMENT_POSITION_DISCONNECTED}}, {{Node/DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC}}, and either {{Node/DOCUMENT_POSITION_PRECEDING}} or {{Node/DOCUMENT_POSITION_FOLLOWING}}, with the constraint that this is to be consistent, together.
Whether to return {{Node/DOCUMENT_POSITION_PRECEDING}} or
{{Node/DOCUMENT_POSITION_FOLLOWING}} is typically implemented via pointer comparison. In
JavaScript implementations a cached Math.random() value can
be used.
If node1 is an ancestor of node2 and attr1 is null, or node1 is node2 and attr2 is non-null, then return the result of adding {{Node/DOCUMENT_POSITION_CONTAINS}} to {{Node/DOCUMENT_POSITION_PRECEDING}}.
If node1 is a descendant of node2 and attr2 is null, or node1 is node2 and attr1 is non-null, then return the result of adding {{Node/DOCUMENT_POSITION_CONTAINED_BY}} to {{Node/DOCUMENT_POSITION_FOLLOWING}}.
If node1 is preceding node2, then return {{Node/DOCUMENT_POSITION_PRECEDING}}.
Due to the way attributes are handled in this algorithm this results in a node's attributes counting as preceding that node's children, despite attributes not participating in the same tree.
Return {{Node/DOCUMENT_POSITION_FOLLOWING}}.
The contains(other) method steps are to return
true if other is an inclusive descendant of this; otherwise false
(including when other is null).
To locate a namespace prefix for an element using namespace, run these steps:
If element's namespace is namespace and its namespace prefix is non-null, then return its namespace prefix.
If element has an attribute whose
namespace prefix is "xmlns" and value is
namespace, then return element's first such attribute's
local name.
If element's parent element is non-null, then return the result of running locate a namespace prefix on that element using namespace.
Return null.
To locate a namespace for a node using prefix, switch on the interface node implements:
If prefix is "xml", then return the XML namespace.
If prefix is "xmlns", then return the XMLNS namespace.
If its namespace is non-null and its namespace prefix is prefix, then return namespace.
If it has an attribute whose namespace
is the XMLNS namespace, namespace prefix is "xmlns", and
local name is prefix, or if prefix is null and it
has an attribute whose namespace is the
XMLNS namespace, namespace prefix is null, and local name
is "xmlns", then return its value if it is not the empty string, and
null otherwise.
If its parent element is null, then return null.
Return the result of running locate a namespace on its parent element using prefix.
If its document element is null, then return null.
Return the result of running locate a namespace on its document element using prefix.
Return null.
If its element is null, then return null.
Return the result of running locate a namespace on its element using prefix.
If its parent element is null, then return null.
Return the result of running locate a namespace on its parent element using prefix.
The lookupPrefix(namespace) method steps are:
If namespace is null or the empty string, then return null.
Switch on the interface this implements:
Return the result of locating a namespace prefix for this using namespace.
If this's document element is null, then return null.
Return the result of locating a namespace prefix for this's document element using namespace.
Return null.
Return the result of locating a namespace prefix for this's element using namespace.
If this's parent element is null, then return null.
Return the result of locating a namespace prefix for this's parent element using namespace.
The lookupNamespaceURI(prefix) method steps
are:
If prefix is the empty string, then set it to null.
Return the result of running locate a namespace for this using prefix.
The isDefaultNamespace(namespace) method steps
are:
If namespace is the empty string, then set it to null.
Let defaultNamespace be the result of running locate a namespace for this using null.
Return true if defaultNamespace is the same as namespace; otherwise false.
The insertBefore(node, child)
method steps are to return the result of pre-inserting node into this
before child.
The appendChild(node) method steps are to
return the result of appending node to this.
The replaceChild(node, child)
method steps are to return the result of replacing child with node
within this.
The removeChild(child) method steps are to
return the result of pre-removing child from this.
The list of elements with qualified name qualifiedName for a node root is the {{HTMLCollection}} returned by the following algorithm:
If qualifiedName is U+002A (*), then return an {{HTMLCollection}} rooted at root, whose filter matches only descendant elements.
Otherwise, if root's node document is an HTML document, return an {{HTMLCollection}} rooted at root, whose filter matches the following descendant elements:
Whose namespace is the HTML namespace and whose qualified name is qualifiedName, in ASCII lowercase.
Whose namespace is not the HTML namespace and whose qualified name is qualifiedName.
Otherwise, return an {{HTMLCollection}} rooted at root, whose filter matches descendant elements whose qualified name is qualifiedName.
When invoked with the same argument, and as long as root's node document's type has not changed, the same {{HTMLCollection}} object may be returned as returned by an earlier call.
The list of elements with namespace namespace and local name localName for a node root is the {{HTMLCollection}} returned by the following algorithm:
If namespace is the empty string, then set it to null.
If both namespace and localName are U+002A (*), then return an {{HTMLCollection}} rooted at root, whose filter matches descendant elements.
If namespace is U+002A (*), then return an {{HTMLCollection}} rooted at root, whose filter matches descendant elements whose local name is localName.
If localName is U+002A (*), then return an {{HTMLCollection}} rooted at root, whose filter matches descendant elements whose namespace is namespace.
Return an {{HTMLCollection}} rooted at root, whose filter matches descendant elements whose namespace is namespace and local name is localName.
When invoked with the same arguments, the same {{HTMLCollection}} object may be returned as returned by an earlier call.
The list of elements with class names classNames for a node root is the {{HTMLCollection}} returned by the following algorithm:
Return an {{HTMLCollection}} rooted at root, whose filter matches descendant elements that have all their classes in classes.
The comparisons for the classes must be done in an
ASCII case-insensitive manner if root's node document's
mode is "quirks"; otherwise in an identical to
manner.
When invoked with the same argument, the same {{HTMLCollection}} object may be returned as returned by an earlier call.
[Exposed=Window]
interface Document : Node {
constructor();
[SameObject] readonly attribute DOMImplementation implementation;
readonly attribute USVString URL;
readonly attribute USVString documentURI;
readonly attribute DOMString compatMode;
readonly attribute DOMString characterSet;
readonly attribute DOMString charset; // legacy alias of .characterSet
readonly attribute DOMString inputEncoding; // legacy alias of .characterSet
readonly attribute DOMString contentType;
readonly attribute DocumentType? doctype;
readonly attribute Element? documentElement;
HTMLCollection getElementsByTagName(DOMString qualifiedName);
HTMLCollection getElementsByTagNameNS(DOMString? namespace, DOMString localName);
HTMLCollection getElementsByClassName(DOMString classNames);
[CEReactions, NewObject] Element createElement(DOMString localName, optional (DOMString or ElementCreationOptions) options = {});
[CEReactions, NewObject] Element createElementNS(DOMString? namespace, DOMString qualifiedName, optional (DOMString or ElementCreationOptions) options = {});
[NewObject] DocumentFragment createDocumentFragment();
[NewObject] Text createTextNode(DOMString data);
[NewObject] CDATASection createCDATASection(DOMString data);
[NewObject] Comment createComment(DOMString data);
[NewObject] ProcessingInstruction createProcessingInstruction(DOMString target, DOMString data);
[CEReactions, NewObject] Node importNode(Node node, optional (boolean or ImportNodeOptions) options = false);
[CEReactions] Node adoptNode(Node node);
[NewObject] Attr createAttribute(DOMString localName);
[NewObject] Attr createAttributeNS(DOMString? namespace, DOMString qualifiedName);
[NewObject] Event createEvent(DOMString interface); // legacy
[NewObject] Range createRange();
// NodeFilter.SHOW_ALL = 0xFFFFFFFF
[NewObject] NodeIterator createNodeIterator(Node root, optional unsigned long whatToShow = 0xFFFFFFFF, optional NodeFilter? filter = null);
[NewObject] TreeWalker createTreeWalker(Node root, optional unsigned long whatToShow = 0xFFFFFFFF, optional NodeFilter? filter = null);
};
[Exposed=Window]
interface XMLDocument : Document {};
dictionary ElementCreationOptions {
CustomElementRegistry? customElementRegistry;
DOMString is;
};
dictionary ImportNodeOptions {
CustomElementRegistry customElementRegistry;
boolean selfOnly = false;
};
{{Document}} nodes are simply known as documents.
A document's node document is itself.
Each document has an associated
encoding (an encoding),
content type (a string),
URL (a URL),
origin (an origin),
type ("xml" or "html"),
mode ("no-quirks", "quirks", or "limited-quirks"),
allow declarative shadow roots (a boolean), and
custom element registry (null or a {{CustomElementRegistry}} object).
[[!ENCODING]]
[[!URL]]
[[!HTML]]
Unless stated otherwise, a document's encoding is the
utf-8 encoding, content type is
"application/xml", URL is "about:blank",
origin is an opaque origin,
type is "xml", mode is
"no-quirks", allow declarative shadow roots is false, and
custom element registry is null.
A document is said to be an XML document if its
type is "xml"; otherwise an HTML document.
Whether a document is an HTML document or an XML document affects the
behavior of certain APIs.
Each document has an associated get the base URL algorithm, which returns a URL or null. Unless specified otherwise it returns null.
Each document has a base URL override (a URL or null), initially null.
The base URL override is set when cloning
a document. HTML overrides the get the base URL algorithm to account for the
base element and for the base URL "about:"-schemed documents
inherit. [[!HTML]]
A document is said to be in
no-quirks mode if its
mode is "no-quirks",
quirks mode if its mode
is "quirks", and
limited-quirks mode if its
mode is "limited-quirks".
The mode is only ever changed from the default for documents
created by the HTML parser based on the presence, absence, or value of the DOCTYPE string,
and by a new browsing context (initial "about:blank"). [[!HTML]]
No-quirks mode was originally known as "standards mode" and limited-quirks mode was once known as "almost standards mode". They have been renamed because their details are now defined by standards. (And because Ian Hickson vetoed their original names on the basis that they are nonsensical.)
A document's get the parent algorithm, given an event, returns
null if event's {{Event/type}} attribute value is "load" or
document does not have a browsing context; otherwise the
document's relevant global object.
To create a document that implements an interface interface, given a realm realm:
Assert: interface is {{Document}} or an interface that inherits from {{Document}}.
Return a new node that implements interface, in realm.
document = new {{Document()}}
document . {{Document/implementation}}
document . {{Document/URL}}
document . {{Document/documentURI}}
document . {{Document/compatMode}}
BackCompat" if document's mode is
"quirks"; otherwise "CSS1Compat".
document . {{Document/characterSet}}
document . {{Document/contentType}}
The new Document() constructor
steps are to set this's origin to the origin of
current global object's associated Document. [[!HTML]]
Unlike {{DOMImplementation/createDocument()}}, this constructor does not return an {{XMLDocument}} object, but a document ({{Document}} object).
The
implementation getter steps are to return the
{{DOMImplementation}} object that is associated with this.
The URL and
documentURI getter steps are to return this's
URL, serialized.
The compatMode getter steps are to return
"BackCompat" if this's mode is "quirks";
otherwise "CSS1Compat".
The characterSet,
charset, and
inputEncoding getter steps are to return
this's encoding's name.
The contentType getter steps are to return
this's content type.
collection = document . getElementsByTagName(qualifiedName)
If qualifiedName is "*" returns an {{HTMLCollection}} of all
descendant elements.
Otherwise, returns an {{HTMLCollection}} of all descendant elements whose qualified name is qualifiedName. (Matches case-insensitively against elements in the HTML namespace within an HTML document.)
collection = document . getElementsByTagNameNS(namespace, localName)
If namespace and localName are "*", returns an
{{HTMLCollection}} of all descendant elements.
If only namespace is "*", returns an {{HTMLCollection}} of all
descendant elements whose local name is
localName.
If only localName is "*", returns an {{HTMLCollection}} of all
descendant elements whose namespace is
namespace.
Otherwise, returns an {{HTMLCollection}} of all descendant elements whose namespace is namespace and local name is localName.
collection = document . getElementsByClassName(classNames)
collection = element . getElementsByClassName(classNames)
Returns an {{HTMLCollection}} of the elements in the object on which the method was invoked (a document or an element) that have all the classes given by classNames. The classNames argument is interpreted as a space-separated list of classes.
The doctype getter steps are to return the
child of this that is a doctype; otherwise null.
The documentElement getter steps are to return
this's document element.
The getElementsByTagName(qualifiedName)
method steps are to return the list of elements with qualified name qualifiedName
for this.
Thus, in an HTML document,
document.getElementsByTagName("FOO") will match
<FOO> elements that are not in the
HTML namespace, and <foo> elements that are in
the HTML namespace, but not <FOO> elements
that are in the HTML namespace.
The
getElementsByTagNameNS(namespace, localName)
method steps are to return the list of elements with namespace namespace and local
name localName for this.
The getElementsByClassName(classNames)
method steps are to return the list of elements with class names classNames for
this.
<div id="example">
<p id="p1" class="aaa bbb"/>
<p id="p2" class="aaa ccc"/>
<p id="p3" class="bbb ccc"/>
</div>
A call to
document.getElementById("example").getElementsByClassName("aaa")
would return an {{HTMLCollection}} with the two paragraphs
p1 and p2 in it.
A call to
getElementsByClassName("ccc bbb")
would only return one node, however, namely p3. A call to
document.getElementById("example").getElementsByClassName("bbb ccc ")
would return the same thing.
A call to
getElementsByClassName("aaa,bbb")
would return no nodes; none of the elements above are in the
aaa,bbb class.
element = document . createElement(localName [, options])
Returns an element with localName as local name
(if document is an HTML document, localName gets lowercased). The
element's namespace is the HTML namespace when
document is an HTML document or document's
content type is "application/xhtml+xml"; otherwise null.
When supplied, options's {{ElementCreationOptions/customElementRegistry}} can be used to set the {{CustomElementRegistry}}.
When supplied, options's {{ElementCreationOptions/is}} can be used to create a customized built-in element.
If localName is not a valid element local name an "{{InvalidCharacterError}}" {{DOMException}} will be thrown.
When both options's {{ElementCreationOptions/customElementRegistry}} and options's {{ElementCreationOptions/is}} are supplied, a "{{NotSupportedError!!exception}}" {{DOMException}} will be thrown.
element = document . createElementNS(namespace, qualifiedName [, options])
Returns an element with namespace namespace. Its namespace prefix will be everything before U+003A (:) in qualifiedName or null. Its local name will be everything after U+003A (:) in qualifiedName or qualifiedName.
When supplied, options's {{ElementCreationOptions/customElementRegistry}} can be used to set the {{CustomElementRegistry}}.
When supplied, options's {{ElementCreationOptions/is}} can be used to create a customized built-in element.
If qualifiedName is not a (possibly-prefixed) valid element local name an "{{InvalidCharacterError}}" {{DOMException}} will be thrown.
If one of the following conditions is true a "{{NamespaceError!!exception}}" {{DOMException}} will be thrown:
xml" and namespace is not the
XML namespace.
xmlns" and namespace is not the
XMLNS namespace.
xmlns".
When both options's {{ElementCreationOptions/customElementRegistry}} and options's {{ElementCreationOptions/is}} are supplied, a "{{NotSupportedError!!exception}}" {{DOMException}} will be thrown.
documentFragment = document . {{createDocumentFragment()}}
text = document . {{createTextNode(data)}}
text = document . {{createCDATASection(data)}}
comment = document . {{createComment(data)}}
processingInstruction = document . {{createProcessingInstruction(target, data)}}
[=XML/Name=] production an
"{{InvalidCharacterError!!exception}}" {{DOMException}} will be thrown.
If data contains "?>" an
"{{InvalidCharacterError!!exception}}" {{DOMException}} will be thrown.
The element interface for any name and namespace is {{Element}}, unless stated otherwise.
The HTML Standard will, e.g., define that for html and the
HTML namespace, the {{HTMLHtmlElement}} interface is used. [[!HTML]]
The
createElement(localName, options)
method steps are:
If localName is not a valid element local name, then throw an "{{InvalidCharacterError!!exception}}" {{DOMException}}.
If this is an HTML document, then set localName to localName in ASCII lowercase.
Let registry and is be the result of flattening element creation options given options and this.
Let namespace be the HTML namespace, if this is an
HTML document or this's content type is
"application/xhtml+xml"; otherwise null.
Return the result of creating an element given this, localName, namespace, null, is, true, and registry.
The internal createElementNS steps, given document,
namespace, qualifiedName, and options, are as follows:
Let (namespace, prefix, localName) be the result of
[=validate and extract|validating and extracting=] namespace and
qualifiedName given "element".
Let registry and is be the result of flattening element creation options given options and this.
Return the result of creating an element given document, localName, namespace, prefix, is, true, and registry.
The
createElementNS(namespace, qualifiedName, options)
method steps are to return the result of running the
internal createElementNS steps, given this, namespace,
qualifiedName, and options.
To flatten element creation options, given a string or {{ElementCreationOptions}} dictionary options and a document document:
Let registry be the result of looking up a custom element registry given document.
Let is be null.
If options is a dictionary:
If options["{{ElementCreationOptions/is}}"] exists, then set is to it.
If options["{{ElementCreationOptions/customElementRegistry}}"] exists:
If is is non-null, then throw a "{{NotSupportedError!!exception}}" {{DOMException}}.
Set registry to options["{{ElementCreationOptions/customElementRegistry}}"].
If registry is non-null, registry's is scoped is false, and registry is not document's custom element registry, then throw a "{{NotSupportedError!!exception}}" {{DOMException}}.
Return registry and is.
{{Document/createElement()}} and {{Document/createElementNS()}}'s options parameter is allowed to be a string for web compatibility.
The createDocumentFragment() method steps are to
return the result of creating a document fragment given this.
The createTextNode(data) method steps are
to return the result of creating a text node given this and data.
The createCDATASection(data) method steps
are:
If this is an HTML document, then throw a "{{NotSupportedError!!exception}}" {{DOMException}}.
If data contains the string "]]>", then throw an
"{{InvalidCharacterError!!exception}}" {{DOMException}}.
Return the result of creating a CDATA section node given this and data.
The createComment(data) method steps are to
return the result of creating a comment node given this and data.
The
createProcessingInstruction(target, data)
method steps are to return the result of creating a processing instruction node given
this, target, and data.
clone = document . importNode(node [, options = false])
Returns a copy of node. If options is true or options is a dictionary whose {{ImportNodeOptions/selfOnly}} is false, the copy also includes the node's descendants.
options's {{ImportNodeOptions/customElementRegistry}} can be used to set the {{CustomElementRegistry}} of elements that have none.
If node is a document or a shadow root, throws a "{{NotSupportedError!!exception}}" {{DOMException}}.
node = document . adoptNode(node)
Moves node from another document and returns it.
If node is a document, throws a "{{NotSupportedError!!exception}}" {{DOMException}} or, if node is a shadow root, throws a "{{HierarchyRequestError!!exception}}" {{DOMException}}.
The importNode(node, options)
method steps are:
If node is a document or shadow root, then throw a "{{NotSupportedError!!exception}}" {{DOMException}}.
Let subtree be false.
Let registry be null.
If options is a boolean, then set subtree to options.
Otherwise:
Set subtree to the negation of options["{{ImportNodeOptions/selfOnly}}"].
If options["{{ImportNodeOptions/customElementRegistry}}"] exists, then set registry to it.
If registry's is scoped is false and registry is not this's custom element registry, then throw a "{{NotSupportedError!!exception}}" {{DOMException}}.
If registry is null, then set registry to the result of looking up a custom element registry given this.
Return the result of cloning a node given node with document set to this, subtree set to subtree, and fallbackRegistry set to registry.
Specifications may define adopting steps for all or some nodes. The algorithm is passed node and oldDocument, as indicated in the adopt algorithm.
To adopt a node node into a document document:
Let oldDocument be node's node document.
If document is not oldDocument, then for each inclusiveDescendant of node's shadow-including inclusive descendants, in shadow-including tree order:
Set inclusiveDescendant's node document to document.
If inclusiveDescendant is a shadow root and if any of the following are true:
inclusiveDescendant's custom element registry is null and inclusiveDescendant's keep custom element registry null is false; or
inclusiveDescendant's custom element registry is a global custom element registry,
then set inclusiveDescendant's custom element registry to document's custom element registry's effective global custom element registry.
Otherwise, if inclusiveDescendant is an element:
Set the node document of each attribute in inclusiveDescendant's attribute list to document.
If inclusiveDescendant's custom element registry is null or inclusiveDescendant's custom element registry's is scoped is false:
Let registry be null.
If inclusiveDescendant's custom element registry is
non-null, inclusiveDescendant's parent is null, or
inclusiveDescendant's parent is an
exclusive DocumentFragment node, then set registry to
document's custom element registry.
Otherwise, set registry to the result of looking up a custom element registry given inclusiveDescendant's parent.
Set inclusiveDescendant's custom element registry to registry's effective global custom element registry.
If inclusiveDescendant is custom, then
enqueue a custom element callback reaction with inclusiveDescendant, callback
name "adoptedCallback", and « oldDocument, document ».
Run the adopting steps with inclusiveDescendant and oldDocument.
The adoptNode(node) method steps are:
Null or a {{CustomElementRegistry}} object registry is a global custom element registry if registry is non-null and registry's is scoped is false.
Null or a {{CustomElementRegistry}} object registry's effective global custom element registry is:
If registry is a global custom element registry, then return registry.
Return null.
The createAttribute(localName) method
steps are:
If localName is not a valid attribute local name, then throw an "{{InvalidCharacterError!!exception}}" {{DOMException}}.
Return the result of creating an attribute given this and localName.
The
createAttributeNS(namespace, qualifiedName)
method steps are:
Let (namespace, prefix, localName) be the result of
[=validate and extract|validating and extracting=] namespace and
qualifiedName given "attribute".
Return the result of creating an attribute given this, localName, namespace, and prefix.
The createEvent(interface) method steps
are:
Let constructor be null.
If interface is an ASCII case-insensitive match for any of the strings in the first column in the following table, then set constructor to the interface in the second column on the same row as the matching string:
| String | Interface | Notes |
|---|---|---|
"beforeunloadevent" | {{BeforeUnloadEvent}} | [[!HTML]] |
"compositionevent" | {{CompositionEvent}} | [[!UIEVENTS]] |
"customevent" | {{CustomEvent}} | |
"devicemotionevent" | {{DeviceMotionEvent}} | [[!DEVICE-ORIENTATION]] |
"deviceorientationevent" | {{DeviceOrientationEvent}} | |
"dragevent" | {{DragEvent}} | [[!HTML]] |
"event" | {{Event}} | |
"events"
| ||
"focusevent" | {{FocusEvent}} | [[!UIEVENTS]] |
"hashchangeevent" | {{HashChangeEvent}} | [[!HTML]] |
"htmlevents" | {{Event}} | |
"keyboardevent" | {{KeyboardEvent}} | [[!UIEVENTS]] |
"messageevent" | {{MessageEvent}} | [[!HTML]] |
"mouseevent" | {{MouseEvent}} | [[!UIEVENTS]] |
"mouseevents"
| ||
"storageevent" | {{StorageEvent}} | [[!HTML]] |
"svgevents" | {{Event}} | |
"textevent" | {{TextEvent}} | [[!UIEVENTS]] |
"touchevent" | {{TouchEvent}} | [[!TOUCH-EVENTS]] |
"uievent" | {{UIEvent}} | [[!UIEVENTS]] |
"uievents"
|
If constructor is null, then throw a "{{NotSupportedError!!exception}}" {{DOMException}}.
If the interface indicated by constructor is not exposed on the relevant global object of this, then throw a "{{NotSupportedError!!exception}}" {{DOMException}}.
Typically user agents disable support for touch events in some configurations, in which case this clause would be triggered for the interface {{TouchEvent}}.
Let event be the result of creating an event given constructor.
Initialize event's {{Event/type}} attribute to the empty string.
Initialize event's {{Event/timeStamp}} attribute to the result of calling current high resolution time with this's relevant global object.
Initialize event's {{Event/isTrusted}} attribute to false.
Unset event's initialized flag.
Return event.
Event constructors ought to be used instead.
The createRange() method steps are to return a new
live range with (this, 0) as its start an end.
The {{Range/Range()}} constructor can be used instead.
The
createNodeIterator(root, whatToShow, filter)
method steps are:
Let iterator be a new {{NodeIterator}} object.
Set iterator's root to root.
Set iterator's reference to (root, true).
Set iterator's whatToShow to whatToShow.
Set iterator's filter to filter.
Return iterator.
The
createTreeWalker(root, whatToShow, filter)
method steps are:
Let walker be a new {{TreeWalker}} object.
Set walker's whatToShow to whatToShow.
Set walker's filter to filter.
User agents must create a {{DOMImplementation}} object whenever a document is created and associate it with that document.
[Exposed=Window]
interface DOMImplementation {
[NewObject] DocumentType createDocumentType(DOMString name, DOMString publicId, DOMString systemId);
[NewObject] XMLDocument createDocument(DOMString? namespace, [LegacyNullToEmptyString] DOMString qualifiedName, optional DocumentType? doctype = null);
[NewObject] Document createHTMLDocument(optional DOMString title);
boolean hasFeature(); // historical; always returns true
};
doctype = document . {{Document/implementation}} . {{createDocumentType(name, publicId, systemId)}}
doc = document . {{Document/implementation}} . createDocument(namespace, qualifiedName [, doctype = null])
doc = document . {{Document/implementation}} . createHTMLDocument([title])
The
createDocumentType(name, publicId, systemId)
method steps are:
If name is not a valid doctype name, then throw an "{{InvalidCharacterError}}" {{DOMException}}.
Return the result of creating a doctype given the associated document of this, name, publicId, and systemId.
The
createDocument(namespace, qualifiedName, doctype)
method steps are:
Let document be the result of creating a document that implements {{XMLDocument}}, given this's relevant realm.
Let element be null.
If qualifiedName is not the empty string, then set element to the
result of running the internal createElementNS steps, given
document, namespace, qualifiedName, and an empty dictionary.
If doctype is non-null, append doctype to document.
If element is non-null, append element to document.
document's content type is determined by namespace:
application/xhtml+xml
image/svg+xml
application/xml
Return document.
The
createHTMLDocument(title)
method steps are:
Let doc be the result of creating a document that implements {{Document}}, given this's relevant realm.
Set doc's type to "html" and
content type to "text/html".
Let doctype be the result of creating a doctype given doc and
"html".
Append doctype to doc.
Append the result of creating an element given doc,
"html", and the HTML namespace, to doc.
Append the result of creating an element given doc,
"head", and the HTML namespace, to the <{html}> element created earlier.
If title is given:
Append the result of creating an element given doc,
"title", and the HTML namespace, to the <{head}> element created earlier.
Let text be the result of creating a text node given doc and title (which could be the empty string).
Append text to the <{title}> element created earlier.
Append the result of creating an element given doc,
"body", and the HTML namespace, to the <{html}> element created earlier.
Return doc.
The hasFeature() method steps are to
return true.
{{hasFeature()}} originally would report whether the user agent claimed to support a given DOM feature, but experience proved it was not nearly as reliable or granular as simply checking whether the desired objects, attributes, or methods existed. As such, it is no longer to be used, but continues to exist (and simply returns true) so that old pages don't stop working.
[Exposed=Window]
interface DocumentType : Node {
readonly attribute DOMString name;
readonly attribute DOMString publicId;
readonly attribute DOMString systemId;
};
{{DocumentType}} nodes are simply known as doctypes.
Doctypes have an associated name (a string), public ID (a string), and system ID (a string).
To create a doctype given a document document, a string name, and optionally a string publicId (default the empty string) and a string systemId (default the empty string):
Let doctype be the result of creating a node that implements {{DocumentType}}, given document.
Set doctype's name to name, public ID to publicId, and system ID to systemId.
Return doctype.
The name getter steps are to return
this's name.
The publicId getter steps are to return
this's public ID.
The systemId getter steps are to return
this's system ID.
[Exposed=Window]
interface DocumentFragment : Node {
constructor();
};
tree = new {{DocumentFragment()}}
An exclusive {{DocumentFragment}} node is a {{DocumentFragment}} node that is not a {{ShadowRoot}} node.
A {{DocumentFragment}} node has an associated host (null or an element in a different node tree). It is null unless otherwise stated.
An object A is a host-including inclusive ancestor of an object B, if either A is an inclusive ancestor of B, or if B's root has a non-null host and A is a host-including inclusive ancestor of B's root's host.
The {{DocumentFragment}} node's host concept is useful for HTML's <{template}> element and for shadow roots, and impacts the pre-insert and replace algorithms.
To create a document fragment given a document document: return the result of creating a node that implements {{DocumentFragment}}, given document.
The
new DocumentFragment()
constructor steps are to set this's node document to
current global object's associated Document.
[Exposed=Window]
interface ShadowRoot : DocumentFragment {
readonly attribute ShadowRootMode mode;
readonly attribute boolean delegatesFocus;
readonly attribute boolean serializable;
readonly attribute SlotAssignmentMode slotAssignment;
readonly attribute boolean clonable;
readonly attribute Element host;
attribute EventHandler onslotchange;
};
enum ShadowRootMode { "open", "closed" };
enum SlotAssignmentMode { "manual", "named" };
{{ShadowRoot}} nodes are simply known as shadow roots.
Shadow roots's associated host is never null.
Shadow roots have an associated mode ("open"
or "closed").
Shadow roots have an associated delegates focus (a boolean). It is initially set to false.
Shadow roots have an associated available to element internals (a boolean). It is initially set to false.
Shadow roots have an associated declarative (a boolean). It is initially set to false.
Shadow roots have an associated serializable (a boolean). It is initially set to false.
Shadow roots have an associated slot assignment
("manual" or "named").
Shadow roots have an associated clonable (a boolean). It is initially set to false.
Shadow roots have an associated custom element registry (null or a {{CustomElementRegistry}} object). It is initially null.
Shadow roots have an associated keep custom element registry null (a boolean). It is initially false.
This can only ever be true in combination with declarative shadow roots. And it only matters for as long as the shadow root's custom element registry is null.
A shadow root's get the parent algorithm, given an event, returns null if event's composed flag is unset and shadow root is the root of event's path's first event path item's invocation target; otherwise shadow root's host.
The mode getter steps are to return
this's mode.
The delegatesFocus getter steps are to return
this's delegates focus.
The serializable getter steps are to return
this's serializable.
The slotAssignment getter steps are to return
this's slot assignment.
The clonable getter steps are to return
this's clonable.
The host getter steps are to return
this's host.
The onslotchange attribute is an
event handler IDL attribute for the
onslotchange event handler, whose
event handler event type is {{HTMLSlotElement/slotchange}}.
In shadow-including tree order is shadow-including preorder, depth-first traversal of a node tree. Shadow-including preorder, depth-first traversal of a node tree tree is preorder, depth-first traversal of tree, with for each shadow host encountered in tree, shadow-including preorder, depth-first traversal of that element's shadow root's node tree just after it is encountered.
The shadow-including root of an object is its root's host's shadow-including root, if the object's root is a shadow root; otherwise its root.
An object A is a shadow-including descendant of an object B, if A is a descendant of B, or A's root is a shadow root and A's root's host is a shadow-including inclusive descendant of B.
A shadow-including inclusive descendant is an object or one of its shadow-including descendants.
An object A is a shadow-including ancestor of an object B, if and only if B is a shadow-including descendant of A.
A shadow-including inclusive ancestor is an object or one of its shadow-including ancestors.
A node A is closed-shadow-hidden from a node B if all of the following conditions are true:
A's root is a shadow root.
A's root is not a shadow-including inclusive ancestor of B.
A's root is a shadow root whose
mode is "closed" or A's root's
host is closed-shadow-hidden from B.
To retarget an object A against an object B, repeat these steps until they return an object:
If one of the following is true
then return A.
The retargeting algorithm is used by event dispatch as well as other specifications, such as Fullscreen. [[FULLSCREEN]]
[Exposed=Window]
interface Element : Node {
readonly attribute DOMString? namespaceURI;
readonly attribute DOMString? prefix;
readonly attribute DOMString localName;
readonly attribute DOMString tagName;
[CEReactions] attribute DOMString id;
[CEReactions] attribute DOMString className;
[SameObject, PutForwards=value] readonly attribute DOMTokenList classList;
[CEReactions, Unscopable] attribute DOMString slot;
boolean hasAttributes();
[SameObject] readonly attribute NamedNodeMap attributes;
sequence<DOMString> getAttributeNames();
DOMString? getAttribute(DOMString qualifiedName);
DOMString? getAttributeNS(DOMString? namespace, DOMString localName);
[CEReactions] undefined setAttribute(DOMString qualifiedName, (TrustedType or DOMString) value);
[CEReactions] undefined setAttributeNS(DOMString? namespace, DOMString qualifiedName, (TrustedType or DOMString) value);
[CEReactions] undefined removeAttribute(DOMString qualifiedName);
[CEReactions] undefined removeAttributeNS(DOMString? namespace, DOMString localName);
[CEReactions] boolean toggleAttribute(DOMString qualifiedName, optional boolean force);
boolean hasAttribute(DOMString qualifiedName);
boolean hasAttributeNS(DOMString? namespace, DOMString localName);
Attr? getAttributeNode(DOMString qualifiedName);
Attr? getAttributeNodeNS(DOMString? namespace, DOMString localName);
[CEReactions] Attr? setAttributeNode(Attr attr);
[CEReactions] Attr? setAttributeNodeNS(Attr attr);
[CEReactions] Attr removeAttributeNode(Attr attr);
ShadowRoot attachShadow(ShadowRootInit init);
readonly attribute ShadowRoot? shadowRoot;
readonly attribute CustomElementRegistry? customElementRegistry;
Element? closest(DOMString selectors);
boolean matches(DOMString selectors);
boolean webkitMatchesSelector(DOMString selectors); // legacy alias of .matches
HTMLCollection getElementsByTagName(DOMString qualifiedName);
HTMLCollection getElementsByTagNameNS(DOMString? namespace, DOMString localName);
HTMLCollection getElementsByClassName(DOMString classNames);
[CEReactions] Element? insertAdjacentElement(DOMString where, Element element); // legacy
undefined insertAdjacentText(DOMString where, DOMString data); // legacy
};
dictionary ShadowRootInit {
required ShadowRootMode mode;
boolean delegatesFocus = false;
boolean serializable = false;
SlotAssignmentMode slotAssignment = "named";
boolean clonable = false;
CustomElementRegistry? customElementRegistry;
};
{{ShadowRootInit}} somewhat unusually allows both undefined and
null to be passed to its {{ShadowRootInit/customElementRegistry}} member to allow web
developers to pass a {{ShadowRoot}} node instead of a dictionary to {{Element/attachShadow()}}.
{{Element}} nodes are simply known as elements.
Elements have an associated:
undefined", "failed", "uncustomized",
"precustomized", or "custom".
is value
When an element is created, all of these values are initialized.
An element whose custom element state is
"uncustomized" or "custom" is said to be
defined. An element whose
custom element state is "custom" is said to be
custom.
Whether or not an element is defined is used to determine the
behavior of the '':defined'' pseudo-class. Whether or not an element is custom is
used to determine the behavior of the mutation algorithms. The
"failed" and "precustomized" states are used to ensure that if a
custom element constructor fails to execute correctly the first time, it is not executed
again by an upgrade.
The following code illustrates elements in each of these four states:
<!DOCTYPE html>
<script>
window.customElements.define("sw-rey", class extends HTMLElement {})
window.customElements.define("sw-finn", class extends HTMLElement {}, { extends: "p" })
window.customElements.define("sw-kylo", class extends HTMLElement {
constructor() {
// super() intentionally omitted for this example
}
})
</script>
<!-- "undefined" (not defined, not custom) -->
<sw-han></sw-han>
<p is="sw-luke"></p>
<p is="asdf"></p>
<!-- "failed" (not defined, not custom) -->
<sw-kylo></sw-kylo>
<!-- "uncustomized" (defined, not custom) -->
<p></p>
<asdf></asdf>
<!-- "custom" (defined, custom) -->
<sw-rey></sw-rey>
<p is="sw-finn"></p>
Elements also have an associated shadow root (null or a shadow root). It is null unless otherwise stated. An element is a shadow host if its shadow root is non-null.
An element's
qualified name is its
local name if its namespace prefix is null; otherwise its
namespace prefix, followed by ":", followed by its
local name.
An element's HTML-uppercased qualified name is the return value of these steps:
Let qualifiedName be this's qualified name.
If this is in the HTML namespace and its node document is an HTML document, then return qualifiedName in ASCII uppercase.
User agents could optimize qualified name and HTML-uppercased qualified name by storing them in internal slots.
To create an element, given a document
document, string localName, string-or-null namespace, and
optionally a string-or-null prefix (default null), string-or-null is (default
null), boolean synchronousCustomElements (default false), and "default",
null, or a {{CustomElementRegistry}} object registry (default "default"):
Let result be null.
If registry is "default", then set registry to the result
of looking up a custom element registry given document.
Let definition be the result of looking up a custom element definition given registry, namespace, localName, and is.
If definition is non-null, and definition's name is not equal to its local name (i.e., definition represents a customized built-in element):
Let interface be the element interface for localName and the HTML namespace.
Set result to the result of creating an element internal given
document, interface, localName, the HTML namespace,
prefix, "undefined", is, and registry.
If synchronousCustomElements is true, then run this step while catching any exceptions:
Upgrade result using definition.
If this step threw an exception exception:
Report exception for definition's constructor's corresponding JavaScript object's associated realm's global object.
Set result's custom element state to
"failed".
Otherwise, enqueue a custom element upgrade reaction given result and definition.
Otherwise, if definition is non-null:
If synchronousCustomElements is true:
Let C be definition's constructor.
Let previousRegistry be the surrounding agent's active custom element constructor map[C] with default null.
Set the surrounding agent's active custom element constructor map[C] to registry.
Run these steps while catching any exceptions:
Set result to the result of constructing C, with no arguments.
Assert: one of the following is true:
custom"
and its custom element definition is non-null;
precustomized"; or
custom" nor "precustomized" and its
custom element definition is null.
customElements.define("x-example", class extends HTMLElement {
constructor() {
// Non-conformant: returns an existing element instead of calling super().
return document.createElement("p");
}
});
document.createElement("x-example");
Here result is the p element, whose
custom element state is "uncustomized" and whose
custom element definition is null.
Assert: result's namespace is the HTML namespace.
IDL enforces that result is an {{HTMLElement}} object, which all use the HTML namespace.
If result's attribute list is not empty, then throw a "{{NotSupportedError!!exception}}" {{DOMException}}.
If result has children, then throw a "{{NotSupportedError!!exception}}" {{DOMException}}.
If result's parent is non-null, then throw a "{{NotSupportedError!!exception}}" {{DOMException}}.
If result's node document is not document, then throw a "{{NotSupportedError!!exception}}" {{DOMException}}.
If result's local name is not equal to localName, then throw a "{{NotSupportedError!!exception}}" {{DOMException}}.
Set result's namespace prefix to prefix.
Set result's is value to null.
Set result's custom element registry to registry.
If any of these steps threw an exception exception:
Report exception for definition's constructor's corresponding JavaScript object's associated realm's global object.
Set result to the result of creating an element internal given
document, {{HTMLUnknownElement}}, localName, the HTML namespace,
prefix, "failed", null, and registry.
If previousRegistry is null, then remove the surrounding agent's active custom element constructor map[C].
Otherwise, set the surrounding agent's active custom element constructor map[C] to previousRegistry.
Otherwise:
Set result to the result of creating an element internal given
document, {{HTMLElement}}, localName, the HTML namespace,
prefix, "undefined", null, and registry.
Enqueue a custom element upgrade reaction given result and definition.
Otherwise:
Let interface be the element interface for localName and namespace.
Set result to the result of creating an element internal given
document, interface, localName, namespace,
prefix, "uncustomized", is, and registry.
If namespace is the HTML namespace, and either localName is a
valid custom element name or is is non-null, then set result's
custom element state to "undefined".
Return result.
To create an element internal given a document document, an interface interface a string localName, a string-or-null namespace, a string-or-null prefix, a string state, a string-or-null is, and null or a {{CustomElementRegistry}} object registry:
Let element be the result of creating a node that implements interface, given document.
Set element's namespace to namespace,
namespace prefix to prefix, local name to
localName, custom element registry to registry,
custom element state to state,
custom element definition to null, and is value
to is.
Assert: element's attribute list is empty.
Return element.
Elements also have an attribute list, which is a list exposed through a {{NamedNodeMap}}. Unless explicitly given when an element is created, its attribute list is empty.
An element has an attribute A if its attribute list contains A.
This and other specifications may define attribute change steps for elements. The algorithm is passed element, localName, oldValue, value, and namespace.
To handle attribute changes for an attribute attribute with element, oldValue, and newValue, run these steps:
Queue a mutation record of "attributes" for element with
attribute's local name, attribute's
namespace, oldValue, « », « », null, and null.
If element is custom, then
enqueue a custom element callback reaction with element, callback name
"attributeChangedCallback", and « attribute's local name,
oldValue, newValue, attribute's namespace ».
Run the attribute change steps with element, attribute's local name, oldValue, newValue, and attribute's namespace.
To change an attribute attribute to value:
Let oldValue be attribute's value.
Set attribute's value to value.
Handle attribute changes for attribute with attribute's element, oldValue, and value.
To append an attribute attribute to an element element:
Append attribute to element's attribute list.
Set attribute's element to element.
Set attribute's node document to element's node document.
Handle attribute changes for attribute with element, null, and attribute's value.
To remove an attribute attribute:
Let element be attribute's element.
Set attribute's element to null.
Handle attribute changes for attribute with element, attribute's value, and null.
To replace an attribute oldAttribute with an attribute newAttribute:
Let element be oldAttribute's element.
Replace oldAttribute by newAttribute in element's attribute list.
Set newAttribute's element to element.
Set newAttribute's node document to element's node document.
Set oldAttribute's element to null.
Handle attribute changes for oldAttribute with element, oldAttribute's value, and newAttribute's value.
To get an attribute by name given a string qualifiedName and an element element:
If element is in the HTML namespace and its node document is an HTML document, then set qualifiedName to qualifiedName in ASCII lowercase.
Return the first attribute in element's attribute list whose qualified name is qualifiedName; otherwise null.
To get an attribute by namespace and local name given null or a string namespace, a string localName, and an element element:
If namespace is the empty string, then set it to null.
Return the attribute in element's attribute list whose namespace is namespace and local name is localName, if any; otherwise null.
To get an attribute value given an element element, a string localName, and an optional null or string namespace (default null):
Let attr be the result of getting an attribute given namespace, localName, and element.
If attr is null, then return the empty string.
Return attr's value.
To set an attribute given an attribute attr and an element element:
Let verifiedValue be the result of calling get trusted type compliant attribute value with attr's local name, attr's namespace, element, and attr's value. [[!TRUSTED-TYPES]]
If attr's element is neither null nor element, throw an "{{InUseAttributeError!!exception}}" {{DOMException}}.
Let oldAttr be the result of getting an attribute given attr's namespace, attr's local name, and element.
If oldAttr is attr, return attr.
Set attr's value to verifiedValue.
If oldAttr is non-null, then replace oldAttr with attr.
Otherwise, append attr to element.
Return oldAttr.
To set an attribute value given an element element, a string localName, a string value, an optional null or string prefix (default null), and an optional null or string namespace (default null):
Change attribute to value.
To remove an attribute by name given a string qualifiedName and an element element:
Let attr be the result of getting an attribute given qualifiedName and element.
If attr is non-null, then remove attr.
Return attr.
To remove an attribute by namespace and local name given null or a string namespace, a string localName, and an element element:
Let attr be the result of getting an attribute given namespace, localName, and element.
If attr is non-null, then remove attr.
Return attr.
An element can have an associated unique identifier (ID)
Historically elements could have multiple identifiers e.g., by using
the HTML id attribute and a DTD. This specification makes ID
a concept of the DOM and allows for only one per element, given by an
id attribute.
Use these attribute change steps to update an element's ID:
If localName is id, namespace is null, and
value is null or the empty string, then unset element's
ID.
Otherwise, if localName is id, namespace is null, then
set element's ID to value.
While this specification defines requirements for class,
id, and slot attributes on any element, it makes no
claims as to whether using them is conforming or not.
A node's parent of type {{Element}} is known as its parent element. If the node has a parent of a different type, its parent element is null.
The namespaceURI getter steps are to return
this's namespace.
The prefix getter steps are to return
this's namespace prefix.
The localName getter steps are to return
this's local name.
The tagName getter steps are to return
this's HTML-uppercased qualified name.
element . id [ = value ]
Returns the value of element's id content attribute. Can be set to
change it.
element . className [ = value ]
Returns the value of element's class content attribute. Can be set
to change it.
element . classList
Allows for manipulation of element's class content attribute as a
set of whitespace-separated tokens through a {{DOMTokenList}} object.
element . slot [ = value ]
Returns the value of element's slot content attribute. Can be set to
change it.
IDL attributes that are defined to reflect a string name, must have these getter and setter steps:
Return the result of running get an attribute value given this and name.
Set an attribute value for this using name and the given value.
The id attribute must reflect
"id".
The className attribute must
reflect "class".
The classList getter steps are to return a
{{DOMTokenList}} object whose associated element is this and whose associated
attribute's local name is class. The token set of this
particular {{DOMTokenList}} object are also known as the element's
classes.
The slot attribute must reflect
"slot".
id, class, and slot are effectively
superglobal attributes as they can appear on any element, regardless of that element's
namespace.
element . hasAttributes()
Returns true if element has attributes; otherwise false.
element . getAttributeNames()
Returns the qualified names of all element's attributes. Can contain duplicates.
element . getAttribute(qualifiedName)
Returns element's first attribute whose qualified name is qualifiedName, and null if there is no such attribute otherwise.
element . getAttributeNS(namespace, localName)
Returns element's attribute whose namespace is namespace and local name is localName, and null if there is no such attribute otherwise.
element . setAttribute(qualifiedName, value)
Sets the value of element's first attribute whose qualified name is qualifiedName to value.
element . setAttributeNS(namespace, localName, value)
Sets the value of element's attribute whose namespace is namespace and local name is localName to value.
element . removeAttribute(qualifiedName)
Removes element's first attribute whose qualified name is qualifiedName.
element . removeAttributeNS(namespace, localName)
Removes element's attribute whose namespace is namespace and local name is localName.
element . toggleAttribute(qualifiedName [, force])
If force is not given, "toggles" qualifiedName, removing it if it is present and adding it if it is not present. If force is true, adds qualifiedName. If force is false, removes qualifiedName.
Returns true if qualifiedName is now present; otherwise false.
element . hasAttribute(qualifiedName)
Returns true if element has an attribute whose qualified name is qualifiedName; otherwise false.
element . hasAttributeNS(namespace, localName)
Returns true if element has an attribute whose namespace is namespace and local name is localName.
The hasAttributes() method steps are to return false
if this's attribute list is empty; otherwise true.
The attributes getter steps are to return the
associated {{NamedNodeMap}}.
The getAttributeNames() method steps are to return the
qualified names of the attributes in this's
attribute list, in order; otherwise a new list.
These are not guaranteed to be unique.
The getAttribute(qualifiedName) method
steps are:
Let attr be the result of getting an attribute given qualifiedName and this.
If attr is null, return null.
Return attr's value.
The
getAttributeNS(namespace, localName)
method steps are:
Let attr be the result of getting an attribute given namespace, localName, and this.
If attr is null, return null.
Return attr's value.
The
setAttribute(qualifiedName, value)
method steps are:
If qualifiedName is not a valid attribute local name, then throw an "{{InvalidCharacterError!!exception}}" {{DOMException}}.
Despite the parameter naming, qualifiedName is only used as a [=Attr/qualified name=] if an [=attribute=] already exists with that qualified name. Otherwise, it is used as the [=Attr/local name=] of the new attribute. We only need to validate it for the latter case.
If this is in the HTML namespace and its node document is an HTML document, then set qualifiedName to qualifiedName in ASCII lowercase.
Let verifiedValue be the result of calling get trusted type compliant attribute value with qualifiedName, null, this, and value. [[!TRUSTED-TYPES]]
Let attribute be the first attribute in this's attribute list whose qualified name is qualifiedName, and null otherwise.
If attribute is non-null, then change attribute to verifiedValue and return.
Set attribute to the result of creating an attribute given this's node document, qualifiedName, null, null, and verifiedValue.
The
setAttributeNS(namespace, qualifiedName, value)
method steps are:
Let (namespace, prefix, localName) be the result of
[=validate and extract|validating and extracting=] namespace and
qualifiedName given "attribute".
Let verifiedValue be the result of calling get trusted type compliant attribute value with localName, namespace, this, and value. [[!TRUSTED-TYPES]]
Set an attribute value for this using localName, verifiedValue, prefix, and namespace.
The
removeAttribute(qualifiedName)
method steps are to remove an attribute given
qualifiedName and this, and then return undefined.
The
removeAttributeNS(namespace, localName)
method steps are to remove an attribute
given namespace, localName, and this, and then return undefined.
The hasAttribute(qualifiedName) method
steps are:
If this is in the HTML namespace and its node document is an HTML document, then set qualifiedName to qualifiedName in ASCII lowercase.
Return true if this has an attribute whose qualified name is qualifiedName; otherwise false.
The
toggleAttribute(qualifiedName, force)
method steps are:
If qualifiedName is not a valid attribute local name, then throw an "{{InvalidCharacterError!!exception}}" {{DOMException}}.
See the discussion above about why we validate it as a local name, instead of a qualified name.
If this is in the HTML namespace and its node document is an HTML document, then set qualifiedName to qualifiedName in ASCII lowercase.
Let attribute be the first attribute in this's attribute list whose qualified name is qualifiedName, and null otherwise.
If attribute is null:
If force is not given or is true, then append the result of creating an attribute given this's node document and qualifiedName to this, and then return true.
Return false.
If force is not given or is false, remove an attribute given qualifiedName and this, and then return false.
Return true.
The
hasAttributeNS(namespace, localName)
method steps are:
If namespace is the empty string, then set it to null.
The getAttributeNode(qualifiedName) method
steps are to return the result of getting an attribute given
qualifiedName and this.
The
getAttributeNodeNS(namespace, localName)
method steps are to return the result of
getting an attribute given
namespace, localName, and this.
The setAttributeNode(attr) and
setAttributeNodeNS(attr) methods steps are to
return the result of setting an attribute given attr and
this.
The removeAttributeNode(attr) method steps
are:
If this's attribute list does not contain attr, then throw a "{{NotFoundError!!exception}}" {{DOMException}}.
Remove attr.
Return attr.
shadow = element . {{attachShadow(init)}}
Creates a shadow root for element and returns it.
shadow = element . {{shadowRoot}}
Returns element's shadow root, if any, and if
shadow root's mode is "open"; otherwise null.
A valid shadow host name is:
article",
"aside",
"blockquote",
"body",
"div",
"footer",
"h1",
"h2",
"h3",
"h4",
"h5",
"h6",
"header",
"main",
"nav",
"p",
"section", or
"span"
This list is intentionally limited so that built-in elements can gain internal shadow trees over time as needed.
The attachShadow(init) method steps are:
Let registry be this's node document's custom element registry.
If init["{{ShadowRootInit/customElementRegistry}}"] exists, then set registry to it.
If registry is non-null, registry's is scoped is false, and registry is not this's node document's custom element registry, then throw a "{{NotSupportedError!!exception}}" {{DOMException}}.
Run attach a shadow root with this, init["{{ShadowRootInit/mode}}"], init["{{ShadowRootInit/delegatesFocus}}"], init["{{ShadowRootInit/serializable}}"], init["{{ShadowRootInit/slotAssignment}}"], init["{{ShadowRootInit/clonable}}"], and registry.
Return this's shadow root.
To attach a shadow root, given an element element, a string mode, a boolean delegatesFocus, a boolean serializable, a string slotAssignment, a boolean clonable, and null or a {{CustomElementRegistry}} object registry:
If element's namespace is not the HTML namespace, then throw a "{{NotSupportedError!!exception}}" {{DOMException}}.
If element's local name is not a valid shadow host name, then throw a "{{NotSupportedError!!exception}}" {{DOMException}}.
If element's local name is a valid custom element name, or
element's is value is non-null:
Let definition be the result of looking up a custom element definition
given element's custom element registry, its
namespace, its local name, and its
is value.
If definition is non-null and definition's disable shadow is true, then throw a "{{NotSupportedError!!exception}}" {{DOMException}}.
If element is a shadow host:
Let currentShadowRoot be element's shadow root.
If any of the following are true:
currentShadowRoot's declarative is false; or
currentShadowRoot's mode is not mode,
then throw a "{{NotSupportedError!!exception}}" {{DOMException}}.
Remove all of currentShadowRoot's children, in tree order.
Set currentShadowRoot's declarative to false.
Return.
Let shadow be the result of creating a node that implements {{ShadowRoot}}, given element's node document.
Set shadow's host to element.
Set shadow's mode to mode.
Set shadow's delegates focus to delegatesFocus.
If element's custom element state is
"precustomized" or "custom", then set shadow's
available to element internals to true.
Set shadow's declarative to false.
Set shadow's serializable to serializable.
Set shadow's slot assignment to slotAssignment.
Set shadow's clonable to clonable.
Set shadow's custom element registry to registry.
Set element's shadow root to shadow.
The shadowRoot getter steps are:
Let shadow be this's shadow root.
If shadow is null or its mode is "closed",
then return null.
Return shadow.
registry = element . {{Element/customElementRegistry}}
Returns element's {{CustomElementRegistry}} object, if any; otherwise null.
The customElementRegistry getter steps are to
return this's custom element registry.
element . {{closest(selectors)}}
element . {{matches(selectors)}}
The closest(selectors) method steps are:
Let selector be the result of parse a selector from selectors. [[!SELECTORS4]]
If selector is failure, then throw a "{{SyntaxError!!exception}}" {{DOMException}}.
Let elements be this's inclusive ancestors that are elements, in reverse tree order.
For each element of elements: if match a selector against an element, using selector, element, and scoping root this, returns success, return element. [[!SELECTORS4]]
Return null.
The matches(selectors) and
webkitMatchesSelector(selectors) method steps
are:
Let selector be the result of parse a selector from selectors. [[!SELECTORS4]]
If selector is failure, then throw a "{{SyntaxError!!exception}}" {{DOMException}}.
If the result of match a selector against an element, using selector, this, and scoping root this, returns success, then return true; otherwise, return false. [[!SELECTORS4]]
The getElementsByTagName(qualifiedName)
method steps are to return the list of elements with qualified name qualifiedName
for this.
The
getElementsByTagNameNS(namespace, localName)
method steps are to return the list of elements with namespace namespace and local
name localName for this.
The getElementsByClassName(classNames)
method steps are to return the list of elements with class names classNames for
this.
To insert adjacent, given an element element, string where, and a node node, run the steps associated with the first ASCII case-insensitive match for where:
beforebegin"
If element's parent is null, return null.
Return the result of pre-inserting node into element's parent before element.
afterbegin"
Return the result of pre-inserting node into element before element's first child.
beforeend"
Return the result of pre-inserting node into element before null.
afterend"
If element's parent is null, return null.
Return the result of pre-inserting node into element's parent before element's next sibling.
Throw a "{{SyntaxError!!exception}}" {{DOMException}}.
The
insertAdjacentElement(where, element)
method steps are to return the result of running insert adjacent, give this,
where, and element.
The
insertAdjacentText(where, data)
method steps are:
Let text be the result of creating a text node given this's node document and data.
Run insert adjacent, given this, where, and text.
This method returns nothing because it existed before we had a chance to design it.
[Exposed=Window,
LegacyUnenumerableNamedProperties]
interface NamedNodeMap {
readonly attribute unsigned long length;
getter Attr? item(unsigned long index);
getter Attr? getNamedItem(DOMString qualifiedName);
Attr? getNamedItemNS(DOMString? namespace, DOMString localName);
[CEReactions] Attr? setNamedItem(Attr attr);
[CEReactions] Attr? setNamedItemNS(Attr attr);
[CEReactions] Attr removeNamedItem(DOMString qualifiedName);
[CEReactions] Attr removeNamedItemNS(DOMString? namespace, DOMString localName);
};
A {{NamedNodeMap}} has an associated element (an element).
A {{NamedNodeMap}} object's attribute list is its element's attribute list.
A {{NamedNodeMap}} object's supported property indices are the numbers in the range zero to its attribute list's size − 1, unless the attribute list is empty, in which case there are no supported property indices.
The length getter steps are to return
the attribute list's size.
The item(index) method steps are:
If index is equal to or greater than this's attribute list's size, then return null.
Otherwise, return this's attribute list[index].
A {{NamedNodeMap}} object's supported property names are the return value of running these steps:
Let names be the qualified names of the attributes in this {{NamedNodeMap}} object's attribute list, with duplicates omitted, in order.
If this {{NamedNodeMap}} object's element is in the HTML namespace and its node document is an HTML document, then for each name of names:
Let lowercaseName be name, in ASCII lowercase.
If lowercaseName is not equal to name, remove name from names.
Return names.
The getNamedItem(qualifiedName)
method steps are to return the result of getting an attribute
given qualifiedName and element.
The
getNamedItemNS(namespace, localName)
method steps are to return the result of
getting an attribute given
namespace, localName, and element.
The setNamedItem(attr) and
setNamedItemNS(attr) method steps are
to return the result of setting an attribute given attr and
element.
The removeNamedItem(qualifiedName)
method steps are:
Let attr be the result of removing an attribute given qualifiedName and element.
If attr is null, then throw a "{{NotFoundError!!exception}}" {{DOMException}}.
Return attr.
The
removeNamedItemNS(namespace, localName)
method steps are:
Let attr be the result of removing an attribute given namespace, localName, and element.
If attr is null, then throw a "{{NotFoundError!!exception}}" {{DOMException}}.
Return attr.
[Exposed=Window]
interface Attr : Node {
readonly attribute DOMString? namespaceURI;
readonly attribute DOMString? prefix;
readonly attribute DOMString localName;
readonly attribute DOMString name;
[CEReactions] attribute DOMString value;
readonly attribute Element? ownerElement;
readonly attribute boolean specified; // historical; always returns true
};
{{Attr}} nodes are simply known as attributes. They are sometimes referred to as content attributes to avoid confusion with IDL attributes. Attributes have a namespace (null or a non-empty string), namespace prefix (null or a non-empty string), local name (a non-empty string), value (a string), and element (null or an element).
If designed today they would just have a name and value. ☹
An attribute's
qualified name is its
local name if its namespace prefix is null, and its
namespace prefix, followed by ":", followed by its
local name, otherwise.
User agents could have this as an internal slot as an optimization.
To create an attribute given a document document, a string localName, and optionally a string-or-null namespace (default null), a string-or-null prefix (default null), and a string value (default the empty string):
Let attribute be the result of creating a node that implements {{Attr}}, given document.
Set attribute's namespace to namespace, namespace prefix to prefix, local name to localName, and value to value.
Return attribute.
An
A attribute
is an attribute whose
local name is
A and whose
namespace and
namespace prefix are
null.
The namespaceURI getter steps are to return
this's namespace.
The prefix getter steps are to return this's
namespace prefix.
The localName getter steps are to return
this's local name.
The name getter steps are to return this's
qualified name.
The value getter steps are to return this's
value.
To set an existing attribute value, given an attribute attribute and string value, run these steps:
If attribute's element is null, then set attribute's value to value and return.
Let element be attribute's element.
Let verifiedValue be the result of calling get trusted type compliant attribute value with attribute's local name, attribute's namespace, element, and value. [[!TRUSTED-TYPES]]
If attribute's element is null, then set attribute's value to verifiedValue and return.
Change attribute to verifiedValue.
The {{Attr/value}} setter steps are to set an existing attribute value with this and the given value.
The ownerElement getter steps are to return
this's element.
The specified getter steps are to return true.
[Exposed=Window]
interface CharacterData : Node {
attribute [LegacyNullToEmptyString] DOMString data;
readonly attribute unsigned long length;
DOMString substringData(unsigned long offset, unsigned long count);
undefined appendData(DOMString data);
undefined insertData(unsigned long offset, DOMString data);
undefined deleteData(unsigned long offset, unsigned long count);
undefined replaceData(unsigned long offset, unsigned long count, DOMString data);
};
{{CharacterData}} is an abstract interface. You cannot get a direct instance of it. It is used by {{Text}}, {{ProcessingInstruction}}, and {{Comment}} nodes.
Each node inheriting from the {{CharacterData}} interface has an associated mutable string called data.
To replace data of a node node with an integer offset, integer count, string data, and an optional boolean piAttributesAlreadyUpdated (default false):
Let length be node's length.
If offset is greater than length, then throw an "{{IndexSizeError!!exception}}" {{DOMException}}.
If offset + count is greater than length, then set count to length − offset.
Queue a mutation record of "characterData" for node with
null, null, node's data, « », « », null, and null.
Insert data into node's data after offset code units.
Let deleteOffset be offset + data's length.
Starting from deleteOffset code units, remove count code units from node's data.
For each live range whose start node is node and start offset is greater than offset but less than or equal to offset + count: set its start offset to offset.
For each live range whose end node is node and end offset is greater than offset but less than or equal to offset + count: set its end offset to offset.
For each live range whose start node is node and start offset is greater than offset + count: increase its start offset by data's length and decrease it by count.
For each live range whose end node is node and end offset is greater than offset + count: increase its end offset by data's length and decrease it by count.
If node is a {{ProcessingInstruction}} node and piAttributesAlreadyUpdated is false, then update attributes from data given node.
If node's parent is non-null, then run the children changed steps for node's parent.
To substring data of a node node with an integer offset and integer count:
Let length be node's length.
If offset is greater than length, then throw an "{{IndexSizeError!!exception}}" {{DOMException}}.
If offset + count is greater than length, then return a string whose value is the code units from the offsetth code unit to the end of node's data.
Return a string whose value is the code units from the offsetth code unit to the offset+countth code unit in node's data.
The data getter steps are to return
this's data. Its setter steps are to replace data of
this with 0, this's length, and the given value.
The
substringData(offset, count)
method steps are to return the result of substringing data of this with
offset and count.
The appendData(data) method steps are
to replace data of this with this's length, 0, and
data.
The
insertData(offset, data)
method steps are to replace data of this with offset, 0, and
data.
The
deleteData(offset, count)
method steps are to replace data of this with offset, count, and
the empty string.
The
replaceData(offset, count, data)
method steps are to replace data of this with offset, count, and
data.
[Exposed=Window]
interface Text : CharacterData {
constructor(optional DOMString data = "");
[NewObject] Text splitText(unsigned long offset);
readonly attribute DOMString wholeText;
};
text = new Text([data = ""])
text . {{Text/splitText(offset)}}
text . {{Text/wholeText}}
The contiguous {{Text}} nodes of a node node are
node, node's previous sibling {{Text}} node, if any, and
its contiguous Text nodes, and node's next sibling
{{Text}} node, if any, and its contiguous Text nodes, avoiding any
duplicates.
The contiguous exclusive {{Text}} nodes of a node node
are node, node's previous sibling
exclusive Text node, if any, and its
contiguous exclusive Text nodes, and node's
next sibling exclusive Text node, if any, and its
contiguous exclusive Text nodes, avoiding any duplicates.
The child text content of a node node is the concatenation of the data of all the {{Text}} node children of node, in tree order.
The descendant text content of a node node is the concatenation of the data of all the {{Text}} node descendants of node, in tree order.
To create a text node given a document document and a string data:
Let text be the result of creating a node that implements {{Text}}, given document.
Set text's data to data.
Return text.
The new Text(data)
constructor steps are to set this's data to data and
this's node document to current global object's
associated Document.
To split a {{Text}} node node with integer offset:
Let length be node's length.
If offset is greater than length, then throw an "{{IndexSizeError!!exception}}" {{DOMException}}.
Let count be length − offset.
Let newData be the result of substringing data of node with offset and count.
Let newNode be the result of creating a text node given node's node document and newData.
Let parent be node's parent.
If parent is non-null:
Insert newNode into parent before node's next sibling.
For each live range whose start node is node and start offset is greater than offset, set its start node to newNode and decrease its start offset by offset.
For each live range whose end node is node and end offset is greater than offset, set its end node to newNode and decrease its end offset by offset.
For each live range whose start node is parent and start offset is equal to the index of node plus 1, increase its start offset by 1.
For each live range whose end node is parent and end offset is equal to the index of node plus 1, increase its end offset by 1.
Replace data of node with offset, count, and the empty string.
Return newNode.
The wholeText getter steps are to return the
concatenation of the data of the
contiguous Text nodes of this, in tree order.
[Exposed=Window]
interface CDATASection : Text {
};
To create a CDATA section node given a document document and a string data:
Let node be the result of creating a node that implements {{CDATASection}}, given document.
Set node's data to data.
Return node.
[Exposed=Window]
interface ProcessingInstruction : CharacterData {
constructor(DOMString target, optional DOMString data = "");
readonly attribute DOMString target;
boolean hasAttributes();
sequence<DOMString> getAttributeNames();
DOMString? getAttribute(DOMString name);
undefined setAttribute(DOMString name, DOMString value);
undefined removeAttribute(DOMString name);
boolean toggleAttribute(DOMString name, optional boolean force);
boolean hasAttribute(DOMString name);
};
pi = new ProcessingInstruction(target [, data = ""])
pi . {{ProcessingInstruction/target}}
pi . hasAttributes()
Returns true if pi has attributes; otherwise false.
pi . getAttributeNames()
Returns the names of all of pi's attributes. Cannot contain duplicates.
pi . getAttribute(name)
Returns the value of pi's attribute named name, and null if there is no such attribute.
pi . setAttribute(name, value)
Sets pi's attribute named name to value.
pi . removeAttribute(name)
Removes pi's attribute named name.
pi . toggleAttribute(name [, force])
If force is not given, "toggles" name, removing it if it is present and adding it if it is not present. If force is true, adds name. If force is false, removes name.
Returns true if name is now present; otherwise false.
pi . hasAttribute(name)
Returns true if pi has an attribute named name; otherwise false.
{{ProcessingInstruction}} nodes have an associated target.
{{ProcessingInstruction}} nodes have an associated attribute map, which is a map, initially empty.
To create a processing instruction node given a document document, a string target, and a string data:
Let pi be the result of creating a node that implements {{ProcessingInstruction}}, given document.
Initialize pi with target and data.
Return pi.
To initialize a {{ProcessingInstruction}} node pi, with target and data:
If target does not match the [=XML/Name=] production, then
throw an "{{InvalidCharacterError!!exception}}" {{DOMException}}.
If data contains the string "?>", then throw an
"{{InvalidCharacterError!!exception}}" {{DOMException}}.
Set pi's target to target.
Set pi's data to data.
Update attributes from data given pi.
To update attributes from data, given a {{ProcessingInstruction}} node pi:
Clear pi's attribute map.
Let result be the parsing result of invoking the rules for parsing pseudo-attributes from a string given pi's data.
If result is an error, then return.
For each pseudo-attribute pseudoAttr of result: set pi's attribute map[pseudoAttr's [=pseudo-attribute/name=]] to pseudoAttr's [=pseudo-attribute/value=].
To update data from attributes, given a {{ProcessingInstruction}} node pi:
Let data be the empty string.
For each name → value of pi's attribute map:
If data is not the empty string, then append U+0020 SPACE to data.
Append name to data.
Append U+003D (=) to data.
Append U+0022 (") to data.
Replace any U+0026 (&) in value with "&".
Replace any U+003C (<) in value with "<".
Replace any U+003E (>) in value with ">".
Replace any U+0022 (") in value with """.
Append value to data.
Append U+0022 (") to data.
Replace data of pi with 0, pi's length, data, and true.
To get a processing instruction attribute, given a {{ProcessingInstruction}} node pi and a string name: return pi's attribute map[name] with default null.
The
new ProcessingInstruction(target, data)
constructor steps are:
Set this's node document to current global object's
associated Document.
Initialize this with target and data.
The hasAttributes() method steps are to
return false if this's attribute map
is empty; otherwise true.
The getAttributeNames() method steps
are to return the result of getting the keys of this's
attribute map.
The getAttribute(name) method
steps are to return the result of getting a processing instruction attribute given this
and name.
The
setAttribute(name, value)
method steps are:
If name is not a valid attribute local name, then throw an "{{InvalidCharacterError!!exception}}" {{DOMException}}.
Set this's attribute map[name] to value.
Update data from attributes given this.
The removeAttribute(name)
method steps are:
Remove this's attribute map[name].
Update data from attributes given this.
The
toggleAttribute(name, force)
method steps are:
If name is not a valid attribute local name, then throw an "{{InvalidCharacterError!!exception}}" {{DOMException}}.
Let attributes be this's attribute map.
If attributes[name] does not exist:
If force is not given or is true, set attributes[name] to the empty string, update data from attributes given this, and then return true.
Return false.
If force is not given or is false, remove attributes[name], update data from attributes given this, and then return false.
Return true.
The hasAttribute(name)
method steps are to return true if this's
attribute map[name] exists; otherwise
false.
[Exposed=Window]
interface Comment : CharacterData {
constructor(optional DOMString data = "");
};
comment = new Comment([data = ""])
To create a comment node given a document document and a string data:
Let comment be the result of creating a node that implements {{Comment}}, given document.
Set comment's data to data.
Return comment.
The new Comment(data)
constructor steps are to set this's data to data and
this's node document to current global object's
associated Document.
{{StaticRange}} and {{Range}} objects (ranges) represent a sequence of content within a node tree. Each range has a start and an end which are boundary points. A boundary point is a tuple consisting of a node and an offset. So in other words, a range represents a piece of content within a node tree between two boundary points.
Ranges are frequently used in editing for selecting and copying content.
p
<img src="insanity-wolf" alt="Little-endian BOM; decode as big-endian!">
<em>
In the node tree above, a
range can be used to represent the sequence
“syndata is awes”. Assuming p is assigned to the
p element, and
em to the em
element, this would be done as follows:
var range = new Range(),
firstText = p.childNodes[1],
secondText = em.firstChild
range.setStart(firstText, 9) // do not forget the leading space
range.setEnd(secondText, 4)
// range now stringifies to the aforementioned quote
Attributes such as src and alt in the
node tree above cannot be represented by a range. Ranges are only useful for
nodes.
{{Range}} objects, unlike {{StaticRange}} objects, are affected by mutations to the node tree. Therefore they are also known as live ranges. Such mutations will not invalidate them and will try to ensure that it still represents the same piece of content. Necessarily, a live range might itself be modified as part of the mutation to the node tree when, e.g., part of the content it represents is mutated.
See the insert and remove algorithms, the {{Node/normalize()}} method, and the replace data and split algorithms for details.
Updating live ranges in response to node tree mutations can be expensive. For every node tree change, all affected {{Range}} objects need to be updated. Even if the application is uninterested in some live ranges, it still has to pay the cost of keeping them up-to-date when a mutation occurs.
A {{StaticRange}} object is a lightweight range that does not update when the node tree mutates. It is therefore not subject to the same maintenance cost as live ranges.
A boundary point is a tuple consisting of a node (a node) and an offset (a non-negative integer).
A correct boundary point's offset will be between 0 and the boundary point's node's length, inclusive.
The position of a boundary point (nodeA, offsetA) relative to a boundary point (nodeB, offsetB) is before, equal, or after, as returned by these steps:
Assert: nodeA and nodeB have the same root.
If nodeA is following nodeB, then if the position of (nodeB, offsetB) relative to (nodeA, offsetA) is before, return after, and if it is after, return before.
If nodeA is an ancestor of nodeB:
Return before.
[Exposed=Window]
interface AbstractRange {
readonly attribute Node startContainer;
readonly attribute unsigned long startOffset;
readonly attribute Node endContainer;
readonly attribute unsigned long endOffset;
readonly attribute boolean collapsed;
};
Objects implementing the {{AbstractRange}} interface are known as ranges.
A range has two associated boundary points — a start and end.
For convenience, a range's start node is its start's node, its start offset is its start's offset, its end node is its end's node, and its end offset is its end's offset.
A range is collapsed if its start node is its end node and its start offset is its end offset.
node = range . startContainer
offset = range . startOffset
node = range . endContainer
offset = range . endOffset
collapsed = range . collapsed
The
startContainer
getter steps are to return this's start node.
The startOffset
getter steps are to return this's start offset.
The endOffset
getter steps are to return this's end offset.
dictionary StaticRangeInit {
required Node startContainer;
required unsigned long startOffset;
required Node endContainer;
required unsigned long endOffset;
};
[Exposed=Window]
interface StaticRange : AbstractRange {
constructor(StaticRangeInit init);
};
staticRange = new StaticRange(init)
Returns a new range object that does not update when the node tree mutates.
The
new StaticRange(init)
constructor steps are:
If init["{{StaticRangeInit/startContainer}}"] or init["{{StaticRangeInit/endContainer}}"] is a {{DocumentType}} or {{Attr}} node, then throw an "{{InvalidNodeTypeError!!exception}}" {{DOMException}}.
Set this's start to (init["{{StaticRangeInit/startContainer}}"], init["{{StaticRangeInit/startOffset}}"]) and end to (init["{{StaticRangeInit/endContainer}}"], init["{{StaticRangeInit/endOffset}}"]).
A {{StaticRange}} is valid if all of the following are true:
Its start offset is between 0 and its start node's length, inclusive.
Its end offset is between 0 and its end node's length, inclusive.
[Exposed=Window]
interface Range : AbstractRange {
constructor();
readonly attribute Node commonAncestorContainer;
undefined setStart(Node node, unsigned long offset);
undefined setEnd(Node node, unsigned long offset);
undefined setStartBefore(Node node);
undefined setStartAfter(Node node);
undefined setEndBefore(Node node);
undefined setEndAfter(Node node);
undefined collapse(optional boolean toStart = false);
undefined selectNode(Node node);
undefined selectNodeContents(Node node);
const unsigned short START_TO_START = 0;
const unsigned short START_TO_END = 1;
const unsigned short END_TO_END = 2;
const unsigned short END_TO_START = 3;
short compareBoundaryPoints(unsigned short how, Range sourceRange);
[CEReactions] undefined deleteContents();
[CEReactions, NewObject] DocumentFragment extractContents();
[CEReactions, NewObject] DocumentFragment cloneContents();
[CEReactions] undefined insertNode(Node node);
[CEReactions] undefined surroundContents(Node newParent);
[NewObject] Range cloneRange();
undefined detach();
boolean isPointInRange(Node node, unsigned long offset);
short comparePoint(Node node, unsigned long offset);
boolean intersectsNode(Node node);
stringifier;
};
Objects implementing the {{Range}} interface are known as live ranges.
Algorithms that modify a tree (in particular the insert, remove, move, replace data, and split algorithms) modify live ranges associated with that tree.
The root of a live range is the root of its start node.
A node node is contained in a live range range if node's root is range's root, and (node, 0) is after range's start, and (node, node's length) is before range's end.
A node is partially contained in a live range if it's an inclusive ancestor of the live range's start node but not its end node, or vice versa.
Some facts to better understand these definitions:
The content that one would think of as being within the live range consists of all contained nodes, plus possibly some of the contents of the start node and end node if those are {{CharacterData}} nodes.
The nodes that are contained in a live range will generally not be contiguous, because the parent of a contained node will not always be contained.
However, the descendants of a contained node are contained, and if two siblings are contained, so are any siblings that lie between them.
The start node and end node of a live range are never contained within it.
The first contained node (if there are any) will always be after the start node, and the last contained node will always be equal to or before the end node's last descendant.
There exists a partially contained node if and only if the start node and end node are different.
The {{Range/commonAncestorContainer}} attribute value is neither contained nor partially contained.
If the start node is an ancestor of the end node, the common inclusive ancestor will be the start node. Exactly one of its children will be partially contained, and a child will be contained if and only if it precedes the partially contained child. If the end node is an ancestor of the start node, the opposite holds.
If the start node is not an inclusive ancestor of the end node, nor vice versa, the common inclusive ancestor will be distinct from both of them. Exactly two of its children will be partially contained, and a child will be contained if and only if it lies between those two.
The live range pre-remove steps given a node node, are:
Let parent be node's parent.
Assert: parent is non-null.
Let index be node's index.
For each live range whose start node is an inclusive descendant of node, set its start to (parent, index).
For each live range whose end node is an inclusive descendant of node, set its end to (parent, index).
For each live range whose start node is parent and start offset is greater than index, decrease its start offset by 1.
For each live range whose end node is parent and end offset is greater than index, decrease its end offset by 1.
range = new Range()
The new Range() constructor steps are
to set this's start and end to
(current global object's associated Document, 0).
To get the common ancestor of a live range range:
Let container be range's start node.
While container is not an inclusive ancestor of range's end node: set container to container's parent.
Return container.
The commonAncestorContainer getter steps are to
return the result of getting the common ancestor of this.
To set the start or end of a range to a boundary point (node, offset):
If node is a doctype, then throw an "{{InvalidNodeTypeError!!exception}}" {{DOMException}}.
If offset is greater than node's length, then throw an "{{IndexSizeError!!exception}}" {{DOMException}}.
Let boundaryPoint be the boundary point (node, offset).
The setStart(node, offset) method
steps are to set the start of this to boundary point
(node, offset).
The setEnd(node, offset) method
steps are to set the end of this to boundary point
(node, offset).
The setStartBefore(node) method steps are:
Let parent be node's parent.
If parent is null, then throw an "{{InvalidNodeTypeError!!exception}}" {{DOMException}}.
Set the start of this to boundary point (parent, node's index).
The setStartAfter(node) method steps are:
Let parent be node's parent.
If parent is null, then throw an "{{InvalidNodeTypeError!!exception}}" {{DOMException}}.
Set the start of this to boundary point (parent, node's index plus 1).
The setEndBefore(node) method steps are:
Let parent be node's parent.
If parent is null, then throw an "{{InvalidNodeTypeError!!exception}}" {{DOMException}}.
Set the end of this to boundary point (parent, node's index).
The setEndAfter(node) method steps are:
Let parent be node's parent.
If parent is null, then throw an "{{InvalidNodeTypeError!!exception}}" {{DOMException}}.
Set the end of this to boundary point (parent, node's index plus 1).
The collapse(toStart) method steps are to, if
toStart is true, set end to start; otherwise set
start to end.
To select a node node within a range range:
Let parent be node's parent.
If parent is null, then throw an "{{InvalidNodeTypeError!!exception}}" {{DOMException}}.
Let index be node's index.
Set range's start to boundary point (parent, index).
Set range's end to boundary point (parent, index plus 1).
The selectNodeContents(node) method steps
are:
If node is a doctype, then throw an "{{InvalidNodeTypeError!!exception}}" {{DOMException}}.
Let length be the length of node.
Set start to the boundary point (node, 0).
Set end to the boundary point (node, length).
The
compareBoundaryPoints(how, sourceRange)
method steps are:
If how is not one of
then throw a "{{NotSupportedError!!exception}}" {{DOMException}}.
If this's root is not sourceRange's root, then throw a "{{WrongDocumentError!!exception}}" {{DOMException}}.
Let thisPoint and sourcePoint be null.
Switch on how:
Set thisPoint to this's start and sourcePoint to sourceRange's start.
Set thisPoint to this's end and sourcePoint to sourceRange's start.
Set thisPoint to this's end and sourcePoint to sourceRange's end.
Set thisPoint to this's start and sourcePoint to sourceRange's end.
Switch on the position of thisPoint relative to sourcePoint:
The deleteContents() method steps are:
Let originalStartNode, originalStartOffset, originalEndNode, and originalEndOffset be this's start node, start offset, end node, and end offset, respectively.
If originalStartNode is originalEndNode and it is a {{CharacterData}} node:
Replace data of originalStartNode with originalStartOffset, originalEndOffset − originalStartOffset, and the empty string.
Return.
Let nodesToRemove be a list of all the nodes that are contained in this, in tree order, omitting any node whose parent is also contained in this.
Let newNode and newOffset be null.
If originalStartNode is an inclusive ancestor of originalEndNode, then set newNode to originalStartNode and newOffset to originalStartOffset.
Otherwise:
Let referenceNode be originalStartNode.
While referenceNode's parent is non-null and is not an inclusive ancestor of originalEndNode: set referenceNode to its parent.
Set newNode to referenceNode's parent and newOffset to referenceNode's index + 1.
If referenceNode's parent were null, it would be the root of this. And then it would be an inclusive ancestor of originalEndNode and we could not reach this point.
If originalStartNode is a {{CharacterData}} node, then replace data of originalStartNode with originalStartOffset, originalStartNode's length − originalStartOffset, and the empty string.
For each node of nodesToRemove, in tree order: remove node.
If originalEndNode is a {{CharacterData}} node, then replace data of originalEndNode with 0, originalEndOffset, and the empty string.
To extract a live range range:
Let fragment be the result of creating a document fragment given range's start node's node document.
If range is collapsed, then return fragment.
Let originalStartNode, originalStartOffset, originalEndNode, and originalEndOffset be range's start node, start offset, end node, and end offset, respectively.
If originalStartNode is originalEndNode and it is a {{CharacterData}} node:
Let clone be a clone of originalStartNode.
Set clone's data to the result of substringing data of originalStartNode with originalStartOffset and originalEndOffset − originalStartOffset.
Append clone to fragment.
Replace data of originalStartNode with originalStartOffset, originalEndOffset − originalStartOffset, and the empty string.
Let commonAncestor be the result of getting the common ancestor of range.
Let firstPartiallyContainedChild be null.
Let lastPartiallyContainedChild be null.
If originalEndNode is not an inclusive ancestor of originalStartNode, then set lastPartiallyContainedChild to the last child of commonAncestor that is partially contained in range.
These variable assignments do actually always make sense. For instance, if originalStartNode is not an inclusive ancestor of originalEndNode, originalStartNode is itself partially contained in range, and so are all its ancestors up until a child of commonAncestor. commonAncestor cannot be originalStartNode, because it has to be an inclusive ancestor of originalEndNode. The other case is similar. Also, notice that the two children will never be equal if both are defined.
Let containedChildren be a list of all children of commonAncestor that are contained in range, in tree order.
If any member of containedChildren is a doctype, then throw a "{{HierarchyRequestError!!exception}}" {{DOMException}}.
We do not have to worry about the first or last partially contained node, because a doctype can never be partially contained. It cannot be a boundary point of a range, and it cannot be the ancestor of anything.
Let newNode and newOffset be null.
If originalStartNode is an inclusive ancestor of originalEndNode, then set newNode to originalStartNode and newOffset to originalStartOffset.
Otherwise:
Let referenceNode be originalStartNode.
While referenceNode's parent is non-null and is not an inclusive ancestor of originalEndNode: set referenceNode to its parent.
Set newNode to the parent of referenceNode, and newOffset to referenceNode's index + 1.
If referenceNode's parent is null, it would be the root of range. And then it would be an inclusive ancestor of originalEndNode and we could not reach this point.
If firstPartiallyContainedChild is a {{CharacterData}} node:
In this case, firstPartiallyContainedChild is originalStartNode.
Let clone be a clone of originalStartNode.
Set the data of clone to the result of substringing data of originalStartNode with originalStartOffset and originalStartNode's length − originalStartOffset.
Append clone to fragment.
Replace data of originalStartNode with originalStartOffset, originalStartNode's length − originalStartOffset, and the empty string.
Otherwise, if firstPartiallyContainedChild is non-null:
Let clone be a clone of firstPartiallyContainedChild.
Append clone to fragment.
Let subrange be a new live range whose start is (originalStartNode, originalStartOffset) and whose end is (firstPartiallyContainedChild, firstPartiallyContainedChild's length).
Let subfragment be the result of extracting subrange.
For each contained child of containedChildren: append contained child to fragment.
If lastPartiallyContainedChild is a {{CharacterData}} node:
In this case, lastPartiallyContainedChild is originalEndNode.
Let clone be a clone of originalEndNode.
Set clone's data to the result of substringing data of originalEndNode with 0 and originalEndOffset.
Append clone to fragment.
Replace data of originalEndNode with 0, originalEndOffset, and the empty string.
Otherwise, if lastPartiallyContainedChild is non-null:
Let clone be a clone of lastPartiallyContainedChild.
Append clone to fragment.
Let subrange be a new live range whose start is (lastPartiallyContainedChild, 0) and whose end is (originalEndNode, originalEndOffset).
Let subfragment be the result of extracting subrange.
Append subfragment to clone.
Return fragment.
The extractContents() method steps are to return the
result of extracting this.
To clone the contents of a live range range:
Let fragment be the result of creating a document fragment given range's start node's node document.
If range is collapsed, then return fragment.
Let originalStartNode, originalStartOffset, originalEndNode, and originalEndOffset be range's start node, start offset, end node, and end offset, respectively.
If originalStartNode is originalEndNode and it is a {{CharacterData}} node:
Let clone be a clone of originalStartNode.
Set clone's data to the result of substringing data of originalStartNode with originalStartOffset and originalEndOffset − originalStartOffset.
Append clone to fragment.
Return fragment.
Let commonAncestor be the result of getting the common ancestor of range.
Let firstPartiallyContainedChild be null.
If originalStartNode is not an inclusive ancestor of originalEndNode, then set firstPartiallyContainedChild to the first child of commonAncestor that is partially contained in range.
Let lastPartiallyContainedChild be null.
If originalEndNode is not an inclusive ancestor of originalStartNode, then set lastPartiallyContainedChild to the last child of commonAncestor that is partially contained in range.
These variable assignments do actually always make sense. For instance, if originalStartNode is not an inclusive ancestor of originalEndNode, originalStartNode is itself partially contained in range, and so are all its ancestors up until a child of commonAncestor. commonAncestor cannot be originalStartNode, because it has to be an inclusive ancestor of originalEndNode. The other case is similar. Also, notice that the two children will never be equal if both are defined.
Let containedChildren be a list of all children of commonAncestor that are contained in range, in tree order.
If any member of containedChildren is a doctype, then throw a "{{HierarchyRequestError!!exception}}" {{DOMException}}.
We do not have to worry about the first or last partially contained node, because a doctype can never be partially contained. It cannot be a boundary point of a range, and it cannot be the ancestor of anything.
If firstPartiallyContainedChild is a {{CharacterData}} node:
In this case, firstPartiallyContainedChild is originalStartNode.
Let clone be a clone of originalStartNode.
Set the data of clone to the result of substringing data of originalStartNode with originalStartOffset and originalStartNode's length − originalStartOffset.
Append clone to fragment.
Otherwise, if firstPartiallyContainedChild is non-null:
Let clone be a clone of firstPartiallyContainedChild.
Append clone to fragment.
Let subrange be a new live range whose start is (originalStartNode, originalStartOffset) and whose end is (firstPartiallyContainedChild, firstPartiallyContainedChild's length).
Let subfragment be the result of cloning the contents of subrange.
Append subfragment to clone.
For each contained child of containedChildren:
If lastPartiallyContainedChild is a {{CharacterData}} node:
In this case, lastPartiallyContainedChild is originalEndNode.
Let clone be a clone of originalEndNode.
Set clone's data to the result of substringing data of originalEndNode with 0 and originalEndOffset.
Append clone to fragment.
Otherwise, if lastPartiallyContainedChild is non-null:
Let clone be a clone of lastPartiallyContainedChild.
Append clone to fragment.
Let subrange be a new live range whose start is (lastPartiallyContainedChild, 0) and whose end is (originalEndNode, originalEndOffset).
Let subfragment be the result of cloning the contents of subrange.
Append subfragment to clone.
Return fragment.
The cloneContents() method steps are to return the
result of cloning the contents of this.
To insert a node node into a live range range:
If range's start node is a {{ProcessingInstruction}} or {{Comment}} node, is a {{Text}} node whose parent is null, or is node, then throw a "{{HierarchyRequestError!!exception}}" {{DOMException}}.
Let referenceNode be null.
If range's start node is a {{Text}} node, then set referenceNode to that {{Text}} node.
Otherwise, set referenceNode to the child of range's start node whose index is range's start offset if there is such a child; otherwise null.
Let parent be range's start node if referenceNode is null; otherwise referenceNode's parent.
Ensure pre-insert validity given node, parent, referenceNode, and « ».
If range's start node is a {{Text}} node, then set referenceNode to the result of splitting it with offset range's start offset.
If node is referenceNode, then set referenceNode to its next sibling.
Let newOffset be parent's length if referenceNode is null; otherwise referenceNode's index.
Increase newOffset by node's length if node is a {{DocumentFragment}} node; otherwise 1.
Pre-insert node into parent before referenceNode.
If range is collapsed, then set range's end to (parent, newOffset).
The surroundContents(newParent) method steps
are:
If a non-{{Text}} node is partially contained in this, then throw an "{{InvalidStateError!!exception}}" {{DOMException}}.
If newParent is a {{Document}}, {{DocumentType}}, or {{DocumentFragment}} node, then throw an "{{InvalidNodeTypeError!!exception}}" {{DOMException}}.
For historical reasons {{CharacterData}} nodes are not checked here and end up throwing later on as a side effect.
Let fragment be the result of extracting this.
If newParent has children, then replace all with null within newParent.
Append fragment to newParent.
The cloneRange() method steps are to return a new
live range with the same start and end as this.
The detach() method steps are to do nothing.
Its functionality (disabling a {{Range}} object) was removed, but the method itself
is preserved for compatibility.
The isPointInRange(node, offset)
method steps are:
The comparePoint(node, offset)
method steps are:
If node's root is not this's root, then throw a "{{WrongDocumentError!!exception}}" {{DOMException}}.
If node is a doctype, then throw an "{{InvalidNodeTypeError!!exception}}" {{DOMException}}.
If offset is greater than node's length, then throw an "{{IndexSizeError!!exception}}" {{DOMException}}.
Return 0.
The intersectsNode(node) method steps are:
The stringification behavior must run these steps:
Let string be the empty string.
If this's start node is this's end node and it is a {{Text}} node, then return the substring of that {{Text}} node's data beginning at this's start offset and ending at this's end offset.
If this's start node is a {{Text}} node, then append the substring of that node's data from this's start offset until the end to string.
Append the concatenation of the data of all {{Text}} nodes that are contained in this, in tree order, to string.
If this's end node is a {{Text}} node, then append the substring of that node's data from its start until this's end offset to string.
Return string.
The {{createContextualFragment()}}, {{Range/getClientRects()}}, and {{Range/getBoundingClientRect()}} methods are defined in other specifications. [[DOM-Parsing]] [[CSSOM-VIEW]]
{{NodeIterator}} and {{TreeWalker}} objects can be used to filter and traverse node trees.
Each {{NodeIterator}} and {{TreeWalker}} object has an associated boolean is active to avoid recursive invocations. It is initially false.
Each {{NodeIterator}} and {{TreeWalker}} object also has an associated root (a node), a whatToShow (a bitmask), and a filter (a callback).
To filter a node node within a {{NodeIterator}} or {{TreeWalker}} object traverser:
If traverser's is active is true, then throw an "{{InvalidStateError!!exception}}" {{DOMException}}.
Let n be node's {{Node/nodeType}} attribute value − 1.
If the nth bit (where 0 is the least significant bit) of traverser's whatToShow is not set, then return {{NodeFilter/FILTER_SKIP}}.
If traverser's filter is null, then return {{NodeFilter/FILTER_ACCEPT}}.
Set traverser's is active to true.
Let result be the return value of call a user object's operation with
traverser's filter, "acceptNode", and
« node ». If this throws an exception, then set traverser's
is active to false and rethrow the exception.
Set traverser's is active to false.
Return result.
[Exposed=Window]
interface NodeIterator {
[SameObject] readonly attribute Node root;
readonly attribute Node referenceNode;
readonly attribute boolean pointerBeforeReferenceNode;
readonly attribute unsigned long whatToShow;
readonly attribute NodeFilter? filter;
Node? nextNode();
Node? previousNode();
undefined detach();
};
{{NodeIterator}} objects can be created using the {{createNodeIterator()}} method on {{Document}} objects.
Each {{NodeIterator}} object has an associated iterator collection, which is a collection rooted at the {{NodeIterator}} object's root, whose filter matches any node.
A node pointer is a tuple consisting of a node (a node) and a pointer before (a boolean).
Each {{NodeIterator}} object also has an associated reference (a node pointer) and candidate reference (null or a node pointer, and initially null).
As mentioned earlier, {{NodeIterator}} objects have an associated is active, root, whatToShow, and filter as well.
The NodeIterator pre-remove steps
given a {{NodeIterator}} object nodeIterator and node
toBeRemovedNode, are:
Set nodeIterator's reference to the result of adjusting a node pointer given nodeIterator's reference, nodeIterator, and toBeRemovedNode.
If nodeIterator's candidate reference is non-null, then set nodeIterator's candidate reference to the result of adjusting a node pointer given nodeIterator's candidate reference, nodeIterator, and toBeRemovedNode.
To adjust a node pointer given a node pointer nodePointer, a {{NodeIterator}} object nodeIterator, and a node toBeRemovedNode, perform the following steps. They return a node pointer.
If toBeRemovedNode is not an inclusive ancestor of nodePointer's node, or toBeRemovedNode is an inclusive ancestor of nodeIterator's root, then return nodePointer.
If nodePointer's pointer before is true:
Let next be toBeRemovedNode's first following node that is an inclusive descendant of nodeIterator's root and is not an inclusive descendant of toBeRemovedNode, if there is such a node; otherwise null.
If next is non-null, then return (next, true).
Let newNode be toBeRemovedNode's parent, if toBeRemovedNode's previous sibling is null; otherwise the inclusive descendant of toBeRemovedNode's previous sibling that appears last in tree order.
Return (newNode, false).
The pointerBeforeReferenceNode getter steps
are to return this's reference's
pointer before.
The whatToShow getter steps are to return
this's whatToShow.
To traverse, given a
{{NodeIterator}} object iterator and "next" or "previous"
type:
Set iterator's candidate reference to iterator's reference.
Let result be null.
While true:
If type is "next":
If iterator's candidate reference's pointer before is false:
Let following be the first node following iterator's candidate reference's node in iterator's iterator collection. If there is no such node, then break.
Set iterator's candidate reference to (following, false).
Otherwise, set iterator's candidate reference to (iterator's candidate reference's node, false).
Otherwise:
If iterator's candidate reference's pointer before is true:
Let preceding be the first node preceding iterator's candidate reference's node in iterator's iterator collection. If there is no such node, then break.
Set iterator's candidate reference to (preceding, true).
Otherwise, set iterator's candidate reference to (iterator's candidate reference's node, true).
Let node be iterator's candidate reference's node.
Let filterResult be the result of filtering node within iterator. If this throws an exception, then set iterator's candidate reference to null and rethrow that exception.
If filterResult is {{NodeFilter/FILTER_ACCEPT}}:
Set iterator's reference to iterator's candidate reference.
Set result to node.
Set iterator's candidate reference to null.
Return result.
The nextNode() method steps are to return the
result of traversing with this and "next".
The previousNode() method steps are to return the
result of traversing with this and "previous".
The detach() method steps are to do nothing.
Its functionality (disabling a {{NodeIterator}} object) was removed, but the method
itself is preserved for compatibility.
[Exposed=Window]
interface TreeWalker {
[SameObject] readonly attribute Node root;
readonly attribute unsigned long whatToShow;
readonly attribute NodeFilter? filter;
attribute Node currentNode;
Node? parentNode();
Node? firstChild();
Node? lastChild();
Node? previousSibling();
Node? nextSibling();
Node? previousNode();
Node? nextNode();
};
{{TreeWalker}} objects can be created using the {{createTreeWalker()}} method on {{Document}} objects.
Each {{TreeWalker}} object has an associated current (a node).
As mentioned earlier {{TreeWalker}} objects have an associated root, whatToShow, and filter as well.
The whatToShow getter steps are to return
this's whatToShow.
The parentNode() method steps are:
To traverse children, given a
{{TreeWalker}} object walker and "first" or "last"
type:
Let node be walker's current.
Set node to node's first child if type is
"first"; otherwise to node's last child.
While node is non-null:
Let result be the result of filtering node within walker.
If result is {{NodeFilter/FILTER_ACCEPT}}, then set walker's current to node and return node.
If result is {{NodeFilter/FILTER_SKIP}}:
Let child be node's first child if type
is "first"; otherwise node's last child.
If child is non-null, then set node to child and continue.
While node is non-null:
Let sibling be node's next sibling if
type is "first"; otherwise node's
previous sibling.
If sibling is non-null, then set node to sibling and break.
Let parent be node's parent.
If parent is null, walker's root, or walker's current, then return null.
Set node to parent.
Return null.
The firstChild() method steps are to
traverse children with this and "first".
The lastChild() method steps are to
traverse children with this and "last".
To traverse siblings, given a {{TreeWalker}}
object walker and "next" or "previous" type:
Let node be walker's current.
If node is root, then return null.
While true:
Let sibling be node's next sibling if
type is "next"; otherwise node's
previous sibling.
While sibling is non-null:
Set node to sibling.
Let result be the result of filtering node within walker.
If result is {{NodeFilter/FILTER_ACCEPT}}, then set walker's current to node and return node.
Set sibling to node's first child if
type is "next"; otherwise to node's
last child.
If result is {{NodeFilter/FILTER_REJECT}} or sibling is null, then
set sibling to node's next sibling if type is
"next"; otherwise to node's previous sibling.
Set node to node's parent.
If node is null or walker's root, then return null.
If the return value of filtering node within walker is {{NodeFilter/FILTER_ACCEPT}}, then return null.
The nextSibling() method steps are to
traverse siblings with this and "next".
The previousSibling() method steps are to
traverse siblings with this and "previous".
The previousNode() method steps are:
While node is not this's root:
Let sibling be node's previous sibling.
While sibling is non-null:
Set node to sibling.
While result is not {{NodeFilter/FILTER_REJECT}} and node has a child:
Set node to node's last child.
If result is {{NodeFilter/FILTER_ACCEPT}}, then set this's current to node and return node.
Set sibling to node's previous sibling.
If node is this's root or node's parent is null, then return null.
Set node to node's parent.
If the return value of filtering node within this is {{NodeFilter/FILTER_ACCEPT}}, then set this's current to node and return node.
Return null.
The nextNode() method steps are:
Let result be {{NodeFilter/FILTER_ACCEPT}}.
While true:
While result is not {{NodeFilter/FILTER_REJECT}} and node has a child:
Set node to its first child.
If result is {{NodeFilter/FILTER_ACCEPT}}, then set this's current to node and return node.
Let sibling be null.
Let temporary be node.
While temporary is non-null:
Set sibling to temporary's next sibling.
If sibling is non-null, then break.
Set temporary to temporary's parent.
If sibling is null, then return null.
Set node to sibling.
If result is {{NodeFilter/FILTER_ACCEPT}}, then set this's current to node and return node.
[Exposed=Window]
callback interface NodeFilter {
// Constants for acceptNode()
const unsigned short FILTER_ACCEPT = 1;
const unsigned short FILTER_REJECT = 2;
const unsigned short FILTER_SKIP = 3;
// Constants for whatToShow
const unsigned long SHOW_ALL = 0xFFFFFFFF;
const unsigned long SHOW_ELEMENT = 0x1;
const unsigned long SHOW_ATTRIBUTE = 0x2;
const unsigned long SHOW_TEXT = 0x4;
const unsigned long SHOW_CDATA_SECTION = 0x8;
const unsigned long SHOW_ENTITY_REFERENCE = 0x10; // legacy
const unsigned long SHOW_ENTITY = 0x20; // legacy
const unsigned long SHOW_PROCESSING_INSTRUCTION = 0x40;
const unsigned long SHOW_COMMENT = 0x80;
const unsigned long SHOW_DOCUMENT = 0x100;
const unsigned long SHOW_DOCUMENT_TYPE = 0x200;
const unsigned long SHOW_DOCUMENT_FRAGMENT = 0x400;
const unsigned long SHOW_NOTATION = 0x800; // legacy
unsigned short acceptNode(Node node);
};
{{NodeFilter}} objects can be used as filter for {{NodeIterator}} and {{TreeWalker}} objects and also provide constants for their whatToShow bitmask. A {{NodeFilter}} object is typically implemented as a JavaScript function.
These constants can be used as filter return value:
FILTER_ACCEPT (1);
FILTER_REJECT (2);
FILTER_SKIP (3).
These constants can be used for whatToShow:
SHOW_ALL (4294967295, FFFFFFFF in hexadecimal);
SHOW_ELEMENT (1);
SHOW_ATTRIBUTE (2);
SHOW_TEXT (4);
SHOW_CDATA_SECTION (8);
SHOW_PROCESSING_INSTRUCTION (64, 40 in hexadecimal);
SHOW_COMMENT (128, 80 in hexadecimal);
SHOW_DOCUMENT (256, 100 in hexadecimal);
SHOW_DOCUMENT_TYPE (512, 200 in hexadecimal);
SHOW_DOCUMENT_FRAGMENT (1024, 400 in hexadecimal).
Yes, the name {{DOMTokenList}} is an unfortunate legacy mishap.
[Exposed=Window]
interface DOMTokenList {
readonly attribute unsigned long length;
getter DOMString? item(unsigned long index);
boolean contains(DOMString token);
[CEReactions] undefined add(DOMString... tokens);
[CEReactions] undefined remove(DOMString... tokens);
[CEReactions] boolean toggle(DOMString token, optional boolean force);
[CEReactions] boolean replace(DOMString token, DOMString newToken);
boolean supports(DOMString token);
[CEReactions] stringifier attribute DOMString value;
iterable<DOMString>;
};
A {{DOMTokenList}} object has an associated token set (a set), which is initially empty.
A {{DOMTokenList}} object also has an associated element (an element) and an attribute name (an attribute's local name). Specifications may define supported tokens for a {{DOMTokenList}}'s element and attribute name.
A {{DOMTokenList}} object set's validation steps for a given token are:
If set's element and
attribute name does not define supported tokens, then
throw a TypeError.
Let lowercaseToken be token, in ASCII lowercase.
If lowercaseToken is present in the supported tokens of set's element and attribute name, then return true.
Return false.
A {{DOMTokenList}} object set's update steps are:
If get an attribute by namespace and local name given null, set's attribute name, and set's element returns null and set's token set is empty, then return.
Set an attribute value given set's element, set's attribute name, and the result of running the ordered set serializer for set's token set.
A {{DOMTokenList}} object set's serialize steps are to return the result of running get an attribute value given set's element and set's attribute name.
A {{DOMTokenList}} object set has these attribute change steps for set's element:
If localName is set's attribute name, namespace is null, and value is null, then empty token set.
Otherwise, if localName is set's attribute name and namespace is null, then set set's token set to value, parsed.
When a {{DOMTokenList}} object set is created:
Let element be set's element.
Let attributeName be set's attribute name.
Let value be the result of getting an attribute value given element and attributeName.
Run the attribute change steps for element, attributeName, value, value, and null.
tokenlist . {{DOMTokenList/length}}
Returns the number of tokens.
tokenlist . {{DOMTokenList/item(index)}}
tokenlist[index]
Returns the token with index index.
tokenlist . {{DOMTokenList/contains(token)}}
Returns true if token is present; otherwise false.
tokenlist . add(tokens…)
Adds all arguments passed, except those already present.
Throws a "{{SyntaxError!!exception}}" {{DOMException}} if one of the arguments is the empty string.
Throws an "{{InvalidCharacterError!!exception}}" {{DOMException}} if one of the arguments contains any ASCII whitespace.
tokenlist . remove(tokens…)
Removes arguments passed, if they are present.
Throws a "{{SyntaxError!!exception}}" {{DOMException}} if one of the arguments is the empty string.
Throws an "{{InvalidCharacterError!!exception}}" {{DOMException}} if one of the arguments contains any ASCII whitespace.
tokenlist . toggle(token [, force])
If force is not given, "toggles" token, removing it if it's present and adding it if it's not present. If force is true, adds token (same as {{add()}}). If force is false, removes token (same as {{DOMTokenList/remove()}}).
Returns true if token is now present; otherwise false.
Throws a "{{SyntaxError!!exception}}" {{DOMException}} if token is empty.
Throws an "{{InvalidCharacterError!!exception}}" {{DOMException}} if token contains any spaces.
tokenlist . replace(token, newToken)
Replaces token with newToken.
Returns true if token was replaced with newToken; otherwise false.
Throws a "{{SyntaxError!!exception}}" {{DOMException}} if one of the arguments is the empty string.
Throws an "{{InvalidCharacterError!!exception}}" {{DOMException}} if one of the arguments contains any ASCII whitespace.
tokenlist . supports(token)
Returns true if token is in the associated attribute's supported tokens. Returns false otherwise.
Throws a TypeError if the associated attribute has no supported tokens defined.
tokenlist . {{DOMTokenList/value}}
Returns the associated set as string.
Can be set, to change the associated attribute.
The object's supported property indices are the numbers in the range zero to object's token set's size − 1, unless token set is empty, in which case there are no supported property indices.
The item(index) method steps are:
The contains(token) method steps are
to return true if this's token set[token] exists; otherwise
false.
The
add(tokens…)
method steps are:
For each token of tokens:
If token is the empty string, then throw a "{{SyntaxError!!exception}}" {{DOMException}}.
If token contains any ASCII whitespace, then throw an "{{InvalidCharacterError!!exception}}" {{DOMException}}.
Run the update steps.
The
remove(tokens…)
method steps are:
For each token of tokens:
If token is the empty string, then throw a "{{SyntaxError!!exception}}" {{DOMException}}.
If token contains any ASCII whitespace, then throw an "{{InvalidCharacterError!!exception}}" {{DOMException}}.
For each token of tokens: remove token from this's token set.
Run the update steps.
The toggle(token, force)
method steps are:
If token is the empty string, then throw a "{{SyntaxError!!exception}}" {{DOMException}}.
If token contains any ASCII whitespace, then throw an "{{InvalidCharacterError!!exception}}" {{DOMException}}.
If this's token set[token] exists:
If force is either not given or is false, then remove token from this's token set, run the update steps and return false.
Return true.
Otherwise, if force not given or is true, append token to this's token set, run the update steps, and return true.
Return false.
The update steps are not always run for {{DOMTokenList/toggle()}} for web compatibility.
The
replace(token, newToken)
method steps are:
If either token or newToken is the empty string, then throw a "{{SyntaxError!!exception}}" {{DOMException}}.
If either token or newToken contains any ASCII whitespace, then throw an "{{InvalidCharacterError!!exception}}" {{DOMException}}.
If this's token set does not contain token, then return false.
Run the update steps.
Return true.
The update steps are not always run for {{DOMTokenList/replace()}} for web compatibility.
The
supports(token)
method steps are:
Let result be the return value of validation steps called with token.
Return result.
The value getter steps are to return the
result of running this's serialize steps.
The value setter steps are to
set an attribute value for this's element using this's
attribute name and the given value.
DOM Level 3 XPath defined an API for evaluating XPath 1.0 expressions. These APIs are widely implemented, but have not been maintained. The interface definitions are maintained here so that they can be updated when Web IDL changes. Complete definitions of these APIs remain necessary and such work is tracked and can be contributed to in whatwg/dom#67. [[DOM-Level-3-XPath]] [[XPath]] [[WEBIDL]]
[Exposed=Window]
interface XPathResult {
const unsigned short ANY_TYPE = 0;
const unsigned short NUMBER_TYPE = 1;
const unsigned short STRING_TYPE = 2;
const unsigned short BOOLEAN_TYPE = 3;
const unsigned short UNORDERED_NODE_ITERATOR_TYPE = 4;
const unsigned short ORDERED_NODE_ITERATOR_TYPE = 5;
const unsigned short UNORDERED_NODE_SNAPSHOT_TYPE = 6;
const unsigned short ORDERED_NODE_SNAPSHOT_TYPE = 7;
const unsigned short ANY_UNORDERED_NODE_TYPE = 8;
const unsigned short FIRST_ORDERED_NODE_TYPE = 9;
readonly attribute unsigned short resultType;
readonly attribute unrestricted double numberValue;
readonly attribute DOMString stringValue;
readonly attribute boolean booleanValue;
readonly attribute Node? singleNodeValue;
readonly attribute boolean invalidIteratorState;
readonly attribute unsigned long snapshotLength;
Node? iterateNext();
Node? snapshotItem(unsigned long index);
};
[Exposed=Window]
interface XPathExpression {
// XPathResult.ANY_TYPE = 0
XPathResult evaluate(Node contextNode, optional unsigned short type = 0, optional XPathResult? result = null);
};
callback interface XPathNSResolver {
DOMString? lookupNamespaceURI(DOMString? prefix);
};
interface mixin XPathEvaluatorBase {
[NewObject] XPathExpression createExpression(DOMString expression, optional XPathNSResolver? resolver = null);
Node createNSResolver(Node nodeResolver); // legacy
// XPathResult.ANY_TYPE = 0
XPathResult evaluate(DOMString expression, Node contextNode, optional XPathNSResolver? resolver = null, optional unsigned short type = 0, optional XPathResult? result = null);
};
Document includes XPathEvaluatorBase;
The
createNSResolver(nodeResolver)
method steps are to return nodeResolver.
This method exists only for historical reasons.
[Exposed=Window]
interface XPathEvaluator {
constructor();
};
XPathEvaluator includes XPathEvaluatorBase;
For historical reasons you can both construct {{XPathEvaluator}} and access the same methods on {{Document}}.
Avoid using client-side XSLT in browsers. The browser implementations of XSLT are highly susceptible to memory safety vulnerabilities, and the web platform has evolved toward JavaScript as the safe replacement. For these reasons, this feature is in the process of being removed from the web platform. (This is a long process that takes many years.)
XSL Transformations (XSLT) is a language for transforming XML documents into other XML documents. The APIs defined in this section have been widely implemented, and are maintained here so that they can be updated when Web IDL changes. Complete definitions of these APIs remain necessary and such work is tracked and can be contributed to in whatwg/dom#181. [[XSLT]]
[Exposed=Window]
interface XSLTProcessor {
constructor();
undefined importStylesheet(Node style);
[CEReactions] DocumentFragment transformToFragment(Node source, Document output);
[CEReactions] Document transformToDocument(Node source);
undefined setParameter([LegacyNullToEmptyString] DOMString namespaceURI, DOMString localName, any value);
any getParameter([LegacyNullToEmptyString] DOMString namespaceURI, DOMString localName);
undefined removeParameter([LegacyNullToEmptyString] DOMString namespaceURI, DOMString localName);
undefined clearParameters();
undefined reset();
};
There are no known security or privacy considerations for this standard.
This standard used to contain several interfaces and interface members that have been removed.
These interfaces have been removed:
DOMConfiguration
DOMError
DOMErrorHandler
DOMImplementationList
DOMImplementationSource
DOMLocator
DOMObject
DOMUserData
Entity
EntityReference
MutationEvent
MutationNameEvent
NameList
Notation
RangeException
TypeInfo
UserDataHandler
And these interface members have been removed:
schemaTypeInfo
isId
createEntityReference()
xmlEncoding
xmlStandalone
xmlVersion
strictErrorChecking
domConfig
normalizeDocument()
renameNode()
entities
notations
internalSubset
getFeature()
schemaTypeInfo
setIdAttribute()
setIdAttributeNS()
setIdAttributeNode()
isSupported
getFeature()
getUserData()
setUserData()
isElementContentWhitespace
replaceWholeText()
There have been a lot of people that have helped make DOM more interoperable over the years and thereby furthered the goals of this standard. Likewise many people have helped making this standard what it is today.
With that, many thanks to Adam Klein, Adrian Bateman, Ahmid snuggs, Alex Komoroske, Alex Russell, Alexey Shvayka, Andreas Kling, Andreu Botella, Anthony Ramine, Arkadiusz Michalski, Armen Michaeli, Arnaud Le Hors, Arun Ranganathan, Benjamin Gruenbaum, Björn Höhrmann, Boris Zbarsky, Brandon Payton, Brandon Slade, Brandon Wallace, Brian Kardell, C. Scott Ananian, Cameron McCormack, Chris Dumez, Chris Paris, Chris Rebert, Cyrille Tuzi, Dan Burzo, Daniel Clark, Daniel Glazman, Darien Maillet Valentine, Darin Fisher, David Baron, David Bruant, David Flanagan, David Håsäther, David Hyatt, Deepak Sherveghar, Dethe Elza, Dimitri Glazkov, Domenic Denicola, Dominic Cooney, Dominique Hazaël-Massieux, Don Jordan, Doug Schepers, Edgar Chen, Elisée Maurer, Elliott Sprehn, Emilio Cobos Álvarez, Eric Bidelman, Erik Arvidsson, Evgeny Kapun, François Daoust, François Remy, Gary Kacmarcik, Gavin Nicol, Giorgio Liscio, Glen Huang, Glenn Adams, Glenn Maynard, Hajime Morrita, Harald Alvestrand, Hayato Ito, Henri Sivonen, Hongchan Choi, Hunan Rostomyan, Ian Hickson, Igor Bukanov, Jacob Rossi, Jake Archibald, Jake Verbaten, James Graham, James Greene, James M Snell, James Robinson, Jayson Chen, Jeffrey Yasskin, Jens Lindström, Jeremy Davis, Jesse McCarthy, Jinho Bang, João Eiras, Joe Kesselman, John Atkins, John Dai, Jonas Sicking, Jonathan Kingston, Jonathan Robie, Joris van der Wel, Joshua Bell, J. S. Choi, Jungkee Song, Justin Summerlin, Kagami Sascha Rosylight, 呂康豪 (Kang-Hao Lu), 田村健人 (Kent TAMURA), Kevin J. Sung, Kevin Sweeney, Kirill Topolyan, Koji Ishii, Lachlan Hunt, Lauren Wood, Luca Casonato, Luke Zielinski, Magne Andersson, Majid Valipour, Malte Ubl, Manish Goregaokar, Manish Tripathi, Marcos Caceres, Mark Miller, Martijn van der Ven, Mason Freed, Mats Palmgren, Mounir Lamouri, Michael Stramel, Michael™ Smith, Mike Champion, Mike Taylor, Mike West, Nicolás Peña Moreno, Nidhi Jaju, Ojan Vafai, Oliver Nightingale, Olli Pettay, Ondřej Žára, Peter Sharpe, Philip Jägenstedt, Philippe Le Hégaret, Piers Wombwell, Pierre-Marie Dartus, prosody—Gab Vereable Context(, Rafael Weinstein, Rakina Zata Amni, Richard Bradshaw, Rick Byers, Rick Waldron, Robbert Broersma, Robin Berjon, Roland Steiner, Rune F. Halvorsen, Russell Bicknell, Ruud Steltenpool, Ryosuke Niwa, Sam Dutton, Sam Sneddon, Samuel Giles, Sanket Joshi, Scott Haseley, Sebastian Mayr, Seo Sanghyeon, Sergey G. Grekhov, Shiki Okasaka, Shinya Kawanaka, Simon Pieters, Simon Wülker, Stef Busking, Steve Byrne, Steven Obiajulu, Stig Halvorsen, Tab Atkins, Takashi Sakamoto, Takayoshi Kochi, Theresa O'Connor, Theodore Dubois, timeless, Timo Tijhof, Tobie Langel, Tom Pixley, Travis Leithead, Trevor Rowbotham, triple-underscore, Tristan Fraipont, Veli Şenol, Vidur Apparao, Warren He, Xidorn Quan, Yash Handa, Yehuda Katz, Yoav Weiss, Yoichi Osato, Yoshinori Sano, Yu Han, Yusuke Abe, and Zack Weinberg for being awesome!
This standard is written by Anne van Kesteren (Apple, annevk@annevk.nl) with substantial contributions from Aryeh Gregor (ayg@aryeh.name) and Ms2ger (ms2ger@gmail.com).
Part of the revision history of the integration points related to custom elements can be found in the w3c/webcomponents repository, which is available under the W3C Software and Document License.