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 13 commits into
base: main
Choose a base branch
from

Conversation

josepharhar
Copy link
Contributor

@josepharhar josepharhar commented Sep 18, 2024

The <selectedcontent> element is part of the customizable <select> proposal: #9799

It allows authors to declaratively clone the contents of the currently selected <option> of a <select> and style it independently for use in a base appearance <select>'s button.

The timing of cloning has been discussed here:
#10520

The selectedcontent element has been discussed generally here: w3c/csswg-drafts#10242

html-aria PR: w3c/html-aria#528
html-aam PR: w3c/html-aam#566

(See WHATWG Working Mode: Changes for more details.)


/form-control-infrastructure.html ( diff )
/form-elements.html ( diff )
/index.html ( diff )
/indices.html ( diff )
/infrastructure.html ( diff )
/interactive-elements.html ( diff )
/parsing.html ( diff )

The `<selectedoption>` element is part of the customizable `<select>`
proposal: whatwg#9799

It allows authors to declaratively clone the contents of the currently
selected `<option>` of a `<select>` and style it independently for use
in a base appearance `<select>`'s button.

The timing of cloning has been discussed here:
whatwg#10520

The selectedoption element has been discussed generally here:
w3c/csswg-drafts#10242
@annevk
Copy link
Member

annevk commented Sep 19, 2024

It seems this is missing a lot of the boilerplate that new elements normally have as well as changes to content models, indexes, etc. See also this checklist at the top of source:

 !   Adding a new element involves editing the following sections:
 !    - section for the element itself
 !    - descriptions of the element's categories
 !    - images/content-venn.svg
 !    - syntax, if it's void or otherwise special
 !    - parser, if it's not phrasing-level
 !    - rendering
 !    - obsolete section
 !    - element, attribute, content model, and interface indices

scottaohara added a commit to w3c/aria that referenced this pull request Sep 27, 2024
I recreated the [original PR](w3c/html-aam#566) by @josepharhar

The `<selectedoption>` element is part of the [customizable select feature](whatwg/html#9799) and is being added to HTML [here](whatwg/html#10633).

## Implementation

* WPT tests: web-platform-tests/wpt#45096
* Implementations (link to issue or when done, link to commit):
   * WebKit: TODO
   * Gecko: TODO
   * Blink: https://chromium.googlesource.com/chromium/src/+/18b5eac27b14b409503aa8047cf9358082a0e0df

Co-authored-by: Joey Arhar @josepharhar
@josepharhar
Copy link
Contributor Author

Thanks!

  • I added a dl with a bunch of metadata for the element itself.
  • I didn't include this element in any categories
  • I didn't update the content-venn image because I didn't add it to any categories.
  • I didn't update syntax or parsing because it doesn't have any special rules and I didn't implement anything in the HTML parser for this.
  • I didn't update rendering because I noticed that elements like <div> and <span> don't have sections in there, and selectedoption is supposed to render like those elements.
  • I didn't update the obsolete section because nothing is becoming obsolete...?
  • I updated the element and interface indexes

@annevk
Copy link
Member

annevk commented Oct 4, 2024

This still seems incomplete. Where does the button element indicate this element can be a descendant, for instance? If you don't adjust the categories, you still need to account for how the categories are used.

source Outdated Show resolved Hide resolved
@josepharhar
Copy link
Contributor Author

This still seems incomplete. Where does the button element indicate this element can be a descendant, for instance? If you don't adjust the categories, you still need to account for how the categories are used.

Thanks, I updated the content model of the button element

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
source Outdated Show resolved Hide resolved
@josepharhar
Copy link
Contributor Author

I just made some changes:

@josepharhar josepharhar changed the title Define the <selectedoption> element Define the <selectedcontent> element Nov 4, 2024
@annevk annevk added the topic: select The <select> element label Nov 8, 2024
@@ -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.

@@ -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>,
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 like the repetition of the class name in its member. I would also continue to markup selectedcontent I think.

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 changed it to descendant <code>selectedcontent</code> elements.

source Outdated
<ol>
<li>
<p>For each <var>ancestor</var> of <var>option</var>'s <span
data-x="ancestor">ancestors</span>:</p>
Copy link
Member

Choose a reason for hiding this comment

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

You need to define ordering here.

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 I would also express the ordering in the name of this algorithm. Maybe something like:

To get the <dfn>option element's nearest select ancestor</dfn>

And I think I would markup option and select personally (similar to what Anne suggested further above regarding selectedcontent).

Also related: #10633 (comment) (regarding ordering of "select" and "ancestor", which is a nit I don't feel that strongly about).

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 think that's sufficient to define ordering for the iteration though. It needs to be part of the iteration somehow. cc @zcorpan

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As I mentioned in at least one of the other PRs, I don't know what would be the best way to do this. I have seen other text add "in tree order" to the end of stuff like this to indicate ordering, but I think that "in tree order" might be the wrong order because I want to start at the parent and then walk up the tree.

I could add "starting at option's parent node"

Copy link
Member

Choose a reason for hiding this comment

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

Yeah that's why I said "also"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Or I could replace the "for each" loop with a while loop that manually updates the variable like this: https://html.spec.whatwg.org/multipage/interactive-elements.html#ancestor-details-revealing-algorithm

Copy link
Member

Choose a reason for hiding this comment

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

You could say "in reverse tree order".

source Show resolved Hide resolved
<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?

source Outdated
Comment on lines 56108 to 56109
<code>select</code>'s <code>button</code>, with alternate rendering based on different selectors
in the author's stylesheet.</p>
Copy link
Member

Choose a reason for hiding this comment

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

select element's button element.

As this should describe the semantics, I don't think we should discuss style sheets. That seems more suitable for an example.

<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?

<code>option</code> element.</p>

<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>
Copy link
Member

Choose a reason for hiding this comment

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

a select element*

(but this also doesn't seem entirely true as their parent has to be button and the parent of the button has to be a select)


<li>
<p>For each <var>child</var> of <var>option</var>'s <span
data-x="concept-tree-child">children</span>:</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 think you need to specify order.

Copy link
Member

Choose a reason for hiding this comment

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

Hmm, I don't know? The children member is an ordered set, and I think we can just iterate over ordered sets normally, right? Just like the children DOM getter doesn't specify the order of the collection returned: https://dom.spec.whatwg.org/#dom-parentnode-children.

Copy link
Member

Choose a reason for hiding this comment

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

Oh right. I forgot I made that change at some point and was thinking about an earlier definition of child.

Copy link
Member

@domfarolino domfarolino left a comment

Choose a reason for hiding this comment

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

Nothing major except I'm concerned about using selectedcontent element's insertion steps instead of post-connection steps. This is because I believe the steps as currently specified can run script, and script must not run during an element's insertion steps.

source Outdated
<ol>
<li>
<p>For each <var>ancestor</var> of <var>option</var>'s <span
data-x="ancestor">ancestors</span>:</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 think I would also express the ordering in the name of this algorithm. Maybe something like:

To get the <dfn>option element's nearest select ancestor</dfn>

And I think I would markup option and select personally (similar to what Anne suggested further above regarding selectedcontent).

Also related: #10633 (comment) (regarding ordering of "select" and "ancestor", which is a nit I don't feel that strongly about).


<li>
<p>For each <var>child</var> of <var>option</var>'s <span
data-x="concept-tree-child">children</span>:</p>
Copy link
Member

Choose a reason for hiding this comment

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

Hmm, I don't know? The children member is an ordered set, and I think we can just iterate over ordered sets normally, right? Just like the children DOM getter doesn't specify the order of the collection returned: https://dom.spec.whatwg.org/#dom-parentnode-children.

</ol>
</li>

<li><p>Let <var>convertedNode</var> be the result of <span>convert nodes into a node</span> given
Copy link
Member

Choose a reason for hiding this comment

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

nit: this feels like it should be the result of running or the result of <span> converting

</ol>
</li>

<li><p>Let <var>convertedNode</var> be the result of <span>convert nodes into a node</span> given
Copy link
Member

Choose a reason for hiding this comment

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

Maybe for readability/clarity this variable could be documentFragment?

<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>
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
<var>SelectedContent</var> before null.</p></li>
<var>selectedcontent</var> before null.</p></li>

<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>
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
order</span></p></li>
order</span>.</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?

<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>
Copy link
Member

Choose a reason for hiding this comment

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

Hmm, this scares me a bit! You're calling the "clone an option" algorithm from inside the selectedcontent's insertion steps, but these steps must not run script, yet the "clone an option" algorithm can run script, IIUC, because of the "replace all" call.

Given that, I'm actually thinking we should run all of these steps not inside the selected content insertion steps, but maybe its post-connection steps instead — those can run script. A test for this would be great, to confirm my suspicion. It might require some tricks to clone a script that will run during the "clone an option" algorithm.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
addition/proposal New features or enhancements topic: forms topic: select The <select> element
Development

Successfully merging this pull request may close these issues.

5 participants