1/* 2 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). 3 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 4 * (C) 1999 Antti Koivisto (koivisto@kde.org) 5 * (C) 2000 Dirk Mueller (mueller@kde.org) 6 * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2011 Apple Inc. All rights reserved. 7 * Copyright (C) 2010 Google Inc. All rights reserved. 8 * 9 * This library is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Library General Public 11 * License as published by the Free Software Foundation; either 12 * version 2 of the License, or (at your option) any later version. 13 * 14 * This library is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Library General Public License for more details. 18 * 19 * You should have received a copy of the GNU Library General Public License 20 * along with this library; see the file COPYING.LIB. If not, write to 21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 22 * Boston, MA 02110-1301, USA. 23 * 24 */ 25 26#ifndef HTMLSelectElement_h 27#define HTMLSelectElement_h 28 29#include "Event.h" 30#include "HTMLFormControlElementWithState.h" 31#include "TypeAhead.h" 32#include <wtf/Vector.h> 33 34namespace WebCore { 35 36class HTMLOptionElement; 37class HTMLOptionsCollection; 38 39class HTMLSelectElement : public HTMLFormControlElementWithState, public TypeAheadDataSource { 40public: 41 static PassRefPtr<HTMLSelectElement> create(const QualifiedName&, Document&, HTMLFormElement*); 42 43 int selectedIndex() const; 44 void setSelectedIndex(int); 45 46 void optionSelectedByUser(int index, bool dispatchChangeEvent, bool allowMultipleSelection = false); 47 48 // For ValidityState 49 virtual String validationMessage() const override; 50 virtual bool valueMissing() const override; 51 52 unsigned length() const; 53 54 int size() const { return m_size; } 55 bool multiple() const { return m_multiple; } 56 57 bool usesMenuList() const; 58 59 void add(HTMLElement*, HTMLElement* beforeElement, ExceptionCode&); 60 61 using Node::remove; 62 // Should be remove(int) but it conflicts with Node::remove(ExceptionCode&). 63 void removeByIndex(int); 64 void remove(HTMLOptionElement*); 65 66 String value() const; 67 void setValue(const String&); 68 69 PassRefPtr<HTMLOptionsCollection> options(); 70 PassRefPtr<HTMLCollection> selectedOptions(); 71 72 void optionElementChildrenChanged(); 73 74 void setRecalcListItems(); 75 void invalidateSelectedItems(); 76 void updateListItemSelectedStates(); 77 78 const Vector<HTMLElement*>& listItems() const; 79 80 virtual void accessKeyAction(bool sendMouseEvents) override; 81 void accessKeySetSelectedIndex(int); 82 83 void setMultiple(bool); 84 85 void setSize(int); 86 87 void setOption(unsigned index, HTMLOptionElement*, ExceptionCode&); 88 void setLength(unsigned, ExceptionCode&); 89 90 Node* namedItem(const AtomicString& name); 91 Node* item(unsigned index); 92 93 void scrollToSelection(); 94 95 void listBoxSelectItem(int listIndex, bool allowMultiplySelections, bool shift, bool fireOnChangeNow = true); 96 97#if PLATFORM(IOS) 98 virtual bool willRespondToMouseClickEvents() override; 99#endif 100 101 bool canSelectAll() const; 102 void selectAll(); 103 int listToOptionIndex(int listIndex) const; 104 void listBoxOnChange(); 105 int optionToListIndex(int optionIndex) const; 106 int activeSelectionStartListIndex() const; 107 int activeSelectionEndListIndex() const; 108 void setActiveSelectionAnchorIndex(int); 109 void setActiveSelectionEndIndex(int); 110 void updateListBoxSelection(bool deselectOtherOptions); 111 112 // For use in the implementation of HTMLOptionElement. 113 void optionSelectionStateChanged(HTMLOptionElement*, bool optionIsSelected); 114 bool allowsNonContiguousSelection() const { return m_allowsNonContiguousSelection; }; 115 116protected: 117 HTMLSelectElement(const QualifiedName&, Document&, HTMLFormElement*); 118 119private: 120 virtual const AtomicString& formControlType() const override; 121 122 virtual bool isKeyboardFocusable(KeyboardEvent*) const override; 123 virtual bool isMouseFocusable() const override; 124 125 virtual void dispatchFocusEvent(PassRefPtr<Element> oldFocusedElement, FocusDirection) override final; 126 virtual void dispatchBlurEvent(PassRefPtr<Element> newFocusedElement) override final; 127 128 virtual bool canStartSelection() const override { return false; } 129 130 virtual bool isEnumeratable() const override { return true; } 131 virtual bool supportLabels() const override { return true; } 132 133 virtual FormControlState saveFormControlState() const override; 134 virtual void restoreFormControlState(const FormControlState&) override; 135 136 virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; 137 virtual bool isPresentationAttribute(const QualifiedName&) const override; 138 139 virtual bool childShouldCreateRenderer(const Node&) const override; 140 virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; 141 virtual bool appendFormData(FormDataList&, bool) override; 142 143 virtual void reset() override; 144 145 virtual void defaultEventHandler(Event*) override; 146 147 void dispatchChangeEventForMenuList(); 148 149 virtual void didRecalcStyle(Style::Change) override final; 150 151 void recalcListItems(bool updateSelectedStates = true) const; 152 153 void deselectItems(HTMLOptionElement* excludeElement = 0); 154 void typeAheadFind(KeyboardEvent*); 155 void saveLastSelection(); 156 157 virtual InsertionNotificationRequest insertedInto(ContainerNode&) override; 158 159 virtual bool isOptionalFormControl() const override { return !isRequiredFormControl(); } 160 virtual bool isRequiredFormControl() const override; 161 162 bool hasPlaceholderLabelOption() const; 163 164 enum SelectOptionFlag { 165 DeselectOtherOptions = 1 << 0, 166 DispatchChangeEvent = 1 << 1, 167 UserDriven = 1 << 2, 168 }; 169 typedef unsigned SelectOptionFlags; 170 void selectOption(int optionIndex, SelectOptionFlags = 0); 171 void deselectItemsWithoutValidation(HTMLElement* elementToExclude = 0); 172 void parseMultipleAttribute(const AtomicString&); 173 int lastSelectedListIndex() const; 174 void updateSelectedState(int listIndex, bool multi, bool shift); 175 void menuListDefaultEventHandler(Event*); 176 bool platformHandleKeydownEvent(KeyboardEvent*); 177 void listBoxDefaultEventHandler(Event*); 178 void setOptionsChangedOnRenderer(); 179 size_t searchOptionsForValue(const String&, size_t listIndexStart, size_t listIndexEnd) const; 180 181 enum SkipDirection { 182 SkipBackwards = -1, 183 SkipForwards = 1 184 }; 185 int nextValidIndex(int listIndex, SkipDirection, int skip) const; 186 int nextSelectableListIndex(int startIndex) const; 187 int previousSelectableListIndex(int startIndex) const; 188 int firstSelectableListIndex() const; 189 int lastSelectableListIndex() const; 190 int nextSelectableListIndexPageAway(int startIndex, SkipDirection) const; 191 192 virtual void childrenChanged(const ChildChange&) override; 193 194 // TypeAheadDataSource functions. 195 virtual int indexOfSelectedOption() const override; 196 virtual int optionCount() const override; 197 virtual String optionAtIndex(int index) const override; 198 199 // m_listItems contains HTMLOptionElement, HTMLOptGroupElement, and HTMLHRElement objects. 200 mutable Vector<HTMLElement*> m_listItems; 201 Vector<bool> m_lastOnChangeSelection; 202 Vector<bool> m_cachedStateForActiveSelection; 203 TypeAhead m_typeAhead; 204 int m_size; 205 int m_lastOnChangeIndex; 206 int m_activeSelectionAnchorIndex; 207 int m_activeSelectionEndIndex; 208 bool m_isProcessingUserDrivenChange; 209 bool m_multiple; 210 bool m_activeSelectionState; 211 bool m_allowsNonContiguousSelection; 212 mutable bool m_shouldRecalcListItems; 213}; 214 215NODE_TYPE_CASTS(HTMLSelectElement) 216 217} // namespace 218 219#endif 220