Simplify and streamline some Color-related code to prepare for some Color/ExtendedCol...
[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-2017 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 #pragma once
26
27 #include "FileChooser.h"
28 #include "HTMLTextFormControlElement.h"
29 #include "StepRange.h"
30 #include <memory>
31
32 #if PLATFORM(IOS)
33 #include "DateComponents.h"
34 #endif
35
36 namespace WebCore {
37
38 class DragData;
39 class FileList;
40 class HTMLDataListElement;
41 class HTMLImageLoader;
42 class Icon;
43 class InputType;
44 class ListAttributeTargetObserver;
45 class RadioButtonGroups;
46 class URL;
47
48 struct DateTimeChooserParameters;
49
50 struct InputElementClickState {
51     bool stateful { false };
52     bool checked { false };
53     bool indeterminate { false };
54     RefPtr<HTMLInputElement> checkedRadioButton;
55 };
56
57 class HTMLInputElement : public HTMLTextFormControlElement {
58 public:
59     static Ref<HTMLInputElement> create(const QualifiedName&, Document&, HTMLFormElement*, bool createdByParser);
60     virtual ~HTMLInputElement();
61
62     WEBCORE_EXPORT bool shouldAutocomplete() const final;
63
64     // For ValidityState
65     bool hasBadInput() const final;
66     bool patternMismatch() const final;
67     bool rangeUnderflow() const final;
68     bool rangeOverflow() const final;
69     bool stepMismatch() const final;
70     bool tooShort() const final;
71     bool tooLong() const final;
72     bool typeMismatch() const final;
73     bool valueMissing() const final;
74     bool isValid() const final;
75     WEBCORE_EXPORT String validationMessage() const final;
76
77     // Returns the minimum value for type=date, number, or range.  Don't call this for other types.
78     double minimum() const;
79     // Returns the maximum value for type=date, number, or range.  Don't call this for other types.
80     // This always returns a value which is >= minimum().
81     double maximum() const;
82     // Sets the "allowed value step" defined in the HTML spec to the specified double pointer.
83     // Returns false if there is no "allowed value step."
84     bool getAllowedValueStep(Decimal*) const;
85     StepRange createStepRange(AnyStepHandling) const;
86
87 #if ENABLE(DATALIST_ELEMENT)
88     std::optional<Decimal> findClosestTickMarkValue(const Decimal&);
89 #endif
90
91     WEBCORE_EXPORT ExceptionOr<void> stepUp(int = 1);
92     WEBCORE_EXPORT ExceptionOr<void> stepDown(int = 1);
93
94     // stepUp()/stepDown() for user-interaction.
95     bool isSteppable() const;
96
97     bool isTextButton() const;
98
99     bool isRadioButton() const;
100     WEBCORE_EXPORT bool isTextField() const;
101     WEBCORE_EXPORT bool isSearchField() const;
102     bool isInputTypeHidden() const;
103     WEBCORE_EXPORT bool isPasswordField() const;
104     bool isCheckbox() const;
105     bool isRangeControl() const;
106
107 #if ENABLE(INPUT_TYPE_COLOR)
108     bool isColorControl() const;
109 #endif
110
111     // FIXME: It's highly likely that any call site calling this function should instead
112     // be using a different one. Many input elements behave like text fields, and in addition
113     // any unknown input type is treated as text. Consider, for example, isTextField or
114     // isTextField && !isPasswordField.
115     WEBCORE_EXPORT bool isText() const;
116
117     WEBCORE_EXPORT bool isEmailField() const;
118     bool isFileUpload() const;
119     bool isImageButton() const;
120     WEBCORE_EXPORT bool isNumberField() const;
121     bool isSubmitButton() const;
122     WEBCORE_EXPORT bool isTelephoneField() const;
123     WEBCORE_EXPORT bool isURLField() const;
124     WEBCORE_EXPORT bool isDateField() const;
125     WEBCORE_EXPORT bool isDateTimeField() const;
126     WEBCORE_EXPORT bool isDateTimeLocalField() const;
127     WEBCORE_EXPORT bool isMonthField() const;
128     WEBCORE_EXPORT bool isTimeField() const;
129     WEBCORE_EXPORT bool isWeekField() const;
130
131 #if PLATFORM(IOS)
132     DateComponents::Type dateType() const;
133 #endif
134
135     HTMLElement* containerElement() const;
136     
137     RefPtr<TextControlInnerTextElement> innerTextElement() const final;
138     RenderStyle createInnerTextStyle(const RenderStyle&) const override;
139
140     HTMLElement* innerBlockElement() const;
141     HTMLElement* innerSpinButtonElement() const;
142     HTMLElement* capsLockIndicatorElement() const;
143     HTMLElement* resultsButtonElement() const;
144     HTMLElement* cancelButtonElement() const;
145     HTMLElement* sliderThumbElement() const;
146     HTMLElement* sliderTrackElement() const;
147     HTMLElement* placeholderElement() const final;
148     WEBCORE_EXPORT HTMLElement* autoFillButtonElement() const;
149
150 #if ENABLE(ALTERNATIVE_PRESENTATION_BUTTON_ELEMENT)
151     WEBCORE_EXPORT HTMLElement* alternativePresentationButtonElement() const;
152 #endif
153
154     bool checked() const { return m_isChecked; }
155     WEBCORE_EXPORT 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     WEBCORE_EXPORT 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     bool matchesIndeterminatePseudoClass() const final;
163     bool shouldAppearIndeterminate() const final;
164
165     WEBCORE_EXPORT unsigned size() const;
166     bool sizeShouldIncludeDecoration(int& preferredSize) const;
167     float decorationWidth() const;
168
169     WEBCORE_EXPORT void setType(const AtomicString&);
170
171 #if ENABLE(ALTERNATIVE_PRESENTATION_BUTTON_ELEMENT)
172     void setTypeWithoutUpdatingAttribute(const AtomicString&);
173 #endif
174
175     WEBCORE_EXPORT String value() const final;
176     WEBCORE_EXPORT ExceptionOr<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 ExceptionOr<void> setValueAsDate(double);
194
195     WEBCORE_EXPORT double valueAsNumber() const;
196     WEBCORE_EXPORT ExceptionOr<void> setValueAsNumber(double, 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     void didBlur();
225
226     int maxResults() const { return m_maxResults; }
227
228     WEBCORE_EXPORT String defaultValue() const;
229     WEBCORE_EXPORT void setDefaultValue(const String&);
230
231     Vector<String> acceptMIMETypes();
232     Vector<String> acceptFileExtensions();
233     String accept() const;
234     WEBCORE_EXPORT String alt() const;
235
236     WEBCORE_EXPORT ExceptionOr<void> setSize(unsigned);
237
238     URL src() const;
239
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     bool isAutoFillAvailable() const { return m_isAutoFillAvailable; }
251     void setAutoFillAvailable(bool autoFillAvailable) { m_isAutoFillAvailable = autoFillAvailable; }
252
253     WEBCORE_EXPORT FileList* files();
254     WEBCORE_EXPORT void setFiles(RefPtr<FileList>&&);
255
256 #if ENABLE(DRAG_SUPPORT)
257     // Returns true if the given DragData has more than one dropped files.
258     bool receiveDroppedFiles(const DragData&);
259 #endif
260
261     Icon* icon() const;
262     String displayString() const;
263
264     // These functions are used for rendering the input active during a
265     // drag-and-drop operation.
266     bool canReceiveDroppedFiles() const;
267     void setCanReceiveDroppedFiles(bool);
268
269     void addSearchResult();
270     void onSearch();
271
272     bool willRespondToMouseClickEvents() override;
273
274 #if ENABLE(DATALIST_ELEMENT)
275     RefPtr<HTMLElement> list() const;
276     RefPtr<HTMLDataListElement> dataList() const;
277     void listAttributeTargetChanged();
278 #endif
279
280     Vector<HTMLInputElement*> radioButtonGroup() const;
281     HTMLInputElement* checkedRadioButtonForGroup() const;
282     bool isInRequiredRadioButtonGroup();
283     // Returns null if this isn't associated with any radio button group.
284     RadioButtonGroups* radioButtonGroups() const;
285
286     // Functions for InputType classes.
287     void setValueInternal(const String&, TextFieldEventBehavior);
288     bool isTextFormControlFocusable() const;
289     bool isTextFormControlKeyboardFocusable(KeyboardEvent&) const;
290     bool isTextFormControlMouseFocusable() const;
291     bool valueAttributeWasUpdatedAfterParsing() const { return m_valueAttributeWasUpdatedAfterParsing; }
292
293     void cacheSelectionInResponseToSetValue(int caretOffset) { cacheSelection(caretOffset, caretOffset, SelectionHasNoDirection); }
294
295     Color valueAsColor() const; // Returns transparent color if not type=color.
296     WEBCORE_EXPORT void selectColor(StringView); // Does nothing if not type=color. Simulates user selection of color; intended for testing.
297
298     String defaultToolTip() const;
299
300 #if ENABLE(MEDIA_CAPTURE)
301     MediaCaptureType mediaCaptureType() const;
302 #endif
303
304     static const unsigned maxEffectiveLength;
305
306     WEBCORE_EXPORT unsigned height() const;
307     WEBCORE_EXPORT unsigned width() const;
308     WEBCORE_EXPORT void setHeight(unsigned);
309     WEBCORE_EXPORT void setWidth(unsigned);
310
311     void blur() final;
312     void defaultBlur();
313
314     const AtomicString& name() const final;
315
316     void endEditing();
317
318     void setSpellcheckDisabledExceptTextReplacement(bool disabled) { m_isSpellcheckDisabledExceptTextReplacement = disabled; }
319     bool isSpellcheckDisabledExceptTextReplacement() const { return m_isSpellcheckDisabledExceptTextReplacement; }
320
321     static Vector<FileChooserFileInfo> filesFromFileInputFormControlState(const FormControlState&);
322
323     bool matchesReadWritePseudoClass() const final;
324     WEBCORE_EXPORT ExceptionOr<void> setRangeText(const String& replacement) final;
325     WEBCORE_EXPORT ExceptionOr<void> setRangeText(const String& replacement, unsigned start, unsigned end, const String& selectionMode) final;
326
327     HTMLImageLoader* imageLoader() { return m_imageLoader.get(); }
328     HTMLImageLoader& ensureImageLoader();
329
330 #if ENABLE(DATE_AND_TIME_INPUT_TYPES)
331     bool setupDateTimeChooserParameters(DateTimeChooserParameters&);
332 #endif
333
334     void capsLockStateMayHaveChanged();
335
336     bool shouldTruncateText(const RenderStyle&) const;
337
338     ExceptionOr<int> selectionStartForBindings() const;
339     ExceptionOr<void> setSelectionStartForBindings(int);
340
341     ExceptionOr<int> selectionEndForBindings() const;
342     ExceptionOr<void> setSelectionEndForBindings(int);
343
344     ExceptionOr<String> selectionDirectionForBindings() const;
345     ExceptionOr<void> setSelectionDirectionForBindings(const String&);
346
347     ExceptionOr<void> setSelectionRangeForBindings(int start, int end, const String& direction);
348
349 protected:
350     HTMLInputElement(const QualifiedName&, Document&, HTMLFormElement*, bool createdByParser);
351
352     void defaultEventHandler(Event&) override;
353
354 private:
355     enum AutoCompleteSetting { Uninitialized, On, Off };
356
357     void didAddUserAgentShadowRoot(ShadowRoot&) final;
358
359     void willChangeForm() final;
360     void didChangeForm() final;
361     InsertedIntoAncestorResult insertedIntoAncestor(InsertionType, ContainerNode&) final;
362     void didFinishInsertingNode() final;
363     void removedFromAncestor(RemovalType, ContainerNode&) final;
364     void didMoveToNewDocument(Document& oldDocument, Document& newDocument) final;
365
366     bool hasCustomFocusLogic() const final;
367     bool isKeyboardFocusable(KeyboardEvent&) const final;
368     bool isMouseFocusable() const final;
369     bool isEnumeratable() const final;
370     bool supportLabels() const final;
371     void updateFocusAppearance(SelectionRestorationMode, SelectionRevealMode) final;
372     bool shouldUseInputMethod() final;
373
374     bool isTextFormControl() const final { return isTextField(); }
375
376     bool canTriggerImplicitSubmission() const final { return isTextField(); }
377
378     const AtomicString& formControlType() const final;
379
380     bool shouldSaveAndRestoreFormControlState() const final;
381     FormControlState saveFormControlState() const final;
382     void restoreFormControlState(const FormControlState&) final;
383
384     bool canStartSelection() const final;
385
386     void accessKeyAction(bool sendMouseEvents) final;
387
388     void parseAttribute(const QualifiedName&, const AtomicString&) final;
389     bool isPresentationAttribute(const QualifiedName&) const final;
390     void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) final;
391     void finishParsingChildren() final;
392     void parserDidSetAttributes() final;
393
394     void copyNonAttributePropertiesFromElement(const Element&) final;
395
396     bool appendFormData(DOMFormData&, bool) final;
397
398     bool isSuccessfulSubmitButton() const final;
399     bool matchesDefaultPseudoClass() const final;
400
401     void reset() final;
402
403     bool isURLAttribute(const Attribute&) const final;
404     bool isInRange() const final;
405     bool isOutOfRange() const final;
406
407     void resumeFromDocumentSuspension() final;
408 #if ENABLE(INPUT_TYPE_COLOR)
409     void prepareForDocumentSuspension() final;
410 #endif
411
412     void addSubresourceAttributeURLs(ListHashSet<URL>&) const final;
413
414     bool needsSuspensionCallback();
415     void registerForSuspensionCallbackIfNeeded();
416     void unregisterForSuspensionCallbackIfNeeded();
417
418     bool supportsMinLength() const { return isTextType(); }
419     bool supportsMaxLength() const { return isTextType(); }
420     bool isTextType() const;
421     bool tooShort(StringView, NeedsToCheckDirtyFlag) const;
422     bool tooLong(StringView, NeedsToCheckDirtyFlag) const;
423
424     bool supportsPlaceholder() const final;
425     void updatePlaceholderText() final;
426     bool isEmptyValue() const final;
427     void handleFocusEvent(Node* oldFocusedNode, FocusDirection) final;
428     void handleBlurEvent() final;
429
430     bool isOptionalFormControl() const final { return !isRequiredFormControl(); }
431     bool isRequiredFormControl() const final;
432     bool computeWillValidate() const final;
433     void requiredAttributeChanged() final;
434
435     void initializeInputType();
436     std::unique_ptr<InputType> createInputType(const AtomicString&);
437     void updateType(const AtomicString&);
438     void runPostTypeUpdateTasks();
439     
440     void subtreeHasChanged() final;
441
442 #if ENABLE(DATALIST_ELEMENT)
443     void resetListAttributeTargetObserver();
444 #endif
445     void maxLengthAttributeChanged(const AtomicString& newValue);
446     void minLengthAttributeChanged(const AtomicString& newValue);
447     void updateValueIfNeeded();
448
449     void addToRadioButtonGroup();
450     void removeFromRadioButtonGroup();
451
452     AtomicString m_name;
453     String m_valueIfDirty;
454     unsigned m_size;
455     short m_maxResults;
456     bool m_isChecked : 1;
457     bool m_reflectsCheckedAttribute : 1;
458     bool m_isIndeterminate : 1;
459     bool m_hasType : 1;
460     bool m_isActivatedSubmit : 1;
461     unsigned m_autocomplete : 2; // AutoCompleteSetting
462     bool m_isAutoFilled : 1;
463     unsigned m_autoFillButtonType : 2; // AutoFillButtonType;
464     bool m_isAutoFillAvailable : 1;
465 #if ENABLE(DATALIST_ELEMENT)
466     bool m_hasNonEmptyList : 1;
467 #endif
468     bool m_stateRestored : 1;
469     bool m_parsingInProgress : 1;
470     bool m_valueAttributeWasUpdatedAfterParsing : 1;
471     bool m_wasModifiedByUser : 1;
472     bool m_canReceiveDroppedFiles : 1;
473 #if ENABLE(TOUCH_EVENTS)
474     bool m_hasTouchEventHandler : 1;
475 #endif
476     bool m_isSpellcheckDisabledExceptTextReplacement : 1;
477     std::unique_ptr<InputType> m_inputType;
478     // The ImageLoader must be owned by this element because the loader code assumes
479     // that it lives as long as its owning element lives. If we move the loader into
480     // the ImageInput object we may delete the loader while this element lives on.
481     std::unique_ptr<HTMLImageLoader> m_imageLoader;
482 #if ENABLE(DATALIST_ELEMENT)
483     std::unique_ptr<ListAttributeTargetObserver> m_listAttributeTargetObserver;
484 #endif
485 };
486
487 }