Have is<>(T*) function do a null check on the pointer argument
[WebKit-https.git] / Source / WebCore / html / HTMLInputElement.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2001 Dirk Mueller (mueller@kde.org)
5  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014 Apple Inc. All rights reserved.
6  *           (C) 2006 Alexey Proskuryakov (ap@nypop.com)
7  * Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
8  * Copyright (C) 2010 Google Inc. All rights reserved.
9  * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
10  * Copyright (C) 2012 Samsung Electronics. All rights reserved.
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Library General Public
14  * License as published by the Free Software Foundation; either
15  * version 2 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Library General Public License for more details.
21  *
22  * You should have received a copy of the GNU Library General Public License
23  * along with this library; see the file COPYING.LIB.  If not, write to
24  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25  * Boston, MA 02110-1301, USA.
26  *
27  */
28
29 #include "config.h"
30 #include "HTMLInputElement.h"
31
32 #include "AXObjectCache.h"
33 #include "BeforeTextInsertedEvent.h"
34 #include "CSSPropertyNames.h"
35 #include "DateTimeChooser.h"
36 #include "Document.h"
37 #include "Editor.h"
38 #include "EventNames.h"
39 #include "ExceptionCode.h"
40 #include "FileInputType.h"
41 #include "FileList.h"
42 #include "FormController.h"
43 #include "Frame.h"
44 #include "FrameSelection.h"
45 #include "FrameView.h"
46 #include "HTMLDataListElement.h"
47 #include "HTMLFormElement.h"
48 #include "HTMLImageLoader.h"
49 #include "HTMLOptionElement.h"
50 #include "HTMLParserIdioms.h"
51 #include "IdTargetObserver.h"
52 #include "InsertionPoint.h"
53 #include "KeyboardEvent.h"
54 #include "Language.h"
55 #include "LocalizedStrings.h"
56 #include "MouseEvent.h"
57 #include "PlatformMouseEvent.h"
58 #include "RenderTextControlSingleLine.h"
59 #include "RenderTheme.h"
60 #include "RuntimeEnabledFeatures.h"
61 #include "ScopedEventQueue.h"
62 #include "SearchInputType.h"
63 #include "StyleResolver.h"
64 #include "TextBreakIterator.h"
65 #include <wtf/MathExtras.h>
66 #include <wtf/Ref.h>
67
68 #if ENABLE(INPUT_TYPE_COLOR)
69 #include "ColorInputType.h"
70 #endif
71
72 #if ENABLE(TOUCH_EVENTS)
73 #include "TouchEvent.h"
74 #endif
75
76 namespace WebCore {
77
78 using namespace HTMLNames;
79
80 #if ENABLE(DATALIST_ELEMENT)
81 class ListAttributeTargetObserver : IdTargetObserver {
82     WTF_MAKE_FAST_ALLOCATED;
83 public:
84     ListAttributeTargetObserver(const AtomicString& id, HTMLInputElement*);
85
86     virtual void idTargetChanged() override;
87
88 private:
89     HTMLInputElement* m_element;
90 };
91 #endif
92
93 // FIXME: According to HTML4, the length attribute's value can be arbitrarily
94 // large. However, due to https://bugs.webkit.org/show_bug.cgi?id=14536 things
95 // get rather sluggish when a text field has a larger number of characters than
96 // this, even when just clicking in the text field.
97 const int HTMLInputElement::maximumLength = 524288;
98 const int defaultSize = 20;
99 const int maxSavedResults = 256;
100
101 HTMLInputElement::HTMLInputElement(const QualifiedName& tagName, Document& document, HTMLFormElement* form, bool createdByParser)
102     : HTMLTextFormControlElement(tagName, document, form)
103     , m_size(defaultSize)
104     , m_maxLength(maximumLength)
105     , m_maxResults(-1)
106     , m_isChecked(false)
107     , m_reflectsCheckedAttribute(true)
108     , m_isIndeterminate(false)
109     , m_hasType(false)
110     , m_isActivatedSubmit(false)
111     , m_autocomplete(Uninitialized)
112     , m_isAutofilled(false)
113 #if ENABLE(DATALIST_ELEMENT)
114     , m_hasNonEmptyList(false)
115 #endif
116     , m_stateRestored(false)
117     , m_parsingInProgress(createdByParser)
118     , m_valueAttributeWasUpdatedAfterParsing(false)
119     , m_wasModifiedByUser(false)
120     , m_canReceiveDroppedFiles(false)
121 #if ENABLE(TOUCH_EVENTS)
122     , m_hasTouchEventHandler(false)
123 #endif
124     , m_inputType(InputType::createText(*this))
125 {
126     ASSERT(hasTagName(inputTag) || hasTagName(isindexTag));
127     setHasCustomStyleResolveCallbacks();
128 }
129
130 PassRefPtr<HTMLInputElement> HTMLInputElement::create(const QualifiedName& tagName, Document& document, HTMLFormElement* form, bool createdByParser)
131 {
132     RefPtr<HTMLInputElement> inputElement = adoptRef(new HTMLInputElement(tagName, document, form, createdByParser));
133     inputElement->ensureUserAgentShadowRoot();
134     return inputElement.release();
135 }
136
137 HTMLImageLoader* HTMLInputElement::imageLoader()
138 {
139     if (!m_imageLoader)
140         m_imageLoader = std::make_unique<HTMLImageLoader>(*this);
141     return m_imageLoader.get();
142 }
143
144 void HTMLInputElement::didAddUserAgentShadowRoot(ShadowRoot*)
145 {
146     m_inputType->createShadowSubtree();
147     updateInnerTextElementEditability();
148 }
149
150 HTMLInputElement::~HTMLInputElement()
151 {
152     if (needsSuspensionCallback())
153         document().unregisterForPageCacheSuspensionCallbacks(this);
154
155     // Need to remove form association while this is still an HTMLInputElement
156     // so that virtual functions are called correctly.
157     setForm(0);
158     // setForm(0) may register this to a document-level radio button group.
159     // We should unregister it to avoid accessing a deleted object.
160     if (isRadioButton())
161         document().formController().checkedRadioButtons().removeButton(this);
162 #if ENABLE(TOUCH_EVENTS)
163     if (m_hasTouchEventHandler)
164         document().didRemoveEventTargetNode(this);
165 #endif
166 }
167
168 const AtomicString& HTMLInputElement::name() const
169 {
170     return m_name.isNull() ? emptyAtom : m_name;
171 }
172
173 Vector<FileChooserFileInfo> HTMLInputElement::filesFromFileInputFormControlState(const FormControlState& state)
174 {
175     return FileInputType::filesFromFormControlState(state);
176 }
177
178 HTMLElement* HTMLInputElement::containerElement() const
179 {
180     return m_inputType->containerElement();
181 }
182
183 TextControlInnerTextElement* HTMLInputElement::innerTextElement() const
184 {
185     return m_inputType->innerTextElement();
186 }
187
188 HTMLElement* HTMLInputElement::innerBlockElement() const
189 {
190     return m_inputType->innerBlockElement();
191 }
192
193 HTMLElement* HTMLInputElement::innerSpinButtonElement() const
194 {
195     return m_inputType->innerSpinButtonElement();
196 }
197
198 HTMLElement* HTMLInputElement::resultsButtonElement() const
199 {
200     return m_inputType->resultsButtonElement();
201 }
202
203 HTMLElement* HTMLInputElement::cancelButtonElement() const
204 {
205     return m_inputType->cancelButtonElement();
206 }
207
208 HTMLElement* HTMLInputElement::sliderThumbElement() const
209 {
210     return m_inputType->sliderThumbElement();
211 }
212
213 HTMLElement* HTMLInputElement::sliderTrackElement() const
214 {
215     return m_inputType->sliderTrackElement();
216 }
217
218 HTMLElement* HTMLInputElement::placeholderElement() const
219 {
220     return m_inputType->placeholderElement();
221 }
222
223 bool HTMLInputElement::shouldAutocomplete() const
224 {
225     if (m_autocomplete != Uninitialized)
226         return m_autocomplete == On;
227     return HTMLTextFormControlElement::shouldAutocomplete();
228 }
229
230 bool HTMLInputElement::isValidValue(const String& value) const
231 {
232     if (!m_inputType->canSetStringValue()) {
233         ASSERT_NOT_REACHED();
234         return false;
235     }
236     return !m_inputType->typeMismatchFor(value)
237         && !m_inputType->stepMismatch(value)
238         && !m_inputType->rangeUnderflow(value)
239         && !m_inputType->rangeOverflow(value)
240         && !tooLong(value, IgnoreDirtyFlag)
241         && !m_inputType->patternMismatch(value)
242         && !m_inputType->valueMissing(value);
243 }
244
245 bool HTMLInputElement::tooLong() const
246 {
247     return willValidate() && tooLong(value(), CheckDirtyFlag);
248 }
249
250 bool HTMLInputElement::typeMismatch() const
251 {
252     return willValidate() && m_inputType->typeMismatch();
253 }
254
255 bool HTMLInputElement::valueMissing() const
256 {
257     return willValidate() && m_inputType->valueMissing(value());
258 }
259
260 bool HTMLInputElement::hasBadInput() const
261 {
262     return willValidate() && m_inputType->hasBadInput();
263 }
264
265 bool HTMLInputElement::patternMismatch() const
266 {
267     return willValidate() && m_inputType->patternMismatch(value());
268 }
269
270 bool HTMLInputElement::tooLong(const String& value, NeedsToCheckDirtyFlag check) const
271 {
272     // We use isTextType() instead of supportsMaxLength() because of the
273     // 'virtual' overhead.
274     if (!isTextType())
275         return false;
276     int max = maxLength();
277     if (max < 0)
278         return false;
279     if (check == CheckDirtyFlag) {
280         // Return false for the default value or a value set by a script even if
281         // it is longer than maxLength.
282         if (!hasDirtyValue() || !m_wasModifiedByUser)
283             return false;
284     }
285     return numGraphemeClusters(value) > static_cast<unsigned>(max);
286 }
287
288 bool HTMLInputElement::rangeUnderflow() const
289 {
290     return willValidate() && m_inputType->rangeUnderflow(value());
291 }
292
293 bool HTMLInputElement::rangeOverflow() const
294 {
295     return willValidate() && m_inputType->rangeOverflow(value());
296 }
297
298 String HTMLInputElement::validationMessage() const
299 {
300     if (!willValidate())
301         return String();
302
303     if (customError())
304         return customValidationMessage();
305
306     return m_inputType->validationMessage();
307 }
308
309 double HTMLInputElement::minimum() const
310 {
311     return m_inputType->minimum();
312 }
313
314 double HTMLInputElement::maximum() const
315 {
316     return m_inputType->maximum();
317 }
318
319 bool HTMLInputElement::stepMismatch() const
320 {
321     return willValidate() && m_inputType->stepMismatch(value());
322 }
323
324 bool HTMLInputElement::getAllowedValueStep(Decimal* step) const
325 {
326     return m_inputType->getAllowedValueStep(step);
327 }
328
329 StepRange HTMLInputElement::createStepRange(AnyStepHandling anyStepHandling) const
330 {
331     return m_inputType->createStepRange(anyStepHandling);
332 }
333
334 #if ENABLE(DATALIST_ELEMENT)
335 Decimal HTMLInputElement::findClosestTickMarkValue(const Decimal& value)
336 {
337     return m_inputType->findClosestTickMarkValue(value);
338 }
339 #endif
340
341 void HTMLInputElement::stepUp(int n, ExceptionCode& ec)
342 {
343     m_inputType->stepUp(n, ec);
344 }
345
346 void HTMLInputElement::stepDown(int n, ExceptionCode& ec)
347 {
348     m_inputType->stepUp(-n, ec);
349 }
350
351 void HTMLInputElement::blur()
352 {
353     m_inputType->blur();
354 }
355
356 void HTMLInputElement::defaultBlur()
357 {
358     HTMLTextFormControlElement::blur();
359 }
360
361 bool HTMLInputElement::hasCustomFocusLogic() const
362 {
363     return m_inputType->hasCustomFocusLogic();
364 }
365
366 bool HTMLInputElement::isKeyboardFocusable(KeyboardEvent* event) const
367 {
368     return m_inputType->isKeyboardFocusable(event);
369 }
370
371 bool HTMLInputElement::isMouseFocusable() const
372 {
373     return m_inputType->isMouseFocusable();
374 }
375
376 bool HTMLInputElement::isTextFormControlFocusable() const
377 {
378     return HTMLTextFormControlElement::isFocusable();
379 }
380
381 bool HTMLInputElement::isTextFormControlKeyboardFocusable(KeyboardEvent* event) const
382 {
383     return HTMLTextFormControlElement::isKeyboardFocusable(event);
384 }
385
386 bool HTMLInputElement::isTextFormControlMouseFocusable() const
387 {
388     return HTMLTextFormControlElement::isMouseFocusable();
389 }
390
391 void HTMLInputElement::updateFocusAppearance(bool restorePreviousSelection)
392 {
393     if (isTextField()) {
394         if (!restorePreviousSelection || !hasCachedSelection())
395             select();
396         else
397             restoreCachedSelection();
398         if (document().frame())
399             document().frame()->selection().revealSelection();
400     } else
401         HTMLTextFormControlElement::updateFocusAppearance(restorePreviousSelection);
402 }
403
404 void HTMLInputElement::endEditing()
405 {
406     if (!isTextField())
407         return;
408
409     if (Frame* frame = document().frame())
410         frame->editor().textFieldDidEndEditing(this);
411 }
412
413 bool HTMLInputElement::shouldUseInputMethod()
414 {
415     return m_inputType->shouldUseInputMethod();
416 }
417
418 void HTMLInputElement::handleFocusEvent(Node* oldFocusedNode, FocusDirection direction)
419 {
420     m_inputType->handleFocusEvent(oldFocusedNode, direction);
421 }
422
423 void HTMLInputElement::handleBlurEvent()
424 {
425     m_inputType->handleBlurEvent();
426 }
427
428 void HTMLInputElement::setType(const String& type)
429 {
430     // FIXME: This should just call setAttribute. No reason to handle the empty string specially.
431     // We should write a test case to show that setting to the empty string does not remove the
432     // attribute in other browsers and then fix this. Note that setting to null *does* remove
433     // the attribute and setAttribute implements that.
434     if (type.isEmpty())
435         removeAttribute(typeAttr);
436     else
437         setAttribute(typeAttr, type);
438 }
439
440 void HTMLInputElement::updateType()
441 {
442     auto newType = InputType::create(*this, fastGetAttribute(typeAttr));
443     bool hadType = m_hasType;
444     m_hasType = true;
445     if (m_inputType->formControlType() == newType->formControlType())
446         return;
447
448     if (hadType && !newType->canChangeFromAnotherType()) {
449         // Set the attribute back to the old value.
450         // Useful in case we were called from inside parseAttribute.
451         setAttribute(typeAttr, type());
452         return;
453     }
454
455     removeFromRadioButtonGroup();
456
457     bool didStoreValue = m_inputType->storesValueSeparateFromAttribute();
458     bool neededSuspensionCallback = needsSuspensionCallback();
459     bool didRespectHeightAndWidth = m_inputType->shouldRespectHeightAndWidthAttributes();
460
461     m_inputType->destroyShadowSubtree();
462
463     m_inputType = WTF::move(newType);
464     m_inputType->createShadowSubtree();
465     updateInnerTextElementEditability();
466
467 #if ENABLE(TOUCH_EVENTS)
468     bool hasTouchEventHandler = m_inputType->hasTouchEventHandler();
469     if (hasTouchEventHandler != m_hasTouchEventHandler) {
470         if (hasTouchEventHandler)
471             document().didAddTouchEventHandler(this);
472         else
473             document().didRemoveTouchEventHandler(this);
474         m_hasTouchEventHandler = hasTouchEventHandler;
475     }
476 #endif
477
478     setNeedsWillValidateCheck();
479
480     bool willStoreValue = m_inputType->storesValueSeparateFromAttribute();
481
482     if (didStoreValue && !willStoreValue && hasDirtyValue()) {
483         setAttribute(valueAttr, m_valueIfDirty);
484         m_valueIfDirty = String();
485     }
486     if (!didStoreValue && willStoreValue) {
487         AtomicString valueString = fastGetAttribute(valueAttr);
488         m_valueIfDirty = sanitizeValue(valueString);
489     } else
490         updateValueIfNeeded();
491
492     setFormControlValueMatchesRenderer(false);
493     m_inputType->updateInnerTextValue();
494
495     m_wasModifiedByUser = false;
496
497     if (neededSuspensionCallback)
498         unregisterForSuspensionCallbackIfNeeded();
499     else
500         registerForSuspensionCallbackIfNeeded();
501
502     if (didRespectHeightAndWidth != m_inputType->shouldRespectHeightAndWidthAttributes()) {
503         ASSERT(elementData());
504         // FIXME: We don't have the old attribute values so we pretend that we didn't have the old values.
505         if (const Attribute* height = findAttributeByName(heightAttr))
506             attributeChanged(heightAttr, nullAtom, height->value());
507         if (const Attribute* width = findAttributeByName(widthAttr))
508             attributeChanged(widthAttr, nullAtom, width->value());
509         if (const Attribute* align = findAttributeByName(alignAttr))
510             attributeChanged(alignAttr, nullAtom, align->value());
511     }
512
513     if (renderer())
514         setNeedsStyleRecalc(ReconstructRenderTree);
515
516     if (document().focusedElement() == this)
517         updateFocusAppearance(true);
518
519     if (ShadowRoot* shadowRoot = shadowRootOfParentForDistribution(this))
520         shadowRoot->invalidateDistribution();
521
522     setChangedSinceLastFormControlChangeEvent(false);
523
524     addToRadioButtonGroup();
525
526     setNeedsValidityCheck();
527 }
528
529 void HTMLInputElement::subtreeHasChanged()
530 {
531     m_inputType->subtreeHasChanged();
532     // When typing in an input field, childrenChanged is not called, so we need to force the directionality check.
533     calculateAndAdjustDirectionality();
534 }
535
536 const AtomicString& HTMLInputElement::formControlType() const
537 {
538     return m_inputType->formControlType();
539 }
540
541 bool HTMLInputElement::shouldSaveAndRestoreFormControlState() const
542 {
543     if (!m_inputType->shouldSaveAndRestoreFormControlState())
544         return false;
545     return HTMLTextFormControlElement::shouldSaveAndRestoreFormControlState();
546 }
547
548 FormControlState HTMLInputElement::saveFormControlState() const
549 {
550     return m_inputType->saveFormControlState();
551 }
552
553 void HTMLInputElement::restoreFormControlState(const FormControlState& state)
554 {
555     m_inputType->restoreFormControlState(state);
556     m_stateRestored = true;
557 }
558
559 bool HTMLInputElement::canStartSelection() const
560 {
561     if (!isTextField())
562         return false;
563     return HTMLTextFormControlElement::canStartSelection();
564 }
565
566 bool HTMLInputElement::canHaveSelection() const
567 {
568     return isTextField();
569 }
570
571 void HTMLInputElement::accessKeyAction(bool sendMouseEvents)
572 {
573     m_inputType->accessKeyAction(sendMouseEvents);
574 }
575
576 bool HTMLInputElement::isPresentationAttribute(const QualifiedName& name) const
577 {
578     if (name == vspaceAttr || name == hspaceAttr || name == alignAttr || name == widthAttr || name == heightAttr || (name == borderAttr && isImageButton()))
579         return true;
580     return HTMLTextFormControlElement::isPresentationAttribute(name);
581 }
582
583 void HTMLInputElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStyleProperties& style)
584 {
585     if (name == vspaceAttr) {
586         addHTMLLengthToStyle(style, CSSPropertyMarginTop, value);
587         addHTMLLengthToStyle(style, CSSPropertyMarginBottom, value);
588     } else if (name == hspaceAttr) {
589         addHTMLLengthToStyle(style, CSSPropertyMarginLeft, value);
590         addHTMLLengthToStyle(style, CSSPropertyMarginRight, value);
591     } else if (name == alignAttr) {
592         if (m_inputType->shouldRespectAlignAttribute())
593             applyAlignmentAttributeToStyle(value, style);
594     } else if (name == widthAttr) {
595         if (m_inputType->shouldRespectHeightAndWidthAttributes())
596             addHTMLLengthToStyle(style, CSSPropertyWidth, value);
597     } else if (name == heightAttr) {
598         if (m_inputType->shouldRespectHeightAndWidthAttributes())
599             addHTMLLengthToStyle(style, CSSPropertyHeight, value);
600     } else if (name == borderAttr && isImageButton())
601         applyBorderAttributeToStyle(value, style);
602     else
603         HTMLTextFormControlElement::collectStyleForPresentationAttribute(name, value, style);
604 }
605
606 void HTMLInputElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
607 {
608     if (name == nameAttr) {
609         removeFromRadioButtonGroup();
610         m_name = value;
611         addToRadioButtonGroup();
612         HTMLTextFormControlElement::parseAttribute(name, value);
613     } else if (name == autocompleteAttr) {
614         if (equalIgnoringCase(value, "off")) {
615             m_autocomplete = Off;
616             registerForSuspensionCallbackIfNeeded();
617         } else {
618             bool needsToUnregister = m_autocomplete == Off;
619
620             if (value.isEmpty())
621                 m_autocomplete = Uninitialized;
622             else
623                 m_autocomplete = On;
624
625             if (needsToUnregister)
626                 unregisterForSuspensionCallbackIfNeeded();
627         }
628     } else if (name == typeAttr)
629         updateType();
630     else if (name == valueAttr) {
631         // Changes to the value attribute may change whether or not this element has a default value.
632         // If this field is autocomplete=off that might affect the return value of needsSuspensionCallback.
633         if (m_autocomplete == Off) {
634             unregisterForSuspensionCallbackIfNeeded();
635             registerForSuspensionCallbackIfNeeded();
636         }
637         // We only need to setChanged if the form is looking at the default value right now.
638         if (!hasDirtyValue()) {
639             updatePlaceholderVisibility();
640             setNeedsStyleRecalc();
641         }
642         setFormControlValueMatchesRenderer(false);
643         setNeedsValidityCheck();
644         m_valueAttributeWasUpdatedAfterParsing = !m_parsingInProgress;
645         m_inputType->valueAttributeChanged();
646     } else if (name == checkedAttr) {
647         // Another radio button in the same group might be checked by state
648         // restore. We shouldn't call setChecked() even if this has the checked
649         // attribute. So, delay the setChecked() call until
650         // finishParsingChildren() is called if parsing is in progress.
651         if (!m_parsingInProgress && m_reflectsCheckedAttribute) {
652             setChecked(!value.isNull());
653             m_reflectsCheckedAttribute = true;
654         }
655     } else if (name == maxlengthAttr)
656         parseMaxLengthAttribute(value);
657     else if (name == sizeAttr) {
658         int oldSize = m_size;
659         int valueAsInteger = value.toInt();
660         m_size = valueAsInteger > 0 ? valueAsInteger : defaultSize;
661         if (m_size != oldSize && renderer())
662             renderer()->setNeedsLayoutAndPrefWidthsRecalc();
663     } else if (name == altAttr)
664         m_inputType->altAttributeChanged();
665     else if (name == srcAttr)
666         m_inputType->srcAttributeChanged();
667     else if (name == usemapAttr || name == accesskeyAttr) {
668         // FIXME: ignore for the moment
669     } else if (name == onsearchAttr) {
670         // Search field and slider attributes all just cause updateFromElement to be called through style recalcing.
671         setAttributeEventListener(eventNames().searchEvent, name, value);
672     } else if (name == resultsAttr) {
673         m_maxResults = !value.isNull() ? std::min(value.toInt(), maxSavedResults) : -1;
674         m_inputType->maxResultsAttributeChanged();
675     } else if (name == autosaveAttr) {
676         setNeedsStyleRecalc();
677     } else if (name == incrementalAttr) {
678         setNeedsStyleRecalc();
679     } else if (name == minAttr) {
680         m_inputType->minOrMaxAttributeChanged();
681         setNeedsValidityCheck();
682     } else if (name == maxAttr) {
683         m_inputType->minOrMaxAttributeChanged();
684         setNeedsValidityCheck();
685     } else if (name == multipleAttr) {
686         m_inputType->multipleAttributeChanged();
687         setNeedsValidityCheck();
688     } else if (name == stepAttr) {
689         m_inputType->stepAttributeChanged();
690         setNeedsValidityCheck();
691     } else if (name == patternAttr) {
692         setNeedsValidityCheck();
693     } else if (name == precisionAttr) {
694         setNeedsValidityCheck();
695     } else if (name == disabledAttr) {
696         HTMLTextFormControlElement::parseAttribute(name, value);
697         m_inputType->disabledAttributeChanged();
698     } else if (name == readonlyAttr) {
699         HTMLTextFormControlElement::parseAttribute(name, value);
700         m_inputType->readonlyAttributeChanged();
701     }
702 #if ENABLE(DATALIST_ELEMENT)
703     else if (name == listAttr) {
704         m_hasNonEmptyList = !value.isEmpty();
705         if (m_hasNonEmptyList) {
706             resetListAttributeTargetObserver();
707             listAttributeTargetChanged();
708         }
709     }
710 #endif
711     else
712         HTMLTextFormControlElement::parseAttribute(name, value);
713     m_inputType->attributeChanged();
714 }
715
716 void HTMLInputElement::finishParsingChildren()
717 {
718     m_parsingInProgress = false;
719     HTMLTextFormControlElement::finishParsingChildren();
720     if (!m_stateRestored) {
721         bool checked = fastHasAttribute(checkedAttr);
722         if (checked)
723             setChecked(checked);
724         m_reflectsCheckedAttribute = true;
725     }
726 }
727
728 bool HTMLInputElement::rendererIsNeeded(const RenderStyle& style)
729 {
730     return m_inputType->rendererIsNeeded() && HTMLTextFormControlElement::rendererIsNeeded(style);
731 }
732
733 RenderPtr<RenderElement> HTMLInputElement::createElementRenderer(PassRef<RenderStyle> style)
734 {
735     return m_inputType->createInputRenderer(WTF::move(style));
736 }
737
738 void HTMLInputElement::willAttachRenderers()
739 {
740     if (!m_hasType)
741         updateType();
742 }
743
744 void HTMLInputElement::didAttachRenderers()
745 {
746     HTMLTextFormControlElement::didAttachRenderers();
747
748     m_inputType->attach();
749
750     if (document().focusedElement() == this)
751         document().updateFocusAppearanceSoon(true /* restore selection */);
752 }
753
754 void HTMLInputElement::didDetachRenderers()
755 {
756     setFormControlValueMatchesRenderer(false);
757     m_inputType->detach();
758 }
759
760 String HTMLInputElement::altText() const
761 {
762     // http://www.w3.org/TR/1998/REC-html40-19980424/appendix/notes.html#altgen
763     // also heavily discussed by Hixie on bugzilla
764     // note this is intentionally different to HTMLImageElement::altText()
765     String alt = fastGetAttribute(altAttr);
766     // fall back to title attribute
767     if (alt.isNull())
768         alt = getAttribute(titleAttr);
769     if (alt.isNull())
770         alt = fastGetAttribute(valueAttr);
771     if (alt.isEmpty())
772         alt = inputElementAltText();
773     return alt;
774 }
775
776 bool HTMLInputElement::isSuccessfulSubmitButton() const
777 {
778     // HTML spec says that buttons must have names to be considered successful.
779     // However, other browsers do not impose this constraint. So we do not.
780     return !isDisabledFormControl() && m_inputType->canBeSuccessfulSubmitButton();
781 }
782
783 bool HTMLInputElement::isActivatedSubmit() const
784 {
785     return m_isActivatedSubmit;
786 }
787
788 void HTMLInputElement::setActivatedSubmit(bool flag)
789 {
790     m_isActivatedSubmit = flag;
791 }
792
793 bool HTMLInputElement::appendFormData(FormDataList& encoding, bool multipart)
794 {
795     return m_inputType->isFormDataAppendable() && m_inputType->appendFormData(encoding, multipart);
796 }
797
798 void HTMLInputElement::reset()
799 {
800     if (m_inputType->storesValueSeparateFromAttribute())
801         setValue(String());
802
803     setAutofilled(false);
804     setChecked(fastHasAttribute(checkedAttr));
805     m_reflectsCheckedAttribute = true;
806 }
807
808 bool HTMLInputElement::isTextField() const
809 {
810     return m_inputType->isTextField();
811 }
812
813 bool HTMLInputElement::isTextType() const
814 {
815     return m_inputType->isTextType();
816 }
817
818 void HTMLInputElement::setChecked(bool nowChecked, TextFieldEventBehavior eventBehavior)
819 {
820     if (checked() == nowChecked)
821         return;
822
823     m_reflectsCheckedAttribute = false;
824     m_isChecked = nowChecked;
825     setNeedsStyleRecalc();
826
827     if (CheckedRadioButtons* buttons = checkedRadioButtons())
828             buttons->updateCheckedState(this);
829     if (renderer() && renderer()->style().hasAppearance())
830         renderer()->theme().stateChanged(*renderer(), ControlStates::CheckedState);
831     setNeedsValidityCheck();
832
833     // Ideally we'd do this from the render tree (matching
834     // RenderTextView), but it's not possible to do it at the moment
835     // because of the way the code is structured.
836     if (renderer()) {
837         if (AXObjectCache* cache = renderer()->document().existingAXObjectCache())
838             cache->checkedStateChanged(this);
839     }
840
841     // Only send a change event for items in the document (avoid firing during
842     // parsing) and don't send a change event for a radio button that's getting
843     // unchecked to match other browsers. DOM is not a useful standard for this
844     // because it says only to fire change events at "lose focus" time, which is
845     // definitely wrong in practice for these types of elements.
846     if (eventBehavior != DispatchNoEvent && inDocument() && m_inputType->shouldSendChangeEventAfterCheckedChanged()) {
847         setTextAsOfLastFormControlChangeEvent(String());
848         dispatchFormControlChangeEvent();
849     }
850
851     didAffectSelector(AffectedSelectorChecked);
852 }
853
854 void HTMLInputElement::setIndeterminate(bool newValue)
855 {
856     if (indeterminate() == newValue)
857         return;
858
859     m_isIndeterminate = newValue;
860
861     didAffectSelector(AffectedSelectorIndeterminate);
862
863     if (renderer() && renderer()->style().hasAppearance())
864         renderer()->theme().stateChanged(*renderer(), ControlStates::CheckedState);
865 }
866
867 int HTMLInputElement::size() const
868 {
869     return m_size;
870 }
871
872 bool HTMLInputElement::sizeShouldIncludeDecoration(int& preferredSize) const
873 {
874     return m_inputType->sizeShouldIncludeDecoration(defaultSize, preferredSize);
875 }
876
877 float HTMLInputElement::decorationWidth() const
878 {
879     return m_inputType->decorationWidth();
880 }
881
882 void HTMLInputElement::copyNonAttributePropertiesFromElement(const Element& source)
883 {
884     const HTMLInputElement& sourceElement = static_cast<const HTMLInputElement&>(source);
885
886     m_valueIfDirty = sourceElement.m_valueIfDirty;
887     m_wasModifiedByUser = false;
888     setChecked(sourceElement.m_isChecked);
889     m_reflectsCheckedAttribute = sourceElement.m_reflectsCheckedAttribute;
890     m_isIndeterminate = sourceElement.m_isIndeterminate;
891
892     HTMLTextFormControlElement::copyNonAttributePropertiesFromElement(source);
893
894     setFormControlValueMatchesRenderer(false);
895     m_inputType->updateInnerTextValue();
896 }
897
898 String HTMLInputElement::value() const
899 {
900     String value;
901     if (m_inputType->getTypeSpecificValue(value))
902         return value;
903
904     value = m_valueIfDirty;
905     if (!value.isNull())
906         return value;
907
908     AtomicString valueString = fastGetAttribute(valueAttr);
909     value = sanitizeValue(valueString);
910     if (!value.isNull())
911         return value;
912
913     return m_inputType->fallbackValue();
914 }
915
916 String HTMLInputElement::valueWithDefault() const
917 {
918     String value = this->value();
919     if (!value.isNull())
920         return value;
921
922     return m_inputType->defaultValue();
923 }
924
925 void HTMLInputElement::setValueForUser(const String& value)
926 {
927     // Call setValue and make it send a change event.
928     setValue(value, DispatchChangeEvent);
929 }
930
931 void HTMLInputElement::setEditingValue(const String& value)
932 {
933     if (!renderer() || !isTextField())
934         return;
935     setInnerTextValue(value);
936     subtreeHasChanged();
937
938     unsigned max = value.length();
939     if (focused())
940         setSelectionRange(max, max);
941     else
942         cacheSelectionInResponseToSetValue(max);
943
944     dispatchInputEvent();
945 }
946
947 void HTMLInputElement::setValue(const String& value, ExceptionCode& ec, TextFieldEventBehavior eventBehavior)
948 {
949     if (isFileUpload() && !value.isEmpty()) {
950         ec = INVALID_STATE_ERR;
951         return;
952     }
953     setValue(value, eventBehavior);
954 }
955
956 void HTMLInputElement::setValue(const String& value, TextFieldEventBehavior eventBehavior)
957 {
958     if (!m_inputType->canSetValue(value))
959         return;
960
961     Ref<HTMLInputElement> protect(*this);
962     EventQueueScope scope;
963     String sanitizedValue = sanitizeValue(value);
964     bool valueChanged = sanitizedValue != this->value();
965
966     setLastChangeWasNotUserEdit();
967     setFormControlValueMatchesRenderer(false);
968     m_inputType->setValue(sanitizedValue, valueChanged, eventBehavior);
969
970     if (!valueChanged)
971         return;
972 }
973
974 void HTMLInputElement::setValueInternal(const String& sanitizedValue, TextFieldEventBehavior eventBehavior)
975 {
976     m_valueIfDirty = sanitizedValue;
977     m_wasModifiedByUser = eventBehavior != DispatchNoEvent;
978     setNeedsValidityCheck();
979 }
980
981 double HTMLInputElement::valueAsDate() const
982 {
983     return m_inputType->valueAsDate();
984 }
985
986 void HTMLInputElement::setValueAsDate(double value, ExceptionCode& ec)
987 {
988     m_inputType->setValueAsDate(value, ec);
989 }
990
991 double HTMLInputElement::valueAsNumber() const
992 {
993     return m_inputType->valueAsDouble();
994 }
995
996 void HTMLInputElement::setValueAsNumber(double newValue, ExceptionCode& ec, TextFieldEventBehavior eventBehavior)
997 {
998     if (!std::isfinite(newValue)) {
999         ec = NOT_SUPPORTED_ERR;
1000         return;
1001     }
1002     m_inputType->setValueAsDouble(newValue, eventBehavior, ec);
1003 }
1004
1005 void HTMLInputElement::setValueFromRenderer(const String& value)
1006 {
1007     // File upload controls will never use this.
1008     ASSERT(!isFileUpload());
1009
1010     // Renderer and our event handler are responsible for sanitizing values.
1011     ASSERT(value == sanitizeValue(value) || sanitizeValue(value).isEmpty());
1012
1013     // Workaround for bug where trailing \n is included in the result of textContent.
1014     // The assert macro above may also be simplified to: value == constrainValue(value)
1015     // http://bugs.webkit.org/show_bug.cgi?id=9661
1016     m_valueIfDirty = value == "\n" ? emptyString() : value;
1017
1018     setFormControlValueMatchesRenderer(true);
1019     m_wasModifiedByUser = true;
1020
1021     // Input event is fired by the Node::defaultEventHandler for editable controls.
1022     if (!isTextField())
1023         dispatchInputEvent();
1024
1025     setNeedsValidityCheck();
1026
1027     // Clear autofill flag (and yellow background) on user edit.
1028     setAutofilled(false);
1029 }
1030
1031 void HTMLInputElement::willDispatchEvent(Event& event, InputElementClickState& state)
1032 {
1033     if (event.type() == eventNames().textInputEvent && m_inputType->shouldSubmitImplicitly(&event))
1034         event.stopPropagation();
1035     if (event.type() == eventNames().clickEvent && is<MouseEvent>(event) && downcast<MouseEvent>(event).button() == LeftButton) {
1036         m_inputType->willDispatchClick(state);
1037         state.stateful = true;
1038     }
1039 }
1040
1041 void HTMLInputElement::didDispatchClickEvent(Event& event, const InputElementClickState& state)
1042 {
1043     m_inputType->didDispatchClick(&event, state);
1044 }
1045
1046 void HTMLInputElement::defaultEventHandler(Event* evt)
1047 {
1048     ASSERT(evt);
1049     if (is<MouseEvent>(*evt) && evt->type() == eventNames().clickEvent && downcast<MouseEvent>(*evt).button() == LeftButton) {
1050         m_inputType->handleClickEvent(downcast<MouseEvent>(evt));
1051         if (evt->defaultHandled())
1052             return;
1053     }
1054
1055 #if ENABLE(TOUCH_EVENTS)
1056     if (is<TouchEvent>(*evt)) {
1057         m_inputType->handleTouchEvent(downcast<TouchEvent>(evt));
1058         if (evt->defaultHandled())
1059             return;
1060     }
1061 #endif
1062
1063     if (is<KeyboardEvent>(*evt) && evt->type() == eventNames().keydownEvent) {
1064         m_inputType->handleKeydownEvent(downcast<KeyboardEvent>(evt));
1065         if (evt->defaultHandled())
1066             return;
1067     }
1068
1069     // Call the base event handler before any of our own event handling for almost all events in text fields.
1070     // Makes editing keyboard handling take precedence over the keydown and keypress handling in this function.
1071     bool callBaseClassEarly = isTextField() && (evt->type() == eventNames().keydownEvent || evt->type() == eventNames().keypressEvent);
1072     if (callBaseClassEarly) {
1073         HTMLTextFormControlElement::defaultEventHandler(evt);
1074         if (evt->defaultHandled())
1075             return;
1076     }
1077
1078     // DOMActivate events cause the input to be "activated" - in the case of image and submit inputs, this means
1079     // actually submitting the form. For reset inputs, the form is reset. These events are sent when the user clicks
1080     // on the element, or presses enter while it is the active element. JavaScript code wishing to activate the element
1081     // must dispatch a DOMActivate event - a click event will not do the job.
1082     if (evt->type() == eventNames().DOMActivateEvent) {
1083         m_inputType->handleDOMActivateEvent(evt);
1084         if (evt->defaultHandled())
1085             return;
1086     }
1087
1088     // Use key press event here since sending simulated mouse events
1089     // on key down blocks the proper sending of the key press event.
1090     if (is<KeyboardEvent>(*evt)) {
1091         KeyboardEvent& keyboardEvent = downcast<KeyboardEvent>(*evt);
1092         if (keyboardEvent.type() == eventNames().keypressEvent) {
1093             m_inputType->handleKeypressEvent(&keyboardEvent);
1094             if (keyboardEvent.defaultHandled())
1095                 return;
1096         } else if (keyboardEvent.type() == eventNames().keyupEvent) {
1097             m_inputType->handleKeyupEvent(&keyboardEvent);
1098             if (keyboardEvent.defaultHandled())
1099                 return;
1100         }
1101     }
1102
1103     if (m_inputType->shouldSubmitImplicitly(evt)) {
1104         if (isSearchField()) {
1105             addSearchResult();
1106             onSearch();
1107         }
1108         // Form submission finishes editing, just as loss of focus does.
1109         // If there was a change, send the event now.
1110         if (wasChangedSinceLastFormControlChangeEvent())
1111             dispatchFormControlChangeEvent();
1112
1113         RefPtr<HTMLFormElement> formForSubmission = m_inputType->formForSubmission();
1114         // Form may never have been present, or may have been destroyed by code responding to the change event.
1115         if (formForSubmission)
1116             formForSubmission->submitImplicitly(evt, canTriggerImplicitSubmission());
1117
1118         evt->setDefaultHandled();
1119         return;
1120     }
1121
1122     if (is<BeforeTextInsertedEvent>(*evt))
1123         m_inputType->handleBeforeTextInsertedEvent(downcast<BeforeTextInsertedEvent>(evt));
1124
1125     if (is<MouseEvent>(*evt) && evt->type() == eventNames().mousedownEvent) {
1126         m_inputType->handleMouseDownEvent(downcast<MouseEvent>(evt));
1127         if (evt->defaultHandled())
1128             return;
1129     }
1130
1131     m_inputType->forwardEvent(evt);
1132
1133     if (!callBaseClassEarly && !evt->defaultHandled())
1134         HTMLTextFormControlElement::defaultEventHandler(evt);
1135 }
1136
1137 bool HTMLInputElement::willRespondToMouseClickEvents()
1138 {
1139     if (!isDisabledFormControl())
1140         return true;
1141
1142     return HTMLTextFormControlElement::willRespondToMouseClickEvents();
1143 }
1144
1145 bool HTMLInputElement::isURLAttribute(const Attribute& attribute) const
1146 {
1147     return attribute.name() == srcAttr || attribute.name() == formactionAttr || HTMLTextFormControlElement::isURLAttribute(attribute);
1148 }
1149
1150 String HTMLInputElement::defaultValue() const
1151 {
1152     return fastGetAttribute(valueAttr);
1153 }
1154
1155 void HTMLInputElement::setDefaultValue(const String &value)
1156 {
1157     setAttribute(valueAttr, value);
1158 }
1159
1160 static inline bool isRFC2616TokenCharacter(UChar ch)
1161 {
1162     return isASCII(ch) && ch > ' ' && ch != '"' && ch != '(' && ch != ')' && ch != ',' && ch != '/' && (ch < ':' || ch > '@') && (ch < '[' || ch > ']') && ch != '{' && ch != '}' && ch != 0x7f;
1163 }
1164
1165 static bool isValidMIMEType(const String& type)
1166 {
1167     size_t slashPosition = type.find('/');
1168     if (slashPosition == notFound || !slashPosition || slashPosition == type.length() - 1)
1169         return false;
1170     for (size_t i = 0; i < type.length(); ++i) {
1171         if (!isRFC2616TokenCharacter(type[i]) && i != slashPosition)
1172             return false;
1173     }
1174     return true;
1175 }
1176
1177 static bool isValidFileExtension(const String& type)
1178 {
1179     if (type.length() < 2)
1180         return false;
1181     return type[0] == '.';
1182 }
1183
1184 static Vector<String> parseAcceptAttribute(const String& acceptString, bool (*predicate)(const String&))
1185 {
1186     Vector<String> types;
1187     if (acceptString.isEmpty())
1188         return types;
1189
1190     Vector<String> splitTypes;
1191     acceptString.split(',', false, splitTypes);
1192     for (size_t i = 0; i < splitTypes.size(); ++i) {
1193         String trimmedType = stripLeadingAndTrailingHTMLSpaces(splitTypes[i]);
1194         if (trimmedType.isEmpty())
1195             continue;
1196         if (!predicate(trimmedType))
1197             continue;
1198         types.append(trimmedType.lower());
1199     }
1200
1201     return types;
1202 }
1203
1204 Vector<String> HTMLInputElement::acceptMIMETypes()
1205 {
1206     return parseAcceptAttribute(fastGetAttribute(acceptAttr), isValidMIMEType);
1207 }
1208
1209 Vector<String> HTMLInputElement::acceptFileExtensions()
1210 {
1211     return parseAcceptAttribute(fastGetAttribute(acceptAttr), isValidFileExtension);
1212 }
1213
1214 String HTMLInputElement::accept() const
1215 {
1216     return fastGetAttribute(acceptAttr);
1217 }
1218
1219 String HTMLInputElement::alt() const
1220 {
1221     return fastGetAttribute(altAttr);
1222 }
1223
1224 int HTMLInputElement::maxLength() const
1225 {
1226     return m_maxLength;
1227 }
1228
1229 void HTMLInputElement::setMaxLength(int maxLength, ExceptionCode& ec)
1230 {
1231     if (maxLength < 0)
1232         ec = INDEX_SIZE_ERR;
1233     else
1234         setIntegralAttribute(maxlengthAttr, maxLength);
1235 }
1236
1237 bool HTMLInputElement::multiple() const
1238 {
1239     return fastHasAttribute(multipleAttr);
1240 }
1241
1242 void HTMLInputElement::setSize(unsigned size)
1243 {
1244     setUnsignedIntegralAttribute(sizeAttr, size);
1245 }
1246
1247 void HTMLInputElement::setSize(unsigned size, ExceptionCode& ec)
1248 {
1249     if (!size)
1250         ec = INDEX_SIZE_ERR;
1251     else
1252         setSize(size);
1253 }
1254
1255 URL HTMLInputElement::src() const
1256 {
1257     return document().completeURL(fastGetAttribute(srcAttr));
1258 }
1259
1260 void HTMLInputElement::setAutofilled(bool autofilled)
1261 {
1262     if (autofilled == m_isAutofilled)
1263         return;
1264
1265     m_isAutofilled = autofilled;
1266     setNeedsStyleRecalc();
1267 }
1268
1269 FileList* HTMLInputElement::files()
1270 {
1271     return m_inputType->files();
1272 }
1273
1274 void HTMLInputElement::setFiles(PassRefPtr<FileList> files)
1275 {
1276     m_inputType->setFiles(files);
1277 }
1278
1279 #if ENABLE(DRAG_SUPPORT)
1280 bool HTMLInputElement::receiveDroppedFiles(const DragData& dragData)
1281 {
1282     return m_inputType->receiveDroppedFiles(dragData);
1283 }
1284 #endif
1285
1286 Icon* HTMLInputElement::icon() const
1287 {
1288     return m_inputType->icon();
1289 }
1290
1291 #if PLATFORM(IOS)
1292 String HTMLInputElement::displayString() const
1293 {
1294     return m_inputType->displayString();
1295 }
1296 #endif
1297
1298 bool HTMLInputElement::canReceiveDroppedFiles() const
1299 {
1300     return m_canReceiveDroppedFiles;
1301 }
1302
1303 void HTMLInputElement::setCanReceiveDroppedFiles(bool canReceiveDroppedFiles)
1304 {
1305     if (m_canReceiveDroppedFiles == canReceiveDroppedFiles)
1306         return;
1307     m_canReceiveDroppedFiles = canReceiveDroppedFiles;
1308     if (renderer())
1309         renderer()->updateFromElement();
1310 }
1311
1312 String HTMLInputElement::visibleValue() const
1313 {
1314     return m_inputType->visibleValue();
1315 }
1316
1317 String HTMLInputElement::sanitizeValue(const String& proposedValue) const
1318 {
1319     if (proposedValue.isNull())
1320         return proposedValue;
1321     return m_inputType->sanitizeValue(proposedValue);
1322 }
1323
1324 String HTMLInputElement::localizeValue(const String& proposedValue) const
1325 {
1326     if (proposedValue.isNull())
1327         return proposedValue;
1328     return m_inputType->localizeValue(proposedValue);
1329 }
1330
1331 bool HTMLInputElement::isInRange() const
1332 {
1333     return m_inputType->isInRange(value());
1334 }
1335
1336 bool HTMLInputElement::isOutOfRange() const
1337 {
1338     return m_inputType->isOutOfRange(value());
1339 }
1340
1341 bool HTMLInputElement::needsSuspensionCallback()
1342 {
1343     if (m_inputType->shouldResetOnDocumentActivation())
1344         return true;
1345
1346     // Sensitive input elements are marked with autocomplete=off, and we want to wipe them out
1347     // when going back; returning true here arranges for us to call reset at the time
1348     // the page is restored. Non-empty textual default values indicate that the field
1349     // is not really sensitive -- there's no default value for an account number --
1350     // and we would see unexpected results if we reset to something other than blank.
1351     bool isSensitive = m_autocomplete == Off && !(m_inputType->isTextType() && !defaultValue().isEmpty());
1352
1353     return isSensitive;
1354 }
1355
1356 void HTMLInputElement::registerForSuspensionCallbackIfNeeded()
1357 {
1358     if (needsSuspensionCallback())
1359         document().registerForPageCacheSuspensionCallbacks(this);
1360 }
1361
1362 void HTMLInputElement::unregisterForSuspensionCallbackIfNeeded()
1363 {
1364     if (!needsSuspensionCallback())
1365         document().unregisterForPageCacheSuspensionCallbacks(this);
1366 }
1367
1368 bool HTMLInputElement::isRequiredFormControl() const
1369 {
1370     return m_inputType->supportsRequired() && isRequired();
1371 }
1372
1373 bool HTMLInputElement::matchesReadWritePseudoClass() const
1374 {
1375     return m_inputType->supportsReadOnly() && !isDisabledOrReadOnly();
1376 }
1377
1378 void HTMLInputElement::addSearchResult()
1379 {
1380     m_inputType->addSearchResult();
1381 }
1382
1383 void HTMLInputElement::onSearch()
1384 {
1385     ASSERT(isSearchField());
1386     if (m_inputType)
1387         static_cast<SearchInputType*>(m_inputType.get())->stopSearchEventTimer();
1388     dispatchEvent(Event::create(eventNames().searchEvent, true, false));
1389 }
1390
1391 void HTMLInputElement::updateClearButtonVisibility()
1392 {
1393     m_inputType->updateClearButtonVisibility();
1394 }
1395
1396 void HTMLInputElement::documentDidResumeFromPageCache()
1397 {
1398     ASSERT(needsSuspensionCallback());
1399
1400 #if ENABLE(INPUT_TYPE_COLOR)
1401     // <input type=color> uses documentWillSuspendForPageCache to detach the color picker UI,
1402     // so it should not be reset when being loaded from page cache.
1403     if (isColorControl()) 
1404         return;
1405 #endif // ENABLE(INPUT_TYPE_COLOR)
1406     reset();
1407 }
1408
1409 #if ENABLE(INPUT_TYPE_COLOR)
1410 void HTMLInputElement::documentWillSuspendForPageCache()
1411 {
1412     if (!isColorControl())
1413         return;
1414     m_inputType->detach();
1415 }
1416 #endif // ENABLE(INPUT_TYPE_COLOR)
1417
1418
1419 void HTMLInputElement::willChangeForm()
1420 {
1421     removeFromRadioButtonGroup();
1422     HTMLTextFormControlElement::willChangeForm();
1423 }
1424
1425 void HTMLInputElement::didChangeForm()
1426 {
1427     HTMLTextFormControlElement::didChangeForm();
1428     addToRadioButtonGroup();
1429 }
1430
1431 Node::InsertionNotificationRequest HTMLInputElement::insertedInto(ContainerNode& insertionPoint)
1432 {
1433     HTMLTextFormControlElement::insertedInto(insertionPoint);
1434     if (insertionPoint.inDocument() && !form())
1435         addToRadioButtonGroup();
1436 #if ENABLE(DATALIST_ELEMENT)
1437     resetListAttributeTargetObserver();
1438 #endif
1439     return InsertionDone;
1440 }
1441
1442 void HTMLInputElement::removedFrom(ContainerNode& insertionPoint)
1443 {
1444     if (insertionPoint.inDocument() && !form())
1445         removeFromRadioButtonGroup();
1446     HTMLTextFormControlElement::removedFrom(insertionPoint);
1447     ASSERT(!inDocument());
1448 #if ENABLE(DATALIST_ELEMENT)
1449     resetListAttributeTargetObserver();
1450 #endif
1451 }
1452
1453 void HTMLInputElement::didMoveToNewDocument(Document* oldDocument)
1454 {
1455     if (hasImageLoader())
1456         imageLoader()->elementDidMoveToNewDocument();
1457
1458     bool needsSuspensionCallback = this->needsSuspensionCallback();
1459     if (oldDocument) {
1460         // Always unregister for cache callbacks when leaving a document, even if we would otherwise like to be registered
1461         if (needsSuspensionCallback)
1462             oldDocument->unregisterForPageCacheSuspensionCallbacks(this);
1463         if (isRadioButton())
1464             oldDocument->formController().checkedRadioButtons().removeButton(this);
1465 #if ENABLE(TOUCH_EVENTS)
1466         if (m_hasTouchEventHandler)
1467             oldDocument->didRemoveEventTargetNode(this);
1468 #endif
1469     }
1470
1471     if (needsSuspensionCallback)
1472         document().registerForPageCacheSuspensionCallbacks(this);
1473
1474 #if ENABLE(TOUCH_EVENTS)
1475     if (m_hasTouchEventHandler)
1476         document().didAddTouchEventHandler(this);
1477 #endif
1478
1479     HTMLTextFormControlElement::didMoveToNewDocument(oldDocument);
1480 }
1481
1482 void HTMLInputElement::addSubresourceAttributeURLs(ListHashSet<URL>& urls) const
1483 {
1484     HTMLTextFormControlElement::addSubresourceAttributeURLs(urls);
1485
1486     addSubresourceURL(urls, src());
1487 }
1488
1489 bool HTMLInputElement::recalcWillValidate() const
1490 {
1491     return m_inputType->supportsValidation() && HTMLTextFormControlElement::recalcWillValidate();
1492 }
1493
1494 void HTMLInputElement::requiredAttributeChanged()
1495 {
1496     HTMLTextFormControlElement::requiredAttributeChanged();
1497     if (CheckedRadioButtons* buttons = checkedRadioButtons())
1498         buttons->requiredAttributeChanged(this);
1499     m_inputType->requiredAttributeChanged();
1500 }
1501
1502 #if ENABLE(INPUT_TYPE_COLOR)
1503 void HTMLInputElement::selectColorInColorChooser(const Color& color)
1504 {
1505     if (!m_inputType->isColorControl())
1506         return;
1507     static_cast<ColorInputType*>(m_inputType.get())->didChooseColor(color);
1508 }
1509 #endif
1510     
1511 #if ENABLE(DATALIST_ELEMENT)
1512 HTMLElement* HTMLInputElement::list() const
1513 {
1514     return dataList();
1515 }
1516
1517 HTMLDataListElement* HTMLInputElement::dataList() const
1518 {
1519     if (!m_hasNonEmptyList)
1520         return nullptr;
1521
1522     if (!m_inputType->shouldRespectListAttribute())
1523         return nullptr;
1524
1525     Element* element = treeScope().getElementById(fastGetAttribute(listAttr));
1526     if (!is<HTMLDataListElement>(element))
1527         return nullptr;
1528
1529     return downcast<HTMLDataListElement>(element);
1530 }
1531
1532 void HTMLInputElement::resetListAttributeTargetObserver()
1533 {
1534     if (inDocument())
1535         m_listAttributeTargetObserver = std::make_unique<ListAttributeTargetObserver>(fastGetAttribute(listAttr), this);
1536     else
1537         m_listAttributeTargetObserver = nullptr;
1538 }
1539
1540 void HTMLInputElement::listAttributeTargetChanged()
1541 {
1542     m_inputType->listAttributeTargetChanged();
1543 }
1544 #endif // ENABLE(DATALIST_ELEMENT)
1545
1546 bool HTMLInputElement::isSteppable() const
1547 {
1548     return m_inputType->isSteppable();
1549 }
1550
1551 #if PLATFORM(IOS)
1552 DateComponents::Type HTMLInputElement::dateType() const
1553 {
1554     return m_inputType->dateType();
1555 }
1556 #endif
1557
1558 bool HTMLInputElement::isTextButton() const
1559 {
1560     return m_inputType->isTextButton();
1561 }
1562
1563 bool HTMLInputElement::isRadioButton() const
1564 {
1565     return m_inputType->isRadioButton();
1566 }
1567
1568 bool HTMLInputElement::isSearchField() const
1569 {
1570     return m_inputType->isSearchField();
1571 }
1572
1573 bool HTMLInputElement::isInputTypeHidden() const
1574 {
1575     return m_inputType->isHiddenType();
1576 }
1577
1578 bool HTMLInputElement::isPasswordField() const
1579 {
1580     return m_inputType->isPasswordField();
1581 }
1582
1583 bool HTMLInputElement::isCheckbox() const
1584 {
1585     return m_inputType->isCheckbox();
1586 }
1587
1588 bool HTMLInputElement::isRangeControl() const
1589 {
1590     return m_inputType->isRangeControl();
1591 }
1592
1593 #if ENABLE(INPUT_TYPE_COLOR)
1594 bool HTMLInputElement::isColorControl() const
1595 {
1596     return m_inputType->isColorControl();
1597 }
1598 #endif
1599
1600 bool HTMLInputElement::isText() const
1601 {
1602     return m_inputType->isTextType();
1603 }
1604
1605 bool HTMLInputElement::isEmailField() const
1606 {
1607     return m_inputType->isEmailField();
1608 }
1609
1610 bool HTMLInputElement::isFileUpload() const
1611 {
1612     return m_inputType->isFileUpload();
1613 }
1614
1615 bool HTMLInputElement::isImageButton() const
1616 {
1617     return m_inputType->isImageButton();
1618 }
1619
1620 bool HTMLInputElement::isNumberField() const
1621 {
1622     return m_inputType->isNumberField();
1623 }
1624
1625 bool HTMLInputElement::isSubmitButton() const
1626 {
1627     return m_inputType->isSubmitButton();
1628 }
1629
1630 bool HTMLInputElement::isTelephoneField() const
1631 {
1632     return m_inputType->isTelephoneField();
1633 }
1634
1635 bool HTMLInputElement::isURLField() const
1636 {
1637     return m_inputType->isURLField();
1638 }
1639
1640 bool HTMLInputElement::isDateField() const
1641 {
1642     return m_inputType->isDateField();
1643 }
1644
1645 bool HTMLInputElement::isDateTimeField() const
1646 {
1647     return m_inputType->isDateTimeField();
1648 }
1649
1650 bool HTMLInputElement::isDateTimeLocalField() const
1651 {
1652     return m_inputType->isDateTimeLocalField();
1653 }
1654
1655 bool HTMLInputElement::isMonthField() const
1656 {
1657     return m_inputType->isMonthField();
1658 }
1659
1660 bool HTMLInputElement::isTimeField() const
1661 {
1662     return m_inputType->isTimeField();
1663 }
1664
1665 bool HTMLInputElement::isWeekField() const
1666 {
1667     return m_inputType->isWeekField();
1668 }
1669
1670 bool HTMLInputElement::isEnumeratable() const
1671 {
1672     return m_inputType->isEnumeratable();
1673 }
1674
1675 bool HTMLInputElement::supportLabels() const
1676 {
1677     return m_inputType->supportLabels();
1678 }
1679
1680 bool HTMLInputElement::shouldAppearChecked() const
1681 {
1682     return checked() && m_inputType->isCheckable();
1683 }
1684
1685 bool HTMLInputElement::supportsPlaceholder() const
1686 {
1687     return m_inputType->supportsPlaceholder();
1688 }
1689
1690 void HTMLInputElement::updatePlaceholderText()
1691 {
1692     return m_inputType->updatePlaceholderText();
1693 }
1694
1695 void HTMLInputElement::parseMaxLengthAttribute(const AtomicString& value)
1696 {
1697     int maxLength;
1698     if (!parseHTMLInteger(value, maxLength))
1699         maxLength = maximumLength;
1700     if (maxLength < 0 || maxLength > maximumLength)
1701         maxLength = maximumLength;
1702     int oldMaxLength = m_maxLength;
1703     m_maxLength = maxLength;
1704     if (oldMaxLength != maxLength)
1705         updateValueIfNeeded();
1706     setNeedsStyleRecalc();
1707     setNeedsValidityCheck();
1708 }
1709
1710 void HTMLInputElement::updateValueIfNeeded()
1711 {
1712     String newValue = sanitizeValue(m_valueIfDirty);
1713     ASSERT(!m_valueIfDirty.isNull() || newValue.isNull());
1714     if (newValue != m_valueIfDirty)
1715         setValue(newValue);
1716 }
1717
1718 String HTMLInputElement::defaultToolTip() const
1719 {
1720     return m_inputType->defaultToolTip();
1721 }
1722
1723 bool HTMLInputElement::shouldAppearIndeterminate() const 
1724 {
1725     return m_inputType->supportsIndeterminateAppearance() && indeterminate();
1726 }
1727
1728 #if ENABLE(MEDIA_CAPTURE)
1729 bool HTMLInputElement::shouldUseMediaCapture() const
1730 {
1731     return isFileUpload() && fastHasAttribute(captureAttr);
1732 }
1733 #endif
1734
1735 bool HTMLInputElement::isInRequiredRadioButtonGroup()
1736 {
1737     ASSERT(isRadioButton());
1738     if (CheckedRadioButtons* buttons = checkedRadioButtons())
1739         return buttons->isInRequiredGroup(this);
1740     return false;
1741 }
1742
1743 HTMLInputElement* HTMLInputElement::checkedRadioButtonForGroup() const
1744 {
1745     if (CheckedRadioButtons* buttons = checkedRadioButtons())
1746         return buttons->checkedButtonForGroup(name());
1747     return 0;
1748 }
1749
1750 CheckedRadioButtons* HTMLInputElement::checkedRadioButtons() const
1751 {
1752     if (!isRadioButton())
1753         return 0;
1754     if (HTMLFormElement* formElement = form())
1755         return &formElement->checkedRadioButtons();
1756     if (inDocument())
1757         return &document().formController().checkedRadioButtons();
1758     return 0;
1759 }
1760
1761 inline void HTMLInputElement::addToRadioButtonGroup()
1762 {
1763     if (CheckedRadioButtons* buttons = checkedRadioButtons())
1764         buttons->addButton(this);
1765 }
1766
1767 inline void HTMLInputElement::removeFromRadioButtonGroup()
1768 {
1769     if (CheckedRadioButtons* buttons = checkedRadioButtons())
1770         buttons->removeButton(this);
1771 }
1772
1773 unsigned HTMLInputElement::height() const
1774 {
1775     return m_inputType->height();
1776 }
1777
1778 unsigned HTMLInputElement::width() const
1779 {
1780     return m_inputType->width();
1781 }
1782
1783 void HTMLInputElement::setHeight(unsigned height)
1784 {
1785     setUnsignedIntegralAttribute(heightAttr, height);
1786 }
1787
1788 void HTMLInputElement::setWidth(unsigned width)
1789 {
1790     setUnsignedIntegralAttribute(widthAttr, width);
1791 }
1792
1793 #if ENABLE(DATALIST_ELEMENT)
1794 ListAttributeTargetObserver::ListAttributeTargetObserver(const AtomicString& id, HTMLInputElement* element)
1795     : IdTargetObserver(element->treeScope().idTargetObserverRegistry(), id)
1796     , m_element(element)
1797 {
1798 }
1799
1800 void ListAttributeTargetObserver::idTargetChanged()
1801 {
1802     m_element->listAttributeTargetChanged();
1803 }
1804 #endif
1805
1806 void HTMLInputElement::setRangeText(const String& replacement, ExceptionCode& ec)
1807 {
1808     if (!m_inputType->supportsSelectionAPI()) {
1809         ec = INVALID_STATE_ERR;
1810         return;
1811     }
1812
1813     HTMLTextFormControlElement::setRangeText(replacement, ec);
1814 }
1815
1816 void HTMLInputElement::setRangeText(const String& replacement, unsigned start, unsigned end, const String& selectionMode, ExceptionCode& ec)
1817 {
1818     if (!m_inputType->supportsSelectionAPI()) {
1819         ec = INVALID_STATE_ERR;
1820         return;
1821     }
1822
1823     HTMLTextFormControlElement::setRangeText(replacement, start, end, selectionMode, ec);
1824 }
1825
1826 #if ENABLE(DATE_AND_TIME_INPUT_TYPES)
1827 bool HTMLInputElement::setupDateTimeChooserParameters(DateTimeChooserParameters& parameters)
1828 {
1829     if (!document().view())
1830         return false;
1831
1832     parameters.type = type();
1833     parameters.minimum = minimum();
1834     parameters.maximum = maximum();
1835     parameters.required = isRequired();
1836     if (!RuntimeEnabledFeatures::sharedFeatures().langAttributeAwareFormControlUIEnabled())
1837         parameters.locale = defaultLanguage();
1838     else {
1839         AtomicString computedLocale = computeInheritedLanguage();
1840         parameters.locale = computedLocale.isEmpty() ? AtomicString(defaultLanguage()) : computedLocale;
1841     }
1842
1843     StepRange stepRange = createStepRange(RejectAny);
1844     if (stepRange.hasStep()) {
1845         parameters.step = stepRange.step().toDouble();
1846         parameters.stepBase = stepRange.stepBase().toDouble();
1847     } else {
1848         parameters.step = 1.0;
1849         parameters.stepBase = 0;
1850     }
1851
1852     parameters.anchorRectInRootView = document().view()->contentsToRootView(pixelSnappedBoundingBox());
1853     parameters.currentValue = value();
1854     parameters.isAnchorElementRTL = computedStyle()->direction() == RTL;
1855 #if ENABLE(DATALIST_ELEMENT)
1856     if (HTMLDataListElement* dataList = this->dataList()) {
1857         RefPtr<HTMLCollection> options = dataList->options();
1858         for (unsigned i = 0; HTMLOptionElement* option = downcast<HTMLOptionElement>(options->item(i)); ++i) {
1859             if (!isValidValue(option->value()))
1860                 continue;
1861             parameters.suggestionValues.append(sanitizeValue(option->value()));
1862             parameters.localizedSuggestionValues.append(localizeValue(option->value()));
1863             parameters.suggestionLabels.append(option->value() == option->label() ? String() : option->label());
1864         }
1865     }
1866 #endif
1867     return true;
1868 }
1869 #endif
1870
1871 } // namespace