Skip to content

Commit b5a5a49

Browse files
committed
Reset a <select>'s selectedness when its size or an option's disabledness changes
https://bugs.webkit.org/show_bug.cgi?id=325639 Reviewed by Ryosuke Niwa and Tim Nguyen. whatwg/html#12263 made changing the size or multiple attribute of <select>, or the disabled attribute of <option> or <optgroup>, reset the selectedness of the <select>, updating <selectedcontent> when that changes the selected option. A <select> no longer selects its first option when all of its options are disabled, as the specification requires nothing to be selected then. The parser also no longer selects an option inside a disabled <optgroup> by default, a mistake from 310930@main. Chromium and Gecko already behave this way. Removing the multiple attribute when no option is selected no longer resets the options to their default selectedness and dirtiness. It selects the first enabled option instead. Enabling an <optgroup> now selects its first option when nothing is selected. It used to recalculate the selection before updating its own disabledness. Canonical link: https://commits.webkit.org/322349@main
1 parent afc5c2a commit b5a5a49

15 files changed

Lines changed: 113 additions & 63 deletions

File tree

‎LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-select-element/customizable-select/selectedcontent-attribute-change-expected.txt‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11

2-
FAIL Reducing a select's size to 1 updates selectedcontent. assert_equals: selectedcontent should be updated when reducing the display size to 1. expected "A" but got ""
2+
PASS Reducing a select's size to 1 updates selectedcontent.
33
PASS Removing a select's multiple attribute updates selectedcontent.
4-
FAIL Removing an option's disabled attribute updates selectedcontent. assert_equals: selectedcontent should be updated when enabling an option. expected "C" but got ""
5-
FAIL Removing an optgroup's disabled attribute updates selectedcontent. assert_equals: selectedcontent should be empty while the optgroup is disabled. expected "" but got "D"
4+
PASS Removing an option's disabled attribute updates selectedcontent.
5+
PASS Removing an optgroup's disabled attribute updates selectedcontent.
66
PASS Adding an option's selected attribute updates selectedcontent.
77
PASS An attribute change that does not change selectedness does not update selectedcontent.
88
PASS Removing a select's multiple attribute updates selectedcontent when selectedness does not change.

‎LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-select-element/select-attribute-change-reset-expected.txt‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11

22
PASS Reducing a select's size to 1 selects the first enabled option.
33
PASS Removing a select's multiple attribute selects the first enabled option.
4-
FAIL Removing an option's disabled attribute selects it. assert_equals: No option should be selected while every option is disabled. expected "" but got "C"
5-
FAIL Removing an optgroup's disabled attribute selects the option inside it. assert_equals: No option should be selected while the optgroup is disabled. expected "" but got "E"
4+
PASS Removing an option's disabled attribute selects it.
5+
PASS Removing an optgroup's disabled attribute selects the option inside it.
66
PASS Adding an option's selected attribute deselects the other options.
77
PASS Removing an option's selected attribute falls back to the first enabled option.
88
PASS Removing the selected attribute from a dirty option does not change selectedness.

‎LayoutTests/platform/gtk/fast/forms/basic-selects-expected.txt‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ layer at (174,10) size 56x28
110110
text run at (5,5) width 30: "f o o"
111111
layer at (239,10) size 56x28
112112
RenderBlock {DIV} at (1,1) size 56x28
113-
RenderText {#text} at (5,5) size 30x18
114-
text run at (5,5) width 30: "f o o"
113+
RenderText {#text} at (5,5) size 0x18
114+
text run at (5,5) width 0: " "
115115
layer at (145,56) size 49x28
116116
RenderBlock {DIV} at (1,1) size 49x28
117117
RenderText {#text} at (5,5) size 22x18
@@ -158,8 +158,8 @@ layer at (490,324) size 48x28
158158
text run at (5,5) width 22: "foo"
159159
layer at (547,324) size 48x28
160160
RenderBlock {DIV} at (1,1) size 48x28
161-
RenderText {#text} at (5,5) size 22x18
162-
text run at (5,5) width 22: "foo"
161+
RenderText {#text} at (5,5) size 0x18
162+
text run at (5,5) width 0: " "
163163
layer at (512,370) size 49x28
164164
RenderBlock {DIV} at (1,1) size 49x28
165165
RenderText {#text} at (5,5) size 22x18

‎LayoutTests/platform/ios-18/fast/forms/basic-selects-expected.txt‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ layer at (0,0) size 800x468
1414
text run at (217,0) width 8: "a"
1515
RenderMenuList {SELECT} at (224,1) size 49x20 [color=#007AFF] [bgcolor=#E9E9EA] [border: (1px solid #FFFFFF)]
1616
RenderBlock {DIV} at (6,3) size 36x14
17-
RenderText {#text} at (0,0) size 24x14
18-
text run at (0,0) width 24: "f o o"
17+
RenderText {#text} at (0,0) size 0x14
18+
text run at (0,0) width 0: " "
1919
RenderText {#text} at (272,0) size 9x19
2020
text run at (272,0) width 9: "b"
2121
RenderBR {BR} at (280,0) size 1x19
@@ -110,8 +110,8 @@ layer at (0,0) size 800x468
110110
text run at (532,233) width 8: "a"
111111
RenderMenuList {SELECT} at (539,229) size 42x30 [color=#3C3C434C] [bgcolor=#EEEEEF] [border: (1px solid #FFFFFF)]
112112
RenderBlock {DIV} at (6,8) size 29x14
113-
RenderText {#text} at (0,0) size 17x14
114-
text run at (0,0) width 17: "foo"
113+
RenderText {#text} at (0,0) size 0x14
114+
text run at (0,0) width 0: " "
115115
RenderText {#text} at (580,233) size 9x19
116116
text run at (580,233) width 9: "b"
117117
RenderBR {BR} at (588,233) size 1x19

‎LayoutTests/platform/ios/fast/forms/basic-selects-expected.txt‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ layer at (183,13) size 36x13
110110
text run at (0,0) width 24: "f o o"
111111
layer at (239,13) size 36x13
112112
RenderBlock {DIV} at (6,3) size 36x14
113-
RenderText {#text} at (0,-1) size 24x15
114-
text run at (0,0) width 24: "f o o"
113+
RenderText {#text} at (0,-1) size 0x15
114+
text run at (0,0) width 0: " "
115115
layer at (155,49) size 30x13
116116
RenderBlock {DIV} at (6,3) size 30x14
117117
RenderText {#text} at (0,-1) size 17x15
@@ -158,8 +158,8 @@ layer at (505,257) size 29x13
158158
text run at (0,0) width 17: "foo"
159159
layer at (553,257) size 29x13
160160
RenderBlock {DIV} at (6,8) size 29x14
161-
RenderText {#text} at (0,-1) size 17x15
162-
text run at (0,0) width 17: "foo"
161+
RenderText {#text} at (0,-1) size 0x15
162+
text run at (0,0) width 0: " "
163163
layer at (529,297) size 30x13
164164
RenderBlock {DIV} at (6,1) size 30x13
165165
RenderText {#text} at (0,-1) size 17x15

‎LayoutTests/platform/mac-sequoia-wk2/fast/forms/basic-selects-expected.txt‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ layer at (0,0) size 800x446
1414
text run at (224,0) width 8: "a"
1515
RenderMenuList {SELECT} at (231,1) size 56x18 [bgcolor=#FFFFFF]
1616
RenderBlock {DIV} at (0,0) size 55x18
17-
RenderText {#text} at (8,2) size 24x13
18-
text run at (8,2) width 24: "f o o"
17+
RenderText {#text} at (8,2) size 0x13
18+
text run at (8,2) width 0: " "
1919
RenderText {#text} at (286,0) size 9x18
2020
text run at (286,0) width 9: "b"
2121
RenderBR {BR} at (294,0) size 1x18
@@ -110,8 +110,8 @@ layer at (0,0) size 800x446
110110
text run at (539,224) width 8: "a"
111111
RenderMenuList {SELECT} at (546,225) size 49x18 [color=#0000003F] [bgcolor=#FFFFFF]
112112
RenderBlock {DIV} at (0,0) size 48x18
113-
RenderText {#text} at (8,2) size 17x13
114-
text run at (8,2) width 17: "foo"
113+
RenderText {#text} at (8,2) size 0x13
114+
text run at (8,2) width 0: " "
115115
RenderText {#text} at (594,224) size 9x18
116116
text run at (594,224) width 9: "b"
117117
RenderBR {BR} at (602,224) size 1x18

‎LayoutTests/platform/mac-wk2/fast/forms/basic-selects-expected.txt‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ layer at (0,0) size 800x486
1414
text run at (226,1) width 8: "a"
1515
RenderMenuList {SELECT} at (233,1) size 58x20 [color=#000000D8] [bgcolor=#FFFFFF] [border: (1px solid #000000D8)]
1616
RenderBlock {DIV} at (1,1) size 55x18
17-
RenderText {#text} at (8,2) size 24x13
18-
text run at (8,2) width 24: "f o o"
17+
RenderText {#text} at (8,2) size 0x13
18+
text run at (8,2) width 0: " "
1919
RenderText {#text} at (290,1) size 9x18
2020
text run at (290,1) width 9: "b"
2121
RenderBR {BR} at (298,1) size 1x18
@@ -110,8 +110,8 @@ layer at (0,0) size 800x486
110110
text run at (541,255) width 8: "a"
111111
RenderMenuList {SELECT} at (548,250) size 51x30 [color=#00000042] [bgcolor=#FFFFFF] [border: (1px solid #00000042)]
112112
RenderBlock {DIV} at (1,6) size 48x18
113-
RenderText {#text} at (8,2) size 17x13
114-
text run at (8,2) width 17: "foo"
113+
RenderText {#text} at (8,2) size 0x13
114+
text run at (8,2) width 0: " "
115115
RenderText {#text} at (598,255) size 9x18
116116
text run at (598,255) width 9: "b"
117117
RenderBR {BR} at (606,255) size 1x18

‎LayoutTests/platform/mac/fast/forms/basic-selects-expected.txt‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ layer at (0,0) size 800x477
1414
text run at (226,1) width 8: "a"
1515
RenderMenuList {SELECT} at (233,1) size 58x20 [color=#000000D8] [bgcolor=#FFFFFF] [border: (1px solid #000000D8)]
1616
RenderBlock {DIV} at (1,1) size 55x18
17-
RenderText {#text} at (8,2) size 24x13
18-
text run at (8,2) width 24: "f o o"
17+
RenderText {#text} at (8,2) size 0x13
18+
text run at (8,2) width 0: " "
1919
RenderText {#text} at (290,1) size 9x18
2020
text run at (290,1) width 9: "b"
2121
RenderBR {BR} at (298,1) size 1x18
@@ -110,8 +110,8 @@ layer at (0,0) size 800x477
110110
text run at (541,246) width 8: "a"
111111
RenderMenuList {SELECT} at (548,241) size 51x30 [color=#00000042] [bgcolor=#FFFFFF] [border: (1px solid #00000042)]
112112
RenderBlock {DIV} at (1,6) size 48x18
113-
RenderText {#text} at (8,2) size 17x13
114-
text run at (8,2) width 17: "foo"
113+
RenderText {#text} at (8,2) size 0x13
114+
text run at (8,2) width 0: " "
115115
RenderText {#text} at (598,246) size 9x18
116116
text run at (598,246) width 9: "b"
117117
RenderBR {BR} at (606,246) size 1x18

‎LayoutTests/platform/wpe/fast/forms/basic-selects-expected.txt‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ layer at (174,10) size 55x28
110110
text run at (5,5) width 29: "f o o"
111111
layer at (238,10) size 55x28
112112
RenderBlock {DIV} at (1,1) size 55x28
113-
RenderText {#text} at (5,5) size 29x18
114-
text run at (5,5) width 29: "f o o"
113+
RenderText {#text} at (5,5) size 0x18
114+
text run at (5,5) width 0: " "
115115
layer at (145,56) size 47x28
116116
RenderBlock {DIV} at (1,1) size 47x28
117117
RenderText {#text} at (5,5) size 21x18
@@ -158,8 +158,8 @@ layer at (490,324) size 47x28
158158
text run at (5,5) width 21: "foo"
159159
layer at (546,324) size 47x28
160160
RenderBlock {DIV} at (1,1) size 47x28
161-
RenderText {#text} at (5,5) size 21x18
162-
text run at (5,5) width 21: "foo"
161+
RenderText {#text} at (5,5) size 0x18
162+
text run at (5,5) width 0: " "
163163
layer at (512,370) size 47x28
164164
RenderBlock {DIV} at (1,1) size 47x28
165165
RenderText {#text} at (5,5) size 21x18

‎Source/WebCore/html/HTMLOptGroupElement.cpp‎

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -215,23 +215,41 @@ void HTMLOptGroupElement::childrenChanged(const ChildChange& change)
215215
void HTMLOptGroupElement::attributeChanged(const QualifiedName& name, const AtomString& oldValue, const AtomString& newValue, AttributeModificationReason attributeModificationReason)
216216
{
217217
HTMLElement::attributeChanged(name, oldValue, newValue, attributeModificationReason);
218-
recalcSelectOptions();
219218

220219
if (name == disabledAttr) {
221-
bool newDisabled = !newValue.isNull();
222-
if (m_isDisabled != newDisabled) {
223-
Style::PseudoClassChangeInvalidation disabledInvalidation(*this, { { CSSSelector::PseudoClass::Disabled, newDisabled }, { CSSSelector::PseudoClass::Enabled, !newDisabled } });
220+
parseDisabledAttribute(newValue);
221+
return;
222+
}
224223

225-
Vector<Style::PseudoClassChangeInvalidation> optionInvalidation;
226-
for (Ref descendant : descendantsOfType<HTMLOptionElement>(*this))
227-
optionInvalidation.append({ descendant, { { CSSSelector::PseudoClass::Disabled, newDisabled }, { CSSSelector::PseudoClass::Enabled, !newDisabled } } });
224+
recalcSelectOptions();
228225

229-
m_isDisabled = newDisabled;
230-
}
231-
} else if (name == labelAttr)
226+
if (name == labelAttr)
232227
invalidateShadowTree();
233228
}
234229

230+
void HTMLOptGroupElement::parseDisabledAttribute(const AtomString& value)
231+
{
232+
bool newDisabled = !value.isNull();
233+
if (m_isDisabled == newDisabled)
234+
return;
235+
236+
RefPtr select = ownerSelectElement();
237+
RefPtr oldSelectedOption = select ? select->selectedOptionForSelectedContent() : nullptr;
238+
{
239+
Style::PseudoClassChangeInvalidation disabledInvalidation(*this, { { CSSSelector::PseudoClass::Disabled, newDisabled }, { CSSSelector::PseudoClass::Enabled, !newDisabled } });
240+
241+
Vector<Style::PseudoClassChangeInvalidation> optionInvalidation;
242+
for (Ref descendant : descendantsOfType<HTMLOptionElement>(*this))
243+
optionInvalidation.append({ descendant, { { CSSSelector::PseudoClass::Disabled, newDisabled }, { CSSSelector::PseudoClass::Enabled, !newDisabled } } });
244+
245+
m_isDisabled = newDisabled;
246+
}
247+
248+
recalcSelectOptions();
249+
if (select)
250+
select->resetSelectedness(oldSelectedOption.get());
251+
}
252+
235253
void HTMLOptGroupElement::recalcSelectOptions()
236254
{
237255
if (RefPtr selectElement = ownerSelectElement()) {

0 commit comments

Comments
 (0)