1. Infrastructure
This specification depends on the Infra Standard. [INFRA]
Some of the terms used in this specification are defined in Encoding, Selectors, Web IDL, XML, and Namespaces in XML. [ENCODING] [SELECTORS4] [WEBIDL] [XML] [XML-NAMES]
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.
1.1. Trees
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.
1.2. Ordered sets
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.
- Return tokens.
The ordered set serializer takes a set and returns the concatenation of set using U+0020 SPACE.
1.3. Selectors
To scope-match a selectors string selectors against a node, run these steps:
-
Let s be the result of parse a selector selectors. [SELECTORS4]
-
If s is failure, then throw a "
SyntaxError
"DOMException
. -
Return the result of match a selector against a tree with s and node’s root using scoping root node. [SELECTORS4].
Support for namespaces within selectors is not planned and will not be added.
1.4. Name validation
A string is a valid namespace prefix if its 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 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 length is 0, then return false.
-
If name’s 0th code point is an ASCII alpha, then:
-
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 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 (:):
-
Let splitResult be the result of running strictly split given qualifiedName and U+003A (:).
-
Set prefix to splitResult[0].
-
Set localName to splitResult[1].
-
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
"DOMException
. -
If prefix is "
xml
" and namespace is not the XML namespace, then throw a "NamespaceError
"DOMException
. -
If either qualifiedName or prefix is "
xmlns
" and namespace is not the XMLNS namespace, then throw a "NamespaceError
"DOMException
. -
If namespace is the XMLNS namespace and neither qualifiedName nor prefix is "
xmlns
", then throw a "NamespaceError
"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.
2. Events
2.1. Introduction to "DOM Events"
Throughout the web platform events are dispatched to objects to signal an
occurrence, such as network activity or user interaction. These objects implement the
EventTarget
interface and can therefore add event listeners to observe
events by calling addEventListener()
:
obj. addEventListener( "load" , imgFetched) function imgFetched( ev) { // great success …}
Event listeners can be removed
by utilizing the
removeEventListener()
method, passing the same arguments.
Alternatively, event listeners can be removed by passing an AbortSignal
to
addEventListener()
and calling 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
type
attribute value
("load
" in the above example). The
event’s
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
type
attribute value is
"submit
" is
dispatched. If this
event’s
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
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 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
target
attribute value will be the span
element. The first time
currentTarget
attribute’s value will be the document, the second time the
body
element. eventPhase
attribute’s value switches from
CAPTURING_PHASE
to BUBBLING_PHASE
. If an event listener was registered
for the span
element, eventPhase
attribute’s value would have
been AT_TARGET
.
2.2. Interface Event
[Exposed=*]interface {
Event (
constructor DOMString ,
type optional EventInit = {});
eventInitDict readonly attribute DOMString type ;readonly attribute EventTarget ?target ;readonly attribute EventTarget ?srcElement ; // legacyreadonly 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 ; // legacyundefined 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 structs. Each struct consists 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])
- Returns a new event whose
type
attribute value is set to type. The eventInitDict argument allows for setting thebubbles
andcancelable
attributes via object members of the same name. event .
type
- Returns the type of event, e.g.
"
click
", "hashchange
", or "submit
". event .
target
- Returns the object to which event is dispatched (its target).
event .
currentTarget
- Returns the object whose event listener’s callback is currently being invoked.
event .
composedPath()
- Returns the invocation target objects of event’s
path (objects on which listeners will be invoked), except for any
nodes in shadow trees of which the shadow root’s
mode is "
closed
" that are not reachable from event’scurrentTarget
. event .
eventPhase
- Returns the event’s phase, which is one of
NONE
,CAPTURING_PHASE
,AT_TARGET
, andBUBBLING_PHASE
. event . stopPropagation()
- When dispatched in a tree, invoking this method prevents event from reaching any objects other than the current object.
event . stopImmediatePropagation()
- Invoking this method prevents event from reaching any registered event listeners after the current one finishes running and, when dispatched in a tree, also prevents event from reaching any other objects.
event .
bubbles
- Returns true or false depending on how event was initialized. True if event goes through its target’s ancestors in reverse tree order; otherwise false.
event .
cancelable
- Returns true or false depending on how event was initialized. Its return
value does not always carry meaning, but true can indicate that part of the operation
during which event was dispatched, can be canceled by invoking the
preventDefault()
method. event . preventDefault()
- If invoked when the
cancelable
attribute value is true, and while executing a listener for the event withpassive
set to false, signals to the operation that caused event to be dispatched that it needs to be canceled. event .
defaultPrevented
- Returns true if
preventDefault()
was invoked successfully to indicate cancelation; otherwise false. event .
composed
- Returns true or false depending on how event was initialized. True if
event invokes listeners past a
ShadowRoot
node that is the root of its target; otherwise false. event .
isTrusted
- Returns true if event was dispatched by the user agent, and false otherwise.
event .
timeStamp
- Returns the event’s timestamp as the number of milliseconds measured relative to the occurrence.
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
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:
NONE
(numeric value 0)- Events not currently dispatched are in this phase.
CAPTURING_PHASE
(numeric value 1)- When an event is dispatched to an object that participates in a tree it will be in this phase before it reaches its target.
AT_TARGET
(numeric value 2)- When an event is dispatched it will be in this phase on its target.
BUBBLING_PHASE
(numeric value 3)- When an event is dispatched to an object that participates in a tree it will be in this phase after it reaches its target.
Initially the attribute must be initialized to NONE
.
Each event has the following associated flags that are all initially unset:
- stop propagation flag
- stop immediate propagation flag
- canceled flag
- in passive listener flag
- composed flag
- initialized flag
- dispatch flag
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 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 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 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 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.
isTrusted
is a convenience that indicates whether an
event is dispatched by the user agent (as opposed to using
dispatchEvent()
). The sole legacy exception is click()
, which causes
the user agent to dispatch an event whose 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
isTrusted
attribute to false. -
Set event’s target to null.
-
Set event’s
type
attribute to type. -
Set event’s
bubbles
attribute to bubbles. -
Set event’s
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.
initEvent()
is redundant with event constructors and
incapable of setting composed
. It has to be supported for legacy content.
2.3. Legacy extensions to the Window
interface
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.
2.4. Interface CustomEvent
[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])
- Works analogously to the constructor for
Event
except that the eventInitDict argument now allows for setting thedetail
attribute too. event .
detail
- Returns any custom data event was created with. Typically used for synthetic events.
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.
2.5. Constructing events
Specifications may define
event constructing steps for all or some
events. The algorithm is passed an event event and an EventInit
eventInitDict as indicated in the inner event creation steps.
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
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 ofNSEvent
objects. -
Initialize event’s
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
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.
2.6. Defining event interfaces
In general, when defining a new interface that inherits from Event
please always ask
feedback from the WHATWG or the
W3C WebApps WG community.
The CustomEvent
interface can be used as starting point.
However, do not introduce any 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.
2.7. Interface EventTarget
[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:
- type (a string)
- callback (null or an
EventListener
object) - capture (a boolean, initially false)
- passive (null or a boolean, initially null)
- once (a boolean, initially false)
- signal (null or an
AbortSignal
object) - removed (a boolean for bookkeeping purposes, initially false)
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 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
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
capture
.When set to true, options’s
capture
prevents callback from being invoked when the event’seventPhase
attribute value isBUBBLING_PHASE
. When false (or not present), callback will not be invoked when event’seventPhase
attribute value isCAPTURING_PHASE
. Either way, callback will be invoked if event’seventPhase
attribute value isAT_TARGET
.When set to true, options’s
passive
indicates that the callback will not cancel the event by invokingpreventDefault()
. This is used to enable performance optimizations described in § 2.8 Observing event listeners.When set to true, options’s
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’ssignal
, 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
cancelable
attribute value is false or itspreventDefault()
method was not invoked; otherwise false.
To flatten options, run these steps:
-
If options is a boolean, then return options.
-
Return options["
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:
-
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. Let us know
if this would be useful for your programs. 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 thetype
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 not null and is 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 not null, then add the following abort steps to it:
- Remove an event listener with eventTarget and listener.
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
"DOMException
. -
Initialize event’s
isTrusted
attribute to false. -
Return the result of dispatching event to this.
2.8. Observing event listeners
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 cancelable
only when there is
at least one non-passive
listener. For example,
non-passive
TouchEvent
listeners must block scrolling, but if all
listeners are passive
then scrolling can be allowed to start
in parallel by making the TouchEvent
uncancelable (so that calls to
preventDefault()
are ignored). So code dispatching an event is able to observe the absence
of non-passive
listeners, and use that to clear the 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.
2.9. Dispatching events
To dispatch an event to a target, with an optional legacy target override flag and an optional legacyOutputDidListenersThrowFlag, run these steps:
-
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’stype
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 slot-in-closed-tree 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 slot-in-closed-tree 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
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 slot-in-closed-tree.
-
-
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 slot-in-closed-tree.
-
-
If parent is non-null, then set parent to the result of invoking parent’s get the parent with event.
-
Set slot-in-closed-tree to false.
-
-
Let clearTargetsStruct be the last struct in event’s path whose shadow-adjusted target is non-null.
-
If clearTargetsStruct’s shadow-adjusted target, clearTargetsStruct’s relatedTarget, or an
EventTarget
object in clearTargetsStruct’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 struct of event’s path, in reverse order:
-
If struct’s shadow-adjusted target is non-null, then set event’s
eventPhase
attribute toAT_TARGET
. -
Otherwise, set event’s
eventPhase
attribute toCAPTURING_PHASE
. -
Invoke with struct, event, "
capturing
", and legacyOutputDidListenersThrowFlag if given.
-
-
For each struct of event’s path:
-
If struct’s shadow-adjusted target is non-null, then set event’s
eventPhase
attribute toAT_TARGET
. -
Otherwise:
-
Set event’s
eventPhase
attribute toBUBBLING_PHASE
.
-
Invoke with struct, event, "
bubbling
", and legacyOutputDidListenersThrowFlag if given.
-
-
-
Set event’s
eventPhase
attribute toNONE
. -
Set event’s
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, invocationTarget, shadowAdjustedTarget, relatedTarget, touchTargets, and a slot-in-closed-tree, run these steps:
-
Let invocationTargetInShadowTree be false.
-
If invocationTarget is a node and its root is a shadow root, then set invocationTargetInShadowTree to true.
-
Let root-of-closed-tree be false.
-
If invocationTarget is a shadow root whose mode is "
closed
", then set root-of-closed-tree to true. -
Append a new struct 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 root-of-closed-tree, and slot-in-closed-tree is slot-in-closed-tree.
To invoke, given a struct, event, phase, and an optional legacyOutputDidListenersThrowFlag, run these steps:
-
Set event’s target to the shadow-adjusted target of the last struct in event’s path, that is either struct or preceding struct, whose shadow-adjusted target is non-null.
-
Set event’s relatedTarget to struct’s relatedTarget.
-
Set event’s touch target list to struct’s touch target list.
-
If event’s stop propagation flag is set, then return.
-
Initialize event’s
currentTarget
attribute to struct’s invocation target. -
Let listeners be a clone of event’s
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 struct’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
isTrusted
attribute is true:-
Let originalEventType be event’s
type
attribute value. -
If event’s
type
attribute value is a match for any of the strings in the first column in the following table, set event’stype
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
type
attribute value to originalEventType.
-
To inner invoke, given an event, listeners, phase, invocationTargetInShadowTree, and an optional legacyOutputDidListenersThrowFlag, run these steps:
-
Let found be false.
-
For each listener of listeners, whose removed is false:
-
If event’s
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
currentTarget
attribute value and listener. -
Let global be listener callback’s associated realm’s global object.
-
Let currentEvent be undefined.
-
If global is a
Window
object:-
Set currentEvent to global’s current event.
-
If invocationTargetInShadowTree is false, then set global’s current event to event.
-
-
If listener’s passive is true, then set event’s in passive listener flag.
-
If global 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’scurrentTarget
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 global is a
Window
object, then set global’s current event to currentEvent. -
If event’s stop immediate propagation flag is set, then break.
-
-
Return found.
2.10. Firing events
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:
-
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
type
attribute to e. -
Initialize any other IDL attributes of event as described in the invocation of this algorithm.
This also allows for the
isTrusted
attribute to be set to false. -
Return the result of dispatching event at target, with legacy target override flag set if set.
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 bubbles
or cancelable
attribute initialized,
one could write "fire an event named submit
at target with its
cancelable
attribute initialized to true".
Or, when a custom constructor is needed, "fire an event named click
at
target using MouseEvent
with its 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 …
2.11. Action versus occurrence
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 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.
3. Aborting ongoing activities
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
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 abort()
by rejecting any unsettled promise with the AbortSignal
’s 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 abort reason at all. 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.
3.1. Interface AbortController
[Exposed=*]interface {
AbortController constructor (); [SameObject ]readonly attribute AbortSignal signal ;undefined abort (optional any ); };
reason
controller = new AbortController()
- Returns a new controller whose
signal
is set to a newly createdAbortSignal
object. controller . signal
- Returns the
AbortSignal
object associated with this object. controller . abort(reason)
- Invoking this method will store reason in this object’s
AbortSignal
’s abort reason, and signal to any observers that the associated activity is to be aborted. If reason is undefined, then an "AbortError
"DOMException
will be stored.
An AbortController
object has an associated signal (an
AbortSignal
object).
The
new AbortController()
constructor steps are:
-
Let signal be a new
AbortSignal
object.
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.
3.2. Interface AbortSignal
[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)
- Returns an
AbortSignal
instance whose abort reason is set to reason if not undefined; otherwise to an "AbortError
"DOMException
. AbortSignal . any(signals)
- Returns an
AbortSignal
instance which will be aborted once any of signals is aborted. Its abort reason will be set to whichever one of signals caused it to be aborted. AbortSignal . timeout(milliseconds)
- Returns an
AbortSignal
instance which will be aborted in milliseconds milliseconds. Its abort reason will be set to a "TimeoutError
"DOMException
. signal . aborted
- Returns true if signal’s
AbortController
has signaled to abort; otherwise false. signal . reason
- Returns signal’s abort reason.
signal . throwIfAborted()
- Throws signal’s abort reason, if signal’s
AbortController
has signaled to abort; otherwise, does nothing.
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 aborted),
which is initially empty.
The abort algorithms enable APIs with complex
requirements to react in a reasonable way to abort()
. For example, a given API’s
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
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
aborted state), which is initially empty.
The static abort(reason)
method steps
are:
-
Let signal be a new
AbortSignal
object. -
Set signal’s abort reason to reason if it is given; otherwise to a new "
AbortError
"DOMException
. - Return signal.
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
"DOMException
.
For the duration of this timeout, if signal has any event listeners registered for its
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 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 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.,
) 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
abort reason is not undefined.
To add an algorithm algorithm to an AbortSignal
object signal:
-
If signal is 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 aborted, then return.
-
Set signal’s abort reason to reason if it is given; otherwise to a new "
AbortError
"DOMException
. -
Let dependentSignalsToAbort be a new list.
-
For each dependentSignal of signal’s dependent signals:
-
If dependentSignal is not aborted:
-
Set dependentSignal’s abort reason to signal’s 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 abort algorithms: run algorithm.
-
Empty signal’s abort algorithms.
-
Fire an event named
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 aborted, then set resultSignal’s abort reason to signal’s abort reason and return resultSignal.
-
Set resultSignal’s dependent to true.
-
For each signal of signals:
-
If signal’s dependent is false:
-
Append signal to resultSignal’s source signals.
-
Append resultSignal to signal’s dependent signals.
-
-
Otherwise, for each sourceSignal of signal’s source signals:
-
Append sourceSignal to resultSignal’s source signals.
-
Append resultSignal to sourceSignal’s dependent signals.
-
-
Return resultSignal.
3.2.1. Garbage collection
A non-aborted dependent AbortSignal
object must not be
garbage collected while its source signals is non-empty and it has registered event
listeners for its abort
event or its abort algorithms is non-empty.
3.3. Using AbortController
and AbortSignal
objects in
APIs
Any web platform API using promises to represent operations that can be aborted must adhere to the following:
- Accept
AbortSignal
objects through asignal
dictionary member. - Convey that the operation got aborted by rejecting the promise with
AbortSignal
object’s abort reason. - Reject immediately if the
AbortSignal
is already aborted, otherwise: - Use the abort algorithms mechanism to observe changes to the
AbortSignal
object and do so in a manner that does not lead to clashes with other observers.
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 aborted, then reject p with signal’s abort reason and return p.
-
Add the following abort steps to signal:
-
Stop doing amazing things.
-
Reject p with signal’s 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.
4. Nodes
4.1. Introduction to "The DOM"
In its original sense, "The DOM" is an API for accessing and manipulating documents (in particular, HTML and XML documents). In this specification, the term "document" is used for any markup-based resource, ranging from short static documents to long essays or reports with rich multimedia, as well as to fully-fledged interactive applications.
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:
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.
4.2. Node tree
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:
Document
-
In tree order:
-
Zero or more
ProcessingInstruction
orComment
nodes. -
Optionally one
DocumentType
node. -
Zero or more
ProcessingInstruction
orComment
nodes. -
Zero or more
ProcessingInstruction
orComment
nodes.
-
DocumentFragment
Element
-
Zero or more
Element
orCharacterData
nodes. DocumentType
CharacterData
Attr
-
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
orAttr
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.
4.2.1. Document tree
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.
4.2.2. Shadow tree
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.
4.2.2.1. Slots
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.
4.2.2.2. Slottables
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.
4.2.2.3. Finding slots and slottables
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.
4.2.2.4. Assigning slottables and slots
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.
4.2.2.5. Signaling slot change
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.
4.2.3. Mutation algorithms
To ensure pre-insert validity of a node node into a node parent before a node child:
-
If parent is not a
Document
,DocumentFragment
, orElement
node, then throw a "HierarchyRequestError
"DOMException
. -
If node is a host-including inclusive ancestor of parent, then throw a "
HierarchyRequestError
"DOMException
. -
If child is non-null and its parent is not parent, then throw a "
NotFoundError
"DOMException
. -
If node is not a
DocumentFragment
,DocumentType
,Element
, orCharacterData
node, then throw a "HierarchyRequestError
"DOMException
. -
If either node is a
Text
node and parent is a document, or node is a doctype and parent is not a document, then throw a "HierarchyRequestError
"DOMException
. -
If parent is a document, and any of the statements below, switched on the interface node implements, are true, then throw a "
HierarchyRequestError
"DOMException
.DocumentFragment
-
If node has more than one element child or has a
Text
node child.Otherwise, if node has one element child and either parent has an element child, child is a doctype, or child is non-null and a doctype is following child.
Element
-
parent has an element child, child is a doctype, or child is non-null and a doctype is following child.
DocumentType
-
parent has a doctype child, child is non-null and an element is preceding child, or child is null and parent has an element child.
To pre-insert a node into a parent before a child, run these steps:
-
Ensure pre-insert validity of node into parent before child.
-
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 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
because
the following happen in order:
-
The insert algorithm runs, which will insert the
script
andstyle
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 into a parent before a child, with an optional suppress observers flag, run these steps:
-
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:-
Queue a tree mutation record for node with « », nodes, null, and null.
This step intentionally does not pay attention to the suppress observers flag.
-
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:
-
If inclusiveDescendant’s custom element registry is null, then set inclusiveDescendant’s custom element registry to the result of looking up a custom element registry given inclusiveDescendant’s parent.
-
Otherwise, if inclusiveDescendant’s custom element registry’s is scoped is true, 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:
-
If inclusiveDescendant’s custom element registry is null and inclusiveDescendant’s keep custom element registry null is false, then set inclusiveDescendant’s custom element registry to the result of looking up a custom element registry given inclusiveDescendant’s host.
-
Otherwise, if inclusiveDescendant’s custom element registry is non-null and inclusiveDescendant’s custom element registry’s is scoped is true, append inclusiveDescendant’s node document to inclusiveDescendant’s custom element registry’s scoped document set.
-
-
-
-
If suppress observers flag is unset, 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.
Specifications may define moving steps for all or some nodes. The algorithm is passed a node movedNode, and a node-or-null oldParent 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 a node-or-null child:
-
If newParent’s shadow-including root is not the same as node’s shadow-including root, then throw a "
HierarchyRequestError
"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
"DOMException
. -
If child is non-null and its parent is not newParent, then throw a "
NotFoundError
"DOMException
. -
If node is not an
Element
or aCharacterData
node, then throw a "HierarchyRequestError
"DOMException
. -
If node is a
Text
node and newParent is a document, then throw a "HierarchyRequestError
"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
"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 theNodeIterator
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.
-
-
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:
-
If inclusiveDescendant is node, then run the moving steps with inclusiveDescendant and oldParent. Otherwise, run the moving steps with inclusiveDescendant and null.
Because the move algorithm is a separate primitive from insert and remove, it does not invoke the traditional 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 append a node to a parent, pre-insert node into parent before null.
To replace a child with node within a parent, run these steps:
-
If parent is not a
Document
,DocumentFragment
, orElement
node, then throw a "HierarchyRequestError
"DOMException
. -
If node is a host-including inclusive ancestor of parent, then throw a "
HierarchyRequestError
"DOMException
. -
If child’s parent is not parent, then throw a "
NotFoundError
"DOMException
. -
If node is not a
DocumentFragment
,DocumentType
,Element
, orCharacterData
node, then throw a "HierarchyRequestError
"DOMException
. -
If either node is a
Text
node and parent is a document, or node is a doctype and parent is not a document, then throw a "HierarchyRequestError
"DOMException
. -
If parent is a document, and any of the statements below, switched on the interface node implements, are true, then throw a "
HierarchyRequestError
"DOMException
.DocumentFragment
-
If node has more than one element child or has a
Text
node child.Otherwise, if node has one element child and either parent has an element child that is not child or a doctype is following child.
Element
-
parent has an element child that is not child or a doctype is following child.
DocumentType
-
parent has a doctype child that is not child, or an element is preceding child.
The above statements differ from the pre-insert algorithm.
-
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.
-
If child’s parent is non-null:
-
Set removedNodes to « child ».
-
Remove child with the suppress observers flag set.
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 the suppress observers flag set.
-
Queue a tree mutation record for parent with nodes, removedNodes, previousSibling, and referenceChild.
-
Return child.
To replace all with a node within a parent, run these steps:
-
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 the suppress observers flag set.
-
If node is non-null, then insert node into parent before null with the suppress observers flag set.
-
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.
To pre-remove a child from a parent, run these steps:
-
If child’s parent is not parent, then throw a "
NotFoundError
"DOMException
. -
Remove child.
-
Return child.
Specifications may define removing steps for all or some nodes. The algorithm is passed a node removedNode and a node-or-null oldParent, as indicated in the remove algorithm below.
To remove a node node, with an optional suppress observers flag, run these steps:
-
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 theNodeIterator
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 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 and null.
-
If descendant is custom and isParentConnected is true, then enqueue a custom element callback reaction with descendant, callback name "
disconnectedCallback
", and « ».
-
-
For each inclusive ancestor inclusiveAncestor of parent, and then for each registered of inclusiveAncestor’s registered observer list, if registered’s options["
subtree
"] is true, then append a new transient registered observer whose observer is registered’s observer, options is registered’s options, and source is registered to node’s registered observer list. -
If suppress observers flag is unset, then queue a tree mutation record for parent with « », « node », oldPreviousSibling, and oldNextSibling.
-
Run the children changed steps for parent.
4.2.4. Mixin NonElementParentNode
Web compatibility prevents the 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.
The getElementById(elementId)
method steps are to return the first element, in tree order, within
this’s descendants, whose ID is elementId;
otherwise, if there is no such element, null.
4.2.5. Mixin DocumentOrShadowRoot
interface mixin {
DocumentOrShadowRoot readonly attribute CustomElementRegistry ?customElementRegistry ; };Document includes DocumentOrShadowRoot ;ShadowRoot includes DocumentOrShadowRoot ;
registry = 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.
-
Assert: this is a
ShadowRoot
node. -
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.
4.2.6. Mixin ParentNode
To convert nodes into a node, given nodes and document, run these steps:
-
Let node be null.
-
Replace each string in nodes with a new
Text
node whose data is the string and node document is document. -
If nodes contains one node, then set node to nodes[0].
-
Otherwise, set node to a new
DocumentFragment
node whose node document is document, and then append each node in nodes, if any, to it. -
Return node.
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 .
children
- Returns the child elements.
element = node .
firstElementChild
- Returns the first child that is an element; otherwise null.
element = node .
lastElementChild
- Returns the last child that is an element; otherwise null.
node . prepend(nodes)
-
Inserts nodes before the first child of node, while replacing strings in nodes with equivalent
Text
nodes.Throws a "
HierarchyRequestError
"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
"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
"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
"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 lastElementChild
getter steps are to return
the last child that is an element; otherwise null.
The childElementCount
getter steps are to return
the number of children of this that are elements.
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 of node into this before null.
-
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.
4.2.7. Mixin NonDocumentTypeChildNode
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
- Returns the first preceding sibling that is an element; otherwise null.
element = node .
nextElementSibling
- Returns the first following sibling that is an element; otherwise null.
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.
4.2.8. Mixin ChildNode
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
"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
"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
"DOMException
if the constraints of the node tree are violated. node .
remove()
- Removes node.
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.
The remove()
method steps are:
4.2.9. Mixin Slottable
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.
4.2.10. Old-style collections: NodeList
and HTMLCollection
A collection is an object that represents a list of nodes. A collection can be either live or static. Unless otherwise stated, a collection must be live.
If a collection is live, then the attributes and methods on that object must operate on the actual underlying data, not a snapshot of the data.
When a collection is created, a filter and a root are associated with it.
The collection then represents a view of the subtree rooted at the collection’s root, containing only nodes that match the given filter. The view is linear. In the absence of specific requirements to the contrary, the nodes within the collection must be sorted in tree order.
4.2.10.1. Interface NodeList
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 >; };
- collection .
length
- Returns the number of nodes in the collection.
- element = collection .
item(index)
- element = collection[index]
- Returns the node with index index from the collection. The nodes are sorted in tree order.
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.
4.2.10.2. Interface HTMLCollection
[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).
- collection .
length
- Returns the number of elements in the collection.
- element = collection .
item(index)
- element = collection[index]
- Returns the element with index index from the collection. The elements are sorted in tree order.
- element = collection .
namedItem(name)
- element = collection[name]
- Returns the first element with ID or name name from the collection.
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’sname
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:
- it has an ID which is key;
- it is in the HTML namespace and has a
name
attribute whose value is key;
or null if there is no such element.
4.3. Mutation observers
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.
To queue a mutation observer microtask, run these steps:
-
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, run these steps:
-
Set the surrounding agent’s mutation observer microtask queued to false.
-
Let notifySet be a clone of the surrounding agent’s pending mutation observers.
-
Let signalSet be a clone of the surrounding agent’s signal slots.
-
Empty the surrounding agent’s signal slots.
-
For each mo of notifySet:
-
Let records be a clone of mo’s record queue.
-
Empty mo’s record queue.
-
For each node of mo’s node list, remove all transient registered observers whose observer is mo from node’s registered observer list.
-
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 itsbubbles
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).
Transient registered observers are used to track mutations within
a given node’s descendants after node has been removed so
they do not get lost when subtree
is set to true on node’s
parent.
4.3.1. Interface MutationObserver
[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:
- A callback set on creation.
- A node list (a list of weak references to nodes), which is initially empty.
- A record queue (a queue of
zero or more
MutationRecord
objects), which is initially empty.
observer = new
MutationObserver(callback)
- Constructs a
MutationObserver
object and sets its callback to callback. The callback is invoked with a list ofMutationRecord
objects as first argument and the constructedMutationObserver
object as second argument. It is invoked after nodes registered with theobserve()
method, are mutated. observer .
observe(target, options)
-
Instructs the user agent to observe a given target
(a node) and report any mutations based on
the criteria given by options (an object).
The options argument allows for setting mutation observation options via object members. These are the object members that can be used:
childList
- Set to true if mutations to target’s children are to be observed.
attributes
- Set to true if mutations to target’s
attributes are to be observed. Can be omitted if
attributeOldValue
orattributeFilter
is specified. characterData
- Set to true if mutations to target’s
data are to be observed. Can be omitted if
characterDataOldValue
is specified. subtree
- Set to true if mutations to not just target, but also target’s descendants are to be observed.
attributeOldValue
- Set to true if
attributes
is true or omitted and target’s attribute value before the mutation needs to be recorded. characterDataOldValue
- Set to true if
characterData
is set to true or omitted and target’s data before the mutation needs to be recorded. attributeFilter
- Set to a list of attribute
local names (without namespace) if not all
attribute mutations need to be
observed and
attributes
is true or omitted.
observer .
disconnect()
- Stops observer from observing any mutations. Until the
observe()
method is used again, observer’s callback will not be invoked. observer .
takeRecords()
- Empties the record queue and returns what was in there.
The
new MutationObserver(callback)
constructor steps are to set this’s callback to
callback.
The
observe(target, options)
method steps are:
-
If either options["
attributeOldValue
"] or options["attributeFilter
"] exists, and options["attributes
"] does not exist, then set options["attributes
"] to true. -
If options["
characterDataOldValue
"] exists and options["characterData
"] does not exist, then set options["characterData
"] to true. -
If none of options["
childList
"], options["attributes
"], and options["characterData
"] is true, then throw aTypeError
. -
If options["
attributeOldValue
"] is true and options["attributes
"] is false, then throw aTypeError
. -
If options["
attributeFilter
"] is present and options["attributes
"] is false, then throw aTypeError
. -
If options["
characterDataOldValue
"] is true and options["characterData
"] is false, then throw aTypeError
. -
For each registered of target’s registered observer list, if registered’s observer is this:
-
For each node of this’s node list, 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.
4.3.2. Queuing a mutation record
To queue a mutation record of type for target with name, namespace, oldValue, addedNodes, removedNodes, previousSibling, and nextSibling, run these steps:
-
Let interestedObservers be an empty map.
-
Let nodes be the inclusive ancestors of target.
-
For each node in 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
- node is not target and
options["
subtree
"] is false - type is "
attributes
" and options["attributes
"] either does not exist or is false - type is "
attributes
", options["attributeFilter
"] exists, and options["attributeFilter
"] does not contain name or namespace is non-null - type is "
characterData
" and options["characterData
"] either does not exist or is false - type is "
childList
" and options["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["attributeOldValue
"] is true, or type is "characterData
" and options["characterDataOldValue
"] is true, then set interestedObservers[mo] to oldValue.
- node is not target and
options["
-
-
For each observer → mappedOldValue of interestedObservers:
-
Let record be a new
MutationRecord
object with itstype
set to type,target
set to target,attributeName
set to name,attributeNamespace
set to namespace,oldValue
set to mappedOldValue,addedNodes
set to addedNodes,removedNodes
set to removedNodes,previousSibling
set to previousSibling, andnextSibling
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, run these steps:
-
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.
4.3.3. Interface MutationRecord
[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 .
type
- Returns "
attributes
" if it was an attribute mutation. "characterData
" if it was a mutation to aCharacterData
node. And "childList
" if it was a mutation to the tree of nodes. record .
target
- Returns the node the mutation
affected, depending on the
type
. For "attributes
", it is the element whose attribute changed. For "characterData
", it is theCharacterData
node. For "childList
", it is the node whose children changed. record .
addedNodes
record .
removedNodes
- Return the nodes added and removed respectively.
record .
previousSibling
record .
nextSibling
- Return the previous and next sibling respectively of the added or removed nodes; otherwise null.
record .
attributeName
- Returns the local name of the changed attribute; otherwise null.
record .
attributeNamespace
- Returns the namespace of the changed attribute; otherwise null.
record .
oldValue
- The return value depends on
type
. For "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.
4.4. Interface Node
[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 = 5; // legacy
ENTITY_REFERENCE_NODE const unsigned short = 6; // legacy
ENTITY_NODE 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 = 12; // legacy
NOTATION_NODE 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 ?); // legacy alias of ===
otherNode 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.
node .
nodeType
-
Returns a number appropriate for the type of node, as follows:
Element
(1).Node
.ELEMENT_NODE
Attr
(2).Node
.ATTRIBUTE_NODE
- An exclusive
Text
node
(3).Node
.TEXT_NODE
CDATASection
(4).Node
.CDATA_SECTION_NODE
ProcessingInstruction
(7).Node
.PROCESSING_INSTRUCTION_NODE
Comment
(8).Node
.COMMENT_NODE
Document
(9).Node
.DOCUMENT_NODE
DocumentType
(10).Node
.DOCUMENT_TYPE_NODE
DocumentFragment
(11).Node
.DOCUMENT_FRAGMENT_NODE
node .
nodeName
-
Returns a string appropriate for the type of node, as follows:
Element
- Its HTML-uppercased qualified name.
Attr
- Its qualified name.
- An exclusive
Text
node - "
#text
". CDATASection
- "
#cdata-section
". ProcessingInstruction
- Its target.
Comment
- "
#comment
". Document
- "
#document
". DocumentType
- Its name.
DocumentFragment
- "
#document-fragment
".
The nodeType
getter steps are to return the first matching
statement, switching on the interface this implements:
Element
ELEMENT_NODE
(1)Attr
ATTRIBUTE_NODE
(2);- An exclusive
Text
node TEXT_NODE
(3);CDATASection
CDATA_SECTION_NODE
(4);ProcessingInstruction
PROCESSING_INSTRUCTION_NODE
(7);Comment
COMMENT_NODE
(8);Document
DOCUMENT_NODE
(9);DocumentType
DOCUMENT_TYPE_NODE
(10);DocumentFragment
DOCUMENT_FRAGMENT_NODE
(11).
The nodeName
getter steps are to return the first matching
statement, switching on the interface this implements:
Element
- Its HTML-uppercased qualified name.
Attr
- Its qualified name.
- An exclusive
Text
node - "
#text
". CDATASection
- "
#cdata-section
". ProcessingInstruction
- Its target.
Comment
- "
#comment
". Document
- "
#document
". DocumentType
- Its name.
DocumentFragment
- "
#document-fragment
".
node .
baseURI
- Returns node’s node document’s document base URL.
The baseURI
getter steps are to return this’s
node document’s document base URL, serialized.
node .
isConnected
-
Returns true if node is connected; otherwise false.
node .
ownerDocument
- Returns the node document. Returns null for documents.
node .
getRootNode()
- Returns node’s root.
node . getRootNode({ composed:true })
- Returns node’s shadow-including root.
node .
parentNode
- Returns the parent.
node .
parentElement
- Returns the parent element.
node .
hasChildNodes()
- Returns whether node has children.
node .
childNodes
- Returns the children.
node .
firstChild
- Returns the first child.
node .
lastChild
- Returns the last child.
node .
previousSibling
- Returns the previous sibling.
node .
nextSibling
- Returns the next sibling.
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["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:
Attr
- this’s value.
CharacterData
- this’s data.
- Otherwise
- Null.
The 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:
Attr
-
Set an existing attribute value with this and the given value.
CharacterData
-
Replace data with node this, offset 0, count this’s length, and data the given value.
- Otherwise
-
Do nothing.
To get text content with a node node, return the following, switching on the interface node implements:
DocumentFragment
Element
- The descendant text content of node.
Attr
- node’s value.
CharacterData
- node’s data.
- Otherwise
- Null.
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 a new
Text
node whose data is string and node document is parent’s node document. -
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:
DocumentFragment
Element
-
String replace all with value within node.
Attr
-
Set an existing attribute value with node and value.
CharacterData
-
Replace data with node node, offset 0, count node’s length, and data value.
- Otherwise
-
Do nothing.
The 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 .
normalize()
- Removes empty exclusive
Text
nodes and concatenates the data of remaining contiguous exclusiveText
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 with node node, offset length, count 0, and data 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])
- Returns a copy of node. If subtree is true, the copy also includes the node’s descendants.
node .
isEqualNode(otherNode)
- Returns whether node and otherNode have the same properties.
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 effective global custom element registry.
-
Attach a shadow root with copy, node’s shadow root’s mode, true, node’s shadow root’s serializable, node’s shadow root’s delegates focus, node’s shadow root’s slot assignment, and shadowRootRegistry.
-
Set copy’s shadow root’s declarative to node’s shadow root’s declarative.
-
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 subtree, 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 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, set copy to a node that implements the same interfaces as node, and fulfills these additional requirements, switching on the interface node implements:
Document
-
-
Set copy’s encoding, content type, URL, origin, type, mode, and allow declarative shadow roots, to those of node.
-
If node’s custom element registry’s is scoped is true, then set copy’s custom element registry to node’s custom element registry.
-
DocumentType
Attr
-
Set copy’s namespace, namespace prefix, local name, and value to those of node.
Text
Comment
-
Set copy’s data to that of node.
ProcessingInstruction
- Otherwise
-
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
"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:
DocumentType
- Its name, public ID, and system ID.
Element
- Its namespace, namespace prefix, local name, and its attribute list’s size.
Attr
- Its namespace, local name, and value.
ProcessingInstruction
- Its target and data.
Text
Comment
- Its data.
- Otherwise
- —
-
If A is an element, each attribute in its attribute list has an attribute that 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)
-
Returns a bitmask indicating the position of other
relative to node. These are the bits that can be set:
(1)Node
.DOCUMENT_POSITION_DISCONNECTED
- Set when node and other are not in the same tree.
(2)Node
.DOCUMENT_POSITION_PRECEDING
- Set when other is preceding node.
(4)Node
.DOCUMENT_POSITION_FOLLOWING
- Set when other is following node.
(8)Node
.DOCUMENT_POSITION_CONTAINS
- Set when other is an ancestor of node.
(16, 10 in hexadecimal)Node
.DOCUMENT_POSITION_CONTAINED_BY
- Set when other is a descendant of node.
node .
contains(other)
- Returns true if other is an inclusive descendant of node; otherwise false.
These are the constants compareDocumentPosition()
returns as mask:
DOCUMENT_POSITION_DISCONNECTED
(1);DOCUMENT_POSITION_PRECEDING
(2);DOCUMENT_POSITION_FOLLOWING
(4);DOCUMENT_POSITION_CONTAINS
(8);DOCUMENT_POSITION_CONTAINED_BY
(16, 10 in hexadecimal);DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
(32, 20 in hexadecimal).
The compareDocumentPosition(other)
method
steps are: