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

Add Imperative Slot API #5483

Closed
wants to merge 15 commits into from
Closed

Add Imperative Slot API #5483

wants to merge 15 commits into from

Conversation

yuzhe-han
Copy link

@yuzhe-han yuzhe-han commented Apr 24, 2020

The explainer for this feature is here: https://github.com/w3c/webcomponents/blob/gh-pages/proposals/Imperative-Shadow-DOM-Distribution-API.md
The issue discussion is here: 3534
There is a corresponding Pull Request for the DOM spec that goes along with this PR.


/acknowledgements.html ( diff )
/infrastructure.html ( diff )
/scripting.html ( diff )

source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
@yuzhe-han yuzhe-han mentioned this pull request Apr 24, 2020
3 tasks
@yuzhe-han yuzhe-han requested a review from annevk April 29, 2020 16:34
@annevk
Copy link
Member

annevk commented Apr 30, 2020

As far as I know you want to track which nodes are manually assigned. You need some infrastructure for that which isn't provided/hooked into here.

@annevk annevk added the topic: shadow Relates to shadow trees (as defined in DOM) label Apr 30, 2020
@yuzhe-han
Copy link
Author

@annevk,

I updated the spec to include manuallyAssignedNodes concept.
I also fetched from whatwg:master to update my branch and rebased my changes, not sure if that's advised since the rebase modified the reviews you did earlier.

Please take a look, Thanks.

source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
@yuzhe-han
Copy link
Author

Thanks for reviewing. I've updated the spec based on feedback.

source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
source Outdated
<span>shadow root</span>'s <span>slot assignment</span> is not "manual", then throw <span>"<code>NotAllowedError</code>"</span>
<code>DOMException</code>.</p></li>

<li><p>For each <var>node</var> in <var>nodes</var>: if <var>node</var> is not a <span data-x="concept-tree-child">child</span>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if I change this after assignment? Per the current set of algorithms it seems like it would still be assigned, despite no longer being a child of the host. Is that correct?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. The algorithms in corresponding DOM spec PR doesn't update manually assigned nodes when an assigned node or a slot is removed.

I looked at the #concept-node-remove to see how when "slot assignment' auto is handled.
Step 11 and 12 takes care of the assigned node case[1]. And step 14 takes care of the case[2] if the removed node is a slot or it contains a slot descendant.

So in theory, when "slot assignment" manual, it can use the same algorithm to make sure that slottables at the 3 of #assign-slotables are set back to manually assigned nodes. Thus, I updated the corresponding DOM spec to keep slot's assigned nodes and manually assigned nodes in sync.

Hopefully, this works. I also looked at the possibility of clearing out the manually assigned nodes during #concept-node-remove, but decided to go with a similar path for auto assignment.

@annevk
Copy link
Member

annevk commented Jul 6, 2020

I wonder if it wouldn't be easier if instead the children of a host had a reference to null or a slot. Then whenever you need the "assigned slottables" of a slot you can go through those children and if you need to update anything you can go through those children rather than traversing the entire shadow tree looking for slots. And if you compute the "assigned slottables" lazily I guess you only need to care for mutations to the host's children, potentially simplifying the changes in DOM.

cc @smaug---- @rniwa

@smaug----
Copy link

had a reference to null or a slot.

Current DOM's https://dom.spec.whatwg.org/#find-a-slot is going through the tree.
(Though Gecko does keep element->slot reference to have fast access)

@yuzhe-han
Copy link
Author

Anne@,
Thanks for your suggestion. I think for children of a host to have a reference to either null or slot makes sense. I send you an email for some clarification on how to best move forward.

Thanks.

@rniwa
Copy link

rniwa commented Aug 5, 2020

FWIW, what's being proposed here seems fine.

Copy link
Member

@annevk annevk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is good now, except for the nits. It does seem as defined assign() is quite expensive, but also has lots of room for optimizations.

source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
@yuzhe-han
Copy link
Author

@annevk,

Thanks for reviewing.
If it makes it easier, I can be available for reviewing this together.

Thanks.

source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
@yuzhe-han yuzhe-han requested a review from annevk November 12, 2020 03:58
source Outdated Show resolved Hide resolved
source Show resolved Hide resolved
source Outdated Show resolved Hide resolved
@yuzhe-han yuzhe-han requested a review from annevk January 12, 2021 00:17
@annevk
Copy link
Member

annevk commented Jan 13, 2021

@domenic @rniwa can either of you give this and the DOM PR at whatwg/dom#860 a review? I have some nits that I can address, but I'm worried about losing the plot given the amount of time that has passed.

Base automatically changed from master to main January 15, 2021 07:57
@annevk annevk removed their assignment Feb 22, 2021
@annevk annevk requested review from domenic and rniwa February 22, 2021 10:17
Copy link
Member

@domenic domenic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed some tweaks. The only one of substance is that I made it explicit that you loop through descendants in tree order when removing them. I imagine the order might be observable using mutation observers?

I also tidied some nearby method definitions and IDL stuff to conform to modern conventions.

The HTML side of this seems relatively simple, so next up is the DOM side...

@domenic
Copy link
Member

domenic commented Feb 23, 2021

Hmm, I also changed "manually assigned nodes" from a set to a list, because I didn't see any protection against el.assign(node, node). Is that change OK, @yuzhe-han?

@yuzhe-han
Copy link
Author

@domenic,
Thanks for your clean up on this PR.
Your change from a set to a list look correct to me.

@domenic
Copy link
Member

domenic commented Feb 23, 2021

OK, cool. So there's no problem with the algorithms if the same node appears twice in the manually assigned nodes list? Do we have test cases for the behavior in that scenario?

</ol>
</li>

<li><p>Set <span>this</span>'s <span>manually assigned nodes</span> to <var>nodes</var>.</p></li>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't quite right. We need to remove duplicates from the manually assigned nodes since "find slottables" in https://github.com/whatwg/dom/pull/860/files doesn't remove duplicates either.

Copy link
Member

@domenic domenic Feb 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, that seems more correct to me, and seems to match the implementation in Chromium. https://source.chromium.org/chromium/chromium/src/+/master:third_party/blink/renderer/core/html/html_slot_element.cc;l=187;drc=510d6b8791a0e20c3470f9c0fcf1472d1bb71995

I will update the PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems slightly cleaner to make the set during the first iteration to avoid redundant descendant searches, but I think it should not be observable...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree here that we should unique the list here. The Chromium implementation also has some logic around ordering in the case of duplicates, which I think makes sense. I'll try to write that up here. domenic@, you mentioned you'd update the PR, that didn't happen, right? Just making sure I don't step on a change for that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did update the PR; see commit fdc36ca

<p>The <code>slot</code> element has <dfn export for="HTMLSlotElement">manually assigned
nodes</dfn>, which is an <span data-x="set">ordered set</span> of <span
data-x="slottable">slottables</span> set by <code data-x="dom-slot-assign">assign()</code>. It is
initially empty.</p>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we move this up? Usually we describe "slots" before public members.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved this up above the assignedNodes method steps. Let me know if that's what you were requesting here.

</ol>
</li>

<li><p>Set <span>this</span>'s <span>manually assigned nodes</span> to <var>nodes</var>.</p></li>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems slightly cleaner to make the set during the first iteration to avoid redundant descendant searches, but I think it should not be observable...

@domenic domenic added the agenda+ To be discussed at a triage meeting label Mar 3, 2021
@mfreed7 mfreed7 mentioned this pull request Apr 2, 2021
3 tasks
<li><p><span data-x="list iterate">For each</span> <var>node</var> of <var>nodes</var>: if
<var>node</var> is not a <span data-x="concept-tree-child">child</span> of <span>this</span>'s
<span>root</span>'s <span>shadow host</span>, then throw a
<span>"<code>NotAllowedError</code>"</span> <code>DOMException</code>.</p></li>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to leave this whole thing here - it seems reasonable to me to throw an exception if, at assign() call time, the provided children aren't in the right place. If they're later removed from the shadow host, we will just pretend they're not there. If they're ever put back, we'll start using them again. But I don't know what the use case would be for assigning nodes that aren't present yet (perhaps not even in the same document). Does that sound ok?

For this reason, I don't think there are any changes needed to this PR to incorporate the proposed changes.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm... what if you wanted to assign nodes then add them as children of the shadow host? The one of main use cases of manual assignment is so that custom element can have JS API which accepts a list of nodes to use, right? In that scenario, it's possible for the users of a custom element to create a bunch of nodes, call JS API, then add them as children of the host instead of adding them first and then giving them to the JS API. At least, that was one of the use cases that came up during accessibility related discussion in the past which motivated the current design.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's a good point. Ok, sounds like we should probably remove the second <li> here that throws an exception if node isn't a child of the shadow host. I'll leave the first check that the <slot> is within a shadow root and that it is in manual mode.

mfreed7 added a commit to mfreed7/html that referenced this pull request Apr 6, 2021
@mfreed7 mfreed7 mentioned this pull request Apr 6, 2021
3 tasks
Copy link
Contributor

@mfreed7 mfreed7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've opened another PR for this, with the changes requested: #6561

<li><p><span data-x="list iterate">For each</span> <var>node</var> of <var>nodes</var>: if
<var>node</var> is not a <span data-x="concept-tree-child">child</span> of <span>this</span>'s
<span>root</span>'s <span>shadow host</span>, then throw a
<span>"<code>NotAllowedError</code>"</span> <code>DOMException</code>.</p></li>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's a good point. Ok, sounds like we should probably remove the second <li> here that throws an exception if node isn't a child of the shadow host. I'll leave the first check that the <slot> is within a shadow root and that it is in manual mode.

</ol>
</li>

<li><p>Set <span>this</span>'s <span>manually assigned nodes</span> to <var>nodes</var>.</p></li>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree here that we should unique the list here. The Chromium implementation also has some logic around ordering in the case of duplicates, which I think makes sense. I'll try to write that up here. domenic@, you mentioned you'd update the PR, that didn't happen, right? Just making sure I don't step on a change for that.

<p>The <code>slot</code> element has <dfn export for="HTMLSlotElement">manually assigned
nodes</dfn>, which is an <span data-x="set">ordered set</span> of <span
data-x="slottable">slottables</span> set by <code data-x="dom-slot-assign">assign()</code>. It is
initially empty.</p>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved this up above the assignedNodes method steps. Let me know if that's what you were requesting here.

@domenic domenic closed this in 24a6d00 Apr 14, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
agenda+ To be discussed at a triage meeting topic: shadow Relates to shadow trees (as defined in DOM)
Development

Successfully merging this pull request may close these issues.

8 participants