Tidy handling of type=color in HTMLInputElement a bit
[WebKit-https.git] / Source / WebCore / html / HTMLInputElement.h
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, 2010 Apple Inc. All rights reserved.
6  * Copyright (C) 2012 Samsung Electronics. All rights reserved.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  *
23  */
24
25 #ifndef HTMLInputElement_h
26 #define HTMLInputElement_h
27
28 #include "FileChooser.h"
29 #include "HTMLTextFormControlElement.h"
30 #include "StepRange.h"
31 #include <memory>
32
33 #if PLATFORM(IOS)
34 #include "DateComponents.h"
35 #endif
36
37 namespace WebCore {
38
39 class CheckedRadioButtons;
40 class DragData;
41 class FileList;
42 class HTMLDataListElement;
43 class HTMLImageLoader;
44 class HTMLOptionElement;
45 class Icon;
46 class InputType;
47 class ListAttributeTargetObserver;
48 class TextControlInnerTextElement;
49 class URL;
50 struct DateTimeChooserParameters;
51
52 struct InputElementClickState {
53     InputElementClickState()
54         : stateful(false)
55         , checked(false)
56         , indeterminate(false)
57     { }
58     bool stateful;
59     bool checked;
60     bool indeterminate;
61     RefPtr<HTMLInputElement> checkedRadioButton;
62 };
63
64 class HTMLInputElement : public HTMLTextFormControlElement {
65 public:
66     static Ref<HTMLInputElement> create(const QualifiedName&, Document&, HTMLFormElement*, bool createdByParser);
67     virtual ~HTMLInputElement();
68
69     WEBCORE_EXPORT virtual bool shouldAutocomplete() const override final;
70
71     // For ValidityState
72     virtual bool hasBadInput() const override final;
73     virtual bool patternMismatch() const override final;
74     virtual bool rangeUnderflow() const override final;
75     virtual bool rangeOverflow() const override final;
76     virtual bool stepMismatch() const override final;
77     virtual bool tooLong() const override final;
78     virtual bool typeMismatch() const override final;
79     virtual bool valueMissing() const override final;
80     virtual String validationMessage() const override final;
81
82     // Returns the minimum value for type=date, number, or range.  Don't call this for other types.
83     double minimum() const;
84     // Returns the maximum value for type=date, number, or range.  Don't call this for other types.
85     // This always returns a value which is >= minimum().
86     double maximum() const;
87     // Sets the "allowed value step" defined in the HTML spec to the specified double pointer.
88     // Returns false if there is no "allowed value step."
89     bool getAllowedValueStep(Decimal*) const;
90     StepRange createStepRange(AnyStepHandling) const;
91
92 #if ENABLE(DATALIST_ELEMENT)
93     Decimal findClosestTickMarkValue(const Decimal&);
94 #endif
95
96     // Implementations of HTMLInputElement::stepUp() and stepDown().
97     void stepUp(int, ExceptionCode&);
98     void stepDown(int, ExceptionCode&);
99     void stepUp(ExceptionCode& ec) { stepUp(1, ec); }
100     void stepDown(ExceptionCode& ec) { stepDown(1, ec); }
101     // stepUp()/stepDown() for user-interaction.
102     bool isSteppable() const;
103
104     bool isTextButton() const;
105
106     bool isRadioButton() const;
107     WEBCORE_EXPORT bool isTextField() const;
108     WEBCORE_EXPORT bool isSearchField() const;
109     bool isInputTypeHidden() const;
110     WEBCORE_EXPORT bool isPasswordField() const;
111     bool isCheckbox() const;
112     bool isRangeControl() const;
113
114 #if ENABLE(INPUT_TYPE_COLOR)
115     bool isColorControl() const;
116 #endif
117
118     // FIXME: It's highly likely that any call site calling this function should instead
119     // be using a different one. Many input elements behave like text fields, and in addition
120     // any unknown input type is treated as text. Consider, for example, isTextField or
121     // isTextField && !isPasswordField.
122     WEBCORE_EXPORT bool isText() const;
123
124     WEBCORE_EXPORT bool isEmailField() const;
125     bool isFileUpload() const;
126     bool isImageButton() const;
127     WEBCORE_EXPORT bool isNumberField() const;
128     bool isSubmitButton() const;
129     WEBCORE_EXPORT bool isTelephoneField() const;
130     WEBCORE_EXPORT bool isURLField() const;
131     WEBCORE_EXPORT bool isDateField() const;
132     WEBCORE_EXPORT bool isDateTimeField() const;
133     WEBCORE_EXPORT bool isDateTimeLocalField() const;
134     WEBCORE_EXPORT bool isMonthField() const;
135     WEBCORE_EXPORT bool isTimeField() const;
136     WEBCORE_EXPORT bool isWeekField() const;
137
138 #if PLATFORM(IOS)
139     DateComponents::Type dateType() const;
140 #endif
141
142     HTMLElement* containerElement() const;
143     virtual TextControlInnerTextElement* innerTextElement() const override final;
144     HTMLElement* innerBlockElement() const;
145     HTMLElement* innerSpinButtonElement() const;
146     HTMLElement* capsLockIndicatorElement() const;
147     HTMLElement* resultsButtonElement() const;
148     HTMLElement* cancelButtonElement() const;
149     HTMLElement* sliderThumbElement() const;
150     HTMLElement* sliderTrackElement() const;
151     virtual HTMLElement* placeholderElement() const override final;
152     WEBCORE_EXPORT HTMLElement* autoFillButtonElement() const;
153
154     bool checked() const { return m_isChecked; }
155     void setChecked(bool, TextFieldEventBehavior = DispatchNoEvent);
156
157     // 'indeterminate' is a state independent of the checked state that causes the control to draw in a way that hides the actual state.
158     bool indeterminate() const { return m_isIndeterminate; }
159     void setIndeterminate(bool);
160     // shouldAppearChecked is used by the rendering tree/CSS while checked() is used by JS to determine checked state
161     bool shouldAppearChecked() const;
162     virtual bool shouldAppearIndeterminate() const override final;
163
164     int size() const;
165     bool sizeShouldIncludeDecoration(int& preferredSize) const;
166     float decorationWidth() const;
167
168     void setType(const AtomicString&);
169
170     WEBCORE_EXPORT virtual String value() const override final;
171     void setValue(const String&, ExceptionCode&, TextFieldEventBehavior = DispatchNoEvent);
172     WEBCORE_EXPORT void setValue(const String&, TextFieldEventBehavior = DispatchNoEvent);
173     WEBCORE_EXPORT void setValueForUser(const String&);
174     // Checks if the specified string would be a valid value.
175     // We should not call this for types with no string value such as CHECKBOX and RADIO.
176     bool isValidValue(const String&) const;
177     bool hasDirtyValue() const { return !m_valueIfDirty.isNull(); };
178
179     String sanitizeValue(const String&) const;
180
181     String localizeValue(const String&) const;
182
183     // The value which is drawn by a renderer.
184     String visibleValue() const;
185
186     WEBCORE_EXPORT void setEditingValue(const String&);
187
188     double valueAsDate() const;
189     void setValueAsDate(double, ExceptionCode&);
190
191     WEBCORE_EXPORT double valueAsNumber() const;
192     WEBCORE_EXPORT void setValueAsNumber(double, ExceptionCode&, TextFieldEventBehavior = DispatchNoEvent);
193
194     String valueWithDefault() const;
195
196     void setValueFromRenderer(const String&);
197
198     bool canHaveSelection() const;
199
200     virtual bool rendererIsNeeded(const RenderStyle&) override final;
201     virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override final;
202     virtual void willAttachRenderers() override final;
203     virtual void didAttachRenderers() override final;
204     virtual void didDetachRenderers() override final;
205
206     // FIXME: For isActivatedSubmit and setActivatedSubmit, we should use the NVI-idiom here by making
207     // it private virtual in all classes and expose a public method in HTMLFormControlElement to call
208     // the private virtual method.
209     virtual bool isActivatedSubmit() const override final;
210     virtual void setActivatedSubmit(bool flag) override final;
211
212     String altText() const;
213
214     void willDispatchEvent(Event&, InputElementClickState&);
215     void didDispatchClickEvent(Event&, const InputElementClickState&);
216
217     int maxResults() const { return m_maxResults; }
218
219     String defaultValue() const;
220     void setDefaultValue(const String&);
221
222     Vector<String> acceptMIMETypes();
223     Vector<String> acceptFileExtensions();
224     String accept() const;
225     String alt() const;
226
227     void setSize(unsigned);
228     void setSize(unsigned, ExceptionCode&);
229
230     URL src() const;
231
232     virtual int maxLength() const override final;
233     void setMaxLength(int, ExceptionCode&);
234
235     bool multiple() const;
236
237     bool isAutoFilled() const { return m_isAutoFilled; }
238     WEBCORE_EXPORT void setAutoFilled(bool = true);
239
240     bool showAutoFillButton() const { return m_showAutoFillButton; }
241     WEBCORE_EXPORT void setShowAutoFillButton(bool);
242
243     FileList* files();
244     void setFiles(PassRefPtr<FileList>);
245
246 #if ENABLE(DRAG_SUPPORT)
247     // Returns true if the given DragData has more than one dropped files.
248     bool receiveDroppedFiles(const DragData&);
249 #endif
250
251     Icon* icon() const;
252 #if PLATFORM(IOS)
253     String displayString() const;
254 #endif
255     // These functions are used for rendering the input active during a
256     // drag-and-drop operation.
257     bool canReceiveDroppedFiles() const;
258     void setCanReceiveDroppedFiles(bool);
259
260     void addSearchResult();
261     void onSearch();
262
263     virtual bool willRespondToMouseClickEvents() override;
264
265 #if ENABLE(DATALIST_ELEMENT)
266     HTMLElement* list() const;
267     HTMLDataListElement* dataList() const;
268     void listAttributeTargetChanged();
269 #endif
270
271     HTMLInputElement* checkedRadioButtonForGroup() const;
272     bool isInRequiredRadioButtonGroup();
273
274     // Functions for InputType classes.
275     void setValueInternal(const String&, TextFieldEventBehavior);
276     bool isTextFormControlFocusable() const;
277     bool isTextFormControlKeyboardFocusable(KeyboardEvent*) const;
278     bool isTextFormControlMouseFocusable() const;
279     bool valueAttributeWasUpdatedAfterParsing() const { return m_valueAttributeWasUpdatedAfterParsing; }
280
281     void cacheSelectionInResponseToSetValue(int caretOffset) { cacheSelection(caretOffset, caretOffset, SelectionHasNoDirection); }
282
283     Color valueAsColor() const; // Returns transparent color if not type=color.
284     WEBCORE_EXPORT void selectColor(const Color&); // Does nothing if not type=color. Simulates user selection of color; intended for testing.
285
286     String defaultToolTip() const;
287
288 #if ENABLE(MEDIA_CAPTURE)
289     bool shouldUseMediaCapture() const;
290 #endif
291
292     static const int maximumLength;
293
294     unsigned height() const;
295     unsigned width() const;
296     void setHeight(unsigned);
297     void setWidth(unsigned);
298
299     virtual void blur() override final;
300     void defaultBlur();
301
302     virtual const AtomicString& name() const override final;
303
304     void endEditing();
305
306     static Vector<FileChooserFileInfo> filesFromFileInputFormControlState(const FormControlState&);
307
308     virtual bool matchesReadWritePseudoClass() const override final;
309     virtual void setRangeText(const String& replacement, ExceptionCode&) override final;
310     virtual void setRangeText(const String& replacement, unsigned start, unsigned end, const String& selectionMode, ExceptionCode&) override final;
311
312     HTMLImageLoader* imageLoader() { return m_imageLoader.get(); }
313     HTMLImageLoader& ensureImageLoader();
314
315 #if ENABLE(DATE_AND_TIME_INPUT_TYPES)
316     bool setupDateTimeChooserParameters(DateTimeChooserParameters&);
317 #endif
318
319     void capsLockStateMayHaveChanged();
320
321 protected:
322     HTMLInputElement(const QualifiedName&, Document&, HTMLFormElement*, bool createdByParser);
323
324     virtual void defaultEventHandler(Event*) override;
325
326 private:
327     enum AutoCompleteSetting { Uninitialized, On, Off };
328
329     virtual void didAddUserAgentShadowRoot(ShadowRoot*) override final;
330     virtual bool canHaveUserAgentShadowRoot() const override final { return true; }
331
332     virtual void willChangeForm() override final;
333     virtual void didChangeForm() override final;
334     virtual InsertionNotificationRequest insertedInto(ContainerNode&) override final;
335     void finishedInsertingSubtree() override final;
336     virtual void removedFrom(ContainerNode&) override final;
337     virtual void didMoveToNewDocument(Document* oldDocument) override final;
338
339     virtual bool hasCustomFocusLogic() const override final;
340     virtual bool isKeyboardFocusable(KeyboardEvent*) const override final;
341     virtual bool isMouseFocusable() const override final;
342     virtual bool isEnumeratable() const override final;
343     virtual bool supportLabels() const override final;
344     virtual void updateFocusAppearance(SelectionRestorationMode, SelectionRevealMode) override final;
345     virtual bool shouldUseInputMethod() override final;
346
347     virtual bool isTextFormControl() const override final { return isTextField(); }
348
349     virtual bool canTriggerImplicitSubmission() const override final { return isTextField(); }
350
351     virtual const AtomicString& formControlType() const override final;
352
353     virtual bool shouldSaveAndRestoreFormControlState() const override final;
354     virtual FormControlState saveFormControlState() const override final;
355     virtual void restoreFormControlState(const FormControlState&) override final;
356
357     virtual bool canStartSelection() const override final;
358
359     virtual void accessKeyAction(bool sendMouseEvents) override final;
360
361     virtual void parseAttribute(const QualifiedName&, const AtomicString&) override final;
362     virtual bool isPresentationAttribute(const QualifiedName&) const override final;
363     virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) override final;
364     virtual void finishParsingChildren() override final;
365     virtual void parserDidSetAttributes() override final;
366
367     virtual void copyNonAttributePropertiesFromElement(const Element&) override final;
368
369     virtual bool appendFormData(FormDataList&, bool) override final;
370
371     virtual bool isSuccessfulSubmitButton() const override final;
372
373     virtual void reset() override final;
374
375     virtual bool isURLAttribute(const Attribute&) const override final;
376     virtual bool isInRange() const override final;
377     virtual bool isOutOfRange() const override final;
378
379     virtual void documentDidResumeFromPageCache() override final;
380 #if ENABLE(INPUT_TYPE_COLOR)
381     virtual void documentWillSuspendForPageCache() override final;
382 #endif
383
384     virtual void addSubresourceAttributeURLs(ListHashSet<URL>&) const override final;
385
386     bool needsSuspensionCallback();
387     void registerForSuspensionCallbackIfNeeded();
388     void unregisterForSuspensionCallbackIfNeeded();
389
390     bool supportsMaxLength() const { return isTextType(); }
391     bool isTextType() const;
392     bool tooLong(const String&, NeedsToCheckDirtyFlag) const;
393
394     virtual bool supportsPlaceholder() const override final;
395     virtual void updatePlaceholderText() override final;
396     virtual bool isEmptyValue() const override final;
397     virtual void handleFocusEvent(Node* oldFocusedNode, FocusDirection) override final;
398     virtual void handleBlurEvent() override final;
399
400     virtual bool isOptionalFormControl() const override final { return !isRequiredFormControl(); }
401     virtual bool isRequiredFormControl() const override final;
402     virtual bool computeWillValidate() const override final;
403     virtual void requiredAttributeChanged() override final;
404
405     void initializeInputType();
406     void updateType();
407     void runPostTypeUpdateTasks();
408     
409     virtual void subtreeHasChanged() override final;
410
411 #if ENABLE(DATALIST_ELEMENT)
412     void resetListAttributeTargetObserver();
413 #endif
414     void parseMaxLengthAttribute(const AtomicString&);
415     void updateValueIfNeeded();
416
417     // Returns null if this isn't associated with any radio button group.
418     CheckedRadioButtons* checkedRadioButtons() const;
419     void addToRadioButtonGroup();
420     void removeFromRadioButtonGroup();
421
422     AtomicString m_name;
423     String m_valueIfDirty;
424     int m_size;
425     int m_maxLength;
426     short m_maxResults;
427     bool m_isChecked : 1;
428     bool m_reflectsCheckedAttribute : 1;
429     bool m_isIndeterminate : 1;
430     bool m_hasType : 1;
431     bool m_isActivatedSubmit : 1;
432     unsigned m_autocomplete : 2; // AutoCompleteSetting
433     bool m_isAutoFilled : 1;
434     bool m_showAutoFillButton : 1;
435 #if ENABLE(DATALIST_ELEMENT)
436     bool m_hasNonEmptyList : 1;
437 #endif
438     bool m_stateRestored : 1;
439     bool m_parsingInProgress : 1;
440     bool m_valueAttributeWasUpdatedAfterParsing : 1;
441     bool m_wasModifiedByUser : 1;
442     bool m_canReceiveDroppedFiles : 1;
443 #if ENABLE(TOUCH_EVENTS)
444     bool m_hasTouchEventHandler : 1;
445 #endif
446     std::unique_ptr<InputType> m_inputType;
447     // The ImageLoader must be owned by this element because the loader code assumes
448     // that it lives as long as its owning element lives. If we move the loader into
449     // the ImageInput object we may delete the loader while this element lives on.
450     std::unique_ptr<HTMLImageLoader> m_imageLoader;
451 #if ENABLE(DATALIST_ELEMENT)
452     std::unique_ptr<ListAttributeTargetObserver> m_listAttributeTargetObserver;
453 #endif
454 };
455
456 } //namespace
457 #endif