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 |