| 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 827 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 838 // In conforming HTML code, only <optgroup> and <option> will be found | 838 // In conforming HTML code, only <optgroup> and <option> will be found |
| 839 // within a <select>. We call NodeTraversal::nextSkippingChildren so | 839 // within a <select>. We call NodeTraversal::nextSkippingChildren so |
| 840 // that we only step into those tags that we choose to. For web-compat, | 840 // that we only step into those tags that we choose to. For web-compat, |
| 841 // we should cope with the case where odd tags like a <div> have been | 841 // we should cope with the case where odd tags like a <div> have been |
| 842 // added but we handle this because such tags have already been removed | 842 // added but we handle this because such tags have already been removed |
| 843 // from the <select>'s subtree at this point. | 843 // from the <select>'s subtree at this point. |
| 844 currentElement = ElementTraversal::nextSkippingChildren(*currentElement,
this); | 844 currentElement = ElementTraversal::nextSkippingChildren(*currentElement,
this); |
| 845 } | 845 } |
| 846 } | 846 } |
| 847 | 847 |
| 848 void HTMLSelectElement::resetToDefaultSelection() | 848 void HTMLSelectElement::resetToDefaultSelection(ResetReason reason) |
| 849 { | 849 { |
| 850 // https://html.spec.whatwg.org/multipage/forms.html#ask-for-a-reset | 850 // https://html.spec.whatwg.org/multipage/forms.html#ask-for-a-reset |
| 851 if (multiple()) | 851 if (multiple()) |
| 852 return; | 852 return; |
| 853 HTMLOptionElement* firstEnabledOption = nullptr; | 853 HTMLOptionElement* firstEnabledOption = nullptr; |
| 854 int firstEnabledOptionIndex = -1; | 854 int firstEnabledOptionIndex = -1; |
| 855 HTMLOptionElement* lastSelectedOption = nullptr; | 855 HTMLOptionElement* lastSelectedOption = nullptr; |
| 856 bool didChange = false; | 856 bool didChange = false; |
| 857 int optionIndex = 0; | 857 int optionIndex = 0; |
| 858 // We can't use HTMLSelectElement::options here because this function is | 858 // We can't use HTMLSelectElement::options here because this function is |
| 859 // called in Node::insertedInto and Node::removedFrom before invalidating | 859 // called in Node::insertedInto and Node::removedFrom before invalidating |
| 860 // node collections. | 860 // node collections. |
| 861 for (auto& item : listItems()) { | 861 for (auto& item : listItems()) { |
| 862 if (!isHTMLOptionElement(item)) | 862 if (!isHTMLOptionElement(item)) |
| 863 continue; | 863 continue; |
| 864 HTMLOptionElement* option = toHTMLOptionElement(item); | 864 HTMLOptionElement* option = toHTMLOptionElement(item); |
| 865 if (option->selected()) { | 865 if (option->selected()) { |
| 866 if (lastSelectedOption) { | 866 if (lastSelectedOption) { |
| 867 lastSelectedOption->setSelectedState(false); | 867 lastSelectedOption->setSelectedState(false); |
| 868 didChange = true; | 868 didChange = true; |
| 869 } | 869 } |
| 870 lastSelectedOption = option; | 870 lastSelectedOption = option; |
| 871 } | 871 } |
| 872 if (!firstEnabledOption && !option->isDisabledFormControl()) { | 872 if (!firstEnabledOption && !option->isDisabledFormControl()) { |
| 873 firstEnabledOption = option; | 873 firstEnabledOption = option; |
| 874 firstEnabledOptionIndex = optionIndex; | 874 firstEnabledOptionIndex = optionIndex; |
| 875 if (reason == ResetReasonSelectedOptionRemoved) { |
| 876 // There must be no selected OPTIONs. |
| 877 break; |
| 878 } |
| 875 } | 879 } |
| 876 ++optionIndex; | 880 ++optionIndex; |
| 877 } | 881 } |
| 878 if (!lastSelectedOption && m_size <= 1 && firstEnabledOption && !firstEnable
dOption->selected()) { | 882 if (!lastSelectedOption && m_size <= 1 && firstEnabledOption && !firstEnable
dOption->selected()) { |
| 879 selectOption(firstEnabledOption, firstEnabledOptionIndex, 0); | 883 selectOption(firstEnabledOption, firstEnabledOptionIndex, 0); |
| 880 lastSelectedOption = firstEnabledOption; | 884 lastSelectedOption = firstEnabledOption; |
| 881 didChange = true; | 885 didChange = true; |
| 882 } | 886 } |
| 883 if (didChange) | 887 if (didChange) |
| 884 setNeedsValidityCheck(); | 888 setNeedsValidityCheck(); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 982 } else { | 986 } else { |
| 983 // No need to reset if we already have a selected option. | 987 // No need to reset if we already have a selected option. |
| 984 if (!m_lastOnChangeOption) | 988 if (!m_lastOnChangeOption) |
| 985 resetToDefaultSelection(); | 989 resetToDefaultSelection(); |
| 986 } | 990 } |
| 987 } | 991 } |
| 988 | 992 |
| 989 void HTMLSelectElement::optionRemoved(const HTMLOptionElement& option) | 993 void HTMLSelectElement::optionRemoved(const HTMLOptionElement& option) |
| 990 { | 994 { |
| 991 setRecalcListItems(); | 995 setRecalcListItems(); |
| 992 if (option.selected() || !m_lastOnChangeOption) | 996 if (option.selected()) |
| 997 resetToDefaultSelection(ResetReasonSelectedOptionRemoved); |
| 998 else if (!m_lastOnChangeOption) |
| 993 resetToDefaultSelection(); | 999 resetToDefaultSelection(); |
| 994 if (m_lastOnChangeOption == &option) | 1000 if (m_lastOnChangeOption == &option) |
| 995 m_lastOnChangeOption.clear(); | 1001 m_lastOnChangeOption.clear(); |
| 996 if (m_optionToScrollTo == &option) | 1002 if (m_optionToScrollTo == &option) |
| 997 m_optionToScrollTo.clear(); | 1003 m_optionToScrollTo.clear(); |
| 998 if (m_activeSelectionAnchor == &option) | 1004 if (m_activeSelectionAnchor == &option) |
| 999 m_activeSelectionAnchor.clear(); | 1005 m_activeSelectionAnchor.clear(); |
| 1000 if (m_activeSelectionEnd == &option) | 1006 if (m_activeSelectionEnd == &option) |
| 1001 m_activeSelectionEnd.clear(); | 1007 m_activeSelectionEnd.clear(); |
| 1002 if (option.selected()) | 1008 if (option.selected()) |
| (...skipping 1074 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2077 } | 2083 } |
| 2078 | 2084 |
| 2079 void HTMLSelectElement::didMutateSubtree() | 2085 void HTMLSelectElement::didMutateSubtree() |
| 2080 { | 2086 { |
| 2081 DCHECK(popupIsVisible()); | 2087 DCHECK(popupIsVisible()); |
| 2082 DCHECK(m_popup); | 2088 DCHECK(m_popup); |
| 2083 m_popup->updateFromElement(PopupMenu::ByDOMChange); | 2089 m_popup->updateFromElement(PopupMenu::ByDOMChange); |
| 2084 } | 2090 } |
| 2085 | 2091 |
| 2086 } // namespace blink | 2092 } // namespace blink |
| OLD | NEW |