blob: 9147c3f0f57b5ab90cb1dd3ed60e45a15dcbb1ab [file] [log] [blame]
darinb9481ed2006-03-20 02:57:59 +00001/*
eric@webkit.org28784e02010-03-18 19:32:03 +00002 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
darinb9481ed2006-03-20 02:57:59 +00003 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
4 * (C) 1999 Antti Koivisto (koivisto@kde.org)
5 * (C) 2000 Dirk Mueller (mueller@kde.org)
darin@apple.com318f8892011-10-15 00:30:43 +00006 * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2011 Apple Inc. All rights reserved.
eric@webkit.org30c94452010-01-23 06:19:10 +00007 * Copyright (C) 2010 Google Inc. All rights reserved.
darinb9481ed2006-03-20 02:57:59 +00008 *
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
ddkilzerc8eccec2007-09-26 02:29:57 +000021 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
darinb9481ed2006-03-20 02:57:59 +000023 *
24 */
25
eseidel8eddecf2007-01-16 00:49:43 +000026#ifndef HTMLSelectElement_h
27#define HTMLSelectElement_h
darinb9481ed2006-03-20 02:57:59 +000028
tonyg@chromium.org8d183cb2011-05-10 08:19:52 +000029#include "Event.h"
tkent@chromium.orgbd756552012-01-06 08:33:24 +000030#include "HTMLFormControlElementWithState.h"
kling@webkit.orgfe420042012-01-07 09:35:21 +000031#include "HTMLOptionsCollection.h"
tkent@chromium.org608cbb02011-10-11 08:45:38 +000032#include <wtf/Vector.h>
darinb9481ed2006-03-20 02:57:59 +000033
34namespace WebCore {
35
36class HTMLOptionElement;
darinb9481ed2006-03-20 02:57:59 +000037
tkent@chromium.org8ce493b2011-10-07 06:05:18 +000038class HTMLSelectElement : public HTMLFormControlElementWithState {
darinb9481ed2006-03-20 02:57:59 +000039public:
darin@apple.com877ce5b2010-05-28 15:38:58 +000040 static PassRefPtr<HTMLSelectElement> create(const QualifiedName&, Document*, HTMLFormElement*);
darinb9481ed2006-03-20 02:57:59 +000041
tkent@chromium.org8ce493b2011-10-07 06:05:18 +000042 int selectedIndex() const;
darin@apple.com92c0a622011-11-02 02:47:18 +000043 void setSelectedIndex(int);
44
45 void optionSelectedByUser(int index, bool dispatchChangeEvent, bool allowMultipleSelection = false);
darin@apple.com8bca65c2009-05-30 23:27:00 +000046
commit-queue@webkit.orga259a132010-12-09 13:07:15 +000047 // For ValidityState
commit-queue@webkit.org02527752012-05-14 04:22:44 +000048 virtual String validationMessage() const OVERRIDE;
49 virtual bool valueMissing() const OVERRIDE;
commit-queue@webkit.orga259a132010-12-09 13:07:15 +000050
darin@apple.com8bca65c2009-05-30 23:27:00 +000051 unsigned length() const;
52
tkent@chromium.org0c74c3e2011-10-12 07:14:12 +000053 int size() const { return m_size; }
54 bool multiple() const { return m_multiple; }
darin@apple.com8bca65c2009-05-30 23:27:00 +000055
jonlee@apple.coma30a69a2011-10-26 18:36:22 +000056 bool usesMenuList() const;
57
darin@apple.com7e8868d2011-01-01 00:58:22 +000058 void add(HTMLElement*, HTMLElement* beforeElement, ExceptionCode&);
darin@apple.com8bca65c2009-05-30 23:27:00 +000059 void remove(int index);
darin@apple.com7e8868d2011-01-01 00:58:22 +000060 void remove(HTMLOptionElement*);
darin@apple.com8bca65c2009-05-30 23:27:00 +000061
commit-queue@webkit.org28926bc2011-01-28 12:46:50 +000062 String value() const;
darin@apple.com8bca65c2009-05-30 23:27:00 +000063 void setValue(const String&);
64
rniwa@webkit.org4823cc12012-07-09 17:40:09 +000065 PassRefPtr<HTMLOptionsCollection> options();
66 PassRefPtr<HTMLCollection> selectedOptions();
darin@apple.com8bca65c2009-05-30 23:27:00 +000067
darin@apple.com318f8892011-10-15 00:30:43 +000068 void optionElementChildrenChanged();
darin@apple.com8bca65c2009-05-30 23:27:00 +000069
70 void setRecalcListItems();
alexis.menard@openbossa.org0fcb5662012-06-28 01:05:27 +000071 void invalidateSelectedItems();
darin@apple.com318f8892011-10-15 00:30:43 +000072 void updateListItemSelectedStates();
darin@apple.com8bca65c2009-05-30 23:27:00 +000073
tkent@chromium.org76e5b122011-10-13 09:08:18 +000074 const Vector<HTMLElement*>& listItems() const;
darin@apple.com8bca65c2009-05-30 23:27:00 +000075
commit-queue@webkit.org5bc308c2011-11-18 21:19:14 +000076 virtual void accessKeyAction(bool sendMouseEvents);
darin@apple.com8bca65c2009-05-30 23:27:00 +000077 void accessKeySetSelectedIndex(int);
78
79 void setMultiple(bool);
80
81 void setSize(int);
82
83 void setOption(unsigned index, HTMLOptionElement*, ExceptionCode&);
84 void setLength(unsigned, ExceptionCode&);
85
86 Node* namedItem(const AtomicString& name);
87 Node* item(unsigned index);
88
darin@apple.com8bca65c2009-05-30 23:27:00 +000089 void scrollToSelection();
90
abecsi@webkit.orgc44c9f82011-10-27 13:02:42 +000091 void listBoxSelectItem(int listIndex, bool allowMultiplySelections, bool shift, bool fireOnChangeNow = true);
abecsi@webkit.orgc44c9f82011-10-27 13:02:42 +000092
darin@apple.com318f8892011-10-15 00:30:43 +000093 bool canSelectAll() const;
94 void selectAll();
tkent@chromium.org8ce493b2011-10-07 06:05:18 +000095 int listToOptionIndex(int listIndex) const;
96 void listBoxOnChange();
97 int optionToListIndex(int optionIndex) const;
98 int activeSelectionStartListIndex() const;
99 int activeSelectionEndListIndex() const;
100 void setActiveSelectionAnchorIndex(int);
101 void setActiveSelectionEndIndex(int);
102 void updateListBoxSelection(bool deselectOtherOptions);
103
darin@apple.com92c0a622011-11-02 02:47:18 +0000104 // For use in the implementation of HTMLOptionElement.
105 void optionSelectionStateChanged(HTMLOptionElement*, bool optionIsSelected);
106
darin@apple.com877ce5b2010-05-28 15:38:58 +0000107protected:
108 HTMLSelectElement(const QualifiedName&, Document*, HTMLFormElement*);
109
darin@apple.com8bca65c2009-05-30 23:27:00 +0000110private:
zimmermann@webkit.orgb75da282009-05-07 21:43:11 +0000111 virtual const AtomicString& formControlType() const;
adelec1577332006-07-07 02:29:11 +0000112
darin2a7db552006-11-09 02:00:10 +0000113 virtual bool isKeyboardFocusable(KeyboardEvent*) const;
adelec1577332006-07-07 02:29:11 +0000114 virtual bool isMouseFocusable() const;
darinb9481ed2006-03-20 02:57:59 +0000115
hayato@chromium.org91ac1342011-08-18 02:41:10 +0000116 virtual void dispatchFocusEvent(PassRefPtr<Node> oldFocusedNode);
117 virtual void dispatchBlurEvent(PassRefPtr<Node> newFocusedNode);
adele79c8ed22007-09-19 18:04:30 +0000118
119 virtual bool canStartSelection() const { return false; }
aroben026ca892006-10-10 21:57:14 +0000120
darinb9481ed2006-03-20 02:57:59 +0000121 virtual bool isEnumeratable() const { return true; }
commit-queue@webkit.orga3eabcd2012-03-16 01:49:05 +0000122 virtual bool supportLabels() const OVERRIDE { return true; }
darinb9481ed2006-03-20 02:57:59 +0000123
tkent@chromium.orgd08b5512012-06-19 06:20:48 +0000124 virtual FormControlState saveFormControlState() const OVERRIDE;
125 virtual void restoreFormControlState(const FormControlState&) OVERRIDE;
darinb9481ed2006-03-20 02:57:59 +0000126
kling@webkit.org260fca82012-05-16 00:34:16 +0000127 virtual void parseAttribute(const Attribute&) OVERRIDE;
kling@webkit.org44bc0dd2012-02-28 22:21:02 +0000128 virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
darinb9481ed2006-03-20 02:57:59 +0000129
morrita@google.combeaa6642012-02-24 09:59:07 +0000130 virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const OVERRIDE;
darinb9481ed2006-03-20 02:57:59 +0000131 virtual RenderObject* createRenderer(RenderArena*, RenderStyle *);
132 virtual bool appendFormData(FormDataList&, bool);
133
darinb9481ed2006-03-20 02:57:59 +0000134 virtual void reset();
darinb9481ed2006-03-20 02:57:59 +0000135
136 virtual void defaultEventHandler(Event*);
zimmermann@webkit.org7c6ec002009-05-28 17:49:09 +0000137
darin@apple.com92c0a622011-11-02 02:47:18 +0000138 void dispatchChangeEventForMenuList();
antti72417192007-02-22 19:57:49 +0000139
mitz@apple.com7a1fd562007-12-13 00:23:34 +0000140 void recalcListItems(bool updateSelectedStates = true) const;
darin@apple.comc2e05f92007-12-07 19:44:20 +0000141
adeleab6a3862006-10-31 22:10:51 +0000142 void deselectItems(HTMLOptionElement* excludeElement = 0);
aroben4a062e82006-10-26 18:19:57 +0000143 void typeAheadFind(KeyboardEvent*);
adele31872c82007-03-17 07:40:53 +0000144 void saveLastSelection();
darinb9481ed2006-03-20 02:57:59 +0000145
darin@apple.com183547b2012-05-23 16:56:33 +0000146 virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
ap@webkit.org2827d622009-04-30 16:55:02 +0000147
commit-queue@webkit.orga259a132010-12-09 13:07:15 +0000148 virtual bool isOptionalFormControl() const { return !isRequiredFormControl(); }
149 virtual bool isRequiredFormControl() const;
150
151 bool hasPlaceholderLabelOption() const;
pkasting@chromium.orgb8a72042009-07-17 22:37:41 +0000152
darin@apple.com92c0a622011-11-02 02:47:18 +0000153 enum SelectOptionFlag {
154 DeselectOtherOptions = 1 << 0,
155 DispatchChangeEvent = 1 << 1,
156 UserDriven = 1 << 2,
157 };
158 typedef unsigned SelectOptionFlags;
159 void selectOption(int optionIndex, SelectOptionFlags = 0);
160 void deselectItemsWithoutValidation(HTMLElement* elementToExclude = 0);
kling@webkit.org260fca82012-05-16 00:34:16 +0000161 void parseMultipleAttribute(const Attribute&);
tkent@chromium.org150660f2011-10-10 03:25:36 +0000162 int lastSelectedListIndex() const;
163 void updateSelectedState(int listIndex, bool multi, bool shift);
164 void menuListDefaultEventHandler(Event*);
165 bool platformHandleKeydownEvent(KeyboardEvent*);
166 void listBoxDefaultEventHandler(Event*);
167 void setOptionsChangedOnRenderer();
tkent@chromium.orgf5e42c22012-06-25 01:47:35 +0000168 size_t searchOptionsForValue(const String&, size_t listIndexStart, size_t listIndexEnd) const;
tkent@chromium.org8ce493b2011-10-07 06:05:18 +0000169
tkent@chromium.orgafd1fb02011-10-10 18:01:09 +0000170 enum SkipDirection {
171 SkipBackwards = -1,
172 SkipForwards = 1
173 };
darin@apple.com318f8892011-10-15 00:30:43 +0000174 int nextValidIndex(int listIndex, SkipDirection, int skip) const;
tkent@chromium.orgafd1fb02011-10-10 18:01:09 +0000175 int nextSelectableListIndex(int startIndex) const;
176 int previousSelectableListIndex(int startIndex) const;
177 int firstSelectableListIndex() const;
178 int lastSelectableListIndex() const;
179 int nextSelectableListIndexPageAway(int startIndex, SkipDirection) const;
180
darin@apple.com318f8892011-10-15 00:30:43 +0000181 virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
morrita@google.comc2ca66f2012-09-12 16:16:14 +0000182 virtual bool areAuthorShadowsAllowed() const OVERRIDE { return false; }
darin@apple.com318f8892011-10-15 00:30:43 +0000183
darin@apple.com318f8892011-10-15 00:30:43 +0000184 // m_listItems contains HTMLOptionElement, HTMLOptGroupElement, and HTMLHRElement objects.
185 mutable Vector<HTMLElement*> m_listItems;
tkent@chromium.org0c74c3e2011-10-12 07:14:12 +0000186 Vector<bool> m_lastOnChangeSelection;
187 Vector<bool> m_cachedStateForActiveSelection;
188 DOMTimeStamp m_lastCharTime;
189 String m_typedString;
190 int m_size;
191 int m_lastOnChangeIndex;
192 int m_activeSelectionAnchorIndex;
193 int m_activeSelectionEndIndex;
194 UChar m_repeatingChar;
darin@apple.com92c0a622011-11-02 02:47:18 +0000195 bool m_isProcessingUserDrivenChange;
tkent@chromium.org0c74c3e2011-10-12 07:14:12 +0000196 bool m_multiple;
197 bool m_activeSelectionState;
darin@apple.com318f8892011-10-15 00:30:43 +0000198 mutable bool m_shouldRecalcListItems;
darinb9481ed2006-03-20 02:57:59 +0000199};
200
shinyak@chromium.org9327f7a2012-08-15 09:51:56 +0000201inline bool isHTMLSelectElement(const Node* node)
202{
203 return node->hasTagName(HTMLNames::selectTag);
204}
darin@apple.com318f8892011-10-15 00:30:43 +0000205
206inline HTMLSelectElement* toHTMLSelectElement(Node* node)
207{
shinyak@chromium.org9327f7a2012-08-15 09:51:56 +0000208 ASSERT(!node || isHTMLSelectElement(node));
darin@apple.com318f8892011-10-15 00:30:43 +0000209 return static_cast<HTMLSelectElement*>(node);
210}
211
212inline const HTMLSelectElement* toHTMLSelectElement(const Node* node)
213{
shinyak@chromium.org9327f7a2012-08-15 09:51:56 +0000214 ASSERT(!node || isHTMLSelectElement(node));
darin@apple.com318f8892011-10-15 00:30:43 +0000215 return static_cast<const HTMLSelectElement*>(node);
216}
217
shinyak@chromium.org9327f7a2012-08-15 09:51:56 +0000218void toHTMLSelectElement(const HTMLSelectElement*); // This overload will catch anyone doing an unnecessary cast.
darin@apple.com318f8892011-10-15 00:30:43 +0000219
darin419b2c22006-07-12 02:55:47 +0000220} // namespace
darinb9481ed2006-03-20 02:57:59 +0000221
222#endif