Clean up ContainerNode::childrenChanged
[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, 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 "HTMLOptionsCollection.h"
32 #include "TypeAhead.h"
33 #include <wtf/Vector.h>
34
35 namespace WebCore {
36
37 class HTMLOptionElement;
38
39 class HTMLSelectElement : public HTMLFormControlElementWithState, public TypeAheadDataSource {
40 public:
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     void remove(int index);
61     void remove(HTMLOptionElement*);
62
63     String value() const;
64     void setValue(const String&);
65
66     PassRefPtr<HTMLOptionsCollection> options();
67     PassRefPtr<HTMLCollection> selectedOptions();
68
69     void optionElementChildrenChanged();
70
71     void setRecalcListItems();
72     void invalidateSelectedItems();
73     void updateListItemSelectedStates();
74
75     const Vector<HTMLElement*>& listItems() const;
76
77     virtual void accessKeyAction(bool sendMouseEvents);
78     void accessKeySetSelectedIndex(int);
79
80     void setMultiple(bool);
81
82     void setSize(int);
83
84     void setOption(unsigned index, HTMLOptionElement*, ExceptionCode&);
85     void setLength(unsigned, ExceptionCode&);
86
87     Node* namedItem(const AtomicString& name);
88     Node* item(unsigned index);
89
90     void scrollToSelection();
91
92     void listBoxSelectItem(int listIndex, bool allowMultiplySelections, bool shift, bool fireOnChangeNow = true);
93
94     bool canSelectAll() const;
95     void selectAll();
96     int listToOptionIndex(int listIndex) const;
97     void listBoxOnChange();
98     int optionToListIndex(int optionIndex) const;
99     int activeSelectionStartListIndex() const;
100     int activeSelectionEndListIndex() const;
101     void setActiveSelectionAnchorIndex(int);
102     void setActiveSelectionEndIndex(int);
103     void updateListBoxSelection(bool deselectOtherOptions);
104     
105     // For use in the implementation of HTMLOptionElement.
106     void optionSelectionStateChanged(HTMLOptionElement*, bool optionIsSelected);
107
108 protected:
109     HTMLSelectElement(const QualifiedName&, Document*, HTMLFormElement*);
110
111 private:
112     virtual const AtomicString& formControlType() const;
113     
114     virtual bool isKeyboardFocusable(KeyboardEvent*) const OVERRIDE;
115     virtual bool isMouseFocusable() const OVERRIDE;
116
117     virtual void dispatchFocusEvent(PassRefPtr<Element> oldFocusedElement, FocusDirection) OVERRIDE FINAL;
118     virtual void dispatchBlurEvent(PassRefPtr<Element> newFocusedElement) OVERRIDE FINAL;
119     
120     virtual bool canStartSelection() const { return false; }
121
122     virtual bool isEnumeratable() const { return true; }
123     virtual bool supportLabels() const OVERRIDE { return true; }
124
125     virtual FormControlState saveFormControlState() const OVERRIDE;
126     virtual void restoreFormControlState(const FormControlState&) OVERRIDE;
127
128     virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
129     virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
130
131     virtual bool childShouldCreateRenderer(const Node*) const OVERRIDE;
132     virtual RenderObject* createRenderer(RenderArena*, RenderStyle *);
133     virtual bool appendFormData(FormDataList&, bool);
134
135     virtual void reset();
136
137     virtual void defaultEventHandler(Event*);
138
139     void dispatchChangeEventForMenuList();
140     
141     void recalcListItems(bool updateSelectedStates = true) const;
142
143     void deselectItems(HTMLOptionElement* excludeElement = 0);
144     void typeAheadFind(KeyboardEvent*);
145     void saveLastSelection();
146
147     virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
148
149     virtual bool isOptionalFormControl() const { return !isRequiredFormControl(); }
150     virtual bool isRequiredFormControl() const;
151
152     bool hasPlaceholderLabelOption() const;
153
154     enum SelectOptionFlag {
155         DeselectOtherOptions = 1 << 0,
156         DispatchChangeEvent = 1 << 1,
157         UserDriven = 1 << 2,
158     };
159     typedef unsigned SelectOptionFlags;
160     void selectOption(int optionIndex, SelectOptionFlags = 0);
161     void deselectItemsWithoutValidation(HTMLElement* elementToExclude = 0);
162     void parseMultipleAttribute(const AtomicString&);
163     int lastSelectedListIndex() const;
164     void updateSelectedState(int listIndex, bool multi, bool shift);
165     void menuListDefaultEventHandler(Event*);
166     bool platformHandleKeydownEvent(KeyboardEvent*);
167     void listBoxDefaultEventHandler(Event*);
168     void setOptionsChangedOnRenderer();
169     size_t searchOptionsForValue(const String&, size_t listIndexStart, size_t listIndexEnd) const;
170
171     enum SkipDirection {
172         SkipBackwards = -1,
173         SkipForwards = 1
174     };
175     int nextValidIndex(int listIndex, SkipDirection, int skip) const;
176     int nextSelectableListIndex(int startIndex) const;
177     int previousSelectableListIndex(int startIndex) const;
178     int firstSelectableListIndex() const;
179     int lastSelectableListIndex() const;
180     int nextSelectableListIndexPageAway(int startIndex, SkipDirection) const;
181
182     virtual void childrenChanged(const ChildChange&) OVERRIDE;
183     virtual bool areAuthorShadowsAllowed() const OVERRIDE { return false; }
184
185     // TypeAheadDataSource functions.
186     virtual int indexOfSelectedOption() const OVERRIDE;
187     virtual int optionCount() const OVERRIDE;
188     virtual String optionAtIndex(int index) const OVERRIDE;
189
190     // m_listItems contains HTMLOptionElement, HTMLOptGroupElement, and HTMLHRElement objects.
191     mutable Vector<HTMLElement*> m_listItems;
192     Vector<bool> m_lastOnChangeSelection;
193     Vector<bool> m_cachedStateForActiveSelection;
194     TypeAhead m_typeAhead;
195     int m_size;
196     int m_lastOnChangeIndex;
197     int m_activeSelectionAnchorIndex;
198     int m_activeSelectionEndIndex;
199     bool m_isProcessingUserDrivenChange;
200     bool m_multiple;
201     bool m_activeSelectionState;
202     mutable bool m_shouldRecalcListItems;
203 };
204
205 inline HTMLSelectElement* toHTMLSelectElement(Node* node)
206 {
207     ASSERT_WITH_SECURITY_IMPLICATION(!node || node->hasTagName(HTMLNames::selectTag));
208     return static_cast<HTMLSelectElement*>(node);
209 }
210
211 } // namespace
212
213 #endif