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