2.2. Interface Event

Each event has the following associated flags that are all initially unset:

To initialize an event, with type, bubbles, and cancelable, run these steps:

  1. Set event’s initialized flag.

  2. Unset event’s stop propagation flag, stop immediate propagation flag, and canceled flag.

  3. Set event’s isTrusted attribute to false.

  4. Set event’s target to null.

  5. Set event’s type attribute to type.

  6. Set event’s bubbles attribute to bubbles.

  7. Set event’s cancelable attribute to cancelable.

The initEvent(type, bubbles, cancelable) method steps are:

  1. If this’s dispatch flag is set, then return.

  2. Initialize this with type, bubbles, and cancelable.

Nodes are objects that implement Node. Nodes participate in a tree, which is known as the node tree.

To insert a node node into a node parent before null or a node child, with an optional boolean suppressObservers (default false):

  1. Let nodes be node’s children, if node is a DocumentFragment node; otherwise « node ».

  2. Let count be nodes’s size.

  3. If count is 0, then return.

  4. If node is a DocumentFragment node:

    1. Remove its children with suppressObservers set to true.

    2. Queue a tree mutation record for node with « », nodes, null, and null.

      This step intentionally does not pay attention to suppressObservers.

  5. If child is non-null:

    1. For each live range whose start node is parent and start offset is greater than child’s index: increase its start offset by count.

    2. For each live range whose end node is parent and end offset is greater than child’s index: increase its end offset by count.

  6. Let previousSibling be child’s previous sibling or parent’s last child if child is null.

  7. For each node in nodes, in tree order:

    1. Adopt node into parent’s node document.

    2. If child is null, then append node to parent’s children.

    3. Otherwise, insert node into parent’s children before child’s index.

    4. 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.

    5. 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.

    6. Run assign slottables for a tree with node’s root.

    7. For each shadow-including inclusive descendant inclusiveDescendant of node, in shadow-including tree order:

      1. Run the insertion steps with inclusiveDescendant.

      2. If inclusiveDescendant is not connected, then continue.

      3. If inclusiveDescendant is an element and inclusiveDescendant’s custom element registry is non-null:

        1. If inclusiveDescendant’s custom element registry’s is scoped is true, then append inclusiveDescendant’s node document to inclusiveDescendant’s custom element registry’s scoped document set.

        2. If inclusiveDescendant is custom, then enqueue a custom element callback reaction with inclusiveDescendant, callback name "connectedCallback", and « ».

        3. Otherwise, try to upgrade inclusiveDescendant.

          If this successfully upgrades inclusiveDescendant, its connectedCallback will be enqueued automatically during the upgrade an element algorithm.

      4. Otherwise, if inclusiveDescendant is a shadow root, inclusiveDescendant’s custom element registry is non-null, and inclusiveDescendant’s custom element registry’s is scoped is true, then append inclusiveDescendant’s node document to inclusiveDescendant’s custom element registry’s scoped document set.

  8. If suppressObservers is false, then queue a tree mutation record for parent with nodes, « », previousSibling, and child.

  9. Run the children changed steps for parent.

  10. 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.

  11. For each node of nodes, in tree order:

    1. For each shadow-including inclusive descendant inclusiveDescendant of node, in shadow-including tree order: append inclusiveDescendant to staticNodeList.

  12. For each node of staticNodeList: if node is connected, then run the post-connection steps with node.

To replace a node child with a node node within a node parent:

  1. Ensure pre-insert validity given node, parent, child, and « child ».

  2. Let referenceChild be child’s next sibling.

  3. If referenceChild is node, then set referenceChild to node’s next sibling.

  4. Let previousSibling be child’s previous sibling.

  5. Let removedNodes be the empty set.

  6. Adopt node into parent’s node document.

  7. If child’s parent is non-null:

    1. Set removedNodes to « child ».

    2. Remove child with suppressObservers set to true.

    The above can only be false if child is node.

  8. Let nodes be node’s children if node is a DocumentFragment node; otherwise « node ».

  9. Insert node into parent before referenceChild with suppressObservers set to true.

  10. Queue a tree mutation record for parent with nodes, removedNodes, previousSibling, and referenceChild.

  11. Return child.

4.4. Interface Node

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):

  1. Assert: node is not a document or node is document.

  2. Let copy be the result of cloning a single node given node, document, and fallbackRegistry.

  3. Run any cloning steps defined for node in other applicable specifications and pass node, copy, and subtree as parameters.

  4. If parent is non-null, then append copy to parent.

  5. 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.

  6. If node is an element, node is a shadow host, and node’s shadow root’s clonable is true:

    1. Assert: copy is not a shadow host.

    2. Let shadowRootRegistry be node’s shadow root’s custom element registry.

    3. If shadowRootRegistry is a global custom element registry, then set shadowRootRegistry to document’s custom element registry’s effective global custom element registry.

    4. Attach a shadow root with copy, node’s shadow root’s mode, node’s shadow root’s delegates focus, node’s shadow root’s serializable, node’s shadow root’s slot assignment, true, and shadowRootRegistry.

    5. Set copy’s shadow root’s declarative to node’s shadow root’s declarative.

    6. Set copy’s shadow root’s keep custom element registry null to node’s shadow root’s keep custom element registry null.

    7. For each child of node’s shadow root’s children, in tree order: clone a node given child with document set to document, subtree set to true, and parent set to copy’s shadow root.

      This intentionally does not pass the fallbackRegistry argument.

  7. Return copy.

To create an element, given a document document, string localName, string-or-null namespace, and optionally a string-or-null prefix (default null), string-or-null is (default null), boolean synchronousCustomElements (default false), and "default", null, or a CustomElementRegistry object registry (default "default"):

  1. Let result be null.

  2. If registry is "default", then set registry to the result of looking up a custom element registry given document.

  3. Let definition be the result of looking up a custom element definition given registry, namespace, localName, and is.

  4. If definition is non-null, and definition’s name is not equal to its local name (i.e., definition represents a customized built-in element):

    1. Let interface be the element interface for localName and the HTML namespace.

    2. Set result to the result of creating an element internal given document, interface, localName, the HTML namespace, prefix, "undefined", is, and registry.

    3. If synchronousCustomElements is true, then run this step while catching any exceptions:

      1. Upgrade result using definition.

      If this step threw an exception exception:

      1. Report exception for definition’s constructor’s corresponding JavaScript object’s associated realm’s global object.

      2. Set result’s custom element state to "failed".

    4. Otherwise, enqueue a custom element upgrade reaction given result and definition.

  5. Otherwise, if definition is non-null:

    1. If synchronousCustomElements is true:

      1. Let C be definition’s constructor.

      2. Let previousRegistry be the surrounding agent’s active custom element constructor map[C] with default null.

      3. Set the surrounding agent’s active custom element constructor map[C] to registry.

      4. Run these steps while catching any exceptions:

        1. Set result to the result of constructing C, with no arguments.

        2. Assert: one of the following is true:

          customElements.define("x-example", class extends HTMLElement {
            constructor() {
              // Non-conformant: returns an existing element instead of calling super().
              return document.createElement("p");
            }
          });
          
          document.createElement("x-example");
          

          Here result is the p element, whose custom element state is "uncustomized" and whose custom element definition is null.

        3. Assert: result’s namespace is the HTML namespace.

          IDL enforces that result is an HTMLElement object, which all use the HTML namespace.

        4. If result’s attribute list is not empty, then throw a "NotSupportedError" DOMException.

        5. If result has children, then throw a "NotSupportedError" DOMException.

        6. If result’s parent is non-null, then throw a "NotSupportedError" DOMException.

        7. If result’s node document is not document, then throw a "NotSupportedError" DOMException.

        8. If result’s local name is not equal to localName, then throw a "NotSupportedError" DOMException.

        9. Set result’s namespace prefix to prefix.

        10. Set result’s is value to null.

        11. Set result’s custom element registry to registry.

        If any of these steps threw an exception exception:

        1. Report exception for definition’s constructor’s corresponding JavaScript object’s associated realm’s global object.

        2. Set result to the result of creating an element internal given document, HTMLUnknownElement, localName, the HTML namespace, prefix, "failed", null, and registry.

      5. If previousRegistry is null, then remove the surrounding agent’s active custom element constructor map[C].

      6. Otherwise, set the surrounding agent’s active custom element constructor map[C] to previousRegistry.

    2. Otherwise:

      1. Set result to the result of creating an element internal given document, HTMLElement, localName, the HTML namespace, prefix, "undefined", null, and registry.

      2. Enqueue a custom element upgrade reaction given result and definition.

  6. Otherwise:

    1. Let interface be the element interface for localName and namespace.

    2. Set result to the result of creating an element internal given document, interface, localName, namespace, prefix, "uncustomized", is, and registry.

    3. If namespace is the HTML namespace, and either localName is a valid custom element name or is is non-null, then set result’s custom element state to "undefined".

  7. Return result.