DOM event handling should pass Event around by reference.
[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-2016 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 DragData;
40 class FileList;
41 class HTMLDataListElement;
42 class HTMLImageLoader;
43 class HTMLOptionElement;
44 class Icon;
45 class InputType;
46 class ListAttributeTargetObserver;
47 class RadioButtonGroups;
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 bool shouldAutocomplete() const final;
70
71     // For ValidityState
72     bool hasBadInput() const final;
73     bool patternMismatch() const final;
74     bool rangeUnderflow() const final;
75     bool rangeOverflow() const final;
76     bool stepMismatch() const final;
77     bool tooLong() const final;
78     bool typeMismatch() const final;
79     bool valueMissing() const final;
80     WEBCORE_EXPORT String validationMessage() const 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     Optional<Decimal> findClosestTickMarkValue(const Decimal&);
94 #endif
95
96     // Implementations of HTMLInputElement::stepUp() and stepDown().
97     WEBCORE_EXPORT void stepUp(int, ExceptionCode&);
98     WEBCORE_EXPORT 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     
144     TextControlInnerTextElement* innerTextElement() const final;
145     RenderStyle createInnerTextStyle(const RenderStyle&) const override;
146
147     HTMLElement* innerBlockElement() const;
148     HTMLElement* innerSpinButtonElement() const;
149     HTMLElement* capsLockIndicatorElement() const;
150     HTMLElement* resultsButtonElement() const;
151     HTMLElement* cancelButtonElement() const;
152     HTMLElement* sliderThumbElement() const;
153     HTMLElement* sliderTrackElement() const;
154     HTMLElement* placeholderElement() const final;
155     WEBCORE_EXPORT HTMLElement* autoFillButtonElement() const;
156
157     bool checked() const { return m_isChecked; }
158     WEBCORE_EXPORT void setChecked(bool, TextFieldEventBehavior = DispatchNoEvent);
159
160     // 'indeterminate' is a state independent of the checked state that causes the control to draw in a way that hides the actual state.
161     bool indeterminate() const { return m_isIndeterminate; }
162     WEBCORE_EXPORT void setIndeterminate(bool);
163     // shouldAppearChecked is used by the rendering tree/CSS while checked() is used by JS to determine checked state
164     bool shouldAppearChecked() const;
165     bool matchesIndeterminatePseudoClass() const final;
166     bool shouldAppearIndeterminate() const final;
167
168     WEBCORE_EXPORT unsigned size() const;
169     bool sizeShouldIncludeDecoration(int& preferredSize) const;
170     float decorationWidth() const;
171
172     WEBCORE_EXPORT void setType(const AtomicString&);
173
174     WEBCORE_EXPORT String value() const final;
175     void setValue(const String&, ExceptionCode&, TextFieldEventBehavior = DispatchNoEvent);
176     WEBCORE_EXPORT void setValue(const String&, TextFieldEventBehavior = DispatchNoEvent);
177     WEBCORE_EXPORT void setValueForUser(const String&);
178     // Checks if the specified string would be a valid value.
179     // We should not call this for types with no string value such as CHECKBOX and RADIO.
180     bool isValidValue(const String&) const;
181     bool hasDirtyValue() const { return !m_valueIfDirty.isNull(); };
182
183     String sanitizeValue(const String&) const;
184
185     String localizeValue(const String&) const;
186
187     // The value which is drawn by a renderer.
188     String visibleValue() const;
189
190     WEBCORE_EXPORT void setEditingValue(const String&);
191
192     WEBCORE_EXPORT double valueAsDate() const;
193     WEBCORE_EXPORT void setValueAsDate(double, ExceptionCode&);
194
195     WEBCORE_EXPORT double valueAsNumber() const;
196     WEBCORE_EXPORT void setValueAsNumber(double, ExceptionCode&, TextFieldEventBehavior = DispatchNoEvent);
197
198     String valueWithDefault() const;
199
200     // This function dispatches 'input' event for non-textfield types. Callers
201     // need to handle any DOM structure changes by event handlers, or need to
202     // delay the 'input' event with EventQueueScope.
203     void setValueFromRenderer(const String&);
204
205     bool canHaveSelection() const;
206
207     bool rendererIsNeeded(const RenderStyle&) final;
208     RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final;
209     void willAttachRenderers() final;
210     void didAttachRenderers() final;
211     void didDetachRenderers() final;
212
213     // FIXME: For isActivatedSubmit and setActivatedSubmit, we should use the NVI-idiom here by making
214     // it private virtual in all classes and expose a public method in HTMLFormControlElement to call
215     // the private virtual method.
216     bool isActivatedSubmit() const final;
217     void setActivatedSubmit(bool flag) final;
218
219     String altText() const;
220
221     void willDispatchEvent(Event&, InputElementClickState&);
222     void didDispatchClickEvent(Event&, const InputElementClickState&);
223
224     int maxResults() const { return m_maxResults; }
225
226     WEBCORE_EXPORT String defaultValue() const;
227     WEBCORE_EXPORT void setDefaultValue(const String&);
228
229     Vector<String> acceptMIMETypes();
230     Vector<String> acceptFileExtensions();
231     String accept() const;
232     WEBCORE_EXPORT String alt() const;
233
234     WEBCORE_EXPORT void setSize(unsigned);
235     void setSize(unsigned, ExceptionCode&);
236
237     URL src() const;
238
239     int maxLengthForBindings() const { return m_maxLength; }
240     unsigned effectiveMaxLength() const;
241
242     bool multiple() const;
243
244     bool isAutoFilled() const { return m_isAutoFilled; }
245     WEBCORE_EXPORT void setAutoFilled(bool = true);
246
247     AutoFillButtonType autoFillButtonType() const { return (AutoFillButtonType)m_autoFillButtonType; }
248     WEBCORE_EXPORT void setShowAutoFillButton(AutoFillButtonType);
249
250     WEBCORE_EXPORT FileList* files();
251     WEBCORE_EXPORT void setFiles(PassRefPtr<FileList>);
252
253 #if ENABLE(DRAG_SUPPORT)
254     // Returns true if the given DragData has more than one dropped files.
255     bool receiveDroppedFiles(const DragData&);
256 #endif
257
258     Icon* icon() const;
259 #if PLATFORM(IOS)
260     String displayString() const;
261 #endif
262     // These functions are used for rendering the input active during a
263     // drag-and-drop operation.
264     bool canReceiveDroppedFiles() const;
265     void setCanReceiveDroppedFiles(bool);
266
267     void addSearchResult();
268     void onSearch();
269
270     bool willRespondToMouseClickEvents() override;
271
272 #if ENABLE(DATALIST_ELEMENT)
273     HTMLElement* list() const;
274     HTMLDataListElement* dataList() const;
275     void listAttributeTargetChanged();
276 #endif
277
278     Vector<HTMLInputElement*> radioButtonGroup() const;
279     HTMLInputElement* checkedRadioButtonForGroup() const;
280     bool isInRequiredRadioButtonGroup();
281     // Returns null if this isn't associated with any radio button group.
282     RadioButtonGroups* radioButtonGroups() const;
283
284     // Functions for InputType classes.
285     void setValueInternal(const String&, TextFieldEventBehavior);
286     bool isTextFormControlFocusable() const;
287     bool isTextFormControlKeyboardFocusable(KeyboardEvent&) const;
288     bool isTextFormControlMouseFocusable() const;
289     bool valueAttributeWasUpdatedAfterParsing() const { return m_valueAttributeWasUpdatedAfterParsing; }
290
291     void cacheSelectionInResponseToSetValue(int caretOffset) { cacheSelection(caretOffset, caretOffset, SelectionHasNoDirection); }
292
293     Color valueAsColor() const; // Returns transparent color if not type=color.
294     WEBCORE_EXPORT void selectColor(const Color&); // Does nothing if not type=color. Simulates user selection of color; intended for testing.
295
296     String defaultToolTip() const;
297
298 #if ENABLE(MEDIA_CAPTURE)
299     MediaCaptureType mediaCaptureType() const;
300 #endif
301
302     static const unsigned maxEffectiveLength;
303
304     WEBCORE_EXPORT unsigned height() const;
305     WEBCORE_EXPORT unsigned width() const;
306     WEBCORE_EXPORT void setHeight(unsigned);
307     WEBCORE_EXPORT void setWidth(unsigned);
308
309     void blur() final;
310     void defaultBlur();
311
312     const AtomicString& name() const final;
313
314     void endEditing();
315
316     void setSpellcheckEnabled(bool enabled) { m_isSpellCheckingEnabled = enabled; }
317
318     static Vector<FileChooserFileInfo> filesFromFileInputFormControlState(const FormControlState&);
319
320     bool matchesReadWritePseudoClass() const final;
321     WEBCORE_EXPORT void setRangeText(const String& replacement, ExceptionCode&) final;
322     WEBCORE_EXPORT void setRangeText(const String& replacement, unsigned start, unsigned end, const String& selectionMode, ExceptionCode&) final;
323
324     HTMLImageLoader* imageLoader() { return m_imageLoader.get(); }
325     HTMLImageLoader& ensureImageLoader();
326
327 #if ENABLE(DATE_AND_TIME_INPUT_TYPES)
328     bool setupDateTimeChooserParameters(DateTimeChooserParameters&);
329 #endif
330
331     void capsLockStateMayHaveChanged();
332
333     bool shouldTruncateText(const RenderStyle&) const;
334
335 protected:
336     HTMLInputElement(const QualifiedName&, Document&, HTMLFormElement*, bool createdByParser);
337
338     void defaultEventHandler(Event&) override;
339
340 private:
341     enum AutoCompleteSetting { Uninitialized, On, Off };
342
343     void didAddUserAgentShadowRoot(ShadowRoot*) final;
344
345     void willChangeForm() final;
346     void didChangeForm() final;
347     InsertionNotificationRequest insertedInto(ContainerNode&) final;
348     void finishedInsertingSubtree() final;
349     void removedFrom(ContainerNode&) final;
350     void didMoveToNewDocument(Document* oldDocument) final;
351
352     bool hasCustomFocusLogic() const final;
353     bool isKeyboardFocusable(KeyboardEvent&) const final;
354     bool isMouseFocusable() const final;
355     bool isEnumeratable() const final;
356     bool supportLabels() const final;
357     void updateFocusAppearance(SelectionRestorationMode, SelectionRevealMode) final;
358     bool shouldUseInputMethod() final;
359     bool isSpellCheckingEnabled() const final;
360
361     bool isTextFormControl() const final { return isTextField(); }
362
363     bool canTriggerImplicitSubmission() const final { return isTextField(); }
364
365     const AtomicString& formControlType() const final;
366
367     bool shouldSaveAndRestoreFormControlState() const final;
368     FormControlState saveFormControlState() const final;
369     void restoreFormControlState(const FormControlState&) final;
370
371     bool canStartSelection() const final;
372
373     void accessKeyAction(bool sendMouseEvents) final;
374
375     void parseAttribute(const QualifiedName&, const AtomicString&) final;
376     bool isPresentationAttribute(const QualifiedName&) const final;
377     void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) final;
378     void finishParsingChildren() final;
379     void parserDidSetAttributes() final;
380
381     void copyNonAttributePropertiesFromElement(const Element&) final;
382
383     bool appendFormData(FormDataList&, bool) final;
384
385     bool isSuccessfulSubmitButton() const final;
386     bool matchesDefaultPseudoClass() const final;
387
388     void reset() final;
389
390     bool isURLAttribute(const Attribute&) const final;
391     bool isInRange() const final;
392     bool isOutOfRange() const final;
393
394     void resumeFromDocumentSuspension() final;
395 #if ENABLE(INPUT_TYPE_COLOR)
396     void prepareForDocumentSuspension() final;
397 #endif
398
399     void addSubresourceAttributeURLs(ListHashSet<URL>&) const final;
400
401     bool needsSuspensionCallback();
402     void registerForSuspensionCallbackIfNeeded();
403     void unregisterForSuspensionCallbackIfNeeded();
404
405     bool supportsMaxLength() const { return isTextType(); }
406     bool isTextType() const;
407     bool tooLong(const String&, NeedsToCheckDirtyFlag) const;
408
409     bool supportsPlaceholder() const final;
410     void updatePlaceholderText() final;
411     bool isEmptyValue() const final;
412     void handleFocusEvent(Node* oldFocusedNode, FocusDirection) final;
413     void handleBlurEvent() final;
414
415     bool isOptionalFormControl() const final { return !isRequiredFormControl(); }
416     bool isRequiredFormControl() const final;
417     bool computeWillValidate() const final;
418     void requiredAttributeChanged() final;
419
420     void initializeInputType();
421     void updateType();
422     void runPostTypeUpdateTasks();
423     
424     void subtreeHasChanged() final;
425
426 #if ENABLE(DATALIST_ELEMENT)
427     void resetListAttributeTargetObserver();
428 #endif
429     void maxLengthAttributeChanged(const AtomicString& newValue);
430     void updateValueIfNeeded();
431
432     void addToRadioButtonGroup();
433     void removeFromRadioButtonGroup();
434
435     AtomicString m_name;
436     String m_valueIfDirty;
437     unsigned m_size;
438     int m_maxLength;
439     short m_maxResults;
440     bool m_isChecked : 1;
441     bool m_reflectsCheckedAttribute : 1;
442     bool m_isIndeterminate : 1;
443     bool m_hasType : 1;
444     bool m_isActivatedSubmit : 1;
445     unsigned m_autocomplete : 2; // AutoCompleteSetting
446     bool m_isAutoFilled : 1;
447     unsigned m_autoFillButtonType : 2; // AutoFillButtonType;
448 #if ENABLE(DATALIST_ELEMENT)
449     bool m_hasNonEmptyList : 1;
450 #endif
451     bool m_stateRestored : 1;
452     bool m_parsingInProgress : 1;
453     bool m_valueAttributeWasUpdatedAfterParsing : 1;
454     bool m_wasModifiedByUser : 1;
455     bool m_canReceiveDroppedFiles : 1;
456 #if ENABLE(TOUCH_EVENTS)
457     bool m_hasTouchEventHandler : 1;
458 #endif
459     bool m_isSpellCheckingEnabled : 1;
460     std::unique_ptr<InputType> m_inputType;
461     // The ImageLoader must be owned by this element because the loader code assumes
462     // that it lives as long as its owning element lives. If we move the loader into
463     // the ImageInput object we may delete the loader while this element lives on.
464     std::unique_ptr<HTMLImageLoader> m_imageLoader;
465 #if ENABLE(DATALIST_ELEMENT)
466     std::unique_ptr<ListAttributeTargetObserver> m_listAttributeTargetObserver;
467 #endif
468 };
469
470 } //namespace
471 #endif