f9de4319a339b901c75492be163558d3f068c48b
[WebKit-https.git] / Source / WebCore / html / HTMLSelectElement.h
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 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 "CollectionCache.h"
30 #include "Event.h"
31 #include "HTMLFormControlElement.h"
32 #include <wtf/Vector.h>
33
34 namespace WebCore {
35
36 class HTMLOptionElement;
37 class HTMLOptionsCollection;
38
39 class HTMLSelectElement : public HTMLFormControlElementWithState {
40 public:
41     static PassRefPtr<HTMLSelectElement> create(const QualifiedName&, Document*, HTMLFormElement*);
42
43     int selectedIndex() const;
44     void setSelectedIndex(int index, bool deselect = true);
45     void setSelectedIndexByUser(int index, bool deselect = true, bool fireOnChangeNow = false, bool allowMultipleSelection = false);
46
47     // For ValidityState
48     bool valueMissing() const;
49
50     unsigned length() const;
51
52     int size() const { return m_size; }
53     bool multiple() const { return m_multiple; }
54
55     void add(HTMLElement*, HTMLElement* beforeElement, ExceptionCode&);
56     void remove(int index);
57     void remove(HTMLOptionElement*);
58
59     String value() const;
60     void setValue(const String&);
61
62     PassRefPtr<HTMLOptionsCollection> options();
63
64     virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
65
66     void setRecalcListItems();
67     void recalcListItemsIfNeeded();
68
69     const Vector<HTMLElement*>& listItems() const;
70
71     virtual void accessKeyAction(bool sendToAnyElement);
72     void accessKeySetSelectedIndex(int);
73
74     void setMultiple(bool);
75
76     void setSize(int);
77
78     void setOption(unsigned index, HTMLOptionElement*, ExceptionCode&);
79     void setLength(unsigned, ExceptionCode&);
80
81     Node* namedItem(const AtomicString& name);
82     Node* item(unsigned index);
83
84     CollectionCache* collectionInfo() { m_collectionInfo.checkConsistency(); return &m_collectionInfo; }
85
86     void scrollToSelection();
87
88     void listBoxSelectItem(int listIndex, bool allowMultiplySelections, bool shift, bool fireOnChangeNow = true);
89
90     void updateValidity() { setNeedsValidityCheck(); }
91
92     virtual bool canSelectAll() const;
93     virtual void selectAll();
94     int listToOptionIndex(int listIndex) const;
95     void listBoxOnChange();
96     int optionToListIndex(int optionIndex) const;
97     int activeSelectionStartListIndex() const;
98     int activeSelectionEndListIndex() const;
99     void setActiveSelectionAnchorIndex(int);
100     void setActiveSelectionEndIndex(int);
101     void updateListBoxSelection(bool deselectOtherOptions);
102     
103 protected:
104     HTMLSelectElement(const QualifiedName&, Document*, HTMLFormElement*);
105
106 private:
107     virtual const AtomicString& formControlType() const;
108     
109     virtual bool isKeyboardFocusable(KeyboardEvent*) const;
110     virtual bool isMouseFocusable() const;
111
112     virtual void dispatchFocusEvent(PassRefPtr<Node> oldFocusedNode);
113     virtual void dispatchBlurEvent(PassRefPtr<Node> newFocusedNode);
114     
115     virtual bool canStartSelection() const { return false; }
116
117     virtual bool isEnumeratable() const { return true; }
118
119     virtual bool saveFormControlState(String& value) const;
120     virtual void restoreFormControlState(const String&);
121
122     virtual void parseMappedAttribute(Attribute*);
123
124     virtual RenderObject* createRenderer(RenderArena*, RenderStyle *);
125     virtual bool appendFormData(FormDataList&, bool);
126
127     virtual void reset();
128
129     virtual void defaultEventHandler(Event*);
130
131     void menuListOnChange();
132     
133     void recalcListItems(bool updateSelectedStates = true) const;
134
135     void deselectItems(HTMLOptionElement* excludeElement = 0);
136     void typeAheadFind(KeyboardEvent*);
137     void saveLastSelection();
138
139     virtual void insertedIntoTree(bool);
140
141     virtual bool isOptionalFormControl() const { return !isRequiredFormControl(); }
142     virtual bool isRequiredFormControl() const;
143
144     bool hasPlaceholderLabelOption() const;
145
146     void recalcListItemsInternal(bool updateSelectedStates = true);
147     void setSelectedIndexInternal(int optionIndex, bool deselect = true, bool fireOnChangeNow = false, bool userDrivenChange = true);
148     void deselectItemsWithoutValidation(Element* excludeElement = 0);
149     void parseMultipleAttribute(const Attribute*);
150     int lastSelectedListIndex() const;
151     void updateSelectedState(int listIndex, bool multi, bool shift);
152     void menuListDefaultEventHandler(Event*);
153     bool platformHandleKeydownEvent(KeyboardEvent*);
154     void listBoxDefaultEventHandler(Event*);
155     void setOptionsChangedOnRenderer();
156     bool usesMenuList() const;
157
158     enum SkipDirection {
159         SkipBackwards = -1,
160         SkipForwards = 1
161     };
162     static int nextValidIndex(const Vector<HTMLElement*>& listItems, int listIndex, SkipDirection, int skip);
163     int nextSelectableListIndex(int startIndex) const;
164     int previousSelectableListIndex(int startIndex) const;
165     int firstSelectableListIndex() const;
166     int lastSelectableListIndex() const;
167     int nextSelectableListIndexPageAway(int startIndex, SkipDirection) const;
168
169     CollectionCache m_collectionInfo;
170     // m_listItems contains HTMLOptionElement, HTMLOptGroupElement, or HTMLHRElement.
171     Vector<HTMLElement*> m_listItems;
172     Vector<bool> m_lastOnChangeSelection;
173     Vector<bool> m_cachedStateForActiveSelection;
174     DOMTimeStamp m_lastCharTime;
175     String m_typedString;
176     int m_size;
177     int m_lastOnChangeIndex;
178     int m_activeSelectionAnchorIndex;
179     int m_activeSelectionEndIndex;
180     UChar m_repeatingChar;
181     bool m_userDrivenChange;
182     bool m_multiple;
183     bool m_activeSelectionState;
184     bool m_shouldRecalcListItems;
185 };
186
187 HTMLSelectElement* toSelectElement(Element*);
188
189 inline bool HTMLSelectElement::usesMenuList() const
190 {
191 #if ENABLE(NO_LISTBOX_RENDERING)
192     return true;
193 #else
194     return !m_multiple && m_size <= 1;
195 #endif
196 }
197
198 } // namespace
199
200 #endif