-
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?
Conversation
|
||
<ol> | ||
<li><p>If the <span>form-associated element</span>'s <span>parser inserted flag</span> is set, | ||
then return.</p></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:
- During removal, that element gets its form owner reset because it hits the conditions in the "HTML element removing steps". This unsets the parser inserted bit. Next time that element gets inserted into the DOM, we'll reset the form owner again, always to the nearest form element.
- During removal, that element does not get its form owner reset. The parser-inserted bit remains set even though the element is disconnected. When it's inserted next, we trip the insertion condition "If the parser inserted flag is set", and we do not reset the form owner, ever.
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:
If the form-associated element has a form owner and the form-associated element and its form owner are no longer in the same tree, then reset the form owner of the form-associated element.
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:
- There's a bug in the current HTML element removing steps
- Removed form-associated elements with non-null form owners are always reset (during removal)
- We don't need the parser inserted condition in the HTML element moving steps
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.
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.
But removing makes an element disconnected, so I don't think it could ever be in the same tree as anything.
Why not? If both are a child of some element that gets removed, they're all in the same tree still. Just a tree that's disconnected. (We should probably stop using "same tree" though and instead always do root checks. That's clearer.)
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 don't think we should have this parser-inserted check here though. That's a legacy thing and the parser won't call move. So we can just always reset for moves.
@@ -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 comment
The 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 comment
The 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.
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 don't think you mentioned connectedMoveCallback everywhere connectedCallback is mentioned (and it's relevant).
- https://html.spec.whatwg.org/#custom-element-reactions
- https://html.spec.whatwg.org/#element-definition (this one seems especially important)
- It could do with some examples as well.
|
||
<ol> | ||
<li><p>If the <span>form-associated element</span>'s <span>parser inserted flag</span> is set, | ||
then return.</p></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.
But removing makes an element disconnected, so I don't think it could ever be in the same tree as anything.
Why not? If both are a child of some element that gets removed, they're all in the same tree still. Just a tree that's disconnected. (We should probably stop using "same tree" though and instead always do root checks. That's clearer.)
|
||
<ol> | ||
<li><p>If the <span>form-associated element</span>'s <span>parser inserted flag</span> is set, | ||
then return.</p></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 don't think we should have this parser-inserted check here though. That's a legacy thing and the parser won't call move. So we can just always reset for moves.
<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 |
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.
removedNode
<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> | ||
|
||
<li><p>When it is <span data-x="concept-node-adopt">adopted</span> into a new document, its <code |
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.
Indentation.
@@ -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: |
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.
Modern style:
<var>callback</var> is null, then: | |
<var>callback</var> is null: |
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.
Did we agree that this fallback behavior needs to be there? I'm still a bit skeptical I notice.
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.
Yes, we did discuss this. Some existing custom elements might have existing connectedCallback
logic that relies on checking hierarchy.
This PR is a supplementary PR to whatwg/dom#1307. It provides the HTML-overrides for the DOM Standard's "moving steps" extension, to allow pieces of the HTML Standard to react to atomic DOM moves without the use of the "insertion steps" or "removing steps", which by default, intentionally fail to preserve most state. The changes in this PR are inspired by the audit carried out in https://docs.google.com/document/d/1qfYyvdK4zhzloABKeh0K1lHPm-SpnEcsWEE9UdDuoMk/edit.
Node.prototype.moveBefore
) WebKit/standards-positions#375Node.prototype.moveBefore
) mozilla/standards-positions#1053(See WHATWG Working Mode: Changes for more details.)
💥 Error: Wattsi server error 💥
PR Preview failed to build. (Last tried on Nov 4, 2024, 1:08 PM UTC).
More
PR Preview relies on a number of web services to run. There seems to be an issue with the following one:
🚨 Wattsi Server - Wattsi Server is the web service used to build the WHATWG HTML spec.
🔗 Related URL
If you don't have enough information above to solve the error by yourself (or to understand to which web service the error is related to, if any), please file an issue.