Bug 235237 - When inserting a selected <option> in a <select> element, its selected state should remain
Summary: When inserting a selected <option> in a <select> element, its selected state ...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Forms (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Chris Dumez
URL:
Keywords: InRadar
Depends on: 235247
Blocks:
  Show dependency treegraph
 
Reported: 2022-01-14 10:16 PST by Chris Dumez
Modified: 2022-01-18 18:33 PST (History)
14 users (show)

See Also:


Attachments
Patch (5.25 KB, patch)
2022-01-14 10:21 PST, Chris Dumez
no flags Details | Formatted Diff | Diff
Patch (20.70 KB, patch)
2022-01-14 16:37 PST, Chris Dumez
no flags Details | Formatted Diff | Diff
Patch (20.84 KB, patch)
2022-01-18 08:21 PST, Chris Dumez
no flags Details | Formatted Diff | Diff
Patch (21.02 KB, patch)
2022-01-18 15:43 PST, Chris Dumez
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Chris Dumez 2022-01-14 10:16:46 PST
When inserting a selected <option> in a <select> element, its selected state should remain and other selected options should be de-selected.

This is as per the specification [1] that says:
"""
If the multiple attribute is absent, whenever an option element in the select element's list of options has its selectedness set to true, and whenever an option element with its selectedness set to true is added to the select element's list of options, the user agent must set the selectedness of all the other option elements in its list of options to false.
"""

Firefox and Chrome correctly implement this. However, in WebKit, after insertion of a new <option>, if there is more than one selected <option> it is the last selected <option> in the list that retains the selected state (not necessarily the newly inserted one).

[1] https://html.spec.whatwg.org/multipage/form-elements.html#the-select-element
Comment 1 Chris Dumez 2022-01-14 10:21:18 PST
Created attachment 449181 [details]
Patch
Comment 2 Chris Dumez 2022-01-14 16:37:49 PST
Created attachment 449232 [details]
Patch
Comment 3 Chris Dumez 2022-01-18 08:21:31 PST
Created attachment 449394 [details]
Patch
Comment 4 Darin Adler 2022-01-18 13:44:39 PST
Comment on attachment 449394 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=449394&action=review

> Source/WebCore/html/HTMLOptGroupElement.cpp:80
> +    for (auto* option = Traversal<HTMLOptionElement>::lastChild(*this); option; option = Traversal<HTMLOptionElement>::previousSibling(*option)) {

Does this work?

    for (auto& option : makeReversedRange(childrenOfType<HTMLOptionElement>(*this))) {

I think it should work and I like it better. But maybe makeReversedRange won’t work until we add rbegin and rend to ElementChildRange? I’d want to do this soon.

> Source/WebCore/html/HTMLSelectElement.cpp:374
>  void HTMLSelectElement::childrenChanged(const ChildChange& change)

Can we find a way to share more of the code between HTMLSelectElement and HTMLOptGroupElement? Helper function or class?
Comment 5 Chris Dumez 2022-01-18 13:55:52 PST
(In reply to Darin Adler from comment #4)
> Comment on attachment 449394 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=449394&action=review
> 
> > Source/WebCore/html/HTMLOptGroupElement.cpp:80
> > +    for (auto* option = Traversal<HTMLOptionElement>::lastChild(*this); option; option = Traversal<HTMLOptionElement>::previousSibling(*option)) {
> 
> Does this work?
> 
>     for (auto& option :
> makeReversedRange(childrenOfType<HTMLOptionElement>(*this))) {
> 
> I think it should work and I like it better. But maybe makeReversedRange
> won’t work until we add rbegin and rend to ElementChildRange? I’d want to do
> this soon.

No, this doesn't work currently:
In file included from /Volumes/Data/WebKit/OpenSource/WebKitBuild/Debug/DerivedSources/WebCore/unified-sources/UnifiedSource173.cpp:4:
./html/HTMLOptGroupElement.cpp:80:25: error: no matching function for call to 'makeReversedRange'
    for (auto& option : makeReversedRange(childrenOfType<HTMLOptionElement>(*this))) {
In file included from /Volumes/Data/WebKit/OpenSource/WebKitBuild/Debug/DerivedSources/WebCore/unified-sources/UnifiedSource173.cpp:1:
In file included from /Volumes/Data/WebKit/OpenSource/Source/WebCore/WebCorePrefix.h:171:
In file included from /Volumes/Data/WebKit/OpenSource/WebKitBuild/Debug/usr/local/include/wtf/HashMap.h:26:
/Volumes/Data/WebKit/OpenSource/WebKitBuild/Debug/usr/local/include/wtf/IteratorRange.h:61:53: note: candidate template ignored: substitution failure [with Container = WebCore::ElementChildRange<WebCore::HTMLOptionElement>]: no type named 'reverse_iterator' in 'WebCore::ElementChildRange<WebCore::HTMLOptionElement>'
IteratorRange<typename Container::reverse_iterator> makeReversedRange(Container& container)
/Volumes/Data/WebKit/OpenSource/WebKitBuild/Debug/usr/local/include/wtf/IteratorRange.h:67:59: note: candidate template ignored: substitution failure [with Container = WebCore::ElementChildRange<WebCore::HTMLOptionElement>]: no type named 'const_reverse_iterator' in 'WebCore::ElementChildRange<WebCore::HTMLOptionElement>'
IteratorRange<typename Container::const_reverse_iterator> makeReversedRange(const Container& container)
1 error generated.


> 
> > Source/WebCore/html/HTMLSelectElement.cpp:374
> >  void HTMLSelectElement::childrenChanged(const ChildChange& change)
> 
> Can we find a way to share more of the code between HTMLSelectElement and
> HTMLOptGroupElement? Helper function or class?

I already tried to share as much as I could. I'll do another pass and see if I can do better.
Comment 6 Darin Adler 2022-01-18 14:22:31 PST
Comment on attachment 449394 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=449394&action=review

>>> Source/WebCore/html/HTMLOptGroupElement.cpp:80
>>> +    for (auto* option = Traversal<HTMLOptionElement>::lastChild(*this); option; option = Traversal<HTMLOptionElement>::previousSibling(*option)) {
>> 
>> Does this work?
>> 
>>     for (auto& option : makeReversedRange(childrenOfType<HTMLOptionElement>(*this))) {
>> 
>> I think it should work and I like it better. But maybe makeReversedRange won’t work until we add rbegin and rend to ElementChildRange? I’d want to do this soon.
> 
> No, this doesn't work currently:
> In file included from /Volumes/Data/WebKit/OpenSource/WebKitBuild/Debug/DerivedSources/WebCore/unified-sources/UnifiedSource173.cpp:4:
> ./html/HTMLOptGroupElement.cpp:80:25: error: no matching function for call to 'makeReversedRange'
>     for (auto& option : makeReversedRange(childrenOfType<HTMLOptionElement>(*this))) {
> In file included from /Volumes/Data/WebKit/OpenSource/WebKitBuild/Debug/DerivedSources/WebCore/unified-sources/UnifiedSource173.cpp:1:
> In file included from /Volumes/Data/WebKit/OpenSource/Source/WebCore/WebCorePrefix.h:171:
> In file included from /Volumes/Data/WebKit/OpenSource/WebKitBuild/Debug/usr/local/include/wtf/HashMap.h:26:
> /Volumes/Data/WebKit/OpenSource/WebKitBuild/Debug/usr/local/include/wtf/IteratorRange.h:61:53: note: candidate template ignored: substitution failure [with Container = WebCore::ElementChildRange<WebCore::HTMLOptionElement>]: no type named 'reverse_iterator' in 'WebCore::ElementChildRange<WebCore::HTMLOptionElement>'
> IteratorRange<typename Container::reverse_iterator> makeReversedRange(Container& container)
> /Volumes/Data/WebKit/OpenSource/WebKitBuild/Debug/usr/local/include/wtf/IteratorRange.h:67:59: note: candidate template ignored: substitution failure [with Container = WebCore::ElementChildRange<WebCore::HTMLOptionElement>]: no type named 'const_reverse_iterator' in 'WebCore::ElementChildRange<WebCore::HTMLOptionElement>'
> IteratorRange<typename Container::const_reverse_iterator> makeReversedRange(const Container& container)
> 1 error generated.

I will fix this and make it usable here after you land.
Comment 7 Chris Dumez 2022-01-18 15:43:50 PST
Created attachment 449436 [details]
Patch
Comment 8 EWS 2022-01-18 18:32:43 PST
Committed r288174 (246158@main): <https://commits.webkit.org/246158@main>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 449436 [details].
Comment 9 Radar WebKit Bug Importer 2022-01-18 18:33:16 PST
<rdar://problem/87746816>