Bug 13287 - Cannot change SELECT to a dynamically created option
Summary: Cannot change SELECT to a dynamically created option
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Forms (show other bugs)
Version: 523.x (Safari 3)
Hardware: Mac OS X 10.4
: P2 Normal
Assignee: Alexey Proskuryakov
URL:
Keywords:
Depends on: 23949
Blocks: 13270
  Show dependency treegraph
 
Reported: 2007-04-05 06:32 PDT by Alexey Proskuryakov
Modified: 2009-03-17 11:00 PDT (History)
0 users

See Also:


Attachments
test case (537 bytes, text/html)
2007-04-05 06:32 PDT, Alexey Proskuryakov
no flags Details
extended test case (1.75 KB, text/html)
2007-04-05 12:03 PDT, Alexey Proskuryakov
no flags Details
proposed fix (14.96 KB, patch)
2008-05-15 13:43 PDT, Alexey Proskuryakov
darin: review-
Details | Formatted Diff | Diff
proposed fix (23.14 KB, patch)
2009-03-17 10:42 PDT, Alexey Proskuryakov
darin: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Alexey Proskuryakov 2007-04-05 06:32:26 PDT
Another issue reduced from trenitalia.com.

    theSelect.insertBefore(new Option("SUCCESS", "SUCCESS", false, true), theSelect.firstChild);
    theSelect.options[0].selected = true; // FAILS

Surprisingly, this is not a regression.
Comment 1 Alexey Proskuryakov 2007-04-05 06:32:49 PDT
Created attachment 13968 [details]
test case
Comment 2 Alexey Proskuryakov 2007-04-05 11:39:46 PDT
These OPTION elements are created selected, but WebKit doesn't let SELECT know that when inserting them. So, OPTION elements think that they are selected, and ignore setting .selected to true.
Comment 3 Alexey Proskuryakov 2007-04-05 12:03:28 PDT
Created attachment 13971 [details]
extended test case
Comment 4 Alexey Proskuryakov 2008-05-15 13:43:22 PDT
Created attachment 21176 [details]
proposed fix
Comment 5 Darin Adler 2008-05-24 22:41:04 PDT
Comment on attachment 21176 [details]
proposed fix

+        if (newChildPtr->isElementNode() && static_cast<Element*>(newChildPtr)->hasLocalName(optionTag) && !m_multiple) {

As far as I can tell, nothing guarantees that the node pointed to by newChild won't be deallocated by this point. You will need to use a RefPtr here. Maybe the right thing to do is to use the "prp" pattern (naming the argument prpNewChild and the local RefPtr newChild).

Ideally we'd make a test case that uses DOM mutation events to make this unlikely even occur.

Isn't there a better hook we can use to deal with the change in children? At the very least I'd like to see the repeated code shared in a single function rather than pasted three times.

Patch otherwise looks good.
Comment 6 Alexey Proskuryakov 2009-03-17 10:42:02 PDT
Created attachment 28692 [details]
proposed fix
Comment 7 Darin Adler 2009-03-17 10:52:04 PDT
Comment on attachment 28692 [details]
proposed fix

> +        (WebCore::dispatchChildInsertionEvents): Increment DOM tree version. This will happen when
> +        dispatching DOMSubtreeModified again, but the version should be incremented for event
> +        listeners to have an up to date view of the DOM.
> +        (WebCore::dispatchChildRemovalEvents): Ditto.

Seems too bad that we later increment the DOM tree version a second time unnecessarily. But no big problem.

> +        (WebCore::HTMLSelectElement::add): This function doesn't look at exception code, so it
> +        doesn't need to reset it.

This sort of change can be risky; the function can accidentally depend on the passed-in exception code being zero. Accordingly, I wish you'd make this change that's not necessarily tied to the rest of the patch in a separate check-in to possibly help people later who might be tracking down a regression.

r=me
Comment 8 Alexey Proskuryakov 2009-03-17 11:00:22 PDT
Committed revision 41772. Will land the "ec = 0" change next.