diff --git a/dom.bs b/dom.bs index 3e4c85cb..2b99f885 100644 --- a/dom.bs +++ b/dom.bs @@ -2645,12 +2645,69 @@ of a node into a parent before a child, run the

Specifications may define insertion steps for all or some nodes. The -algorithm is passed insertedNode, as indicated in the insert -algorithm below. +algorithm is passed insertedNode, as indicated in the insert algorithm +below. These steps must not modify the node tree that insertedNode +participates in, create browsing contexts, +fire events, or otherwise execute JavaScript. These steps may +[=queue a global task|queue tasks=] to do these things asynchronously, however. + +

+

While the insertion steps cannot execute JavaScript (among other things), they will + indeed have script-observable consequences. Consider the below example: + +


+ const h1 = document.querySelector('h1');
+
+ const fragment = new DocumentFragment();
+ const script = fragment.appendChild(document.createElement('script'));
+ const style = fragment.appendChild(document.createElement('style'));
+
+ script.innerText= 'console.log(getComputedStyle(h1).color)'; // Logs 'rgb(255, 0, 0)'
+ style.innerText = 'h1 {color: rgb(255, 0, 0);}';
+
+ document.body.append(fragment);
+ 
+ +

The script in the above example logs 'rgb(255, 0, 0)' because + the following happen in order: + +

    +
  1. The insert algorithm runs, which will insert the <{script}> and + style elements in order. + +

      +
    1. The HTML Standard's insertion steps run for the <{script}> element; they do + nothing. [[!HTML]] + +

    2. The HTML Standard's insertion steps run for the + style element; they immediately apply its style rules to the + document. [[!HTML]] + +

    3. 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]] +

    +
  2. +
+
+ +

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, @@ -2752,6 +2809,30 @@ before a child, with an optional suppress observers flag, run 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: + +

      +
    1. 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.