| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). | 2 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
| 3 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 3 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 4 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 4 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 5 * (C) 2001 Dirk Mueller (mueller@kde.org) | 5 * (C) 2001 Dirk Mueller (mueller@kde.org) |
| 6 * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2011 Apple Inc. All rights
reserved. | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2011 Apple Inc. All rights
reserved. |
| 7 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) | 7 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) |
| 8 * Copyright (C) 2010 Google Inc. All rights reserved. | 8 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 9 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) | 9 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) |
| 10 * | 10 * |
| (...skipping 1077 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1088 // We should update active selection after finishing OPTION state change | 1088 // We should update active selection after finishing OPTION state change |
| 1089 // because setActiveSelectionAnchorIndex() stores OPTION's selection state. | 1089 // because setActiveSelectionAnchorIndex() stores OPTION's selection state. |
| 1090 if (element) { | 1090 if (element) { |
| 1091 // setActiveSelectionAnchor is O(N). | 1091 // setActiveSelectionAnchor is O(N). |
| 1092 if (!m_activeSelectionAnchor || !multiple() || flags & DeselectOtherOpti
ons) | 1092 if (!m_activeSelectionAnchor || !multiple() || flags & DeselectOtherOpti
ons) |
| 1093 setActiveSelectionAnchor(element); | 1093 setActiveSelectionAnchor(element); |
| 1094 if (!m_activeSelectionEnd || !multiple() || flags & DeselectOtherOptions
) | 1094 if (!m_activeSelectionEnd || !multiple() || flags & DeselectOtherOptions
) |
| 1095 setActiveSelectionEnd(element); | 1095 setActiveSelectionEnd(element); |
| 1096 } | 1096 } |
| 1097 | 1097 |
| 1098 // Need to update m_lastOnChangeOption before |
| 1099 // LayoutMenuList::updateFromElement. |
| 1100 bool shouldDispatchEvents = false; |
| 1101 if (usesMenuList()) { |
| 1102 shouldDispatchEvents = (flags & DispatchInputAndChangeEvent) && m_lastOn
ChangeOption != element; |
| 1103 m_lastOnChangeOption = element; |
| 1104 } |
| 1105 |
| 1098 // For the menu list case, this is what makes the selected element appear. | 1106 // For the menu list case, this is what makes the selected element appear. |
| 1099 if (LayoutObject* layoutObject = this->layoutObject()) | 1107 if (LayoutObject* layoutObject = this->layoutObject()) |
| 1100 layoutObject->updateFromElement(); | 1108 layoutObject->updateFromElement(); |
| 1101 // PopupMenu::updateFromElement() posts an O(N) task. | 1109 // PopupMenu::updateFromElement() posts an O(N) task. |
| 1102 if (popupIsVisible()) | 1110 if (popupIsVisible()) |
| 1103 m_popup->updateFromElement(PopupMenu::BySelectionChange); | 1111 m_popup->updateFromElement(PopupMenu::BySelectionChange); |
| 1104 | 1112 |
| 1105 scrollToSelection(); | 1113 scrollToSelection(); |
| 1106 setNeedsValidityCheck(); | 1114 setNeedsValidityCheck(); |
| 1107 | 1115 |
| 1108 if (usesMenuList()) { | 1116 if (usesMenuList()) { |
| 1109 if (flags & DispatchInputAndChangeEvent) | 1117 if (shouldDispatchEvents) { |
| 1110 dispatchInputAndChangeEventForMenuList(); | 1118 dispatchInputEvent(); |
| 1111 else | 1119 dispatchFormControlChangeEvent(); |
| 1112 m_lastOnChangeOption = element; | 1120 } |
| 1113 if (LayoutObject* layoutObject = this->layoutObject()) { | 1121 if (LayoutObject* layoutObject = this->layoutObject()) { |
| 1114 // Need to check usesMenuList() again because | 1122 // Need to check usesMenuList() again because event handlers might |
| 1115 // dispatchInputAndChangeEventForMenuList() might change the status. | 1123 // change the status. |
| 1116 if (usesMenuList()) { | 1124 if (usesMenuList()) { |
| 1117 // didSetSelectedIndex() is O(N) because of optionToListIndex. | 1125 // didSetSelectedIndex() is O(N) because of optionToListIndex. |
| 1118 toLayoutMenuList(layoutObject)->didSetSelectedIndex(optionIndex)
; | 1126 toLayoutMenuList(layoutObject)->didSetSelectedIndex(optionIndex)
; |
| 1119 } | 1127 } |
| 1120 } | 1128 } |
| 1121 } | 1129 } |
| 1122 | 1130 |
| 1123 notifyFormStateChanged(); | 1131 notifyFormStateChanged(); |
| 1124 } | 1132 } |
| 1125 | 1133 |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1237 toHTMLOptionElement(item)->setSelectedState(false); | 1245 toHTMLOptionElement(item)->setSelectedState(false); |
| 1238 } | 1246 } |
| 1239 | 1247 |
| 1240 // The saved state should have at least one value and an index. | 1248 // The saved state should have at least one value and an index. |
| 1241 ASSERT(state.valueSize() >= 2); | 1249 ASSERT(state.valueSize() >= 2); |
| 1242 if (!multiple()) { | 1250 if (!multiple()) { |
| 1243 size_t index = state[1].toUInt(); | 1251 size_t index = state[1].toUInt(); |
| 1244 if (index < itemsSize && isHTMLOptionElement(items[index]) && toHTMLOpti
onElement(items[index])->value() == state[0]) { | 1252 if (index < itemsSize && isHTMLOptionElement(items[index]) && toHTMLOpti
onElement(items[index])->value() == state[0]) { |
| 1245 toHTMLOptionElement(items[index])->setSelectedState(true); | 1253 toHTMLOptionElement(items[index])->setSelectedState(true); |
| 1246 toHTMLOptionElement(items[index])->setDirty(true); | 1254 toHTMLOptionElement(items[index])->setDirty(true); |
| 1255 m_lastOnChangeOption = toHTMLOptionElement(items[index]); |
| 1247 } else { | 1256 } else { |
| 1248 size_t foundIndex = searchOptionsForValue(state[0], 0, itemsSize); | 1257 size_t foundIndex = searchOptionsForValue(state[0], 0, itemsSize); |
| 1249 if (foundIndex != kNotFound) { | 1258 if (foundIndex != kNotFound) { |
| 1250 toHTMLOptionElement(items[foundIndex])->setSelectedState(true); | 1259 toHTMLOptionElement(items[foundIndex])->setSelectedState(true); |
| 1251 toHTMLOptionElement(items[foundIndex])->setDirty(true); | 1260 toHTMLOptionElement(items[foundIndex])->setDirty(true); |
| 1261 m_lastOnChangeOption = toHTMLOptionElement(items[foundIndex]); |
| 1252 } | 1262 } |
| 1253 } | 1263 } |
| 1254 } else { | 1264 } else { |
| 1255 size_t startIndex = 0; | 1265 size_t startIndex = 0; |
| 1256 for (size_t i = 0; i < state.valueSize(); i+= 2) { | 1266 for (size_t i = 0; i < state.valueSize(); i+= 2) { |
| 1257 const String& value = state[i]; | 1267 const String& value = state[i]; |
| 1258 const size_t index = state[i + 1].toUInt(); | 1268 const size_t index = state[i + 1].toUInt(); |
| 1259 if (index < itemsSize && isHTMLOptionElement(items[index]) && toHTML
OptionElement(items[index])->value() == value) { | 1269 if (index < itemsSize && isHTMLOptionElement(items[index]) && toHTML
OptionElement(items[index])->value() == value) { |
| 1260 toHTMLOptionElement(items[index])->setSelectedState(true); | 1270 toHTMLOptionElement(items[index])->setSelectedState(true); |
| 1261 toHTMLOptionElement(items[index])->setDirty(true); | 1271 toHTMLOptionElement(items[index])->setDirty(true); |
| (...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1972 { | 1982 { |
| 1973 m_indexToSelectOnCancel = listIndex; | 1983 m_indexToSelectOnCancel = listIndex; |
| 1974 if (layoutObject()) | 1984 if (layoutObject()) |
| 1975 layoutObject()->updateFromElement(); | 1985 layoutObject()->updateFromElement(); |
| 1976 } | 1986 } |
| 1977 | 1987 |
| 1978 int HTMLSelectElement::optionIndexToBeShown() const | 1988 int HTMLSelectElement::optionIndexToBeShown() const |
| 1979 { | 1989 { |
| 1980 if (m_indexToSelectOnCancel >= 0) | 1990 if (m_indexToSelectOnCancel >= 0) |
| 1981 return listToOptionIndex(m_indexToSelectOnCancel); | 1991 return listToOptionIndex(m_indexToSelectOnCancel); |
| 1992 // TODO(tkent): HTMLOptionElement::index() is O(N). This function should |
| 1993 // return HTMLOptionElement*. |
| 1982 if (m_suggestedOption) | 1994 if (m_suggestedOption) |
| 1983 return m_suggestedOption->index(); | 1995 return m_suggestedOption->index(); |
| 1984 return selectedIndex(); | 1996 int optionIndex = m_lastOnChangeOption ? m_lastOnChangeOption->index() : -1; |
| 1997 DCHECK_EQ(optionIndex, selectedIndex()); |
| 1998 return optionIndex; |
| 1985 } | 1999 } |
| 1986 | 2000 |
| 1987 void HTMLSelectElement::valueChanged(unsigned listIndex) | 2001 void HTMLSelectElement::valueChanged(unsigned listIndex) |
| 1988 { | 2002 { |
| 1989 // Check to ensure a page navigation has not occurred while the popup was | 2003 // Check to ensure a page navigation has not occurred while the popup was |
| 1990 // up. | 2004 // up. |
| 1991 Document& doc = document(); | 2005 Document& doc = document(); |
| 1992 if (&doc != doc.frame()->document()) | 2006 if (&doc != doc.frame()->document()) |
| 1993 return; | 2007 return; |
| 1994 | 2008 |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2130 } | 2144 } |
| 2131 | 2145 |
| 2132 void HTMLSelectElement::didMutateSubtree() | 2146 void HTMLSelectElement::didMutateSubtree() |
| 2133 { | 2147 { |
| 2134 DCHECK(popupIsVisible()); | 2148 DCHECK(popupIsVisible()); |
| 2135 DCHECK(m_popup); | 2149 DCHECK(m_popup); |
| 2136 m_popup->updateFromElement(PopupMenu::ByDOMChange); | 2150 m_popup->updateFromElement(PopupMenu::ByDOMChange); |
| 2137 } | 2151 } |
| 2138 | 2152 |
| 2139 } // namespace blink | 2153 } // namespace blink |
| OLD | NEW |