| 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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 , m_activeSelectionState(false) | 91 , m_activeSelectionState(false) |
| 92 , m_shouldRecalcListItems(false) | 92 , m_shouldRecalcListItems(false) |
| 93 , m_suggestedIndex(-1) | 93 , m_suggestedIndex(-1) |
| 94 , m_isAutofilledByPreview(false) | 94 , m_isAutofilledByPreview(false) |
| 95 , m_indexToSelectOnCancel(-1) | 95 , m_indexToSelectOnCancel(-1) |
| 96 , m_popupIsVisible(false) | 96 , m_popupIsVisible(false) |
| 97 { | 97 { |
| 98 setHasCustomStyleCallbacks(); | 98 setHasCustomStyleCallbacks(); |
| 99 } | 99 } |
| 100 | 100 |
| 101 PassRefPtrWillBeRawPtr<HTMLSelectElement> HTMLSelectElement::create(Document& do
cument) | 101 RawPtr<HTMLSelectElement> HTMLSelectElement::create(Document& document) |
| 102 { | 102 { |
| 103 RefPtrWillBeRawPtr<HTMLSelectElement> select = adoptRefWillBeNoop(new HTMLSe
lectElement(document, 0)); | 103 RawPtr<HTMLSelectElement> select = (new HTMLSelectElement(document, 0)); |
| 104 select->ensureUserAgentShadowRoot(); | 104 select->ensureUserAgentShadowRoot(); |
| 105 return select.release(); | 105 return select.release(); |
| 106 } | 106 } |
| 107 | 107 |
| 108 PassRefPtrWillBeRawPtr<HTMLSelectElement> HTMLSelectElement::create(Document& do
cument, HTMLFormElement* form) | 108 RawPtr<HTMLSelectElement> HTMLSelectElement::create(Document& document, HTMLForm
Element* form) |
| 109 { | 109 { |
| 110 RefPtrWillBeRawPtr<HTMLSelectElement> select = adoptRefWillBeNoop(new HTMLSe
lectElement(document, form)); | 110 RawPtr<HTMLSelectElement> select = (new HTMLSelectElement(document, form)); |
| 111 select->ensureUserAgentShadowRoot(); | 111 select->ensureUserAgentShadowRoot(); |
| 112 return select.release(); | 112 return select.release(); |
| 113 } | 113 } |
| 114 | 114 |
| 115 HTMLSelectElement::~HTMLSelectElement() | 115 HTMLSelectElement::~HTMLSelectElement() |
| 116 { | 116 { |
| 117 } | 117 } |
| 118 | 118 |
| 119 const AtomicString& HTMLSelectElement::formControlType() const | 119 const AtomicString& HTMLSelectElement::formControlType() const |
| 120 { | 120 { |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 | 223 |
| 224 int HTMLSelectElement::activeSelectionEndListIndex() const | 224 int HTMLSelectElement::activeSelectionEndListIndex() const |
| 225 { | 225 { |
| 226 if (m_activeSelectionEndIndex >= 0) | 226 if (m_activeSelectionEndIndex >= 0) |
| 227 return m_activeSelectionEndIndex; | 227 return m_activeSelectionEndIndex; |
| 228 return lastSelectedListIndex(); | 228 return lastSelectedListIndex(); |
| 229 } | 229 } |
| 230 | 230 |
| 231 void HTMLSelectElement::add(const HTMLOptionElementOrHTMLOptGroupElement& elemen
t, const HTMLElementOrLong& before, ExceptionState& exceptionState) | 231 void HTMLSelectElement::add(const HTMLOptionElementOrHTMLOptGroupElement& elemen
t, const HTMLElementOrLong& before, ExceptionState& exceptionState) |
| 232 { | 232 { |
| 233 RefPtrWillBeRawPtr<HTMLElement> elementToInsert; | 233 RawPtr<HTMLElement> elementToInsert; |
| 234 ASSERT(!element.isNull()); | 234 ASSERT(!element.isNull()); |
| 235 if (element.isHTMLOptionElement()) | 235 if (element.isHTMLOptionElement()) |
| 236 elementToInsert = element.getAsHTMLOptionElement(); | 236 elementToInsert = element.getAsHTMLOptionElement(); |
| 237 else | 237 else |
| 238 elementToInsert = element.getAsHTMLOptGroupElement(); | 238 elementToInsert = element.getAsHTMLOptGroupElement(); |
| 239 | 239 |
| 240 RefPtrWillBeRawPtr<HTMLElement> beforeElement; | 240 RawPtr<HTMLElement> beforeElement; |
| 241 if (before.isHTMLElement()) | 241 if (before.isHTMLElement()) |
| 242 beforeElement = before.getAsHTMLElement(); | 242 beforeElement = before.getAsHTMLElement(); |
| 243 else if (before.isLong()) | 243 else if (before.isLong()) |
| 244 beforeElement = options()->item(before.getAsLong()); | 244 beforeElement = options()->item(before.getAsLong()); |
| 245 else | 245 else |
| 246 beforeElement = nullptr; | 246 beforeElement = nullptr; |
| 247 | 247 |
| 248 insertBefore(elementToInsert, beforeElement.get(), exceptionState); | 248 insertBefore(elementToInsert, beforeElement.get(), exceptionState); |
| 249 setNeedsValidityCheck(); | 249 setNeedsValidityCheck(); |
| 250 } | 250 } |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 return !usesMenuList(); | 394 return !usesMenuList(); |
| 395 } | 395 } |
| 396 | 396 |
| 397 LayoutObject* HTMLSelectElement::createLayoutObject(const ComputedStyle&) | 397 LayoutObject* HTMLSelectElement::createLayoutObject(const ComputedStyle&) |
| 398 { | 398 { |
| 399 if (usesMenuList()) | 399 if (usesMenuList()) |
| 400 return new LayoutMenuList(this); | 400 return new LayoutMenuList(this); |
| 401 return new LayoutListBox(this); | 401 return new LayoutListBox(this); |
| 402 } | 402 } |
| 403 | 403 |
| 404 PassRefPtrWillBeRawPtr<HTMLCollection> HTMLSelectElement::selectedOptions() | 404 RawPtr<HTMLCollection> HTMLSelectElement::selectedOptions() |
| 405 { | 405 { |
| 406 updateListItemSelectedStates(); | 406 updateListItemSelectedStates(); |
| 407 return ensureCachedCollection<HTMLCollection>(SelectedOptions); | 407 return ensureCachedCollection<HTMLCollection>(SelectedOptions); |
| 408 } | 408 } |
| 409 | 409 |
| 410 PassRefPtrWillBeRawPtr<HTMLOptionsCollection> HTMLSelectElement::options() | 410 RawPtr<HTMLOptionsCollection> HTMLSelectElement::options() |
| 411 { | 411 { |
| 412 return ensureCachedCollection<HTMLOptionsCollection>(SelectOptions); | 412 return ensureCachedCollection<HTMLOptionsCollection>(SelectOptions); |
| 413 } | 413 } |
| 414 | 414 |
| 415 void HTMLSelectElement::updateListItemSelectedStates() | 415 void HTMLSelectElement::updateListItemSelectedStates() |
| 416 { | 416 { |
| 417 if (!m_shouldRecalcListItems) | 417 if (!m_shouldRecalcListItems) |
| 418 return; | 418 return; |
| 419 recalcListItems(); | 419 recalcListItems(); |
| 420 setNeedsValidityCheck(); | 420 setNeedsValidityCheck(); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 if (diff < 0) { // Add dummy elements. | 513 if (diff < 0) { // Add dummy elements. |
| 514 do { | 514 do { |
| 515 appendChild(document().createElement(optionTag, false), exceptionSta
te); | 515 appendChild(document().createElement(optionTag, false), exceptionSta
te); |
| 516 if (exceptionState.hadException()) | 516 if (exceptionState.hadException()) |
| 517 break; | 517 break; |
| 518 } while (++diff); | 518 } while (++diff); |
| 519 } else { | 519 } else { |
| 520 // Removing children fires mutation events, which might mutate the DOM | 520 // Removing children fires mutation events, which might mutate the DOM |
| 521 // further, so we first copy out a list of elements that we intend to | 521 // further, so we first copy out a list of elements that we intend to |
| 522 // remove then attempt to remove them one at a time. | 522 // remove then attempt to remove them one at a time. |
| 523 WillBeHeapVector<RefPtrWillBeMember<Element>> itemsToRemove; | 523 HeapVector<Member<Element>> itemsToRemove; |
| 524 size_t optionIndex = 0; | 524 size_t optionIndex = 0; |
| 525 for (auto& item : listItems()) { | 525 for (auto& item : listItems()) { |
| 526 if (isHTMLOptionElement(item) && optionIndex++ >= newLen) { | 526 if (isHTMLOptionElement(item) && optionIndex++ >= newLen) { |
| 527 ASSERT(item->parentNode()); | 527 ASSERT(item->parentNode()); |
| 528 itemsToRemove.append(item.get()); | 528 itemsToRemove.append(item.get()); |
| 529 } | 529 } |
| 530 } | 530 } |
| 531 | 531 |
| 532 for (auto& item : itemsToRemove) { | 532 for (auto& item : itemsToRemove) { |
| 533 if (item->parentNode()) | 533 if (item->parentNode()) |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 723 bool fireOnChange = false; | 723 bool fireOnChange = false; |
| 724 for (unsigned i = 0; i < items.size(); ++i) { | 724 for (unsigned i = 0; i < items.size(); ++i) { |
| 725 HTMLElement* element = items[i]; | 725 HTMLElement* element = items[i]; |
| 726 bool selected = isHTMLOptionElement(*element) && toHTMLOptionElement(ele
ment)->selected(); | 726 bool selected = isHTMLOptionElement(*element) && toHTMLOptionElement(ele
ment)->selected(); |
| 727 if (selected != m_lastOnChangeSelection[i]) | 727 if (selected != m_lastOnChangeSelection[i]) |
| 728 fireOnChange = true; | 728 fireOnChange = true; |
| 729 m_lastOnChangeSelection[i] = selected; | 729 m_lastOnChangeSelection[i] = selected; |
| 730 } | 730 } |
| 731 | 731 |
| 732 if (fireOnChange) { | 732 if (fireOnChange) { |
| 733 RefPtrWillBeRawPtr<HTMLSelectElement> protector(this); | 733 RawPtr<HTMLSelectElement> protector(this); |
| 734 dispatchInputEvent(); | 734 dispatchInputEvent(); |
| 735 dispatchFormControlChangeEvent(); | 735 dispatchFormControlChangeEvent(); |
| 736 } | 736 } |
| 737 } | 737 } |
| 738 | 738 |
| 739 void HTMLSelectElement::dispatchInputAndChangeEventForMenuList() | 739 void HTMLSelectElement::dispatchInputAndChangeEventForMenuList() |
| 740 { | 740 { |
| 741 ASSERT(usesMenuList()); | 741 ASSERT(usesMenuList()); |
| 742 | 742 |
| 743 HTMLOptionElement* selectedOption = this->selectedOption(); | 743 HTMLOptionElement* selectedOption = this->selectedOption(); |
| 744 if (m_lastOnChangeOption.get() != selectedOption) { | 744 if (m_lastOnChangeOption.get() != selectedOption) { |
| 745 m_lastOnChangeOption = selectedOption; | 745 m_lastOnChangeOption = selectedOption; |
| 746 RefPtrWillBeRawPtr<HTMLSelectElement> protector(this); | 746 RawPtr<HTMLSelectElement> protector(this); |
| 747 dispatchInputEvent(); | 747 dispatchInputEvent(); |
| 748 dispatchFormControlChangeEvent(); | 748 dispatchFormControlChangeEvent(); |
| 749 } | 749 } |
| 750 } | 750 } |
| 751 | 751 |
| 752 void HTMLSelectElement::scrollToSelection() | 752 void HTMLSelectElement::scrollToSelection() |
| 753 { | 753 { |
| 754 if (!isFinishedParsingChildren()) | 754 if (!isFinishedParsingChildren()) |
| 755 return; | 755 return; |
| 756 if (usesMenuList()) | 756 if (usesMenuList()) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 767 toLayoutMenuList(layoutObject)->setOptionsChanged(true); | 767 toLayoutMenuList(layoutObject)->setOptionsChanged(true); |
| 768 } | 768 } |
| 769 } | 769 } |
| 770 | 770 |
| 771 const HTMLSelectElement::ListItems& HTMLSelectElement::listItems() const | 771 const HTMLSelectElement::ListItems& HTMLSelectElement::listItems() const |
| 772 { | 772 { |
| 773 if (m_shouldRecalcListItems) { | 773 if (m_shouldRecalcListItems) { |
| 774 recalcListItems(); | 774 recalcListItems(); |
| 775 } else { | 775 } else { |
| 776 #if ENABLE(ASSERT) | 776 #if ENABLE(ASSERT) |
| 777 WillBeHeapVector<RawPtrWillBeMember<HTMLElement>> items = m_listItems; | 777 HeapVector<Member<HTMLElement>> items = m_listItems; |
| 778 recalcListItems(false); | 778 recalcListItems(false); |
| 779 ASSERT(items == m_listItems); | 779 ASSERT(items == m_listItems); |
| 780 #endif | 780 #endif |
| 781 } | 781 } |
| 782 | 782 |
| 783 return m_listItems; | 783 return m_listItems; |
| 784 } | 784 } |
| 785 | 785 |
| 786 void HTMLSelectElement::invalidateSelectedItems() | 786 void HTMLSelectElement::invalidateSelectedItems() |
| 787 { | 787 { |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 938 // unnecessary. The specified listIndex must point an HTMLOptionElement, but | 938 // unnecessary. The specified listIndex must point an HTMLOptionElement, but |
| 939 // our code about activeSelection{Anchor,End}Index is not reliable. | 939 // our code about activeSelection{Anchor,End}Index is not reliable. |
| 940 if (!isHTMLOptionElement(*items[listIndex])) | 940 if (!isHTMLOptionElement(*items[listIndex])) |
| 941 return; | 941 return; |
| 942 bool hasPendingTask = m_optionToScrollTo; | 942 bool hasPendingTask = m_optionToScrollTo; |
| 943 // We'd like to keep an HTMLOptionElement reference rather than |listIndex| | 943 // We'd like to keep an HTMLOptionElement reference rather than |listIndex| |
| 944 // because the task should work even if unselected option is inserted before | 944 // because the task should work even if unselected option is inserted before |
| 945 // |listIndex| before executing scrollToIndexTask(). | 945 // |listIndex| before executing scrollToIndexTask(). |
| 946 m_optionToScrollTo = toHTMLOptionElement(items[listIndex]); | 946 m_optionToScrollTo = toHTMLOptionElement(items[listIndex]); |
| 947 if (!hasPendingTask) | 947 if (!hasPendingTask) |
| 948 document().postTask(BLINK_FROM_HERE, createSameThreadTask(&HTMLSelectEle
ment::scrollToIndexTask, PassRefPtrWillBeRawPtr<HTMLSelectElement>(this))); | 948 document().postTask(BLINK_FROM_HERE, createSameThreadTask(&HTMLSelectEle
ment::scrollToIndexTask, RawPtr<HTMLSelectElement>(this))); |
| 949 } | 949 } |
| 950 | 950 |
| 951 void HTMLSelectElement::scrollToIndexTask() | 951 void HTMLSelectElement::scrollToIndexTask() |
| 952 { | 952 { |
| 953 RefPtrWillBeRawPtr<HTMLOptionElement> option = m_optionToScrollTo.release(); | 953 RawPtr<HTMLOptionElement> option = m_optionToScrollTo.release(); |
| 954 if (!option || !inDocument()) | 954 if (!option || !inDocument()) |
| 955 return; | 955 return; |
| 956 // optionRemoved() makes sure m_optionToScrollTo doesn't have an option with | 956 // optionRemoved() makes sure m_optionToScrollTo doesn't have an option with |
| 957 // another owner. | 957 // another owner. |
| 958 ASSERT(option->ownerSelectElement() == this); | 958 ASSERT(option->ownerSelectElement() == this); |
| 959 document().updateLayoutIgnorePendingStylesheets(); | 959 document().updateLayoutIgnorePendingStylesheets(); |
| 960 if (!layoutObject() || !layoutObject()->isListBox()) | 960 if (!layoutObject() || !layoutObject()->isListBox()) |
| 961 return; | 961 return; |
| 962 LayoutRect bounds = option->boundingBox(); | 962 LayoutRect bounds = option->boundingBox(); |
| 963 toLayoutListBox(layoutObject())->scrollToRect(bounds); | 963 toLayoutListBox(layoutObject())->scrollToRect(bounds); |
| (...skipping 835 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1799 { | 1799 { |
| 1800 HTMLFormControlElementWithState::finishParsingChildren(); | 1800 HTMLFormControlElementWithState::finishParsingChildren(); |
| 1801 updateListItemSelectedStates(); | 1801 updateListItemSelectedStates(); |
| 1802 if (usesMenuList()) | 1802 if (usesMenuList()) |
| 1803 return; | 1803 return; |
| 1804 scrollToIndex(optionToListIndex(selectedIndex())); | 1804 scrollToIndex(optionToListIndex(selectedIndex())); |
| 1805 if (AXObjectCache* cache = document().existingAXObjectCache()) | 1805 if (AXObjectCache* cache = document().existingAXObjectCache()) |
| 1806 cache->listboxActiveIndexChanged(this); | 1806 cache->listboxActiveIndexChanged(this); |
| 1807 } | 1807 } |
| 1808 | 1808 |
| 1809 bool HTMLSelectElement::anonymousIndexedSetter(unsigned index, PassRefPtrWillBeR
awPtr<HTMLOptionElement> value, ExceptionState& exceptionState) | 1809 bool HTMLSelectElement::anonymousIndexedSetter(unsigned index, RawPtr<HTMLOption
Element> value, ExceptionState& exceptionState) |
| 1810 { | 1810 { |
| 1811 if (!value) { // undefined or null | 1811 if (!value) { // undefined or null |
| 1812 remove(index); | 1812 remove(index); |
| 1813 return true; | 1813 return true; |
| 1814 } | 1814 } |
| 1815 setOption(index, value.get(), exceptionState); | 1815 setOption(index, value.get(), exceptionState); |
| 1816 return true; | 1816 return true; |
| 1817 } | 1817 } |
| 1818 | 1818 |
| 1819 bool HTMLSelectElement::isInteractiveContent() const | 1819 bool HTMLSelectElement::isInteractiveContent() const |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1847 // recalcListItems will update the selected state of the <option> elements | 1847 // recalcListItems will update the selected state of the <option> elements |
| 1848 // in this <select> so we need to do it before we recalc their style so they | 1848 // in this <select> so we need to do it before we recalc their style so they |
| 1849 // match the right selectors (ex. :checked). | 1849 // match the right selectors (ex. :checked). |
| 1850 // TODO(esprehn): Find a way to avoid needing a willRecalcStyle callback. | 1850 // TODO(esprehn): Find a way to avoid needing a willRecalcStyle callback. |
| 1851 if (m_shouldRecalcListItems) | 1851 if (m_shouldRecalcListItems) |
| 1852 recalcListItems(); | 1852 recalcListItems(); |
| 1853 } | 1853 } |
| 1854 | 1854 |
| 1855 void HTMLSelectElement::didAddUserAgentShadowRoot(ShadowRoot& root) | 1855 void HTMLSelectElement::didAddUserAgentShadowRoot(ShadowRoot& root) |
| 1856 { | 1856 { |
| 1857 RefPtrWillBeRawPtr<HTMLContentElement> content = HTMLContentElement::create(
document()); | 1857 RawPtr<HTMLContentElement> content = HTMLContentElement::create(document()); |
| 1858 content->setAttribute(selectAttr, "option,optgroup,hr"); | 1858 content->setAttribute(selectAttr, "option,optgroup,hr"); |
| 1859 root.appendChild(content); | 1859 root.appendChild(content); |
| 1860 } | 1860 } |
| 1861 | 1861 |
| 1862 HTMLOptionElement* HTMLSelectElement::spatialNavigationFocusedOption() | 1862 HTMLOptionElement* HTMLSelectElement::spatialNavigationFocusedOption() |
| 1863 { | 1863 { |
| 1864 if (!isSpatialNavigationEnabled(document().frame())) | 1864 if (!isSpatialNavigationEnabled(document().frame())) |
| 1865 return nullptr; | 1865 return nullptr; |
| 1866 int focusedIndex = activeSelectionEndListIndex(); | 1866 int focusedIndex = activeSelectionEndListIndex(); |
| 1867 if (focusedIndex < 0) | 1867 if (focusedIndex < 0) |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2010 m_popupIsVisible = false; | 2010 m_popupIsVisible = false; |
| 2011 m_popup = nullptr; | 2011 m_popup = nullptr; |
| 2012 } | 2012 } |
| 2013 | 2013 |
| 2014 void HTMLSelectElement::resetTypeAheadSessionForTesting() | 2014 void HTMLSelectElement::resetTypeAheadSessionForTesting() |
| 2015 { | 2015 { |
| 2016 m_typeAhead.resetSession(); | 2016 m_typeAhead.resetSession(); |
| 2017 } | 2017 } |
| 2018 | 2018 |
| 2019 } // namespace blink | 2019 } // namespace blink |
| OLD | NEW |