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