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 #966

Merged
merged 8 commits into from
Apr 15, 2021
Merged

Add Imperative Slot API #966

merged 8 commits into from
Apr 15, 2021

Conversation

mfreed7
Copy link
Contributor

@mfreed7 mfreed7 commented Apr 2, 2021

This is a fresh PR, with updates from #860. I don't have permissions to update that PR, and the master-to-main transition made it difficult anyway.

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 HTML spec that goes along with this PR.


💥 Error: 500 Internal Server Error 💥

PR Preview failed to build. (Last tried on Apr 15, 2021, 7:24 AM UTC).

More

PR Preview relies on a number of web services to run. There seems to be an issue with the following one:

🚨 HTML Diff Service - The HTML Diff Service is used to create HTML diffs of the spec changes suggested in a pull request.

🔗 Related URL

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>500 Internal Server Error</title>
</head><body>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error or
misconfiguration and was unable to complete
your request.</p>
<p>Please contact the server administrator at 
 sysreq@w3.org to inform them of the time this error occurred,
 and the actions you performed just before this error.</p>
<p>More information about this error may be available
in the server error log.</p>
</body></html>

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.

dom.bs Outdated Show resolved Hide resolved
dom.bs Outdated Show resolved Hide resolved
@mfreed7 mfreed7 mentioned this pull request Apr 6, 2021
3 tasks
dom.bs Outdated Show resolved Hide resolved
dom.bs Outdated Show resolved Hide resolved
dom.bs Outdated Show resolved Hide resolved
Copy link
Contributor Author

@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.

Ok, this should be updated with the new "weak pointer in both directions" logic. The intention was:

  • you can call slot.assign() at any time with any nodes, regardless of where the nodes or the slot lives at the time.
  • Each node can be manually assigned to only a single <slot> at any time.
  • If a <slot> currently lives inside a shadow tree that is in "manual" mode, then any nodes in its manually assigned nodes list that are currently light-dom direct children of the shadow host will be slotted in. Any other manually assigned nodes that don't meet these criteria will not be slotted, but will also not be removed from the list.
  • If a <slot> with manually assigned nodes currently lives inside a shadow tree that is in "name" mode, the manually assigned nodes will be ignored, and nodes will be assigned based on normal "name" assignment rules. Again, nodes will not be removed from the list here.
  • Given the above, both slots and nodes should be able to be moved around the tree and among documents without destroying the slot-to-node relationships established by slot.assign(). Nodes will be (re-)assigned to slots if/when they meet the criteria above.

dom.bs Outdated
<p>A <a>slottable</a> has an associated
<dfn export for=slottable id=slottable-manual-slot-assignment>manual slot assignment</dfn> (null
or a <a>slot</a>). Unless stated otherwise, it is null. The <a>manual slot assignment</a> is
a weak reference to the slot, such that it can be garbage collected if not referenced elsewhere.</p>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here also, comments appreciated on the "weak pointer" stuff.

dom.bs Outdated Show resolved Hide resolved
@rniwa
Copy link
Collaborator

rniwa commented Apr 9, 2021

Ok, this should be updated with the new "weak pointer in both directions" logic. The intention was:

  • you can call slot.assign() at any time with any nodes, regardless of where the nodes or the slot lives at the time.
  • Each node can be manually assigned to only a single <slot> at any time.
  • If a <slot> currently lives inside a shadow tree that is in "manual" mode, then any nodes in its manually assigned nodes list that are currently light-dom direct children of the shadow host will be slotted in. Any other manually assigned nodes that don't meet these criteria will not be slotted, but will also not be removed from the list.
  • If a <slot> with manually assigned nodes currently lives inside a shadow tree that is in "name" mode, the manually assigned nodes will be ignored, and nodes will be assigned based on normal "name" assignment rules. Again, nodes will not be removed from the list here.
  • Given the above, both slots and nodes should be able to be moved around the tree and among documents without destroying the slot-to-node relationships established by slot.assign(). Nodes will be (re-)assigned to slots if/when they meet the criteria above.

@alice does this match your current understanding / expectation of how element reflection works as well?

dom.bs Outdated

<li>
<p>For each <a>slottable</a> <a for=tree>child</a> of <var>host</var>, <var>slottable</var>, in
<p>Otherwise, for each <a>slottable</a> <a for=tree>child</a> of <var>host</var>, <var>slottable</var>, in
Copy link
Collaborator

Choose a reason for hiding this comment

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

I guess there is a question about what we're gonna do about slots which has non-empty manually assigned nodes inserted inside a shadow tree whose assignment mode is "name". Maybe clearing the manual assignment is the simplest thing to do in that case? It would be very mysterious if manually assigned nodes are completely ignored and it was treated as the default slot and/or it was silently ignored.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, I thought we were leaving these as-is. I.e. while that slot is located in a "named" mode shadow root, then "named" mode takes precedence. But nothing, other than re-assigning a node to another slot, removes anything from manually assigned nodes. I.e. .assign() is the only thing with the power to add/remove from manually assigned nodes. And no amount of node movement or slot movement can cause assignments to get cleared. I kind of feel like that's the easiest mental model for developers to have, rather than having to remember never to put a manually assigned slot into the wrong shadow root. It seems like a common pattern might be:

shadow.appendChild(slot);
slot.assign([a,b,c]);
shadow.slotAssignment = 'named';

WDYT?

Copy link
Member

Choose a reason for hiding this comment

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

I don't understand the last line of your example. slotAssignment is readonly. I do tend to agree that assign() being the only way to clear seems more straightforward than having insertion in certain trees have side effects.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah sorry, good point. That's not a great example. So you'd prefer this?

const shadow = host.attachShadow({mode: 'open'}); // "named" slot assignment
shadow.appendChild(slot);
slot.assign([a,b,c]); // Has no effect

I suppose I could live with this. It just feels weird that the entire point of all of this conversation was to make the node-to-slot assignments "sticky" across all kinds of tree mutations. But then this would be the one exception - you can move a node or a slot anywhere in any tree and the references will be maintained, except if any stop is ever within a "named"-assignment shadow root.

Given the fact that the node references are unobservable, there will definitely be cases that are a bit hard to understand for developers. E.g. assigning a node to a slot, and then making the node a grandchild (instead of direct child) of the host. We'll need to develop developer tooling to make this situation better. But I don't think adding even more magic is the answer. Again, I'm ok either way, just trying to get this right.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, re-reading your comment @annevk, it does sound like you might agree that .assign() should be the only way to clear/change node assignments.

I think this is the only remaining material issue to resolve.

Copy link
Collaborator

Choose a reason for hiding this comment

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

So assign(~) has no side effect and its results get simply ignored? That's a bit strange but all other options are equally strange so maybe it's okay. I guess this might be something we want to solicit some developer feedback.

Copy link
Member

Choose a reason for hiding this comment

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

Oh no, it got confusing. That's not what Mason or I mean. That particular comment was based on a misunderstanding.

assign() always succeeds (and doesn't no-op or throw), as per the current HTML PR. And moving a slot around doesn't affect its manually assigned nodes, as per this PR.

And the answer to your question in this subthread OP is that manually assigned nodes would be ignored in that case as it would be quite esoteric if moving a slot element around is a no-op for manually assigned nodes except if you move it to a shadow tree with named slot assignment.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah, I mean that assign(~) will succeed but it won't have any observable side effect until the slot is moved to another shadow root with manual slot assignment along with the assigned nodes, right?

Copy link
Member

Choose a reason for hiding this comment

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

Ah yes, indeed. 😊

If we can get developer feedback in a timely fashion it seems reasonable to block on that, but otherwise I'd be inclined to land these PRs and count on the fact that making a change for that particular scenario is without risk and can be made once developers have some more experience with the API.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah, sounds good to me.

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.

LGTM modulo naming of SlotAssignmentMode.

dom.bs Outdated Show resolved Hide resolved
@annevk
Copy link
Member

annevk commented Apr 13, 2021

Is there a WPT PR for dropping .tentative. from the tests? Do the tests cover the newer never-remove assigned nodes model?

Notes for the final commit message:

  • Needs to close the older PR.
  • Needs to give both authors committer credit.

Also note that all implementation bugs need to be filed before that criteria is met (unless there's a reason not to file them, but none seems to be given).

dom.bs Outdated Show resolved Hide resolved
dom.bs Outdated Show resolved Hide resolved
dom.bs Outdated Show resolved Hide resolved
@mfreed7
Copy link
Contributor Author

mfreed7 commented Apr 13, 2021

Is there a WPT PR for dropping .tentative. from the tests? Do the tests cover the newer never-remove assigned nodes model?

I don't have that ready yet, but I'll own doing it. I have the WPT updates included as part of the Chromium tracking bug. I'm just waiting until we nail down the exact behavior before I go implement it.

@annevk
Copy link
Member

annevk commented Apr 14, 2021

Okay, so I think once we have bugs for Firefox and Safari all is in order here (and ditto for the HTML PR), assuming my editorial changes look good to you all. It's fine to handle the test renaming as part of a Chromium changeset.

@mfreed7
Copy link
Contributor Author

mfreed7 commented Apr 14, 2021

Okay, so I think once we have bugs for Firefox and Safari all is in order here (and ditto for the HTML PR), assuming my editorial changes look good to you all. It's fine to handle the test renaming as part of a Chromium changeset.

Thanks! LGTM. I just updated both PRs with tracking bugs.

domenic pushed a commit to whatwg/html that referenced this pull request Apr 14, 2021
Closes #3534. Closes #5483 by superseding it.

Explainer: https://github.com/WICG/webcomponents/blob/gh-pages/proposals/Imperative-Shadow-DOM-Distribution-API.md

Corresponding DOM Standard pull request: whatwg/dom#966

Co-authored-by: Yu Han <yuzhehan@yuzhehan-macbookpro.roam.corp.google.com>
@mfreed7
Copy link
Contributor Author

mfreed7 commented Apr 14, 2021

Thanks everyone!

@annevk annevk merged commit acfe96b into whatwg:main Apr 15, 2021
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this pull request Apr 15, 2021
The original implementation of the imperative slot distribution
API was done before the final spec PRs landed. In the process of
landing those PRs, several changes were made to the way the API
works. Primarily, there are two changes:

 1. The "auto" slotAssignment mode was renamed to "named".
 2. The "linkage" that is created by HTMLSlotElement.assign() was
    made more permanent. Previously, moving either the <slot> or
    the assigned node around in the tree (or across documents)
    would "break" the linkage. Now, the linkage is more permanent,
    and the only way to break it is through another call to .assign().

See [1] for the chromestatus entry, [2] for the intent to ship,
[3], [4], and [5] for the spec PRs, and [6]/[7] for the landed spec.

[1] https://chromestatus.com/feature/4979822998585344
[2] https://groups.google.com/a/chromium.org/g/blink-dev/c/6U78F3KWJ78
[3] whatwg/html#6561
[4] whatwg/html#6585
[5] whatwg/dom#966
[6] https://dom.spec.whatwg.org/#find-slotables
[7] https://html.spec.whatwg.org/#dom-slot-assign

Fixed: 1196842
Fixed: 1067153
Bug: 1067157
Change-Id: I0ee71043c23f3b49a1461296d722045f06eca540
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this pull request Apr 15, 2021
The original implementation of the imperative slot distribution
API was done before the final spec PRs landed. In the process of
landing those PRs, several changes were made to the way the API
works. Primarily, there are two changes:

 1. The "auto" slotAssignment mode was renamed to "named".
 2. The "linkage" that is created by HTMLSlotElement.assign() was
    made more permanent. Previously, moving either the <slot> or
    the assigned node around in the tree (or across documents)
    would "break" the linkage. Now, the linkage is more permanent,
    and the only way to break it is through another call to .assign().

See [1] for the chromestatus entry, [2] for the intent to ship,
[3], [4], and [5] for the spec PRs, and [6]/[7] for the landed spec.

[1] https://chromestatus.com/feature/4979822998585344
[2] https://groups.google.com/a/chromium.org/g/blink-dev/c/6U78F3KWJ78
[3] whatwg/html#6561
[4] whatwg/html#6585
[5] whatwg/dom#966
[6] https://dom.spec.whatwg.org/#find-slotables
[7] https://html.spec.whatwg.org/#dom-slot-assign

Fixed: 1196842
Fixed: 1067153
Bug: 1067157
Change-Id: I0ee71043c23f3b49a1461296d722045f06eca540
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this pull request Apr 16, 2021
The original implementation of the imperative slot distribution
API was done before the final spec PRs landed. In the process of
landing those PRs, several changes were made to the way the API
works. Primarily, there are two changes:

 1. The "auto" slotAssignment mode was renamed to "named".
 2. The "linkage" that is created by HTMLSlotElement.assign() was
    made more permanent. Previously, moving either the <slot> or
    the assigned node around in the tree (or across documents)
    would "break" the linkage. Now, the linkage is more permanent,
    and the only way to break it is through another call to .assign().

See [1] for the chromestatus entry, [2] for the intent to ship,
[3], [4], and [5] for the spec PRs, and [6]/[7] for the landed spec.

[1] https://chromestatus.com/feature/4979822998585344
[2] https://groups.google.com/a/chromium.org/g/blink-dev/c/6U78F3KWJ78
[3] whatwg/html#6561
[4] whatwg/html#6585
[5] whatwg/dom#966
[6] https://dom.spec.whatwg.org/#find-slotables
[7] https://html.spec.whatwg.org/#dom-slot-assign

Fixed: 1196842
Fixed: 1067153
Bug: 1067157
Change-Id: I0ee71043c23f3b49a1461296d722045f06eca540
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this pull request Apr 20, 2021
The original implementation of the imperative slot distribution
API was done before the final spec PRs landed. In the process of
landing those PRs, several changes were made to the way the API
works. Primarily, there are two changes:

 1. The "auto" slotAssignment mode was renamed to "named".
 2. The "linkage" that is created by HTMLSlotElement.assign() was
    made more permanent. Previously, moving either the <slot> or
    the assigned node around in the tree (or across documents)
    would "break" the linkage. Now, the linkage is more permanent,
    and the only way to break it is through another call to .assign().

See [1] for the chromestatus entry, [2] for the intent to ship,
[3], [4], and [5] for the spec PRs, and [6]/[7] for the landed spec.

[1] https://chromestatus.com/feature/4979822998585344
[2] https://groups.google.com/a/chromium.org/g/blink-dev/c/6U78F3KWJ78
[3] whatwg/html#6561
[4] whatwg/html#6585
[5] whatwg/dom#966
[6] https://dom.spec.whatwg.org/#find-slotables
[7] https://html.spec.whatwg.org/#dom-slot-assign

Fixed: 1196842
Fixed: 1067153
Bug: 1067157
Change-Id: I0ee71043c23f3b49a1461296d722045f06eca540
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2824763
Reviewed-by: Joey Arhar <jarhar@chromium.org>
Commit-Queue: Mason Freed <masonf@chromium.org>
Cr-Commit-Position: refs/heads/master@{#874413}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this pull request Apr 20, 2021
The original implementation of the imperative slot distribution
API was done before the final spec PRs landed. In the process of
landing those PRs, several changes were made to the way the API
works. Primarily, there are two changes:

 1. The "auto" slotAssignment mode was renamed to "named".
 2. The "linkage" that is created by HTMLSlotElement.assign() was
    made more permanent. Previously, moving either the <slot> or
    the assigned node around in the tree (or across documents)
    would "break" the linkage. Now, the linkage is more permanent,
    and the only way to break it is through another call to .assign().

See [1] for the chromestatus entry, [2] for the intent to ship,
[3], [4], and [5] for the spec PRs, and [6]/[7] for the landed spec.

[1] https://chromestatus.com/feature/4979822998585344
[2] https://groups.google.com/a/chromium.org/g/blink-dev/c/6U78F3KWJ78
[3] whatwg/html#6561
[4] whatwg/html#6585
[5] whatwg/dom#966
[6] https://dom.spec.whatwg.org/#find-slotables
[7] https://html.spec.whatwg.org/#dom-slot-assign

Fixed: 1196842
Fixed: 1067153
Bug: 1067157
Change-Id: I0ee71043c23f3b49a1461296d722045f06eca540
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2824763
Reviewed-by: Joey Arhar <jarhar@chromium.org>
Commit-Queue: Mason Freed <masonf@chromium.org>
Cr-Commit-Position: refs/heads/master@{#874413}
pull bot pushed a commit to jamlee-t/chromium that referenced this pull request Apr 21, 2021
The original implementation of the imperative slot distribution
API was done before the final spec PRs landed. In the process of
landing those PRs, several changes were made to the way the API
works. Primarily, there are two changes:

 1. The "auto" slotAssignment mode was renamed to "named".
 2. The "linkage" that is created by HTMLSlotElement.assign() was
    made more permanent. Previously, moving either the <slot> or
    the assigned node around in the tree (or across documents)
    would "break" the linkage. Now, the linkage is more permanent,
    and the only way to break it is through another call to .assign().

See [1] for the chromestatus entry, [2] for the intent to ship,
[3], [4], and [5] for the spec PRs, and [6]/[7] for the landed spec.

[1] https://chromestatus.com/feature/4979822998585344
[2] https://groups.google.com/a/chromium.org/g/blink-dev/c/6U78F3KWJ78
[3] whatwg/html#6561
[4] whatwg/html#6585
[5] whatwg/dom#966
[6] https://dom.spec.whatwg.org/#find-slotables
[7] https://html.spec.whatwg.org/#dom-slot-assign

Fixed: 1196842
Fixed: 1067153
Bug: 1067157
Change-Id: I0ee71043c23f3b49a1461296d722045f06eca540
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2824763
Reviewed-by: Joey Arhar <jarhar@chromium.org>
Commit-Queue: Mason Freed <masonf@chromium.org>
Cr-Commit-Position: refs/heads/master@{#874413}
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this pull request Apr 25, 2021
…s, a=testonly

Automatic update from web-platform-tests
Implement imperative slotting API changes

The original implementation of the imperative slot distribution
API was done before the final spec PRs landed. In the process of
landing those PRs, several changes were made to the way the API
works. Primarily, there are two changes:

 1. The "auto" slotAssignment mode was renamed to "named".
 2. The "linkage" that is created by HTMLSlotElement.assign() was
    made more permanent. Previously, moving either the <slot> or
    the assigned node around in the tree (or across documents)
    would "break" the linkage. Now, the linkage is more permanent,
    and the only way to break it is through another call to .assign().

See [1] for the chromestatus entry, [2] for the intent to ship,
[3], [4], and [5] for the spec PRs, and [6]/[7] for the landed spec.

[1] https://chromestatus.com/feature/4979822998585344
[2] https://groups.google.com/a/chromium.org/g/blink-dev/c/6U78F3KWJ78
[3] whatwg/html#6561
[4] whatwg/html#6585
[5] whatwg/dom#966
[6] https://dom.spec.whatwg.org/#find-slotables
[7] https://html.spec.whatwg.org/#dom-slot-assign

Fixed: 1196842
Fixed: 1067153
Bug: 1067157
Change-Id: I0ee71043c23f3b49a1461296d722045f06eca540
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2824763
Reviewed-by: Joey Arhar <jarhar@chromium.org>
Commit-Queue: Mason Freed <masonf@chromium.org>
Cr-Commit-Position: refs/heads/master@{#874413}

--

wpt-commits: db1be04691e1b5fe58e186d682d26c69d282cbe0
wpt-pr: 28521
mjfroman pushed a commit to mjfroman/moz-libwebrtc-third-party that referenced this pull request Oct 14, 2022
The original implementation of the imperative slot distribution
API was done before the final spec PRs landed. In the process of
landing those PRs, several changes were made to the way the API
works. Primarily, there are two changes:

 1. The "auto" slotAssignment mode was renamed to "named".
 2. The "linkage" that is created by HTMLSlotElement.assign() was
    made more permanent. Previously, moving either the <slot> or
    the assigned node around in the tree (or across documents)
    would "break" the linkage. Now, the linkage is more permanent,
    and the only way to break it is through another call to .assign().

See [1] for the chromestatus entry, [2] for the intent to ship,
[3], [4], and [5] for the spec PRs, and [6]/[7] for the landed spec.

[1] https://chromestatus.com/feature/4979822998585344
[2] https://groups.google.com/a/chromium.org/g/blink-dev/c/6U78F3KWJ78
[3] whatwg/html#6561
[4] whatwg/html#6585
[5] whatwg/dom#966
[6] https://dom.spec.whatwg.org/#find-slotables
[7] https://html.spec.whatwg.org/#dom-slot-assign

Fixed: 1196842
Fixed: 1067153
Bug: 1067157
Change-Id: I0ee71043c23f3b49a1461296d722045f06eca540
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2824763
Reviewed-by: Joey Arhar <jarhar@chromium.org>
Commit-Queue: Mason Freed <masonf@chromium.org>
Cr-Commit-Position: refs/heads/master@{#874413}
GitOrigin-RevId: 821490f6968ba4cb60d1c937d1efc6e79cc6626b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants