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

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

Issue 2152643002: SELECT element: Introduce HTMLSelectElement::optionAtListIndex(). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
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 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 return String(); 182 return String();
183 return validationMessage(); 183 return validationMessage();
184 } 184 }
185 185
186 void HTMLSelectElement::selectMultipleOptionsByPopup(const Vector<int>& listIndi ces) 186 void HTMLSelectElement::selectMultipleOptionsByPopup(const Vector<int>& listIndi ces)
187 { 187 {
188 DCHECK(usesMenuList()); 188 DCHECK(usesMenuList());
189 DCHECK(!multiple()); 189 DCHECK(!multiple());
190 for (size_t i = 0; i < listIndices.size(); ++i) { 190 for (size_t i = 0; i < listIndices.size(); ++i) {
191 bool addSelectionIfNotFirst = i > 0; 191 bool addSelectionIfNotFirst = i > 0;
192 HTMLElement* element = listItems()[listIndices[i]]; 192 if (HTMLOptionElement* option = optionAtListIndex(listIndices[i]))
193 if (isHTMLOptionElement(element)) 193 updateSelectedState(option, addSelectionIfNotFirst, false);
194 updateSelectedState(toHTMLOptionElement(element), addSelectionIfNotF irst, false);
195 } 194 }
196 setNeedsValidityCheck(); 195 setNeedsValidityCheck();
197 // TODO(tkent): Using listBoxOnChange() is very confusing. 196 // TODO(tkent): Using listBoxOnChange() is very confusing.
198 listBoxOnChange(); 197 listBoxOnChange();
199 } 198 }
200 199
201 bool HTMLSelectElement::usesMenuList() const 200 bool HTMLSelectElement::usesMenuList() const
202 { 201 {
203 if (LayoutTheme::theme().delegatesMenuListRendering()) 202 if (LayoutTheme::theme().delegatesMenuListRendering())
204 return true; 203 return true;
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 } 473 }
475 } 474 }
476 setNeedsValidityCheck(); 475 setNeedsValidityCheck();
477 } 476 }
478 477
479 bool HTMLSelectElement::isRequiredFormControl() const 478 bool HTMLSelectElement::isRequiredFormControl() const
480 { 479 {
481 return isRequired(); 480 return isRequired();
482 } 481 }
483 482
483 HTMLOptionElement* HTMLSelectElement::optionAtListIndex(int listIndex) const
484 {
485 if (listIndex < 0)
486 return nullptr;
487 const ListItems& items = listItems();
488 if (static_cast<size_t>(listIndex) >= items.size() || !isHTMLOptionElement(i tems[listIndex]))
489 return nullptr;
490 return toHTMLOptionElement(items[listIndex]);
491 }
492
484 // Returns the 1st valid OPTION |skip| items from |listIndex| in direction 493 // Returns the 1st valid OPTION |skip| items from |listIndex| in direction
485 // |direction| if there is one. 494 // |direction| if there is one.
486 // Otherwise, it returns the valid OPTION closest to that boundary which is past 495 // Otherwise, it returns the valid OPTION closest to that boundary which is past
487 // |listIndex| if there is one. 496 // |listIndex| if there is one.
488 // Otherwise, it returns nullptr. 497 // Otherwise, it returns nullptr.
489 // Valid means that it is enabled and visible. 498 // Valid means that it is enabled and visible.
490 HTMLOptionElement* HTMLSelectElement::nextValidOption(int listIndex, SkipDirecti on direction, int skip) const 499 HTMLOptionElement* HTMLSelectElement::nextValidOption(int listIndex, SkipDirecti on direction, int skip) const
491 { 500 {
492 ASSERT(direction == SkipBackwards || direction == SkipForwards); 501 ASSERT(direction == SkipBackwards || direction == SkipForwards);
493 const ListItems& listItems = this->listItems(); 502 const ListItems& listItems = this->listItems();
(...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after
1051 return listIndex; 1060 return listIndex;
1052 } 1061 }
1053 } 1062 }
1054 1063
1055 return -1; 1064 return -1;
1056 } 1065 }
1057 1066
1058 int HTMLSelectElement::listToOptionIndex(int listIndex) const 1067 int HTMLSelectElement::listToOptionIndex(int listIndex) const
1059 { 1068 {
1060 const ListItems& items = listItems(); 1069 const ListItems& items = listItems();
1061 if (listIndex < 0 || listIndex >= static_cast<int>(items.size()) || !isHTMLO ptionElement(*items[listIndex])) 1070 if (!optionAtListIndex(listIndex))
1062 return -1; 1071 return -1;
1063 1072
1064 // Actual index of option not counting OPTGROUP entries that may be in list. 1073 // Actual index of option not counting OPTGROUP entries that may be in list.
1065 int optionIndex = 0; 1074 int optionIndex = 0;
1066 for (int i = 0; i < listIndex; ++i) { 1075 for (int i = 0; i < listIndex; ++i) {
1067 if (isHTMLOptionElement(*items[i])) 1076 if (isHTMLOptionElement(*items[i]))
1068 ++optionIndex; 1077 ++optionIndex;
1069 } 1078 }
1070 1079
1071 return optionIndex; 1080 return optionIndex;
(...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after
1667 return; 1676 return;
1668 } 1677 }
1669 } 1678 }
1670 HTMLFormControlElementWithState::defaultEventHandler(event); 1679 HTMLFormControlElementWithState::defaultEventHandler(event);
1671 } 1680 }
1672 1681
1673 HTMLOptionElement* HTMLSelectElement::lastSelectedOption() const 1682 HTMLOptionElement* HTMLSelectElement::lastSelectedOption() const
1674 { 1683 {
1675 const ListItems& items = listItems(); 1684 const ListItems& items = listItems();
1676 for (size_t i = items.size(); i;) { 1685 for (size_t i = items.size(); i;) {
1677 HTMLElement* element = items[--i]; 1686 if (HTMLOptionElement* option = optionAtListIndex(--i)) {
1678 if (isHTMLOptionElement(*element) && toHTMLOptionElement(element)->selec ted()) 1687 if (option->selected())
1679 return toHTMLOptionElement(element); 1688 return option;
1689 }
1680 } 1690 }
1681 return nullptr; 1691 return nullptr;
1682 } 1692 }
1683 1693
1684 int HTMLSelectElement::indexOfSelectedOption() const 1694 int HTMLSelectElement::indexOfSelectedOption() const
1685 { 1695 {
1686 return optionToListIndex(selectedIndex()); 1696 return optionToListIndex(selectedIndex());
1687 } 1697 }
1688 1698
1689 int HTMLSelectElement::optionCount() const 1699 int HTMLSelectElement::optionCount() const
1690 { 1700 {
1691 return listItems().size(); 1701 return listItems().size();
1692 } 1702 }
1693 1703
1694 String HTMLSelectElement::optionAtIndex(int index) const 1704 String HTMLSelectElement::optionAtIndex(int index) const
1695 { 1705 {
1696 const ListItems& items = listItems(); 1706 if (HTMLOptionElement* option = optionAtListIndex(index)) {
1697 HTMLElement* element = items[index]; 1707 if (!option->isDisabledFormControl())
1698 if (!isHTMLOptionElement(*element) || toHTMLOptionElement(element)->isDisabl edFormControl()) 1708 return option->displayLabel();
1699 return String(); 1709 }
1700 return toHTMLOptionElement(element)->displayLabel(); 1710 return String();
1701 } 1711 }
1702 1712
1703 void HTMLSelectElement::typeAheadFind(KeyboardEvent* event) 1713 void HTMLSelectElement::typeAheadFind(KeyboardEvent* event)
1704 { 1714 {
1705 int index = m_typeAhead.handleEvent(event, TypeAhead::MatchPrefix | TypeAhea d::CycleFirstChar); 1715 int index = m_typeAhead.handleEvent(event, TypeAhead::MatchPrefix | TypeAhea d::CycleFirstChar);
1706 if (index < 0) 1716 if (index < 0)
1707 return; 1717 return;
1708 HTMLOptionElement* option = nullptr; 1718 selectOption(optionAtListIndex(index), DeselectOtherOptions | MakeOptionDirt y | DispatchInputAndChangeEvent);
1709 if (static_cast<size_t>(index) < listItems().size() && isHTMLOptionElement(l istItems()[index]))
1710 option = toHTMLOptionElement(listItems()[index]);
1711 selectOption(option, DeselectOtherOptions | MakeOptionDirty | DispatchInputA ndChangeEvent);
1712 if (!usesMenuList()) 1719 if (!usesMenuList())
1713 listBoxOnChange(); 1720 listBoxOnChange();
1714 } 1721 }
1715 1722
1716 void HTMLSelectElement::accessKeySetSelectedIndex(int index) 1723 void HTMLSelectElement::accessKeySetSelectedIndex(int index)
1717 { 1724 {
1718 // First bring into focus the list box. 1725 // First bring into focus the list box.
1719 if (!focused()) 1726 if (!focused())
1720 accessKeyAction(false); 1727 accessKeyAction(false);
1721 1728
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1881 1888
1882 void HTMLSelectElement::setIndexToSelectOnCancel(int listIndex) 1889 void HTMLSelectElement::setIndexToSelectOnCancel(int listIndex)
1883 { 1890 {
1884 m_indexToSelectOnCancel = listIndex; 1891 m_indexToSelectOnCancel = listIndex;
1885 if (layoutObject()) 1892 if (layoutObject())
1886 layoutObject()->updateFromElement(); 1893 layoutObject()->updateFromElement();
1887 } 1894 }
1888 1895
1889 HTMLOptionElement* HTMLSelectElement::optionToBeShown() const 1896 HTMLOptionElement* HTMLSelectElement::optionToBeShown() const
1890 { 1897 {
1891 if (m_indexToSelectOnCancel >= 0 && static_cast<size_t>(m_indexToSelectOnCan cel) < listItems().size() && isHTMLOptionElement(listItems()[m_indexToSelectOnCa ncel])) 1898 if (HTMLOptionElement* option = optionAtListIndex(m_indexToSelectOnCancel))
1892 return toHTMLOptionElement(listItems()[m_indexToSelectOnCancel]); 1899 return option;
1893 if (m_suggestedOption) 1900 if (m_suggestedOption)
1894 return m_suggestedOption; 1901 return m_suggestedOption;
1895 // TODO(tkent): We should not call optionToBeShown() in multiple() case. 1902 // TODO(tkent): We should not call optionToBeShown() in multiple() case.
1896 if (multiple()) 1903 if (multiple())
1897 return selectedOption(); 1904 return selectedOption();
1898 DCHECK_EQ(selectedOption(), m_lastOnChangeOption); 1905 DCHECK_EQ(selectedOption(), m_lastOnChangeOption);
1899 return m_lastOnChangeOption; 1906 return m_lastOnChangeOption;
1900 } 1907 }
1901 1908
1902 void HTMLSelectElement::selectOptionByPopup(int listIndex) 1909 void HTMLSelectElement::selectOptionByPopup(int listIndex)
1903 { 1910 {
1904 DCHECK(usesMenuList()); 1911 DCHECK(usesMenuList());
1905 // Check to ensure a page navigation has not occurred while the popup was 1912 // Check to ensure a page navigation has not occurred while the popup was
1906 // up. 1913 // up.
1907 Document& doc = document(); 1914 Document& doc = document();
1908 if (&doc != doc.frame()->document()) 1915 if (&doc != doc.frame()->document())
1909 return; 1916 return;
1910 1917
1911 setIndexToSelectOnCancel(-1); 1918 setIndexToSelectOnCancel(-1);
1912 1919
1913 HTMLOptionElement* option = nullptr; 1920 HTMLOptionElement* option = optionAtListIndex(listIndex);
1914 if (listIndex >= 0 && isHTMLOptionElement(listItems()[listIndex]))
1915 option = toHTMLOptionElement(listItems()[listIndex]);
1916 // Bail out if this index is already the selected one, to avoid running 1921 // Bail out if this index is already the selected one, to avoid running
1917 // unnecessary JavaScript that can mess up autofill when there is no actual 1922 // unnecessary JavaScript that can mess up autofill when there is no actual
1918 // change (see https://bugs.webkit.org/show_bug.cgi?id=35256 and 1923 // change (see https://bugs.webkit.org/show_bug.cgi?id=35256 and
1919 // <rdar://7467917>). The selectOption function does not behave this way, 1924 // <rdar://7467917>). The selectOption function does not behave this way,
1920 // possibly because other callers need a change event even in cases where 1925 // possibly because other callers need a change event even in cases where
1921 // the selected option is not change. 1926 // the selected option is not change.
1922 if (option == selectedOption()) 1927 if (option == selectedOption())
1923 return; 1928 return;
1924 selectOption(option, DeselectOtherOptions | MakeOptionDirty | DispatchInputA ndChangeEvent); 1929 selectOption(option, DeselectOtherOptions | MakeOptionDirty | DispatchInputA ndChangeEvent);
1925 } 1930 }
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
2058 } 2063 }
2059 2064
2060 void HTMLSelectElement::didMutateSubtree() 2065 void HTMLSelectElement::didMutateSubtree()
2061 { 2066 {
2062 DCHECK(popupIsVisible()); 2067 DCHECK(popupIsVisible());
2063 DCHECK(m_popup); 2068 DCHECK(m_popup);
2064 m_popup->updateFromElement(PopupMenu::ByDOMChange); 2069 m_popup->updateFromElement(PopupMenu::ByDOMChange);
2065 } 2070 }
2066 2071
2067 } // namespace blink 2072 } // 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