Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(193)

Side by Side Diff: third_party/WebKit/Source/core/html/HTMLSelectElement.cpp

Issue 2108503008: Merge "Improve performance of HTMLSelectElement::resetToDefaultSelection()." to M52. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2743
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/core/html/HTMLSelectElement.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 869 matching lines...) Expand 10 before | Expand all | Expand 10 after
880 firstEnabledOption = option; 880 firstEnabledOption = option;
881 firstEnabledOptionIndex = optionIndex; 881 firstEnabledOptionIndex = optionIndex;
882 if (reason == ResetReasonSelectedOptionRemoved) { 882 if (reason == ResetReasonSelectedOptionRemoved) {
883 // There must be no selected OPTIONs. 883 // There must be no selected OPTIONs.
884 break; 884 break;
885 } 885 }
886 } 886 }
887 ++optionIndex; 887 ++optionIndex;
888 } 888 }
889 if (!lastSelectedOption && m_size <= 1 && firstEnabledOption && !firstEnable dOption->selected()) { 889 if (!lastSelectedOption && m_size <= 1 && firstEnabledOption && !firstEnable dOption->selected()) {
890 selectOption(firstEnabledOption, firstEnabledOptionIndex, 0); 890 selectOption(firstEnabledOption, firstEnabledOptionIndex, reason == Rese tReasonSelectedOptionRemoved ? 0 : DeselectOtherOptions);
891 lastSelectedOption = firstEnabledOption; 891 lastSelectedOption = firstEnabledOption;
892 didChange = true; 892 didChange = true;
893 } 893 }
894 if (didChange) 894 if (didChange)
895 setNeedsValidityCheck(); 895 setNeedsValidityCheck();
896 m_lastOnChangeOption = lastSelectedOption; 896 m_lastOnChangeOption = lastSelectedOption;
897 } 897 }
898 898
899 HTMLOptionElement* HTMLSelectElement::selectedOption() const 899 HTMLOptionElement* HTMLSelectElement::selectedOption() const
900 { 900 {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
970 if (!layoutObject() || !layoutObject()->isListBox()) 970 if (!layoutObject() || !layoutObject()->isListBox())
971 return; 971 return;
972 LayoutRect bounds = option->boundingBox(); 972 LayoutRect bounds = option->boundingBox();
973 toLayoutListBox(layoutObject())->scrollToRect(bounds); 973 toLayoutListBox(layoutObject())->scrollToRect(bounds);
974 } 974 }
975 975
976 void HTMLSelectElement::optionSelectionStateChanged(HTMLOptionElement* option, b ool optionIsSelected) 976 void HTMLSelectElement::optionSelectionStateChanged(HTMLOptionElement* option, b ool optionIsSelected)
977 { 977 {
978 ASSERT(option->ownerSelectElement() == this); 978 ASSERT(option->ownerSelectElement() == this);
979 if (optionIsSelected) 979 if (optionIsSelected)
980 selectOption(option); 980 selectOption(option, multiple() ? 0 : DeselectOtherOptions);
981 else if (!usesMenuList() || multiple()) 981 else if (!usesMenuList() || multiple())
982 selectOption(nullptr); 982 selectOption(nullptr, multiple() ? 0 : DeselectOtherOptions);
983 else 983 else
984 selectOption(nextSelectableOption(nullptr)); 984 selectOption(nextSelectableOption(nullptr), DeselectOtherOptions);
985 } 985 }
986 986
987 void HTMLSelectElement::optionInserted(HTMLOptionElement& option, bool optionIsS elected) 987 void HTMLSelectElement::optionInserted(HTMLOptionElement& option, bool optionIsS elected)
988 { 988 {
989 ASSERT(option.ownerSelectElement() == this); 989 ASSERT(option.ownerSelectElement() == this);
990 setRecalcListItems(); 990 setRecalcListItems();
991 if (optionIsSelected) { 991 if (optionIsSelected) {
992 selectOption(&option); 992 selectOption(&option, multiple() ? 0 : DeselectOtherOptions);
993 } else { 993 } else {
994 // No need to reset if we already have a selected option. 994 // No need to reset if we already have a selected option.
995 if (!m_lastOnChangeOption) 995 if (!m_lastOnChangeOption)
996 resetToDefaultSelection(); 996 resetToDefaultSelection();
997 } 997 }
998 } 998 }
999 999
1000 void HTMLSelectElement::optionRemoved(const HTMLOptionElement& option) 1000 void HTMLSelectElement::optionRemoved(const HTMLOptionElement& option)
1001 { 1001 {
1002 setRecalcListItems(); 1002 setRecalcListItems();
(...skipping 21 matching lines...) Expand all
1024 void HTMLSelectElement::selectOption(HTMLOptionElement* option, SelectOptionFlag s flags) 1024 void HTMLSelectElement::selectOption(HTMLOptionElement* option, SelectOptionFlag s flags)
1025 { 1025 {
1026 selectOption(option, option ? option->index() : -1, flags); 1026 selectOption(option, option ? option->index() : -1, flags);
1027 } 1027 }
1028 1028
1029 // TODO(tkent): This function is not efficient. It contains multiple O(N) 1029 // TODO(tkent): This function is not efficient. It contains multiple O(N)
1030 // operations. crbug.com/577989. 1030 // operations. crbug.com/577989.
1031 void HTMLSelectElement::selectOption(HTMLOptionElement* element, int optionIndex , SelectOptionFlags flags) 1031 void HTMLSelectElement::selectOption(HTMLOptionElement* element, int optionIndex , SelectOptionFlags flags)
1032 { 1032 {
1033 TRACE_EVENT0("blink", "HTMLSelectElement::selectOption"); 1033 TRACE_EVENT0("blink", "HTMLSelectElement::selectOption");
1034 bool shouldDeselect = !m_multiple || (flags & DeselectOtherOptions);
1035
1036 ASSERT((!element && optionIndex < 0) || (element && optionIndex >= 0)); 1034 ASSERT((!element && optionIndex < 0) || (element && optionIndex >= 0));
1037 1035
1038 // selectedIndex() is O(N). 1036 // selectedIndex() is O(N).
1039 if (isAutofilled() && selectedIndex() != optionIndex) 1037 if (isAutofilled() && selectedIndex() != optionIndex)
1040 setAutofilled(false); 1038 setAutofilled(false);
1041 1039
1042 if (element) { 1040 if (element) {
1043 element->setSelectedState(true); 1041 element->setSelectedState(true);
1044 if (flags & MakeOptionDirty) 1042 if (flags & MakeOptionDirty)
1045 element->setDirty(true); 1043 element->setDirty(true);
1046 } 1044 }
1047 1045
1048 // deselectItemsWithoutValidation() is O(N). 1046 // deselectItemsWithoutValidation() is O(N).
1049 if (shouldDeselect) 1047 if (flags & DeselectOtherOptions)
1050 deselectItemsWithoutValidation(element); 1048 deselectItemsWithoutValidation(element);
1051 1049
1052 // We should update active selection after finishing OPTION state change 1050 // We should update active selection after finishing OPTION state change
1053 // because setActiveSelectionAnchorIndex() stores OPTION's selection state. 1051 // because setActiveSelectionAnchorIndex() stores OPTION's selection state.
1054 if (element) { 1052 if (element) {
1055 // setActiveSelectionAnchor is O(N). 1053 // setActiveSelectionAnchor is O(N).
1056 if (!m_activeSelectionAnchor || shouldDeselect) 1054 if (!m_activeSelectionAnchor || !multiple() || flags & DeselectOtherOpti ons)
1057 setActiveSelectionAnchor(element); 1055 setActiveSelectionAnchor(element);
1058 if (!m_activeSelectionEnd || shouldDeselect) 1056 if (!m_activeSelectionEnd || !multiple() || flags & DeselectOtherOptions )
1059 setActiveSelectionEnd(element); 1057 setActiveSelectionEnd(element);
1060 } 1058 }
1061 1059
1062 // For the menu list case, this is what makes the selected element appear. 1060 // For the menu list case, this is what makes the selected element appear.
1063 if (LayoutObject* layoutObject = this->layoutObject()) 1061 if (LayoutObject* layoutObject = this->layoutObject())
1064 layoutObject->updateFromElement(); 1062 layoutObject->updateFromElement();
1065 // PopupMenu::updateFromElement() posts an O(N) task. 1063 // PopupMenu::updateFromElement() posts an O(N) task.
1066 if (popupIsVisible()) 1064 if (popupIsVisible())
1067 m_popup->updateFromElement(PopupMenu::BySelectionChange); 1065 m_popup->updateFromElement(PopupMenu::BySelectionChange);
1068 1066
(...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after
1769 const ListItems& items = listItems(); 1767 const ListItems& items = listItems();
1770 int listIndex = optionToListIndex(index); 1768 int listIndex = optionToListIndex(index);
1771 if (listIndex < 0) 1769 if (listIndex < 0)
1772 return; 1770 return;
1773 HTMLElement& element = *items[listIndex]; 1771 HTMLElement& element = *items[listIndex];
1774 if (!isHTMLOptionElement(element)) 1772 if (!isHTMLOptionElement(element))
1775 return; 1773 return;
1776 EventQueueScope scope; 1774 EventQueueScope scope;
1777 // If this index is already selected, unselect. otherwise update the 1775 // If this index is already selected, unselect. otherwise update the
1778 // selected index. 1776 // selected index.
1777 SelectOptionFlags flags = DispatchInputAndChangeEvent | (multiple() ? 0 : De selectOtherOptions);
1779 if (toHTMLOptionElement(element).selected()) { 1778 if (toHTMLOptionElement(element).selected()) {
1780 if (usesMenuList()) 1779 if (usesMenuList())
1781 selectOption(-1, DispatchInputAndChangeEvent); 1780 selectOption(-1, flags);
1782 else 1781 else
1783 toHTMLOptionElement(element).setSelectedState(false); 1782 toHTMLOptionElement(element).setSelectedState(false);
1784 } else { 1783 } else {
1785 selectOption(index, DispatchInputAndChangeEvent); 1784 selectOption(index, flags);
1786 } 1785 }
1787 toHTMLOptionElement(element).setDirty(true); 1786 toHTMLOptionElement(element).setDirty(true);
1788 if (usesMenuList()) 1787 if (usesMenuList())
1789 return; 1788 return;
1790 listBoxOnChange(); 1789 listBoxOnChange();
1791 scrollToSelection(); 1790 scrollToSelection();
1792 } 1791 }
1793 1792
1794 unsigned HTMLSelectElement::length() const 1793 unsigned HTMLSelectElement::length() const
1795 { 1794 {
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
2090 } 2089 }
2091 2090
2092 void HTMLSelectElement::didMutateSubtree() 2091 void HTMLSelectElement::didMutateSubtree()
2093 { 2092 {
2094 DCHECK(popupIsVisible()); 2093 DCHECK(popupIsVisible());
2095 DCHECK(m_popup); 2094 DCHECK(m_popup);
2096 m_popup->updateFromElement(PopupMenu::ByDOMChange); 2095 m_popup->updateFromElement(PopupMenu::ByDOMChange);
2097 } 2096 }
2098 2097
2099 } // namespace blink 2098 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/html/HTMLSelectElement.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698