Bug 70547 - selectedIndex gets set from -1 to 0 when modifying options
Summary: selectedIndex gets set from -1 to 0 when modifying options
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Forms (show other bugs)
Version: 528+ (Nightly build)
Hardware: Mac OS X 10.7
: P2 Normal
Assignee: Jon Lee
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2011-10-20 14:16 PDT by Jon Lee
Modified: 2011-10-26 11:36 PDT (History)
3 users (show)

See Also:


Attachments
Patch (7.79 KB, patch)
2011-10-24 16:57 PDT, Jon Lee
darin: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jon Lee 2011-10-20 14:16:04 PDT
1. Set a <select> field's selectedIndex attribute to -1.
2. Change one of the values of the options (e.g. theField.options[2].text = "Something")
3. Observe that selectedIndex is now 0.

<rdar://problem/8388856>
Comment 1 Jon Lee 2011-10-21 16:27:27 PDT
Looks like the culprit is in HTMLSelectElement::recalcListItems(). When we recalculate the list items, it goes through the options, and sets the first option to selected regardless of the select's prior state:

            if (updateSelectedStates && !m_multiple) {
                if (!foundSelected && (m_size <= 1 || optionElement->selected())) {
                    foundSelected = optionElement;
                    foundSelected->setSelectedState(true);
                } else if (foundSelected && optionElement->selected()) {
                    foundSelected->setSelectedState(false);
                    foundSelected = optionElement;
                }
            }

I tried to tighten up the m_size <= 1 check (line 700) but that regressed a lot of tests, so need to rethink.
Comment 2 Jon Lee 2011-10-24 16:57:54 PDT
Created attachment 112277 [details]
Patch
Comment 3 Darin Adler 2011-10-25 14:49:30 PDT
Comment on attachment 112277 [details]
Patch

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

> Source/WebCore/html/HTMLOptionElement.cpp:144
> +    bool selectIsMenuList = select && !select->multiple() && select->size() <= 1;

It’s not great for this to repeat the algorithm for whether the select is a menu list. Instead, the HTMLSelectElement function that answers that question could be made public.

> Source/WebCore/html/HTMLOptionElement.cpp:157
> +        select->setSelectedIndex(oldSelectedIndex);

Is letting the thing get deselected and re-selecting it OK? Are there side effects? Any extra DOM events that get sent?
Comment 4 Jon Lee 2011-10-25 14:56:27 PDT
(In reply to comment #3)
> (From update of attachment 112277 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=112277&action=review
> 
> > Source/WebCore/html/HTMLOptionElement.cpp:144
> > +    bool selectIsMenuList = select && !select->multiple() && select->size() <= 1;
> 
> It’s not great for this to repeat the algorithm for whether the select is a menu list. Instead, the HTMLSelectElement function that answers that question could be made public.

I'll reformulate this to use usesMenuList(), and promote that function to public.

> 
> > Source/WebCore/html/HTMLOptionElement.cpp:157
> > +        select->setSelectedIndex(oldSelectedIndex);
> 
> Is letting the thing get deselected and re-selecting it OK? Are there side effects? Any extra DOM events that get sent?

I checked to see if additional change events get sent, and none do, with or without this patch.
Comment 5 Jon Lee 2011-10-26 11:36:36 PDT
Committed r98505: <http://trac.webkit.org/changeset/98505>