/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
 *           (C) 2001 Dirk Mueller (mueller@kde.org)
 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
 *           (C) 2006 Alexey Proskuryakov (ap@nypop.com)
 * Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
 * Copyright (C) 2010 Google Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#include "config.h"
#include "HTMLInputElement.h"

#include "AXObjectCache.h"
#include "Attribute.h"
#include "BeforeTextInsertedEvent.h"
#include "CSSPropertyNames.h"
#include "Document.h"
#include "EventNames.h"
#include "ExceptionCode.h"
#include "FileList.h"
#include "HTMLCollection.h"
#include "HTMLDataListElement.h"
#include "HTMLFormElement.h"
#include "HTMLNames.h"
#include "HTMLOptionElement.h"
#include "HTMLParserIdioms.h"
#include "InputType.h"
#include "KeyboardEvent.h"
#include "LocalizedStrings.h"
#include "MouseEvent.h"
#include "PlatformMouseEvent.h"
#include "RenderTextControlSingleLine.h"
#include "RenderTheme.h"
#include "RuntimeEnabledFeatures.h"
#include "ScriptEventListener.h"
#include "WheelEvent.h"
#include <wtf/MathExtras.h>
#include <wtf/StdLibExtras.h>

#ifdef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS
#include "PlatformBridge.h"
#endif

#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
#include "TouchEvent.h"
#endif

using namespace std;

namespace WebCore {

using namespace HTMLNames;

const int maxSavedResults = 256;

HTMLInputElement::HTMLInputElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form, bool createdByParser)
    : HTMLTextFormControlElement(tagName, document, form)
    , m_maxResults(-1)
    , m_isChecked(false)
    , m_reflectsCheckedAttribute(true)
    , m_isIndeterminate(false)
    , m_hasType(false)
    , m_isActivatedSubmit(false)
    , m_autocomplete(Uninitialized)
    , m_isAutofilled(false)
    , m_stateRestored(false)
    , m_parsingInProgress(createdByParser)
    , m_inputType(InputType::createText(this))
{
    ASSERT(hasTagName(inputTag) || hasTagName(isindexTag));
}

PassRefPtr<HTMLInputElement> HTMLInputElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form, bool createdByParser)
{
    return adoptRef(new HTMLInputElement(tagName, document, form, createdByParser));
}

HTMLInputElement::~HTMLInputElement()
{
    if (needsActivationCallback())
        document()->unregisterForDocumentActivationCallbacks(this);

    document()->checkedRadioButtons().removeButton(this);

    // Need to remove this from the form while it is still an HTMLInputElement,
    // so can't wait for the base class's destructor to do it.
    removeFromForm();
}

const AtomicString& HTMLInputElement::formControlName() const
{
    return m_data.name();
}

bool HTMLInputElement::autoComplete() const
{
    if (m_autocomplete != Uninitialized)
        return m_autocomplete == On;
    return HTMLTextFormControlElement::autoComplete();
}

void HTMLInputElement::updateCheckedRadioButtons()
{
    if (attached() && checked())
        checkedRadioButtons().addButton(this);

    if (form()) {
        const Vector<FormAssociatedElement*>& controls = form()->associatedElements();
        for (unsigned i = 0; i < controls.size(); ++i) {
            if (!controls[i]->isFormControlElement())
                continue;
            HTMLFormControlElement* control = static_cast<HTMLFormControlElement*>(controls[i]);
            if (control->name() != name())
                continue;
            if (control->type() != type())
                continue;
            control->setNeedsValidityCheck();
        }
    } else {
        // FIXME: Traversing the document is inefficient.
        for (Node* node = document()->body(); node; node = node->traverseNextNode()) {
            if (!node->isElementNode())
                continue;
            Element* element = static_cast<Element*>(node);
            if (element->formControlName() != name())
                continue;
            if (element->formControlType() != type())
                continue;
            HTMLFormControlElement* control = static_cast<HTMLFormControlElement*>(element);
            if (control->form())
                continue;
            control->setNeedsValidityCheck();
        }
    }

    if (renderer() && renderer()->style()->hasAppearance())
        renderer()->theme()->stateChanged(renderer(), CheckedState);
}

bool HTMLInputElement::lastChangeWasUserEdit() const
{
    if (!isTextField())
        return false;
    
    if (!renderer())
        return false;

    return toRenderTextControl(renderer())->lastChangeWasUserEdit();
}

bool HTMLInputElement::isValidValue(const String& value) const
{
    if (!m_inputType->canSetStringValue()) {
        ASSERT_NOT_REACHED();
        return false;
    }
    return !m_inputType->typeMismatchFor(value)
        && !stepMismatch(value)
        && !rangeUnderflow(value)
        && !rangeOverflow(value)
        && !tooLong(value, IgnoreDirtyFlag)
        && !patternMismatch(value)
        && !valueMissing(value);
}

bool HTMLInputElement::typeMismatch() const
{
    return m_inputType->typeMismatch();
}

bool HTMLInputElement::valueMissing(const String& value) const
{
    if (!isRequiredFormControl() || readOnly() || disabled())
        return false;
    return m_inputType->valueMissing(value);
}

bool HTMLInputElement::patternMismatch(const String& value) const
{
    return m_inputType->patternMismatch(value);
}

bool HTMLInputElement::tooLong(const String& value, NeedsToCheckDirtyFlag check) const
{
    // We use isTextType() instead of supportsMaxLength() because of the
    // 'virtual' overhead.
    if (!isTextType())
        return false;
    int max = maxLength();
    if (max < 0)
        return false;
    if (check == CheckDirtyFlag) {
        // Return false for the default value even if it is longer than maxLength.
        bool userEdited = !m_data.value().isNull();
        if (!userEdited)
            return false;
    }
    return numGraphemeClusters(value) > static_cast<unsigned>(max);
}

bool HTMLInputElement::rangeUnderflow(const String& value) const
{
    return m_inputType->rangeUnderflow(value);
}

bool HTMLInputElement::rangeOverflow(const String& value) const
{
    return m_inputType->rangeOverflow(value);
}

double HTMLInputElement::minimum() const
{
    return m_inputType->minimum();
}

double HTMLInputElement::maximum() const
{
    return m_inputType->maximum();
}

bool HTMLInputElement::stepMismatch(const String& value) const
{
    double step;
    if (!getAllowedValueStep(&step))
        return false;
    return m_inputType->stepMismatch(value, step);
}

String HTMLInputElement::minimumString() const
{
    return m_inputType->serialize(minimum());
}

String HTMLInputElement::maximumString() const
{
    return m_inputType->serialize(maximum());
}

String HTMLInputElement::stepBaseString() const
{
    return m_inputType->serialize(m_inputType->stepBase());
}

String HTMLInputElement::stepString() const
{
    double step;
    if (!getAllowedValueStep(&step)) {
        // stepString() should be called only if stepMismatch() can be true.
        ASSERT_NOT_REACHED();
        return String();
    }
    return serializeForNumberType(step / m_inputType->stepScaleFactor());
}

String HTMLInputElement::typeMismatchText() const
{
    return m_inputType->typeMismatchText();
}

String HTMLInputElement::valueMissingText() const
{
    return m_inputType->valueMissingText();
}

bool HTMLInputElement::getAllowedValueStep(double* step) const
{
    return getAllowedValueStepWithDecimalPlaces(step, 0);
}

bool HTMLInputElement::getAllowedValueStepWithDecimalPlaces(double* step, unsigned* decimalPlaces) const
{
    ASSERT(step);
    double defaultStep = m_inputType->defaultStep();
    double stepScaleFactor = m_inputType->stepScaleFactor();
    if (!isfinite(defaultStep) || !isfinite(stepScaleFactor))
        return false;
    const AtomicString& stepString = fastGetAttribute(stepAttr);
    if (stepString.isEmpty()) {
        *step = defaultStep * stepScaleFactor;
        if (decimalPlaces)
            *decimalPlaces = 0;
        return true;
    }
    if (equalIgnoringCase(stepString, "any"))
        return false;
    double parsed;
    if (!decimalPlaces) {
        if (!parseToDoubleForNumberType(stepString, &parsed) || parsed <= 0.0) {
            *step = defaultStep * stepScaleFactor;
            return true;
        }
    } else {
        if (!parseToDoubleForNumberTypeWithDecimalPlaces(stepString, &parsed, decimalPlaces) || parsed <= 0.0) {
            *step = defaultStep * stepScaleFactor;
            *decimalPlaces = 0;
            return true;
        }
    }
    // For date, month, week, the parsed value should be an integer for some types.
    if (m_inputType->parsedStepValueShouldBeInteger())
        parsed = max(round(parsed), 1.0);
    double result = parsed * stepScaleFactor;
    // For datetime, datetime-local, time, the result should be an integer.
    if (m_inputType->scaledStepValueShouldBeInteger())
        result = max(round(result), 1.0);
    ASSERT(result > 0);
    *step = result;
    return true;
}

void HTMLInputElement::applyStep(double count, ExceptionCode& ec)
{
    double step;
    unsigned stepDecimalPlaces, currentDecimalPlaces;
    if (!getAllowedValueStepWithDecimalPlaces(&step, &stepDecimalPlaces)) {
        ec = INVALID_STATE_ERR;
        return;
    }
    const double nan = numeric_limits<double>::quiet_NaN();
    double current = m_inputType->parseToDoubleWithDecimalPlaces(value(), nan, &currentDecimalPlaces);
    if (!isfinite(current)) {
        ec = INVALID_STATE_ERR;
        return;
    }
    double newValue = current + step * count;
    if (isinf(newValue)) {
        ec = INVALID_STATE_ERR;
        return;
    }
    double acceptableError = m_inputType->acceptableError(step);
    if (newValue - m_inputType->minimum() < -acceptableError) {
        ec = INVALID_STATE_ERR;
        return;
    }
    if (newValue < m_inputType->minimum())
        newValue = m_inputType->minimum();
    unsigned baseDecimalPlaces;
    double base = m_inputType->stepBaseWithDecimalPlaces(&baseDecimalPlaces);
    baseDecimalPlaces = min(baseDecimalPlaces, 16u);
    if (newValue < pow(10.0, 21.0)) {
      if (stepMismatch(value())) {
            double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, currentDecimalPlaces)));
            newValue = round(newValue * scale) / scale;
        } else {
            double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces)));
            newValue = round((base + round((newValue - base) / step) * step) * scale) / scale;
        }
    }
    if (newValue - m_inputType->maximum() > acceptableError) {
        ec = INVALID_STATE_ERR;
        return;
    }
    if (newValue > m_inputType->maximum())
        newValue = m_inputType->maximum();
    setValueAsNumber(newValue, ec);

    if (AXObjectCache::accessibilityEnabled())
         document()->axObjectCache()->postNotification(renderer(), AXObjectCache::AXValueChanged, true);
}

void HTMLInputElement::stepUp(int n, ExceptionCode& ec)
{
    applyStep(n, ec);
}

void HTMLInputElement::stepDown(int n, ExceptionCode& ec)
{
    applyStep(-n, ec);
}

bool HTMLInputElement::isKeyboardFocusable(KeyboardEvent* event) const
{
    if (isTextField())
        return HTMLFormControlElementWithState::isFocusable();
    return HTMLFormControlElementWithState::isKeyboardFocusable(event) && m_inputType->isKeyboardFocusable();
}

bool HTMLInputElement::isMouseFocusable() const
{
    if (isTextField())
        return HTMLFormControlElementWithState::isFocusable();
    return HTMLFormControlElementWithState::isMouseFocusable();
}

void HTMLInputElement::updateFocusAppearance(bool restorePreviousSelection)
{
    if (isTextField())
        InputElement::updateFocusAppearance(m_data, this, this, restorePreviousSelection);
    else
        HTMLFormControlElementWithState::updateFocusAppearance(restorePreviousSelection);
}

void HTMLInputElement::aboutToUnload()
{
    InputElement::aboutToUnload(this, this);
}

bool HTMLInputElement::shouldUseInputMethod() const
{
    return m_inputType->shouldUseInputMethod();
}

void HTMLInputElement::handleFocusEvent()
{
    InputElement::dispatchFocusEvent(this, this);
}

void HTMLInputElement::handleBlurEvent()
{
    m_inputType->handleBlurEvent();
    InputElement::dispatchBlurEvent(this, this);
}

void HTMLInputElement::setType(const String& type)
{
    // FIXME: This should just call setAttribute. No reason to handle the empty string specially.
    // We should write a test case to show that setting to the empty string does not remove the
    // attribute in other browsers and then fix this. Note that setting to null *does* remove
    // the attribute and setAttribute implements that.
    if (type.isEmpty()) {
        ExceptionCode ec;
        removeAttribute(typeAttr, ec);
    } else
        setAttribute(typeAttr, type);
}

void HTMLInputElement::updateType()
{
    OwnPtr<InputType> newType = InputType::create(this, fastGetAttribute(typeAttr));
    bool hadType = m_hasType;
    m_hasType = true;
    if (m_inputType->formControlType() == newType->formControlType())
        return;

    if (hadType && !newType->canChangeFromAnotherType()) {
        // Set the attribute back to the old value.
        // Useful in case we were called from inside parseMappedAttribute.
        setAttribute(typeAttr, type());
        return;
    }

    checkedRadioButtons().removeButton(this);

    bool wasAttached = attached();
    if (wasAttached)
        detach();

    bool didStoreValue = m_inputType->storesValueSeparateFromAttribute();
    bool neededActivationCallback = needsActivationCallback();
    bool didRespectHeightAndWidth = m_inputType->shouldRespectHeightAndWidthAttributes();

    m_inputType->destroyShadowSubtree();
    m_inputType = newType.release();
    m_inputType->createShadowSubtree();

    setNeedsWillValidateCheck();

    bool willStoreValue = m_inputType->storesValueSeparateFromAttribute();

    if (didStoreValue && !willStoreValue && !m_data.value().isNull()) {
        setAttribute(valueAttr, m_data.value());
        m_data.setValue(String());
    }
    if (!didStoreValue && willStoreValue)
        m_data.setValue(sanitizeValue(fastGetAttribute(valueAttr)));
    else
        InputElement::updateValueIfNeeded(m_data, this);

    if (neededActivationCallback)
        unregisterForActivationCallbackIfNeeded();
    else
        registerForActivationCallbackIfNeeded();

    if (didRespectHeightAndWidth != m_inputType->shouldRespectHeightAndWidthAttributes()) {
        NamedNodeMap* map = attributeMap();
        ASSERT(map);
        if (Attribute* height = map->getAttributeItem(heightAttr))
            attributeChanged(height, false);
        if (Attribute* width = map->getAttributeItem(widthAttr))
            attributeChanged(width, false);
        if (Attribute* align = map->getAttributeItem(alignAttr))
            attributeChanged(align, false);
    }

    if (wasAttached) {
        attach();
        if (document()->focusedNode() == this)
            updateFocusAppearance(true);
    }

    setChangedSinceLastFormControlChangeEvent(false);

    checkedRadioButtons().addButton(this);

    setNeedsValidityCheck();
    InputElement::notifyFormStateChanged(this);
}

const AtomicString& HTMLInputElement::formControlType() const
{
    return m_inputType->formControlType();
}

bool HTMLInputElement::saveFormControlState(String& result) const
{
    return m_inputType->saveFormControlState(result);
}

void HTMLInputElement::restoreFormControlState(const String& state)
{
    m_inputType->restoreFormControlState(state);
    m_stateRestored = true;
}

bool HTMLInputElement::canStartSelection() const
{
    if (!isTextField())
        return false;
    return HTMLFormControlElementWithState::canStartSelection();
}

bool HTMLInputElement::canHaveSelection() const
{
    return isTextField();
}

void HTMLInputElement::accessKeyAction(bool sendToAnyElement)
{
    m_inputType->accessKeyAction(sendToAnyElement);
}

bool HTMLInputElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
{
    if (((attrName == heightAttr || attrName == widthAttr) && m_inputType->shouldRespectHeightAndWidthAttributes())
        || attrName == vspaceAttr
        || attrName == hspaceAttr) {
        result = eUniversal;
        return false;
    }

    if (attrName == alignAttr && m_inputType->shouldRespectAlignAttribute()) {
        // Share with <img> since the alignment behavior is the same.
        result = eReplaced;
        return false;
    }

    return HTMLElement::mapToEntry(attrName, result);
}

void HTMLInputElement::parseMappedAttribute(Attribute* attr)
{
    if (attr->name() == nameAttr) {
        checkedRadioButtons().removeButton(this);
        m_data.setName(attr->value());
        checkedRadioButtons().addButton(this);
        HTMLFormControlElementWithState::parseMappedAttribute(attr);
    } else if (attr->name() == autocompleteAttr) {
        if (equalIgnoringCase(attr->value(), "off")) {
            m_autocomplete = Off;
            registerForActivationCallbackIfNeeded();
        } else {
            bool needsToUnregister = m_autocomplete == Off;

            if (attr->isEmpty())
                m_autocomplete = Uninitialized;
            else
                m_autocomplete = On;

            if (needsToUnregister)
                unregisterForActivationCallbackIfNeeded();
        }
    } else if (attr->name() == typeAttr) {
        updateType();
    } else if (attr->name() == valueAttr) {
        // We only need to setChanged if the form is looking at the default value right now.
        if (m_data.value().isNull())
            setNeedsStyleRecalc();
        setFormControlValueMatchesRenderer(false);
        setNeedsValidityCheck();
    } else if (attr->name() == checkedAttr) {
        // Another radio button in the same group might be checked by state
        // restore. We shouldn't call setChecked() even if this has the checked
        // attribute. So, delay the setChecked() call until
        // finishParsingChildren() is called if parsing is in progress.
        if (!m_parsingInProgress && m_reflectsCheckedAttribute) {
            setChecked(!attr->isNull());
            m_reflectsCheckedAttribute = true;
        }
    } else if (attr->name() == maxlengthAttr) {
        InputElement::parseMaxLengthAttribute(m_data, this, this, attr);
        setNeedsValidityCheck();
    } else if (attr->name() == sizeAttr)
        InputElement::parseSizeAttribute(m_data, this, attr);
    else if (attr->name() == altAttr)
        m_inputType->altAttributeChanged();
    else if (attr->name() == srcAttr)
        m_inputType->srcAttributeChanged();
    else if (attr->name() == usemapAttr || attr->name() == accesskeyAttr) {
        // FIXME: ignore for the moment
    } else if (attr->name() == vspaceAttr) {
        addCSSLength(attr, CSSPropertyMarginTop, attr->value());
        addCSSLength(attr, CSSPropertyMarginBottom, attr->value());
    } else if (attr->name() == hspaceAttr) {
        addCSSLength(attr, CSSPropertyMarginLeft, attr->value());
        addCSSLength(attr, CSSPropertyMarginRight, attr->value());
    } else if (attr->name() == alignAttr) {
        if (m_inputType->shouldRespectAlignAttribute())
            addHTMLAlignment(attr);
    } else if (attr->name() == widthAttr) {
        if (m_inputType->shouldRespectHeightAndWidthAttributes())
            addCSSLength(attr, CSSPropertyWidth, attr->value());
    } else if (attr->name() == heightAttr) {
        if (m_inputType->shouldRespectHeightAndWidthAttributes())
            addCSSLength(attr, CSSPropertyHeight, attr->value());
    } else if (attr->name() == onsearchAttr) {
        // Search field and slider attributes all just cause updateFromElement to be called through style recalcing.
        setAttributeEventListener(eventNames().searchEvent, createAttributeEventListener(this, attr));
    } else if (attr->name() == resultsAttr) {
        int oldResults = m_maxResults;
        m_maxResults = !attr->isNull() ? std::min(attr->value().toInt(), maxSavedResults) : -1;
        // FIXME: Detaching just for maxResults change is not ideal.  We should figure out the right
        // time to relayout for this change.
        if (m_maxResults != oldResults && (m_maxResults <= 0 || oldResults <= 0) && attached()) {
            detach();
            attach();
        }
        setNeedsStyleRecalc();
    } else if (attr->name() == autosaveAttr || attr->name() == incrementalAttr)
        setNeedsStyleRecalc();
    else if (attr->name() == minAttr || attr->name() == maxAttr) {
        m_inputType->minOrMaxAttributeChanged();
        setNeedsValidityCheck();
    } else if (attr->name() == multipleAttr || attr->name() == patternAttr || attr->name() == precisionAttr || attr->name() == stepAttr)
        setNeedsValidityCheck();
#if ENABLE(DATALIST)
    else if (attr->name() == listAttr)
        m_hasNonEmptyList = !attr->isEmpty();
        // FIXME: we need to tell this change to a renderer if the attribute affects the appearance.
#endif
#if ENABLE(INPUT_SPEECH)
    else if (attr->name() == webkitspeechAttr) {
        if (renderer()) {
            // This renderer and its children have quite different layouts and styles depending on
            // whether the speech button is visible or not. So we reset the whole thing and recreate
            // to get the right styles and layout.
            detach();
            attach();
        }
        setNeedsStyleRecalc();
    } else if (attr->name() == onwebkitspeechchangeAttr)
        setAttributeEventListener(eventNames().webkitspeechchangeEvent, createAttributeEventListener(this, attr));
#endif
    else
        HTMLTextFormControlElement::parseMappedAttribute(attr);
}

void HTMLInputElement::finishParsingChildren()
{
    m_parsingInProgress = false;
    HTMLFormControlElementWithState::finishParsingChildren();
    if (!m_stateRestored) {
        bool checked = hasAttribute(checkedAttr);
        if (checked)
            setChecked(checked);
        m_reflectsCheckedAttribute = true;
    }
}

bool HTMLInputElement::rendererIsNeeded(RenderStyle* style)
{
    return m_inputType->rendererIsNeeded() && HTMLFormControlElementWithState::rendererIsNeeded(style);
}

RenderObject* HTMLInputElement::createRenderer(RenderArena* arena, RenderStyle* style)
{
    return m_inputType->createRenderer(arena, style);
}

void HTMLInputElement::attach()
{
    suspendPostAttachCallbacks();

    if (!m_hasType)
        updateType();

    HTMLFormControlElementWithState::attach();

    m_inputType->attach();

    if (document()->focusedNode() == this)
        document()->updateFocusAppearanceSoon(true /* restore selection */);

    resumePostAttachCallbacks();
}

void HTMLInputElement::detach()
{
    HTMLFormControlElementWithState::detach();
    setFormControlValueMatchesRenderer(false);
}

String HTMLInputElement::altText() const
{
    // http://www.w3.org/TR/1998/REC-html40-19980424/appendix/notes.html#altgen
    // also heavily discussed by Hixie on bugzilla
    // note this is intentionally different to HTMLImageElement::altText()
    String alt = fastGetAttribute(altAttr);
    // fall back to title attribute
    if (alt.isNull())
        alt = getAttribute(titleAttr);
    if (alt.isNull())
        alt = getAttribute(valueAttr);
    if (alt.isEmpty())
        alt = inputElementAltText();
    return alt;
}

bool HTMLInputElement::isSuccessfulSubmitButton() const
{
    // HTML spec says that buttons must have names to be considered successful.
    // However, other browsers do not impose this constraint. So we do not.
    return !disabled() && m_inputType->canBeSuccessfulSubmitButton();
}

bool HTMLInputElement::isActivatedSubmit() const
{
    return m_isActivatedSubmit;
}

void HTMLInputElement::setActivatedSubmit(bool flag)
{
    m_isActivatedSubmit = flag;
}

bool HTMLInputElement::appendFormData(FormDataList& encoding, bool multipart)
{
    return m_inputType->isFormDataAppendable() && m_inputType->appendFormData(encoding, multipart);
}

void HTMLInputElement::reset()
{
    if (m_inputType->storesValueSeparateFromAttribute())
        setValue(String());

    setAutofilled(false);
    setChecked(hasAttribute(checkedAttr));
    m_reflectsCheckedAttribute = true;
}

bool HTMLInputElement::isTextField() const
{
    return m_inputType->isTextField();
}

bool HTMLInputElement::isTextType() const
{
    return m_inputType->isTextType();
}

void HTMLInputElement::setChecked(bool nowChecked, bool sendChangeEvent)
{
    if (checked() == nowChecked)
        return;

    checkedRadioButtons().removeButton(this);

    m_reflectsCheckedAttribute = false;
    m_isChecked = nowChecked;
    setNeedsStyleRecalc();

    updateCheckedRadioButtons();
    setNeedsValidityCheck();

    // Ideally we'd do this from the render tree (matching
    // RenderTextView), but it's not possible to do it at the moment
    // because of the way the code is structured.
    if (renderer() && AXObjectCache::accessibilityEnabled())
        renderer()->document()->axObjectCache()->postNotification(renderer(), AXObjectCache::AXCheckedStateChanged, true);

    // Only send a change event for items in the document (avoid firing during
    // parsing) and don't send a change event for a radio button that's getting
    // unchecked to match other browsers. DOM is not a useful standard for this
    // because it says only to fire change events at "lose focus" time, which is
    // definitely wrong in practice for these types of elements.
    if (sendChangeEvent && inDocument() && m_inputType->shouldSendChangeEventAfterCheckedChanged()) {
        setTextAsOfLastFormControlChangeEvent(String());
        dispatchFormControlChangeEvent();
    }
}

void HTMLInputElement::setIndeterminate(bool newValue)
{
    if (!m_inputType->isCheckable() || indeterminate() == newValue)
        return;

    m_isIndeterminate = newValue;

    setNeedsStyleRecalc();

    if (renderer() && renderer()->style()->hasAppearance())
        renderer()->theme()->stateChanged(renderer(), CheckedState);
}

int HTMLInputElement::size() const
{
    return m_data.size();
}

void HTMLInputElement::copyNonAttributeProperties(const Element* source)
{
    const HTMLInputElement* sourceElement = static_cast<const HTMLInputElement*>(source);

    m_data.setValue(sourceElement->m_data.value());
    setChecked(sourceElement->m_isChecked);
    m_reflectsCheckedAttribute = sourceElement->m_reflectsCheckedAttribute;
    m_isIndeterminate = sourceElement->m_isIndeterminate;

    HTMLFormControlElementWithState::copyNonAttributeProperties(source);
}

String HTMLInputElement::value() const
{
    String value;
    if (m_inputType->getTypeSpecificValue(value))
        return value;

    value = m_data.value();
    if (!value.isNull())
        return value;

    value = sanitizeValue(fastGetAttribute(valueAttr));
    if (!value.isNull())
        return value;

    return m_inputType->fallbackValue();
}

String HTMLInputElement::valueWithDefault() const
{
    String value = this->value();
    if (!value.isNull())
        return value;

    return m_inputType->defaultValue();
}

void HTMLInputElement::setValueForUser(const String& value)
{
    // Call setValue and make it send a change event.
    setValue(value, true);
}

const String& HTMLInputElement::suggestedValue() const
{
    return m_data.suggestedValue();
}

void HTMLInputElement::setSuggestedValue(const String& value)
{
    if (!m_inputType->canSetSuggestedValue())
        return;
    setFormControlValueMatchesRenderer(false);
    m_data.setSuggestedValue(sanitizeValue(value));
    updatePlaceholderVisibility(false);
    if (renderer())
        renderer()->updateFromElement();
    setNeedsStyleRecalc();
}

void HTMLInputElement::setValue(const String& value, bool sendChangeEvent)
{
    if (!m_inputType->canSetValue(value))
        return;

    setFormControlValueMatchesRenderer(false);
    if (m_inputType->storesValueSeparateFromAttribute()) {
        if (files())
            files()->clear();
        else {
            m_data.setValue(sanitizeValue(value));
            if (isTextField())
                updatePlaceholderVisibility(false);
        }
        setNeedsStyleRecalc();
    } else
        setAttribute(valueAttr, sanitizeValue(value));

    setNeedsValidityCheck();

    if (isTextField()) {
        unsigned max = m_data.value().length();
#ifdef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS
        // Make sure our UI side textfield changes to match the RenderTextControl
        PlatformBridge::updateTextfield(document()->view(), this, value);
#endif
        if (document()->focusedNode() == this)
            InputElement::updateSelectionRange(this, this, max, max);
        else
            cacheSelection(max, max);
        m_data.setSuggestedValue(String());
    }
    m_inputType->valueChanged();

    if (sendChangeEvent) {
        // If the user is still editing this field, dispatch an input event rather than a change event.
        // The change event will be dispatched when editing finishes.
        if (isTextField() && focused())
            dispatchFormControlInputEvent();
        else
            dispatchFormControlChangeEvent();
    }

    if (isText() && (!focused() || !sendChangeEvent))
        setTextAsOfLastFormControlChangeEvent(value);

    InputElement::notifyFormStateChanged(this);
}

double HTMLInputElement::valueAsDate() const
{
    return m_inputType->valueAsDate();
}

void HTMLInputElement::setValueAsDate(double value, ExceptionCode& ec)
{
    m_inputType->setValueAsDate(value, ec);
}

double HTMLInputElement::valueAsNumber() const
{
    return m_inputType->valueAsNumber();
}

void HTMLInputElement::setValueAsNumber(double newValue, ExceptionCode& ec)
{
    if (!isfinite(newValue)) {
        ec = NOT_SUPPORTED_ERR;
        return;
    }
    m_inputType->setValueAsNumber(newValue, ec);
}

String HTMLInputElement::placeholder() const
{
    return fastGetAttribute(placeholderAttr).string();
}

void HTMLInputElement::setPlaceholder(const String& value)
{
    setAttribute(placeholderAttr, value);
}

bool HTMLInputElement::searchEventsShouldBeDispatched() const
{
    return hasAttribute(incrementalAttr);
}

void HTMLInputElement::setValueFromRenderer(const String& value)
{
    // File upload controls will always use setFileListFromRenderer.
    ASSERT(!isFileUpload());

    m_data.setSuggestedValue(String());
    InputElement::setValueFromRenderer(m_data, this, this, value);
    updatePlaceholderVisibility(false);
    setNeedsValidityCheck();

    // Clear autofill flag (and yellow background) on user edit.
    setAutofilled(false);
}

void HTMLInputElement::setFileListFromRenderer(const Vector<String>& paths)
{
    m_inputType->setFileList(paths);

    setFormControlValueMatchesRenderer(true);
    InputElement::notifyFormStateChanged(this);
    setNeedsValidityCheck();
}

void* HTMLInputElement::preDispatchEventHandler(Event* event)
{
    if (event->type() == eventNames().textInputEvent && m_inputType->shouldSubmitImplicitly(event)) {
        event->stopPropagation();
        return 0;
    }
    if (event->type() != eventNames().clickEvent)
        return 0;
    if (!event->isMouseEvent() || static_cast<MouseEvent*>(event)->button() != LeftButton)
        return 0;
    // FIXME: Check whether there are any cases where this actually ends up leaking.
    return m_inputType->willDispatchClick().leakPtr();
}

void HTMLInputElement::postDispatchEventHandler(Event* event, void* dataFromPreDispatch)
{
    OwnPtr<ClickHandlingState> state = adoptPtr(static_cast<ClickHandlingState*>(dataFromPreDispatch));
    if (!state)
        return;
    m_inputType->didDispatchClick(event, *state);
}

void HTMLInputElement::defaultEventHandler(Event* evt)
{
    if (evt->isMouseEvent() && evt->type() == eventNames().clickEvent && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
        m_inputType->handleClickEvent(static_cast<MouseEvent*>(evt));
        if (evt->defaultHandled())
            return;
    }

    if (evt->isKeyboardEvent() && evt->type() == eventNames().keydownEvent) {
        m_inputType->handleKeydownEvent(static_cast<KeyboardEvent*>(evt));
        if (evt->defaultHandled())
            return;
    }

    // Call the base event handler before any of our own event handling for almost all events in text fields.
    // Makes editing keyboard handling take precedence over the keydown and keypress handling in this function.
    bool callBaseClassEarly = isTextField() && (evt->type() == eventNames().keydownEvent || evt->type() == eventNames().keypressEvent);
    if (callBaseClassEarly) {
        HTMLFormControlElementWithState::defaultEventHandler(evt);
        if (evt->defaultHandled())
            return;
    }

    // DOMActivate events cause the input to be "activated" - in the case of image and submit inputs, this means
    // actually submitting the form. For reset inputs, the form is reset. These events are sent when the user clicks
    // on the element, or presses enter while it is the active element. JavaScript code wishing to activate the element
    // must dispatch a DOMActivate event - a click event will not do the job.
    if (evt->type() == eventNames().DOMActivateEvent) {
        m_inputType->handleDOMActivateEvent(evt);
        if (evt->defaultHandled())
            return;
    }

    // Use key press event here since sending simulated mouse events
    // on key down blocks the proper sending of the key press event.
    if (evt->isKeyboardEvent() && evt->type() == eventNames().keypressEvent) {
        m_inputType->handleKeypressEvent(static_cast<KeyboardEvent*>(evt));
        if (evt->defaultHandled())
            return;
    }

    if (evt->isKeyboardEvent() && evt->type() == eventNames().keyupEvent) {
        m_inputType->handleKeyupEvent(static_cast<KeyboardEvent*>(evt));
        if (evt->defaultHandled())
            return;
    }

    if (m_inputType->shouldSubmitImplicitly(evt)) {
        if (isSearchField()) {
            addSearchResult();
            onSearch();
        }
        // Form submission finishes editing, just as loss of focus does.
        // If there was a change, send the event now.
        if (wasChangedSinceLastFormControlChangeEvent())
            dispatchFormControlChangeEvent();

        RefPtr<HTMLFormElement> formForSubmission = m_inputType->formForSubmission();
        // Form may never have been present, or may have been destroyed by code responding to the change event.
        if (formForSubmission)
            formForSubmission->submitImplicitly(evt, canTriggerImplicitSubmission());

        evt->setDefaultHandled();
        return;
    }

    if (evt->isBeforeTextInsertedEvent())
        m_inputType->handleBeforeTextInsertedEvent(static_cast<BeforeTextInsertedEvent*>(evt));

    if (evt->isWheelEvent()) {
        m_inputType->handleWheelEvent(static_cast<WheelEvent*>(evt));
        if (evt->defaultHandled())
            return;
    }

    if (evt->isMouseEvent() && evt->type() == eventNames().mousedownEvent) {
        m_inputType->handleMouseDownEvent(static_cast<MouseEvent*>(evt));
        if (evt->defaultHandled())
            return;
    }

#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
    if (evt->isTouchEvent() && evt->type() == eventNames().touchstartEvent) {
        m_inputType->handleTouchStartEvent(static_cast<TouchEvent*>(evt));
        if (evt->defaultHandled())
            return;
    }
#endif

    m_inputType->forwardEvent(evt);

    if (!callBaseClassEarly && !evt->defaultHandled())
        HTMLFormControlElementWithState::defaultEventHandler(evt);
}

bool HTMLInputElement::isURLAttribute(Attribute *attr) const
{
    return (attr->name() == srcAttr || attr->name() == formactionAttr);
}

String HTMLInputElement::defaultValue() const
{
    return fastGetAttribute(valueAttr);
}

void HTMLInputElement::setDefaultValue(const String &value)
{
    setAttribute(valueAttr, value);
}

void HTMLInputElement::setDefaultName(const AtomicString& name)
{
    m_data.setName(name);
}

String HTMLInputElement::accept() const
{
    return fastGetAttribute(acceptAttr);
}

String HTMLInputElement::alt() const
{
    return fastGetAttribute(altAttr);
}

int HTMLInputElement::maxLength() const
{
    return m_data.maxLength();
}

void HTMLInputElement::setMaxLength(int maxLength, ExceptionCode& ec)
{
    if (maxLength < 0)
        ec = INDEX_SIZE_ERR;
    else
        setAttribute(maxlengthAttr, String::number(maxLength));
}

bool HTMLInputElement::multiple() const
{
    return fastHasAttribute(multipleAttr);
}

void HTMLInputElement::setSize(unsigned size)
{
    setAttribute(sizeAttr, String::number(size));
}

KURL HTMLInputElement::src() const
{
    return document()->completeURL(fastGetAttribute(srcAttr));
}

void HTMLInputElement::setAutofilled(bool autofilled)
{
    if (autofilled == m_isAutofilled)
        return;

    m_isAutofilled = autofilled;
    setNeedsStyleRecalc();
}

FileList* HTMLInputElement::files()
{
    return m_inputType->files();
}

String HTMLInputElement::visibleValue() const
{
    return m_inputType->visibleValue();
}

String HTMLInputElement::convertFromVisibleValue(const String& visibleValue) const
{
    return m_inputType->convertFromVisibleValue(visibleValue);
}

bool HTMLInputElement::isAcceptableValue(const String& proposedValue) const
{
    return m_inputType->isAcceptableValue(proposedValue);
}

String HTMLInputElement::sanitizeValue(const String& proposedValue) const
{
    return m_inputType->sanitizeValue(proposedValue);
}

bool HTMLInputElement::hasUnacceptableValue() const
{
    return m_inputType->hasUnacceptableValue();
}

bool HTMLInputElement::isInRange() const
{
    return m_inputType->supportsRangeLimitation() && !rangeUnderflow(value()) && !rangeOverflow(value());
}

bool HTMLInputElement::isOutOfRange() const
{
    return m_inputType->supportsRangeLimitation() && (rangeUnderflow(value()) || rangeOverflow(value()));
}

bool HTMLInputElement::needsActivationCallback()
{
    return m_autocomplete == Off || m_inputType->shouldResetOnDocumentActivation();
}

void HTMLInputElement::registerForActivationCallbackIfNeeded()
{
    if (needsActivationCallback())
        document()->registerForDocumentActivationCallbacks(this);
}

void HTMLInputElement::unregisterForActivationCallbackIfNeeded()
{
    if (!needsActivationCallback())
        document()->unregisterForDocumentActivationCallbacks(this);
}

bool HTMLInputElement::isRequiredFormControl() const
{
    return m_inputType->supportsRequired() && required();
}

void HTMLInputElement::cacheSelection(int start, int end)
{
    m_data.setCachedSelectionStart(start);
    m_data.setCachedSelectionEnd(end);
}

void HTMLInputElement::addSearchResult()
{
    ASSERT(isSearchField());
    if (renderer())
        toRenderTextControlSingleLine(renderer())->addSearchResult();
}

void HTMLInputElement::onSearch()
{
    ASSERT(isSearchField());
    if (renderer())
        toRenderTextControlSingleLine(renderer())->stopSearchEventTimer();
    dispatchEvent(Event::create(eventNames().searchEvent, true, false));
}

void HTMLInputElement::documentDidBecomeActive()
{
    ASSERT(needsActivationCallback());
    reset();
}

void HTMLInputElement::willMoveToNewOwnerDocument()
{
    m_inputType->willMoveToNewOwnerDocument();

    // Always unregister for cache callbacks when leaving a document, even if we would otherwise like to be registered
    if (needsActivationCallback())
        document()->unregisterForDocumentActivationCallbacks(this);

    document()->checkedRadioButtons().removeButton(this);

    HTMLFormControlElementWithState::willMoveToNewOwnerDocument();
}

void HTMLInputElement::didMoveToNewOwnerDocument()
{
    registerForActivationCallbackIfNeeded();

    HTMLFormControlElementWithState::didMoveToNewOwnerDocument();
}

void HTMLInputElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
{
    HTMLFormControlElementWithState::addSubresourceAttributeURLs(urls);

    addSubresourceURL(urls, src());
}

bool HTMLInputElement::recalcWillValidate() const
{
    return m_inputType->supportsValidation() && HTMLFormControlElementWithState::recalcWillValidate();
}

#if ENABLE(DATALIST)

HTMLElement* HTMLInputElement::list() const
{
    return dataList();
}

HTMLDataListElement* HTMLInputElement::dataList() const
{
    if (!m_hasNonEmptyList)
        return 0;

    if (!m_inputType->shouldRespectListAttribute())
        return 0;

    Element* element = document()->getElementById(fastGetAttribute(listAttr));
    if (!element)
        return 0;
    if (!element->hasTagName(datalistTag))
        return 0;

    return static_cast<HTMLDataListElement*>(element);
}

HTMLOptionElement* HTMLInputElement::selectedOption() const
{
    String value = this->value();

    // The empty string never matches to a datalist option because it
    // doesn't represent a suggestion according to the standard.
    if (value.isEmpty())
        return 0;

    HTMLDataListElement* sourceElement = dataList();
    if (!sourceElement)
        return 0;
    RefPtr<HTMLCollection> options = sourceElement->options();
    if (!options)
        return 0;
    unsigned length = options->length();
    for (unsigned i = 0; i < length; ++i) {
        HTMLOptionElement* option = static_cast<HTMLOptionElement*>(options->item(i));
        if (!option->disabled() && value == option->value())
            return option;
    }
    return 0;
}

#endif // ENABLE(DATALIST)

void HTMLInputElement::stepUpFromRenderer(int n)
{
    // The differences from stepUp()/stepDown():
    //
    // Difference 1: the current value
    // If the current value is not a number, including empty, the current value is assumed as 0.
    //   * If 0 is in-range, and matches to step value
    //     - The value should be the +step if n > 0
    //     - The value should be the -step if n < 0
    //     If -step or +step is out of range, new value should be 0.
    //   * If 0 is smaller than the minimum value
    //     - The value should be the minimum value for any n
    //   * If 0 is larger than the maximum value
    //     - The value should be the maximum value for any n
    //   * If 0 is in-range, but not matched to step value
    //     - The value should be the larger matched value nearest to 0 if n > 0
    //       e.g. <input type=number min=-100 step=3> -> 2
    //     - The value should be the smaler matched value nearest to 0 if n < 0
    //       e.g. <input type=number min=-100 step=3> -> -1
    //   As for date/datetime-local/month/time/week types, the current value is assumed as "the current local date/time".
    //   As for datetime type, the current value is assumed as "the current date/time in UTC".
    // If the current value is smaller than the minimum value:
    //  - The value should be the minimum value if n > 0
    //  - Nothing should happen if n < 0
    // If the current value is larger than the maximum value:
    //  - The value should be the maximum value if n < 0
    //  - Nothing should happen if n > 0
    //
    // Difference 2: clamping steps
    // If the current value is not matched to step value:
    // - The value should be the larger matched value nearest to 0 if n > 0
    //   e.g. <input type=number value=3 min=-100 step=3> -> 5
    // - The value should be the smaler matched value nearest to 0 if n < 0
    //   e.g. <input type=number value=3 min=-100 step=3> -> 2
    //
    // n is assumed as -n if step < 0.

    ASSERT(hasSpinButton() || m_inputType->isRangeControl());
    if (!hasSpinButton() && !m_inputType->isRangeControl())
        return;
    ASSERT(n);
    if (!n)
        return;

    unsigned stepDecimalPlaces, baseDecimalPlaces;
    double step, base;
    // The value will be the default value after stepping for <input value=(empty/invalid) step="any" />
    // FIXME: Not any changes after stepping, even if it is an invalid value, may be better.
    // (e.g. Stepping-up for <input type="number" value="foo" step="any" /> => "foo")
    if (equalIgnoringCase(fastGetAttribute(stepAttr), "any"))
        step = 0;
    else if (!getAllowedValueStepWithDecimalPlaces(&step, &stepDecimalPlaces))
        return;
    base = m_inputType->stepBaseWithDecimalPlaces(&baseDecimalPlaces);
    baseDecimalPlaces = min(baseDecimalPlaces, 16u);

    int sign;
    if (step > 0)
        sign = n;
    else if (step < 0)
        sign = -n;
    else
        sign = 0;

    const double nan = numeric_limits<double>::quiet_NaN();
    String currentStringValue = value();
    double current = m_inputType->parseToDouble(currentStringValue, nan);
    if (!isfinite(current)) {
        ExceptionCode ec;
        current = m_inputType->defaultValueForStepUp();
        setValueAsNumber(current, ec);
    }
    if ((sign > 0 && current < m_inputType->minimum()) || (sign < 0 && current > m_inputType->maximum()))
        setValue(m_inputType->serialize(sign > 0 ? m_inputType->minimum() : m_inputType->maximum()));
    else {
        ExceptionCode ec;
        if (stepMismatch(currentStringValue)) {
            ASSERT(step);
            double newValue;
            double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces)));

            if (sign < 0)
                newValue = round((base + floor((current - base) / step) * step) * scale) / scale;
            else if (sign > 0)
                newValue = round((base + ceil((current - base) / step) * step) * scale) / scale;
            else
                newValue = current;

            if (newValue < m_inputType->minimum())
                newValue = m_inputType->minimum();
            if (newValue > m_inputType->maximum())
                newValue = m_inputType->maximum();

            setValueAsNumber(newValue, ec);
            current = newValue;
            if (n > 1)
                applyStep(n - 1, ec);
            else if (n < -1)
                applyStep(n + 1, ec);
        } else
            applyStep(n, ec);
    }

    if (currentStringValue != value()) {
        if (m_inputType->isRangeControl())
            dispatchFormControlChangeEvent();
        else
            dispatchFormControlInputEvent();
    }
}

#if ENABLE(WCSS)

void HTMLInputElement::setWapInputFormat(String& mask)
{
    String validateMask = validateInputMask(m_data, mask);
    if (!validateMask.isEmpty())
        m_data.setInputFormatMask(validateMask);
}

#endif

#if ENABLE(INPUT_SPEECH)

bool HTMLInputElement::isSpeechEnabled() const
{
    // FIXME: Add support for RANGE, EMAIL, URL, COLOR and DATE/TIME input types.
    return m_inputType->shouldRespectSpeechAttribute() && RuntimeEnabledFeatures::speechInputEnabled() && hasAttribute(webkitspeechAttr);
}

#endif

bool HTMLInputElement::isTextButton() const
{
    return m_inputType->isTextButton();
}

bool HTMLInputElement::isRadioButton() const
{
    return m_inputType->isRadioButton();
}

bool HTMLInputElement::isSearchField() const
{
    return m_inputType->isSearchField();
}

bool HTMLInputElement::isInputTypeHidden() const
{
    return m_inputType->isHiddenType();
}

bool HTMLInputElement::isPasswordField() const
{
    return m_inputType->isPasswordField();
}

bool HTMLInputElement::isCheckbox() const
{
    return m_inputType->isCheckbox();
}

bool HTMLInputElement::isText() const
{
    return m_inputType->isTextType();
}

bool HTMLInputElement::isEmailField() const
{
    return m_inputType->isEmailField();
}

bool HTMLInputElement::isFileUpload() const
{
    return m_inputType->isFileUpload();
}

bool HTMLInputElement::isImageButton() const
{
    return m_inputType->isImageButton();
}

bool HTMLInputElement::isNumberField() const
{
    return m_inputType->isNumberField();
}

bool HTMLInputElement::isSubmitButton() const
{
    return m_inputType->isSubmitButton();
}

bool HTMLInputElement::isTelephoneField() const
{
    return m_inputType->isTelephoneField();
}

bool HTMLInputElement::isURLField() const
{
    return m_inputType->isURLField();
}

bool HTMLInputElement::isEnumeratable() const
{
    return m_inputType->isEnumeratable();
}

bool HTMLInputElement::isChecked() const
{
    return checked() && m_inputType->isCheckable();
}

bool HTMLInputElement::hasSpinButton() const
{
    return m_inputType->hasSpinButton();
}

bool HTMLInputElement::supportsPlaceholder() const
{
#if PLATFORM(ANDROID)
    return isTextType() || isNumberField();
#else
    return isTextType();
#endif
}

CheckedRadioButtons& HTMLInputElement::checkedRadioButtons() const
{
    if (HTMLFormElement* formElement = form())
        return formElement->checkedRadioButtons();
    return document()->checkedRadioButtons();
}

void HTMLInputElement::handleBeforeTextInsertedEvent(Event* event)
{
    InputElement::handleBeforeTextInsertedEvent(m_data, this, this, event);
}

#if PLATFORM(ANDROID) && ENABLE(MEDIA_CAPTURE)
String HTMLInputElement::capture() const
{
    if (!isFileUpload()) {
        // capture has no meaning on anything other than file pickers.
        return String();
    }

    String capture = fastGetAttribute(captureAttr).lower();
    if (capture == "camera"
        || capture == "camcorder"
        || capture == "microphone"
        || capture == "filesystem")
        return capture;
    // According to the HTML Media Capture specification, the invalid and
    // missing default value is filesystem.
    return "filesystem";
}
#endif

} // namespace
