| 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 | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2011 Apple Inc. All rights |
| 7 * reserved. | 7 * reserved. |
| 8 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) | 8 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) |
| 9 * Copyright (C) 2010 Google Inc. All rights reserved. | 9 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 10 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. | 10 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. |
| (...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 } while (++diff); | 439 } while (++diff); |
| 440 } else { | 440 } else { |
| 441 // Removing children fires mutation events, which might mutate the DOM | 441 // Removing children fires mutation events, which might mutate the DOM |
| 442 // further, so we first copy out a list of elements that we intend to | 442 // further, so we first copy out a list of elements that we intend to |
| 443 // remove then attempt to remove them one at a time. | 443 // remove then attempt to remove them one at a time. |
| 444 HeapVector<Member<HTMLOptionElement>> itemsToRemove; | 444 HeapVector<Member<HTMLOptionElement>> itemsToRemove; |
| 445 size_t optionIndex = 0; | 445 size_t optionIndex = 0; |
| 446 for (const auto& option : optionList()) { | 446 for (const auto& option : optionList()) { |
| 447 if (optionIndex++ >= newLen) { | 447 if (optionIndex++ >= newLen) { |
| 448 DCHECK(option->parentNode()); | 448 DCHECK(option->parentNode()); |
| 449 itemsToRemove.append(option); | 449 itemsToRemove.push_back(option); |
| 450 } | 450 } |
| 451 } | 451 } |
| 452 | 452 |
| 453 for (auto& item : itemsToRemove) { | 453 for (auto& item : itemsToRemove) { |
| 454 if (item->parentNode()) | 454 if (item->parentNode()) |
| 455 item->parentNode()->removeChild(item.get(), exceptionState); | 455 item->parentNode()->removeChild(item.get(), exceptionState); |
| 456 } | 456 } |
| 457 } | 457 } |
| 458 setNeedsValidityCheck(); | 458 setNeedsValidityCheck(); |
| 459 } | 459 } |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 572 } | 572 } |
| 573 | 573 |
| 574 void HTMLSelectElement::saveLastSelection() { | 574 void HTMLSelectElement::saveLastSelection() { |
| 575 if (usesMenuList()) { | 575 if (usesMenuList()) { |
| 576 m_lastOnChangeOption = selectedOption(); | 576 m_lastOnChangeOption = selectedOption(); |
| 577 return; | 577 return; |
| 578 } | 578 } |
| 579 | 579 |
| 580 m_lastOnChangeSelection.clear(); | 580 m_lastOnChangeSelection.clear(); |
| 581 for (auto& element : listItems()) | 581 for (auto& element : listItems()) |
| 582 m_lastOnChangeSelection.append(isHTMLOptionElement(*element) && | 582 m_lastOnChangeSelection.push_back(isHTMLOptionElement(*element) && |
| 583 toHTMLOptionElement(element)->selected()); | 583 toHTMLOptionElement(element)->selected()); |
| 584 } | 584 } |
| 585 | 585 |
| 586 void HTMLSelectElement::setActiveSelectionAnchor(HTMLOptionElement* option) { | 586 void HTMLSelectElement::setActiveSelectionAnchor(HTMLOptionElement* option) { |
| 587 m_activeSelectionAnchor = option; | 587 m_activeSelectionAnchor = option; |
| 588 if (!usesMenuList()) | 588 if (!usesMenuList()) |
| 589 saveListboxActiveSelection(); | 589 saveListboxActiveSelection(); |
| 590 } | 590 } |
| 591 | 591 |
| 592 void HTMLSelectElement::saveListboxActiveSelection() { | 592 void HTMLSelectElement::saveListboxActiveSelection() { |
| 593 // Cache the selection state so we can restore the old selection as the new | 593 // Cache the selection state so we can restore the old selection as the new |
| 594 // selection pivots around this anchor index. | 594 // selection pivots around this anchor index. |
| 595 // Example: | 595 // Example: |
| 596 // 1. Press the mouse button on the second OPTION | 596 // 1. Press the mouse button on the second OPTION |
| 597 // m_activeSelectionAnchorIndex = 1 | 597 // m_activeSelectionAnchorIndex = 1 |
| 598 // 2. Drag the mouse pointer onto the fifth OPTION | 598 // 2. Drag the mouse pointer onto the fifth OPTION |
| 599 // m_activeSelectionEndIndex = 4, options at 1-4 indices are selected. | 599 // m_activeSelectionEndIndex = 4, options at 1-4 indices are selected. |
| 600 // 3. Drag the mouse pointer onto the fourth OPTION | 600 // 3. Drag the mouse pointer onto the fourth OPTION |
| 601 // m_activeSelectionEndIndex = 3, options at 1-3 indices are selected. | 601 // m_activeSelectionEndIndex = 3, options at 1-3 indices are selected. |
| 602 // updateListBoxSelection needs to clear selection of the fifth OPTION. | 602 // updateListBoxSelection needs to clear selection of the fifth OPTION. |
| 603 m_cachedStateForActiveSelection.resize(0); | 603 m_cachedStateForActiveSelection.resize(0); |
| 604 for (const auto& option : optionList()) { | 604 for (const auto& option : optionList()) { |
| 605 m_cachedStateForActiveSelection.append(option->selected()); | 605 m_cachedStateForActiveSelection.push_back(option->selected()); |
| 606 } | 606 } |
| 607 } | 607 } |
| 608 | 608 |
| 609 void HTMLSelectElement::setActiveSelectionEnd(HTMLOptionElement* option) { | 609 void HTMLSelectElement::setActiveSelectionEnd(HTMLOptionElement* option) { |
| 610 m_activeSelectionEnd = option; | 610 m_activeSelectionEnd = option; |
| 611 } | 611 } |
| 612 | 612 |
| 613 void HTMLSelectElement::updateListBoxSelection(bool deselectOtherOptions, | 613 void HTMLSelectElement::updateListBoxSelection(bool deselectOtherOptions, |
| 614 bool scroll) { | 614 bool scroll) { |
| 615 DCHECK(layoutObject()); | 615 DCHECK(layoutObject()); |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 765 HTMLElement& current = toHTMLElement(*currentElement); | 765 HTMLElement& current = toHTMLElement(*currentElement); |
| 766 | 766 |
| 767 // We should ignore nested optgroup elements. The HTML parser flatten | 767 // We should ignore nested optgroup elements. The HTML parser flatten |
| 768 // them. However we need to ignore nested optgroups built by DOM APIs. | 768 // them. However we need to ignore nested optgroups built by DOM APIs. |
| 769 // This behavior matches to IE and Firefox. | 769 // This behavior matches to IE and Firefox. |
| 770 if (isHTMLOptGroupElement(current)) { | 770 if (isHTMLOptGroupElement(current)) { |
| 771 if (current.parentNode() != this) { | 771 if (current.parentNode() != this) { |
| 772 currentElement = ElementTraversal::nextSkippingChildren(current, this); | 772 currentElement = ElementTraversal::nextSkippingChildren(current, this); |
| 773 continue; | 773 continue; |
| 774 } | 774 } |
| 775 m_listItems.append(¤t); | 775 m_listItems.push_back(¤t); |
| 776 if (Element* nextElement = ElementTraversal::firstWithin(current)) { | 776 if (Element* nextElement = ElementTraversal::firstWithin(current)) { |
| 777 currentElement = nextElement; | 777 currentElement = nextElement; |
| 778 continue; | 778 continue; |
| 779 } | 779 } |
| 780 } | 780 } |
| 781 | 781 |
| 782 if (isHTMLOptionElement(current)) | 782 if (isHTMLOptionElement(current)) |
| 783 m_listItems.append(¤t); | 783 m_listItems.push_back(¤t); |
| 784 | 784 |
| 785 if (isHTMLHRElement(current)) | 785 if (isHTMLHRElement(current)) |
| 786 m_listItems.append(¤t); | 786 m_listItems.push_back(¤t); |
| 787 | 787 |
| 788 // In conforming HTML code, only <optgroup> and <option> will be found | 788 // In conforming HTML code, only <optgroup> and <option> will be found |
| 789 // within a <select>. We call NodeTraversal::nextSkippingChildren so | 789 // within a <select>. We call NodeTraversal::nextSkippingChildren so |
| 790 // that we only step into those tags that we choose to. For web-compat, | 790 // that we only step into those tags that we choose to. For web-compat, |
| 791 // we should cope with the case where odd tags like a <div> have been | 791 // we should cope with the case where odd tags like a <div> have been |
| 792 // added but we handle this because such tags have already been removed | 792 // added but we handle this because such tags have already been removed |
| 793 // from the <select>'s subtree at this point. | 793 // from the <select>'s subtree at this point. |
| 794 currentElement = | 794 currentElement = |
| 795 ElementTraversal::nextSkippingChildren(*currentElement, this); | 795 ElementTraversal::nextSkippingChildren(*currentElement, this); |
| 796 } | 796 } |
| (...skipping 1209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2006 Member<HTMLSelectElement> m_select; | 2006 Member<HTMLSelectElement> m_select; |
| 2007 Member<MutationObserver> m_observer; | 2007 Member<MutationObserver> m_observer; |
| 2008 }; | 2008 }; |
| 2009 | 2009 |
| 2010 HTMLSelectElement::PopupUpdater::PopupUpdater(HTMLSelectElement& select) | 2010 HTMLSelectElement::PopupUpdater::PopupUpdater(HTMLSelectElement& select) |
| 2011 : m_select(select) { | 2011 : m_select(select) { |
| 2012 m_observer = MutationObserver::create(this); | 2012 m_observer = MutationObserver::create(this); |
| 2013 Vector<String> filter; | 2013 Vector<String> filter; |
| 2014 filter.reserveCapacity(4); | 2014 filter.reserveCapacity(4); |
| 2015 // Observe only attributes which affect popup content. | 2015 // Observe only attributes which affect popup content. |
| 2016 filter.append(String("disabled")); | 2016 filter.push_back(String("disabled")); |
| 2017 filter.append(String("label")); | 2017 filter.push_back(String("label")); |
| 2018 filter.append(String("selected")); | 2018 filter.push_back(String("selected")); |
| 2019 filter.append(String("value")); | 2019 filter.push_back(String("value")); |
| 2020 MutationObserverInit init; | 2020 MutationObserverInit init; |
| 2021 init.setAttributeOldValue(true); | 2021 init.setAttributeOldValue(true); |
| 2022 init.setAttributes(true); | 2022 init.setAttributes(true); |
| 2023 init.setAttributeFilter(filter); | 2023 init.setAttributeFilter(filter); |
| 2024 init.setCharacterData(true); | 2024 init.setCharacterData(true); |
| 2025 init.setCharacterDataOldValue(true); | 2025 init.setCharacterDataOldValue(true); |
| 2026 init.setChildList(true); | 2026 init.setChildList(true); |
| 2027 init.setSubtree(true); | 2027 init.setSubtree(true); |
| 2028 m_observer->observe(&select, init, ASSERT_NO_EXCEPTION); | 2028 m_observer->observe(&select, init, ASSERT_NO_EXCEPTION); |
| 2029 } | 2029 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2046 m_popupUpdater = nullptr; | 2046 m_popupUpdater = nullptr; |
| 2047 } | 2047 } |
| 2048 | 2048 |
| 2049 void HTMLSelectElement::didMutateSubtree() { | 2049 void HTMLSelectElement::didMutateSubtree() { |
| 2050 DCHECK(popupIsVisible()); | 2050 DCHECK(popupIsVisible()); |
| 2051 DCHECK(m_popup); | 2051 DCHECK(m_popup); |
| 2052 m_popup->updateFromElement(PopupMenu::ByDOMChange); | 2052 m_popup->updateFromElement(PopupMenu::ByDOMChange); |
| 2053 } | 2053 } |
| 2054 | 2054 |
| 2055 } // namespace blink | 2055 } // namespace blink |
| OLD | NEW |