Make <selectedcontent> work with <select multiple> [chromium/src : main]

0 views
Skip to first unread message

Mason Freed (Gerrit)

unread,
Apr 6, 2026, 7:53:15 PMApr 6
to Una Kravets, AyeAye, Chromium LUCI CQ, jmedle...@chromium.org, kinuko...@chromium.org, blink-rev...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org
Attention needed from Joey Arhar

Mason Freed added 1 comment

Patchset-level comments
File-level comment, Patchset 3 (Latest):
Mason Freed . resolved

Una is curious about this functionality. Any ETA For landing it?

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 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: I6e8f8d272aac38db534ba54a8bf3c74df670c8c7
Gerrit-Change-Number: 6767467
Gerrit-PatchSet: 3
Gerrit-Owner: Joey Arhar <jar...@chromium.org>
Gerrit-Reviewer: Joey Arhar <jar...@chromium.org>
Gerrit-CC: Mason Freed <mas...@chromium.org>
Gerrit-CC: Una Kravets <unakr...@google.com>
Gerrit-Attention: Joey Arhar <jar...@chromium.org>
Gerrit-Comment-Date: Mon, 06 Apr 2026 23:53:05 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
satisfied_requirement
unsatisfied_requirement
open
diffy

Mason Freed (Gerrit)

unread,
Apr 13, 2026, 5:53:57 PM (9 days ago) Apr 13
to Una Kravets, android-bu...@system.gserviceaccount.com, chromiu...@luci-project-accounts.iam.gserviceaccount.com, jmedle...@chromium.org, kinuko...@chromium.org, blink-rev...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org
Attention needed from Joey Arhar

Mason Freed voted and added 10 comments

Votes added by Mason Freed

Code-Review+1

10 comments

Patchset-level comments
Mason Freed . resolved

Looks good I think! Just some smaller things.

File third_party/blink/renderer/core/html/forms/html_select_element.h
Line 372, Patchset 3 (Latest): void UpdateSelectedcontent(HTMLSelectedContentElement&);
Mason Freed . unresolved

I think something like `UpdateContainedSelectedcontentElement()` might be a bit better? It's confusing to have both `UpdateAllSelectedcontents*` and `UpdateSelectedcontent`, and one updates all for the current `<select>` and the other updates just a single `<selectedcontent>` that is assumed to be within this select.

Line 370, Patchset 3 (Latest): // elemnts into the provided selectedcontent element. This is called when the
Mason Freed . unresolved

Please fix this WARNING reported by Spellchecker: "elemnts" is a possible misspelling of "elements".

To bypass Spellchecker, add ...

"elemnts" is a possible misspelling of "elements".

To bypass Spellchecker, add a footer with DISABLE_SPELLCHECKER

Line 366, Patchset 3 (Latest): // can use the cached currently selected option element as an optimization.
Mason Freed . unresolved

uber-nit: `currently-selected`

File third_party/blink/renderer/core/html/forms/html_select_element.cc
Line 1173, Patchset 3 (Latest): }
Mason Freed . unresolved

Shouldn't this branch have an `UpdateAllSelectedcontentsMultiple()` somewhere?

Line 1992, Patchset 3 (Latest): for (HTMLSelectedContentElement* selectedcontent :
Mason Freed . unresolved

this would probably be easier to read as `auto*`.

Line 2000, Patchset 3 (Latest): if (IsMultiple()) {
Mason Freed . unresolved

Can you `DCHECK()` in here that the provided `<selectedcontent>` is contained within this `<select>`?

File third_party/blink/renderer/core/html/forms/html_selected_content_element.h
Line 24, Patchset 3 (Latest): void CloneContentsFromOptionElement(const HTMLOptionElement*);
Mason Freed . unresolved

Would be good to have a comment here also, about the difference between the two.

File third_party/blink/renderer/core/html/forms/html_selected_content_element.cc
Line 51, Patchset 3 (Latest): for (Node& child : NodeTraversal::ChildrenOf(*option)) {
container->appendChild(child.cloneNode(/*deep=*/true));
}
Mason Freed . unresolved

How come you can't use `ReplaceChildren()` here too?

File third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select-multiple-popup/selectedcontent-multiple.tentative.html
Line 36, Patchset 3 (Latest):
test(() => {
const optionOne = document.querySelector('option.one');
const optionTwo = document.querySelector('option.two');
const optionThree = document.querySelector('option.three');
const selectedcontent = document.querySelector('selectedcontent');

assert_equals(selectedcontent.innerHTML, expectedHtml([optionOne, optionTwo]),
'The innerHTML of <selectedcontent> should initially match the innerHTML of the initially selected options.');

optionTwo.selected = false;
assert_equals(selectedcontent.innerHTML, expectedHtml([optionOne]),
'The innerHTML of <selectedcontent> should update after de-selecting option two.');

optionThree.selected = true;
assert_equals(selectedcontent.innerHTML, expectedHtml([optionOne, optionThree]),
'The innerHTML of <selectedcontent> should update after selecting option three.');
}, '<selectedcontent> should support <select multiple>.');
</script>
Mason Freed . unresolved

It would be good to check the corner cases, like adding and removing selected options, and adding and removing `<selectedcontents>`.

Open in Gerrit

Related details

Attention is currently required from:
  • Joey Arhar
Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement satisfiedCode-Owners
    • requirement 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: I6e8f8d272aac38db534ba54a8bf3c74df670c8c7
    Gerrit-Change-Number: 6767467
    Gerrit-PatchSet: 3
    Gerrit-Owner: Joey Arhar <jar...@chromium.org>
    Gerrit-Reviewer: Joey Arhar <jar...@chromium.org>
    Gerrit-Reviewer: Mason Freed <mas...@chromium.org>
    Gerrit-CC: Una Kravets <unakr...@google.com>
    Gerrit-Attention: Joey Arhar <jar...@chromium.org>
    Gerrit-Comment-Date: Mon, 13 Apr 2026 21:53:43 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: Yes
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Joey Arhar (Gerrit)

    unread,
    Apr 15, 2026, 6:05:55 PM (7 days ago) Apr 15
    to Mason Freed, Una Kravets, android-bu...@system.gserviceaccount.com, Chromium LUCI CQ, jmedle...@chromium.org, kinuko...@chromium.org, blink-rev...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org
    Attention needed from Mason Freed

    Joey Arhar added 9 comments

    File third_party/blink/renderer/core/html/forms/html_select_element.h
    Line 372, Patchset 3 (Latest): void UpdateSelectedcontent(HTMLSelectedContentElement&);
    Mason Freed . unresolved

    I think something like `UpdateContainedSelectedcontentElement()` might be a bit better? It's confusing to have both `UpdateAllSelectedcontents*` and `UpdateSelectedcontent`, and one updates all for the current `<select>` and the other updates just a single `<selectedcontent>` that is assumed to be within this select.

    Joey Arhar

    I renamed it to UpdateIndividualSelectedContent. How does that look?

    Line 370, Patchset 3 (Latest): // elemnts into the provided selectedcontent element. This is called when the
    Mason Freed . resolved

    Please fix this WARNING reported by Spellchecker: "elemnts" is a possible misspelling of "elements".

    To bypass Spellchecker, add ...

    "elemnts" is a possible misspelling of "elements".

    To bypass Spellchecker, add a footer with DISABLE_SPELLCHECKER

    Joey Arhar

    Done

    Line 366, Patchset 3 (Latest): // can use the cached currently selected option element as an optimization.
    Mason Freed . resolved

    uber-nit: `currently-selected`

    Joey Arhar

    Done

    File third_party/blink/renderer/core/html/forms/html_select_element.cc
    Mason Freed . resolved

    Shouldn't this branch have an `UpdateAllSelectedcontentsMultiple()` somewhere?

    Joey Arhar

    done and added a test for it

    Line 1992, Patchset 3 (Latest): for (HTMLSelectedContentElement* selectedcontent :
    Mason Freed . unresolved

    this would probably be easier to read as `auto*`.

    Joey Arhar

    David keeps telling me to not use auto* in cases like this, I suspect that the style guide says not to use auto here.

    Mason Freed . resolved

    Can you `DCHECK()` in here that the provided `<selectedcontent>` is contained within this `<select>`?

    Joey Arhar

    Done

    File third_party/blink/renderer/core/html/forms/html_selected_content_element.h
    Line 24, Patchset 3 (Latest): void CloneContentsFromOptionElement(const HTMLOptionElement*);
    Mason Freed . resolved

    Would be good to have a comment here also, about the difference between the two.

    Joey Arhar

    Done

    File third_party/blink/renderer/core/html/forms/html_selected_content_element.cc
    Line 51, Patchset 3 (Latest): for (Node& child : NodeTraversal::ChildrenOf(*option)) {
    container->appendChild(child.cloneNode(/*deep=*/true));
    }
    Mason Freed . unresolved

    How come you can't use `ReplaceChildren()` here too?

    Joey Arhar

    This NodeTraversal::ChildrenOf(*option) loop is called in the same way as it is in the single-select method. If I wanted to use ReplaceChildren to replace the children of each generated <div> with the cloned children the option elements, then I'd have to create a vector to hold all the generated nodes with so I can pass them all to ReplaceChildren(), which would be more code than it looks like here - unless you have a more specific suggestion that I'm not seeing?

    File third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select-multiple-popup/selectedcontent-multiple.tentative.html
    Line 36, Patchset 3 (Latest):
    test(() => {
    const optionOne = document.querySelector('option.one');
    const optionTwo = document.querySelector('option.two');
    const optionThree = document.querySelector('option.three');
    const selectedcontent = document.querySelector('selectedcontent');

    assert_equals(selectedcontent.innerHTML, expectedHtml([optionOne, optionTwo]),
    'The innerHTML of <selectedcontent> should initially match the innerHTML of the initially selected options.');

    optionTwo.selected = false;
    assert_equals(selectedcontent.innerHTML, expectedHtml([optionOne]),
    'The innerHTML of <selectedcontent> should update after de-selecting option two.');

    optionThree.selected = true;
    assert_equals(selectedcontent.innerHTML, expectedHtml([optionOne, optionThree]),
    'The innerHTML of <selectedcontent> should update after selecting option three.');
    }, '<selectedcontent> should support <select multiple>.');
    </script>
    Mason Freed . resolved

    It would be good to check the corner cases, like adding and removing selected options, and adding and removing `<selectedcontents>`.

    Joey Arhar

    Done

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Mason Freed
    Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement satisfiedCode-Owners
    • requirement 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: I6e8f8d272aac38db534ba54a8bf3c74df670c8c7
    Gerrit-Change-Number: 6767467
    Gerrit-PatchSet: 3
    Gerrit-Owner: Joey Arhar <jar...@chromium.org>
    Gerrit-Reviewer: Joey Arhar <jar...@chromium.org>
    Gerrit-Reviewer: Mason Freed <mas...@chromium.org>
    Gerrit-Attention: Mason Freed <mas...@chromium.org>
    Gerrit-Comment-Date: Wed, 15 Apr 2026 22:05:45 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Mason Freed <mas...@chromium.org>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Mason Freed (Gerrit)

    unread,
    Apr 16, 2026, 8:11:31 PM (5 days ago) Apr 16
    to Una Kravets, android-bu...@system.gserviceaccount.com, Chromium LUCI CQ, jmedle...@chromium.org, kinuko...@chromium.org, blink-rev...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org
    Attention needed from Joey Arhar

    Mason Freed voted and added 4 comments

    Votes added by Mason Freed

    Code-Review+1

    4 comments

    Patchset-level comments
    File-level comment, Patchset 5 (Latest):
    Mason Freed . resolved

    Thanks! Still LGTM.

    File third_party/blink/renderer/core/html/forms/html_select_element.h
    Line 372, Patchset 3: void UpdateSelectedcontent(HTMLSelectedContentElement&);
    Mason Freed . resolved

    I think something like `UpdateContainedSelectedcontentElement()` might be a bit better? It's confusing to have both `UpdateAllSelectedcontents*` and `UpdateSelectedcontent`, and one updates all for the current `<select>` and the other updates just a single `<selectedcontent>` that is assumed to be within this select.

    Joey Arhar

    I renamed it to UpdateIndividualSelectedContent. How does that look?

    Mason Freed

    Sure, that works, thanks.,

    File third_party/blink/renderer/core/html/forms/html_select_element.cc
    Line 1992, Patchset 3: for (HTMLSelectedContentElement* selectedcontent :
    Mason Freed . unresolved

    this would probably be easier to read as `auto*`.

    Joey Arhar

    David keeps telling me to not use auto* in cases like this, I suspect that the style guide says not to use auto here.

    Mason Freed

    The style guide basically says "whatever's more readable". And people differ. The approach I use is that if you can read that one line and tell roughly what kind of object `auto` comes out to, then use `auto`. In this case, it's on the fence, but it's a pretty good guess that you'll get a `<selectedcontent>` element, based on all of the `selectedcontent` words in that line.

    I leave it to you! Either way is ok.

    File third_party/blink/renderer/core/html/forms/html_selected_content_element.cc
    Line 51, Patchset 3: for (Node& child : NodeTraversal::ChildrenOf(*option)) {
    container->appendChild(child.cloneNode(/*deep=*/true));
    }
    Mason Freed . unresolved

    How come you can't use `ReplaceChildren()` here too?

    Joey Arhar

    This NodeTraversal::ChildrenOf(*option) loop is called in the same way as it is in the single-select method. If I wanted to use ReplaceChildren to replace the children of each generated <div> with the cloned children the option elements, then I'd have to create a vector to hold all the generated nodes with so I can pass them all to ReplaceChildren(), which would be more code than it looks like here - unless you have a more specific suggestion that I'm not seeing?

    Mason Freed

    No I guess you're right. Maybe we should add a helper version of ReplaceChildren that takes in a `NodeList*` or something? I've seen this problem before.

    Ok to do that later, and this is ok as-is.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Joey Arhar
    Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement satisfiedCode-Owners
    • requirement 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: I6e8f8d272aac38db534ba54a8bf3c74df670c8c7
    Gerrit-Change-Number: 6767467
    Gerrit-PatchSet: 5
    Gerrit-Owner: Joey Arhar <jar...@chromium.org>
    Gerrit-Reviewer: Joey Arhar <jar...@chromium.org>
    Gerrit-Reviewer: Mason Freed <mas...@chromium.org>
    Gerrit-CC: Una Kravets <unakr...@google.com>
    Gerrit-Attention: Joey Arhar <jar...@chromium.org>
    Gerrit-Comment-Date: Fri, 17 Apr 2026 00:11:20 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: Yes
    Comment-In-Reply-To: Mason Freed <mas...@chromium.org>
    Comment-In-Reply-To: Joey Arhar <jar...@chromium.org>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Joey Arhar (Gerrit)

    unread,
    Apr 21, 2026, 1:10:09 AM (yesterday) Apr 21
    to Mason Freed, Una Kravets, android-bu...@system.gserviceaccount.com, Chromium LUCI CQ, jmedle...@chromium.org, kinuko...@chromium.org, blink-rev...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org

    Joey Arhar voted and added 2 comments

    Votes added by Joey Arhar

    Code-Review+1
    Commit-Queue+2

    2 comments

    File third_party/blink/renderer/core/html/forms/html_select_element.cc
    Line 1992, Patchset 3: for (HTMLSelectedContentElement* selectedcontent :
    Mason Freed . resolved

    this would probably be easier to read as `auto*`.

    Joey Arhar

    David keeps telling me to not use auto* in cases like this, I suspect that the style guide says not to use auto here.

    Mason Freed

    The style guide basically says "whatever's more readable". And people differ. The approach I use is that if you can read that one line and tell roughly what kind of object `auto` comes out to, then use `auto`. In this case, it's on the fence, but it's a pretty good guess that you'll get a `<selectedcontent>` element, based on all of the `selectedcontent` words in that line.

    I leave it to you! Either way is ok.

    Joey Arhar

    Acknowledged

    File third_party/blink/renderer/core/html/forms/html_selected_content_element.cc
    Line 51, Patchset 3: for (Node& child : NodeTraversal::ChildrenOf(*option)) {
    container->appendChild(child.cloneNode(/*deep=*/true));
    }
    Mason Freed . resolved

    How come you can't use `ReplaceChildren()` here too?

    Joey Arhar

    This NodeTraversal::ChildrenOf(*option) loop is called in the same way as it is in the single-select method. If I wanted to use ReplaceChildren to replace the children of each generated <div> with the cloned children the option elements, then I'd have to create a vector to hold all the generated nodes with so I can pass them all to ReplaceChildren(), which would be more code than it looks like here - unless you have a more specific suggestion that I'm not seeing?

    Mason Freed

    No I guess you're right. Maybe we should add a helper version of ReplaceChildren that takes in a `NodeList*` or something? I've seen this problem before.

    Ok to do that later, and this is ok as-is.

    Joey Arhar

    Acknowledged

    Open in Gerrit

    Related details

    Attention set is empty
    Submit Requirements:
      • requirement satisfiedCode-Coverage
      • requirement satisfiedCode-Owners
      • requirement satisfiedCode-Review
      • requirement 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: I6e8f8d272aac38db534ba54a8bf3c74df670c8c7
      Gerrit-Change-Number: 6767467
      Gerrit-PatchSet: 5
      Gerrit-Owner: Joey Arhar <jar...@chromium.org>
      Gerrit-Reviewer: Joey Arhar <jar...@chromium.org>
      Gerrit-Reviewer: Mason Freed <mas...@chromium.org>
      Gerrit-CC: Una Kravets <unakr...@google.com>
      Gerrit-Comment-Date: Tue, 21 Apr 2026 05:09:58 +0000
      satisfied_requirement
      open
      diffy

      Blink W3C Test Autoroller (Gerrit)

      unread,
      Apr 21, 2026, 1:36:47 AM (yesterday) Apr 21
      to Mason Freed, Una Kravets, android-bu...@system.gserviceaccount.com, Chromium LUCI CQ, jmedle...@chromium.org, kinuko...@chromium.org, blink-rev...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org
      Attention needed from Joey Arhar

      Message from Blink W3C Test Autoroller

      Exportable changes to web-platform-tests were detected in this CL and a pull request in the upstream repo has been made: https://github.com/web-platform-tests/wpt/pull/59376.

      When this CL lands, the bot will automatically merge the PR on GitHub if the required GitHub checks pass; otherwise, ecosystem-infra@ team will triage the failures and may contact you.

      WPT Export docs:
      https://chromium.googlesource.com/chromium/src/+/main/docs/testing/web_platform_tests.md#Automatic-export-process

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Joey Arhar
      Submit Requirements:
      • requirement satisfiedCode-Coverage
      • requirement satisfiedCode-Owners
      • requirement satisfiedCode-Review
      • requirement 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: I6e8f8d272aac38db534ba54a8bf3c74df670c8c7
      Gerrit-Change-Number: 6767467
      Gerrit-PatchSet: 5
      Gerrit-Owner: Joey Arhar <jar...@chromium.org>
      Gerrit-Reviewer: Joey Arhar <jar...@chromium.org>
      Gerrit-Reviewer: Mason Freed <mas...@chromium.org>
      Gerrit-CC: Blink W3C Test Autoroller <blink-w3c-te...@chromium.org>
      Gerrit-Attention: Joey Arhar <jar...@chromium.org>
      Gerrit-Comment-Date: Tue, 21 Apr 2026 05:36:40 +0000
      Gerrit-HasComments: No
      Gerrit-Has-Labels: No
      satisfied_requirement
      open
      diffy
      Reply all
      Reply to author
      Forward
      0 new messages