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