Bug 309730
| Summary: | Deleting next sibling node while replacing this node stops the replacement being processed | ||
|---|---|---|---|
| Product: | WebKit | Reporter: | Barry Pollard <barry> |
| Component: | DOM | Assignee: | Ryosuke Niwa <rniwa> |
| Status: | RESOLVED FIXED | ||
| Severity: | Normal | CC: | annevk, cdumez, rniwa, webkit-bug-importer |
| Priority: | P2 | Keywords: | InRadar |
| Version: | Safari 26 | ||
| Hardware: | Unspecified | ||
| OS: | Unspecified | ||
Barry Pollard
Take this HTML:
```html
<div id="to-be-replaced"></div><span id="to-be-removed"></span>
<template id="my-template">
<span>New </span>
<script id="removal-script">
document.querySelector("#to-be-removed").remove();
</script>
<span>content</span>
</template>
<script>
const template = document.querySelector('#my-template');
document.querySelector('#to-be-replaced').replaceWith(template.content.cloneNode(true));
</script>
```
This should replace the `<div id="to-be-replaced"></div>` with the contents of the template, and the `<script>` in that should remove the following `<span id="ref"></span>`, and so we should be left with "New content" (with a hidden `<script>` in between those two words).
This works in Chrome and Firefox.
However in Safari, when it inserts the script, and deletes the `<span>`, Safari stops processing the rest of the `replaceWith` and so you're left with "New" (and the hidden script) but without "Content".
However, if you add any whitespace between the `<div>` and the `<span>`, then it all works fine. The bug only happens when the next sibling is removed mid-replacement.
Additionally, if you wrap the children of the `<template>` into a single `<div>` element it also works.
You can see this in the test cases here: https://www.tunetheweb.com/experiments/safari-node-replacement-bug/
| Attachments | ||
|---|---|---|
| Add attachment proposed patch, testcase, etc. |
Ryosuke Niwa
The `script` element now uses the "post-connection steps" in https://dom.spec.whatwg.org/#concept-node-insert.
Whereas WebKit runs scripts as they get inserted, the spec delays the execution until all nodes are inserted.
To match the spec's behavior, we'd need to change delay childrenChanged and didFinishInsertingNode who inserting a document fragment.
Ryosuke Niwa
This has been fixed by https://commits.webkit.org/309388@main.
Ryosuke Niwa
Pull request: https://github.com/WebKit/WebKit/pull/60755
EWS
Committed 309411@main (c495217439eb): <https://commits.webkit.org/309411@main>
Reviewed commits have been landed. Closing PR #60755 and removing active labels.
Radar WebKit Bug Importer
<rdar://problem/172753019>