Update selectedcontent element to match spec [chromium/src : main]

0 views
Skip to first unread message

David Baron (Gerrit)

unread,
Dec 8, 2025, 3:19:02 PM12/8/25
to David Baron, AyeAye, Chromium LUCI CQ, blink-re...@chromium.org, blink-revie...@chromium.org, blink-rev...@chromium.org, blink-...@chromium.org, jmedle...@chromium.org, kinuko...@chromium.org
Attention needed from Joey Arhar

David Baron added 9 comments

Commit Message
Line 14, Patchset 6 (Latest):This patch implements the behavior in the spec behind a flag.
David Baron . unresolved

maybe say that the flag is enabled by default, since my default interpretation when reading "behind a flag" is that the flag isn't on yet

File third_party/blink/renderer/core/dom/tree_ordered_list.h
Line 113, Patchset 6 (Latest): for (const T* node : nodes_) {
if (node == node_to_check) {
return true;
}
}
return false;
David Baron . unresolved

Just use the `LinkedHashSet` implementation?

```suggestion
return nodes_.Contains(node_to_check);
```

Although probably also inline it in the class definition at that point?

File third_party/blink/renderer/core/html/forms/html_selected_content_element.cc
Line 53, Patchset 6 (Latest): // <seletedoption> can lead to infinite loops.
David Baron . unresolved
```suggestion
// <selectedcontent> can lead to infinite loops.
```
Line 55, Patchset 6 (Latest): // The HTML spec has a "break" here, but we continue instead because we
David Baron . unresolved

I don't see this "break" in the spec (reading the [post-connection steps](https://html.spec.whatwg.org/multipage/form-elements.html#the-selectedcontent-element:html-element-post-connection-steps)). (Though I also don't see anything that makes the code wrong, just the comment.)

Line 60, Patchset 6 (Latest): }
if (auto* select = DynamicTo<HTMLSelectElement>(ancestor)) {
David Baron . unresolved
```suggestion
} else if (auto* select = DynamicTo<HTMLSelectElement>(ancestor)) {
```
Line 73, Patchset 6 (Latest): if (nearest_ancestor_select_ && !disabled_) {
David Baron . unresolved

This doesn't seem sufficient. If a `<select>` initially has a working `<selectedcontent>`, and then somebody inserts a new one *before* it that the algorithm makes *disabled*, I think we need to update the select at that point so that the previously-working one gets cleared, no? (That said, I'm reading the spec somewhat quickly so I may have missed something.)

Line 85, Patchset 6 (Latest): // <seletedoption> can lead to infinite loops.
David Baron . unresolved
```suggestion
// <selectedcontent> can lead to infinite loops.
```
Line 106, Patchset 6 (Latest): // the spec since the spec doesn't have a dached nearest_ancestor_select_, but
David Baron . unresolved
```suggestion
// the spec since the spec doesn't have a cached nearest_ancestor_select_, but
```
Line 107, Patchset 6 (Latest): // the behavior is the same.
David Baron . unresolved

Is the behavior the same? Won't there be detectable mutations here that the spec says shouldn't happen?

Open in Gerrit

Related details

Attention is currently required from:
  • Joey Arhar
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I904f83292ec6e6619eb72cdddfc740440edcc753
Gerrit-Change-Number: 7127725
Gerrit-PatchSet: 6
Gerrit-Owner: Joey Arhar <jar...@chromium.org>
Gerrit-Reviewer: David Baron <dba...@chromium.org>
Gerrit-Reviewer: Joey Arhar <jar...@chromium.org>
Gerrit-Attention: Joey Arhar <jar...@chromium.org>
Gerrit-Comment-Date: Mon, 08 Dec 2025 20:18:56 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
satisfied_requirement
unsatisfied_requirement
open
diffy

Joey Arhar (Gerrit)

unread,
Dec 9, 2025, 12:50:01 AM12/9/25
to David Baron, AyeAye, Chromium LUCI CQ, blink-re...@chromium.org, blink-revie...@chromium.org, blink-rev...@chromium.org, blink-...@chromium.org, jmedle...@chromium.org, kinuko...@chromium.org
Attention needed from David Baron

Joey Arhar added 9 comments

Commit Message
Line 14, Patchset 6 (Latest):This patch implements the behavior in the spec behind a flag.
David Baron . resolved

maybe say that the flag is enabled by default, since my default interpretation when reading "behind a flag" is that the flag isn't on yet

Joey Arhar

good point, i changed the flag to experimental

File third_party/blink/renderer/core/dom/tree_ordered_list.h
Line 113, Patchset 6 (Latest): for (const T* node : nodes_) {
if (node == node_to_check) {
return true;
}
}
return false;
David Baron . resolved

Just use the `LinkedHashSet` implementation?

```suggestion
return nodes_.Contains(node_to_check);
```

Although probably also inline it in the class definition at that point?

Joey Arhar

Done

File third_party/blink/renderer/core/html/forms/html_selected_content_element.cc
Line 53, Patchset 6 (Latest): // <seletedoption> can lead to infinite loops.
David Baron . resolved
```suggestion
// <selectedcontent> can lead to infinite loops.
```
Joey Arhar

Done

Line 55, Patchset 6 (Latest): // The HTML spec has a "break" here, but we continue instead because we
David Baron . unresolved

I don't see this "break" in the spec (reading the [post-connection steps](https://html.spec.whatwg.org/multipage/form-elements.html#the-selectedcontent-element:html-element-post-connection-steps)). (Though I also don't see anything that makes the code wrong, just the comment.)

Joey Arhar

A break is being added here: https://github.com/whatwg/html/pull/11878

I added a link to it in the commit message.

I suppose that I could wait for the PR to be merged first, but I found it helpful to implement in order to review that PR.

Line 60, Patchset 6 (Latest): }
if (auto* select = DynamicTo<HTMLSelectElement>(ancestor)) {
David Baron . resolved
```suggestion
} else if (auto* select = DynamicTo<HTMLSelectElement>(ancestor)) {
```
Joey Arhar

Done

Line 73, Patchset 6 (Latest): if (nearest_ancestor_select_ && !disabled_) {
David Baron . unresolved

This doesn't seem sufficient. If a `<select>` initially has a working `<selectedcontent>`, and then somebody inserts a new one *before* it that the algorithm makes *disabled*, I think we need to update the select at that point so that the previously-working one gets cleared, no? (That said, I'm reading the spec somewhat quickly so I may have missed something.)

Joey Arhar

Without this disabled check, this test will infinitely loop: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/selectedcontent-in-option-crash.html

I'm not really inclined to make cases like this any less broken since putting a selectedcontent element inside another one or inside an option is not something that anybody should ever do. I can try to make it clear selectedcontent elements without doing any cloning though if you still think we should.

Line 85, Patchset 6 (Latest): // <seletedoption> can lead to infinite loops.
David Baron . resolved
```suggestion
// <selectedcontent> can lead to infinite loops.
```
Joey Arhar

Done

Line 106, Patchset 6 (Latest): // the spec since the spec doesn't have a dached nearest_ancestor_select_, but
David Baron . resolved
```suggestion
// the spec since the spec doesn't have a cached nearest_ancestor_select_, but
```
Joey Arhar

Done

Line 107, Patchset 6 (Latest): // the behavior is the same.
David Baron . unresolved

Is the behavior the same? Won't there be detectable mutations here that the spec says shouldn't happen?

Joey Arhar

I added DCHECKs with logic which more closely matches the spec. How does it look?

Open in Gerrit

Related details

Attention is currently required from:
  • David Baron
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I904f83292ec6e6619eb72cdddfc740440edcc753
Gerrit-Change-Number: 7127725
Gerrit-PatchSet: 6
Gerrit-Owner: Joey Arhar <jar...@chromium.org>
Gerrit-Reviewer: David Baron <dba...@chromium.org>
Gerrit-Reviewer: Joey Arhar <jar...@chromium.org>
Gerrit-Attention: David Baron <dba...@chromium.org>
Gerrit-Comment-Date: Tue, 09 Dec 2025 05:49:49 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: David Baron <dba...@chromium.org>
satisfied_requirement
unsatisfied_requirement
open
diffy

David Baron (Gerrit)

unread,
Dec 9, 2025, 11:05:01 AM12/9/25
to David Baron, AyeAye, Chromium LUCI CQ, blink-re...@chromium.org, blink-revie...@chromium.org, blink-rev...@chromium.org, blink-...@chromium.org, jmedle...@chromium.org, kinuko...@chromium.org
Attention needed from Joey Arhar

David Baron added 1 comment

File third_party/blink/renderer/core/html/forms/html_selected_content_element.cc
Line 73, Patchset 6: if (nearest_ancestor_select_ && !disabled_) {
David Baron . unresolved

This doesn't seem sufficient. If a `<select>` initially has a working `<selectedcontent>`, and then somebody inserts a new one *before* it that the algorithm makes *disabled*, I think we need to update the select at that point so that the previously-working one gets cleared, no? (That said, I'm reading the spec somewhat quickly so I may have missed something.)

Joey Arhar

Without this disabled check, this test will infinitely loop: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/selectedcontent-in-option-crash.html

I'm not really inclined to make cases like this any less broken since putting a selectedcontent element inside another one or inside an option is not something that anybody should ever do. I can try to make it clear selectedcontent elements without doing any cloning though if you still think we should.

David Baron

As I commented on the PR, would it make sense here if we have a separate `updateSelect` boolean that gets set to `false` if we make the `selectedcontent` `disabled` because of the `selectedcontent` ancestor check, but not if it's because of the `option` ancestor check?

(Also, I'm still thinking about the multiple-select-ancestors case; I just realized the spec is wrong there and I need to make another comment on the PR!)

Open in Gerrit

Related details

Attention is currently required from:
  • Joey Arhar
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I904f83292ec6e6619eb72cdddfc740440edcc753
Gerrit-Change-Number: 7127725
Gerrit-PatchSet: 7
Gerrit-Owner: Joey Arhar <jar...@chromium.org>
Gerrit-Reviewer: David Baron <dba...@chromium.org>
Gerrit-Reviewer: Joey Arhar <jar...@chromium.org>
Gerrit-Attention: Joey Arhar <jar...@chromium.org>
Gerrit-Comment-Date: Tue, 09 Dec 2025 16:04:50 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Joey Arhar <jar...@chromium.org>
Comment-In-Reply-To: David Baron <dba...@chromium.org>
satisfied_requirement
unsatisfied_requirement
open
diffy

Joey Arhar (Gerrit)

unread,
Dec 11, 2025, 7:48:26 PM12/11/25
to David Baron, AyeAye, Chromium LUCI CQ, blink-re...@chromium.org, blink-revie...@chromium.org, blink-rev...@chromium.org, blink-...@chromium.org, jmedle...@chromium.org, kinuko...@chromium.org
Attention needed from David Baron

Joey Arhar added 1 comment

File third_party/blink/renderer/core/html/forms/html_selected_content_element.cc
Line 73, Patchset 6: if (nearest_ancestor_select_ && !disabled_) {
David Baron . unresolved

This doesn't seem sufficient. If a `<select>` initially has a working `<selectedcontent>`, and then somebody inserts a new one *before* it that the algorithm makes *disabled*, I think we need to update the select at that point so that the previously-working one gets cleared, no? (That said, I'm reading the spec somewhat quickly so I may have missed something.)

Joey Arhar

Without this disabled check, this test will infinitely loop: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/selectedcontent-in-option-crash.html

I'm not really inclined to make cases like this any less broken since putting a selectedcontent element inside another one or inside an option is not something that anybody should ever do. I can try to make it clear selectedcontent elements without doing any cloning though if you still think we should.

David Baron

As I commented on the PR, would it make sense here if we have a separate `updateSelect` boolean that gets set to `false` if we make the `selectedcontent` `disabled` because of the `selectedcontent` ancestor check, but not if it's because of the `option` ancestor check?

(Also, I'm still thinking about the multiple-select-ancestors case; I just realized the spec is wrong there and I need to make another comment on the PR!)

Joey Arhar

I tried adding an updateSelect boolean, but it still makes selectedcontent-in-option-crash.html have an infinite loop. I can debug and provide more context, but does it look like I implemented it correctly in the latest patch set?

Open in Gerrit

Related details

Attention is currently required from:
  • David Baron
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I904f83292ec6e6619eb72cdddfc740440edcc753
Gerrit-Change-Number: 7127725
Gerrit-PatchSet: 7
Gerrit-Owner: Joey Arhar <jar...@chromium.org>
Gerrit-Reviewer: David Baron <dba...@chromium.org>
Gerrit-Reviewer: Joey Arhar <jar...@chromium.org>
Gerrit-Attention: David Baron <dba...@chromium.org>
Gerrit-Comment-Date: Fri, 12 Dec 2025 00:48:15 +0000
satisfied_requirement
unsatisfied_requirement
open
diffy

David Baron (Gerrit)

unread,
Dec 12, 2025, 12:15:37 PM12/12/25
to David Baron, AyeAye, Chromium LUCI CQ, blink-re...@chromium.org, blink-revie...@chromium.org, blink-rev...@chromium.org, blink-...@chromium.org, jmedle...@chromium.org, kinuko...@chromium.org
Attention needed from Joey Arhar

David Baron added 1 comment

File third_party/blink/renderer/core/html/forms/html_selected_content_element.cc
Line 55, Patchset 6: // The HTML spec has a "break" here, but we continue instead because we
David Baron . unresolved

I don't see this "break" in the spec (reading the [post-connection steps](https://html.spec.whatwg.org/multipage/form-elements.html#the-selectedcontent-element:html-element-post-connection-steps)). (Though I also don't see anything that makes the code wrong, just the comment.)

Joey Arhar

A break is being added here: https://github.com/whatwg/html/pull/11878

I added a link to it in the commit message.

I suppose that I could wait for the PR to be merged first, but I found it helpful to implement in order to review that PR.

David Baron

I think it's also probably ok to set `update_select` to false in the case a few lines lower where you set `disabled_` to true because of nested selects.

(I think the case where updating is clearly needed is the case where you're inserting a `<selectedcontent>` inside an `<option>`.)

Open in Gerrit

Related details

Attention is currently required from:
  • Joey Arhar
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I904f83292ec6e6619eb72cdddfc740440edcc753
Gerrit-Change-Number: 7127725
Gerrit-PatchSet: 9
Gerrit-Owner: Joey Arhar <jar...@chromium.org>
Gerrit-Reviewer: David Baron <dba...@chromium.org>
Gerrit-Reviewer: Joey Arhar <jar...@chromium.org>
Gerrit-Attention: Joey Arhar <jar...@chromium.org>
Gerrit-Comment-Date: Fri, 12 Dec 2025 17:15:31 +0000
satisfied_requirement
unsatisfied_requirement
open
diffy

Joey Arhar (Gerrit)

unread,
Jan 5, 2026, 11:19:51 AMJan 5
to David Baron, AyeAye, Chromium LUCI CQ, blink-re...@chromium.org, blink-revie...@chromium.org, blink-rev...@chromium.org, blink-...@chromium.org, jmedle...@chromium.org, kinuko...@chromium.org
Attention needed from David Baron

Joey Arhar added 1 comment

File third_party/blink/renderer/core/html/forms/html_selected_content_element.cc
Line 55, Patchset 6: // The HTML spec has a "break" here, but we continue instead because we
David Baron . unresolved

I don't see this "break" in the spec (reading the [post-connection steps](https://html.spec.whatwg.org/multipage/form-elements.html#the-selectedcontent-element:html-element-post-connection-steps)). (Though I also don't see anything that makes the code wrong, just the comment.)

Joey Arhar

A break is being added here: https://github.com/whatwg/html/pull/11878

I added a link to it in the commit message.

I suppose that I could wait for the PR to be merged first, but I found it helpful to implement in order to review that PR.

David Baron

I think it's also probably ok to set `update_select` to false in the case a few lines lower where you set `disabled_` to true because of nested selects.

(I think the case where updating is clearly needed is the case where you're inserting a `<selectedcontent>` inside an `<option>`.)

Joey Arhar

I set update_select to false in that case, but it still times out on selectedcontent-in-option-crash.html

Open in Gerrit

Related details

Attention is currently required from:
  • David Baron
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I904f83292ec6e6619eb72cdddfc740440edcc753
Gerrit-Change-Number: 7127725
Gerrit-PatchSet: 9
Gerrit-Owner: Joey Arhar <jar...@chromium.org>
Gerrit-Reviewer: David Baron <dba...@chromium.org>
Gerrit-Reviewer: Joey Arhar <jar...@chromium.org>
Gerrit-Attention: David Baron <dba...@chromium.org>
Gerrit-Comment-Date: Mon, 05 Jan 2026 16:19:40 +0000
satisfied_requirement
unsatisfied_requirement
open
diffy

David Baron (Gerrit)

unread,
Jan 5, 2026, 3:35:24 PMJan 5
to David Baron, AyeAye, Chromium LUCI CQ, blink-re...@chromium.org, blink-revie...@chromium.org, blink-rev...@chromium.org, blink-...@chromium.org, jmedle...@chromium.org, kinuko...@chromium.org
Attention needed from Joey Arhar

David Baron added 1 comment

File third_party/blink/renderer/core/html/forms/html_selected_content_element.cc
Line 55, Patchset 6: // The HTML spec has a "break" here, but we continue instead because we
David Baron . unresolved

I don't see this "break" in the spec (reading the [post-connection steps](https://html.spec.whatwg.org/multipage/form-elements.html#the-selectedcontent-element:html-element-post-connection-steps)). (Though I also don't see anything that makes the code wrong, just the comment.)

Joey Arhar

A break is being added here: https://github.com/whatwg/html/pull/11878

I added a link to it in the commit message.

I suppose that I could wait for the PR to be merged first, but I found it helpful to implement in order to review that PR.

David Baron

I think it's also probably ok to set `update_select` to false in the case a few lines lower where you set `disabled_` to true because of nested selects.

(I think the case where updating is clearly needed is the case where you're inserting a `<selectedcontent>` inside an `<option>`.)

Joey Arhar

I set update_select to false in that case, but it still times out on selectedcontent-in-option-crash.html

David Baron

Did you try my test in https://github.com/whatwg/html/pull/11878#discussion_r2603233851 ? Do you know if it has the problem that I hypothesized (leaving a `<selectedcontent>` with stale content) without the change I'm suggesting?

(It might be worth adding that as a test.)

Open in Gerrit

Related details

Attention is currently required from:
  • Joey Arhar
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I904f83292ec6e6619eb72cdddfc740440edcc753
Gerrit-Change-Number: 7127725
Gerrit-PatchSet: 10
Gerrit-Owner: Joey Arhar <jar...@chromium.org>
Gerrit-Reviewer: David Baron <dba...@chromium.org>
Gerrit-Reviewer: Joey Arhar <jar...@chromium.org>
Gerrit-Attention: Joey Arhar <jar...@chromium.org>
Gerrit-Comment-Date: Mon, 05 Jan 2026 20:35:17 +0000
satisfied_requirement
unsatisfied_requirement
open
diffy

Joey Arhar (Gerrit)

unread,
Jan 15, 2026, 1:40:53 PMJan 15
to David Baron, AyeAye, Chromium LUCI CQ, blink-re...@chromium.org, blink-revie...@chromium.org, blink-rev...@chromium.org, blink-...@chromium.org, jmedle...@chromium.org, kinuko...@chromium.org
Attention needed from David Baron

Joey Arhar added 1 comment

File third_party/blink/renderer/core/html/forms/html_selected_content_element.cc
Line 55, Patchset 6: // The HTML spec has a "break" here, but we continue instead because we
David Baron . unresolved

I don't see this "break" in the spec (reading the [post-connection steps](https://html.spec.whatwg.org/multipage/form-elements.html#the-selectedcontent-element:html-element-post-connection-steps)). (Though I also don't see anything that makes the code wrong, just the comment.)

Joey Arhar

A break is being added here: https://github.com/whatwg/html/pull/11878

I added a link to it in the commit message.

I suppose that I could wait for the PR to be merged first, but I found it helpful to implement in order to review that PR.

David Baron

I think it's also probably ok to set `update_select` to false in the case a few lines lower where you set `disabled_` to true because of nested selects.

(I think the case where updating is clearly needed is the case where you're inserting a `<selectedcontent>` inside an `<option>`.)

Joey Arhar

I set update_select to false in that case, but it still times out on selectedcontent-in-option-crash.html

David Baron

Did you try my test in https://github.com/whatwg/html/pull/11878#discussion_r2603233851 ? Do you know if it has the problem that I hypothesized (leaving a `<selectedcontent>` with stale content) without the change I'm suggesting?

(It might be worth adding that as a test.)

Joey Arhar

Yes, it has the selectedcontent with stale content issue. As I mentioned in that github thread, I don't believe we should try to fix this case.

I removed the update_select flag to match the current state of the spec PR. Can you review the spec as well like Anne asked?

Open in Gerrit

Related details

Attention is currently required from:
  • David Baron
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I904f83292ec6e6619eb72cdddfc740440edcc753
Gerrit-Change-Number: 7127725
Gerrit-PatchSet: 10
Gerrit-Owner: Joey Arhar <jar...@chromium.org>
Gerrit-Reviewer: David Baron <dba...@chromium.org>
Gerrit-Reviewer: Joey Arhar <jar...@chromium.org>
Gerrit-Attention: David Baron <dba...@chromium.org>
Gerrit-Comment-Date: Thu, 15 Jan 2026 18:40:39 +0000
satisfied_requirement
unsatisfied_requirement
open
diffy

Joey Arhar (Gerrit)

unread,
Jan 15, 2026, 4:31:57 PMJan 15
to David Baron, AyeAye, Chromium LUCI CQ, blink-re...@chromium.org, blink-revie...@chromium.org, blink-rev...@chromium.org, blink-...@chromium.org, jmedle...@chromium.org, kinuko...@chromium.org
Attention needed from David Baron

Joey Arhar voted Commit-Queue+1

Commit-Queue+1
Open in Gerrit

Related details

Attention is currently required from:
  • David Baron
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I904f83292ec6e6619eb72cdddfc740440edcc753
Gerrit-Change-Number: 7127725
Gerrit-PatchSet: 11
Gerrit-Owner: Joey Arhar <jar...@chromium.org>
Gerrit-Reviewer: David Baron <dba...@chromium.org>
Gerrit-Reviewer: Joey Arhar <jar...@chromium.org>
Gerrit-Attention: David Baron <dba...@chromium.org>
Gerrit-Comment-Date: Thu, 15 Jan 2026 21:31:48 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
satisfied_requirement
unsatisfied_requirement
open
diffy

David Baron (Gerrit)

unread,
Jan 20, 2026, 1:51:36 PMJan 20
to David Baron, AyeAye, Chromium LUCI CQ, blink-re...@chromium.org, blink-revie...@chromium.org, blink-rev...@chromium.org, blink-...@chromium.org, jmedle...@chromium.org, kinuko...@chromium.org
Attention needed from Joey Arhar

David Baron added 7 comments

Patchset-level comments
File-level comment, Patchset 12 (Latest):
David Baron . unresolved

So I've pointed out a bunch of issues below -- although my suspicion is that the list probably isn't complete.

I think it would probably help to decide what invariants should be maintained and then try to maintain them. I think that's true at a code level, for example, what exactly should `descendant_selectedcontents_` contain, what exactly should `nearest_ancestor_select_` be set to, etc. I think it's probably also true at an HTML spec level (when should a given `<selectedcontents>` element reflect the contents of the selected option), although I think I have a little less influence over the HTML spec part (particularly given the PR is already merged). (Below I've pointed out some issues related to both of these questions, though I don't think the list of either is complete.)

File third_party/blink/renderer/core/html/forms/html_select_element.cc
Line 1856, Patchset 12 (Latest): descendant_selectedcontent->CloneContentsFromOptionElement(nullptr);
David Baron . unresolved

For what it's worth, `CloneContentsFromOptionElement` bails out if the `selectedcontent` is disabled, which doesn't match the spec. The spec says that you shouldn't get to this code at all if the newly-inserted `selectedcontent` is disabled (which is true), but then it says you should in fact clear any `selectedcontent` elements that aren't the first, whether or not they're disabled.

(I think perhaps it would make more sense to also clear the first if it is disabled! I think maybe that would be an alternative fix for some of my consistency concerns.)

(I think the reason behind those consistency concerns is that I think the original rationale for algorithmic specs is that they make it much clearer how to deal with conflicts between different aspects of descriptive specs. However, I still think it's good for the underlying behavior to be something you can describe in a straightforward way without having to run the whole algorithm, and I don't think that's what's happening here. And in particular I think the behavior here is dependent on the order of mutations that led to the current DOM in ways that I don't think it needs to be, whereas in general I think it's good for the algorithms in the spec to follow the rule that the order of mutations leading to a particular DOM shouldn't affect the behavior of that static DOM.)

File third_party/blink/renderer/core/html/forms/html_selected_content_element.cc
Line 69, Patchset 12 (Latest): select->SelectedContentElementInserted(this);
David Baron . unresolved

So here you're calling `SelectedContentElementInserted` on a select element that this element may have *already* been inserted in. In particular, `nearest_ancestor_select_` may well have already been set to it at the start of this function (for example, if the entire select element was in a subtree that was removed, and it's now being inserted into something else).

In that case, you're going to call `TreeOrderedList::Add` *again* and I think end up with it in the list twice... which means on removal you're going to end up with it still in the list.

More generally, I think this CL could use clearer invariants about what rules are supposed to hold for `nearest_ancestor_select_`, `descendant_selectedcontents_`, etc. -- I think right now it's pretty easy to poke holes here.

Line 74, Patchset 12 (Latest): !nearest_ancestor_select_->IsMultiple()) {
David Baron . unresolved

Should the spec mention this `IsMultiple()` condition somewhere?

Line 106, Patchset 12 (Latest): return;
David Baron . unresolved

Doesn't this risk leaving `nearest_ancestor_select_` in a weird state? Would it make more sense for the `disabled_` check to guard only the call to `SelectedContentElementRemoved` (which I think still matches the spec behavior but doesn't leave the potentially-weird `nearest_ancestor_select_`)?

Line 107, Patchset 6: // the behavior is the same.
David Baron . resolved

Is the behavior the same? Won't there be detectable mutations here that the spec says shouldn't happen?

Joey Arhar

I added DCHECKs with logic which more closely matches the spec. How does it look?

David Baron

Acknowledged

Line 114, Patchset 12 (Latest): Traversal<HTMLSelectElement>::FirstAncestor(removed_from)) {
David Baron . unresolved
What if `removed_from` was the `<select>`?
```suggestion
Traversal<HTMLSelectElement>::FirstAncestorOrSelf(removed_from)) {
```
Open in Gerrit

Related details

Attention is currently required from:
  • Joey Arhar
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I904f83292ec6e6619eb72cdddfc740440edcc753
Gerrit-Change-Number: 7127725
Gerrit-PatchSet: 12
Gerrit-Owner: Joey Arhar <jar...@chromium.org>
Gerrit-Reviewer: David Baron <dba...@chromium.org>
Gerrit-Reviewer: Joey Arhar <jar...@chromium.org>
Gerrit-Attention: Joey Arhar <jar...@chromium.org>
Gerrit-Comment-Date: Tue, 20 Jan 2026 18:51:30 +0000
satisfied_requirement
unsatisfied_requirement
open
diffy

Joey Arhar (Gerrit)

unread,
7:57 PM (4 hours ago) 7:57 PM
to David Baron, AyeAye, Chromium LUCI CQ, blink-re...@chromium.org, blink-revie...@chromium.org, blink-rev...@chromium.org, blink-...@chromium.org, jmedle...@chromium.org, kinuko...@chromium.org
Attention needed from David Baron

Joey Arhar voted and added 6 comments

Votes added by Joey Arhar

Commit-Queue+1

6 comments

Patchset-level comments
David Baron . unresolved

So I've pointed out a bunch of issues below -- although my suspicion is that the list probably isn't complete.

I think it would probably help to decide what invariants should be maintained and then try to maintain them. I think that's true at a code level, for example, what exactly should `descendant_selectedcontents_` contain, what exactly should `nearest_ancestor_select_` be set to, etc. I think it's probably also true at an HTML spec level (when should a given `<selectedcontents>` element reflect the contents of the selected option), although I think I have a little less influence over the HTML spec part (particularly given the PR is already merged). (Below I've pointed out some issues related to both of these questions, though I don't think the list of either is complete.)

Joey Arhar

I think there will be more significant changes coming due to this: https://github.com/whatwg/html/issues/12096#issuecomment-3817882213

Hopefully this simplifies things by removing the invariant that the first selectedcontent element in dom order is the one that is always up to date.

I still want to get this patch merged in order to get the next one merged and keep things moving to avoid more situations like this: https://github.com/whatwg/html/pull/11891#issuecomment-3744421971

File third_party/blink/renderer/core/html/forms/html_select_element.cc
Line 1856, Patchset 12: descendant_selectedcontent->CloneContentsFromOptionElement(nullptr);
David Baron . unresolved

For what it's worth, `CloneContentsFromOptionElement` bails out if the `selectedcontent` is disabled, which doesn't match the spec. The spec says that you shouldn't get to this code at all if the newly-inserted `selectedcontent` is disabled (which is true), but then it says you should in fact clear any `selectedcontent` elements that aren't the first, whether or not they're disabled.

(I think perhaps it would make more sense to also clear the first if it is disabled! I think maybe that would be an alternative fix for some of my consistency concerns.)

(I think the reason behind those consistency concerns is that I think the original rationale for algorithmic specs is that they make it much clearer how to deal with conflicts between different aspects of descriptive specs. However, I still think it's good for the underlying behavior to be something you can describe in a straightforward way without having to run the whole algorithm, and I don't think that's what's happening here. And in particular I think the behavior here is dependent on the order of mutations that led to the current DOM in ways that I don't think it needs to be, whereas in general I think it's good for the algorithms in the spec to follow the rule that the order of mutations leading to a particular DOM shouldn't affect the behavior of that static DOM.)

Joey Arhar

Yeah I will try following up on checking disabled in that method. Hopefully I can add an assert to the spec that it isn't disabled in that case: https://chromium-review.googlesource.com/c/chromium/src/+/7568753

The keeping all selectedcontent elements up to date thing will also likely impact this.

I am also tweaking that in the next followup which I hope to merge very soon: https://chromium-review.googlesource.com/c/chromium/src/+/7128135/6/third_party/blink/renderer/core/html/forms/html_selected_content_element.cc

File third_party/blink/renderer/core/html/forms/html_selected_content_element.cc
Line 69, Patchset 12: select->SelectedContentElementInserted(this);
David Baron . unresolved

So here you're calling `SelectedContentElementInserted` on a select element that this element may have *already* been inserted in. In particular, `nearest_ancestor_select_` may well have already been set to it at the start of this function (for example, if the entire select element was in a subtree that was removed, and it's now being inserted into something else).

In that case, you're going to call `TreeOrderedList::Add` *again* and I think end up with it in the list twice... which means on removal you're going to end up with it still in the list.

More generally, I think this CL could use clearer invariants about what rules are supposed to hold for `nearest_ancestor_select_`, `descendant_selectedcontents_`, etc. -- I think right now it's pretty easy to poke holes here.

Joey Arhar

I believe I fixed this in the next patch by moving the call to SelectedContentElementInserted to HTMLSelectedContentElement::InsertedInto: https://chromium-review.googlesource.com/c/chromium/src/+/7128135/6/third_party/blink/renderer/core/html/forms/html_selected_content_element.cc

Line 74, Patchset 12: !nearest_ancestor_select_->IsMultiple()) {
David Baron . unresolved

Should the spec mention this `IsMultiple()` condition somewhere?

Joey Arhar

Yes, but I am going to make a spec PR soon to remove all IsMultiple checks as part of this: https://issues.chromium.org/issues/483769482

David Baron . unresolved

Doesn't this risk leaving `nearest_ancestor_select_` in a weird state? Would it make more sense for the `disabled_` check to guard only the call to `SelectedContentElementRemoved` (which I think still matches the spec behavior but doesn't leave the potentially-weird `nearest_ancestor_select_`)?

Joey Arhar

I see, I added a TODO to remove the disabled check after we stop doing cloning during removal.

Line 114, Patchset 12: Traversal<HTMLSelectElement>::FirstAncestor(removed_from)) {
David Baron . resolved
What if `removed_from` was the `<select>`?
```suggestion
Traversal<HTMLSelectElement>::FirstAncestorOrSelf(removed_from)) {
```
Joey Arhar

Done

Open in Gerrit

Related details

Attention is currently required from:
  • David Baron
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I904f83292ec6e6619eb72cdddfc740440edcc753
Gerrit-Change-Number: 7127725
Gerrit-PatchSet: 13
Gerrit-Owner: Joey Arhar <jar...@chromium.org>
Gerrit-Reviewer: David Baron <dba...@chromium.org>
Gerrit-Reviewer: Joey Arhar <jar...@chromium.org>
Gerrit-Attention: David Baron <dba...@chromium.org>
Gerrit-Comment-Date: Thu, 12 Feb 2026 00:57:38 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: Yes
Comment-In-Reply-To: David Baron <dba...@chromium.org>
satisfied_requirement
unsatisfied_requirement
open
diffy
Reply all
Reply to author
Forward
0 new messages