-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
State-preserving atomic move integration #10657
base: main
Are you sure you want to change the base?
Changes from all commits
28cc642
8d41fc5
7107603
ea1dfd4
1339991
6f77c67
5bbf7c6
5fe636f
8f95485
1f1b3ff
412d6a3
bdf58da
b746a3d
f6e9fbe
b12ef4f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1773,8 +1773,9 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute | |
data-x="control">controls</span> or U+0020 SPACE).</p> | ||
|
||
<p>An HTML element can have specific <dfn>HTML element insertion steps</dfn>, <dfn>HTML element | ||
post-connection steps</dfn>, and <dfn>HTML element removing steps</dfn>, all defined for the | ||
element's <span data-x="concept-element-local-name">local name</span>.</p> | ||
post-connection steps</dfn>, <dfn>HTML element removing steps</dfn>, and <dfn>HTML element moving | ||
steps</dfn> all defined for the element's <span data-x="concept-element-local-name">local | ||
name</span>.</p> | ||
|
||
<p>The <span data-x="concept-node-insert-ext">insertion steps</span> for the HTML Standard, given | ||
<var>insertedNode</var>, are defined as the following:</p> | ||
|
@@ -1861,6 +1862,29 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute | |
popover algorithm</span> given <var>removedNode</var>, false, false, and false.</p></li> | ||
</ol> | ||
|
||
<p>The <span data-x="concept-node-move-ext">moving steps</span> for the HTML Standard, given | ||
<var>movedNode</var>, are defined as the following:</p> | ||
|
||
<ol> | ||
<li><p>If <var>movedNode</var> is an element whose <span | ||
data-x="concept-element-namespace">namespace</span> is the <span>HTML namespace</span>, and this | ||
standard defines <span>HTML element moving steps</span> for <var>movedNode</var>'s <span | ||
data-x="concept-element-local-name">local name</span>, then run the corresponding <span>HTML | ||
element moving steps</span> given <var>movedNode</var>.</p></li> | ||
|
||
<li> | ||
<p>If <var>movedNode</var> is a <span>form-associated element</span> or the ancestor of a | ||
<span>form-associated element</span>, then:</p> | ||
|
||
<ol> | ||
<li><p>If the <span>form-associated element</span>'s <span>parser inserted flag</span> is set, | ||
then return.</p></li> | ||
|
||
<li><p><span>Reset the form owner</span> of the <span>form-associated element</span>.</p></li> | ||
</ol> | ||
</li> | ||
</ol> | ||
|
||
<p>A <dfn id="insert-an-element-into-a-document" data-x="node is inserted into a document" | ||
data-lt="inserted into a document|node is inserted into a document" export>node is inserted into a | ||
document</dfn> when the <span data-x="concept-node-insert-ext">insertion steps</span> are invoked | ||
|
@@ -3218,6 +3242,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute | |
<li><dfn data-x="dom-Node-append" data-x-href="https://dom.spec.whatwg.org/#dom-node-append"><code>append()</code></dfn> method</li> | ||
<li><dfn data-x="dom-Node-appendChild" data-x-href="https://dom.spec.whatwg.org/#dom-node-appendchild"><code>appendChild()</code></dfn> method</li> | ||
<li><dfn data-x="dom-Node-cloneNode" data-x-href="https://dom.spec.whatwg.org/#dom-node-clonenode"><code>cloneNode()</code></dfn> method</li> | ||
<li><dfn data-x="dom-Node-moveBefore" data-x-href="https://dom.spec.whatwg.org/#dom-node-moveBefore"><code>moveBefore()</code></dfn> method</li> | ||
<li><dfn data-x="dom-Document-importNode" data-x-href="https://dom.spec.whatwg.org/#dom-document-importnode"><code>importNode()</code></dfn> method</li> | ||
<li><dfn data-x="dom-Event-preventDefault" data-x-href="https://dom.spec.whatwg.org/#dom-event-preventdefault"><code>preventDefault()</code></dfn> method</li> | ||
<li><dfn data-x="dom-Element-id" data-x-href="https://dom.spec.whatwg.org/#dom-element-id"><code>id</code></dfn> attribute</li> | ||
|
@@ -3257,6 +3282,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute | |
<li>The <dfn data-x="concept-node-insert-ext" data-x-href="https://dom.spec.whatwg.org/#concept-node-insert-ext">insertion steps</dfn>, | ||
<li>The <dfn data-x="concept-node-post-insert-ext" data-x-href="https://dom.spec.whatwg.org/#concept-node-post-connection-ext">post-connection steps</dfn>, | ||
<dfn data-x="concept-node-remove-ext" data-x-href="https://dom.spec.whatwg.org/#concept-node-remove-ext">removing steps</dfn>, | ||
<dfn data-x="concept-node-move-ext" data-x-href="https://dom.spec.whatwg.org/#concept-node-move-ext">moving steps</dfn>, | ||
<dfn data-x="concept-node-adopt-ext" data-x-href="https://dom.spec.whatwg.org/#concept-node-adopt-ext">adopting steps</dfn>, and | ||
<dfn data-x-href="https://dom.spec.whatwg.org/#concept-node-children-changed-ext">children changed steps</dfn> hooks for elements</li> | ||
<li>The <dfn data-x="concept-element-attributes-change" data-x-href="https://dom.spec.whatwg.org/#concept-element-attributes-change">change</dfn>, <dfn data-x="concept-element-attributes-append" data-x-href="https://dom.spec.whatwg.org/#concept-element-attributes-append">append</dfn>, <dfn data-x="concept-element-attributes-remove" data-x-href="https://dom.spec.whatwg.org/#concept-element-attributes-remove">remove</dfn>, <dfn data-x="concept-element-attributes-replace" data-x-href="https://dom.spec.whatwg.org/#concept-element-attributes-replace">replace</dfn>, <dfn data-x="concept-element-attributes-get-by-namespace" data-x-href="https://dom.spec.whatwg.org/#concept-element-attributes-get-by-namespace">get an attribute by namespace and local name</dfn>, <dfn data-x="concept-element-attributes-set-value" data-x-href="https://dom.spec.whatwg.org/#concept-element-attributes-set-value">set value</dfn>, and <dfn data-x="concept-element-attributes-remove-by-namespace" data-x-href="https://dom.spec.whatwg.org/#concept-element-attributes-remove-by-namespace">remove an attribute by namespace and local name</dfn> algorithms for attributes</li> | ||
|
@@ -29020,8 +29046,8 @@ interface <dfn interface>HTMLSourceElement</dfn> : <span>HTMLElement</span> { | |
|
||
<div w-nodev> | ||
|
||
<p>The <code>source</code> <span data-x="html element insertion steps">HTML element insertion | ||
steps</span>, given <var>insertedNode</var>, are:</p> | ||
<p>The <code>source</code> <span>HTML element insertion steps</span>, given | ||
<var>insertedNode</var>, are:</p> | ||
|
||
<ol> | ||
<li><p>If <var>insertedNode</var>'s parent is a <span>media element</span> that has no <code | ||
|
@@ -29036,8 +29062,17 @@ interface <dfn interface>HTMLSourceElement</dfn> : <span>HTMLElement</span> { | |
mutation</span> for the <code>img</code> element.</p></li> | ||
</ol> | ||
|
||
<p>The <code>source</code> <span data-x="html element removing steps">HTML element removing | ||
steps</span>, given <var>removedNode</var> and <var>oldParent</var>, are:</p> | ||
<p>The <code>source</code> <span>HTML element moving steps</span>, given <var>movedNode</var> and | ||
<var>oldParent</var>, are:</p> | ||
|
||
<ol> | ||
<li><p>If <var>movedNode</var>'s next sibling was an <code>img</code> element and | ||
<var>oldParent</var> is a <code>picture</code> element, then, count this as a <span | ||
data-x="relevant mutations">relevant mutation</span> for the <code>img</code> element.</p></li> | ||
</ol> | ||
|
||
<p>The <code>source</code> <span>HTML element removing steps</span>, given <var>removedNode</var> | ||
and <var>oldParent</var>, are:</p> | ||
|
||
<ol> | ||
<li><p>If <var>removedNode</var>'s next sibling was an <code>img</code> element and | ||
|
@@ -29297,17 +29332,25 @@ interface <dfn interface>HTMLImageElement</dfn> : <span>HTMLElement</span> { | |
page layout from shifting around after the image loads.</p> | ||
</div> | ||
|
||
<p>The <code>img</code> <span data-x="html element insertion steps">HTML element insertion | ||
steps</span>, given <var>insertedNode</var>, are:</p> | ||
<p>The <code>img</code> <span>HTML element insertion steps</span>, given <var>insertedNode</var>, | ||
are:</p> | ||
|
||
<ol> | ||
<li><p>If <var>insertedNode</var>'s parent is a <code>picture</code> element, then, count this as | ||
a <span data-x="relevant mutations">relevant mutation</span> for | ||
<var>insertedNode</var>.</p></li> | ||
</ol> | ||
|
||
<p>The <code>img</code> <span data-x="html element removing steps">HTML element removing | ||
steps</span>, given <var>removedNode</var> and <var>oldParent</var>, are:</p> | ||
<p>The <code>img</code> <span>HTML element moving steps</span>, given <var>movedNode</var> and | ||
<var>oldParent</var>, are:</p> | ||
|
||
<ol> | ||
<li><p>If <var>oldParent</var> is a <code>picture</code> element, then, count this as a | ||
<span data-x="relevant mutations">relevant mutation</span> for <var>movedNode</var>.</p></li> | ||
</ol> | ||
|
||
<p>The <code>img</code> <span>HTML element removing steps</span>, given <var>movedNode</var> and | ||
<var>oldParent</var>, are:</p> | ||
|
||
<ol> | ||
<li><p>If <var>oldParent</var> is a <code>picture</code> element, then, count this as a | ||
|
@@ -30807,9 +30850,9 @@ was an English <a href="/wiki/Music_hall">music hall</a> singer, ...</code | |
<li><p>The element's <code data-x="attr-img-referrerpolicy">referrerpolicy</code> attribute's | ||
state is changed.</p></li> | ||
|
||
<li><p>The <code>img</code> or <code>source</code> <span>HTML element insertion steps</span> or | ||
<span>HTML element removing steps</span> count the mutation as a <span data-x="relevant | ||
mutations">relevant mutation</span>.</p></li> | ||
<li><p>The <code>img</code> or <code>source</code> <span>HTML element insertion steps</span>, | ||
<span>HTML element removing steps</span>, and <span>HTML element moving steps</span> count the | ||
mutation as a <span data-x="relevant mutations">relevant mutation</span>.</p></li> | ||
|
||
<li><p>The element's parent is a <code>picture</code> element and a <code>source</code> element | ||
that is a previous sibling has its <code data-x="attr-source-srcset">srcset</code>, <code | ||
|
@@ -36418,13 +36461,15 @@ interface <dfn interface>MediaError</dfn> { | |
other node is the node after <var>pointer</var>. Initially, let <var>pointer</var> be the position between the <var>candidate</var> node and the | ||
next node, if there are any, or the end of the list, if it is the last node.</p> | ||
|
||
<p>As nodes are <span data-x="concept-node-insert-ext">inserted</span> and <span | ||
data-x="concept-node-remove-ext">removed</span> into the <span>media element</span>, | ||
<p>As nodes are <span data-x="concept-node-insert-ext">inserted</span>, <span | ||
data-x="concept-node-remove-ext">removed</span>, and <span | ||
data-x="concept-node-move-ext">moved</span> into the <span>media element</span>, | ||
<var>pointer</var> must be updated as follows:</p> | ||
|
||
<dl> | ||
<dt>If a new node is <span data-x="concept-node-insert-ext">inserted</span> between the two | ||
nodes that define <var>pointer</var></dt> | ||
<dt>If a new node is <span data-x="concept-node-insert-ext">inserted</span> or <span | ||
data-x="concept-node-move-ext">moved</span> between the two nodes that define | ||
<var>pointer</var></dt> | ||
|
||
<dd>Let <var>pointer</var> be the point between the node before <var>pointer</var> and the new node. In other words, insertions at <var>pointer</var> go after <var>pointer</var>.</dd> | ||
|
||
|
@@ -53462,6 +53507,17 @@ interface <dfn interface>HTMLSelectElement</dfn> : <span>HTMLElement</span> { | |
<code>select</code> element's <span>selectedness setting algorithm</span>.</p></li> | ||
</ol> | ||
|
||
<p>The <code>option</code> <span>HTML element moving steps</span>, given <var>movedNode</var> and | ||
<var>oldParent</var>, are:</p> | ||
|
||
<ol> | ||
<li><p>Run the <code>option</code> <span>HTML element removing steps</span> given | ||
<var>movedNode</var> and <var>oldParent</var>.</p></li> | ||
|
||
<li><p>Run the <code>option</code> <span>HTML element insertion steps</span> given | ||
<var>movedNode</var>.</p></li> | ||
</ol> | ||
|
||
<p>The <code>optgroup</code> <span data-x="html element removing steps">HTML element removing | ||
steps</span>, given <var>removedNode</var> and <var>oldParent</var>, are:</p> | ||
|
||
|
@@ -53471,6 +53527,14 @@ interface <dfn interface>HTMLSelectElement</dfn> : <span>HTMLElement</span> { | |
algorithm</span>.</p></li> | ||
</ol> | ||
|
||
<p>The <code>optgroup</code> <span>HTML element moving steps</span>, given <var>movedNode</var> | ||
and <var>oldParent</var>, are:</p> | ||
|
||
<ol> | ||
<li><p>Run the <code>optgroup</code> <span>HTML element removing steps</span> given | ||
<var>movedNode</var> and <var>oldParent</var>.</p></li> | ||
</ol> | ||
|
||
<p>If an <code>option</code> element in the <span data-x="concept-select-option-list">list of | ||
options</span> <dfn data-x="ask for a reset">asks for a reset</dfn>, then run that | ||
<code>select</code> element's <span>selectedness setting algorithm</span>.</p> | ||
|
@@ -55970,12 +56034,11 @@ interface <dfn interface>HTMLLegendElement</dfn> : <span>HTMLElement</span> { | |
<code data-x="attr-fae-form">form</code> attribute and an element with an <span | ||
data-x="concept-id">ID</span> is <span data-x="node is inserted into a document">inserted | ||
into</span> or <span data-x="node is removed from a document">removed from</span> the | ||
<code>Document</code>, then the user agent must <span>reset the form owner</span> of that | ||
<span>form-associated element</span>.</p> | ||
<code>Document</code>, or its <span>HTML element moving steps</span> are run, then the user agent | ||
must <span>reset the form owner</span> of that <span>form-associated element</span>.</p> | ||
|
||
<p class="note">The form owner is also reset by the HTML Standard's <span | ||
data-x="concept-node-insert-ext">insertion steps</span> and <span | ||
data-x="concept-node-remove-ext">removing steps</span>.</p> | ||
<p class="note">The form owner is also reset by the <span>HTML element insertion steps</span>, | ||
<span>HTML element removing steps</span>, and <span>HTML element moving steps</span>.</p> | ||
|
||
<p>To <dfn>reset the form owner</dfn> of a <span>form-associated element</span> | ||
<var>element</var>:</p> | ||
|
@@ -72128,6 +72191,7 @@ document.body.append(parent); | |
data-x="concept-custom-element-definition-lifecycle-callbacks">lifecycle callbacks</dfn></dt> | ||
<dd>A map, whose keys are the strings "<code data-x="">connectedCallback</code>", | ||
"<code data-x="">disconnectedCallback</code>", "<code data-x="">adoptedCallback</code>", | ||
"<code data-x="">connectedMoveCallback</code>", | ||
"<code data-x="">attributeChangedCallback</code>", | ||
"<code data-x="">formAssociatedCallback</code>", | ||
"<code data-x="">formDisabledCallback</code>", | ||
|
@@ -72810,7 +72874,10 @@ customElements.define("x-foo", class extends HTMLElement { | |
<li><p>When it <span>becomes disconnected</span>, its <code data-x="">disconnectedCallback</code> | ||
is called, with no arguments.</p></li> | ||
|
||
<li><p>When it is <span data-x="concept-node-adopt">adopted</span> into a new document, its <code | ||
<li><p>When it is <span data-x="concept-node-move-ext">moved</span>, its <code | ||
data-x="">connectedMoveCallback</code> is called, with no arguments.</p></li> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't callback get the old subtree owner as an argument, so that one can know easily where one was. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This would require holding a reference to the old tree which might be gone by the time the CE callbacks are fired. Perhaps we can consider this as a future enhancement? I think we should be able to do that in a compatible way. |
||
|
||
<li><p>When it is <span data-x="concept-node-adopt">adopted</span> into a new document, its <code | ||
data-x="">adoptedCallback</code> is called, given the old document and new document as | ||
arguments.</p></li> | ||
|
||
|
@@ -72952,6 +73019,35 @@ customElements.define("x-foo", class extends HTMLElement { | |
data-x="concept-custom-element-definition-lifecycle-callbacks">lifecycle callbacks</span> with | ||
key <var>callbackName</var>.</p></li> | ||
|
||
<li> | ||
<p>If <var>callbackName</var> is "<code data-x="">connectedMoveCallback</code>" and | ||
<var>callback</var> is null, then: | ||
|
||
<ol> | ||
<li><p>Let <var>disconnectedCallback</var> be the value of the entry in <var>definition</var>'s | ||
<span data-x="concept-custom-element-definition-lifecycle-callbacks">lifecycle callbacks</span> | ||
with key "<code data-x="">disconnectedCallback</code>".</p></li> | ||
|
||
<li><p>Let <var>connectedCallback</var> be the value of the entry in <var>definition</var>'s | ||
<span data-x="concept-custom-element-definition-lifecycle-callbacks">lifecycle callbacks</span> | ||
with key "<code data-x="">connectedCallback</code>".</p></li> | ||
|
||
<li><p>If <var>connectedCallback</var> and <var>disconnectedCallback</var> are null, then | ||
return.</p></li> | ||
|
||
<li> | ||
<p>Set <var>callback</var> to the following steps:</p> | ||
<ol> | ||
<li><p>If <var>disconnectedCallback</var> is not null, then call | ||
<var>disconnectedCallback</var> with no arguments.</p></li> | ||
|
||
<li><p>If <var>connectedCallback</var> is not null, then call | ||
<var>connectedCallback</var> with no arguments.</p></li> | ||
</ol> | ||
</li> | ||
</ol> | ||
</li> | ||
|
||
<li><p>If <var>callback</var> is null, then return.</p></li> | ||
|
||
<li> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this special case is here because something similar happens currently when removing and adding such element back?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See the first row in https://docs.google.com/document/d/1qfYyvdK4zhzloABKeh0K1lHPm-SpnEcsWEE9UdDuoMk/edit?tab=t.0 for this in general.
However regarding this condition specifically, if I remember correctly it was just copied from the insertion steps to preserve the behavior of remove+insert during a move. Looking at it again, I'm unsure how this is supposed to work though.
Imagine a form-associated element with a form owner being removed from the DOM. There are two cases:
It isn't clear to me when (2) above can ever happen. That is, when during removal will we not "reset the form owner" of a form-associated element that has a non-null form owner? The condition reads:
So it seems that (during removal) we'd avoid resetting the owner if the element is still in the same tree as its form owner. But removing makes an element disconnected, so I don't think it could ever be in the same tree as anything. I'm left to think that:
If I am wrong about (1)/(2) in the immediately-above list, then we may still need the parser inserted condition in the moving steps.
I don't know much about forms and their associated mechanics but I feel like @zcorpan does and would maybe be willing to take a look here.