Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce moveBefore() state-preserving atomic move API #1307

Open
wants to merge 31 commits into
base: main
Choose a base branch
from
Open
Changes from 6 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
d45ca59
Initial atomic move skeleton
domfarolino Aug 19, 2024
98a70d5
Most of the `MutationObserver` integration
domfarolino Aug 26, 2024
93c2a53
Remove mutation events flag references
domfarolino Aug 26, 2024
1b2ec1c
Populate the `MutationRecord`
domfarolino Aug 26, 2024
30ded0c
Fix punctuation
domfarolino Aug 26, 2024
2811119
Remove trailing whitespace
domfarolino Aug 26, 2024
c659978
`<span>` -> `<a>` plus fix punctuation error
domfarolino Aug 27, 2024
ad05126
Camel case
domfarolino Aug 27, 2024
fbbde69
Throw an exception on failure
domfarolino Sep 24, 2024
b7b71bc
Introduce move primitive + moving steps hook/extension
domfarolino Sep 30, 2024
487a925
Remove changes to insertion primitive
domfarolino Oct 10, 2024
5127374
Revert document flag and mutation record changes
domfarolino Oct 10, 2024
2f132c1
Fix mutation record callsites
domfarolino Oct 10, 2024
f254047
Fix wrapping
domfarolino Oct 10, 2024
fe139ab
Remove suppress observers flag
domfarolino Oct 10, 2024
43578ce
Custom element integration
domfarolino Oct 10, 2024
1d4bb01
Update live ranges and NodeIterators properly; do not call the remove…
domfarolino Oct 10, 2024
696e0fe
Correct removal bookkeeping
domfarolino Oct 10, 2024
a9d54c5
Moving steps prose
domfarolino Oct 15, 2024
caab6e1
Tighten up pre-move checks
domfarolino Oct 15, 2024
a9bd9a8
Assert -> throw condition
domfarolino Oct 15, 2024
9ecae6f
Move conditions into pre-move validity
domfarolino Oct 15, 2024
35a75be
Fix `<old>`
domfarolino Oct 15, 2024
906d710
Ordering and format
domfarolino Oct 16, 2024
8d24d3b
Fix live range updating logic
domfarolino Nov 7, 2024
8b111ad
Document `move` primitive in Range note
domfarolino Nov 7, 2024
6572970
Enable moves in a connected `ShadowRoot` `DocumentFragment` node
domfarolino Nov 11, 2024
12b9ded
Do not explicitly rethrow
domfarolino Nov 13, 2024
29e2ac3
Do not do special range handling
domfarolino Nov 19, 2024
2bbc834
Support both connected->connected and disconnected->disconnected
domfarolino Nov 20, 2024
03d5b58
Whitespace and formatting
domfarolino Nov 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 88 additions & 19 deletions dom.bs
Original file line number Diff line number Diff line change
Expand Up @@ -2729,6 +2729,9 @@ before a <var>child</var>, with an optional <i>suppress observers flag</i>, run
<li><p>Let <var>nodes</var> be <var>node</var>'s <a for=tree>children</a>, if <var>node</var> is a
{{DocumentFragment}} <a for=/>node</a>; otherwise « <var>node</var> ».

<li><p>Let <var>state-preserving atomic move in progress</var> be <var>parent</var>'s
domfarolino marked this conversation as resolved.
Show resolved Hide resolved
<a for=Node>node document</a> <span>state-preserving atomic move in progress</span>.
domfarolino marked this conversation as resolved.
Show resolved Hide resolved

<li><p>Let <var>count</var> be <var>nodes</var>'s <a for=set>size</a>.

<li><p>If <var>count</var> is 0, then return.
Expand All @@ -2737,12 +2740,14 @@ before a <var>child</var>, with an optional <i>suppress observers flag</i>, run
<p>If <var>node</var> is a {{DocumentFragment}} <a for=/>node</a>, then:

<ol>
<li><p><span>Assert</span>: <var>state-preserving atomic move in progress</var> is false.

<li><p><a for=/>Remove</a> its <a for=tree>children</a> with the <i>suppress observers flag</i>
set.

<li>
<p><a>Queue a tree mutation record</a> for <var>node</var> with « », <var>nodes</var>, null, and
null.
<p><a>Queue a tree mutation record</a> for <var>node</var> with « », <var>nodes</var>, « »,
null, and null.

<p class=note>This step intentionally does not pay attention to the
<i>suppress observers flag</i>.
Expand Down Expand Up @@ -2814,8 +2819,24 @@ before a <var>child</var>, with an optional <i>suppress observers flag</i>, run
</li>
</ol>

<li><p>If <i>suppress observers flag</i> is unset, then <a>queue a tree mutation record</a> for
<var>parent</var> with <var>nodes</var>, « », <var>previousSibling</var>, and <var>child</var>.
<li>
<p>If <i>suppress observers flag</i> is unset, then:

<ol>
<li>
<p>If <var>state-preserving atomic move in progress</var>, then
<a>queue a tree mutation record</a> for <var>parent</var> with « », « », <var>nodes</var>,
<var>previousSibling</var>, and <var>child</var>.</p>

<p class="note">This exposes <var>nodes</var> in the corresponding
{{MutationRecord/movedNodes}}.</p>
</li>

<li><p>If <var>state-preserving atomic move in progress</var>, then
<a>queue a tree mutation record</a> for <var>parent</var> with <var>nodes</var>, « », « »,
<var>previousSibling</var>, and <var>child</var>.</p></li>
</ol>
</li>

<li><p>Run the <a>children changed steps</a> for <var>parent</var>.

Expand Down Expand Up @@ -2929,7 +2950,7 @@ within a <var>parent</var>, run these steps:
with the <i>suppress observers flag</i> set.

<li><p><a>Queue a tree mutation record</a> for <var>parent</var> with <var>nodes</var>,
<var>removedNodes</var>, <var>previousSibling</var>, and <var>referenceChild</var>.
<var>removedNodes</var>, « », <var>previousSibling</var>, and <var>referenceChild</var>.

<li><p>Return <var>child</var>.
</ol>
Expand All @@ -2956,7 +2977,7 @@ within a <var>parent</var>, run these steps:

<li><p>If either <var>addedNodes</var> or <var>removedNodes</var> <a for=set>is not empty</a>,
then <a>queue a tree mutation record</a> for <var>parent</var> with <var>addedNodes</var>,
<var>removedNodes</var>, null, and null.
<var>removedNodes</var>, « », null, and null.
</ol>

<p class=note>This algorithm does not make any checks with regards to the
Expand Down Expand Up @@ -3072,7 +3093,7 @@ optional <i>suppress observers flag</i>, run these steps:
<a>registered observer list</a>.

<li><p>If <i>suppress observers flag</i> is unset, then <a>queue a tree mutation record</a> for
<var>parent</var> with « », « <var>node</var> », <var>oldPreviousSibling</var>, and
<var>parent</var> with « », « <var>node</var> », « », <var>oldPreviousSibling</var>, and
<var>oldNextSibling</var>.

<li><p>Run the <a>children changed steps</a> for <var>parent</var>.
Expand Down Expand Up @@ -3888,9 +3909,14 @@ method steps are:

<h4 id=queueing-a-mutation-record>Queuing a mutation record</h4>

<!-- TODO(domfarolino): REMOVE THIS BEFORE MERGING. This is needed for the build to work, until this
term actually appears in HTML -->
<dfn>state-preserving atomic move in progress</dfn>

<p>To <dfn noexport>queue a mutation record</dfn> of <var>type</var> for <var>target</var> with
<var>name</var>, <var>namespace</var>, <var>oldValue</var>, <var>addedNodes</var>,
<var>removedNodes</var>, <var>previousSibling</var>, and <var>nextSibling</var>, run these steps:
<var>removedNodes</var>, <var>movedNodes</var>, <var>previousSibling</var>, and
<var>nextSibling</var>, run these steps:

<ol>
<li><p>Let <var>interestedObservers</var> be an empty <a for=/>map</a>.
Expand Down Expand Up @@ -3955,9 +3981,9 @@ method steps are:
{{MutationRecord/attributeName}} set to <var>name</var>, {{MutationRecord/attributeNamespace}}
set to <var>namespace</var>, {{MutationRecord/oldValue}} set to <var>mappedOldValue</var>,
{{MutationRecord/addedNodes}} set to <var>addedNodes</var>,
{{MutationRecord/removedNodes}} set to <var>removedNodes</var>,
{{MutationRecord/previousSibling}} set to <var>previousSibling</var>, and
{{MutationRecord/nextSibling}} set to <var>nextSibling</var>.
{{MutationRecord/removedNodes}} set to <var>removedNodes</var>, {{MutationRecord/movedNodes}} set
to <var>movedNodes</var>, {{MutationRecord/previousSibling}} set to <var>previousSibling</var>,
and {{MutationRecord/nextSibling}} set to <var>nextSibling</var>.

<li><p><a for=queue>Enqueue</a> <var>record</var> to <var>observer</var>'s
<a for=MutationObserver>record queue</a>.
Expand All @@ -3970,15 +3996,28 @@ method steps are:
</ol>

<p>To <dfn noexport>queue a tree mutation record</dfn> for <var>target</var> with
<var>addedNodes</var>, <var>removedNodes</var>, <var>previousSibling</var>, and
<var>nextSibling</var>, run these steps:
<var>addedNodes</var>, <var>removedNodes</var>, <var>movedNodes</var>, <var>previousSibling</var>,
and <var>nextSibling</var>, run these steps:

<ol>
<li><p>Assert: either <var>addedNodes</var> or <var>removedNodes</var> <a for=set>is not empty</a>.
<li>
<p><span>Assert</span>: one of the following conditions is true:</p>

<ol>
<li><p><var>target</var>'s <a for=Node>node document</a>'s
<span>state-preserving atomic move in progress</span>s false, and either <var>addedNodes</var> or
<var>removedNodes</var> <a for=set>is not empty</a>; or</p></li>

<li><p><var>target</var>'s <a for=Node>node document</a>'s
<span>state-preserving atomic move in progress</span>s true, and both <var>addedNodes</var> and
<var>removedNodes</var> are <a for=set>empty</a>, and <var>movedNodes</var>
<a for=set>is not empty</a></p></li>
</ol>
</li>

<li><p><a>Queue a mutation record</a> of "<code>childList</code>" for <var>target</var> with
null, null, null, <var>addedNodes</var>, <var>removedNodes</var>, <var>previousSibling</var>,
and <var>nextSibling</var>.
null, null, null, <var>addedNodes</var>, <var>removedNodes</var>, <var>movedNodes</var>,
<var>previousSibling</var>, and <var>nextSibling</var>.
</ol>


Expand All @@ -3991,6 +4030,7 @@ interface MutationRecord {
[SameObject] readonly attribute Node target;
[SameObject] readonly attribute NodeList addedNodes;
[SameObject] readonly attribute NodeList removedNodes;
[SameObject] readonly attribute NodeList movedNodes;
readonly attribute Node? previousSibling;
readonly attribute Node? nextSibling;
readonly attribute DOMString? attributeName;
Expand Down Expand Up @@ -4025,6 +4065,10 @@ interface MutationRecord {
<dd>Return the <a for=/>nodes</a> added and removed
respectively.

<dt><code><var>record</var> . {{MutationRecord/movedNodes}}</code>
<dd>Return the <a for=/>nodes</a> that were moved when a
<a lt="state-preserving atomic move in progress">state-preserving atomic move was in progress</a>.

<dt><code><var>record</var> . {{MutationRecord/previousSibling}}</code>
<dt><code><var>record</var> . {{MutationRecord/nextSibling}}</code>
<dd>Return the <a lt="previous sibling">previous</a> and <a for=tree>next sibling</a> respectively
Expand All @@ -4051,6 +4095,7 @@ interface MutationRecord {
<p>The <dfn attribute for=MutationRecord>type</dfn>, <dfn attribute for=MutationRecord>target</dfn>,
<dfn attribute for="MutationRecord">addedNodes</dfn>,
<dfn attribute for="MutationRecord">removedNodes</dfn>,
<dfn attribute for="MutationRecord">movedNodes</dfn>,
<dfn attribute for="MutationRecord">previousSibling</dfn>,
<dfn attribute for="MutationRecord">nextSibling</dfn>,
<dfn attribute for="MutationRecord">attributeName</dfn>,
Expand Down Expand Up @@ -4118,6 +4163,8 @@ interface Node : EventTarget {
[CEReactions] Node appendChild(Node node);
[CEReactions] Node replaceChild(Node node, Node child);
[CEReactions] Node removeChild(Node child);

[CEReactions] Node moveBefore(Node node, Node? child);
};

dictionary GetRootNodeOptions {
Expand Down Expand Up @@ -4986,6 +5033,27 @@ within <a>this</a>.
<p>The <dfn method for=Node><code>removeChild(<var>child</var>)</code></dfn> method steps are to
return the result of <a>pre-removing</a> <var>child</var> from <a>this</a>.

<p>The <dfn method for=Node><code>moveBefore(<var>node</var>, <var>child</var>)</code></dfn>
method steps are:

<ol>
<li><p>Let <var>perform state-preserving atomic move</var> be true if <a>this</a> is
<a>connected</a>, <var>node</var> is <a>connected</a>, <a>this</a>'s <a for=Node>node
document</a> is <a>fully active</a>, and <a>this</a>'s <a for=/>root</a> is the same as
<var>node</var>'s <a for=/>root</a>.</p></li>.
domfarolino marked this conversation as resolved.
Show resolved Hide resolved

<li><p>If <var>perform state-preserving atomic move</var> is true, then set <a>this</a>'s <a
for=Node>node document</a>'s <a>state-preserving atomic move in progress</a> to true.</p></li>

<li><p>Let <var>return node</var> be the result of <a>pre-inserting</a> <var>node</var> into
<a>this</a> before <var>child</var>.</p></li>
domfarolino marked this conversation as resolved.
Show resolved Hide resolved

<li><p>Set <a>this</a>'s <a for=Node>node document</a>'s
<a>state-preserving atomic move in progress</a> to false.</p></li>

<li><p>Return <var>return node</var>.</p></li>
</ol>

<hr><!-- Collections -->

<p>The
Expand Down Expand Up @@ -5577,7 +5645,8 @@ these steps:
<li><p>Let <var>oldDocument</var> be <var>node</var>'s <a for=Node>node document</a>.

<li><p>If <var>node</var>'s <a for=tree>parent</a> is non-null, then <a for=/>remove</a>
<var>node</var>.
<var>node</var> with the <i>suppress observers flag</i> set if <var>document</var>'s
<span>state-preserving atomic move in progress</span> is true, and unset otherwise.

<li>
<p>If <var>document</var> is not <var>oldDocument</var>, then:
Expand Down Expand Up @@ -6467,7 +6536,7 @@ given a <var>document</var>, <var>localName</var>, <var>namespace</var>, and opt
<ol>
<li><p><a>Queue a mutation record</a> of "<code>attributes</code>" for <var>element</var> with
<var>attribute</var>'s <a for=Attr>local name</a>, <var>attribute</var>'s
<a for=Attr>namespace</a>, <var>oldValue</var>, « », « », null, and null.
<a for=Attr>namespace</a>, <var>oldValue</var>, « », « », « », null, and null.

<li><p>If <var>element</var> is <a for=Element>custom</a>, then
<a>enqueue a custom element callback reaction</a> with <var>element</var>, callback name
Expand Down Expand Up @@ -7513,7 +7582,7 @@ string called <dfn export id=concept-cd-data for=CharacterData>data</dfn>.
<var>count</var> to <var>length</var> minus <var>offset</var>.

<li><p><a>Queue a mutation record</a> of "<code>characterData</code>" for <var>node</var> with
null, null, <var>node</var>'s <a for=CharacterData>data</a>, « », « », null, and null.
null, null, <var>node</var>'s <a for=CharacterData>data</a>, « », « », « », null, and null.

<li>Insert <var>data</var> into <var>node</var>'s
<a for=CharacterData>data</a> after <var>offset</var>
Expand Down
Loading