| 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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 #include "core/dom/NodeTraversal.h" | 45 #include "core/dom/NodeTraversal.h" |
| 46 #include "core/events/GestureEvent.h" | 46 #include "core/events/GestureEvent.h" |
| 47 #include "core/events/KeyboardEvent.h" | 47 #include "core/events/KeyboardEvent.h" |
| 48 #include "core/events/MouseEvent.h" | 48 #include "core/events/MouseEvent.h" |
| 49 #include "core/events/ScopedEventQueue.h" | 49 #include "core/events/ScopedEventQueue.h" |
| 50 #include "core/frame/FrameHost.h" | 50 #include "core/frame/FrameHost.h" |
| 51 #include "core/frame/FrameView.h" | 51 #include "core/frame/FrameView.h" |
| 52 #include "core/frame/LocalFrame.h" | 52 #include "core/frame/LocalFrame.h" |
| 53 #include "core/html/FormData.h" | 53 #include "core/html/FormData.h" |
| 54 #include "core/html/HTMLFormElement.h" | 54 #include "core/html/HTMLFormElement.h" |
| 55 #include "core/html/HTMLHRElement.h" |
| 55 #include "core/html/HTMLOptGroupElement.h" | 56 #include "core/html/HTMLOptGroupElement.h" |
| 56 #include "core/html/HTMLOptionElement.h" | 57 #include "core/html/HTMLOptionElement.h" |
| 57 #include "core/html/forms/FormController.h" | 58 #include "core/html/forms/FormController.h" |
| 58 #include "core/input/EventHandler.h" | 59 #include "core/input/EventHandler.h" |
| 59 #include "core/inspector/ConsoleMessage.h" | 60 #include "core/inspector/ConsoleMessage.h" |
| 60 #include "core/layout/HitTestRequest.h" | 61 #include "core/layout/HitTestRequest.h" |
| 61 #include "core/layout/HitTestResult.h" | 62 #include "core/layout/HitTestResult.h" |
| 62 #include "core/layout/LayoutListBox.h" | 63 #include "core/layout/LayoutListBox.h" |
| 63 #include "core/layout/LayoutMenuList.h" | 64 #include "core/layout/LayoutMenuList.h" |
| 64 #include "core/layout/LayoutTheme.h" | 65 #include "core/layout/LayoutTheme.h" |
| (...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 769 | 770 |
| 770 return m_listItems; | 771 return m_listItems; |
| 771 } | 772 } |
| 772 | 773 |
| 773 void HTMLSelectElement::invalidateSelectedItems() | 774 void HTMLSelectElement::invalidateSelectedItems() |
| 774 { | 775 { |
| 775 if (HTMLCollection* collection = cachedCollection<HTMLCollection>(SelectedOp
tions)) | 776 if (HTMLCollection* collection = cachedCollection<HTMLCollection>(SelectedOp
tions)) |
| 776 collection->invalidateCache(); | 777 collection->invalidateCache(); |
| 777 } | 778 } |
| 778 | 779 |
| 779 void HTMLSelectElement::setRecalcListItems() | 780 void HTMLSelectElement::setRecalcListItems(HTMLElement& subject) |
| 780 { | 781 { |
| 781 // FIXME: This function does a bunch of confusing things depending on if it | 782 // FIXME: This function does a bunch of confusing things depending on if it |
| 782 // is in the document or not. | 783 // is in the document or not. |
| 783 | 784 |
| 784 m_shouldRecalcListItems = true; | 785 bool shouldRecalc = true; |
| 786 if (!m_shouldRecalcListItems && !isHTMLOptGroupElement(subject)) { |
| 787 if (firstChild() == &subject) { |
| 788 // The subject was prepended. This doesn't handle elements in an |
| 789 // OPTGROUP. |
| 790 DCHECK(m_listItems.size() == 0 || m_listItems[0] != &subject); |
| 791 m_listItems.prepend(&subject); |
| 792 shouldRecalc = false; |
| 793 } else if (lastChild() == &subject) { |
| 794 // The subject was appended. This doesn't handle elements in an |
| 795 // OPTGROUP. |
| 796 DCHECK(m_listItems.size() == 0 || m_listItems.last() != &subject); |
| 797 m_listItems.append(&subject); |
| 798 shouldRecalc = false; |
| 799 } else if (!subject.isDescendantOf(this)) { |
| 800 // |subject| was removed from this. This logic works well with |
| 801 // SELECT children and OPTGROUP children. |
| 802 // TODO(tkent): m_listItems.size() is 0 in OOBE-related tests. It |
| 803 // should not happen. |
| 804 if (m_listItems.size() > 0) { |
| 805 size_t index; |
| 806 // Avoid Vector::find() in typical cases. |
| 807 if (m_listItems.first() == &subject) { |
| 808 index = 0; |
| 809 } else if (m_listItems.last() == &subject) { |
| 810 index = m_listItems.size() - 1; |
| 811 } else { |
| 812 index = m_listItems.find(&subject); |
| 813 DCHECK_NE(index, WTF::kNotFound); |
| 814 } |
| 815 m_listItems.remove(index); |
| 816 shouldRecalc = false; |
| 817 } |
| 818 } |
| 819 } |
| 820 m_shouldRecalcListItems = shouldRecalc; |
| 821 |
| 785 setOptionsChangedOnLayoutObject(); | 822 setOptionsChangedOnLayoutObject(); |
| 786 if (!inShadowIncludingDocument()) { | 823 if (!inShadowIncludingDocument()) { |
| 787 if (HTMLOptionsCollection* collection = cachedCollection<HTMLOptionsColl
ection>(SelectOptions)) | 824 if (HTMLOptionsCollection* collection = cachedCollection<HTMLOptionsColl
ection>(SelectOptions)) |
| 788 collection->invalidateCache(); | 825 collection->invalidateCache(); |
| 789 invalidateSelectedItems(); | 826 invalidateSelectedItems(); |
| 790 } | 827 } |
| 791 | 828 |
| 792 if (layoutObject()) { | 829 if (layoutObject()) { |
| 793 if (AXObjectCache* cache = layoutObject()->document().existingAXObjectCa
che()) | 830 if (AXObjectCache* cache = layoutObject()->document().existingAXObjectCa
che()) |
| 794 cache->childrenChanged(this); | 831 cache->childrenChanged(this); |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 968 selectOption(option, multiple() ? 0 : DeselectOtherOptions); | 1005 selectOption(option, multiple() ? 0 : DeselectOtherOptions); |
| 969 else if (!usesMenuList() || multiple()) | 1006 else if (!usesMenuList() || multiple()) |
| 970 selectOption(nullptr, multiple() ? 0 : DeselectOtherOptions); | 1007 selectOption(nullptr, multiple() ? 0 : DeselectOtherOptions); |
| 971 else | 1008 else |
| 972 selectOption(nextSelectableOption(nullptr), DeselectOtherOptions); | 1009 selectOption(nextSelectableOption(nullptr), DeselectOtherOptions); |
| 973 } | 1010 } |
| 974 | 1011 |
| 975 void HTMLSelectElement::optionInserted(HTMLOptionElement& option, bool optionIsS
elected) | 1012 void HTMLSelectElement::optionInserted(HTMLOptionElement& option, bool optionIsS
elected) |
| 976 { | 1013 { |
| 977 ASSERT(option.ownerSelectElement() == this); | 1014 ASSERT(option.ownerSelectElement() == this); |
| 978 setRecalcListItems(); | 1015 setRecalcListItems(option); |
| 979 if (optionIsSelected) { | 1016 if (optionIsSelected) { |
| 980 selectOption(&option, multiple() ? 0 : DeselectOtherOptions); | 1017 selectOption(&option, multiple() ? 0 : DeselectOtherOptions); |
| 981 } else { | 1018 } else { |
| 982 // No need to reset if we already have a selected option. | 1019 // No need to reset if we already have a selected option. |
| 983 if (!m_lastOnChangeOption) | 1020 if (!m_lastOnChangeOption) |
| 984 resetToDefaultSelection(); | 1021 resetToDefaultSelection(); |
| 985 } | 1022 } |
| 986 setNeedsValidityCheck(); | 1023 setNeedsValidityCheck(); |
| 987 m_lastOnChangeSelection.clear(); | 1024 m_lastOnChangeSelection.clear(); |
| 988 } | 1025 } |
| 989 | 1026 |
| 990 void HTMLSelectElement::optionRemoved(const HTMLOptionElement& option) | 1027 void HTMLSelectElement::optionRemoved(HTMLOptionElement& option) |
| 991 { | 1028 { |
| 992 setRecalcListItems(); | 1029 setRecalcListItems(option); |
| 993 if (option.selected()) | 1030 if (option.selected()) |
| 994 resetToDefaultSelection(ResetReasonSelectedOptionRemoved); | 1031 resetToDefaultSelection(ResetReasonSelectedOptionRemoved); |
| 995 else if (!m_lastOnChangeOption) | 1032 else if (!m_lastOnChangeOption) |
| 996 resetToDefaultSelection(); | 1033 resetToDefaultSelection(); |
| 997 if (m_lastOnChangeOption == &option) | 1034 if (m_lastOnChangeOption == &option) |
| 998 m_lastOnChangeOption.clear(); | 1035 m_lastOnChangeOption.clear(); |
| 999 if (m_optionToScrollTo == &option) | 1036 if (m_optionToScrollTo == &option) |
| 1000 m_optionToScrollTo.clear(); | 1037 m_optionToScrollTo.clear(); |
| 1001 if (m_activeSelectionAnchor == &option) | 1038 if (m_activeSelectionAnchor == &option) |
| 1002 m_activeSelectionAnchor.clear(); | 1039 m_activeSelectionAnchor.clear(); |
| 1003 if (m_activeSelectionEnd == &option) | 1040 if (m_activeSelectionEnd == &option) |
| 1004 m_activeSelectionEnd.clear(); | 1041 m_activeSelectionEnd.clear(); |
| 1005 if (option.selected()) | 1042 if (option.selected()) |
| 1006 setAutofilled(false); | 1043 setAutofilled(false); |
| 1007 setNeedsValidityCheck(); | 1044 setNeedsValidityCheck(); |
| 1008 m_lastOnChangeSelection.clear(); | 1045 m_lastOnChangeSelection.clear(); |
| 1009 } | 1046 } |
| 1010 | 1047 |
| 1011 void HTMLSelectElement::optGroupInsertedOrRemoved(const HTMLOptGroupElement&) | 1048 void HTMLSelectElement::optGroupInsertedOrRemoved(HTMLOptGroupElement& optgroup) |
| 1012 { | 1049 { |
| 1013 setRecalcListItems(); | 1050 setRecalcListItems(optgroup); |
| 1014 setNeedsValidityCheck(); | 1051 setNeedsValidityCheck(); |
| 1015 m_lastOnChangeSelection.clear(); | 1052 m_lastOnChangeSelection.clear(); |
| 1016 } | 1053 } |
| 1017 | 1054 |
| 1018 void HTMLSelectElement::hrInsertedOrRemoved(const HTMLHRElement&) | 1055 void HTMLSelectElement::hrInsertedOrRemoved(HTMLHRElement& hr) |
| 1019 { | 1056 { |
| 1020 setRecalcListItems(); | 1057 setRecalcListItems(hr); |
| 1021 m_lastOnChangeSelection.clear(); | 1058 m_lastOnChangeSelection.clear(); |
| 1022 } | 1059 } |
| 1023 | 1060 |
| 1024 void HTMLSelectElement::selectOption(int optionIndex, SelectOptionFlags flags) | 1061 void HTMLSelectElement::selectOption(int optionIndex, SelectOptionFlags flags) |
| 1025 { | 1062 { |
| 1026 selectOption(optionIndex < 0 ? nullptr : item(optionIndex), flags); | 1063 selectOption(optionIndex < 0 ? nullptr : item(optionIndex), flags); |
| 1027 } | 1064 } |
| 1028 | 1065 |
| 1029 void HTMLSelectElement::selectOption(HTMLOptionElement* option, SelectOptionFlag
s flags) | 1066 void HTMLSelectElement::selectOption(HTMLOptionElement* option, SelectOptionFlag
s flags) |
| 1030 { | 1067 { |
| (...skipping 1061 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2092 } | 2129 } |
| 2093 | 2130 |
| 2094 void HTMLSelectElement::didMutateSubtree() | 2131 void HTMLSelectElement::didMutateSubtree() |
| 2095 { | 2132 { |
| 2096 DCHECK(popupIsVisible()); | 2133 DCHECK(popupIsVisible()); |
| 2097 DCHECK(m_popup); | 2134 DCHECK(m_popup); |
| 2098 m_popup->updateFromElement(PopupMenu::ByDOMChange); | 2135 m_popup->updateFromElement(PopupMenu::ByDOMChange); |
| 2099 } | 2136 } |
| 2100 | 2137 |
| 2101 } // namespace blink | 2138 } // namespace blink |
| OLD | NEW |