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 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Library General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 * Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU Library General Public License
21 * along with this library; see the file COPYING.LIB.  If not, write to
22 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301, USA.
24 *
25 */
26
27#include "config.h"
28#include "HTMLInputElement.h"
29
30#include "AXObjectCache.h"
31#include "Attribute.h"
32#include "BeforeTextInsertedEvent.h"
33#include "CSSPropertyNames.h"
34#include "Document.h"
35#include "EventNames.h"
36#include "ExceptionCode.h"
37#include "FileList.h"
38#include "HTMLCollection.h"
39#include "HTMLDataListElement.h"
40#include "HTMLFormElement.h"
41#include "HTMLNames.h"
42#include "HTMLOptionElement.h"
43#include "HTMLParserIdioms.h"
44#include "InputType.h"
45#include "KeyboardEvent.h"
46#include "LocalizedStrings.h"
47#include "MouseEvent.h"
48#include "PlatformMouseEvent.h"
49#include "RenderTextControlSingleLine.h"
50#include "RenderTheme.h"
51#include "RuntimeEnabledFeatures.h"
52#include "ScriptEventListener.h"
53#include "WheelEvent.h"
54#include <wtf/MathExtras.h>
55#include <wtf/StdLibExtras.h>
56
57#ifdef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS
58#include "PlatformBridge.h"
59#endif
60
61#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
62#include "TouchEvent.h"
63#endif
64
65using namespace std;
66
67namespace WebCore {
68
69using namespace HTMLNames;
70
71const int maxSavedResults = 256;
72
73HTMLInputElement::HTMLInputElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form, bool createdByParser)
74    : HTMLTextFormControlElement(tagName, document, form)
75    , m_maxResults(-1)
76    , m_isChecked(false)
77    , m_reflectsCheckedAttribute(true)
78    , m_isIndeterminate(false)
79    , m_hasType(false)
80    , m_isActivatedSubmit(false)
81    , m_autocomplete(Uninitialized)
82    , m_isAutofilled(false)
83    , m_stateRestored(false)
84    , m_parsingInProgress(createdByParser)
85    , m_inputType(InputType::createText(this))
86{
87    ASSERT(hasTagName(inputTag) || hasTagName(isindexTag));
88}
89
90PassRefPtr<HTMLInputElement> HTMLInputElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form, bool createdByParser)
91{
92    return adoptRef(new HTMLInputElement(tagName, document, form, createdByParser));
93}
94
95HTMLInputElement::~HTMLInputElement()
96{
97    if (needsActivationCallback())
98        document()->unregisterForDocumentActivationCallbacks(this);
99
100    document()->checkedRadioButtons().removeButton(this);
101
102    // Need to remove this from the form while it is still an HTMLInputElement,
103    // so can't wait for the base class's destructor to do it.
104    removeFromForm();
105}
106
107const AtomicString& HTMLInputElement::formControlName() const
108{
109    return m_data.name();
110}
111
112bool HTMLInputElement::autoComplete() const
113{
114    if (m_autocomplete != Uninitialized)
115        return m_autocomplete == On;
116    return HTMLTextFormControlElement::autoComplete();
117}
118
119void HTMLInputElement::updateCheckedRadioButtons()
120{
121    if (attached() && checked())
122        checkedRadioButtons().addButton(this);
123
124    if (form()) {
125        const Vector<FormAssociatedElement*>& controls = form()->associatedElements();
126        for (unsigned i = 0; i < controls.size(); ++i) {
127            if (!controls[i]->isFormControlElement())
128                continue;
129            HTMLFormControlElement* control = static_cast<HTMLFormControlElement*>(controls[i]);
130            if (control->name() != name())
131                continue;
132            if (control->type() != type())
133                continue;
134            control->setNeedsValidityCheck();
135        }
136    } else {
137        // FIXME: Traversing the document is inefficient.
138        for (Node* node = document()->body(); node; node = node->traverseNextNode()) {
139            if (!node->isElementNode())
140                continue;
141            Element* element = static_cast<Element*>(node);
142            if (element->formControlName() != name())
143                continue;
144            if (element->formControlType() != type())
145                continue;
146            HTMLFormControlElement* control = static_cast<HTMLFormControlElement*>(element);
147            if (control->form())
148                continue;
149            control->setNeedsValidityCheck();
150        }
151    }
152
153    if (renderer() && renderer()->style()->hasAppearance())
154        renderer()->theme()->stateChanged(renderer(), CheckedState);
155}
156
157bool HTMLInputElement::lastChangeWasUserEdit() const
158{
159    if (!isTextField())
160        return false;
161
162    if (!renderer())
163        return false;
164
165    return toRenderTextControl(renderer())->lastChangeWasUserEdit();
166}
167
168bool HTMLInputElement::isValidValue(const String& value) const
169{
170    if (!m_inputType->canSetStringValue()) {
171        ASSERT_NOT_REACHED();
172        return false;
173    }
174    return !m_inputType->typeMismatchFor(value)
175        && !stepMismatch(value)
176        && !rangeUnderflow(value)
177        && !rangeOverflow(value)
178        && !tooLong(value, IgnoreDirtyFlag)
179        && !patternMismatch(value)
180        && !valueMissing(value);
181}
182
183bool HTMLInputElement::typeMismatch() const
184{
185    return m_inputType->typeMismatch();
186}
187
188bool HTMLInputElement::valueMissing(const String& value) const
189{
190    if (!isRequiredFormControl() || readOnly() || disabled())
191        return false;
192    return m_inputType->valueMissing(value);
193}
194
195bool HTMLInputElement::patternMismatch(const String& value) const
196{
197    return m_inputType->patternMismatch(value);
198}
199
200bool HTMLInputElement::tooLong(const String& value, NeedsToCheckDirtyFlag check) const
201{
202    // We use isTextType() instead of supportsMaxLength() because of the
203    // 'virtual' overhead.
204    if (!isTextType())
205        return false;
206    int max = maxLength();
207    if (max < 0)
208        return false;
209    if (check == CheckDirtyFlag) {
210        // Return false for the default value even if it is longer than maxLength.
211        bool userEdited = !m_data.value().isNull();
212        if (!userEdited)
213            return false;
214    }
215    return numGraphemeClusters(value) > static_cast<unsigned>(max);
216}
217
218bool HTMLInputElement::rangeUnderflow(const String& value) const
219{
220    return m_inputType->rangeUnderflow(value);
221}
222
223bool HTMLInputElement::rangeOverflow(const String& value) const
224{
225    return m_inputType->rangeOverflow(value);
226}
227
228double HTMLInputElement::minimum() const
229{
230    return m_inputType->minimum();
231}
232
233double HTMLInputElement::maximum() const
234{
235    return m_inputType->maximum();
236}
237
238bool HTMLInputElement::stepMismatch(const String& value) const
239{
240    double step;
241    if (!getAllowedValueStep(&step))
242        return false;
243    return m_inputType->stepMismatch(value, step);
244}
245
246String HTMLInputElement::minimumString() const
247{
248    return m_inputType->serialize(minimum());
249}
250
251String HTMLInputElement::maximumString() const
252{
253    return m_inputType->serialize(maximum());
254}
255
256String HTMLInputElement::stepBaseString() const
257{
258    return m_inputType->serialize(m_inputType->stepBase());
259}
260
261String HTMLInputElement::stepString() const
262{
263    double step;
264    if (!getAllowedValueStep(&step)) {
265        // stepString() should be called only if stepMismatch() can be true.
266        ASSERT_NOT_REACHED();
267        return String();
268    }
269    return serializeForNumberType(step / m_inputType->stepScaleFactor());
270}
271
272String HTMLInputElement::typeMismatchText() const
273{
274    return m_inputType->typeMismatchText();
275}
276
277String HTMLInputElement::valueMissingText() const
278{
279    return m_inputType->valueMissingText();
280}
281
282bool HTMLInputElement::getAllowedValueStep(double* step) const
283{
284    return getAllowedValueStepWithDecimalPlaces(step, 0);
285}
286
287bool HTMLInputElement::getAllowedValueStepWithDecimalPlaces(double* step, unsigned* decimalPlaces) const
288{
289    ASSERT(step);
290    double defaultStep = m_inputType->defaultStep();
291    double stepScaleFactor = m_inputType->stepScaleFactor();
292    if (!isfinite(defaultStep) || !isfinite(stepScaleFactor))
293        return false;
294    const AtomicString& stepString = fastGetAttribute(stepAttr);
295    if (stepString.isEmpty()) {
296        *step = defaultStep * stepScaleFactor;
297        if (decimalPlaces)
298            *decimalPlaces = 0;
299        return true;
300    }
301    if (equalIgnoringCase(stepString, "any"))
302        return false;
303    double parsed;
304    if (!decimalPlaces) {
305        if (!parseToDoubleForNumberType(stepString, &parsed) || parsed <= 0.0) {
306            *step = defaultStep * stepScaleFactor;
307            return true;
308        }
309    } else {
310        if (!parseToDoubleForNumberTypeWithDecimalPlaces(stepString, &parsed, decimalPlaces) || parsed <= 0.0) {
311            *step = defaultStep * stepScaleFactor;
312            *decimalPlaces = 0;
313            return true;
314        }
315    }
316    // For date, month, week, the parsed value should be an integer for some types.
317    if (m_inputType->parsedStepValueShouldBeInteger())
318        parsed = max(round(parsed), 1.0);
319    double result = parsed * stepScaleFactor;
320    // For datetime, datetime-local, time, the result should be an integer.
321    if (m_inputType->scaledStepValueShouldBeInteger())
322        result = max(round(result), 1.0);
323    ASSERT(result > 0);
324    *step = result;
325    return true;
326}
327
328void HTMLInputElement::applyStep(double count, ExceptionCode& ec)
329{
330    double step;
331    unsigned stepDecimalPlaces, currentDecimalPlaces;
332    if (!getAllowedValueStepWithDecimalPlaces(&step, &stepDecimalPlaces)) {
333        ec = INVALID_STATE_ERR;
334        return;
335    }
336    const double nan = numeric_limits<double>::quiet_NaN();
337    double current = m_inputType->parseToDoubleWithDecimalPlaces(value(), nan, &currentDecimalPlaces);
338    if (!isfinite(current)) {
339        ec = INVALID_STATE_ERR;
340        return;
341    }
342    double newValue = current + step * count;
343    if (isinf(newValue)) {
344        ec = INVALID_STATE_ERR;
345        return;
346    }
347    double acceptableError = m_inputType->acceptableError(step);
348    if (newValue - m_inputType->minimum() < -acceptableError) {
349        ec = INVALID_STATE_ERR;
350        return;
351    }
352    if (newValue < m_inputType->minimum())
353        newValue = m_inputType->minimum();
354    unsigned baseDecimalPlaces;
355    double base = m_inputType->stepBaseWithDecimalPlaces(&baseDecimalPlaces);
356    baseDecimalPlaces = min(baseDecimalPlaces, 16u);
357    if (newValue < pow(10.0, 21.0)) {
358      if (stepMismatch(value())) {
359            double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, currentDecimalPlaces)));
360            newValue = round(newValue * scale) / scale;
361        } else {
362            double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces)));
363            newValue = round((base + round((newValue - base) / step) * step) * scale) / scale;
364        }
365    }
366    if (newValue - m_inputType->maximum() > acceptableError) {
367        ec = INVALID_STATE_ERR;
368        return;
369    }
370    if (newValue > m_inputType->maximum())
371        newValue = m_inputType->maximum();
372    setValueAsNumber(newValue, ec);
373
374    if (AXObjectCache::accessibilityEnabled())
375         document()->axObjectCache()->postNotification(renderer(), AXObjectCache::AXValueChanged, true);
376}
377
378void HTMLInputElement::stepUp(int n, ExceptionCode& ec)
379{
380    applyStep(n, ec);
381}
382
383void HTMLInputElement::stepDown(int n, ExceptionCode& ec)
384{
385    applyStep(-n, ec);
386}
387
388bool HTMLInputElement::isKeyboardFocusable(KeyboardEvent* event) const
389{
390    if (isTextField())
391        return HTMLFormControlElementWithState::isFocusable();
392    return HTMLFormControlElementWithState::isKeyboardFocusable(event) && m_inputType->isKeyboardFocusable();
393}
394
395bool HTMLInputElement::isMouseFocusable() const
396{
397    if (isTextField())
398        return HTMLFormControlElementWithState::isFocusable();
399    return HTMLFormControlElementWithState::isMouseFocusable();
400}
401
402void HTMLInputElement::updateFocusAppearance(bool restorePreviousSelection)
403{
404    if (isTextField())
405        InputElement::updateFocusAppearance(m_data, this, this, restorePreviousSelection);
406    else
407        HTMLFormControlElementWithState::updateFocusAppearance(restorePreviousSelection);
408}
409
410void HTMLInputElement::aboutToUnload()
411{
412    InputElement::aboutToUnload(this, this);
413}
414
415bool HTMLInputElement::shouldUseInputMethod() const
416{
417    return m_inputType->shouldUseInputMethod();
418}
419
420void HTMLInputElement::handleFocusEvent()
421{
422    InputElement::dispatchFocusEvent(this, this);
423}
424
425void HTMLInputElement::handleBlurEvent()
426{
427    m_inputType->handleBlurEvent();
428    InputElement::dispatchBlurEvent(this, this);
429}
430
431void HTMLInputElement::setType(const String& type)
432{
433    // FIXME: This should just call setAttribute. No reason to handle the empty string specially.
434    // We should write a test case to show that setting to the empty string does not remove the
435    // attribute in other browsers and then fix this. Note that setting to null *does* remove
436    // the attribute and setAttribute implements that.
437    if (type.isEmpty()) {
438        ExceptionCode ec;
439        removeAttribute(typeAttr, ec);
440    } else
441        setAttribute(typeAttr, type);
442}
443
444void HTMLInputElement::updateType()
445{
446    OwnPtr<InputType> newType = InputType::create(this, fastGetAttribute(typeAttr));
447#ifdef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS
448    if (newType->isPasswordField() && document()->focusedNode() == this)
449        PlatformBridge::updateTextfield(document()->view(), this, true, String());
450#endif
451    bool hadType = m_hasType;
452    m_hasType = true;
453    if (m_inputType->formControlType() == newType->formControlType())
454        return;
455
456    if (hadType && !newType->canChangeFromAnotherType()) {
457        // Set the attribute back to the old value.
458        // Useful in case we were called from inside parseMappedAttribute.
459        setAttribute(typeAttr, type());
460        return;
461    }
462
463    checkedRadioButtons().removeButton(this);
464
465    bool wasAttached = attached();
466    if (wasAttached)
467        detach();
468
469    bool didStoreValue = m_inputType->storesValueSeparateFromAttribute();
470    bool neededActivationCallback = needsActivationCallback();
471    bool didRespectHeightAndWidth = m_inputType->shouldRespectHeightAndWidthAttributes();
472
473    m_inputType->destroyShadowSubtree();
474    m_inputType = newType.release();
475    m_inputType->createShadowSubtree();
476
477    setNeedsWillValidateCheck();
478
479    bool willStoreValue = m_inputType->storesValueSeparateFromAttribute();
480
481    if (didStoreValue && !willStoreValue && !m_data.value().isNull()) {
482        setAttribute(valueAttr, m_data.value());
483        m_data.setValue(String());
484    }
485    if (!didStoreValue && willStoreValue)
486        m_data.setValue(sanitizeValue(fastGetAttribute(valueAttr)));
487    else
488        InputElement::updateValueIfNeeded(m_data, this);
489
490    if (neededActivationCallback)
491        unregisterForActivationCallbackIfNeeded();
492    else
493        registerForActivationCallbackIfNeeded();
494
495    if (didRespectHeightAndWidth != m_inputType->shouldRespectHeightAndWidthAttributes()) {
496        NamedNodeMap* map = attributeMap();
497        ASSERT(map);
498        if (Attribute* height = map->getAttributeItem(heightAttr))
499            attributeChanged(height, false);
500        if (Attribute* width = map->getAttributeItem(widthAttr))
501            attributeChanged(width, false);
502        if (Attribute* align = map->getAttributeItem(alignAttr))
503            attributeChanged(align, false);
504    }
505
506    if (wasAttached) {
507        attach();
508        if (document()->focusedNode() == this)
509            updateFocusAppearance(true);
510    }
511
512    setChangedSinceLastFormControlChangeEvent(false);
513
514    checkedRadioButtons().addButton(this);
515
516    setNeedsValidityCheck();
517    InputElement::notifyFormStateChanged(this);
518}
519
520const AtomicString& HTMLInputElement::formControlType() const
521{
522    return m_inputType->formControlType();
523}
524
525bool HTMLInputElement::saveFormControlState(String& result) const
526{
527    return m_inputType->saveFormControlState(result);
528}
529
530void HTMLInputElement::restoreFormControlState(const String& state)
531{
532    m_inputType->restoreFormControlState(state);
533    m_stateRestored = true;
534}
535
536bool HTMLInputElement::canStartSelection() const
537{
538    if (!isTextField())
539        return false;
540    return HTMLFormControlElementWithState::canStartSelection();
541}
542
543bool HTMLInputElement::canHaveSelection() const
544{
545    return isTextField();
546}
547
548void HTMLInputElement::accessKeyAction(bool sendToAnyElement)
549{
550    m_inputType->accessKeyAction(sendToAnyElement);
551}
552
553bool HTMLInputElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
554{
555    if (((attrName == heightAttr || attrName == widthAttr) && m_inputType->shouldRespectHeightAndWidthAttributes())
556        || attrName == vspaceAttr
557        || attrName == hspaceAttr) {
558        result = eUniversal;
559        return false;
560    }
561
562    if (attrName == alignAttr && m_inputType->shouldRespectAlignAttribute()) {
563        // Share with <img> since the alignment behavior is the same.
564        result = eReplaced;
565        return false;
566    }
567
568    return HTMLElement::mapToEntry(attrName, result);
569}
570
571void HTMLInputElement::parseMappedAttribute(Attribute* attr)
572{
573    if (attr->name() == nameAttr) {
574        checkedRadioButtons().removeButton(this);
575        m_data.setName(attr->value());
576        checkedRadioButtons().addButton(this);
577        HTMLFormControlElementWithState::parseMappedAttribute(attr);
578    } else if (attr->name() == autocompleteAttr) {
579        if (equalIgnoringCase(attr->value(), "off")) {
580            m_autocomplete = Off;
581            registerForActivationCallbackIfNeeded();
582        } else {
583            bool needsToUnregister = m_autocomplete == Off;
584
585            if (attr->isEmpty())
586                m_autocomplete = Uninitialized;
587            else
588                m_autocomplete = On;
589
590            if (needsToUnregister)
591                unregisterForActivationCallbackIfNeeded();
592        }
593    } else if (attr->name() == typeAttr) {
594        updateType();
595    } else if (attr->name() == valueAttr) {
596        // We only need to setChanged if the form is looking at the default value right now.
597        if (m_data.value().isNull())
598            setNeedsStyleRecalc();
599        setFormControlValueMatchesRenderer(false);
600        setNeedsValidityCheck();
601    } else if (attr->name() == checkedAttr) {
602        // Another radio button in the same group might be checked by state
603        // restore. We shouldn't call setChecked() even if this has the checked
604        // attribute. So, delay the setChecked() call until
605        // finishParsingChildren() is called if parsing is in progress.
606        if (!m_parsingInProgress && m_reflectsCheckedAttribute) {
607            setChecked(!attr->isNull());
608            m_reflectsCheckedAttribute = true;
609        }
610    } else if (attr->name() == maxlengthAttr) {
611        InputElement::parseMaxLengthAttribute(m_data, this, this, attr);
612        setNeedsValidityCheck();
613    } else if (attr->name() == sizeAttr)
614        InputElement::parseSizeAttribute(m_data, this, attr);
615    else if (attr->name() == altAttr)
616        m_inputType->altAttributeChanged();
617    else if (attr->name() == srcAttr)
618        m_inputType->srcAttributeChanged();
619    else if (attr->name() == usemapAttr || attr->name() == accesskeyAttr) {
620        // FIXME: ignore for the moment
621    } else if (attr->name() == vspaceAttr) {
622        addCSSLength(attr, CSSPropertyMarginTop, attr->value());
623        addCSSLength(attr, CSSPropertyMarginBottom, attr->value());
624    } else if (attr->name() == hspaceAttr) {
625        addCSSLength(attr, CSSPropertyMarginLeft, attr->value());
626        addCSSLength(attr, CSSPropertyMarginRight, attr->value());
627    } else if (attr->name() == alignAttr) {
628        if (m_inputType->shouldRespectAlignAttribute())
629            addHTMLAlignment(attr);
630    } else if (attr->name() == widthAttr) {
631        if (m_inputType->shouldRespectHeightAndWidthAttributes())
632            addCSSLength(attr, CSSPropertyWidth, attr->value());
633    } else if (attr->name() == heightAttr) {
634        if (m_inputType->shouldRespectHeightAndWidthAttributes())
635            addCSSLength(attr, CSSPropertyHeight, attr->value());
636    } else if (attr->name() == onsearchAttr) {
637        // Search field and slider attributes all just cause updateFromElement to be called through style recalcing.
638        setAttributeEventListener(eventNames().searchEvent, createAttributeEventListener(this, attr));
639    } else if (attr->name() == resultsAttr) {
640        int oldResults = m_maxResults;
641        m_maxResults = !attr->isNull() ? std::min(attr->value().toInt(), maxSavedResults) : -1;
642        // FIXME: Detaching just for maxResults change is not ideal.  We should figure out the right
643        // time to relayout for this change.
644        if (m_maxResults != oldResults && (m_maxResults <= 0 || oldResults <= 0) && attached()) {
645            detach();
646            attach();
647        }
648        setNeedsStyleRecalc();
649    } else if (attr->name() == autosaveAttr || attr->name() == incrementalAttr)
650        setNeedsStyleRecalc();
651    else if (attr->name() == minAttr || attr->name() == maxAttr) {
652        m_inputType->minOrMaxAttributeChanged();
653        setNeedsValidityCheck();
654    } else if (attr->name() == multipleAttr || attr->name() == patternAttr || attr->name() == precisionAttr || attr->name() == stepAttr)
655        setNeedsValidityCheck();
656#if ENABLE(DATALIST)
657    else if (attr->name() == listAttr)
658        m_hasNonEmptyList = !attr->isEmpty();
659        // FIXME: we need to tell this change to a renderer if the attribute affects the appearance.
660#endif
661#if ENABLE(INPUT_SPEECH)
662    else if (attr->name() == webkitspeechAttr) {
663        if (renderer()) {
664            // This renderer and its children have quite different layouts and styles depending on
665            // whether the speech button is visible or not. So we reset the whole thing and recreate
666            // to get the right styles and layout.
667            detach();
668            attach();
669        }
670        setNeedsStyleRecalc();
671    } else if (attr->name() == onwebkitspeechchangeAttr)
672        setAttributeEventListener(eventNames().webkitspeechchangeEvent, createAttributeEventListener(this, attr));
673#endif
674    else
675        HTMLTextFormControlElement::parseMappedAttribute(attr);
676}
677
678void HTMLInputElement::finishParsingChildren()
679{
680    m_parsingInProgress = false;
681    HTMLFormControlElementWithState::finishParsingChildren();
682    if (!m_stateRestored) {
683        bool checked = hasAttribute(checkedAttr);
684        if (checked)
685            setChecked(checked);
686        m_reflectsCheckedAttribute = true;
687    }
688}
689
690bool HTMLInputElement::rendererIsNeeded(RenderStyle* style)
691{
692    return m_inputType->rendererIsNeeded() && HTMLFormControlElementWithState::rendererIsNeeded(style);
693}
694
695RenderObject* HTMLInputElement::createRenderer(RenderArena* arena, RenderStyle* style)
696{
697    return m_inputType->createRenderer(arena, style);
698}
699
700void HTMLInputElement::attach()
701{
702    suspendPostAttachCallbacks();
703
704    if (!m_hasType)
705        updateType();
706
707    HTMLFormControlElementWithState::attach();
708
709    m_inputType->attach();
710
711    if (document()->focusedNode() == this)
712        document()->updateFocusAppearanceSoon(true /* restore selection */);
713
714    resumePostAttachCallbacks();
715}
716
717void HTMLInputElement::detach()
718{
719    HTMLFormControlElementWithState::detach();
720    setFormControlValueMatchesRenderer(false);
721}
722
723String HTMLInputElement::altText() const
724{
725    // http://www.w3.org/TR/1998/REC-html40-19980424/appendix/notes.html#altgen
726    // also heavily discussed by Hixie on bugzilla
727    // note this is intentionally different to HTMLImageElement::altText()
728    String alt = fastGetAttribute(altAttr);
729    // fall back to title attribute
730    if (alt.isNull())
731        alt = getAttribute(titleAttr);
732    if (alt.isNull())
733        alt = getAttribute(valueAttr);
734    if (alt.isEmpty())
735        alt = inputElementAltText();
736    return alt;
737}
738
739bool HTMLInputElement::isSuccessfulSubmitButton() const
740{
741    // HTML spec says that buttons must have names to be considered successful.
742    // However, other browsers do not impose this constraint. So we do not.
743    return !disabled() && m_inputType->canBeSuccessfulSubmitButton();
744}
745
746bool HTMLInputElement::isActivatedSubmit() const
747{
748    return m_isActivatedSubmit;
749}
750
751void HTMLInputElement::setActivatedSubmit(bool flag)
752{
753    m_isActivatedSubmit = flag;
754}
755
756bool HTMLInputElement::appendFormData(FormDataList& encoding, bool multipart)
757{
758    return m_inputType->isFormDataAppendable() && m_inputType->appendFormData(encoding, multipart);
759}
760
761void HTMLInputElement::reset()
762{
763    if (m_inputType->storesValueSeparateFromAttribute())
764        setValue(String());
765
766    setAutofilled(false);
767    setChecked(hasAttribute(checkedAttr));
768    m_reflectsCheckedAttribute = true;
769}
770
771bool HTMLInputElement::isTextField() const
772{
773    return m_inputType->isTextField();
774}
775
776bool HTMLInputElement::isTextType() const
777{
778    return m_inputType->isTextType();
779}
780
781void HTMLInputElement::setChecked(bool nowChecked, bool sendChangeEvent)
782{
783    if (checked() == nowChecked)
784        return;
785
786    checkedRadioButtons().removeButton(this);
787
788    m_reflectsCheckedAttribute = false;
789    m_isChecked = nowChecked;
790    setNeedsStyleRecalc();
791
792    updateCheckedRadioButtons();
793    setNeedsValidityCheck();
794
795    // Ideally we'd do this from the render tree (matching
796    // RenderTextView), but it's not possible to do it at the moment
797    // because of the way the code is structured.
798    if (renderer() && AXObjectCache::accessibilityEnabled())
799        renderer()->document()->axObjectCache()->postNotification(renderer(), AXObjectCache::AXCheckedStateChanged, true);
800
801    // Only send a change event for items in the document (avoid firing during
802    // parsing) and don't send a change event for a radio button that's getting
803    // unchecked to match other browsers. DOM is not a useful standard for this
804    // because it says only to fire change events at "lose focus" time, which is
805    // definitely wrong in practice for these types of elements.
806    if (sendChangeEvent && inDocument() && m_inputType->shouldSendChangeEventAfterCheckedChanged()) {
807        setTextAsOfLastFormControlChangeEvent(String());
808        dispatchFormControlChangeEvent();
809    }
810}
811
812void HTMLInputElement::setIndeterminate(bool newValue)
813{
814    if (!m_inputType->isCheckable() || indeterminate() == newValue)
815        return;
816
817    m_isIndeterminate = newValue;
818
819    setNeedsStyleRecalc();
820
821    if (renderer() && renderer()->style()->hasAppearance())
822        renderer()->theme()->stateChanged(renderer(), CheckedState);
823}
824
825int HTMLInputElement::size() const
826{
827    return m_data.size();
828}
829
830void HTMLInputElement::copyNonAttributeProperties(const Element* source)
831{
832    const HTMLInputElement* sourceElement = static_cast<const HTMLInputElement*>(source);
833
834    m_data.setValue(sourceElement->m_data.value());
835    setChecked(sourceElement->m_isChecked);
836    m_reflectsCheckedAttribute = sourceElement->m_reflectsCheckedAttribute;
837    m_isIndeterminate = sourceElement->m_isIndeterminate;
838
839    HTMLFormControlElementWithState::copyNonAttributeProperties(source);
840}
841
842String HTMLInputElement::value() const
843{
844    String value;
845    if (m_inputType->getTypeSpecificValue(value))
846        return value;
847
848    value = m_data.value();
849    if (!value.isNull())
850        return value;
851
852    value = sanitizeValue(fastGetAttribute(valueAttr));
853    if (!value.isNull())
854        return value;
855
856    return m_inputType->fallbackValue();
857}
858
859String HTMLInputElement::valueWithDefault() const
860{
861    String value = this->value();
862    if (!value.isNull())
863        return value;
864
865    return m_inputType->defaultValue();
866}
867
868void HTMLInputElement::setValueForUser(const String& value)
869{
870    // Call setValue and make it send a change event.
871    setValue(value, true);
872}
873
874const String& HTMLInputElement::suggestedValue() const
875{
876    return m_data.suggestedValue();
877}
878
879void HTMLInputElement::setSuggestedValue(const String& value)
880{
881    if (!m_inputType->canSetSuggestedValue())
882        return;
883    setFormControlValueMatchesRenderer(false);
884    m_data.setSuggestedValue(sanitizeValue(value));
885    updatePlaceholderVisibility(false);
886    if (renderer())
887        renderer()->updateFromElement();
888    setNeedsStyleRecalc();
889}
890
891void HTMLInputElement::setValue(const String& value, bool sendChangeEvent)
892{
893    if (!m_inputType->canSetValue(value))
894        return;
895
896    setFormControlValueMatchesRenderer(false);
897    if (m_inputType->storesValueSeparateFromAttribute()) {
898        if (files())
899            files()->clear();
900        else {
901            m_data.setValue(sanitizeValue(value));
902            if (isTextField())
903                updatePlaceholderVisibility(false);
904        }
905        setNeedsStyleRecalc();
906    } else
907        setAttribute(valueAttr, sanitizeValue(value));
908
909    setNeedsValidityCheck();
910
911    if (isTextField()) {
912        unsigned max = m_data.value().length();
913#ifdef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS
914        // Make sure our UI side textfield changes to match the RenderTextControl
915        PlatformBridge::updateTextfield(document()->view(), this, false, value);
916#endif
917        if (document()->focusedNode() == this)
918            InputElement::updateSelectionRange(this, this, max, max);
919        else
920            cacheSelection(max, max);
921        m_data.setSuggestedValue(String());
922    }
923    m_inputType->valueChanged();
924
925    if (sendChangeEvent) {
926        // If the user is still editing this field, dispatch an input event rather than a change event.
927        // The change event will be dispatched when editing finishes.
928        if (isTextField() && focused())
929            dispatchFormControlInputEvent();
930        else
931            dispatchFormControlChangeEvent();
932    }
933
934    if (isText() && (!focused() || !sendChangeEvent))
935        setTextAsOfLastFormControlChangeEvent(value);
936
937    InputElement::notifyFormStateChanged(this);
938}
939
940double HTMLInputElement::valueAsDate() const
941{
942    return m_inputType->valueAsDate();
943}
944
945void HTMLInputElement::setValueAsDate(double value, ExceptionCode& ec)
946{
947    m_inputType->setValueAsDate(value, ec);
948}
949
950double HTMLInputElement::valueAsNumber() const
951{
952    return m_inputType->valueAsNumber();
953}
954
955void HTMLInputElement::setValueAsNumber(double newValue, ExceptionCode& ec)
956{
957    if (!isfinite(newValue)) {
958        ec = NOT_SUPPORTED_ERR;
959        return;
960    }
961    m_inputType->setValueAsNumber(newValue, ec);
962}
963
964String HTMLInputElement::placeholder() const
965{
966    return fastGetAttribute(placeholderAttr).string();
967}
968
969void HTMLInputElement::setPlaceholder(const String& value)
970{
971    setAttribute(placeholderAttr, value);
972}
973
974bool HTMLInputElement::searchEventsShouldBeDispatched() const
975{
976    return hasAttribute(incrementalAttr);
977}
978
979void HTMLInputElement::setValueFromRenderer(const String& value)
980{
981    // File upload controls will always use setFileListFromRenderer.
982    ASSERT(!isFileUpload());
983
984    m_data.setSuggestedValue(String());
985    InputElement::setValueFromRenderer(m_data, this, this, value);
986    updatePlaceholderVisibility(false);
987    setNeedsValidityCheck();
988
989    // Clear autofill flag (and yellow background) on user edit.
990    setAutofilled(false);
991}
992
993void HTMLInputElement::setFileListFromRenderer(const Vector<String>& paths)
994{
995    m_inputType->setFileList(paths);
996
997    setFormControlValueMatchesRenderer(true);
998    InputElement::notifyFormStateChanged(this);
999    setNeedsValidityCheck();
1000}
1001
1002void* HTMLInputElement::preDispatchEventHandler(Event* event)
1003{
1004    if (event->type() == eventNames().textInputEvent && m_inputType->shouldSubmitImplicitly(event)) {
1005        event->stopPropagation();
1006        return 0;
1007    }
1008    if (event->type() != eventNames().clickEvent)
1009        return 0;
1010    if (!event->isMouseEvent() || static_cast<MouseEvent*>(event)->button() != LeftButton)
1011        return 0;
1012    // FIXME: Check whether there are any cases where this actually ends up leaking.
1013    return m_inputType->willDispatchClick().leakPtr();
1014}
1015
1016void HTMLInputElement::postDispatchEventHandler(Event* event, void* dataFromPreDispatch)
1017{
1018    OwnPtr<ClickHandlingState> state = adoptPtr(static_cast<ClickHandlingState*>(dataFromPreDispatch));
1019    if (!state)
1020        return;
1021    m_inputType->didDispatchClick(event, *state);
1022}
1023
1024void HTMLInputElement::defaultEventHandler(Event* evt)
1025{
1026    if (evt->isMouseEvent() && evt->type() == eventNames().clickEvent && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
1027        m_inputType->handleClickEvent(static_cast<MouseEvent*>(evt));
1028        if (evt->defaultHandled())
1029            return;
1030    }
1031
1032    if (evt->isKeyboardEvent() && evt->type() == eventNames().keydownEvent) {
1033        m_inputType->handleKeydownEvent(static_cast<KeyboardEvent*>(evt));
1034        if (evt->defaultHandled())
1035            return;
1036    }
1037
1038    // Call the base event handler before any of our own event handling for almost all events in text fields.
1039    // Makes editing keyboard handling take precedence over the keydown and keypress handling in this function.
1040    bool callBaseClassEarly = isTextField() && (evt->type() == eventNames().keydownEvent || evt->type() == eventNames().keypressEvent);
1041    if (callBaseClassEarly) {
1042        HTMLFormControlElementWithState::defaultEventHandler(evt);
1043        if (evt->defaultHandled())
1044            return;
1045    }
1046
1047    // DOMActivate events cause the input to be "activated" - in the case of image and submit inputs, this means
1048    // actually submitting the form. For reset inputs, the form is reset. These events are sent when the user clicks
1049    // on the element, or presses enter while it is the active element. JavaScript code wishing to activate the element
1050    // must dispatch a DOMActivate event - a click event will not do the job.
1051    if (evt->type() == eventNames().DOMActivateEvent) {
1052        m_inputType->handleDOMActivateEvent(evt);
1053        if (evt->defaultHandled())
1054            return;
1055    }
1056
1057    // Use key press event here since sending simulated mouse events
1058    // on key down blocks the proper sending of the key press event.
1059    if (evt->isKeyboardEvent() && evt->type() == eventNames().keypressEvent) {
1060        m_inputType->handleKeypressEvent(static_cast<KeyboardEvent*>(evt));
1061        if (evt->defaultHandled())
1062            return;
1063    }
1064
1065    if (evt->isKeyboardEvent() && evt->type() == eventNames().keyupEvent) {
1066        m_inputType->handleKeyupEvent(static_cast<KeyboardEvent*>(evt));
1067        if (evt->defaultHandled())
1068            return;
1069    }
1070
1071    if (m_inputType->shouldSubmitImplicitly(evt)) {
1072        if (isSearchField()) {
1073            addSearchResult();
1074            onSearch();
1075        }
1076        // Form submission finishes editing, just as loss of focus does.
1077        // If there was a change, send the event now.
1078        if (wasChangedSinceLastFormControlChangeEvent())
1079            dispatchFormControlChangeEvent();
1080
1081        RefPtr<HTMLFormElement> formForSubmission = m_inputType->formForSubmission();
1082        // Form may never have been present, or may have been destroyed by code responding to the change event.
1083        if (formForSubmission)
1084            formForSubmission->submitImplicitly(evt, canTriggerImplicitSubmission());
1085
1086        evt->setDefaultHandled();
1087        return;
1088    }
1089
1090    if (evt->isBeforeTextInsertedEvent())
1091        m_inputType->handleBeforeTextInsertedEvent(static_cast<BeforeTextInsertedEvent*>(evt));
1092
1093    if (evt->isWheelEvent()) {
1094        m_inputType->handleWheelEvent(static_cast<WheelEvent*>(evt));
1095        if (evt->defaultHandled())
1096            return;
1097    }
1098
1099    if (evt->isMouseEvent() && evt->type() == eventNames().mousedownEvent) {
1100        m_inputType->handleMouseDownEvent(static_cast<MouseEvent*>(evt));
1101        if (evt->defaultHandled())
1102            return;
1103    }
1104
1105#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
1106    if (evt->isTouchEvent() && evt->type() == eventNames().touchstartEvent) {
1107        m_inputType->handleTouchStartEvent(static_cast<TouchEvent*>(evt));
1108        if (evt->defaultHandled())
1109            return;
1110    }
1111#endif
1112
1113    m_inputType->forwardEvent(evt);
1114
1115    if (!callBaseClassEarly && !evt->defaultHandled())
1116        HTMLFormControlElementWithState::defaultEventHandler(evt);
1117}
1118
1119bool HTMLInputElement::isURLAttribute(Attribute *attr) const
1120{
1121    return (attr->name() == srcAttr || attr->name() == formactionAttr);
1122}
1123
1124String HTMLInputElement::defaultValue() const
1125{
1126    return fastGetAttribute(valueAttr);
1127}
1128
1129void HTMLInputElement::setDefaultValue(const String &value)
1130{
1131    setAttribute(valueAttr, value);
1132}
1133
1134void HTMLInputElement::setDefaultName(const AtomicString& name)
1135{
1136    m_data.setName(name);
1137}
1138
1139String HTMLInputElement::accept() const
1140{
1141    return fastGetAttribute(acceptAttr);
1142}
1143
1144String HTMLInputElement::alt() const
1145{
1146    return fastGetAttribute(altAttr);
1147}
1148
1149int HTMLInputElement::maxLength() const
1150{
1151    return m_data.maxLength();
1152}
1153
1154void HTMLInputElement::setMaxLength(int maxLength, ExceptionCode& ec)
1155{
1156    if (maxLength < 0)
1157        ec = INDEX_SIZE_ERR;
1158    else
1159        setAttribute(maxlengthAttr, String::number(maxLength));
1160}
1161
1162bool HTMLInputElement::multiple() const
1163{
1164    return fastHasAttribute(multipleAttr);
1165}
1166
1167void HTMLInputElement::setSize(unsigned size)
1168{
1169    setAttribute(sizeAttr, String::number(size));
1170}
1171
1172KURL HTMLInputElement::src() const
1173{
1174    return document()->completeURL(fastGetAttribute(srcAttr));
1175}
1176
1177void HTMLInputElement::setAutofilled(bool autofilled)
1178{
1179    if (autofilled == m_isAutofilled)
1180        return;
1181
1182    m_isAutofilled = autofilled;
1183    setNeedsStyleRecalc();
1184}
1185
1186FileList* HTMLInputElement::files()
1187{
1188    return m_inputType->files();
1189}
1190
1191String HTMLInputElement::visibleValue() const
1192{
1193    return m_inputType->visibleValue();
1194}
1195
1196String HTMLInputElement::convertFromVisibleValue(const String& visibleValue) const
1197{
1198    return m_inputType->convertFromVisibleValue(visibleValue);
1199}
1200
1201bool HTMLInputElement::isAcceptableValue(const String& proposedValue) const
1202{
1203    return m_inputType->isAcceptableValue(proposedValue);
1204}
1205
1206String HTMLInputElement::sanitizeValue(const String& proposedValue) const
1207{
1208    return m_inputType->sanitizeValue(proposedValue);
1209}
1210
1211bool HTMLInputElement::hasUnacceptableValue() const
1212{
1213    return m_inputType->hasUnacceptableValue();
1214}
1215
1216bool HTMLInputElement::isInRange() const
1217{
1218    return m_inputType->supportsRangeLimitation() && !rangeUnderflow(value()) && !rangeOverflow(value());
1219}
1220
1221bool HTMLInputElement::isOutOfRange() const
1222{
1223    return m_inputType->supportsRangeLimitation() && (rangeUnderflow(value()) || rangeOverflow(value()));
1224}
1225
1226bool HTMLInputElement::needsActivationCallback()
1227{
1228    return m_autocomplete == Off || m_inputType->shouldResetOnDocumentActivation();
1229}
1230
1231void HTMLInputElement::registerForActivationCallbackIfNeeded()
1232{
1233    if (needsActivationCallback())
1234        document()->registerForDocumentActivationCallbacks(this);
1235}
1236
1237void HTMLInputElement::unregisterForActivationCallbackIfNeeded()
1238{
1239    if (!needsActivationCallback())
1240        document()->unregisterForDocumentActivationCallbacks(this);
1241}
1242
1243bool HTMLInputElement::isRequiredFormControl() const
1244{
1245    return m_inputType->supportsRequired() && required();
1246}
1247
1248void HTMLInputElement::cacheSelection(int start, int end)
1249{
1250    m_data.setCachedSelectionStart(start);
1251    m_data.setCachedSelectionEnd(end);
1252}
1253
1254void HTMLInputElement::addSearchResult()
1255{
1256    ASSERT(isSearchField());
1257    if (renderer())
1258        toRenderTextControlSingleLine(renderer())->addSearchResult();
1259}
1260
1261void HTMLInputElement::onSearch()
1262{
1263    ASSERT(isSearchField());
1264    if (renderer())
1265        toRenderTextControlSingleLine(renderer())->stopSearchEventTimer();
1266    dispatchEvent(Event::create(eventNames().searchEvent, true, false));
1267}
1268
1269void HTMLInputElement::documentDidBecomeActive()
1270{
1271    ASSERT(needsActivationCallback());
1272    reset();
1273}
1274
1275void HTMLInputElement::willMoveToNewOwnerDocument()
1276{
1277    m_inputType->willMoveToNewOwnerDocument();
1278
1279    // Always unregister for cache callbacks when leaving a document, even if we would otherwise like to be registered
1280    if (needsActivationCallback())
1281        document()->unregisterForDocumentActivationCallbacks(this);
1282
1283    document()->checkedRadioButtons().removeButton(this);
1284
1285    HTMLFormControlElementWithState::willMoveToNewOwnerDocument();
1286}
1287
1288void HTMLInputElement::didMoveToNewOwnerDocument()
1289{
1290    registerForActivationCallbackIfNeeded();
1291
1292    HTMLFormControlElementWithState::didMoveToNewOwnerDocument();
1293}
1294
1295void HTMLInputElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
1296{
1297    HTMLFormControlElementWithState::addSubresourceAttributeURLs(urls);
1298
1299    addSubresourceURL(urls, src());
1300}
1301
1302bool HTMLInputElement::recalcWillValidate() const
1303{
1304    return m_inputType->supportsValidation() && HTMLFormControlElementWithState::recalcWillValidate();
1305}
1306
1307#if ENABLE(DATALIST)
1308
1309HTMLElement* HTMLInputElement::list() const
1310{
1311    return dataList();
1312}
1313
1314HTMLDataListElement* HTMLInputElement::dataList() const
1315{
1316    if (!m_hasNonEmptyList)
1317        return 0;
1318
1319    if (!m_inputType->shouldRespectListAttribute())
1320        return 0;
1321
1322    Element* element = document()->getElementById(fastGetAttribute(listAttr));
1323    if (!element)
1324        return 0;
1325    if (!element->hasTagName(datalistTag))
1326        return 0;
1327
1328    return static_cast<HTMLDataListElement*>(element);
1329}
1330
1331HTMLOptionElement* HTMLInputElement::selectedOption() const
1332{
1333    String value = this->value();
1334
1335    // The empty string never matches to a datalist option because it
1336    // doesn't represent a suggestion according to the standard.
1337    if (value.isEmpty())
1338        return 0;
1339
1340    HTMLDataListElement* sourceElement = dataList();
1341    if (!sourceElement)
1342        return 0;
1343    RefPtr<HTMLCollection> options = sourceElement->options();
1344    if (!options)
1345        return 0;
1346    unsigned length = options->length();
1347    for (unsigned i = 0; i < length; ++i) {
1348        HTMLOptionElement* option = static_cast<HTMLOptionElement*>(options->item(i));
1349        if (!option->disabled() && value == option->value())
1350            return option;
1351    }
1352    return 0;
1353}
1354
1355#endif // ENABLE(DATALIST)
1356
1357void HTMLInputElement::stepUpFromRenderer(int n)
1358{
1359    // The differences from stepUp()/stepDown():
1360    //
1361    // Difference 1: the current value
1362    // If the current value is not a number, including empty, the current value is assumed as 0.
1363    //   * If 0 is in-range, and matches to step value
1364    //     - The value should be the +step if n > 0
1365    //     - The value should be the -step if n < 0
1366    //     If -step or +step is out of range, new value should be 0.
1367    //   * If 0 is smaller than the minimum value
1368    //     - The value should be the minimum value for any n
1369    //   * If 0 is larger than the maximum value
1370    //     - The value should be the maximum value for any n
1371    //   * If 0 is in-range, but not matched to step value
1372    //     - The value should be the larger matched value nearest to 0 if n > 0
1373    //       e.g. <input type=number min=-100 step=3> -> 2
1374    //     - The value should be the smaler matched value nearest to 0 if n < 0
1375    //       e.g. <input type=number min=-100 step=3> -> -1
1376    //   As for date/datetime-local/month/time/week types, the current value is assumed as "the current local date/time".
1377    //   As for datetime type, the current value is assumed as "the current date/time in UTC".
1378    // If the current value is smaller than the minimum value:
1379    //  - The value should be the minimum value if n > 0
1380    //  - Nothing should happen if n < 0
1381    // If the current value is larger than the maximum value:
1382    //  - The value should be the maximum value if n < 0
1383    //  - Nothing should happen if n > 0
1384    //
1385    // Difference 2: clamping steps
1386    // If the current value is not matched to step value:
1387    // - The value should be the larger matched value nearest to 0 if n > 0
1388    //   e.g. <input type=number value=3 min=-100 step=3> -> 5
1389    // - The value should be the smaler matched value nearest to 0 if n < 0
1390    //   e.g. <input type=number value=3 min=-100 step=3> -> 2
1391    //
1392    // n is assumed as -n if step < 0.
1393
1394    ASSERT(hasSpinButton() || m_inputType->isRangeControl());
1395    if (!hasSpinButton() && !m_inputType->isRangeControl())
1396        return;
1397    ASSERT(n);
1398    if (!n)
1399        return;
1400
1401    unsigned stepDecimalPlaces, baseDecimalPlaces;
1402    double step, base;
1403    // The value will be the default value after stepping for <input value=(empty/invalid) step="any" />
1404    // FIXME: Not any changes after stepping, even if it is an invalid value, may be better.
1405    // (e.g. Stepping-up for <input type="number" value="foo" step="any" /> => "foo")
1406    if (equalIgnoringCase(fastGetAttribute(stepAttr), "any"))
1407        step = 0;
1408    else if (!getAllowedValueStepWithDecimalPlaces(&step, &stepDecimalPlaces))
1409        return;
1410    base = m_inputType->stepBaseWithDecimalPlaces(&baseDecimalPlaces);
1411    baseDecimalPlaces = min(baseDecimalPlaces, 16u);
1412
1413    int sign;
1414    if (step > 0)
1415        sign = n;
1416    else if (step < 0)
1417        sign = -n;
1418    else
1419        sign = 0;
1420
1421    const double nan = numeric_limits<double>::quiet_NaN();
1422    String currentStringValue = value();
1423    double current = m_inputType->parseToDouble(currentStringValue, nan);
1424    if (!isfinite(current)) {
1425        ExceptionCode ec;
1426        current = m_inputType->defaultValueForStepUp();
1427        setValueAsNumber(current, ec);
1428    }
1429    if ((sign > 0 && current < m_inputType->minimum()) || (sign < 0 && current > m_inputType->maximum()))
1430        setValue(m_inputType->serialize(sign > 0 ? m_inputType->minimum() : m_inputType->maximum()));
1431    else {
1432        ExceptionCode ec;
1433        if (stepMismatch(currentStringValue)) {
1434            ASSERT(step);
1435            double newValue;
1436            double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces)));
1437
1438            if (sign < 0)
1439                newValue = round((base + floor((current - base) / step) * step) * scale) / scale;
1440            else if (sign > 0)
1441                newValue = round((base + ceil((current - base) / step) * step) * scale) / scale;
1442            else
1443                newValue = current;
1444
1445            if (newValue < m_inputType->minimum())
1446                newValue = m_inputType->minimum();
1447            if (newValue > m_inputType->maximum())
1448                newValue = m_inputType->maximum();
1449
1450            setValueAsNumber(newValue, ec);
1451            current = newValue;
1452            if (n > 1)
1453                applyStep(n - 1, ec);
1454            else if (n < -1)
1455                applyStep(n + 1, ec);
1456        } else
1457            applyStep(n, ec);
1458    }
1459
1460    if (currentStringValue != value()) {
1461        if (m_inputType->isRangeControl())
1462            dispatchFormControlChangeEvent();
1463        else
1464            dispatchFormControlInputEvent();
1465    }
1466}
1467
1468#if ENABLE(WCSS)
1469
1470void HTMLInputElement::setWapInputFormat(String& mask)
1471{
1472    String validateMask = validateInputMask(m_data, mask);
1473    if (!validateMask.isEmpty())
1474        m_data.setInputFormatMask(validateMask);
1475}
1476
1477#endif
1478
1479#if ENABLE(INPUT_SPEECH)
1480
1481bool HTMLInputElement::isSpeechEnabled() const
1482{
1483    // FIXME: Add support for RANGE, EMAIL, URL, COLOR and DATE/TIME input types.
1484    return m_inputType->shouldRespectSpeechAttribute() && RuntimeEnabledFeatures::speechInputEnabled() && hasAttribute(webkitspeechAttr);
1485}
1486
1487#endif
1488
1489bool HTMLInputElement::isTextButton() const
1490{
1491    return m_inputType->isTextButton();
1492}
1493
1494bool HTMLInputElement::isRadioButton() const
1495{
1496    return m_inputType->isRadioButton();
1497}
1498
1499bool HTMLInputElement::isSearchField() const
1500{
1501    return m_inputType->isSearchField();
1502}
1503
1504bool HTMLInputElement::isInputTypeHidden() const
1505{
1506    return m_inputType->isHiddenType();
1507}
1508
1509bool HTMLInputElement::isPasswordField() const
1510{
1511    return m_inputType->isPasswordField();
1512}
1513
1514bool HTMLInputElement::isCheckbox() const
1515{
1516    return m_inputType->isCheckbox();
1517}
1518
1519bool HTMLInputElement::isText() const
1520{
1521    return m_inputType->isTextType();
1522}
1523
1524bool HTMLInputElement::isEmailField() const
1525{
1526    return m_inputType->isEmailField();
1527}
1528
1529bool HTMLInputElement::isFileUpload() const
1530{
1531    return m_inputType->isFileUpload();
1532}
1533
1534bool HTMLInputElement::isImageButton() const
1535{
1536    return m_inputType->isImageButton();
1537}
1538
1539bool HTMLInputElement::isNumberField() const
1540{
1541    return m_inputType->isNumberField();
1542}
1543
1544bool HTMLInputElement::isSubmitButton() const
1545{
1546    return m_inputType->isSubmitButton();
1547}
1548
1549bool HTMLInputElement::isTelephoneField() const
1550{
1551    return m_inputType->isTelephoneField();
1552}
1553
1554bool HTMLInputElement::isURLField() const
1555{
1556    return m_inputType->isURLField();
1557}
1558
1559bool HTMLInputElement::isEnumeratable() const
1560{
1561    return m_inputType->isEnumeratable();
1562}
1563
1564bool HTMLInputElement::isChecked() const
1565{
1566    return checked() && m_inputType->isCheckable();
1567}
1568
1569bool HTMLInputElement::hasSpinButton() const
1570{
1571    return m_inputType->hasSpinButton();
1572}
1573
1574bool HTMLInputElement::supportsPlaceholder() const
1575{
1576    return isTextType();
1577}
1578
1579CheckedRadioButtons& HTMLInputElement::checkedRadioButtons() const
1580{
1581    if (HTMLFormElement* formElement = form())
1582        return formElement->checkedRadioButtons();
1583    return document()->checkedRadioButtons();
1584}
1585
1586void HTMLInputElement::handleBeforeTextInsertedEvent(Event* event)
1587{
1588    InputElement::handleBeforeTextInsertedEvent(m_data, this, this, event);
1589}
1590
1591} // namespace
1592