-
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
Add Imperative Slot API #5483
Add Imperative Slot API #5483
Changes from all commits
f3f5266
91e0d05
1f10e68
1c673df
a705c37
d30c8f1
854a6b0
b39abb7
981de6d
ab78ff5
551f474
bbb886a
174469b
127bb89
fdc36ca
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 |
---|---|---|
|
@@ -2952,6 +2952,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute | |
<li>The <dfn data-x-href="https://dom.spec.whatwg.org/#concept-tree">tree</dfn>, <dfn data-x-href="https://dom.spec.whatwg.org/#concept-shadow-tree">shadow tree</dfn>, and <dfn data-x-href="https://dom.spec.whatwg.org/#concept-node-tree">node tree</dfn> concepts</li> | ||
<li>The <dfn data-x-href="https://dom.spec.whatwg.org/#concept-tree-order">tree order</dfn> and <dfn data-x-href="https://dom.spec.whatwg.org/#concept-shadow-including-tree-order">shadow-including tree order</dfn> concepts</li> | ||
<li>The <dfn data-x-href="https://dom.spec.whatwg.org/#concept-tree-child" data-x="concept-tree-child">child</dfn> concept</li> | ||
<li>The <dfn data-x-href="https://dom.spec.whatwg.org/#concept-tree-descendant" data-x="concept-tree-descendant">descendant</dfn> concept</li> | ||
<li>The <dfn data-x-href="https://dom.spec.whatwg.org/#concept-tree-root">root</dfn> and <dfn data-x-href="https://dom.spec.whatwg.org/#concept-shadow-including-root">shadow-including root</dfn> concepts</li> | ||
<li>The <dfn data-x-href="https://dom.spec.whatwg.org/#concept-tree-inclusive-ancestor">inclusive ancestor</dfn>, | ||
<dfn data-x-href="https://dom.spec.whatwg.org/#concept-shadow-including-descendant">shadow-including descendant</dfn>, | ||
|
@@ -2961,7 +2962,11 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute | |
<li>The <dfn data-x-href="https://dom.spec.whatwg.org/#document-element">document element</dfn> concept</li> | ||
<li>The <dfn data-x-href="https://dom.spec.whatwg.org/#in-a-document-tree">in a document tree</dfn>, <dfn data-x-href="https://dom.spec.whatwg.org/#in-a-document">in a document</dfn> (legacy), and <dfn data-x-href="https://dom.spec.whatwg.org/#connected">connected</dfn> concepts</li> | ||
<li>The <dfn data-x="concept-slot" data-x-href="https://dom.spec.whatwg.org/#concept-slot">slot</dfn> concept, and its <dfn data-x="slot-name" data-x-href="https://dom.spec.whatwg.org/#slot-name">name</dfn> and <dfn data-x-href="https://dom.spec.whatwg.org/#slot-assigned-nodes">assigned nodes</dfn></li> | ||
<li>The <dfn data-x-href="https://dom.spec.whatwg.org/#slotable-assigned-slot">assigned slot</dfn> concept. | ||
<li>The <dfn data-x-href="https://dom.spec.whatwg.org/#slotable-assigned-slot">assigned slot</dfn> concept</li> | ||
<li>The <dfn data-x-href="https://dom.spec.whatwg.org/#dom-shadowroot-slot-assignment">slot assignment</dfn> concept</li> | ||
<li>The <dfn data-x-href="https://dom.spec.whatwg.org/#concept-slotable">slottable</dfn> concept</li> | ||
<li>The <dfn data-x-href="https://dom.spec.whatwg.org/#assign-slotables-for-a-tree">assign slottables for a tree</dfn> algorithm</li> | ||
<li>The <dfn data-x-href="https://dom.spec.whatwg.org/#concept-tree-inclusive-descendant">inclusive descendants</dfn> concept</li>> | ||
<li>The <dfn data-x="finding flattened slottables" data-x-href="https://dom.spec.whatwg.org/#find-flattened-slotables">find flattened slottables</dfn> algorithm</li> | ||
<li>The <dfn data-x-href="https://dom.spec.whatwg.org/#assign-a-slot">assign a slot</dfn> algorithm</li> | ||
<li>The <dfn data-x-href="https://dom.spec.whatwg.org/#concept-node-pre-insert">pre-insert</dfn>, <dfn data-x="concept-node-insert" data-x-href="https://dom.spec.whatwg.org/#concept-node-insert">insert</dfn>, <dfn data-x="concept-node-append" data-x-href="https://dom.spec.whatwg.org/#concept-node-append">append</dfn>, <dfn data-x="concept-node-replace" data-x-href="https://dom.spec.whatwg.org/#concept-node-replace">replace</dfn>, <dfn data-x="concept-node-replace-all" data-x-href="https://dom.spec.whatwg.org/#concept-node-replace-all">replace all</dfn>, <dfn data-x-href="https://dom.spec.whatwg.org/#string-replace-all">string replace all</dfn>, <dfn data-x="concept-node-remove" data-x-href="https://dom.spec.whatwg.org/#concept-node-remove">remove</dfn>, and <dfn data-x="concept-node-adopt" data-x-href="https://dom.spec.whatwg.org/#concept-node-adopt">adopt</dfn> algorithms for nodes</li> | ||
|
@@ -59244,16 +59249,17 @@ interface <dfn>HTMLTemplateElement</dfn> : <span>HTMLElement</span> { | |
<dt><span data-x="concept-element-dom">DOM interface</span>:</dt> | ||
<dd w-nodev> | ||
<pre><code class="idl">[Exposed=Window] | ||
interface <dfn>HTMLSlotElement</dfn> : <span>HTMLElement</span> { | ||
interface <dfn interface>HTMLSlotElement</dfn> : <span>HTMLElement</span> { | ||
[<span>HTMLConstructor</span>] constructor(); | ||
|
||
[<span>CEReactions</span>] attribute DOMString <span data-x="dom-slot-name">name</span>; | ||
sequence<Node> <span data-x="dom-slot-assignedNodes">assignedNodes</span>(optional <span>AssignedNodesOptions</span> options = {}); | ||
sequence<Element> <span data-x="dom-slot-assignedElements">assignedElements</span>(optional <span>AssignedNodesOptions</span> options = {}); | ||
undefined <span data-x="dom-slot-assign">assign</span>((<span>Element</span> or <span>Text</span>)... nodes); | ||
}; | ||
|
||
dictionary <dfn>AssignedNodesOptions</dfn> { | ||
boolean flatten = false; | ||
dictionary <dfn dictionary>AssignedNodesOptions</dfn> { | ||
boolean <dfn dict-member for="AssignedNodeOptions" data-x="dom-AssignedNodesOptions-flatten">flatten</dfn> = false; | ||
};</code></pre> | ||
</dd> | ||
<dd w-dev>Uses <code>HTMLSlotElement</code>.</dd> | ||
|
@@ -59295,33 +59301,85 @@ dictionary <dfn>AssignedNodesOptions</dfn> { | |
<dt><var>slot</var> . <code data-x="dom-slot-assignedElements">assignedElements</code>({ flatten: true })</dt> | ||
<dd>Returns the same as <code data-x="dom-slot-assignedNodes">assignedNodes({ flatten: true | ||
})</code>, limited to elements.</dd> | ||
|
||
<dt><var>slot</var> . <code data-x="dom-slot-assign">assign</code>(...nodes)</dt> | ||
<dd> | ||
<p>Set <var>slot</var>'s <span>assigned nodes</span> to the given <var>nodes</var>.</p> | ||
|
||
<p>Throws a <span>"<code>NotAllowedError</code>"</span> <code>DOMException</code> if | ||
<var>slot</var>'s <span>root</span> is not a <span>shadow root</span>, its <span>root</span>'s | ||
<span>slot assignment</span> is not "manual", or <var>nodes</var> are not <span>slottable</span> | ||
children of <var>slot</var>'s <span>root</span>'s <span>shadow host</span>.</p> | ||
</dd> | ||
</dl> | ||
|
||
<p>The <dfn data-x="dom-slot-name"><code>name</code></dfn> IDL attribute must <span>reflect</span> | ||
the content attribute of the same name.</p> | ||
|
||
<p>The <dfn data-x="dom-slot-assignedNodes"><code>assignedNodes(<var>options</var>)</code></dfn> | ||
method, when invoked, must run these steps:</p> | ||
method steps are:</p> | ||
|
||
<ol> | ||
<li><p>If the value of <var>options</var>'s <code data-x="">flatten</code> member is false, then | ||
return this element's <span>assigned nodes</span>.</p></li> | ||
<li><p>If <var>options</var>["<code data-x="dom-AssignedNodesOptions-flatten">flatten</code>"] is | ||
false, then return <span>this</span>'s <span>assigned nodes</span>.</p></li> | ||
|
||
<li><p>Return the result of <span>finding flattened slottables</span> with this element.</p></li> | ||
<li><p>Return the result of <span>finding flattened slottables</span> with | ||
<span>this</span>.</p></li> | ||
</ol> | ||
|
||
<p>The <dfn data-x="dom-slot-assignedElements"><code>assignedElements(<var>options</var>)</code></dfn> | ||
method, when invoked, must run these steps:</p> | ||
<p>The <dfn | ||
data-x="dom-slot-assignedElements"><code>assignedElements(<var>options</var>)</code></dfn> method | ||
steps are:</p> | ||
|
||
<ol> | ||
<li><p>If the value of <var>options</var>'s <code data-x="">flatten</code> member is false, then | ||
return this element's <span>assigned nodes</span>, filtered to contain only <code>Element</code> | ||
nodes.</p></li> | ||
<li><p>If <var>options</var>["<code data-x="dom-AssignedNodesOptions-flatten">flatten</code>"] is | ||
false, then return <span>this</span>'s <span>assigned nodes</span>, filtered to contain only | ||
<code>Element</code> nodes.</p></li> | ||
|
||
<li><p>Return the result of <span>finding flattened slottables</span> with this element, filtered | ||
to contain only <code>Element</code> nodes.</p></li> | ||
<li><p>Return the result of <span>finding flattened slottables</span> with <span>this</span>, | ||
filtered to contain only <code>Element</code> nodes.</p></li> | ||
</ol> | ||
|
||
<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> | ||
|
||
<p>The <dfn method for="HTMLSlotElement" | ||
data-x="dom-slot-assign"><code>assign(...<var>nodes</var>)</code></dfn> method steps are:</p> | ||
|
||
<ol> | ||
domenic marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<li><p>If <span>this</span>'s <span>root</span> is not a <span>shadow root</span>, or its | ||
<span>slot assignment</span> is not "<code data-x="">manual</code>", then throw a | ||
<span>"<code>NotAllowedError</code>"</span> <code>DOMException</code>.</p></li> | ||
|
||
<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> | ||
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. I'm going to leave this whole thing here - it seems reasonable to me to throw an exception if, at For this reason, I don't think there are any changes needed to this PR to incorporate the proposed changes. 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. 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. 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. Yes, that's a good point. Ok, sounds like we should probably remove the second |
||
|
||
<li><p>Let <var>nodesSet</var> be a new <span data-x="set">ordered set</span>.</p></li> | ||
|
||
<li> | ||
<p><span data-x="list iterate">For each</span> <var>node</var> of <var>nodes</var>:</p> | ||
|
||
<ol> | ||
<li><p><span data-x="list iterate">For each</span> <span | ||
data-x="concept-tree-descendant">descendant</span> <var>descendant</var> of <span>this</span>'s | ||
<span>root</span>, in <span>tree order</span>: if <var>descendant</var> is a <span>slot</span>, | ||
then <span data-x="list remove">remove</span> <var>node</var> from <var>descendant</var>'s | ||
<span>manually assigned nodes</span>.</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. 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. 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. 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. 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. 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... 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. 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. 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. I did update the PR; see commit fdc36ca |
||
<li><p><span data-x="set append">Append</span> <var>node</var> to <var>nodesSet</var>.</p></li> | ||
</ol> | ||
</li> | ||
|
||
<li><p>Set <span>this</span>'s <span>manually assigned nodes</span> to | ||
<var>nodesSet</var>.</p></li> | ||
|
||
<li><p>Run <span>assign slottables for a tree</span> for <span>this</span>'s | ||
<span>root</span>.</p></li> | ||
</ol> | ||
|
||
|
||
<h4 split-filename="canvas">The <dfn id="canvas"><code>canvas</code></dfn> element</h4> | ||
|
@@ -123980,6 +124038,7 @@ INSERT INTERFACES HERE | |
Yngve Nysaeter Pettersen, | ||
Yoav Weiss, | ||
Yonathan Randolph, | ||
Yu Han, <!-- yuzhe-han on GitHub --> | ||
Yu Huojiang, | ||
Yury Delendik, | ||
平野裕 (Yutaka Hirano), | ||
|
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.
Should we move this up? Usually we describe "slots" before public members.
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 moved this up above the
assignedNodes
method steps. Let me know if that's what you were requesting here.