| 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 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 | 273 |
| 274 String HTMLSelectElement::value() const | 274 String HTMLSelectElement::value() const |
| 275 { | 275 { |
| 276 if (HTMLOptionElement* option = selectedOption()) | 276 if (HTMLOptionElement* option = selectedOption()) |
| 277 return option->value(); | 277 return option->value(); |
| 278 return ""; | 278 return ""; |
| 279 } | 279 } |
| 280 | 280 |
| 281 void HTMLSelectElement::setValue(const String &value, bool sendEvents) | 281 void HTMLSelectElement::setValue(const String &value, bool sendEvents) |
| 282 { | 282 { |
| 283 // We clear the previously selected option(s) when needed, to guarantee | |
| 284 // calling setSelectedIndex() only once. | |
| 285 int optionIndex = 0; | |
| 286 HTMLOptionElement* option = nullptr; | 283 HTMLOptionElement* option = nullptr; |
| 287 if (value.isNull()) { | 284 // Find the option with value() matching the given parameter and make it the |
| 288 optionIndex = -1; | 285 // current selection. |
| 289 } else { | 286 for (const auto& item : optionList()) { |
| 290 // Find the option with value() matching the given parameter and make it | 287 if (item->value() == value) { |
| 291 // the current selection. | 288 option = item; |
| 292 for (auto& item : listItems()) { | 289 break; |
| 293 if (!isHTMLOptionElement(item)) | |
| 294 continue; | |
| 295 if (toHTMLOptionElement(item)->value() == value) { | |
| 296 option = toHTMLOptionElement(item); | |
| 297 break; | |
| 298 } | |
| 299 optionIndex++; | |
| 300 } | 290 } |
| 301 if (optionIndex >= static_cast<int>(listItems().size())) | |
| 302 optionIndex = -1; | |
| 303 } | 291 } |
| 304 | 292 |
| 305 int previousSelectedIndex = selectedIndex(); | 293 HTMLOptionElement* previousSelectedOption = selectedOption(); |
| 306 setSuggestedOption(nullptr); | 294 setSuggestedOption(nullptr); |
| 307 if (m_isAutofilledByPreview) | 295 if (m_isAutofilledByPreview) |
| 308 setAutofilled(false); | 296 setAutofilled(false); |
| 309 SelectOptionFlags flags = DeselectOtherOptions | MakeOptionDirty; | 297 SelectOptionFlags flags = DeselectOtherOptions | MakeOptionDirty; |
| 310 if (sendEvents) | 298 if (sendEvents) |
| 311 flags |= DispatchInputAndChangeEvent; | 299 flags |= DispatchInputAndChangeEvent; |
| 312 selectOption(option, flags); | 300 selectOption(option, flags); |
| 313 | 301 |
| 314 if (sendEvents && previousSelectedIndex != selectedIndex() && !usesMenuList(
)) | 302 if (sendEvents && previousSelectedOption != option && !usesMenuList()) |
| 315 listBoxOnChange(); | 303 listBoxOnChange(); |
| 316 } | 304 } |
| 317 | 305 |
| 318 String HTMLSelectElement::suggestedValue() const | 306 String HTMLSelectElement::suggestedValue() const |
| 319 { | 307 { |
| 320 return m_suggestedOption ? m_suggestedOption->value() : ""; | 308 return m_suggestedOption ? m_suggestedOption->value() : ""; |
| 321 } | 309 } |
| 322 | 310 |
| 323 void HTMLSelectElement::setSuggestedValue(const String& value) | 311 void HTMLSelectElement::setSuggestedValue(const String& value) |
| 324 { | 312 { |
| 325 if (value.isNull()) { | 313 if (value.isNull()) { |
| 326 setSuggestedOption(nullptr); | 314 setSuggestedOption(nullptr); |
| 327 return; | 315 return; |
| 328 } | 316 } |
| 329 | 317 |
| 330 for (auto& item : listItems()) { | 318 for (const auto& option : optionList()) { |
| 331 if (!isHTMLOptionElement(item)) | 319 if (option->value() == value) { |
| 332 continue; | 320 setSuggestedOption(option); |
| 333 if (toHTMLOptionElement(item)->value() == value) { | |
| 334 setSuggestedOption(toHTMLOptionElement(item)); | |
| 335 m_isAutofilledByPreview = true; | 321 m_isAutofilledByPreview = true; |
| 336 return; | 322 return; |
| 337 } | 323 } |
| 338 } | 324 } |
| 339 | 325 |
| 340 setSuggestedOption(nullptr); | 326 setSuggestedOption(nullptr); |
| 341 } | 327 } |
| 342 | 328 |
| 343 bool HTMLSelectElement::isPresentationAttribute(const QualifiedName& name) const | 329 bool HTMLSelectElement::isPresentationAttribute(const QualifiedName& name) const |
| 344 { | 330 { |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 if (diff < 0) { // Add dummy elements. | 476 if (diff < 0) { // Add dummy elements. |
| 491 do { | 477 do { |
| 492 appendChild(document().createElement(optionTag, CreatedByCreateEleme
nt), exceptionState); | 478 appendChild(document().createElement(optionTag, CreatedByCreateEleme
nt), exceptionState); |
| 493 if (exceptionState.hadException()) | 479 if (exceptionState.hadException()) |
| 494 break; | 480 break; |
| 495 } while (++diff); | 481 } while (++diff); |
| 496 } else { | 482 } else { |
| 497 // Removing children fires mutation events, which might mutate the DOM | 483 // Removing children fires mutation events, which might mutate the DOM |
| 498 // further, so we first copy out a list of elements that we intend to | 484 // further, so we first copy out a list of elements that we intend to |
| 499 // remove then attempt to remove them one at a time. | 485 // remove then attempt to remove them one at a time. |
| 500 HeapVector<Member<Element>> itemsToRemove; | 486 HeapVector<Member<HTMLOptionElement>> itemsToRemove; |
| 501 size_t optionIndex = 0; | 487 size_t optionIndex = 0; |
| 502 for (auto& item : listItems()) { | 488 for (const auto& option : optionList()) { |
| 503 if (isHTMLOptionElement(item) && optionIndex++ >= newLen) { | 489 if (optionIndex++ >= newLen) { |
| 504 ASSERT(item->parentNode()); | 490 DCHECK(option->parentNode()); |
| 505 itemsToRemove.append(item.get()); | 491 itemsToRemove.append(option); |
| 506 } | 492 } |
| 507 } | 493 } |
| 508 | 494 |
| 509 for (auto& item : itemsToRemove) { | 495 for (auto& item : itemsToRemove) { |
| 510 if (item->parentNode()) | 496 if (item->parentNode()) |
| 511 item->parentNode()->removeChild(item.get(), exceptionState); | 497 item->parentNode()->removeChild(item.get(), exceptionState); |
| 512 } | 498 } |
| 513 } | 499 } |
| 514 setNeedsValidityCheck(); | 500 setNeedsValidityCheck(); |
| 515 } | 501 } |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 881 return option; | 867 return option; |
| 882 } | 868 } |
| 883 return nullptr; | 869 return nullptr; |
| 884 } | 870 } |
| 885 | 871 |
| 886 int HTMLSelectElement::selectedIndex() const | 872 int HTMLSelectElement::selectedIndex() const |
| 887 { | 873 { |
| 888 unsigned index = 0; | 874 unsigned index = 0; |
| 889 | 875 |
| 890 // Return the number of the first option selected. | 876 // Return the number of the first option selected. |
| 891 for (auto& element : listItems()) { | 877 for (const auto& option : optionList()) { |
| 892 if (!isHTMLOptionElement(*element)) | 878 if (option->selected()) |
| 893 continue; | |
| 894 if (toHTMLOptionElement(*element).selected()) | |
| 895 return index; | 879 return index; |
| 896 ++index; | 880 ++index; |
| 897 } | 881 } |
| 898 | 882 |
| 899 return -1; | 883 return -1; |
| 900 } | 884 } |
| 901 | 885 |
| 902 void HTMLSelectElement::setSelectedIndex(int index) | 886 void HTMLSelectElement::setSelectedIndex(int index) |
| 903 { | 887 { |
| 904 selectOption(item(index), DeselectOtherOptions | MakeOptionDirty); | 888 selectOption(item(index), DeselectOtherOptions | MakeOptionDirty); |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1250 resetToDefaultSelection(); | 1234 resetToDefaultSelection(); |
| 1251 } | 1235 } |
| 1252 } | 1236 } |
| 1253 | 1237 |
| 1254 void HTMLSelectElement::appendToFormData(FormData& formData) | 1238 void HTMLSelectElement::appendToFormData(FormData& formData) |
| 1255 { | 1239 { |
| 1256 const AtomicString& name = this->name(); | 1240 const AtomicString& name = this->name(); |
| 1257 if (name.isEmpty()) | 1241 if (name.isEmpty()) |
| 1258 return; | 1242 return; |
| 1259 | 1243 |
| 1260 for (auto& element : listItems()) { | 1244 for (const auto& option : optionList()) { |
| 1261 if (isHTMLOptionElement(*element) && toHTMLOptionElement(*element).selec
ted() && !toHTMLOptionElement(*element).isDisabledFormControl()) | 1245 if (option->selected() && !option->isDisabledFormControl()) |
| 1262 formData.append(name, toHTMLOptionElement(*element).value()); | 1246 formData.append(name, option->value()); |
| 1263 } | 1247 } |
| 1264 } | 1248 } |
| 1265 | 1249 |
| 1266 void HTMLSelectElement::resetImpl() | 1250 void HTMLSelectElement::resetImpl() |
| 1267 { | 1251 { |
| 1268 for (auto& item : listItems()) { | 1252 for (const auto& option : optionList()) { |
| 1269 if (!isHTMLOptionElement(item)) | |
| 1270 continue; | |
| 1271 HTMLOptionElement* option = toHTMLOptionElement(item); | |
| 1272 option->setSelectedState(option->fastHasAttribute(selectedAttr)); | 1253 option->setSelectedState(option->fastHasAttribute(selectedAttr)); |
| 1273 option->setDirty(false); | 1254 option->setDirty(false); |
| 1274 } | 1255 } |
| 1275 resetToDefaultSelection(); | 1256 resetToDefaultSelection(); |
| 1276 setNeedsValidityCheck(); | 1257 setNeedsValidityCheck(); |
| 1277 } | 1258 } |
| 1278 | 1259 |
| 1279 void HTMLSelectElement::handlePopupOpenKeyboardEvent(Event* event) | 1260 void HTMLSelectElement::handlePopupOpenKeyboardEvent(Event* event) |
| 1280 { | 1261 { |
| 1281 focus(); | 1262 focus(); |
| (...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1780 option->setDirty(true); | 1761 option->setDirty(true); |
| 1781 if (usesMenuList()) | 1762 if (usesMenuList()) |
| 1782 return; | 1763 return; |
| 1783 listBoxOnChange(); | 1764 listBoxOnChange(); |
| 1784 scrollToSelection(); | 1765 scrollToSelection(); |
| 1785 } | 1766 } |
| 1786 | 1767 |
| 1787 unsigned HTMLSelectElement::length() const | 1768 unsigned HTMLSelectElement::length() const |
| 1788 { | 1769 { |
| 1789 unsigned options = 0; | 1770 unsigned options = 0; |
| 1790 for (auto& item : listItems()) { | 1771 for (const auto& option : optionList()) { |
| 1791 if (isHTMLOptionElement(*item)) | 1772 ALLOW_UNUSED_LOCAL(option); |
| 1792 ++options; | 1773 ++options; |
| 1793 } | 1774 } |
| 1794 return options; | 1775 return options; |
| 1795 } | 1776 } |
| 1796 | 1777 |
| 1797 void HTMLSelectElement::finishParsingChildren() | 1778 void HTMLSelectElement::finishParsingChildren() |
| 1798 { | 1779 { |
| 1799 HTMLFormControlElementWithState::finishParsingChildren(); | 1780 HTMLFormControlElementWithState::finishParsingChildren(); |
| 1800 if (usesMenuList()) | 1781 if (usesMenuList()) |
| 1801 return; | 1782 return; |
| 1802 scrollToOption(selectedOption()); | 1783 scrollToOption(selectedOption()); |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2088 } | 2069 } |
| 2089 | 2070 |
| 2090 void HTMLSelectElement::didMutateSubtree() | 2071 void HTMLSelectElement::didMutateSubtree() |
| 2091 { | 2072 { |
| 2092 DCHECK(popupIsVisible()); | 2073 DCHECK(popupIsVisible()); |
| 2093 DCHECK(m_popup); | 2074 DCHECK(m_popup); |
| 2094 m_popup->updateFromElement(PopupMenu::ByDOMChange); | 2075 m_popup->updateFromElement(PopupMenu::ByDOMChange); |
| 2095 } | 2076 } |
| 2096 | 2077 |
| 2097 } // namespace blink | 2078 } // namespace blink |
| OLD | NEW |