| 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 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 // Set the attribute value to a number. | 362 // Set the attribute value to a number. |
| 363 // This is important since the style rules for this attribute can | 363 // This is important since the style rules for this attribute can |
| 364 // determine the appearance property. | 364 // determine the appearance property. |
| 365 unsigned size = value.getString().toUInt(); | 365 unsigned size = value.getString().toUInt(); |
| 366 AtomicString attrSize = AtomicString::number(size); | 366 AtomicString attrSize = AtomicString::number(size); |
| 367 if (attrSize != value) { | 367 if (attrSize != value) { |
| 368 // FIXME: This is horribly factored. | 368 // FIXME: This is horribly factored. |
| 369 if (Attribute* sizeAttribute = ensureUniqueElementData().attributes(
).find(sizeAttr)) | 369 if (Attribute* sizeAttribute = ensureUniqueElementData().attributes(
).find(sizeAttr)) |
| 370 sizeAttribute->setValue(attrSize); | 370 sizeAttribute->setValue(attrSize); |
| 371 } | 371 } |
| 372 size = std::max(size, 0u); | 372 m_size = std::max(size, 0u); |
| 373 | |
| 374 // Ensure that we've determined selectedness of the items at least once | |
| 375 // prior to changing the size. | |
| 376 if (oldSize != size) | |
| 377 updateListItemSelectedStates(); | |
| 378 | |
| 379 m_size = size; | |
| 380 setNeedsValidityCheck(); | 373 setNeedsValidityCheck(); |
| 381 if (m_size != oldSize && inActiveDocument()) { | 374 if (m_size != oldSize) { |
| 382 lazyReattachIfAttached(); | 375 if (inActiveDocument()) |
| 383 setRecalcListItems(); | 376 lazyReattachIfAttached(); |
| 377 resetToDefaultSelection(); |
| 384 } | 378 } |
| 385 } else if (name == multipleAttr) { | 379 } else if (name == multipleAttr) { |
| 386 parseMultipleAttribute(value); | 380 parseMultipleAttribute(value); |
| 387 } else if (name == accesskeyAttr) { | 381 } else if (name == accesskeyAttr) { |
| 388 // FIXME: ignore for the moment. | 382 // FIXME: ignore for the moment. |
| 389 // | 383 // |
| 390 } else if (name == disabledAttr) { | 384 } else if (name == disabledAttr) { |
| 391 HTMLFormControlElementWithState::parseAttribute(name, oldValue, value); | 385 HTMLFormControlElementWithState::parseAttribute(name, oldValue, value); |
| 392 if (popupIsVisible()) | 386 if (popupIsVisible()) |
| 393 hidePopup(); | 387 hidePopup(); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 409 | 403 |
| 410 LayoutObject* HTMLSelectElement::createLayoutObject(const ComputedStyle&) | 404 LayoutObject* HTMLSelectElement::createLayoutObject(const ComputedStyle&) |
| 411 { | 405 { |
| 412 if (usesMenuList()) | 406 if (usesMenuList()) |
| 413 return new LayoutMenuList(this); | 407 return new LayoutMenuList(this); |
| 414 return new LayoutListBox(this); | 408 return new LayoutListBox(this); |
| 415 } | 409 } |
| 416 | 410 |
| 417 PassRefPtrWillBeRawPtr<HTMLCollection> HTMLSelectElement::selectedOptions() | 411 PassRefPtrWillBeRawPtr<HTMLCollection> HTMLSelectElement::selectedOptions() |
| 418 { | 412 { |
| 419 updateListItemSelectedStates(); | |
| 420 return ensureCachedCollection<HTMLCollection>(SelectedOptions); | 413 return ensureCachedCollection<HTMLCollection>(SelectedOptions); |
| 421 } | 414 } |
| 422 | 415 |
| 423 PassRefPtrWillBeRawPtr<HTMLOptionsCollection> HTMLSelectElement::options() | 416 PassRefPtrWillBeRawPtr<HTMLOptionsCollection> HTMLSelectElement::options() |
| 424 { | 417 { |
| 425 return ensureCachedCollection<HTMLOptionsCollection>(SelectOptions); | 418 return ensureCachedCollection<HTMLOptionsCollection>(SelectOptions); |
| 426 } | 419 } |
| 427 | 420 |
| 428 void HTMLSelectElement::updateListItemSelectedStates() | |
| 429 { | |
| 430 if (!m_shouldRecalcListItems) | |
| 431 return; | |
| 432 recalcListItems(); | |
| 433 setNeedsValidityCheck(); | |
| 434 } | |
| 435 | |
| 436 void HTMLSelectElement::childrenChanged(const ChildrenChange& change) | 421 void HTMLSelectElement::childrenChanged(const ChildrenChange& change) |
| 437 { | 422 { |
| 438 setRecalcListItems(); | 423 setRecalcListItems(); |
| 439 setNeedsValidityCheck(); | 424 setNeedsValidityCheck(); |
| 440 m_lastOnChangeSelection.clear(); | 425 m_lastOnChangeSelection.clear(); |
| 441 | 426 |
| 442 HTMLFormControlElementWithState::childrenChanged(change); | 427 HTMLFormControlElementWithState::childrenChanged(change); |
| 443 } | 428 } |
| 444 | 429 |
| 445 void HTMLSelectElement::optionElementChildrenChanged() | 430 void HTMLSelectElement::optionElementChildrenChanged() |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 783 } | 768 } |
| 784 } | 769 } |
| 785 | 770 |
| 786 const HTMLSelectElement::ListItems& HTMLSelectElement::listItems() const | 771 const HTMLSelectElement::ListItems& HTMLSelectElement::listItems() const |
| 787 { | 772 { |
| 788 if (m_shouldRecalcListItems) { | 773 if (m_shouldRecalcListItems) { |
| 789 recalcListItems(); | 774 recalcListItems(); |
| 790 } else { | 775 } else { |
| 791 #if ENABLE(ASSERT) | 776 #if ENABLE(ASSERT) |
| 792 WillBeHeapVector<RawPtrWillBeMember<HTMLElement>> items = m_listItems; | 777 WillBeHeapVector<RawPtrWillBeMember<HTMLElement>> items = m_listItems; |
| 793 recalcListItems(false); | 778 recalcListItems(); |
| 794 ASSERT(items == m_listItems); | 779 ASSERT(items == m_listItems); |
| 795 #endif | 780 #endif |
| 796 } | 781 } |
| 797 | 782 |
| 798 return m_listItems; | 783 return m_listItems; |
| 799 } | 784 } |
| 800 | 785 |
| 801 void HTMLSelectElement::invalidateSelectedItems() | 786 void HTMLSelectElement::invalidateSelectedItems() |
| 802 { | 787 { |
| 803 if (HTMLCollection* collection = cachedCollection<HTMLCollection>(SelectedOp
tions)) | 788 if (HTMLCollection* collection = cachedCollection<HTMLCollection>(SelectedOp
tions)) |
| (...skipping 12 matching lines...) Expand all Loading... |
| 816 collection->invalidateCache(); | 801 collection->invalidateCache(); |
| 817 invalidateSelectedItems(); | 802 invalidateSelectedItems(); |
| 818 } | 803 } |
| 819 | 804 |
| 820 if (layoutObject()) { | 805 if (layoutObject()) { |
| 821 if (AXObjectCache* cache = layoutObject()->document().existingAXObjectCa
che()) | 806 if (AXObjectCache* cache = layoutObject()->document().existingAXObjectCa
che()) |
| 822 cache->childrenChanged(this); | 807 cache->childrenChanged(this); |
| 823 } | 808 } |
| 824 } | 809 } |
| 825 | 810 |
| 826 void HTMLSelectElement::recalcListItems(bool updateSelectedStates) const | 811 void HTMLSelectElement::recalcListItems() const |
| 827 { | 812 { |
| 828 TRACE_EVENT0("blink", "HTMLSelectElement::recalcListItems"); | 813 TRACE_EVENT0("blink", "HTMLSelectElement::recalcListItems"); |
| 829 m_listItems.clear(); | 814 m_listItems.clear(); |
| 830 | 815 |
| 831 m_shouldRecalcListItems = false; | 816 m_shouldRecalcListItems = false; |
| 832 | 817 |
| 833 HTMLOptionElement* foundSelected = nullptr; | |
| 834 HTMLOptionElement* firstOption = nullptr; | |
| 835 for (Element* currentElement = ElementTraversal::firstWithin(*this); current
Element && m_listItems.size() < maxListItems; ) { | 818 for (Element* currentElement = ElementTraversal::firstWithin(*this); current
Element && m_listItems.size() < maxListItems; ) { |
| 836 if (!currentElement->isHTMLElement()) { | 819 if (!currentElement->isHTMLElement()) { |
| 837 currentElement = ElementTraversal::nextSkippingChildren(*currentElem
ent, this); | 820 currentElement = ElementTraversal::nextSkippingChildren(*currentElem
ent, this); |
| 838 continue; | 821 continue; |
| 839 } | 822 } |
| 840 HTMLElement& current = toHTMLElement(*currentElement); | 823 HTMLElement& current = toHTMLElement(*currentElement); |
| 841 | 824 |
| 842 // We should ignore nested optgroup elements. The HTML parser flatten | 825 // We should ignore nested optgroup elements. The HTML parser flatten |
| 843 // them. However we need to ignore nested optgroups built by DOM APIs. | 826 // them. However we need to ignore nested optgroups built by DOM APIs. |
| 844 // This behavior matches to IE and Firefox. | 827 // This behavior matches to IE and Firefox. |
| 845 if (isHTMLOptGroupElement(current)) { | 828 if (isHTMLOptGroupElement(current)) { |
| 846 if (current.parentNode() != this) { | 829 if (current.parentNode() != this) { |
| 847 currentElement = ElementTraversal::nextSkippingChildren(current,
this); | 830 currentElement = ElementTraversal::nextSkippingChildren(current,
this); |
| 848 continue; | 831 continue; |
| 849 } | 832 } |
| 850 m_listItems.append(¤t); | 833 m_listItems.append(¤t); |
| 851 if (Element* nextElement = ElementTraversal::firstWithin(current)) { | 834 if (Element* nextElement = ElementTraversal::firstWithin(current)) { |
| 852 currentElement = nextElement; | 835 currentElement = nextElement; |
| 853 continue; | 836 continue; |
| 854 } | 837 } |
| 855 } | 838 } |
| 856 | 839 |
| 857 if (isHTMLOptionElement(current)) { | 840 if (isHTMLOptionElement(current)) |
| 858 m_listItems.append(¤t); | 841 m_listItems.append(¤t); |
| 859 | 842 |
| 860 if (updateSelectedStates && !m_multiple) { | |
| 861 HTMLOptionElement& option = toHTMLOptionElement(current); | |
| 862 if (!firstOption) | |
| 863 firstOption = &option; | |
| 864 if (option.selected()) { | |
| 865 if (foundSelected) | |
| 866 foundSelected->setSelectedState(false); | |
| 867 foundSelected = &option; | |
| 868 } else if (m_size <= 1 && !foundSelected && !option.isDisabledFo
rmControl()) { | |
| 869 foundSelected = &option; | |
| 870 foundSelected->setSelectedState(true); | |
| 871 } | |
| 872 } | |
| 873 } | |
| 874 | |
| 875 if (isHTMLHRElement(current)) | 843 if (isHTMLHRElement(current)) |
| 876 m_listItems.append(¤t); | 844 m_listItems.append(¤t); |
| 877 | 845 |
| 878 // In conforming HTML code, only <optgroup> and <option> will be found | 846 // In conforming HTML code, only <optgroup> and <option> will be found |
| 879 // within a <select>. We call NodeTraversal::nextSkippingChildren so | 847 // within a <select>. We call NodeTraversal::nextSkippingChildren so |
| 880 // that we only step into those tags that we choose to. For web-compat, | 848 // that we only step into those tags that we choose to. For web-compat, |
| 881 // we should cope with the case where odd tags like a <div> have been | 849 // we should cope with the case where odd tags like a <div> have been |
| 882 // added but we handle this because such tags have already been removed | 850 // added but we handle this because such tags have already been removed |
| 883 // from the <select>'s subtree at this point. | 851 // from the <select>'s subtree at this point. |
| 884 currentElement = ElementTraversal::nextSkippingChildren(*currentElement,
this); | 852 currentElement = ElementTraversal::nextSkippingChildren(*currentElement,
this); |
| 885 } | 853 } |
| 854 } |
| 886 | 855 |
| 887 if (!foundSelected && m_size <= 1 && firstOption && !firstOption->selected()
) | 856 void HTMLSelectElement::resetToDefaultSelection() |
| 888 firstOption->setSelectedState(true); | 857 { |
| 858 // https://html.spec.whatwg.org/multipage/forms.html#ask-for-a-reset |
| 859 if (multiple()) |
| 860 return; |
| 861 HTMLOptionElement* firstEnabledOption = nullptr; |
| 862 int firstEnabledOptionIndex = -1; |
| 863 HTMLOptionElement* lastSelectedOption = nullptr; |
| 864 bool didChange = false; |
| 865 int optionIndex = 0; |
| 866 // We can't use HTMLSelectElement::options here because this function is |
| 867 // called in Node::insertedInto and Node::removedFrom before invalidating |
| 868 // node collections. |
| 869 for (auto& item : listItems()) { |
| 870 if (!isHTMLOptionElement(item)) |
| 871 continue; |
| 872 HTMLOptionElement* option = toHTMLOptionElement(item); |
| 873 if (option->selected()) { |
| 874 if (lastSelectedOption) { |
| 875 lastSelectedOption->setSelectedState(false); |
| 876 didChange = true; |
| 877 } |
| 878 lastSelectedOption = option; |
| 879 } |
| 880 if (!firstEnabledOption && !option->isDisabledFormControl()) { |
| 881 firstEnabledOption = option; |
| 882 firstEnabledOptionIndex = optionIndex; |
| 883 } |
| 884 ++optionIndex; |
| 885 } |
| 886 if (!lastSelectedOption && m_size <= 1 && firstEnabledOption && !firstEnable
dOption->selected()) { |
| 887 selectOption(firstEnabledOption, firstEnabledOptionIndex, 0); |
| 888 lastSelectedOption = firstEnabledOption; |
| 889 didChange = true; |
| 890 } |
| 891 if (didChange) |
| 892 setNeedsValidityCheck(); |
| 893 m_lastOnChangeOption = lastSelectedOption; |
| 889 } | 894 } |
| 890 | 895 |
| 891 HTMLOptionElement* HTMLSelectElement::selectedOption() const | 896 HTMLOptionElement* HTMLSelectElement::selectedOption() const |
| 892 { | 897 { |
| 893 for (const auto& element : listItems()) { | 898 for (const auto& element : listItems()) { |
| 894 if (isHTMLOptionElement(*element) && toHTMLOptionElement(*element).selec
ted()) | 899 if (isHTMLOptionElement(*element) && toHTMLOptionElement(*element).selec
ted()) |
| 895 return toHTMLOptionElement(element); | 900 return toHTMLOptionElement(element); |
| 896 } | 901 } |
| 897 return nullptr; | 902 return nullptr; |
| 898 } | 903 } |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 973 else if (!usesMenuList() || multiple()) | 978 else if (!usesMenuList() || multiple()) |
| 974 selectOption(nullptr); | 979 selectOption(nullptr); |
| 975 else | 980 else |
| 976 selectOption(nextSelectableOption(nullptr)); | 981 selectOption(nextSelectableOption(nullptr)); |
| 977 } | 982 } |
| 978 | 983 |
| 979 void HTMLSelectElement::optionInserted(HTMLOptionElement& option, bool optionIsS
elected) | 984 void HTMLSelectElement::optionInserted(HTMLOptionElement& option, bool optionIsS
elected) |
| 980 { | 985 { |
| 981 ASSERT(option.ownerSelectElement() == this); | 986 ASSERT(option.ownerSelectElement() == this); |
| 982 setRecalcListItems(); | 987 setRecalcListItems(); |
| 983 if (optionIsSelected) | 988 if (optionIsSelected) { |
| 984 selectOption(&option); | 989 selectOption(&option); |
| 990 } else { |
| 991 // No need to reset if we already have a selected option. |
| 992 if (!m_lastOnChangeOption) |
| 993 resetToDefaultSelection(); |
| 994 } |
| 985 } | 995 } |
| 986 | 996 |
| 987 void HTMLSelectElement::optionRemoved(const HTMLOptionElement& option) | 997 void HTMLSelectElement::optionRemoved(const HTMLOptionElement& option) |
| 988 { | 998 { |
| 989 setRecalcListItems(); | 999 setRecalcListItems(); |
| 1000 if (option.selected() || !m_lastOnChangeOption) |
| 1001 resetToDefaultSelection(); |
| 990 if (m_lastOnChangeOption == &option) | 1002 if (m_lastOnChangeOption == &option) |
| 991 m_lastOnChangeOption.clear(); | 1003 m_lastOnChangeOption.clear(); |
| 992 if (m_optionToScrollTo == &option) | 1004 if (m_optionToScrollTo == &option) |
| 993 m_optionToScrollTo.clear(); | 1005 m_optionToScrollTo.clear(); |
| 994 if (m_activeSelectionAnchor == &option) | 1006 if (m_activeSelectionAnchor == &option) |
| 995 m_activeSelectionAnchor.clear(); | 1007 m_activeSelectionAnchor.clear(); |
| 996 if (m_activeSelectionEnd == &option) | 1008 if (m_activeSelectionEnd == &option) |
| 997 m_activeSelectionEnd.clear(); | 1009 m_activeSelectionEnd.clear(); |
| 998 if (option.selected()) | 1010 if (option.selected()) |
| 999 setAutofilled(false); | 1011 setAutofilled(false); |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1235 return; | 1247 return; |
| 1236 | 1248 |
| 1237 for (auto& element : listItems()) { | 1249 for (auto& element : listItems()) { |
| 1238 if (isHTMLOptionElement(*element) && toHTMLOptionElement(*element).selec
ted() && !toHTMLOptionElement(*element).isDisabledFormControl()) | 1250 if (isHTMLOptionElement(*element) && toHTMLOptionElement(*element).selec
ted() && !toHTMLOptionElement(*element).isDisabledFormControl()) |
| 1239 formData.append(name, toHTMLOptionElement(*element).value()); | 1251 formData.append(name, toHTMLOptionElement(*element).value()); |
| 1240 } | 1252 } |
| 1241 } | 1253 } |
| 1242 | 1254 |
| 1243 void HTMLSelectElement::resetImpl() | 1255 void HTMLSelectElement::resetImpl() |
| 1244 { | 1256 { |
| 1245 HTMLOptionElement* firstOption = nullptr; | |
| 1246 HTMLOptionElement* selectedOption = nullptr; | |
| 1247 | |
| 1248 for (auto& item : listItems()) { | 1257 for (auto& item : listItems()) { |
| 1249 if (!isHTMLOptionElement(item)) | 1258 if (!isHTMLOptionElement(item)) |
| 1250 continue; | 1259 continue; |
| 1251 HTMLOptionElement* option = toHTMLOptionElement(item); | 1260 HTMLOptionElement* option = toHTMLOptionElement(item); |
| 1252 if (option->fastHasAttribute(selectedAttr)) { | 1261 option->setSelectedState(option->fastHasAttribute(selectedAttr)); |
| 1253 if (selectedOption && !m_multiple) | |
| 1254 selectedOption->setSelectedState(false); | |
| 1255 option->setSelectedState(true); | |
| 1256 selectedOption = option; | |
| 1257 } else { | |
| 1258 option->setSelectedState(false); | |
| 1259 } | |
| 1260 option->setDirty(false); | 1262 option->setDirty(false); |
| 1261 | |
| 1262 if (!firstOption && !option->isDisabledFormControl()) | |
| 1263 firstOption = option; | |
| 1264 } | 1263 } |
| 1265 | 1264 resetToDefaultSelection(); |
| 1266 if (!selectedOption && firstOption && !m_multiple && m_size <= 1) { | |
| 1267 firstOption->setSelectedState(true); | |
| 1268 selectedOption = firstOption; | |
| 1269 } | |
| 1270 | |
| 1271 m_lastOnChangeOption = selectedOption; | |
| 1272 setOptionsChangedOnLayoutObject(); | 1265 setOptionsChangedOnLayoutObject(); |
| 1273 setNeedsValidityCheck(); | 1266 setNeedsValidityCheck(); |
| 1274 } | 1267 } |
| 1275 | 1268 |
| 1276 void HTMLSelectElement::handlePopupOpenKeyboardEvent(Event* event) | 1269 void HTMLSelectElement::handlePopupOpenKeyboardEvent(Event* event) |
| 1277 { | 1270 { |
| 1278 focus(); | 1271 focus(); |
| 1279 // Calling focus() may cause us to lose our layoutObject. Return true so | 1272 // Calling focus() may cause us to lose our layoutObject. Return true so |
| 1280 // that our caller doesn't process the event further, but don't set | 1273 // that our caller doesn't process the event further, but don't set |
| 1281 // the event as handled. | 1274 // the event as handled. |
| (...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1787 for (auto& item : listItems()) { | 1780 for (auto& item : listItems()) { |
| 1788 if (isHTMLOptionElement(*item)) | 1781 if (isHTMLOptionElement(*item)) |
| 1789 ++options; | 1782 ++options; |
| 1790 } | 1783 } |
| 1791 return options; | 1784 return options; |
| 1792 } | 1785 } |
| 1793 | 1786 |
| 1794 void HTMLSelectElement::finishParsingChildren() | 1787 void HTMLSelectElement::finishParsingChildren() |
| 1795 { | 1788 { |
| 1796 HTMLFormControlElementWithState::finishParsingChildren(); | 1789 HTMLFormControlElementWithState::finishParsingChildren(); |
| 1797 updateListItemSelectedStates(); | |
| 1798 if (usesMenuList()) | 1790 if (usesMenuList()) |
| 1799 return; | 1791 return; |
| 1800 scrollToOption(selectedOption()); | 1792 scrollToOption(selectedOption()); |
| 1801 if (AXObjectCache* cache = document().existingAXObjectCache()) | 1793 if (AXObjectCache* cache = document().existingAXObjectCache()) |
| 1802 cache->listboxActiveIndexChanged(this); | 1794 cache->listboxActiveIndexChanged(this); |
| 1803 } | 1795 } |
| 1804 | 1796 |
| 1805 bool HTMLSelectElement::anonymousIndexedSetter(unsigned index, PassRefPtrWillBeR
awPtr<HTMLOptionElement> value, ExceptionState& exceptionState) | 1797 bool HTMLSelectElement::anonymousIndexedSetter(unsigned index, PassRefPtrWillBeR
awPtr<HTMLOptionElement> value, ExceptionState& exceptionState) |
| 1806 { | 1798 { |
| 1807 if (!value) { // undefined or null | 1799 if (!value) { // undefined or null |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1833 visitor->trace(m_listItems); | 1825 visitor->trace(m_listItems); |
| 1834 #endif | 1826 #endif |
| 1835 visitor->trace(m_lastOnChangeOption); | 1827 visitor->trace(m_lastOnChangeOption); |
| 1836 visitor->trace(m_activeSelectionAnchor); | 1828 visitor->trace(m_activeSelectionAnchor); |
| 1837 visitor->trace(m_activeSelectionEnd); | 1829 visitor->trace(m_activeSelectionEnd); |
| 1838 visitor->trace(m_optionToScrollTo); | 1830 visitor->trace(m_optionToScrollTo); |
| 1839 visitor->trace(m_popup); | 1831 visitor->trace(m_popup); |
| 1840 HTMLFormControlElementWithState::trace(visitor); | 1832 HTMLFormControlElementWithState::trace(visitor); |
| 1841 } | 1833 } |
| 1842 | 1834 |
| 1843 void HTMLSelectElement::willRecalcStyle(StyleRecalcChange change) | |
| 1844 { | |
| 1845 // recalcListItems will update the selected state of the <option> elements | |
| 1846 // in this <select> so we need to do it before we recalc their style so they | |
| 1847 // match the right selectors (ex. :checked). | |
| 1848 // TODO(esprehn): Find a way to avoid needing a willRecalcStyle callback. | |
| 1849 if (m_shouldRecalcListItems) | |
| 1850 recalcListItems(); | |
| 1851 } | |
| 1852 | |
| 1853 void HTMLSelectElement::didAddUserAgentShadowRoot(ShadowRoot& root) | 1835 void HTMLSelectElement::didAddUserAgentShadowRoot(ShadowRoot& root) |
| 1854 { | 1836 { |
| 1855 RefPtrWillBeRawPtr<HTMLContentElement> content = HTMLContentElement::create(
document()); | 1837 RefPtrWillBeRawPtr<HTMLContentElement> content = HTMLContentElement::create(
document()); |
| 1856 content->setAttribute(selectAttr, "option,optgroup,hr"); | 1838 content->setAttribute(selectAttr, "option,optgroup,hr"); |
| 1857 root.appendChild(content); | 1839 root.appendChild(content); |
| 1858 } | 1840 } |
| 1859 | 1841 |
| 1860 HTMLOptionElement* HTMLSelectElement::spatialNavigationFocusedOption() | 1842 HTMLOptionElement* HTMLSelectElement::spatialNavigationFocusedOption() |
| 1861 { | 1843 { |
| 1862 if (!isSpatialNavigationEnabled(document().frame())) | 1844 if (!isSpatialNavigationEnabled(document().frame())) |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2005 m_popupIsVisible = false; | 1987 m_popupIsVisible = false; |
| 2006 m_popup = nullptr; | 1988 m_popup = nullptr; |
| 2007 } | 1989 } |
| 2008 | 1990 |
| 2009 void HTMLSelectElement::resetTypeAheadSessionForTesting() | 1991 void HTMLSelectElement::resetTypeAheadSessionForTesting() |
| 2010 { | 1992 { |
| 2011 m_typeAhead.resetSession(); | 1993 m_typeAhead.resetSession(); |
| 2012 } | 1994 } |
| 2013 | 1995 |
| 2014 } // namespace blink | 1996 } // namespace blink |
| OLD | NEW |