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

Define the <selectedcontent> element #10633

Open
wants to merge 27 commits into
base: main
Choose a base branch
from
Open
Changes from 12 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
21b8a2c
Define the `<selectedoption>` element
josepharhar Sep 18, 2024
1aece11
add dl
josepharhar Sep 27, 2024
a1bd1e8
index
josepharhar Sep 27, 2024
c04ca18
inline replacechildren
josepharhar Oct 4, 2024
09777e2
update content model of button element
josepharhar Oct 4, 2024
c846c3e
add clear a selectedoption
josepharhar Nov 4, 2024
bef82d0
nits
josepharhar Nov 4, 2024
daabd98
allow no selectedoption
josepharhar Nov 4, 2024
bf2b5c5
Merge remote-tracking branch 'upstream/main' into selectedoption
josepharhar Nov 4, 2024
8863966
dont track mutations
josepharhar Nov 4, 2024
17ac232
rename to selectedcontent
josepharhar Nov 4, 2024
4960a77
add parser cloning
josepharhar Nov 4, 2024
10d1a14
improve things
josepharhar Nov 11, 2024
1ee134d
only update first inserted selectedoption
josepharhar Nov 22, 2024
ec5244b
some nits
josepharhar Nov 22, 2024
9463f7e
improve name of option element ancestor select
josepharhar Nov 22, 2024
02b8cde
more nits
josepharhar Nov 22, 2024
e268b44
use post-connection steps
josepharhar Dec 3, 2024
c016a74
Merge branch 'main' into selectedoption
josepharhar Dec 9, 2024
f0984d3
Add disabled concept
josepharhar Dec 9, 2024
d8a05e5
Make value and selectedIndex setters trigger cloning
josepharhar Dec 11, 2024
4126c04
Only update first selectedcontent in tree order
josepharhar Dec 16, 2024
42ef681
fix variable names
josepharhar Dec 16, 2024
961fee3
more variable names
josepharhar Dec 16, 2024
999a14a
Remove removal steps
josepharhar Dec 17, 2024
4a175ce
use more <code>
josepharhar Dec 20, 2024
730b52f
Run more updates on insertion and removal
josepharhar Dec 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
232 changes: 229 additions & 3 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -3230,6 +3230,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
<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-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-tree-ancestor">ancestor</dfn>,
<dfn data-x-href="https://dom.spec.whatwg.org/#concept-tree-descendant">descendant</dfn>,
<dfn data-x="concept-shadow-including-ancestor" data-x-href="https://dom.spec.whatwg.org/#concept-shadow-including-ancestor">shadow-including ancestor</dfn>,
<dfn data-x-href="https://dom.spec.whatwg.org/#concept-shadow-including-descendant">shadow-including descendant</dfn>,
Expand Down Expand Up @@ -3343,6 +3344,8 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
<li><dfn data-x-href="https://dom.spec.whatwg.org/#abortcontroller-signal-abort">signal abort</dfn></li>
<li><dfn data-x="AbortSignal-add" data-x-href="https://dom.spec.whatwg.org/#abortsignal-add">add</dfn></li>
<li>The <dfn data-x-href="https://dom.spec.whatwg.org/#concept-element-attributes-get-by-name">get an attribute by name</dfn> algorithm</li>
<li>The <dfn data-x-href="https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity">ensure pre-insertion validity</dfn> algorithm</li>
<li>The <dfn data-x-href="https://dom.spec.whatwg.org/#converting-nodes-into-a-node">convert nodes into a node</dfn> algorithm</li>
</ul>

<p>The following features are defined in <cite>UI Events</cite>: <ref>UIEVENTS</ref></p>
Expand Down Expand Up @@ -53198,6 +53201,8 @@ You cannot submit this form when the field is incorrect.</samp></pre>
<dd><span>Phrasing content</span>, but there must be no <span>interactive content</span>
descendant and no descendant with the <code data-x="attr-tabindex">tabindex</code> attribute
specified.</dd>
<dd>If the element is the first child of a <code>select</code> element, then it may have zero or
one <code>selectedcontent</code> element.</dd>
Copy link
Member

Choose a reason for hiding this comment

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

This does not seem accurate as it may also have other content in such cases, right? Otherwise, what would be the point of this element.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, the previous line about phrasing content also applies so that you can have phrasing content and a selectedcontent element. I added the word "also" to make this more clear. I could also combine this with the previous <dd>, what do you think?

Copy link
Member

Choose a reason for hiding this comment

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

I think in element definitions thus far the dd elements are mutually exclusive. Not additive.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, I combined it with the above dd

<dt><span data-x="concept-element-attributes">Content attributes</span>:</dt>
<dd><span>Global attributes</span></dd>
<dd><code data-x="attr-fe-disabled">disabled</code></dd>
Expand Down Expand Up @@ -53511,6 +53516,9 @@ interface <dfn interface>HTMLSelectElement</dfn> : <span>HTMLElement</span> {
element, and all the <code>option</code> element children of all the <code>optgroup</code> element
children of the <code>select</code> element, in <span>tree order</span>.</p>

<p>Every <code>select</code> element has <dfn>select descendant selectedcontent elements</dfn>,
josepharhar marked this conversation as resolved.
Show resolved Hide resolved
which is a <span>list</span> of <code>selectedcontent</code> elements, initially « ».</p>

<p>The <dfn element-attr for="select"><code data-x="attr-select-required">required</code></dfn>
attribute is a <span>boolean attribute</span>. When specified, the user will be required to select
a value before submitting the form.</p>
Expand Down Expand Up @@ -54363,6 +54371,51 @@ interface <dfn interface>HTMLOptionElement</dfn> : <span>HTMLElement</span> {

</div>

<p>To get the <dfn>option element ancestor select</dfn> given an <code>option</code>
<var>option</var>:</p>

<ol>
<li>
<p>For each <var>ancestor</var> of <var>option</var>'s <span
data-x="ancestor">ancestors</span>:</p>
josepharhar marked this conversation as resolved.
Show resolved Hide resolved

<ol>
<li><p>If <var>ancestor</var> is a <code>select</code>, then return
<var>ancestor</var>.</p></li>
</ol>
</li>

<li><p>Return null.</p></li>
</ol>

<p>To <dfn>maybe clone an option into selectedcontent</dfn>, given an <code>option</code>
<var>option</var>:</p>

<ol>
<li>
<p>If all of the following conditions are true:</p>

<ul>
<li><p><var>option</var> has a non-null <span>option element ancestor select</span>;</p></li>

<li><p><var>option</var>'s <span>option element ancestor select</span> does not have the <code
data-x="attr-select-multiple">multiple</code> attribute;</p></li>

<li><p><var>option</var>'s <span data-x="concept-option-selectedness">selectedness</span>
is true,</p></li>
</ul>

<p>then for each <var>selectedcontent</var> of <var>option</var>'s <span>option element
ancestor select</span>'s <span>select descendant selectedcontent elements</span>, run
<span>clone an option into a selectedcontent</span> given <var>option</var> and
<var>selectedcontent</var>.</p>
Copy link
Member

Choose a reason for hiding this comment

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

If we only support a single selectedcontent element, why do this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It isn't my goal to support multiple selectedcontent elements, and I don't know of a use case for multiple.

I like maintaining a list of descendant selectedcontent elements because it avoids the need to traverse through all the descendants of the select element to find another selectedcontent element in the case that a selectedcontent element is removed.

Now that I think about it, I'm probably OK with just performing a clone into the first selectedoption element in this list. I updated the text to take the first element from the list and added logic in some other places to make sure that only the first inserted selectedcontent element is kept up to date.

</li>
</ol>

<p>Whenever an <code>option</code> <var>option</var>'s <span
data-x="concept-option-selectedness">selectedness</span> is set to true, run <span>maybe clone an
option into selectedcontent</span> given <var>option</var>.</p>
josepharhar marked this conversation as resolved.
Show resolved Hide resolved

<dl class="domintro">
<dt><code data-x=""><var>option</var>.<span subdfn data-x="dom-option-selected">selected</span></code></dt>

Expand Down Expand Up @@ -56023,6 +56076,156 @@ interface <dfn interface>HTMLLegendElement</dfn> : <span>HTMLElement</span> {

</div>

<h4>The <dfn element><code>selectedcontent</code></dfn> element</h4>

<dl class="element">
<dt><span data-x="concept-element-categories">Categories</span>:</dt>
<dd>None.</dd>
<dt><span data-x="concept-element-contexts">Contexts in which this element can be used</span>:</dt>
<dd>As a descendant of a <code>button</code> element which is a child of a <code>select</code>
element.</dd>
<dt><span data-x="concept-element-content-model">Content model</span>:</dt>
<dd><span data-x="concept-content-nothing">Nothing</span>.</dd>
<dt><span data-x="concept-element-attributes">Content attributes</span>:</dt>
<dd><span>Global attributes</span></dd>
<dt><span
data-x="concept-element-accessibility-considerations">Accessibility considerations</span>:</dt>
<dd><a href="https://w3c.github.io/html-aria/#el-selectedcontent">For authors</a>.</dd>
<dd><a href="https://w3c.github.io/html-aam/#el-selectedcontent">For implementers</a>.</dd>
<dt><span data-x="concept-element-dom">DOM interface</span>:</dt>
<dd w-nodev>
<pre><code class="idl">[Exposed=Window]
interface <dfn interface>HTMLSelectedContentElement</dfn> : <span>HTMLElement</span> {
[<span>HTMLConstructor</span>] constructor();
};</code></pre>
</dd>
<dd w-dev>Uses <code>HTMLSelectedContentElement</code>.</dd>
</dl>

<p>The <code>selectedcontent</code> element reflects the contents of a <code>select</code>
element's currently selected <code>option</code> element. <code>selectedcontent</code> elements can
be used to declaratively show the selected <code>option</code> element's contents within the
<code>select</code>'s <code>button</code>, with alternate rendering based on different selectors
in the author's stylesheet.</p>
josepharhar marked this conversation as resolved.
Show resolved Hide resolved

<p>Every time the selected <code>option</code> of a <code>select</code> switches from one option
to another, the <code>selectedcontent</code> element removes all of its children and replaces them
with a new cloned copy of the DOM structure of the <code>select</code>'s selected
<code>option</code> element.</p>
Copy link
Member

Choose a reason for hiding this comment

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

I worry that implementers will look at this and not implement the actual algorithm. Perhaps we can make this web developer edition only or turn it into a note or something?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added the w-dev attribute to the <p>. How does that look?


<p><code>selectedcontent</code> elements become associated with <code>select</code> elements when
the <code>selectedcontent</code> is a <span>descendant</span> of the <code>select</code>.</p>
josepharhar marked this conversation as resolved.
Show resolved Hide resolved

<p>To <dfn>clone an option into a selectedcontent</dfn>, given an <code>option</code> element
<var>option</var> and a <code>selectedcontent</code> element <var>selectedcontent</var>:</p>

<ol>
<li><p>Let <var>nodes</var> be « ».</p></li>

<li>
<p>For each <var>child</var> of <var>option</var>'s <span
data-x="concept-tree-child">children</span>:</p>
josepharhar marked this conversation as resolved.
Show resolved Hide resolved

<ol>
<li><p>Let <var>childClone</var> be the result of running <span
data-x="concept-node-clone">clone</span> given <var>child</var>, null, true.</p></li>

<li><p><span data-x="list append">Append</span> <var>childClone</var> to
<var>nodes</var>.</p></li>
</ol>
</li>

<li><p>Let <var>convertedNode</var> be the result of <span>convert nodes into a node</span> given
josepharhar marked this conversation as resolved.
Show resolved Hide resolved
josepharhar marked this conversation as resolved.
Show resolved Hide resolved
<var>nodes</var> and <var>option</var>'s <span>node document</span>.</p></li>

<li><p><span>Ensure pre-insertion validity</span> of <var>convertedNode</var> into
<var>SelectedContent</var> before null.</p></li>
josepharhar marked this conversation as resolved.
Show resolved Hide resolved

<li><p><span data-x="concept-node-replace-all">Replace all</span> with <var>convertedNode</var>
within <var>selectedcontent</var>.</p></li>
</ol>

<p>To <dfn>clear a selectedcontent</dfn> given a <code>selectedcontent</code> element
<var>selectedcontent</var>:</p>

<ol>
<li><p><span data-x="concept-node-remove-ext">Remove</span> all <span
data-x="concept-tree-child">children</span> of <var>selectedcontent</var>, in <span>tree
order</span></p></li>
josepharhar marked this conversation as resolved.
Show resolved Hide resolved
</ol>

<p>The <code>selectedcontent</code> <span>HTML element insertion steps</span>, given
<var>selectedcontent</var>, are:</p>

<ol>
<li><p>Let <var>nearestSelectAncestor</var> be null.</p></li>

<li><p>Let <var>ancestor</var> be <var>selectedcontent</var>'s <span>parent</span>.</p></li>

<li>
<p><span>While</span> <var>nearestSelectAncestor</var> is null and <var>ancestor</var> is not
null:</p>

<ol>
<li><p>If <var>ancestor</var> is a <code>select</code> element, then set
<var>nearestSelectAncestor</var> to <var>ancestor</var>.</p></li>

<li><p>Set <var>ancestor</var> to <var>ancestor</var>'s <span>parent</span>.</p></li>
</ol>
</li>

<li><p>If <var>nearestSelectAncestor</var> is null, then return.</p></li>

<li><p><span data-x="list append">Append</span> <var>selectedcontent</var> to
<var>nearestSelectAncestor</var>'s <span>select descendant selectedcontent
elements</span>.</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.

I guess this is related to Anne's question above, but do we support multiple selectedcontent elements or no?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In response to that comment I added logic to only support one selectedcontent element, but I still want to keep this list in order to prevent adding even more logic


<li><p>Let <var>option</var> be the first <code>option</code> in
<var>nearestSelectAncestor</var>'s <span data-x="concept-select-option-list">list of
options</span> whose <span data-x="concept-option-selectedness">selectedness</span> is true, if
any such <code>option</code> exists, otherwise null.</p></li>

<li><p>If <var>option</var> is null, then run <span>clear a selectedcontent</span> given
<var>insertedNode</var>.</p></li>

<li><p>Otherwise, run <span>clone an option into a selectedcontent</span> given <var>option</var>
and <var>insertedNode</var>.</p></li>
josepharhar marked this conversation as resolved.
Show resolved Hide resolved
</ol>

<p>The <code>selectedcontent</code> <span>HTML element removing steps</span>, given
<var>selectedcontent</var> and <var>oldParent</var>, are:</p>

<ol>
<li>
<p>For each <var>ancestor</var> of <var>selectedcontent</var>'s <span
data-x="ancestor">ancestors</span>:</p>

<ol>
<li><p>If <var>ancestor</var> is a <code>select</code> element, then return.</p></li>
</ol>
</li>

<li>
<p>For each <var>ancestor</var> of <var>oldParent</var>'s <span data-x="inclusive
ancestor">inclusive ancestors</span>:</p>

<ol>
<li>
<p>If <var>ancestor</var> is a <code>select</code> element, then:</p>

<ol>
<li><p><span data-x="list remove">remove</span> <var>selectedcontent</var> from
<var>ancestor</var>'s <span>select descendant selectedcontent elements</span>.</p></li>

<li><p>Run <span>clear a selectedcontent</span> given <var>selectedcontent</var>.</p></li>

<li><p>Return.</p></li>
</ol>
</li>
</ol>
</li>
</ol>



<h4 split-filename="form-control-infrastructure">Form control infrastructure</h4>
Expand Down Expand Up @@ -131423,9 +131626,18 @@ document.body.appendChild(text);

<dt>An end tag whose tag name is "option"</dt>
<dd>
<p>If the <span>current node</span> is an <code>option</code> element, then pop that node from
the <span>stack of open elements</span>. Otherwise, this is a <span>parse error</span>; ignore
the token.</p>
<p>If the <span>current node</span> is an <code>option</code> element, then:</p>

<ol>
<li><p>Let <var>option</var> be the <span>current node</span>.</p></li>

<li><p>Pop <var>option</var> from the <span>stack of open elements</span>.</p></li>

<li><p>Run <span>maybe clone an option into selectedcontent</span> given
<var>option</var>.</p></li>
</ol>

<p>Otherwise, this is a <span>parse error</span>; ignore the token.</p>
</dd>

<dt>An end tag whose tag name is "select"</dt>
Expand Down Expand Up @@ -140487,6 +140699,16 @@ interface <dfn interface>External</dfn> {
<td><code>HTMLSelectElement</code></td>
</tr>

<tr>
<th><code>selectedcontent</code></th>
<td>Mirrors content from an <code>option</code></td>
<td>none</td>
<td><code>button</code></td>
<td>empty</td>
<td><span data-x="global attributes">globals</span></td>
<td><code>HTMLSelectedContentElement</code></td>
</tr>

<tr>
<th><code>slot</code></th>
<td>Shadow tree slot</td>
Expand Down Expand Up @@ -143279,6 +143501,10 @@ interface <dfn interface>External</dfn> {
<td> <code>select</code>
<td> <code>HTMLSelectElement</code> : <code>HTMLElement</code>

<tr>
<td> <code>selectedcontent</code>
<td> <code>HTMLSelectedContentElement</code> : <code>HTMLElement</code>

<tr>
<td> <code>slot</code>
<td> <code>HTMLSlotElement</code> : <code>HTMLElement</code>
Expand Down