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