Commit 434e5db5 authored by Kent Tamura's avatar Kent Tamura Committed by Commit Bot

MenuList SELECT: Update text in the shadow element

When UpdateFromElement() is called, textContent of the shadow element
should be updated as well as the text in the anonymous block.
Exceptions:
 * In DidStyleRecalc() and AttachLayoutTree(), we must not update DOM
   at all.
 * Instead, we should update the textContent
  - when the UA shadow tree is created, or
  - even if the SELECT has no LayoutObject

This CL has no user-visible behavior changes because the shadow element
has display:none.

Bug: 1040828
Change-Id: I55f0bfd0399ca50a8aa99c64a8fdf89ef5c42e68
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2032656Reviewed-by: default avatarYoshifumi Inoue <yosin@chromium.org>
Commit-Queue: Kent Tamura <tkent@chromium.org>
Cr-Commit-Position: refs/heads/master@{#737652}
parent 42d1f5e9
......@@ -368,9 +368,9 @@ void HTMLSelectElement::OptionElementChildrenChanged(
const HTMLOptionElement& option) {
SetNeedsValidityCheck();
if (option.Selected() && UsesMenuList())
UpdateMenuListLabel(UpdateFromElement());
if (GetLayoutObject()) {
if (option.Selected() && UsesMenuList())
UpdateFromElement();
if (AXObjectCache* cache =
GetLayoutObject()->GetDocument().ExistingAXObjectCache())
cache->ChildrenChanged(this);
......@@ -916,10 +916,9 @@ void HTMLSelectElement::SetSuggestedOption(HTMLOptionElement* option) {
return;
suggested_option_ = option;
if (GetLayoutObject()) {
UpdateFromElement();
UpdateMenuListLabel(UpdateFromElement());
if (GetLayoutObject())
ScrollToOption(option);
}
if (PopupIsVisible())
popup_->UpdateFromElement(PopupMenu::kBySelectionChange);
}
......@@ -1093,7 +1092,7 @@ void HTMLSelectElement::SelectOption(HTMLOptionElement* element,
}
// For the menu list case, this is what makes the selected element appear.
UpdateFromElement();
UpdateMenuListLabel(UpdateFromElement());
// PopupMenu::UpdateFromElement() posts an O(N) task.
if (PopupIsVisible() && should_update_popup)
popup_->UpdateFromElement(PopupMenu::kBySelectionChange);
......@@ -2010,6 +2009,7 @@ void HTMLSelectElement::UpdateUserAgentShadowTree(ShadowRoot& root) {
if (UsesMenuList()) {
root.insertBefore(MakeGarbageCollected<MenuListInnerElement>(GetDocument()),
root.firstChild());
UpdateMenuListLabel(UpdateFromElement());
}
}
......@@ -2077,7 +2077,7 @@ void HTMLSelectElement::PopupDidHide() {
void HTMLSelectElement::SetIndexToSelectOnCancel(int list_index) {
index_to_select_on_cancel_ = list_index;
UpdateFromElement();
UpdateMenuListLabel(UpdateFromElement());
}
HTMLOptionElement* HTMLSelectElement::OptionToBeShown() const {
......@@ -2291,12 +2291,9 @@ void HTMLSelectElement::ChangeRendering() {
}
}
void HTMLSelectElement::UpdateFromElement() {
String HTMLSelectElement::UpdateFromElement() {
if (!UsesMenuList())
return;
auto* layout_object = GetLayoutObject();
if (!layout_object)
return;
return String();
HTMLOptionElement* option = OptionToBeShown();
String text = g_empty_string;
......@@ -2330,9 +2327,18 @@ void HTMLSelectElement::UpdateFromElement() {
}
}
ToLayoutMenuList(layout_object)->SetText(text.StripWhiteSpace());
layout_object->UpdateFromElement();
DidUpdateMenuListActiveOption(option);
String stripped = text.StripWhiteSpace();
if (auto* layout_object = GetLayoutObject()) {
ToLayoutMenuList(layout_object)->SetText(stripped);
layout_object->UpdateFromElement();
DidUpdateMenuListActiveOption(option);
}
return stripped;
}
void HTMLSelectElement::UpdateMenuListLabel(const String& label) {
if (UsesMenuList())
InnerElement().setTextContent(label);
}
const ComputedStyle* HTMLSelectElement::OptionStyle() const {
......
......@@ -186,7 +186,10 @@ class CORE_EXPORT HTMLSelectElement final
private:
const AtomicString& FormControlType() const override;
void UpdateFromElement();
// Update style on style or selected OPTION change, and return text to be
// shown.
String UpdateFromElement();
void UpdateMenuListLabel(const String& label);
bool MayTriggerVirtualKeyboard() const override;
......
......@@ -155,6 +155,7 @@ Input after setting suggestedValue:
| "TX"
| <shadow:root>
| <div>
| "TX"
| <slot>
| name="user-agent-custom-assign-slot"
| "input.value: initial value"
......
......@@ -91,6 +91,7 @@ instead of "initial value".
| "inserted value"
| <shadow:root>
| <div>
| "initial value"
| <slot>
| name="user-agent-custom-assign-slot"
| "input.value: initial value"
......
......@@ -43,7 +43,7 @@ Tests DOMSnapshot.getSnapshot method returning input values.
"childNodeIndexes": [
4,
5,
34
35
],
"attributes": [
{
......@@ -67,11 +67,10 @@ Tests DOMSnapshot.getSnapshot method returning input values.
"childNodeIndexes": [
6,
7,
14,
15,
18,
16,
19,
21,
20,
22,
23,
24,
......@@ -81,7 +80,8 @@ Tests DOMSnapshot.getSnapshot method returning input values.
28,
29,
30,
33
31,
34
],
"attributes": [
{
......@@ -104,7 +104,7 @@ Tests DOMSnapshot.getSnapshot method returning input values.
"backendNodeId": "<number>",
"childNodeIndexes": [
8,
9
10
],
"layoutNodeIndex": 4
},
......@@ -113,6 +113,16 @@ Tests DOMSnapshot.getSnapshot method returning input values.
"nodeName": "DIV",
"nodeValue": "",
"backendNodeId": "<number>",
"childNodeIndexes": [
9
],
"shadowRootType": "user-agent"
},
{
"nodeType": 3,
"nodeName": "#text",
"nodeValue": "Option 1",
"backendNodeId": "<number>",
"shadowRootType": "user-agent"
},
{
......@@ -121,8 +131,8 @@ Tests DOMSnapshot.getSnapshot method returning input values.
"nodeValue": "",
"backendNodeId": "<number>",
"childNodeIndexes": [
10,
12
11,
13
],
"attributes": [
{
......@@ -139,7 +149,7 @@ Tests DOMSnapshot.getSnapshot method returning input values.
"optionSelected": true,
"backendNodeId": "<number>",
"childNodeIndexes": [
11
12
],
"attributes": [
{
......@@ -162,7 +172,7 @@ Tests DOMSnapshot.getSnapshot method returning input values.
"optionSelected": false,
"backendNodeId": "<number>",
"childNodeIndexes": [
13
14
],
"attributes": [
{
......@@ -192,7 +202,7 @@ Tests DOMSnapshot.getSnapshot method returning input values.
"inputValue": "InputValue",
"backendNodeId": "<number>",
"childNodeIndexes": [
16
17
],
"attributes": [
{
......@@ -213,7 +223,7 @@ Tests DOMSnapshot.getSnapshot method returning input values.
"nodeValue": "",
"backendNodeId": "<number>",
"childNodeIndexes": [
17
18
],
"layoutNodeIndex": 7,
"shadowRootType": "user-agent",
......@@ -242,7 +252,7 @@ Tests DOMSnapshot.getSnapshot method returning input values.
"inputValue": "ButtonValue",
"backendNodeId": "<number>",
"childNodeIndexes": [
20
21
],
"attributes": [
{
......@@ -411,7 +421,7 @@ Tests DOMSnapshot.getSnapshot method returning input values.
"textValue": "TextAreaValue",
"backendNodeId": "<number>",
"childNodeIndexes": [
31
32
],
"attributes": [
{
......@@ -427,7 +437,7 @@ Tests DOMSnapshot.getSnapshot method returning input values.
"nodeValue": "",
"backendNodeId": "<number>",
"childNodeIndexes": [
32
33
],
"layoutNodeIndex": 22,
"shadowRootType": "user-agent",
......
......@@ -82,6 +82,7 @@ instead of "initial value".
| "inserted value"
| <shadow:root>
| <div>
| "initial value"
| <slot>
| name="user-agent-custom-assign-slot"
| "input.value: initial value"
......
......@@ -91,6 +91,7 @@ instead of "initial value".
| "inserted value"
| <shadow:root>
| <div>
| "initial value"
| <slot>
| name="user-agent-custom-assign-slot"
| "input.value: initial value"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment