1/*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4 *           (C) 2000 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB.  If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 *
22 */
23
24#ifndef HTMLFormControlElement_h
25#define HTMLFormControlElement_h
26
27#include "FormAssociatedElement.h"
28#include "HTMLElement.h"
29
30namespace WebCore {
31
32class FormDataList;
33class HTMLFormElement;
34class RenderTextControl;
35class ValidationMessage;
36class ValidityState;
37class VisibleSelection;
38
39// HTMLFormControlElement is the default implementation of FormAssociatedElement,
40// and form-associated element implementations should use HTMLFormControlElement
41// unless there is a special reason.
42class HTMLFormControlElement : public HTMLElement, public FormAssociatedElement {
43public:
44    virtual ~HTMLFormControlElement();
45
46    HTMLFormElement* form() const { return FormAssociatedElement::form(); }
47
48    bool formNoValidate() const;
49
50    virtual void reset() { }
51
52    virtual bool formControlValueMatchesRenderer() const { return m_valueMatchesRenderer; }
53    virtual void setFormControlValueMatchesRenderer(bool b) { m_valueMatchesRenderer = b; }
54
55    virtual bool wasChangedSinceLastFormControlChangeEvent() const;
56    virtual void setChangedSinceLastFormControlChangeEvent(bool);
57
58    virtual void dispatchFormControlChangeEvent();
59    virtual void dispatchFormControlInputEvent();
60
61    virtual bool disabled() const { return m_disabled; }
62    void setDisabled(bool);
63
64    virtual bool isFocusable() const;
65    virtual bool isEnumeratable() const { return false; }
66
67    // Determines whether or not a control will be automatically focused.
68    virtual bool autofocus() const;
69
70    bool required() const;
71
72    const AtomicString& type() const { return formControlType(); }
73
74    void setName(const AtomicString& name);
75
76    virtual bool isEnabledFormControl() const { return !disabled(); }
77    virtual bool isReadOnlyFormControl() const { return readOnly(); }
78
79    virtual bool isRadioButton() const { return false; }
80    virtual bool canTriggerImplicitSubmission() const { return false; }
81
82    // Override in derived classes to get the encoded name=value pair for submitting.
83    // Return true for a successful control (see HTML4-17.13.2).
84    virtual bool appendFormData(FormDataList&, bool) { return false; }
85
86    virtual bool isSuccessfulSubmitButton() const { return false; }
87    virtual bool isActivatedSubmit() const { return false; }
88    virtual void setActivatedSubmit(bool) { }
89
90    virtual bool willValidate() const;
91    String validationMessage();
92    void updateVisibleValidationMessage();
93    void hideVisibleValidationMessage();
94    bool checkValidity(Vector<RefPtr<FormAssociatedElement> >* unhandledInvalidControls = 0);
95    // This must be called when a validation constraint or control value is changed.
96    void setNeedsValidityCheck();
97    void setCustomValidity(const String&);
98
99    bool isLabelable() const;
100    PassRefPtr<NodeList> labels();
101
102    bool readOnly() const { return m_readOnly; }
103
104    virtual void attributeChanged(Attribute*, bool preserveDecls = false);
105
106    using TreeShared<ContainerNode>::ref;
107    using TreeShared<ContainerNode>::deref;
108
109protected:
110    HTMLFormControlElement(const QualifiedName& tagName, Document*, HTMLFormElement*);
111
112    virtual void parseMappedAttribute(Attribute*);
113    virtual void attach();
114    virtual void insertedIntoTree(bool deep);
115    virtual void removedFromTree(bool deep);
116    virtual void insertedIntoDocument();
117    virtual void removedFromDocument();
118    virtual void willMoveToNewOwnerDocument();
119
120    virtual bool isKeyboardFocusable(KeyboardEvent*) const;
121    virtual bool isMouseFocusable() const;
122
123    virtual void recalcStyle(StyleChange);
124
125    virtual void dispatchFocusEvent();
126    virtual void dispatchBlurEvent();
127    virtual void detach();
128
129    // This must be called any time the result of willValidate() has changed.
130    void setNeedsWillValidateCheck();
131    virtual bool recalcWillValidate() const;
132
133private:
134    virtual const AtomicString& formControlName() const;
135    virtual const AtomicString& formControlType() const = 0;
136
137    virtual void refFormAssociatedElement() { ref(); }
138    virtual void derefFormAssociatedElement() { deref(); }
139
140    virtual bool isFormControlElement() const { return true; }
141
142    virtual bool supportsFocus() const;
143
144    virtual short tabIndex() const;
145
146    virtual HTMLFormElement* virtualForm() const;
147    virtual bool isDefaultButtonForForm() const;
148    virtual bool isValidFormControlElement();
149    String visibleValidationMessage() const;
150
151    OwnPtr<ValidationMessage> m_validationMessage;
152    bool m_disabled : 1;
153    bool m_readOnly : 1;
154    bool m_required : 1;
155    bool m_valueMatchesRenderer : 1;
156
157    // The initial value of m_willValidate depends on the derived class. We can't
158    // initialize it with a virtual function in the constructor. m_willValidate
159    // is not deterministic as long as m_willValidateInitialized is false.
160    mutable bool m_willValidateInitialized: 1;
161    mutable bool m_willValidate : 1;
162
163    // Cache of validity()->valid().
164    // But "candidate for constraint validation" doesn't affect m_isValid.
165    bool m_isValid : 1;
166
167    bool m_wasChangedSinceLastFormControlChangeEvent : 1;
168};
169
170// FIXME: Give this class its own header file.
171class HTMLFormControlElementWithState : public HTMLFormControlElement {
172public:
173    virtual ~HTMLFormControlElementWithState();
174
175protected:
176    HTMLFormControlElementWithState(const QualifiedName& tagName, Document*, HTMLFormElement*);
177
178    virtual bool autoComplete() const;
179    virtual void finishParsingChildren();
180    virtual void willMoveToNewOwnerDocument();
181    virtual void didMoveToNewOwnerDocument();
182    virtual void defaultEventHandler(Event*);
183
184private:
185    virtual bool shouldSaveAndRestoreFormControlState() const;
186};
187
188// FIXME: Give this class its own header file.
189class HTMLTextFormControlElement : public HTMLFormControlElementWithState {
190public:
191    // Common flag for HTMLInputElement::tooLong() and HTMLTextAreaElement::tooLong().
192    enum NeedsToCheckDirtyFlag {CheckDirtyFlag, IgnoreDirtyFlag};
193
194    virtual ~HTMLTextFormControlElement();
195
196    virtual void insertedIntoDocument();
197
198    // The derived class should return true if placeholder processing is needed.
199    virtual bool supportsPlaceholder() const = 0;
200    String strippedPlaceholder() const;
201    bool placeholderShouldBeVisible() const;
202
203    int selectionStart() const;
204    int selectionEnd() const;
205    void setSelectionStart(int);
206    void setSelectionEnd(int);
207    void select();
208    void setSelectionRange(int start, int end);
209    PassRefPtr<Range> selection() const;
210
211    virtual void dispatchFormControlChangeEvent();
212
213    virtual int maxLength() const = 0;
214    virtual String value() const = 0;
215
216protected:
217    HTMLTextFormControlElement(const QualifiedName&, Document*, HTMLFormElement*);
218
219    void updatePlaceholderVisibility(bool);
220
221    virtual void parseMappedAttribute(Attribute*);
222    virtual void setTextAsOfLastFormControlChangeEvent(String text) { m_textAsOfLastFormControlChangeEvent = text; }
223
224private:
225    virtual void dispatchFocusEvent();
226    virtual void dispatchBlurEvent();
227
228    bool isPlaceholderEmpty() const;
229
230    virtual int cachedSelectionStart() const = 0;
231    virtual int cachedSelectionEnd() const = 0;
232
233    // Returns true if user-editable value is empty. Used to check placeholder visibility.
234    virtual bool isEmptyValue() const = 0;
235    // Returns true if suggested value is empty. Used to check placeholder visibility.
236    virtual bool isEmptySuggestedValue() const { return true; }
237    // Called in dispatchFocusEvent(), after placeholder process, before calling parent's dispatchFocusEvent().
238    virtual void handleFocusEvent() { }
239    // Called in dispatchBlurEvent(), after placeholder process, before calling parent's dispatchBlurEvent().
240    virtual void handleBlurEvent() { }
241
242    RenderTextControl* textRendererAfterUpdateLayout();
243
244    String m_textAsOfLastFormControlChangeEvent;
245};
246
247} // namespace
248
249#endif
250