dom
dom copied to clipboard
Introduce `moveBefore()` state-preserving atomic move API
This PR introduces a new DOM API on the Node interface: moveBefore(). It mirrors insertBefore() in shape, but defers to a new DOM manipulation primitive that this PR adds in service of this new API: the "move" primitive. The move primitive contains some of the DOM tree bookkeeping steps from the remove primitive, as well as the insert primitive, and does three more interesting things:
- Calls the moving steps hook with the moved node and the old parent (possibly null, just like the removing steps)
- Queues a custom element callback reaction for the
connectedMoveCallback() - Queues two back-to-back mutation record tasks: one for removal from the old parent; one for insertion into the new one
The power of the move primitive comes from the fact that the algorithm does not defer to the traditional insert and removal primitives, and therefore does not invoke the removing steps and insertion steps. This allows most state to be preserved by default (i.e., we don't tear down iframes, or close dialogs). Sometimes, the insertion/removing step overrides in other specifications have steps that do need to be performed during a move anyways. These specifications are expected to override the moving steps hook and perform the necessary work accordingly. See https://github.com/whatwg/html/pull/10657 for HTML.
Remaining tasks (some will be PRs in other standards):
- [x] Custom element integration
- [x] Keep popovers open
- [x] Don't call post-connection steps if state-preserving atomic move is in progress
- [x] Don't call becomes connected / becomes browsing-context
- [x] Only disconnect subframes on removal when state-preserving atomic move is not in progress
- [x] Keep dialogs open: see removing steps
- [x] img/source: this shouldn't count as a relevant mutation
- [x] Preserve fullscreen
- [ ] Preserve focus
- Need to resolve
focusinevent semantics
- Need to resolve
- ~[ ] Don't reset animations / transitions. See here
- Maybe nothing needs to be done here. Given how element removals are handled, the spec does NOT require transitions to be removed from the UA's set of running transitions for moved nodes since they are never removed from the Document.~
- ~[ ] Preserve text-selection. See set the selection range. Edit: Nothing needs to be done here. Selection metadata (i.e.,
selectionStartand kin) is preserved by default in browsers, consistent with HTML (no action is taken on removal). The UI behavior of the selection not being highlighted is a side-effect of the element losing focus~ - [ ] Selection API: don't reset the Document's selection
- Updates to the selection range should happen according to how the DOM Standard primitives update ranges. The Selection API specification admits as much, by deferring to the insert and removal algorithms. Therefore, we should reference the move primitive from the Selection API specification, and ensure that the move primitive in this DOM Standard PR updates live ranges correctly.
selectionchangeevent: We've decided to allowselectionchangeevent to still fire, since it is queued in a task. No changes for this part are required.
- [ ] Pointer event state reset: see here
- [ ] Hide input/select picker: here
- [ ] Cancel pointer lock: here
- [ ] Containment: keep last remembered size(see here)
- [x] At least two implementers are interested (and none opposed):
- Chromium: https://issues.chromium.org/issues/40150299
- WebKit: https://github.com/WebKit/standards-positions/issues/375
- Gecko: https://github.com/mozilla/standards-positions/issues/1053
- [x] Tests are written and can be reviewed and commented upon at:
- https://github.com/web-platform-tests/wpt/tree/master/dom/nodes/moveBefore/tentative (need to mark as non-tentative)
- [x] Implementation bugs are filed:
- Chromium: https://issues.chromium.org/issues/40150299
- Gecko: https://bugzilla.mozilla.org/show_bug.cgi?id=1923880
- WebKit: https://bugs.webkit.org/show_bug.cgi?id=281223
- [ ] MDN issue is filed: …
- [ ] The top of this comment includes a clear commit message to use.
(See WHATWG Working Mode: Changes for more details.)