Re: [whatwg/dom] Introduce DOM post-insertion steps (PR #1261)

@domfarolino commented on this pull request.



> +  modify the tree's structure, making live traversal unsafe, possibly leading to the
+  <a>post-insertion steps</a> being called multiple times on the same <a>node</a>.</p>
+ </li>
+
+ <li>
+  <p>For each <var>node</var> in <var>nodes</var>, in <a>tree order</a>:
+
+  <ol>
+   <li><p>For each <a>shadow-including inclusive descendant</a> <var>inclusiveDescendant</var> of
+   <var>node</var>, in <a>shadow-including tree order</a>, <a for=list>append</a>
+   <var>inclusiveDescendant</var> to <var>staticNodeList</var>.
+  </ol>
+ </li>
+
+ <li><p><a for=list>For each</a> <var>node</var> in <var>staticNodeList</var>, if <var>node</var> is
+ <a>connected</a>, then run the <a>post-insertion steps</a> with <var>node</var>.

Great scenario. So to make the case more concrete, you're envisioning something like:

1. Insert **(a)** script and **(b)** iframe at the same time.
    - Both are now in the DOM, but we have not yet made it to the step where we iterate over them and run their post-insertion steps (i.e., the spec step you're commenting on above)
1. **(a)** Run the script's post-insertion steps: this moves the iframe around in the DOM. This both:
    - Re-inserts the iframe into the DOM
    - Runs the iframe's post-insertion steps
1. **(b)** Re-run the iframe's post-insertion steps, even though it exists elsewhere in the DOM now.

Chromium currently runs the post-insertion steps the second time. I think WebKit does the same from looking at their code, but I can't quite re-produce.

Chromium has code that handles this [explicitly for iframes here](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/html/html_frame_element_base.cc;l=192-195;drc=df5e5c413d71fd4d130e837dc5bd7bd0c7ff3cf5) so that we don't try and re-create an iframe's initial document after it has been inserted. And for scripts, I think you would just rely on the [already started boolean](https://html.spec.whatwg.org/C#already-started) to not re-execute a script that has already executed due to insertion ([Chromium code here](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/script/script_loader.cc;l=571-573;drc=b74be264a68fdb02cb216ad60ea610562d2f800d)).

I lean towards DOM being OK running the post-insertion steps multiple times, and then having per-element checks do the right thing if they don't want to run multiple times. The reason I lean towards this is because I can construct a case where we actually rely on the _second_ invocation of the post-insertion steps doing stuff.

Imagine a case where you insert two scripts at the same time, i.e., `document.body.append(script1, script2)`. `script2` has an invalid `type` and therefore is not executable as-is. `script1` does two things:
1. Moves `script2` around in the DOM (thus invoking the second script's post-insertion steps for the first time)
2. Removes `script2`'s invalid `type` attribute, making it finally valid (but not immediately executing it)

At least in Chromium, when `script2`'s post-insertion steps run for the second time (as a result of the outermost `document.body.append(script1, script2)` call finally invoking `script2`'s post-insertion steps), `script2` will finally execute. Here's the code snippet:

```js
const script1 = document.createElement('script');
script1.innerText = `
  const div = document.querySelector('div');
  div.append(script2);
  script2.removeAttribute('type');
`;

const script2 = document.createElement('script');
script2.id = 'script2';
// Makes the script invalid so that it does not run upon insertion.
script2.type = 'foo';
script2.innerText = 'console.log("grazie");';

document.body.append(script1, script2);
```

For some reason WebKit does not run the script, which I think indicates that the post-insertion steps do not run the second time for `script2`. I would love to know why; @rniwa might know. I might've investigated this over in https://github.com/whatwg/html/pull/10188 but I can't remember off the top of my head. Either way, hopefully this sheds some light on this scenario. WDYT @smaug---- 

-- 
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/dom/pull/1261#discussion_r1594562487
You are receiving this because you are subscribed to this thread.

Message ID: <whatwg/dom/pull/1261/review/2046534836@github.com>

Received on Wednesday, 8 May 2024 20:02:19 UTC