1/*
2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 * Copyright (C) 2011-2018 Apple Inc. All rights reserved.
4 * Copyright (C) 2012 Samsung Electronics. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#pragma once
34
35#include "HTMLInputElement.h"
36#include "HTMLTextFormControlElement.h"
37#include "RenderPtr.h"
38#include "StepRange.h"
39#include <wtf/FastMalloc.h>
40#include <wtf/Forward.h>
41#include <wtf/RefCounted.h>
42#include <wtf/RefPtr.h>
43
44#if PLATFORM(IOS_FAMILY)
45#include "DateComponents.h"
46#endif
47
48namespace WebCore {
49
50class BeforeTextInsertedEvent;
51class Chrome;
52class DOMFormData;
53class DateComponents;
54class DragData;
55class Event;
56class FileList;
57class HTMLElement;
58class HTMLFormElement;
59class Icon;
60class KeyboardEvent;
61class MouseEvent;
62class Node;
63class RenderStyle;
64class TextControlInnerTextElement;
65class TouchEvent;
66
67struct InputElementClickState;
68
69// An InputType object represents the type-specific part of an HTMLInputElement.
70// Do not expose instances of InputType and classes derived from it to classes
71// other than HTMLInputElement.
72class InputType : public RefCounted<InputType> {
73 WTF_MAKE_FAST_ALLOCATED;
74
75public:
76 static Ref<InputType> create(HTMLInputElement&, const AtomicString&);
77 static Ref<InputType> createText(HTMLInputElement&);
78 virtual ~InputType();
79
80 void detachFromElement() { m_element = nullptr; }
81
82 static bool themeSupportsDataListUI(InputType*);
83
84 virtual const AtomicString& formControlType() const = 0;
85
86 // Type query functions.
87
88 // Any time we are using one of these functions it's best to refactor
89 // to add a virtual function to allow the input type object to do the
90 // work instead, or at least make a query function that asks a higher
91 // level question. These functions make the HTMLInputElement class
92 // inflexible because it's harder to add new input types if there is
93 // scattered code with special cases for various types.
94
95 virtual bool isCheckbox() const;
96 virtual bool isColorControl() const;
97 virtual bool isDateField() const;
98 virtual bool isDateTimeField() const;
99 virtual bool isDateTimeLocalField() const;
100 virtual bool isEmailField() const;
101 virtual bool isFileUpload() const;
102 virtual bool isHiddenType() const;
103 virtual bool isImageButton() const;
104 virtual bool supportLabels() const;
105 virtual bool isMonthField() const;
106 virtual bool isNumberField() const;
107 virtual bool isPasswordField() const;
108 virtual bool isRadioButton() const;
109 virtual bool isRangeControl() const;
110 virtual bool isSearchField() const;
111 virtual bool isSubmitButton() const;
112 virtual bool isTelephoneField() const;
113 virtual bool isTextButton() const;
114 virtual bool isTextField() const;
115 virtual bool isTextType() const;
116 virtual bool isTimeField() const;
117 virtual bool isURLField() const;
118 virtual bool isWeekField() const;
119
120 // Form value functions.
121
122 virtual bool shouldSaveAndRestoreFormControlState() const;
123 virtual FormControlState saveFormControlState() const;
124 virtual void restoreFormControlState(const FormControlState&);
125 virtual bool isFormDataAppendable() const;
126 virtual bool appendFormData(DOMFormData&, bool multipart) const;
127
128 // DOM property functions.
129
130 virtual bool getTypeSpecificValue(String&); // Checked first, before internal storage or the value attribute.
131 virtual String fallbackValue() const; // Checked last, if both internal storage and value attribute are missing.
132 virtual String defaultValue() const; // Checked after even fallbackValue, only when the valueWithDefault function is called.
133 virtual double valueAsDate() const;
134 virtual ExceptionOr<void> setValueAsDate(double) const;
135 virtual double valueAsDouble() const;
136 virtual ExceptionOr<void> setValueAsDouble(double, TextFieldEventBehavior) const;
137 virtual ExceptionOr<void> setValueAsDecimal(const Decimal&, TextFieldEventBehavior) const;
138
139 // Validation functions.
140
141 virtual String validationMessage() const;
142 virtual bool supportsValidation() const;
143 virtual bool typeMismatchFor(const String&) const;
144 virtual bool supportsRequired() const;
145 virtual bool valueMissing(const String&) const;
146 virtual bool hasBadInput() const;
147 virtual bool patternMismatch(const String&) const;
148 bool rangeUnderflow(const String&) const;
149 bool rangeOverflow(const String&) const;
150 bool isInRange(const String&) const;
151 bool isOutOfRange(const String&) const;
152 virtual Decimal defaultValueForStepUp() const;
153 double minimum() const;
154 double maximum() const;
155 virtual bool sizeShouldIncludeDecoration(int defaultSize, int& preferredSize) const;
156 virtual float decorationWidth() const;
157 bool stepMismatch(const String&) const;
158 virtual bool getAllowedValueStep(Decimal*) const;
159 virtual StepRange createStepRange(AnyStepHandling) const;
160 virtual ExceptionOr<void> stepUp(int);
161 virtual void stepUpFromRenderer(int);
162 virtual String badInputText() const;
163 virtual String typeMismatchText() const;
164 virtual String valueMissingText() const;
165 virtual bool canSetStringValue() const;
166 virtual String localizeValue(const String&) const;
167 virtual String visibleValue() const;
168 virtual bool isEmptyValue() const;
169
170 // Type check for the current input value. We do nothing for some types
171 // though typeMismatchFor() does something for them because of value sanitization.
172 virtual bool typeMismatch() const;
173
174 // Return value of null string means "use the default value".
175 // This function must be called only by HTMLInputElement::sanitizeValue().
176 virtual String sanitizeValue(const String&) const;
177
178 // Event handlers.
179
180 virtual void handleClickEvent(MouseEvent&);
181 virtual void handleMouseDownEvent(MouseEvent&);
182 virtual void willDispatchClick(InputElementClickState&);
183 virtual void didDispatchClick(Event&, const InputElementClickState&);
184 virtual void handleDOMActivateEvent(Event&);
185
186 enum ShouldCallBaseEventHandler { No, Yes };
187 virtual ShouldCallBaseEventHandler handleKeydownEvent(KeyboardEvent&);
188
189 virtual void handleKeypressEvent(KeyboardEvent&);
190 virtual void handleKeyupEvent(KeyboardEvent&);
191 virtual void handleBeforeTextInsertedEvent(BeforeTextInsertedEvent&);
192 virtual void forwardEvent(Event&);
193
194#if ENABLE(TOUCH_EVENTS)
195 virtual void handleTouchEvent(TouchEvent&);
196#endif
197
198 // Helpers for event handlers.
199
200 virtual bool shouldSubmitImplicitly(Event&);
201 virtual bool hasCustomFocusLogic() const;
202 virtual bool isKeyboardFocusable(KeyboardEvent*) const;
203 virtual bool isMouseFocusable() const;
204 virtual bool shouldUseInputMethod() const;
205 virtual void handleFocusEvent(Node* oldFocusedNode, FocusDirection);
206 virtual void handleBlurEvent();
207 virtual void accessKeyAction(bool sendMouseEvents);
208 virtual bool canBeSuccessfulSubmitButton();
209 virtual void subtreeHasChanged();
210 virtual void blur();
211
212 virtual void elementDidBlur() { }
213
214#if ENABLE(TOUCH_EVENTS)
215 virtual bool hasTouchEventHandler() const;
216#endif
217
218 // Shadow tree handling.
219
220 virtual void createShadowSubtree();
221 virtual void destroyShadowSubtree();
222
223 virtual HTMLElement* containerElement() const { return nullptr; }
224 virtual HTMLElement* innerBlockElement() const { return nullptr; }
225 virtual RefPtr<TextControlInnerTextElement> innerTextElement() const;
226 virtual HTMLElement* innerSpinButtonElement() const { return nullptr; }
227 virtual HTMLElement* capsLockIndicatorElement() const { return nullptr; }
228 virtual HTMLElement* autoFillButtonElement() const { return nullptr; }
229 virtual HTMLElement* resultsButtonElement() const { return nullptr; }
230 virtual HTMLElement* cancelButtonElement() const { return nullptr; }
231 virtual HTMLElement* sliderThumbElement() const { return nullptr; }
232 virtual HTMLElement* sliderTrackElement() const { return nullptr; }
233 virtual HTMLElement* placeholderElement() const;
234#if ENABLE(DATALIST_ELEMENT)
235 virtual HTMLElement* dataListButtonElement() const { return nullptr; }
236#endif
237
238 // Miscellaneous functions.
239
240 virtual bool rendererIsNeeded();
241 virtual RenderPtr<RenderElement> createInputRenderer(RenderStyle&&);
242 virtual void addSearchResult();
243 virtual void attach();
244 virtual void detach();
245 virtual bool shouldRespectAlignAttribute();
246 virtual FileList* files();
247 virtual void setFiles(RefPtr<FileList>&&);
248 virtual Icon* icon() const;
249 virtual bool shouldSendChangeEventAfterCheckedChanged();
250 virtual bool canSetValue(const String&);
251 virtual bool storesValueSeparateFromAttribute();
252 virtual void setValue(const String&, bool valueChanged, TextFieldEventBehavior);
253 virtual bool shouldResetOnDocumentActivation();
254 virtual bool shouldRespectListAttribute();
255 virtual bool isEnumeratable();
256 virtual bool isCheckable();
257 virtual bool isSteppable() const;
258 virtual bool shouldRespectHeightAndWidthAttributes();
259 virtual bool supportsPlaceholder() const;
260 virtual bool supportsReadOnly() const;
261 virtual void updateInnerTextValue();
262 virtual void updatePlaceholderText();
263 virtual void attributeChanged(const QualifiedName&) { }
264 virtual void disabledStateChanged() { }
265 virtual void readOnlyStateChanged() { }
266 virtual void requiredStateChanged() { }
267 virtual void capsLockStateMayHaveChanged();
268 virtual void updateAutoFillButton();
269 virtual String defaultToolTip() const;
270 virtual bool matchesIndeterminatePseudoClass() const;
271 virtual bool shouldAppearIndeterminate() const;
272 virtual bool isPresentingAttachedView() const;
273 virtual bool supportsSelectionAPI() const;
274 virtual Color valueAsColor() const;
275 virtual void selectColor(StringView);
276 virtual Vector<Color> suggestedColors() const;
277
278 // Parses the specified string for the type, and return
279 // the Decimal value for the parsing result if the parsing
280 // succeeds; Returns defaultValue otherwise. This function can
281 // return NaN or Infinity only if defaultValue is NaN or Infinity.
282 virtual Decimal parseToNumber(const String&, const Decimal& defaultValue) const;
283
284 // Parses the specified string for this InputType, and returns true if it
285 // is successfully parsed. An instance pointed by the DateComponents*
286 // parameter will have parsed values and be modified even if the parsing
287 // fails. The DateComponents* parameter may be null.
288 virtual bool parseToDateComponents(const String&, DateComponents*) const;
289
290 // Create a string representation of the specified Decimal value for the
291 // input type. If NaN or Infinity is specified, this returns an empty
292 // string. This should not be called for types without valueAsNumber.
293 virtual String serialize(const Decimal&) const;
294
295 // Gets width and height of the input element if the type of the
296 // element is image. It returns 0 if the element is not image type.
297 virtual unsigned height() const;
298 virtual unsigned width() const;
299
300 void dispatchSimulatedClickIfActive(KeyboardEvent&) const;
301
302#if ENABLE(DATALIST_ELEMENT)
303 virtual void listAttributeTargetChanged();
304 virtual Optional<Decimal> findClosestTickMarkValue(const Decimal&);
305#endif
306
307#if ENABLE(DRAG_SUPPORT)
308 virtual bool receiveDroppedFiles(const DragData&);
309#endif
310
311#if PLATFORM(IOS_FAMILY)
312 virtual DateComponents::Type dateType() const;
313#endif
314 virtual String displayString() const;
315
316protected:
317 explicit InputType(HTMLInputElement& element)
318 : m_element(makeWeakPtr(element)) { }
319 HTMLInputElement* element() const { return m_element.get(); }
320 Chrome* chrome() const;
321 Decimal parseToNumberOrNaN(const String&) const;
322
323private:
324 // Helper for stepUp()/stepDown(). Adds step value * count to the current value.
325 ExceptionOr<void> applyStep(int count, AnyStepHandling, TextFieldEventBehavior);
326
327 // m_element is null if this InputType is no longer associated with an element (either the element died or changed input type).
328 WeakPtr<HTMLInputElement> m_element;
329};
330
331} // namespace WebCore
332
333#define SPECIALIZE_TYPE_TRAITS_INPUT_TYPE(ToValueTypeName, predicate) \
334SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \
335static bool isType(const WebCore::InputType& input) { return input.predicate; } \
336SPECIALIZE_TYPE_TRAITS_END()
337