| 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 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 static const unsigned maxListItems = INT_MAX; | 84 static const unsigned maxListItems = INT_MAX; |
| 85 | 85 |
| 86 HTMLSelectElement::HTMLSelectElement(Document& document, HTMLFormElement* form) | 86 HTMLSelectElement::HTMLSelectElement(Document& document, HTMLFormElement* form) |
| 87 : HTMLFormControlElementWithState(selectTag, document, form) | 87 : HTMLFormControlElementWithState(selectTag, document, form) |
| 88 , m_typeAhead(this) | 88 , m_typeAhead(this) |
| 89 , m_size(0) | 89 , m_size(0) |
| 90 , m_lastOnChangeOption(nullptr) | 90 , m_lastOnChangeOption(nullptr) |
| 91 , m_multiple(false) | 91 , m_multiple(false) |
| 92 , m_activeSelectionState(false) | 92 , m_activeSelectionState(false) |
| 93 , m_shouldRecalcListItems(false) | 93 , m_shouldRecalcListItems(false) |
| 94 , m_suggestedIndex(-1) | |
| 95 , m_isAutofilledByPreview(false) | 94 , m_isAutofilledByPreview(false) |
| 96 , m_indexToSelectOnCancel(-1) | 95 , m_indexToSelectOnCancel(-1) |
| 97 , m_popupIsVisible(false) | 96 , m_popupIsVisible(false) |
| 98 { | 97 { |
| 99 setHasCustomStyleCallbacks(); | 98 setHasCustomStyleCallbacks(); |
| 100 } | 99 } |
| 101 | 100 |
| 102 HTMLSelectElement* HTMLSelectElement::create(Document& document) | 101 HTMLSelectElement* HTMLSelectElement::create(Document& document) |
| 103 { | 102 { |
| 104 HTMLSelectElement* select = new HTMLSelectElement(document, 0); | 103 HTMLSelectElement* select = new HTMLSelectElement(document, 0); |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 continue; | 293 continue; |
| 295 if (toHTMLOptionElement(item)->value() == value) | 294 if (toHTMLOptionElement(item)->value() == value) |
| 296 break; | 295 break; |
| 297 optionIndex++; | 296 optionIndex++; |
| 298 } | 297 } |
| 299 if (optionIndex >= static_cast<int>(listItems().size())) | 298 if (optionIndex >= static_cast<int>(listItems().size())) |
| 300 optionIndex = -1; | 299 optionIndex = -1; |
| 301 } | 300 } |
| 302 | 301 |
| 303 int previousSelectedIndex = selectedIndex(); | 302 int previousSelectedIndex = selectedIndex(); |
| 304 setSuggestedIndex(-1); | 303 setSuggestedOption(nullptr); |
| 305 if (m_isAutofilledByPreview) | 304 if (m_isAutofilledByPreview) |
| 306 setAutofilled(false); | 305 setAutofilled(false); |
| 307 SelectOptionFlags flags = DeselectOtherOptions | MakeOptionDirty; | 306 SelectOptionFlags flags = DeselectOtherOptions | MakeOptionDirty; |
| 308 if (sendEvents) | 307 if (sendEvents) |
| 309 flags |= DispatchInputAndChangeEvent; | 308 flags |= DispatchInputAndChangeEvent; |
| 310 selectOption(optionIndex, flags); | 309 selectOption(optionIndex, flags); |
| 311 | 310 |
| 312 if (sendEvents && previousSelectedIndex != selectedIndex() && !usesMenuList(
)) | 311 if (sendEvents && previousSelectedIndex != selectedIndex() && !usesMenuList(
)) |
| 313 listBoxOnChange(); | 312 listBoxOnChange(); |
| 314 } | 313 } |
| 315 | 314 |
| 316 String HTMLSelectElement::suggestedValue() const | 315 String HTMLSelectElement::suggestedValue() const |
| 317 { | 316 { |
| 318 const ListItems& items = listItems(); | 317 return m_suggestedOption ? m_suggestedOption->value() : ""; |
| 319 for (unsigned i = 0; i < items.size(); ++i) { | |
| 320 if (isHTMLOptionElement(items[i]) && m_suggestedIndex >= 0) { | |
| 321 if (i == static_cast<unsigned>(m_suggestedIndex)) | |
| 322 return toHTMLOptionElement(items[i])->value(); | |
| 323 } | |
| 324 } | |
| 325 return ""; | |
| 326 } | 318 } |
| 327 | 319 |
| 328 void HTMLSelectElement::setSuggestedValue(const String& value) | 320 void HTMLSelectElement::setSuggestedValue(const String& value) |
| 329 { | 321 { |
| 330 if (value.isNull()) { | 322 if (value.isNull()) { |
| 331 setSuggestedIndex(-1); | 323 setSuggestedOption(nullptr); |
| 332 return; | 324 return; |
| 333 } | 325 } |
| 334 | 326 |
| 335 unsigned optionIndex = 0; | |
| 336 for (auto& item : listItems()) { | 327 for (auto& item : listItems()) { |
| 337 if (!isHTMLOptionElement(item)) | 328 if (!isHTMLOptionElement(item)) |
| 338 continue; | 329 continue; |
| 339 if (toHTMLOptionElement(item)->value() == value) { | 330 if (toHTMLOptionElement(item)->value() == value) { |
| 340 setSuggestedIndex(optionIndex); | 331 setSuggestedOption(toHTMLOptionElement(item)); |
| 341 m_isAutofilledByPreview = true; | 332 m_isAutofilledByPreview = true; |
| 342 return; | 333 return; |
| 343 } | 334 } |
| 344 optionIndex++; | |
| 345 } | 335 } |
| 346 | 336 |
| 347 setSuggestedIndex(-1); | 337 setSuggestedOption(nullptr); |
| 348 } | 338 } |
| 349 | 339 |
| 350 bool HTMLSelectElement::isPresentationAttribute(const QualifiedName& name) const | 340 bool HTMLSelectElement::isPresentationAttribute(const QualifiedName& name) const |
| 351 { | 341 { |
| 352 if (name == alignAttr) { | 342 if (name == alignAttr) { |
| 353 // Don't map 'align' attribute. This matches what Firefox, Opera and IE
do. | 343 // Don't map 'align' attribute. This matches what Firefox, Opera and IE
do. |
| 354 // See http://bugs.webkit.org/show_bug.cgi?id=12072 | 344 // See http://bugs.webkit.org/show_bug.cgi?id=12072 |
| 355 return false; | 345 return false; |
| 356 } | 346 } |
| 357 | 347 |
| (...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 951 } | 941 } |
| 952 | 942 |
| 953 return -1; | 943 return -1; |
| 954 } | 944 } |
| 955 | 945 |
| 956 void HTMLSelectElement::setSelectedIndex(int index) | 946 void HTMLSelectElement::setSelectedIndex(int index) |
| 957 { | 947 { |
| 958 selectOption(index, DeselectOtherOptions | MakeOptionDirty); | 948 selectOption(index, DeselectOtherOptions | MakeOptionDirty); |
| 959 } | 949 } |
| 960 | 950 |
| 961 int HTMLSelectElement::suggestedIndex() const | 951 void HTMLSelectElement::setSuggestedOption(HTMLOptionElement* option) |
| 962 { | 952 { |
| 963 return m_suggestedIndex; | 953 if (m_suggestedOption == option) |
| 964 } | 954 return; |
| 965 | 955 m_suggestedOption = option; |
| 966 void HTMLSelectElement::setSuggestedIndex(int suggestedIndex) | |
| 967 { | |
| 968 m_suggestedIndex = suggestedIndex; | |
| 969 | 956 |
| 970 if (LayoutObject* layoutObject = this->layoutObject()) { | 957 if (LayoutObject* layoutObject = this->layoutObject()) { |
| 971 layoutObject->updateFromElement(); | 958 layoutObject->updateFromElement(); |
| 972 scrollToOption(item(listToOptionIndex(suggestedIndex))); | 959 scrollToOption(option); |
| 973 } | 960 } |
| 974 if (popupIsVisible()) | 961 if (popupIsVisible()) |
| 975 m_popup->updateFromElement(PopupMenu::BySelectionChange); | 962 m_popup->updateFromElement(PopupMenu::BySelectionChange); |
| 976 } | 963 } |
| 977 | 964 |
| 978 void HTMLSelectElement::scrollToOption(HTMLOptionElement* option) | 965 void HTMLSelectElement::scrollToOption(HTMLOptionElement* option) |
| 979 { | 966 { |
| 980 if (!option) | 967 if (!option) |
| 981 return; | 968 return; |
| 982 if (usesMenuList()) | 969 if (usesMenuList()) |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1039 else if (!m_lastOnChangeOption) | 1026 else if (!m_lastOnChangeOption) |
| 1040 resetToDefaultSelection(); | 1027 resetToDefaultSelection(); |
| 1041 if (m_lastOnChangeOption == &option) | 1028 if (m_lastOnChangeOption == &option) |
| 1042 m_lastOnChangeOption.clear(); | 1029 m_lastOnChangeOption.clear(); |
| 1043 if (m_optionToScrollTo == &option) | 1030 if (m_optionToScrollTo == &option) |
| 1044 m_optionToScrollTo.clear(); | 1031 m_optionToScrollTo.clear(); |
| 1045 if (m_activeSelectionAnchor == &option) | 1032 if (m_activeSelectionAnchor == &option) |
| 1046 m_activeSelectionAnchor.clear(); | 1033 m_activeSelectionAnchor.clear(); |
| 1047 if (m_activeSelectionEnd == &option) | 1034 if (m_activeSelectionEnd == &option) |
| 1048 m_activeSelectionEnd.clear(); | 1035 m_activeSelectionEnd.clear(); |
| 1036 if (m_suggestedOption == &option) |
| 1037 setSuggestedOption(nullptr); |
| 1049 if (option.selected()) | 1038 if (option.selected()) |
| 1050 setAutofilled(false); | 1039 setAutofilled(false); |
| 1051 setNeedsValidityCheck(); | 1040 setNeedsValidityCheck(); |
| 1052 m_lastOnChangeSelection.clear(); | 1041 m_lastOnChangeSelection.clear(); |
| 1053 } | 1042 } |
| 1054 | 1043 |
| 1055 void HTMLSelectElement::optGroupInsertedOrRemoved(HTMLOptGroupElement& optgroup) | 1044 void HTMLSelectElement::optGroupInsertedOrRemoved(HTMLOptGroupElement& optgroup) |
| 1056 { | 1045 { |
| 1057 setRecalcListItems(optgroup); | 1046 setRecalcListItems(optgroup); |
| 1058 setNeedsValidityCheck(); | 1047 setNeedsValidityCheck(); |
| (...skipping 823 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1882 setOptionsChangedOnLayoutObject(); | 1871 setOptionsChangedOnLayoutObject(); |
| 1883 } | 1872 } |
| 1884 | 1873 |
| 1885 DEFINE_TRACE(HTMLSelectElement) | 1874 DEFINE_TRACE(HTMLSelectElement) |
| 1886 { | 1875 { |
| 1887 visitor->trace(m_listItems); | 1876 visitor->trace(m_listItems); |
| 1888 visitor->trace(m_lastOnChangeOption); | 1877 visitor->trace(m_lastOnChangeOption); |
| 1889 visitor->trace(m_activeSelectionAnchor); | 1878 visitor->trace(m_activeSelectionAnchor); |
| 1890 visitor->trace(m_activeSelectionEnd); | 1879 visitor->trace(m_activeSelectionEnd); |
| 1891 visitor->trace(m_optionToScrollTo); | 1880 visitor->trace(m_optionToScrollTo); |
| 1881 visitor->trace(m_suggestedOption); |
| 1892 visitor->trace(m_popup); | 1882 visitor->trace(m_popup); |
| 1893 visitor->trace(m_popupUpdater); | 1883 visitor->trace(m_popupUpdater); |
| 1894 HTMLFormControlElementWithState::trace(visitor); | 1884 HTMLFormControlElementWithState::trace(visitor); |
| 1895 } | 1885 } |
| 1896 | 1886 |
| 1897 void HTMLSelectElement::didAddUserAgentShadowRoot(ShadowRoot& root) | 1887 void HTMLSelectElement::didAddUserAgentShadowRoot(ShadowRoot& root) |
| 1898 { | 1888 { |
| 1899 HTMLContentElement* content = HTMLContentElement::create(document()); | 1889 HTMLContentElement* content = HTMLContentElement::create(document()); |
| 1900 content->setAttribute(selectAttr, "option,optgroup,hr"); | 1890 content->setAttribute(selectAttr, "option,optgroup,hr"); |
| 1901 root.appendChild(content); | 1891 root.appendChild(content); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1978 { | 1968 { |
| 1979 m_indexToSelectOnCancel = listIndex; | 1969 m_indexToSelectOnCancel = listIndex; |
| 1980 if (layoutObject()) | 1970 if (layoutObject()) |
| 1981 layoutObject()->updateFromElement(); | 1971 layoutObject()->updateFromElement(); |
| 1982 } | 1972 } |
| 1983 | 1973 |
| 1984 int HTMLSelectElement::optionIndexToBeShown() const | 1974 int HTMLSelectElement::optionIndexToBeShown() const |
| 1985 { | 1975 { |
| 1986 if (m_indexToSelectOnCancel >= 0) | 1976 if (m_indexToSelectOnCancel >= 0) |
| 1987 return listToOptionIndex(m_indexToSelectOnCancel); | 1977 return listToOptionIndex(m_indexToSelectOnCancel); |
| 1988 if (suggestedIndex() >= 0) | 1978 if (m_suggestedOption) |
| 1989 return suggestedIndex(); | 1979 return m_suggestedOption->index(); |
| 1990 return selectedIndex(); | 1980 return selectedIndex(); |
| 1991 } | 1981 } |
| 1992 | 1982 |
| 1993 void HTMLSelectElement::valueChanged(unsigned listIndex) | 1983 void HTMLSelectElement::valueChanged(unsigned listIndex) |
| 1994 { | 1984 { |
| 1995 // Check to ensure a page navigation has not occurred while the popup was | 1985 // Check to ensure a page navigation has not occurred while the popup was |
| 1996 // up. | 1986 // up. |
| 1997 Document& doc = document(); | 1987 Document& doc = document(); |
| 1998 if (&doc != doc.frame()->document()) | 1988 if (&doc != doc.frame()->document()) |
| 1999 return; | 1989 return; |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2136 } | 2126 } |
| 2137 | 2127 |
| 2138 void HTMLSelectElement::didMutateSubtree() | 2128 void HTMLSelectElement::didMutateSubtree() |
| 2139 { | 2129 { |
| 2140 DCHECK(popupIsVisible()); | 2130 DCHECK(popupIsVisible()); |
| 2141 DCHECK(m_popup); | 2131 DCHECK(m_popup); |
| 2142 m_popup->updateFromElement(PopupMenu::ByDOMChange); | 2132 m_popup->updateFromElement(PopupMenu::ByDOMChange); |
| 2143 } | 2133 } |
| 2144 | 2134 |
| 2145 } // namespace blink | 2135 } // namespace blink |
| OLD | NEW |