Skip to content

Commit 6b4b5fc

Browse files
committed
REGRESSION (254522@main): HTMLSelectElement's value setter sets incorrect values if there are grouped options
https://bugs.webkit.org/show_bug.cgi?id=251024 rdar://103520364 Reviewed by Ryosuke Niwa. While updating `HTMLSelectElement::listItems` to use `WeakPtr`, 254522@main also modified `HTMLSelectElement::setValue` to use `Vector::findIf` to obtain the index of the selected option. However, `listItems` includes `<optgroup>` elements, resulting in the index of the selected option being offset by the number of `<optgroup>` elements before it. `<optgroup>` elements should be ignored when determining the index of the selected option. To fix, restore the range-based for loop that was used prior to 254522@main. * LayoutTests/fast/forms/select-optgroup-set-value-expected.txt: Added. * LayoutTests/fast/forms/select-optgroup-set-value.html: Added. * Source/WebCore/html/HTMLSelectElement.cpp: (WebCore::HTMLSelectElement::setValue): Canonical link: https://commits.webkit.org/259249@main
1 parent 4006773 commit 6b4b5fc

File tree

3 files changed

+46
-7
lines changed

3 files changed

+46
-7
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Tests that setting the value of a <select> element to an <option> within an <optgroup> sets the correct value.
2+
3+
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
4+
5+
6+
PASS select.value is "A"
7+
PASS select.value is "B"
8+
PASS successfullyParsed is true
9+
10+
TEST COMPLETE
11+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<script src="../../resources/js-test.js"></script>
5+
</head>
6+
<body>
7+
<select id="select">
8+
<optgroup>
9+
<option value="A">A</option>
10+
<option value="B">B</option>
11+
<option value="C">C</option>
12+
</optgroup>
13+
</select>
14+
</body>
15+
<script>
16+
17+
description("Tests that setting the value of a &lt;select&gt; element to an &lt;option&gt; within an &lt;optgroup&gt; sets the correct value.");
18+
19+
shouldBeEqualToString("select.value", "A");
20+
select.value = "B";
21+
shouldBeEqualToString("select.value", "B");
22+
23+
</script>
24+
</html>

Source/WebCore/html/HTMLSelectElement.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -259,14 +259,18 @@ String HTMLSelectElement::value() const
259259
void HTMLSelectElement::setValue(const String& value)
260260
{
261261
// Find the option with value() matching the given parameter and make it the current selection.
262-
auto optionIndex = listItems().findIf([&] (const auto& item) {
263-
if (auto* optionElement = dynamicDowncast<HTMLOptionElement>(item.get()))
264-
return optionElement->value() == value;
265-
266-
return false;
267-
});
262+
unsigned optionIndex = 0;
263+
for (auto& item : listItems()) {
264+
if (auto* option = dynamicDowncast<HTMLOptionElement>(item.get())) {
265+
if (option->value() == value) {
266+
setSelectedIndex(optionIndex);
267+
return;
268+
}
269+
++optionIndex;
270+
}
271+
}
268272

269-
setSelectedIndex(optionIndex);
273+
setSelectedIndex(-1);
270274
}
271275

272276
bool HTMLSelectElement::hasPresentationalHintsForAttribute(const QualifiedName& name) const

0 commit comments

Comments
 (0)