Changeset 121128 in webkit
- Timestamp:
- Jun 24, 2012, 6:47:35 PM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 5 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/fast/forms/select/select-state-restore-expected.txt (added)
-
LayoutTests/fast/forms/select/select-state-restore.html (added)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/html/FormController.cpp (modified) (1 diff)
-
Source/WebCore/html/HTMLSelectElement.cpp (modified) (2 diffs)
-
Source/WebCore/html/HTMLSelectElement.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r121127 r121128 1 2012-06-21 Kent Tamura <tkent@chromium.org> 2 3 Selected option is not restored correctly 4 https://bugs.webkit.org/show_bug.cgi?id=89623 5 6 Reviewed by Hajime Morita. 7 8 * fast/forms/select/select-state-restore-expected.txt: Added. 9 * fast/forms/select/select-state-restore.html: Added. 10 1 11 2012-06-24 David Barr <davidbarr@chromium.org> 2 12 -
trunk/Source/WebCore/ChangeLog
r121127 r121128 1 2012-06-22 Kent Tamura <tkent@chromium.org> 2 3 Selected option is not restored correctly 4 https://bugs.webkit.org/show_bug.cgi?id=89623 5 6 Reviewed by Hajime Morita. 7 8 Details of the bug: 9 We saved a state of a <select> element as a string of which length was 10 the size of <select>'s children. e.g. If a <select> had five children 11 and the second and the fifth items were selected, the state string was: 12 ".X..X" 13 14 This didn't work well if the structure of the children was updated after 15 parsing. For example, 16 1. A page has the following <select> initially: 17 <select multiple> 18 <option>Banana 19 <option>Lemon 20 <option>Orange 21 <option>Strawberry 22 <select> 23 24 2. For some reasons, <option>Apple</option> is prepended to the children. 25 3. Some items are selected. 26 4. The page is unloaded. Selection state is saved. 27 5. A user go back to the page again. A browser parses the page again. 28 6. Try to restore the <select> state with the saved data at 4. 29 But "Apple" is missing. The <select> has wrong selections. 30 31 Solution: 32 We save the state as a set of selected values. If "Banana" and 33 "Strawberry" are selected in the above <select>, we save two strings; 34 "Banana" and "Strawberry", not ".X..X". 35 36 Test: fast/forms/select/select-state-restore.html 37 38 * html/HTMLSelectElement.cpp: 39 (WebCore::HTMLSelectElement::saveFormControlState): 40 Store selected value strings to a FormControlState object. 41 (WebCore::HTMLSelectElement::searchOptionsForValue): 42 A helper function to find an <option> with the specified value. 43 (WebCore::HTMLSelectElement::restoreFormControlState): 44 Clear all of selections, then select options with saved values. 45 In order to avoid O(M x N) loop, we start searching at position we found 46 the previous value. 47 * html/HTMLSelectElement.h: Declare searchOptionsForValue. 48 * html/FormController.cpp: 49 (formStateSignature): Bump up the version because this is a incompatible 50 change. 51 1 52 2012-06-24 David Barr <davidbarr@chromium.org> 2 53 -
trunk/Source/WebCore/html/FormController.cpp
r121032 r121128 82 82 // attribute value of a form control. The following string literal should 83 83 // contain some characters which are rarely used for name attribute values. 84 DEFINE_STATIC_LOCAL(String, signature, ("\n\r?% WebKit serialized form state version 2\n\r=&"));84 DEFINE_STATIC_LOCAL(String, signature, ("\n\r?% WebKit serialized form state version 3 \n\r=&")); 85 85 return signature; 86 86 } -
trunk/Source/WebCore/html/HTMLSelectElement.cpp
r121004 r121128 920 920 const Vector<HTMLElement*>& items = listItems(); 921 921 size_t length = items.size(); 922 StringBuilder builder; 923 builder.reserveCapacity(length); 922 FormControlState state; 924 923 for (unsigned i = 0; i < length; ++i) { 925 HTMLElement* element = items[i]; 926 bool selected = element->hasTagName(optionTag) && toHTMLOptionElement(element)->selected(); 927 builder.append(selected ? 'X' : '.'); 928 } 929 return FormControlState(builder.toString()); 924 if (!items[i]->hasTagName(optionTag)) 925 continue; 926 HTMLOptionElement* option = toHTMLOptionElement(items[i]); 927 if (!option->selected()) 928 continue; 929 state.append(option->value()); 930 if (!multiple()) 931 break; 932 } 933 return state; 934 } 935 936 size_t HTMLSelectElement::searchOptionsForValue(const String& value, size_t listIndexStart, size_t listIndexEnd) const 937 { 938 const Vector<HTMLElement*>& items = listItems(); 939 size_t loopEndIndex = std::min(items.size(), listIndexEnd); 940 for (size_t i = listIndexStart; i < loopEndIndex; ++i) { 941 if (!items[i]->hasLocalName(optionTag)) 942 continue; 943 if (static_cast<HTMLOptionElement*>(items[i])->value() == value) 944 return i; 945 } 946 return notFound; 930 947 } 931 948 … … 935 952 936 953 const Vector<HTMLElement*>& items = listItems(); 937 size_t length = items.size(); 938 939 String mask = state[0]; 940 for (size_t i = 0; i < length; ++i) { 941 HTMLElement* element = items[i]; 942 if (element->hasTagName(optionTag)) 943 toHTMLOptionElement(element)->setSelectedState(mask[i] == 'X'); 954 size_t itemsSize = items.size(); 955 if (!itemsSize) 956 return; 957 958 for (size_t i = 0; i < itemsSize; ++i) { 959 if (!items[i]->hasLocalName(optionTag)) 960 continue; 961 static_cast<HTMLOptionElement*>(items[i])->setSelectedState(false); 962 } 963 964 if (!multiple()) { 965 size_t foundIndex = searchOptionsForValue(state[0], 0, itemsSize); 966 if (foundIndex != notFound) 967 toHTMLOptionElement(items[foundIndex])->setSelectedState(true); 968 } else { 969 size_t startIndex = 0; 970 for (size_t i = 0; i < state.valueSize(); ++i) { 971 const String& value = state[i]; 972 size_t foundIndex = searchOptionsForValue(value, startIndex, itemsSize); 973 if (foundIndex == notFound) 974 foundIndex = searchOptionsForValue(value, 0, startIndex); 975 if (foundIndex == notFound) 976 continue; 977 toHTMLOptionElement(items[foundIndex])->setSelectedState(true); 978 startIndex = foundIndex + 1; 979 } 944 980 } 945 981 -
trunk/Source/WebCore/html/HTMLSelectElement.h
r120679 r121128 165 165 void listBoxDefaultEventHandler(Event*); 166 166 void setOptionsChangedOnRenderer(); 167 size_t searchOptionsForValue(const String&, size_t listIndexStart, size_t listIndexEnd) const; 167 168 168 169 enum SkipDirection {
Note:
See TracChangeset
for help on using the changeset viewer.