Re: [whatwg/dom] Introduce `moveBefore()` state-preserving atomic move API (PR #1307)

> 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:
> 
> 1. Calls the [moving steps hook](https://whatpr.org/dom/1307.html#concept-moving-steps-ext) with the moved node and the old parent (possibly null, just like the removing steps)
> 2. Queues a custom element callback reaction for the `connectedMoveCallback()`
> 3. 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](https://dom.spec.whatwg.org/#concept-node-remove-ext) and [insertion steps](https://dom.spec.whatwg.org/#concept-node-insert-ext). 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 [whatwg/html#10657](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](https://html.spec.whatwg.org/C#the-dialog-element:html-element-removing-steps)
> * [x]  img/source: this shouldn't count as a [relevant mutation](https://html.spec.whatwg.org/C#relevant-mutations)
> * [x]  Preserve fullscreen
> * [x]  Preserve focus 
>   
>   * Need to resolve `focusin` event semantics
> * ~[ ] Don't reset animations / transitions. See [here](https://drafts.csswg.org/css-transitions/#starting) 
>   
>   * Maybe nothing needs to be done here. Given [how element removals are handled](https://drafts.csswg.org/css-transitions/#transition-cancel:~:text=If%20an%20element%20is%20no%20longer%20in%20the%20document%2C%20implementations%20must%20cancel%20any%20running%20transitions%20on%20it%20and%20remove%20transitions%20on%20it%20from%20the%20completed%20transitions), 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](https://html.spec.whatwg.org/C#set-the-selection-range). Edit: Nothing needs to be done here. Selection metadata (i.e., `selectionStart` and 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~
> * [x]  Selection API: don't reset the Document's [selection](https://w3c.github.io/selection-api/#dfn-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](https://w3c.github.io/selection-api/#responding-to-dom-mutations) 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: [Reference the move primitive in DOM mutations section w3c/selection-api#341](https://github.com/w3c/selection-api/pull/341)
>   * `selectionchange` event: We've decided to allow `selectionchange` event to still fire, [since it is queued in a task](https://w3c.github.io/selection-api/#ref-for-dfn-schedule-a-selectionchange-event-1). No changes for this part are required.
> * [x]  Pointer event state reset: see [here](https://w3c.github.io/pointerevents/#suppressing-a-pointer-event-stream)
>   
>   * The specification does not reset an element's previously-set pointer capture upon DOM node insertion or removal. While this seems like a gap in that specification ([[DOM integration] No state is reset on node removal w3c/pointerevents#526](https://github.com/w3c/pointerevents/issues/526)), it appears that nothing needs to be done in that specification to satisfy this preservation semantic.
>   * Test: https://github.com/web-platform-tests/wpt/blob/master/dom/nodes/moveBefore/tentative/pointer-events.html
> * [x]  Hide input/select picker: [here](https://html.spec.whatwg.org/C#show-the-picker%2C-if-applicable)
>   
>   * Nothing in the specification seems to hook into DOM for removal when the picker dialog is shown, so no work needs to be done in this PR. See ["Show the picker" steps never dismisses the picker upon node removal html#10743](https://github.com/whatwg/html/issues/10743) for a follow-up.
> * [x]  Preserve pointer lock: [here](https://w3c.github.io/pointerlock/#requestPointerLock)
>   
>   * When a ["pointer-lock target becomes disconnected"](https://w3c.github.io/pointerlock/#ref-for-dfn-pointer-lock-target-12), pointer lock is exited. Since the "becomes disconnected" hook is not run during an atomic move, pointer lock is preserved naturally.
> * [x]  Containment: keep last remembered size(see [here](https://drafts.csswg.org/css-sizing-4/#last-remembered))
> 
> * [x]  At least two implementers are interested (and none opposed):
>   
>   * Chromium: https://issues.chromium.org/issues/40150299
>   * WebKit: [DOM State-preserving move (`Node.prototype.moveBefore`) WebKit/standards-positions#375](https://github.com/WebKit/standards-positions/issues/375)
>   * Gecko: [DOM State-preserving move (`Node.prototype.moveBefore`) mozilla/standards-positions#1053](https://github.com/mozilla/standards-positions/issues/1053)
> * [x]  [Tests](https://github.com/web-platform-tests/wpt) 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](https://github.com/whatwg/meta/blob/main/MAINTAINERS.md#handling-pull-requests) 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
> * [x]  [MDN issue](https://github.com/whatwg/meta/blob/main/MAINTAINERS.md#handling-pull-requests) is filed: I've added the impacts-documentation label, per https://github.com/whatwg/meta/blob/main/MAINTAINERS.md#handling-pull-requests
> * [x]  The top of this comment includes a [clear commit message](https://github.com/whatwg/meta/blob/main/COMMITTING.md) to use.
> 
> (See [WHATWG Working Mode: Changes](https://whatwg.org/working-mode#changes) for more details.)
> 
> [Preview](https://whatpr.org/dom/1307.html) | [Diff](https://whatpr.org/dom/1307/719e45b...4b54a0d.html)

Help

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

Message ID: <whatwg/dom/pull/1307/c2543856940@github.com>

Received on Sunday, 15 December 2024 12:36:35 UTC