0

Add slot=selected-value support for <selectmenu>

We decided to support this in OpenUI:
https://github.com/openui/open-ui/issues/657#issuecomment-1414262186

This patch also adds a test for ::part(selected-value) which as far as I
can tell was not tested before.

Bug: 1121840
Change-Id: I90b18d12249872239bd41e1be460ed46176fd17b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4220472
Auto-Submit: Joey Arhar <jarhar@chromium.org>
Reviewed-by: Xiaocheng Hu <xiaochengh@chromium.org>
Commit-Queue: Joey Arhar <jarhar@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1102933}
This commit is contained in:
Joey Arhar
2023-02-08 21:54:47 +00:00
committed by Chromium LUCI CQ
parent 2f0b1326fa
commit 33e4ae6907
10 changed files with 77 additions and 7 deletions

@@ -4,9 +4,10 @@ rootWebArea focusable
++++++genericContainer ++++++genericContainer
++++++++genericContainer ignored ++++++++genericContainer ignored
++++++++++comboBoxMenuButton collapsed focusable value='Option 1' haspopup=listbox ++++++++++comboBoxMenuButton collapsed focusable value='Option 1' haspopup=listbox
++++++++++++genericContainer ++++++++++++genericContainer ignored
++++++++++++++staticText name='Option 1' ++++++++++++++genericContainer
++++++++++++++++inlineTextBox name='Option 1' ++++++++++++++++staticText name='Option 1'
++++++++++++++++++inlineTextBox name='Option 1'
++++++++++++genericContainer ignored ++++++++++++genericContainer ignored
++++++++++++++genericContainer ignored ++++++++++++++genericContainer ignored
++++++++genericContainer ignored ++++++++genericContainer ignored

@@ -4,9 +4,10 @@ UNKNOWN focusable has_input_focus
++++++UNKNOWN ++++++UNKNOWN
++++++++UNKNOWN hidden ++++++++UNKNOWN hidden
++++++++++UNKNOWN focusable actions='{DEFAULT}' value='Option 1' ++++++++++UNKNOWN focusable actions='{DEFAULT}' value='Option 1'
++++++++++++UNKNOWN actions='{DEFAULT}' ++++++++++++UNKNOWN hidden
++++++++++++++STATIC_TEXT label='Option 1' actions='{DEFAULT}' ++++++++++++++UNKNOWN actions='{DEFAULT}'
++++++++++++++++UNKNOWN label='Option 1' ++++++++++++++++STATIC_TEXT label='Option 1' actions='{DEFAULT}'
++++++++++++++++++UNKNOWN label='Option 1'
++++++++++++UNKNOWN hidden ++++++++++++UNKNOWN hidden
++++++++++++++UNKNOWN hidden ++++++++++++++UNKNOWN hidden
++++++++UNKNOWN hidden ++++++++UNKNOWN hidden

@@ -242,6 +242,10 @@ void HTMLSelectMenuElement::DidAddUserAgentShadowRoot(ShadowRoot& root) {
button_part_->addEventListener(event_type_names::kKeydown, button_part_->addEventListener(event_type_names::kKeydown,
button_part_listener_, /*use_capture=*/false); button_part_listener_, /*use_capture=*/false);
selected_value_slot_ = MakeGarbageCollected<HTMLSlotElement>(document);
selected_value_slot_->setAttribute(html_names::kNameAttr,
kSelectedValuePartName);
selected_value_part_ = MakeGarbageCollected<HTMLDivElement>(document); selected_value_part_ = MakeGarbageCollected<HTMLDivElement>(document);
selected_value_part_->setAttribute(html_names::kPartAttr, selected_value_part_->setAttribute(html_names::kPartAttr,
kSelectedValuePartName); kSelectedValuePartName);
@@ -269,9 +273,11 @@ void HTMLSelectMenuElement::DidAddUserAgentShadowRoot(ShadowRoot& root) {
auto* options_slot = MakeGarbageCollected<HTMLSlotElement>(document); auto* options_slot = MakeGarbageCollected<HTMLSlotElement>(document);
button_part_->AppendChild(selected_value_part_); button_part_->AppendChild(selected_value_slot_);
button_part_->AppendChild(marker_slot_); button_part_->AppendChild(marker_slot_);
selected_value_slot_->AppendChild(selected_value_part_);
marker_slot_->AppendChild(marker_icon); marker_slot_->AppendChild(marker_icon);
button_slot_->AppendChild(button_part_); button_slot_->AppendChild(button_part_);
@@ -1048,6 +1054,7 @@ void HTMLSelectMenuElement::Trace(Visitor* visitor) const {
visitor->Trace(button_slot_); visitor->Trace(button_slot_);
visitor->Trace(listbox_slot_); visitor->Trace(listbox_slot_);
visitor->Trace(marker_slot_); visitor->Trace(marker_slot_);
visitor->Trace(selected_value_slot_);
visitor->Trace(selected_option_); visitor->Trace(selected_option_);
visitor->Trace(selected_option_when_listbox_opened_); visitor->Trace(selected_option_when_listbox_opened_);
HTMLFormControlElementWithState::Trace(visitor); HTMLFormControlElementWithState::Trace(visitor);

@@ -173,6 +173,7 @@ class CORE_EXPORT HTMLSelectMenuElement final
Member<HTMLSlotElement> button_slot_; Member<HTMLSlotElement> button_slot_;
Member<HTMLSlotElement> listbox_slot_; Member<HTMLSlotElement> listbox_slot_;
Member<HTMLSlotElement> marker_slot_; Member<HTMLSlotElement> marker_slot_;
Member<HTMLSlotElement> selected_value_slot_;
Member<HTMLOptionElement> selected_option_; Member<HTMLOptionElement> selected_option_;
Member<HTMLOptionElement> selected_option_when_listbox_opened_; Member<HTMLOptionElement> selected_option_when_listbox_opened_;
bool queued_check_for_missing_parts_{false}; bool queued_check_for_missing_parts_{false};

@@ -0,0 +1,9 @@
<!DOCTYPE html>
<script src="support/fake-selectmenu.js"></script>
<body>
<script>
const selectmenu = createFakeSelectmenu('hello world');
document.body.appendChild(selectmenu);
selectmenu.querySelector('.fake-selectmenu-selected-value')
.style.color = 'blue';
</script>

@@ -0,0 +1,8 @@
<!DOCTYPE html>
<link rel=author href="mailto:jarhar@chromium.org">
<link rel=match href="selectmenu-selected-value-behavior-ref.html">
<selectmenu>
<div style="color:blue" slot=selected-value behavior=selected-value></div>
<option>hello world</option>
</selectmenu>

@@ -0,0 +1,9 @@
<!DOCTYPE html>
<script src="support/fake-selectmenu.js"></script>
<body>
<script>
const selectmenu = createFakeSelectmenu('hello world');
document.body.appendChild(selectmenu);
selectmenu.querySelector('.fake-selectmenu-selected-value')
.style.backgroundColor = 'red';
</script>

@@ -0,0 +1,12 @@
<!DOCTYPE html>
<link rel=author href="mailto:jarhar@chromium.org">
<link rel=match href="selectmenu-selected-value-part-ref.html">
<style>
selectmenu::part(selected-value) {
background-color: red;
}
</style>
<selectmenu>
<option>hello world</option>
</selectmenu>

@@ -0,0 +1,14 @@
<!DOCTYPE html>
<script src="support/fake-selectmenu.js"></script>
<body>
<script>
const selectmenu = createFakeSelectmenu('hello world');
document.body.appendChild(selectmenu);
const oldSelectedValue = selectmenu.querySelector('.fake-selectmenu-selected-value');
const newSelectedValue = document.createElement('div');
newSelectedValue.textContent = 'new selected value';
const button = selectmenu.querySelector('.fake-selectmenu-internal-selectmenu-button');
button.replaceChild(newSelectedValue, oldSelectedValue);
</script>

@@ -0,0 +1,8 @@
<!DOCTYPE html>
<link rel=author href="mailto:jarhar@chromium.org">
<link rel=match href="selectmenu-selected-value-slot-ref.html">
<selectmenu>
<div slot=selected-value>new selected value</div>
<option>hello world</option>
</selectmenu>