Commit message: None
CVE: CVE-2013-0882
CWE: CWE-119
Vulnerability description: Google Chrome before 25.0.1364.97 on Windows and Linux, and before 25.0.1364.99 on Mac OS X, allows remote attackers to cause a denial of service (incorrect memory access) or possibly have unspecified other impact via a large number of SVG parameters.

Project: Chrome

inline HTMLButtonElement::HTMLButtonElement(Document& document, HTMLFormElement* form)
    : HTMLFormControlElement(buttonTag, document, form)
    , m_type(SUBMIT)
    , m_isActivatedSubmit(false)
{
    ScriptWrappable::init(this);
}

Project: Chrome

void HTMLButtonElement::accessKeyAction(bool sendMouseEvents)
{
    focus();

    dispatchSimulatedClick(0, sendMouseEvents ? SendMouseUpDownEvents : SendNoEvents);
}

Project: Chrome

bool HTMLButtonElement::appendFormData(FormDataList& formData, bool)
{
    if (m_type != SUBMIT || name().isEmpty() || !m_isActivatedSubmit)
        return false;
    formData.appendData(name(), value());
    return true;
}

Project: Chrome

bool HTMLButtonElement::canBeSuccessfulSubmitButton() const
{
    return m_type == SUBMIT;
}

Project: Chrome

PassRefPtr<HTMLButtonElement> HTMLButtonElement::create(Document& document, HTMLFormElement* form)
{
    return adoptRef(new HTMLButtonElement(document, form));
}

Project: Chrome

RenderObject* HTMLButtonElement::createRenderer(RenderStyle*)
{
    return new RenderButton(this);
}

Project: Chrome

void HTMLButtonElement::defaultEventHandler(Event* event)
{
    if (event->type() == EventTypeNames::DOMActivate && !isDisabledFormControl()) {
        if (form() && m_type == SUBMIT) {
            m_isActivatedSubmit = true;
            form()->prepareForSubmission(event);
            event->setDefaultHandled();
            m_isActivatedSubmit = false; // Do this in case submission was canceled.
        }
        if (form() && m_type == RESET) {
            form()->reset();
            event->setDefaultHandled();
        }
    }

    if (event->isKeyboardEvent()) {
        if (event->type() == EventTypeNames::keydown && toKeyboardEvent(event)->keyIdentifier() == "U+0020") {
            setActive(true);
            return;
        }
        if (event->type() == EventTypeNames::keypress) {
            switch (toKeyboardEvent(event)->charCode()) {
                case '\r':
                    dispatchSimulatedClick(event);
                    event->setDefaultHandled();
                    return;
                case ' ':
                    event->setDefaultHandled();
                    return;
            }
        }
        if (event->type() == EventTypeNames::keyup && toKeyboardEvent(event)->keyIdentifier() == "U+0020") {
            if (active())
                dispatchSimulatedClick(event);
            event->setDefaultHandled();
            return;
        }
    }

    HTMLFormControlElement::defaultEventHandler(event);
}

Project: Chrome

const AtomicString& HTMLButtonElement::formControlType() const
{
    switch (m_type) {
        case SUBMIT: {
            DEFINE_STATIC_LOCAL(const AtomicString, submit, ("submit", AtomicString::ConstructFromLiteral));
            return submit;
        }
        case BUTTON: {
            DEFINE_STATIC_LOCAL(const AtomicString, button, ("button", AtomicString::ConstructFromLiteral));
            return button;
        }
        case RESET: {
            DEFINE_STATIC_LOCAL(const AtomicString, reset, ("reset", AtomicString::ConstructFromLiteral));
            return reset;
        }
    }

    ASSERT_NOT_REACHED();
    return emptyAtom;
}

Project: Chrome

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

Project: Chrome

bool HTMLButtonElement::isInteractiveContent() const
{
     return true;
 }

Project: Chrome

bool HTMLButtonElement::isPresentationAttribute(const QualifiedName& name) const
{
    if (name == alignAttr) {
        return false;
    }

    return HTMLFormControlElement::isPresentationAttribute(name);
}

Project: Chrome

bool HTMLButtonElement::isURLAttribute(const Attribute& attribute) const
{
    return attribute.name() == formactionAttr || HTMLFormControlElement::isURLAttribute(attribute);
}

Project: Chrome

void HTMLButtonElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
    if (name == typeAttr) {
        if (equalIgnoringCase(value, "reset"))
            m_type = RESET;
        else if (equalIgnoringCase(value, "button"))
            m_type = BUTTON;
        else
            m_type = SUBMIT;
        setNeedsWillValidateCheck();
    } else
        HTMLFormControlElement::parseAttribute(name, value);
}

Project: Chrome

bool HTMLButtonElement::recalcWillValidate() const
{
    return m_type == SUBMIT && HTMLFormControlElement::recalcWillValidate();
}

Project: Chrome

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

Project: Chrome

void HTMLButtonElement::setType(const AtomicString& type)
{
    setAttribute(typeAttr, type);
}

Project: Chrome

const AtomicString& HTMLButtonElement::value() const
{
    return getAttribute(valueAttr);
}

Project: Chrome

bool HTMLButtonElement::willRespondToMouseClickEvents()
{
    if (!isDisabledFormControl() && form() && (m_type == SUBMIT || m_type == RESET))
        return true;
    return HTMLFormControlElement::willRespondToMouseClickEvents();
}

Project: Chrome

HTMLFormControlElement::HTMLFormControlElement(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
    : LabelableElement(tagName, document)
    , m_disabled(false)
    , m_isAutofilled(false)
    , m_isReadOnly(false)
    , m_isRequired(false)
    , m_valueMatchesRenderer(false)
    , m_ancestorDisabledState(AncestorDisabledStateUnknown)
    , m_dataListAncestorState(Unknown)
    , m_willValidateInitialized(false)
    , m_willValidate(true)
    , m_isValid(true)
    , m_wasChangedSinceLastFormControlChangeEvent(false)
    , m_wasFocusedByMouse(false)
    , m_hasAutofocused(false)
{
    setForm(form ? form : findFormAncestor());
    setHasCustomStyleCallbacks();
}

Project: Chrome

void HTMLFormControlElement::ancestorDisabledStateWasChanged()
{
    m_ancestorDisabledState = AncestorDisabledStateUnknown;
    disabledAttributeChanged();
}

Project: Chrome

void HTMLFormControlElement::attach(const AttachContext& context)
{
    HTMLElement::attach(context);

    if (!renderer())
        return;

    renderer()->updateFromElement();

    if (shouldAutofocusOnAttach(this)) {
        setAutofocused();
        document().setAutofocusElement(this);
    }
}

Project: Chrome

bool HTMLFormControlElement::checkValidity(Vector<RefPtr<FormAssociatedElement> >* unhandledInvalidControls, CheckValidityDispatchEvents dispatchEvents)
{
    if (!willValidate() || isValidFormControlElement())
        return true;
    if (dispatchEvents == CheckValidityDispatchEventsNone)
        return false;
    RefPtr<HTMLFormControlElement> protector(this);
    RefPtr<Document> originalDocument(document());
    bool needsDefaultAction = dispatchEvent(Event::createCancelable(EventTypeNames::invalid));
    if (needsDefaultAction && unhandledInvalidControls && inDocument() && originalDocument == document())
        unhandledInvalidControls->append(this);
    return false;
}

Project: Chrome

void HTMLFormControlElement::didMoveToNewDocument(Document& oldDocument)
{
    FormAssociatedElement::didMoveToNewDocument(oldDocument);
    HTMLElement::didMoveToNewDocument(oldDocument);
}

Project: Chrome

void HTMLFormControlElement::didRecalcStyle(StyleRecalcChange)
{
    if (RenderObject* renderer = this->renderer())
        renderer->updateFromElement();
}

Project: Chrome

void HTMLFormControlElement::disabledAttributeChanged()
{
    setNeedsWillValidateCheck();
    didAffectSelector(AffectedSelectorDisabled | AffectedSelectorEnabled);
    if (renderer() && renderer()->style()->hasAppearance())
        RenderTheme::theme().stateChanged(renderer(), EnabledState);
    if (isDisabledFormControl() && treeScope().adjustedFocusedElement() == this) {
        document().setNeedsFocusedElementCheck();
    }
}

Project: Chrome

void HTMLFormControlElement::dispatchBlurEvent(Element* newFocusedElement)
{
    HTMLElement::dispatchBlurEvent(newFocusedElement);
    hideVisibleValidationMessage();
}

Project: Chrome

void HTMLFormControlElement::dispatchFocusEvent(Element* oldFocusedElement, FocusDirection direction)
{
    if (direction != FocusDirectionPage)
        m_wasFocusedByMouse = direction == FocusDirectionMouse;
    HTMLElement::dispatchFocusEvent(oldFocusedElement, direction);
}

Project: Chrome

void HTMLFormControlElement::dispatchFormControlInputEvent()
{
    setChangedSinceLastFormControlChangeEvent(true);
    HTMLElement::dispatchInputEvent();
}

Project: Chrome

HTMLFormControlElement* HTMLFormControlElement::enclosingFormControlElement(Node* node)
{
    for (; node; node = node->parentNode()) {
        if (node->isElementNode() && toElement(node)->isFormControlElement())
            return toHTMLFormControlElement(node);
    }
    return 0;
}

Project: Chrome

String HTMLFormControlElement::formEnctype() const
{
    const AtomicString& formEnctypeAttr = fastGetAttribute(formenctypeAttr);
    if (formEnctypeAttr.isNull())
        return emptyString();
    return FormSubmission::Attributes::parseEncodingType(formEnctypeAttr);
}

Project: Chrome

String HTMLFormControlElement::formMethod() const
{
    const AtomicString& formMethodAttr = fastGetAttribute(formmethodAttr);
    if (formMethodAttr.isNull())
        return emptyString();
    return FormSubmission::Attributes::methodString(FormSubmission::Attributes::parseMethodType(formMethodAttr));
}

Project: Chrome

bool HTMLFormControlElement::formNoValidate() const
{
    return fastHasAttribute(formnovalidateAttr);
}

Project: Chrome

void HTMLFormControlElement::hideVisibleValidationMessage()
{
    if (m_validationMessage)
        m_validationMessage->requestToHideMessage();
}

Project: Chrome

bool HTMLFormControlElement::isDefaultButtonForForm() const
{
    return isSuccessfulSubmitButton() && form() && form()->defaultButton() == this;
}

Project: Chrome

bool HTMLFormControlElement::isDisabledFormControl() const
{
    if (m_disabled)
        return true;

    if (m_ancestorDisabledState == AncestorDisabledStateUnknown)
        updateAncestorDisabledState();
    return m_ancestorDisabledState == AncestorDisabledStateDisabled;
}

Project: Chrome

bool HTMLFormControlElement::isKeyboardFocusable() const
{
    return isFocusable();
}

Project: Chrome

bool HTMLFormControlElement::isRequired() const
{
    return m_isRequired;
}

Project: Chrome

bool HTMLFormControlElement::isSuccessfulSubmitButton() const
{
    return canBeSuccessfulSubmitButton() && !isDisabledFormControl();
}

Project: Chrome

bool HTMLFormControlElement::isValidFormControlElement()
{
    ASSERT(m_isValid == valid());
    return m_isValid;
}

Project: Chrome

String HTMLFormControlElement::nameForAutofill() const
{
    String fullName = name();
    String trimmedName = fullName.stripWhiteSpace();
    if (!trimmedName.isEmpty())
        return trimmedName;
    fullName = getIdAttribute();
    trimmedName = fullName.stripWhiteSpace();
    return trimmedName;
}

Project: Chrome

bool HTMLFormControlElement::recalcWillValidate() const
{
    if (m_dataListAncestorState == Unknown) {
        for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
            if (ancestor->hasTagName(datalistTag)) {
                m_dataListAncestorState = InsideDataList;
                break;
            }
        }
        if (m_dataListAncestorState == Unknown)
            m_dataListAncestorState = NotInsideDataList;
    }
    return m_dataListAncestorState == NotInsideDataList && !isDisabledOrReadOnly();
}

Project: Chrome

void HTMLFormControlElement::requiredAttributeChanged()
{
    setNeedsValidityCheck();
     setNeedsStyleRecalc();
 }

Project: Chrome

void HTMLFormControlElement::reset()
{
    setAutofilled(false);
    resetImpl();
}

Project: Chrome

String HTMLFormControlElement::resultForDialogSubmit()
{
    return fastGetAttribute(valueAttr);
}

Project: Chrome

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

    m_isAutofilled = autofilled;
    setNeedsStyleRecalc();
}

Project: Chrome

void HTMLFormControlElement::setChangedSinceLastFormControlChangeEvent(bool changed)
{
    m_wasChangedSinceLastFormControlChangeEvent = changed;
}

Project: Chrome

void HTMLFormControlElement::setCustomValidity(const String& error)
{
    FormAssociatedElement::setCustomValidity(error);
    setNeedsValidityCheck();
}

Project: Chrome

void HTMLFormControlElement::setFormEnctype(const AtomicString& value)
{
    setAttribute(formenctypeAttr, value);
}

Project: Chrome

void HTMLFormControlElement::setFormMethod(const AtomicString& value)
{
    setAttribute(formmethodAttr, value);
}

Project: Chrome

void HTMLFormControlElement::setNeedsValidityCheck()
{
    bool newIsValid = valid();
    if (willValidate() && newIsValid != m_isValid) {
        setNeedsStyleRecalc();
    }
    m_isValid = newIsValid;

    if (m_validationMessage && m_validationMessage->isVisible()) {
        updateVisibleValidationMessage();
    }
}

Project: Chrome

void HTMLFormControlElement::setNeedsWillValidateCheck()
{
    bool newWillValidate = recalcWillValidate();
    if (m_willValidateInitialized && m_willValidate == newWillValidate)
        return;
    m_willValidateInitialized = true;
    m_willValidate = newWillValidate;
    setNeedsValidityCheck();
    setNeedsStyleRecalc();
    if (!m_willValidate)
        hideVisibleValidationMessage();
}

Project: Chrome

static bool shouldAutofocusOnAttach(const HTMLFormControlElement* element)
{
    if (!element->isAutofocusable())
        return false;
    if (element->hasAutofocused())
        return false;
    if (element->document().isSandboxed(SandboxAutomaticFeatures)) {
        element->document().addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Blocked autofocusing on a form control because the form's frame is sandboxed and the 'allow-scripts' permission is not set.");
        return false;
    }

    return true;
}

Project: Chrome

bool HTMLFormControlElement::shouldHaveFocusAppearance() const
{
    ASSERT(focused());
    return shouldShowFocusRingOnMouseFocus() || !m_wasFocusedByMouse;
}

Project: Chrome

bool HTMLFormControlElement::shouldShowFocusRingOnMouseFocus() const
{
    return false;
}

Project: Chrome

bool HTMLFormControlElement::supportsFocus() const
{
    return !isDisabledFormControl();
}

Project: Chrome

short HTMLFormControlElement::tabIndex() const
{
    return Element::tabIndex();
}

Project: Chrome

void HTMLFormControlElement::updateAncestorDisabledState() const
{
    HTMLFieldSetElement* fieldSetAncestor = 0;
    ContainerNode* legendAncestor = 0;
    for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
        if (!legendAncestor && ancestor->hasTagName(legendTag))
            legendAncestor = ancestor;
        if (ancestor->hasTagName(fieldsetTag)) {
            fieldSetAncestor = toHTMLFieldSetElement(ancestor);
            break;
        }
    }
    m_ancestorDisabledState = (fieldSetAncestor && fieldSetAncestor->isDisabledFormControl() && !(legendAncestor && legendAncestor == fieldSetAncestor->legend())) ? AncestorDisabledStateDisabled : AncestorDisabledStateEnabled;
}

Project: Chrome

void HTMLFormControlElement::updateVisibleValidationMessage()
{
    Page* page = document().page();
    if (!page)
        return;
    String message;
    if (renderer() && willValidate())
        message = validationMessage().stripWhiteSpace();
    if (!m_validationMessage)
        m_validationMessage = ValidationMessage::create(this);
    m_validationMessage->updateValidationMessage(message);
}

Project: Chrome

bool HTMLFormControlElement::wasChangedSinceLastFormControlChangeEvent() const
{
    return m_wasChangedSinceLastFormControlChangeEvent;
}

Project: Chrome

void HTMLFormControlElement::willCallDefaultEventHandler(const Event& event)
{
    if (!event.isKeyboardEvent() || event.type() != EventTypeNames::keydown)
        return;
    if (!m_wasFocusedByMouse)
        return;
    m_wasFocusedByMouse = false;
    if (renderer())
        renderer()->repaint();
}

Project: Chrome

bool HTMLFormControlElement::willValidate() const
{
    if (!m_willValidateInitialized || m_dataListAncestorState == Unknown) {
        m_willValidateInitialized = true;
        bool newWillValidate = recalcWillValidate();
        if (m_willValidate != newWillValidate) {
            m_willValidate = newWillValidate;
            const_cast<HTMLFormControlElement*>(this)->setNeedsValidityCheck();
        }
    } else {
        ASSERT(m_willValidate == recalcWillValidate());
    }
    return m_willValidate;
}

Project: Chrome

HTMLFormControlElement::~HTMLFormControlElement()
{
    setForm(0);
}

Project: Chrome

HTMLInputElement::HTMLInputElement(Document& document, HTMLFormElement* form, bool createdByParser)
    : HTMLTextFormControlElement(inputTag, document, form)
    , m_size(defaultSize)
    , m_maxLength(maximumLength)
    , m_maxResults(-1)
    , m_isChecked(false)
    , m_reflectsCheckedAttribute(true)
    , m_isIndeterminate(false)
    , m_hasType(false)
    , m_isActivatedSubmit(false)
    , m_autocomplete(Uninitialized)
    , m_hasNonEmptyList(false)
    , m_stateRestored(false)
    , m_parsingInProgress(createdByParser)
    , m_valueAttributeWasUpdatedAfterParsing(false)
    , m_canReceiveDroppedFiles(false)
    , m_hasTouchEventHandler(false)
    , m_inputType(InputType::createText(*this))
    , m_inputTypeView(m_inputType)
{
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
    setHasCustomStyleCallbacks();
#endif
    ScriptWrappable::init(this);
}

Project: Chrome

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

Project: Chrome

void HTMLInputElement::beginEditing()
{
    ASSERT(document().isActive());
    if (!document().isActive())
        return;

    if (!isTextField())
        return;

    document().frame()->spellChecker().didBeginEditing(this);
}

Project: Chrome

void HTMLInputElement::blur()
{
    m_inputTypeView->blur();
}

Project: Chrome

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

Project: Chrome

bool HTMLInputElement::capture() const
{
    if (!isFileUpload() || !fastHasAttribute(captureAttr))
        return false;

    bool hasDeprecatedUsage = !fastGetAttribute(captureAttr).isNull();
    if (hasDeprecatedUsage)
        UseCounter::countDeprecation(document(), UseCounter::CaptureAttributeAsEnum);
    else
        UseCounter::count(document(), UseCounter::CaptureAttributeAsEnum);

    return true;
}

Project: Chrome

void HTMLInputElement::copyNonAttributePropertiesFromElement(const Element& source)
{
    const HTMLInputElement& sourceElement = static_cast<const HTMLInputElement&>(source);

    m_valueIfDirty = sourceElement.m_valueIfDirty;
    setChecked(sourceElement.m_isChecked);
    m_reflectsCheckedAttribute = sourceElement.m_reflectsCheckedAttribute;
    m_isIndeterminate = sourceElement.m_isIndeterminate;

    HTMLTextFormControlElement::copyNonAttributePropertiesFromElement(source);

    setFormControlValueMatchesRenderer(false);
    m_inputTypeView->updateView();
}

Project: Chrome

PassRefPtr<HTMLInputElement> HTMLInputElement::create(Document& document, HTMLFormElement* form, bool createdByParser)
{
    RefPtr<HTMLInputElement> inputElement = adoptRef(new HTMLInputElement(document, form, createdByParser));
    inputElement->ensureUserAgentShadowRoot();
    return inputElement.release();
}

Project: Chrome

RenderObject* HTMLInputElement::createRenderer(RenderStyle* style)
{
    return m_inputTypeView->createRenderer(style);
}

Project: Chrome

 PassRefPtr<RenderStyle> HTMLInputElement::customStyleForRenderer()
 {
    return m_inputTypeView->customStyleForRenderer(originalStyleForRenderer());
}

Project: Chrome

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

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

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

    return toHTMLDataListElement(element);
}

Project: Chrome

void HTMLInputElement::defaultEventHandler(Event* evt)
{
    if (evt->isMouseEvent() && evt->type() == EventTypeNames::click && toMouseEvent(evt)->button() == LeftButton) {
        m_inputTypeView->handleClickEvent(toMouseEvent(evt));
        if (evt->defaultHandled())
            return;
    }

    if (evt->isTouchEvent()) {
        m_inputTypeView->handleTouchEvent(toTouchEvent(evt));
        if (evt->defaultHandled())
            return;
    }

    if (evt->isKeyboardEvent() && evt->type() == EventTypeNames::keydown) {
        m_inputTypeView->handleKeydownEvent(toKeyboardEvent(evt));
        if (evt->defaultHandled())
            return;
    }

    bool callBaseClassEarly = isTextField() && (evt->type() == EventTypeNames::keydown || evt->type() == EventTypeNames::keypress);
    if (callBaseClassEarly) {
        HTMLTextFormControlElement::defaultEventHandler(evt);
        if (evt->defaultHandled())
            return;
    }

    if (evt->type() == EventTypeNames::DOMActivate) {
        m_inputType->handleDOMActivateEvent(evt);
        if (evt->defaultHandled())
            return;
    }

    if (evt->isKeyboardEvent() && evt->type() == EventTypeNames::keypress) {
        m_inputTypeView->handleKeypressEvent(toKeyboardEvent(evt));
        if (evt->defaultHandled())
            return;
    }

    if (evt->isKeyboardEvent() && evt->type() == EventTypeNames::keyup) {
        m_inputTypeView->handleKeyupEvent(toKeyboardEvent(evt));
        if (evt->defaultHandled())
            return;
    }

    if (m_inputTypeView->shouldSubmitImplicitly(evt)) {
        if (isSearchField())
            onSearch();
        if (wasChangedSinceLastFormControlChangeEvent())
            dispatchFormControlChangeEvent();

        RefPtr<HTMLFormElement> formForSubmission = m_inputTypeView->formForSubmission();
        if (formForSubmission)
            formForSubmission->submitImplicitly(evt, canTriggerImplicitSubmission());

        evt->setDefaultHandled();
        return;
    }

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

    if (evt->isMouseEvent() && evt->type() == EventTypeNames::mousedown) {
        m_inputTypeView->handleMouseDownEvent(toMouseEvent(evt));
        if (evt->defaultHandled())
            return;
    }

    m_inputTypeView->forwardEvent(evt);

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

Project: Chrome

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

Project: Chrome

void HTMLInputElement::detach(const AttachContext& context)
{
    HTMLTextFormControlElement::detach(context);
    setFormControlValueMatchesRenderer(false);
    m_inputTypeView->closePopupView();
}

Project: Chrome

void HTMLInputElement::didAddShadowRoot(ShadowRoot& root)
{
    if (!root.isOldestAuthorShadowRoot())
        return;
    m_inputTypeView->destroyShadowSubtree();
    m_inputTypeView = InputTypeView::create(*this);
    lazyReattachIfAttached();
}

Project: Chrome

void HTMLInputElement::didAddUserAgentShadowRoot(ShadowRoot&)
{
    m_inputTypeView->createShadowSubtree();
}

Project: Chrome

void HTMLInputElement::didMoveToNewDocument(Document& oldDocument)
{
    if (hasImageLoader())
        imageLoader()->elementDidMoveToNewDocument();

    if (isRadioButton())
        oldDocument.formController()->checkedRadioButtons().removeButton(this);
    if (m_hasTouchEventHandler)
        oldDocument.didRemoveEventTargetNode(this);

    if (m_hasTouchEventHandler)
        document().didAddTouchEventHandler(this);

    HTMLTextFormControlElement::didMoveToNewDocument(oldDocument);
}

Project: Chrome

void HTMLInputElement::handleBlurEvent()
{
    m_inputType->disableSecureTextInput();
    m_inputTypeView->handleBlurEvent();
}

Project: Chrome

void HTMLInputElement::handleFocusEvent(Element* oldFocusedElement, FocusDirection direction)
{
    m_inputTypeView->handleFocusEvent(oldFocusedElement, direction);
    m_inputType->enableSecureTextInput();
}

Project: Chrome

bool HTMLInputElement::hasValidDataListOptions() const
{
    HTMLDataListElement* dataList = this->dataList();
    if (!dataList)
        return false;
    RefPtr<HTMLCollection> options = dataList->options();
    for (unsigned i = 0; HTMLOptionElement* option = toHTMLOptionElement(options->item(i)); ++i) {
        if (isValidValue(option->value()))
            return true;
    }
    return false;
}

Project: Chrome

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

Project: Chrome

static bool isValidMIMEType(const String& type)
{
    size_t slashPosition = type.find('/');
    if (slashPosition == kNotFound || !slashPosition || slashPosition == type.length() - 1)
        return false;
    for (size_t i = 0; i < type.length(); ++i) {
        if (!isRFC2616TokenCharacter(type[i]) && i != slashPosition)
            return false;
    }
    return true;
}

Project: Chrome

void HTMLInputElement::listAttributeTargetChanged()
{
    m_inputTypeView->listAttributeTargetChanged();
}

Project: Chrome

void HTMLInputElement::onSearch()
{
    ASSERT(isSearchField());
    if (m_inputType)
        static_cast<SearchInputType*>(m_inputType.get())->stopSearchEventTimer();
    dispatchEvent(Event::createBubble(EventTypeNames::search));
}

Project: Chrome

void HTMLInputElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
    if (name == nameAttr) {
        removeFromRadioButtonGroup();
        m_name = value;
        addToRadioButtonGroup();
        HTMLTextFormControlElement::parseAttribute(name, value);
    } else if (name == autocompleteAttr) {
        if (equalIgnoringCase(value, "off"))
            m_autocomplete = Off;
        else {
            if (value.isEmpty())
                m_autocomplete = Uninitialized;
            else
                m_autocomplete = On;
        }
    } else if (name == typeAttr)
        updateType();
    else if (name == valueAttr) {
        if (!hasDirtyValue()) {
            updatePlaceholderVisibility(false);
            setNeedsStyleRecalc();
        }
        setFormControlValueMatchesRenderer(false);
        setNeedsValidityCheck();
        m_valueAttributeWasUpdatedAfterParsing = !m_parsingInProgress;
        m_inputTypeView->valueAttributeChanged();
    } else if (name == checkedAttr) {
        if (!m_parsingInProgress && m_reflectsCheckedAttribute) {
            setChecked(!value.isNull());
            m_reflectsCheckedAttribute = true;
        }
    } else if (name == maxlengthAttr)
        parseMaxLengthAttribute(value);
    else if (name == sizeAttr) {
        int oldSize = m_size;
        int valueAsInteger = value.toInt();
        m_size = valueAsInteger > 0 ? valueAsInteger : defaultSize;
        if (m_size != oldSize && renderer())
            renderer()->setNeedsLayoutAndPrefWidthsRecalc();
    } else if (name == altAttr)
        m_inputTypeView->altAttributeChanged();
    else if (name == srcAttr)
        m_inputTypeView->srcAttributeChanged();
    else if (name == usemapAttr || name == accesskeyAttr) {
    } else if (name == onsearchAttr) {
        setAttributeEventListener(EventTypeNames::search, createAttributeEventListener(this, name, value));
    } else if (name == resultsAttr) {
        int oldResults = m_maxResults;
        m_maxResults = !value.isNull() ? std::min(value.toInt(), maxSavedResults) : -1;
        if (m_maxResults != oldResults && (m_maxResults <= 0 || oldResults <= 0))
            lazyReattachIfAttached();
        setNeedsStyleRecalc();
        UseCounter::count(document(), UseCounter::ResultsAttribute);
    } else if (name == incrementalAttr) {
        setNeedsStyleRecalc();
        UseCounter::count(document(), UseCounter::IncrementalAttribute);
    } else if (name == minAttr) {
        m_inputTypeView->minOrMaxAttributeChanged();
        m_inputType->sanitizeValueInResponseToMinOrMaxAttributeChange();
        setNeedsValidityCheck();
        UseCounter::count(document(), UseCounter::MinAttribute);
    } else if (name == maxAttr) {
        m_inputTypeView->minOrMaxAttributeChanged();
        setNeedsValidityCheck();
        UseCounter::count(document(), UseCounter::MaxAttribute);
    } else if (name == multipleAttr) {
        m_inputTypeView->multipleAttributeChanged();
        setNeedsValidityCheck();
    } else if (name == stepAttr) {
        m_inputTypeView->stepAttributeChanged();
        setNeedsValidityCheck();
        UseCounter::count(document(), UseCounter::StepAttribute);
    } else if (name == patternAttr) {
        setNeedsValidityCheck();
        UseCounter::count(document(), UseCounter::PatternAttribute);
    } else if (name == precisionAttr) {
        setNeedsValidityCheck();
        UseCounter::count(document(), UseCounter::PrecisionAttribute);
    } else if (name == disabledAttr) {
        HTMLTextFormControlElement::parseAttribute(name, value);
        m_inputTypeView->disabledAttributeChanged();
    } else if (name == readonlyAttr) {
        HTMLTextFormControlElement::parseAttribute(name, value);
        m_inputTypeView->readonlyAttributeChanged();
    } else if (name == listAttr) {
        m_hasNonEmptyList = !value.isEmpty();
        if (m_hasNonEmptyList) {
            resetListAttributeTargetObserver();
            listAttributeTargetChanged();
        }
        UseCounter::count(document(), UseCounter::ListAttribute);
    }
#if ENABLE(INPUT_SPEECH)
    else if (name == webkitspeechAttr) {
        if (RuntimeEnabledFeatures::speechInputEnabled() && m_inputType->shouldRespectSpeechAttribute()) {
            m_inputTypeView->destroyShadowSubtree();
            lazyReattachIfAttached();
            m_inputTypeView->createShadowSubtree();
            setFormControlValueMatchesRenderer(false);
        }
        UseCounter::count(document(), UseCounter::PrefixedSpeechAttribute);
    } else if (name == onwebkitspeechchangeAttr)
        setAttributeEventListener(EventTypeNames::webkitspeechchange, createAttributeEventListener(this, name, value));
#endif
    else if (name == webkitdirectoryAttr) {
        HTMLTextFormControlElement::parseAttribute(name, value);
        UseCounter::count(document(), UseCounter::PrefixedDirectoryAttribute);
    }
    else
        HTMLTextFormControlElement::parseAttribute(name, value);
    m_inputTypeView->attributeChanged();
}

Project: Chrome

HTMLElement* HTMLInputElement::passwordGeneratorButtonElement() const
{
    return toHTMLElement(userAgentShadowRoot()->getElementById(ShadowElementNames::passwordGenerator()));
}

Project: Chrome

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

Project: Chrome

void* HTMLInputElement::preDispatchEventHandler(Event* event)
{
    if (event->type() == EventTypeNames::textInput && m_inputTypeView->shouldSubmitImplicitly(event)) {
        event->stopPropagation();
        return 0;
    }
    if (event->type() != EventTypeNames::click)
        return 0;
    if (!event->isMouseEvent() || toMouseEvent(event)->button() != LeftButton)
        return 0;
    return m_inputTypeView->willDispatchClick().leakPtr();
}

Project: Chrome

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

Project: Chrome

void HTMLInputElement::requiredAttributeChanged()
{
    HTMLTextFormControlElement::requiredAttributeChanged();
    if (CheckedRadioButtons* buttons = checkedRadioButtons())
        buttons->requiredAttributeChanged(this);
    m_inputTypeView->requiredAttributeChanged();
}

Project: Chrome

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

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

Project: Chrome

String HTMLInputElement::selectionDirectionForBinding(ExceptionState& exceptionState) const
{
    if (!m_inputType->supportsSelectionAPI()) {
        exceptionState.throwDOMException(InvalidStateError, "The input element's type ('" + m_inputType->formControlType() + "') does not support selection.");
        return String();
    }
    return HTMLTextFormControlElement::selectionDirection();
}

Project: Chrome

int HTMLInputElement::selectionEndForBinding(ExceptionState& exceptionState) const
{
    if (!m_inputType->supportsSelectionAPI()) {
        exceptionState.throwDOMException(InvalidStateError, "The input element's type ('" + m_inputType->formControlType() + "') does not support selection.");
        return 0;
    }
    return HTMLTextFormControlElement::selectionEnd();
}

Project: Chrome

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

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

    if (CheckedRadioButtons* buttons = checkedRadioButtons())
            buttons->updateCheckedState(this);
    if (renderer() && renderer()->style()->hasAppearance())
        RenderTheme::theme().stateChanged(renderer(), CheckedState);

    setNeedsValidityCheck();

    if (renderer()) {
        if (AXObjectCache* cache = renderer()->document().existingAXObjectCache())
            cache->checkedStateChanged(this);
    }

    if (eventBehavior != DispatchNoEvent && inDocument() && m_inputType->shouldSendChangeEventAfterCheckedChanged()) {
        setTextAsOfLastFormControlChangeEvent(String());
        dispatchFormControlChangeEvent();
    }

    didAffectSelector(AffectedSelectorChecked);
}

Project: Chrome

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

Project: Chrome

void HTMLInputElement::setHeight(unsigned height)
{
    setUnsignedIntegralAttribute(heightAttr, height);
}

Project: Chrome

void HTMLInputElement::setIndeterminate(bool newValue)
{
    if (indeterminate() == newValue)
        return;

    m_isIndeterminate = newValue;

    didAffectSelector(AffectedSelectorIndeterminate);

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

Project: Chrome

void HTMLInputElement::setMaxLength(int maxLength, ExceptionState& exceptionState)
{
    if (maxLength < 0)
        exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(maxLength) + ") is negative.");
    else
        setIntegralAttribute(maxlengthAttr, maxLength);
}

Project: Chrome

void HTMLInputElement::setRangeText(const String& replacement, ExceptionState& exceptionState)
{
    if (!m_inputType->supportsSelectionAPI()) {
        exceptionState.throwDOMException(InvalidStateError, "The input element's type ('" + m_inputType->formControlType() + "') does not support selection.");
        return;
    }

    HTMLTextFormControlElement::setRangeText(replacement, exceptionState);
}

Project: Chrome

void HTMLInputElement::setRangeText(const String& replacement, unsigned start, unsigned end, const String& selectionMode, ExceptionState& exceptionState)
{
    if (!m_inputType->supportsSelectionAPI()) {
        exceptionState.throwDOMException(InvalidStateError, "The input element's type ('" + m_inputType->formControlType() + "') does not support selection.");
        return;
    }

    HTMLTextFormControlElement::setRangeText(replacement, start, end, selectionMode, exceptionState);
}

Project: Chrome

void HTMLInputElement::setSelectionDirectionForBinding(const String& direction, ExceptionState& exceptionState)
{
    if (!m_inputType->supportsSelectionAPI()) {
        exceptionState.throwDOMException(InvalidStateError, "The input element's type ('" + m_inputType->formControlType() + "') does not support selection.");
        return;
    }
    HTMLTextFormControlElement::setSelectionDirection(direction);
}

Project: Chrome

void HTMLInputElement::setSelectionEndForBinding(int end, ExceptionState& exceptionState)
{
    if (!m_inputType->supportsSelectionAPI()) {
        exceptionState.throwDOMException(InvalidStateError, "The input element's type ('" + m_inputType->formControlType() + "') does not support selection.");
        return;
    }
    HTMLTextFormControlElement::setSelectionEnd(end);
}

Project: Chrome

void HTMLInputElement::setSelectionRangeForBinding(int start, int end, ExceptionState& exceptionState)
{
    if (!m_inputType->supportsSelectionAPI()) {
        exceptionState.throwDOMException(InvalidStateError, "The input element's type ('" + m_inputType->formControlType() + "') does not support selection.");
        return;
    }
    HTMLTextFormControlElement::setSelectionRange(start, end);
}

Project: Chrome

void HTMLInputElement::setSelectionRangeForBinding(int start, int end, const String& direction, ExceptionState& exceptionState)
{
    if (!m_inputType->supportsSelectionAPI()) {
        exceptionState.throwDOMException(InvalidStateError, "The input element's type ('" + m_inputType->formControlType() + "') does not support selection.");
        return;
    }
    HTMLTextFormControlElement::setSelectionRange(start, end, direction);
}

Project: Chrome

void HTMLInputElement::setSize(unsigned size)
{
    setUnsignedIntegralAttribute(sizeAttr, size);
}

Project: Chrome

void HTMLInputElement::setSize(unsigned size, ExceptionState& exceptionState)
{
    if (!size)
        exceptionState.throwDOMException(IndexSizeError, "The value provided is 0, which is an invalid size.");
    else
        setSize(size);
}

Project: Chrome

void HTMLInputElement::setSuggestedValue(const String& value)
{
    if (!m_inputType->canSetSuggestedValue())
        return;
    setFormControlValueMatchesRenderer(false);
    m_suggestedValue = sanitizeValue(value);
    setNeedsStyleRecalc();
    m_inputTypeView->updateView();
}

Project: Chrome

void HTMLInputElement::setType(const AtomicString& type)
{
    if (type.isEmpty())
        removeAttribute(typeAttr);
    else
        setAttribute(typeAttr, type);
}

Project: Chrome

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

    RefPtr<HTMLInputElement> protector(this);
    EventQueueScope scope;
    String sanitizedValue = sanitizeValue(value);
    bool valueChanged = sanitizedValue != this->value();

    setLastChangeWasNotUserEdit();
    setFormControlValueMatchesRenderer(false);
    m_suggestedValue = String(); // Prevent TextFieldInputType::setValue from using the suggested value.

    m_inputType->setValue(sanitizedValue, valueChanged, eventBehavior);

    if (valueChanged && eventBehavior == DispatchNoEvent)
        setTextAsOfLastFormControlChangeEvent(sanitizedValue);

    if (!valueChanged)
        return;

    notifyFormStateChanged();
}

Project: Chrome

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

Project: Chrome

void HTMLInputElement::setValueAsNumber(double newValue, ExceptionState& exceptionState, TextFieldEventBehavior eventBehavior)
{
    if (!std::isfinite(newValue)) {
        exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::notAFiniteNumber(newValue));
        return;
    }
    m_inputType->setValueAsDouble(newValue, eventBehavior, exceptionState);
}

Project: Chrome

void HTMLInputElement::setValueFromRenderer(const String& value)
{
    ASSERT(!isFileUpload());

    m_suggestedValue = String();

    ASSERT(value == sanitizeValue(value) || sanitizeValue(value).isEmpty());

    m_valueIfDirty = value;

    setFormControlValueMatchesRenderer(true);

    if (!isTextField())
        dispatchInputEvent();
    notifyFormStateChanged();

    setNeedsValidityCheck();

    setAutofilled(false);
}

Project: Chrome

void HTMLInputElement::setWidth(unsigned width)
{
    setUnsignedIntegralAttribute(widthAttr, width);
}

Project: Chrome

bool HTMLInputElement::setupDateTimeChooserParameters(DateTimeChooserParameters& parameters)
{
    if (!document().view())
        return false;

    parameters.type = type();
    parameters.minimum = minimum();
    parameters.maximum = maximum();
    parameters.required = isRequired();
    if (!RuntimeEnabledFeatures::langAttributeAwareFormControlUIEnabled())
        parameters.locale = defaultLanguage();
    else {
        AtomicString computedLocale = computeInheritedLanguage();
        parameters.locale = computedLocale.isEmpty() ? defaultLanguage() : computedLocale;
    }

    StepRange stepRange = createStepRange(RejectAny);
    if (stepRange.hasStep()) {
        parameters.step = stepRange.step().toDouble();
        parameters.stepBase = stepRange.stepBase().toDouble();
    } else {
        parameters.step = 1.0;
        parameters.stepBase = 0;
    }

    parameters.anchorRectInRootView = document().view()->contentsToRootView(pixelSnappedBoundingBox());
    parameters.currentValue = value();
    parameters.doubleValue = m_inputType->valueAsDouble();
    parameters.isAnchorElementRTL = computedStyle()->direction() == RTL;
    if (RuntimeEnabledFeatures::dataListElementEnabled()) {
        if (HTMLDataListElement* dataList = this->dataList()) {
            RefPtr<HTMLCollection> options = dataList->options();
            for (unsigned i = 0; HTMLOptionElement* option = toHTMLOptionElement(options->item(i)); ++i) {
                if (!isValidValue(option->value()))
                    continue;
                DateTimeSuggestion suggestion;
                suggestion.value = m_inputType->parseToNumber(option->value(), Decimal::nan()).toDouble();
                if (std::isnan(suggestion.value))
                    continue;
                suggestion.localizedValue = localizeValue(option->value());
                suggestion.label = option->value() == option->label() ? String() : option->label();
                parameters.suggestions.append(suggestion);
            }
        }
    }
    return true;
}

Project: Chrome

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

Project: Chrome

bool HTMLInputElement::sizeShouldIncludeDecoration(int& preferredSize) const
{
    return m_inputTypeView->sizeShouldIncludeDecoration(defaultSize, preferredSize);
}

Project: Chrome

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

Project: Chrome

void HTMLInputElement::stepUp(int n, ExceptionState& exceptionState)
{
    m_inputType->stepUp(n, exceptionState);
}

Project: Chrome

void HTMLInputElement::subtreeHasChanged()
{
    m_inputTypeView->subtreeHasChanged();
    calculateAndAdjustDirectionality();
}

Project: Chrome

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

Project: Chrome

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

Project: Chrome

bool HTMLInputElement::tooLong(const String& value, NeedsToCheckDirtyFlag check) const
{
    if (!isTextType())
        return false;
    int max = maxLength();
    if (max < 0)
        return false;
    if (check == CheckDirtyFlag) {
        if (!hasDirtyValue() || !lastChangeWasUserEdit())
            return false;
    }
    return value.length() > static_cast<unsigned>(max);
}

Project: Chrome

void HTMLInputElement::updateClearButtonVisibility()
{
    m_inputTypeView->updateClearButtonVisibility();
}

Project: Chrome

HTMLInputElement::~HTMLInputElement()
{
    setForm(0);
    if (isRadioButton())
        document().formController()->checkedRadioButtons().removeButton(this);
    if (m_hasTouchEventHandler)
        document().didRemoveEventTargetNode(this);
}

Project: Chrome

HTMLKeygenElement::HTMLKeygenElement(Document& document, HTMLFormElement* form)
    : HTMLFormControlElementWithState(keygenTag, document, form)
{
    ScriptWrappable::init(this);
    ensureUserAgentShadowRoot();
}

Project: Chrome

bool HTMLKeygenElement::appendFormData(FormDataList& encoding, bool)
{
    const AtomicString& keyType = fastGetAttribute(keytypeAttr);
    if (!keyType.isNull() && !equalIgnoringCase(keyType, "rsa"))
        return false;
    String value = signedPublicKeyAndChallengeString(shadowSelect()->selectedIndex(), fastGetAttribute(challengeAttr), document().baseURL());
    if (value.isNull())
        return false;
    encoding.appendData(name(), value.utf8());
    return true;
}

Project: Chrome

void HTMLKeygenElement::didAddUserAgentShadowRoot(ShadowRoot& root)
{
    DEFINE_STATIC_LOCAL(AtomicString, keygenSelectPseudoId, ("-webkit-keygen-select", AtomicString::ConstructFromLiteral));

    Vector<String> keys;
    getSupportedKeySizes(locale(), keys);

    RefPtr<HTMLSelectElement> select = HTMLSelectElement::create(document());
    select->setShadowPseudoId(keygenSelectPseudoId);
    for (size_t i = 0; i < keys.size(); ++i) {
        RefPtr<HTMLOptionElement> option = HTMLOptionElement::create(document());
        option->appendChild(Text::create(document(), keys[i]));
        select->appendChild(option);
    }

    root.appendChild(select);
}

Project: Chrome

const AtomicString& HTMLKeygenElement::formControlType() const
{
    DEFINE_STATIC_LOCAL(const AtomicString, keygen, ("keygen", AtomicString::ConstructFromLiteral));
    return keygen;
}

Project: Chrome

bool HTMLKeygenElement::isInteractiveContent() const
{
     return true;
 }

Project: Chrome

void HTMLKeygenElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
    if (name == disabledAttr)
        shadowSelect()->setAttribute(name, value);

    HTMLFormControlElement::parseAttribute(name, value);
}

Project: Chrome

void HTMLKeygenElement::resetImpl()
{
    shadowSelect()->reset();
}

Project: Chrome

HTMLSelectElement* HTMLKeygenElement::shadowSelect() const
{
    ShadowRoot* root = userAgentShadowRoot();
    return root ? toHTMLSelectElement(root->firstChild()) : 0;
}

Project: Chrome

HTMLSelectElement::HTMLSelectElement(Document& document, HTMLFormElement* form, bool createdByParser)
    : HTMLFormControlElementWithState(selectTag, document, form)
    , m_typeAhead(this)
    , m_size(0)
    , m_lastOnChangeIndex(-1)
    , m_activeSelectionAnchorIndex(-1)
    , m_activeSelectionEndIndex(-1)
    , m_isProcessingUserDrivenChange(false)
    , m_multiple(false)
    , m_activeSelectionState(false)
    , m_shouldRecalcListItems(false)
    , m_isParsingInProgress(createdByParser)
{
    ScriptWrappable::init(this);
}

Project: Chrome

bool HTMLSelectElement::anonymousIndexedSetter(unsigned index, PassRefPtr<HTMLOptionElement> value, ExceptionState& exceptionState)
{
    if (!value) {
        exceptionState.throwTypeError(ExceptionMessages::failedToSet(String::number(index), "HTMLSelectElement", "The value provided was not an HTMLOptionElement."));
        return false;
    }
    setOption(index, value.get(), exceptionState);
    return true;
}

Project: Chrome

bool HTMLSelectElement::anonymousIndexedSetterRemove(unsigned index, ExceptionState& exceptionState)
{
    remove(index);
    return true;
}

Project: Chrome

PassRefPtr<HTMLSelectElement> HTMLSelectElement::create(Document& document)
{
    return adoptRef(new HTMLSelectElement(document, 0, false));
}

Project: Chrome

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

Project: Chrome

RenderObject* HTMLSelectElement::createRenderer(RenderStyle*)
{
    if (usesMenuList())
        return new RenderMenuList(this);
    return new RenderListBox(this);
}

Project: Chrome

void HTMLSelectElement::defaultEventHandler(Event* event)
{
    if (!renderer())
        return;

    if (isDisabledFormControl()) {
        HTMLFormControlElementWithState::defaultEventHandler(event);
        return;
    }

    if (usesMenuList())
        menuListDefaultEventHandler(event);
    else
        listBoxDefaultEventHandler(event);
    if (event->defaultHandled())
        return;

    if (event->type() == EventTypeNames::keypress && event->isKeyboardEvent()) {
        KeyboardEvent* keyboardEvent = toKeyboardEvent(event);
        if (!keyboardEvent->ctrlKey() && !keyboardEvent->altKey() && !keyboardEvent->metaKey() && isPrintableChar(keyboardEvent->charCode())) {
            typeAheadFind(keyboardEvent);
            event->setDefaultHandled();
            return;
        }
    }
    HTMLFormControlElementWithState::defaultEventHandler(event);
}

Project: Chrome

void HTMLSelectElement::dispatchBlurEvent(Element* newFocusedElement)
{
    if (usesMenuList())
        dispatchChangeEventForMenuList();
    HTMLFormControlElementWithState::dispatchBlurEvent(newFocusedElement);
}

Project: Chrome

void HTMLSelectElement::dispatchFocusEvent(Element* oldFocusedElement, FocusDirection direction)
{
    if (usesMenuList())
        saveLastSelection();
    HTMLFormControlElementWithState::dispatchFocusEvent(oldFocusedElement, direction);
}

Project: Chrome

bool HTMLSelectElement::isInteractiveContent() const
{
     return true;
 }

Project: Chrome

void HTMLSelectElement::listBoxDefaultEventHandler(Event* event)
{
    const Vector<HTMLElement*>& listItems = this->listItems();
    bool dragSelection = false;
    if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
        focus();
        if (!renderer())
            return;

        MouseEvent* mouseEvent = toMouseEvent(event);
        IntPoint localOffset = roundedIntPoint(renderer()->absoluteToLocal(mouseEvent->absoluteLocation(), UseTransforms));
        int listIndex = toRenderListBox(renderer())->listIndexAtOffset(toIntSize(localOffset));
        if (listIndex >= 0) {
            if (!isDisabledFormControl()) {
#if OS(MACOSX)
                updateSelectedState(listIndex, mouseEvent->metaKey(), mouseEvent->shiftKey());
#else
                updateSelectedState(listIndex, mouseEvent->ctrlKey(), mouseEvent->shiftKey());
#endif
            }
            if (Frame* frame = document().frame())
                frame->eventHandler().setMouseDownMayStartAutoscroll();

            event->setDefaultHandled();
        }
    } else if (event->type() == EventTypeNames::mousemove && event->isMouseEvent() && !toRenderBox(renderer())->canBeScrolledAndHasScrollableArea()) {
        MouseEvent* mouseEvent = toMouseEvent(event);
        if (mouseEvent->button() != LeftButton || !mouseEvent->buttonDown())
            return;

        IntPoint localOffset = roundedIntPoint(renderer()->absoluteToLocal(mouseEvent->absoluteLocation(), UseTransforms));
        int listIndex = toRenderListBox(renderer())->listIndexAtOffset(toIntSize(localOffset));
        if (listIndex >= 0) {
            if (!isDisabledFormControl()) {
                if (m_multiple) {
                    if (m_activeSelectionAnchorIndex < 0)
                        return;

                    setActiveSelectionEndIndex(listIndex);
                    updateListBoxSelection(false);
                } else {
                    setActiveSelectionAnchorIndex(listIndex);
                    setActiveSelectionEndIndex(listIndex);
                    updateListBoxSelection(true);
                }
            }
            dragSelection = true;
        }
    } else if (event->type() == EventTypeNames::mouseup && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton && renderer() && !toRenderBox(renderer())->autoscrollInProgress()) {
        if (m_lastOnChangeSelection.isEmpty())
            return;
        if (!dragSelection) {
            listBoxOnChange();
        }
    } else if (event->type() == EventTypeNames::keydown) {
        if (!event->isKeyboardEvent())
            return;
        const String& keyIdentifier = toKeyboardEvent(event)->keyIdentifier();

        bool handled = false;
        int endIndex = 0;
        if (m_activeSelectionEndIndex < 0) {
            if (keyIdentifier == "Down" || keyIdentifier == "PageDown") {
                int startIndex = lastSelectedListIndex();
                handled = true;
                if (keyIdentifier == "Down")
                    endIndex = nextSelectableListIndex(startIndex);
                else
                    endIndex = nextSelectableListIndexPageAway(startIndex, SkipForwards);
            } else if (keyIdentifier == "Up" || keyIdentifier == "PageUp") {
                int startIndex = optionToListIndex(selectedIndex());
                handled = true;
                if (keyIdentifier == "Up")
                    endIndex = previousSelectableListIndex(startIndex);
                else
                    endIndex = nextSelectableListIndexPageAway(startIndex, SkipBackwards);
            }
        } else {
            if (keyIdentifier == "Down") {
                endIndex = nextSelectableListIndex(m_activeSelectionEndIndex);
                handled = true;
            } else if (keyIdentifier == "Up") {
                endIndex = previousSelectableListIndex(m_activeSelectionEndIndex);
                handled = true;
            } else if (keyIdentifier == "PageDown") {
                endIndex = nextSelectableListIndexPageAway(m_activeSelectionEndIndex, SkipForwards);
                handled = true;
            } else if (keyIdentifier == "PageUp") {
                endIndex = nextSelectableListIndexPageAway(m_activeSelectionEndIndex, SkipBackwards);
                handled = true;
            }
        }
        if (keyIdentifier == "Home") {
            endIndex = firstSelectableListIndex();
            handled = true;
        } else if (keyIdentifier == "End") {
            endIndex = lastSelectableListIndex();
            handled = true;
        }

        if (isSpatialNavigationEnabled(document().frame()))
            if (keyIdentifier == "Left" || keyIdentifier == "Right" || ((keyIdentifier == "Down" || keyIdentifier == "Up") && endIndex == m_activeSelectionEndIndex))
                return;

        if (endIndex >= 0 && handled) {
            saveLastSelection();

            ASSERT_UNUSED(listItems, !listItems.size() || static_cast<size_t>(endIndex) < listItems.size());
            setActiveSelectionEndIndex(endIndex);

            bool selectNewItem = !m_multiple || toKeyboardEvent(event)->shiftKey() || !isSpatialNavigationEnabled(document().frame());
            if (selectNewItem)
                m_activeSelectionState = true;
            bool deselectOthers = !m_multiple || (!toKeyboardEvent(event)->shiftKey() && selectNewItem);
            if (m_activeSelectionAnchorIndex < 0 || deselectOthers) {
                if (deselectOthers)
                    deselectItemsWithoutValidation();
                setActiveSelectionAnchorIndex(m_activeSelectionEndIndex);
            }

            toRenderListBox(renderer())->scrollToRevealElementAtListIndex(endIndex);
            if (selectNewItem) {
                updateListBoxSelection(deselectOthers);
                listBoxOnChange();
            } else
                scrollToSelection();

            event->setDefaultHandled();
        }
    } else if (event->type() == EventTypeNames::keypress) {
        if (!event->isKeyboardEvent())
            return;
        int keyCode = toKeyboardEvent(event)->keyCode();

        if (keyCode == '\r') {
            if (form())
                form()->submitImplicitly(event, false);
            event->setDefaultHandled();
        } else if (m_multiple && keyCode == ' ' && isSpatialNavigationEnabled(document().frame())) {
            m_activeSelectionState = !m_activeSelectionState;
            updateSelectedState(listToOptionIndex(m_activeSelectionEndIndex), true /*multi*/, false /*shift*/);
            listBoxOnChange();
            event->setDefaultHandled();
        }
    }
}

Project: Chrome

void HTMLSelectElement::menuListDefaultEventHandler(Event* event)
{
    RenderTheme& renderTheme = RenderTheme::theme();

    if (event->type() == EventTypeNames::keydown) {
        if (!renderer() || !event->isKeyboardEvent())
            return;

        if (platformHandleKeydownEvent(toKeyboardEvent(event)))
            return;

        if (isSpatialNavigationEnabled(document().frame())) {
            if (!m_activeSelectionState)
                return;
        }

        const String& keyIdentifier = toKeyboardEvent(event)->keyIdentifier();
        bool handled = true;
        const Vector<HTMLElement*>& listItems = this->listItems();
        int listIndex = optionToListIndex(selectedIndex());

        if (keyIdentifier == "Down" || keyIdentifier == "Right")
            listIndex = nextValidIndex(listIndex, SkipForwards, 1);
        else if (keyIdentifier == "Up" || keyIdentifier == "Left")
            listIndex = nextValidIndex(listIndex, SkipBackwards, 1);
        else if (keyIdentifier == "PageDown")
            listIndex = nextValidIndex(listIndex, SkipForwards, 3);
        else if (keyIdentifier == "PageUp")
            listIndex = nextValidIndex(listIndex, SkipBackwards, 3);
        else if (keyIdentifier == "Home")
            listIndex = nextValidIndex(-1, SkipForwards, 1);
        else if (keyIdentifier == "End")
            listIndex = nextValidIndex(listItems.size(), SkipBackwards, 1);
        else
            handled = false;

        if (handled && static_cast<size_t>(listIndex) < listItems.size())
            selectOption(listToOptionIndex(listIndex), DeselectOtherOptions | DispatchChangeEvent | UserDriven);

        if (handled)
            event->setDefaultHandled();
    }

    if (event->type() == EventTypeNames::keypress) {
        if (!renderer() || !event->isKeyboardEvent())
            return;

        int keyCode = toKeyboardEvent(event)->keyCode();
        bool handled = false;

        if (keyCode == ' ' && isSpatialNavigationEnabled(document().frame())) {
            m_activeSelectionState = !m_activeSelectionState;
            event->setDefaultHandled();
            return;
        }

        if (renderTheme.popsMenuBySpaceOrReturn()) {
            if (keyCode == ' ' || keyCode == '\r') {
                focus();

                if (!renderer() || !renderer()->isMenuList())
                    return;

                saveLastSelection();
                if (RenderMenuList* menuList = toRenderMenuList(renderer()))
                    menuList->showPopup();
                handled = true;
            }
        } else if (renderTheme.popsMenuByArrowKeys()) {
            if (keyCode == ' ') {
                focus();

                if (!renderer() || !renderer()->isMenuList())
                    return;

                saveLastSelection();
                if (RenderMenuList* menuList = toRenderMenuList(renderer()))
                    menuList->showPopup();
                handled = true;
            } else if (keyCode == '\r') {
                if (form())
                    form()->submitImplicitly(event, false);
                dispatchChangeEventForMenuList();
                handled = true;
            }
        }

        if (handled)
            event->setDefaultHandled();
    }

    if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
        focus();
        if (renderer() && renderer()->isMenuList()) {
            if (RenderMenuList* menuList = toRenderMenuList(renderer())) {
                if (menuList->popupIsVisible())
                    menuList->hidePopup();
                else {
                    saveLastSelection();
                    menuList->showPopup();
                }
            }
        }
        event->setDefaultHandled();
    }

    if (event->type() == EventTypeNames::blur) {
        if (RenderMenuList* menuList = toRenderMenuList(renderer())) {
            if (menuList->popupIsVisible())
                menuList->hidePopup();
        }
    }
}

Project: Chrome

String HTMLSelectElement::optionAtIndex(int index) const
{
    const Vector<HTMLElement*>& items = listItems();

    HTMLElement* element = items[index];
    if (!element->hasTagName(optionTag) || toHTMLOptionElement(element)->isDisabledFormControl())
        return String();
    return toHTMLOptionElement(element)->textIndentedToRespectGroupLabel();
}

Project: Chrome

void HTMLSelectElement::optionElementChildrenChanged()
{
    setRecalcListItems();
    setNeedsValidityCheck();

    if (renderer()) {
        if (AXObjectCache* cache = renderer()->document().existingAXObjectCache())
            cache->childrenChanged(this);
    }
}

Project: Chrome

void HTMLSelectElement::optionSelectionStateChanged(HTMLOptionElement* option, bool optionIsSelected)
{
    ASSERT(option->ownerSelectElement() == this);
    if (optionIsSelected)
        selectOption(option->index());
    else if (!usesMenuList() || multiple())
        selectOption(-1);
    else
        selectOption(nextSelectableListIndex(-1));
}

Project: Chrome

void HTMLSelectElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
    if (name == sizeAttr) {
        int oldSize = m_size;
        int size = value.toInt();
        AtomicString attrSize = AtomicString::number(size);
        if (attrSize != value) {
            if (Attribute* sizeAttribute = ensureUniqueElementData()->getAttributeItem(sizeAttr))
                sizeAttribute->setValue(attrSize);
        }
        size = max(size, 1);

        if (oldSize != size)
            updateListItemSelectedStates();

        m_size = size;
        setNeedsValidityCheck();
        if (m_size != oldSize && inActiveDocument()) {
            lazyReattachIfAttached();
            setRecalcListItems();
        }
    } else if (name == multipleAttr)
        parseMultipleAttribute(value);
    else if (name == accesskeyAttr) {
    } else
        HTMLFormControlElementWithState::parseAttribute(name, value);
}

Project: Chrome

bool HTMLSelectElement::platformHandleKeydownEvent(KeyboardEvent* event)
{
    if (!RenderTheme::theme().popsMenuByArrowKeys())
        return false;

    if (!isSpatialNavigationEnabled(document().frame())) {
        if (event->keyIdentifier() == "Down" || event->keyIdentifier() == "Up") {
            focus();
            if (!renderer())
                return true;

            saveLastSelection();
            if (RenderMenuList* menuList = toRenderMenuList(renderer()))
                menuList->showPopup();
            event->setDefaultHandled();
        }
        return true;
    }

    return false;
}

Project: Chrome

void HTMLSelectElement::recalcListItems(bool updateSelectedStates) const
{
    m_listItems.clear();

    m_shouldRecalcListItems = false;

    HTMLOptionElement* foundSelected = 0;
    HTMLOptionElement* firstOption = 0;
    for (Element* currentElement = ElementTraversal::firstWithin(*this); currentElement; ) {
        if (!currentElement->isHTMLElement()) {
            currentElement = ElementTraversal::nextSkippingChildren(*currentElement, this);
            continue;
        }
        HTMLElement& current = toHTMLElement(*currentElement);

        if (current.hasTagName(optgroupTag)) {
            m_listItems.append(&current);
            if (Element* nextElement = ElementTraversal::firstWithin(current)) {
                currentElement = nextElement;
                continue;
            }
        }

        if (current.hasTagName(optionTag)) {
            m_listItems.append(&current);

            if (updateSelectedStates && !m_multiple) {
                HTMLOptionElement& option = toHTMLOptionElement(current);
                if (!firstOption)
                    firstOption = &option;
                if (option.selected()) {
                    if (foundSelected)
                        foundSelected->setSelectedState(false);
                    foundSelected = &option;
                } else if (m_size <= 1 && !foundSelected && !option.isDisabledFormControl()) {
                    foundSelected = &option;
                    foundSelected->setSelectedState(true);
                }
            }
        }

        if (current.hasTagName(hrTag))
            m_listItems.append(&current);

        currentElement = ElementTraversal::nextSkippingChildren(*currentElement, this);
    }

    if (!foundSelected && m_size <= 1 && firstOption && !firstOption->selected())
        firstOption->setSelectedState(true);
}

Project: Chrome

void HTMLSelectElement::resetImpl()
{
    HTMLOptionElement* firstOption = 0;
    HTMLOptionElement* selectedOption = 0;

    const Vector<HTMLElement*>& items = listItems();
    for (unsigned i = 0; i < items.size(); ++i) {
        HTMLElement* element = items[i];
        if (!element->hasTagName(optionTag))
            continue;

        if (items[i]->fastHasAttribute(selectedAttr)) {
            if (selectedOption && !m_multiple)
                selectedOption->setSelectedState(false);
            toHTMLOptionElement(element)->setSelectedState(true);
            selectedOption = toHTMLOptionElement(element);
        } else
            toHTMLOptionElement(element)->setSelectedState(false);

        if (!firstOption)
            firstOption = toHTMLOptionElement(element);
    }

    if (!selectedOption && firstOption && !m_multiple && m_size <= 1)
        firstOption->setSelectedState(true);

    setOptionsChangedOnRenderer();
    setNeedsStyleRecalc();
    setNeedsValidityCheck();
}

Project: Chrome

void HTMLSelectElement::restoreFormControlState(const FormControlState& state)
{
    recalcListItems();

    const Vector<HTMLElement*>& items = listItems();
    size_t itemsSize = items.size();
    if (!itemsSize)
        return;

    for (size_t i = 0; i < itemsSize; ++i) {
        if (!items[i]->hasLocalName(optionTag))
            continue;
        toHTMLOptionElement(items[i])->setSelectedState(false);
    }

    if (!multiple()) {
        size_t foundIndex = searchOptionsForValue(state[0], 0, itemsSize);
        if (foundIndex != kNotFound)
            toHTMLOptionElement(items[foundIndex])->setSelectedState(true);
    } else {
        size_t startIndex = 0;
        for (size_t i = 0; i < state.valueSize(); ++i) {
            const String& value = state[i];
            size_t foundIndex = searchOptionsForValue(value, startIndex, itemsSize);
            if (foundIndex == kNotFound)
                foundIndex = searchOptionsForValue(value, 0, startIndex);
            if (foundIndex == kNotFound)
                continue;
            toHTMLOptionElement(items[foundIndex])->setSelectedState(true);
            startIndex = foundIndex + 1;
        }
    }

    setOptionsChangedOnRenderer();
    setNeedsValidityCheck();
}

Project: Chrome

size_t HTMLSelectElement::searchOptionsForValue(const String& value, size_t listIndexStart, size_t listIndexEnd) const
{
    const Vector<HTMLElement*>& items = listItems();
    size_t loopEndIndex = std::min(items.size(), listIndexEnd);
    for (size_t i = listIndexStart; i < loopEndIndex; ++i) {
        if (!items[i]->hasLocalName(optionTag))
            continue;
        if (toHTMLOptionElement(items[i])->value() == value)
            return i;
    }
    return kNotFound;
}

Project: Chrome

void HTMLSelectElement::setMultiple(bool multiple)
{
    bool oldMultiple = this->multiple();
    int oldSelectedIndex = selectedIndex();
    setAttribute(multipleAttr, multiple ? emptyAtom : nullAtom);

    if (oldMultiple != this->multiple())
        setSelectedIndex(oldSelectedIndex);
}

Project: Chrome

void HTMLSelectElement::setOption(unsigned index, HTMLOptionElement* option, ExceptionState& exceptionState)
{
    if (index > maxSelectItems - 1)
        index = maxSelectItems - 1;
    int diff = index - length();
    RefPtr<HTMLElement> before = 0;
    if (diff > 0) {
        setLength(index, exceptionState);
    } else if (diff < 0) {
        before = toHTMLElement(options()->item(index+1));
        remove(index);
    }
    if (!exceptionState.hadException()) {
        add(option, before.get(), exceptionState);
        if (diff >= 0 && option->selected())
            optionSelectionStateChanged(option, true);
    }
}

Project: Chrome

void HTMLSelectElement::setRecalcListItems()
{

    m_shouldRecalcListItems = true;
    m_activeSelectionAnchorIndex = -1;
    setOptionsChangedOnRenderer();
    setNeedsStyleRecalc();
    if (!inDocument()) {
        if (HTMLCollection* collection = cachedHTMLCollection(SelectOptions))
            collection->invalidateCache();
    }
    if (!inDocument())
        invalidateSelectedItems();

    if (renderer()) {
        if (AXObjectCache* cache = renderer()->document().existingAXObjectCache())
            cache->childrenChanged(this);
    }
}

Project: Chrome

void HTMLSelectElement::setSize(int size)
{
    setIntegralAttribute(sizeAttr, size);
}

Project: Chrome

bool HTMLSelectElement::usesMenuList() const
{
    if (RenderTheme::theme().delegatesMenuListRendering())
        return true;

    return !m_multiple && m_size <= 1;
}

Project: Chrome

String HTMLSelectElement::validationMessage() const
{
    if (!willValidate())
        return String();
    if (customError())
        return customValidationMessage();
    if (valueMissing())
        return locale().queryString(blink::WebLocalizedString::ValidationValueMissingForSelect);
    return String();
}

Project: Chrome

HTMLTextAreaElement::HTMLTextAreaElement(Document& document, HTMLFormElement* form)
    : HTMLTextFormControlElement(textareaTag, document, form)
    , m_rows(defaultRows)
    , m_cols(defaultCols)
    , m_wrap(SoftWrap)
    , m_isDirty(false)
{
    setFormControlValueMatchesRenderer(true);
    ScriptWrappable::init(this);
}

Project: Chrome

void HTMLTextAreaElement::accessKeyAction(bool)
{
    focus();
}

Project: Chrome

bool HTMLTextAreaElement::appendFormData(FormDataList& encoding, bool)
{
    if (name().isEmpty())
        return false;

    document().updateLayout();

    const String& text = (m_wrap == HardWrap) ? valueWithHardLineBreaks() : value();
    encoding.appendData(name(), text);

    const AtomicString& dirnameAttrValue = fastGetAttribute(dirnameAttr);
    if (!dirnameAttrValue.isNull())
        encoding.appendData(dirnameAttrValue, directionForFormData());
    return true;
}

Project: Chrome

void HTMLTextAreaElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
    HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
    setLastChangeWasNotUserEdit();
    if (m_isDirty)
        setInnerTextValue(value());
    else
        setNonDirtyValue(defaultValue());
}

Project: Chrome

void HTMLTextAreaElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style)
{
    if (name == wrapAttr) {
        if (shouldWrapText()) {
            addPropertyToPresentationAttributeStyle(style, CSSPropertyWhiteSpace, CSSValuePreWrap);
            addPropertyToPresentationAttributeStyle(style, CSSPropertyWordWrap, CSSValueBreakWord);
        } else {
            addPropertyToPresentationAttributeStyle(style, CSSPropertyWhiteSpace, CSSValuePre);
            addPropertyToPresentationAttributeStyle(style, CSSPropertyWordWrap, CSSValueNormal);
        }
    } else
        HTMLTextFormControlElement::collectStyleForPresentationAttribute(name, value, style);
}

Project: Chrome

static inline unsigned computeLengthForSubmission(const String& text)
{
    return text.length() + numberOfLineBreaks(text);
}

Project: Chrome

PassRefPtr<HTMLTextAreaElement> HTMLTextAreaElement::create(Document& document, HTMLFormElement* form)
{
    RefPtr<HTMLTextAreaElement> textArea = adoptRef(new HTMLTextAreaElement(document, form));
    textArea->ensureUserAgentShadowRoot();
    return textArea.release();
}

Project: Chrome

RenderObject* HTMLTextAreaElement::createRenderer(RenderStyle*)
{
    return new RenderTextControlMultiLine(this);
}

Project: Chrome

void HTMLTextAreaElement::defaultEventHandler(Event* event)
{
    if (renderer() && (event->isMouseEvent() || event->isDragEvent() || event->hasInterface(EventNames::WheelEvent) || event->type() == EventTypeNames::blur))
        forwardEvent(event);
    else if (renderer() && event->isBeforeTextInsertedEvent())
        handleBeforeTextInsertedEvent(static_cast<BeforeTextInsertedEvent*>(event));

    HTMLTextFormControlElement::defaultEventHandler(event);
}

Project: Chrome

void HTMLTextAreaElement::didAddUserAgentShadowRoot(ShadowRoot& root)
{
    root.appendChild(TextControlInnerTextElement::create(document()));
}

Project: Chrome

const AtomicString& HTMLTextAreaElement::formControlType() const
{
    DEFINE_STATIC_LOCAL(const AtomicString, textarea, ("textarea", AtomicString::ConstructFromLiteral));
    return textarea;
}

Project: Chrome

void HTMLTextAreaElement::handleFocusEvent(Element*, FocusDirection)
{
    if (Frame* frame = document().frame())
        frame->spellChecker().didBeginEditing(this);
}

Project: Chrome

bool HTMLTextAreaElement::hasCustomFocusLogic() const
{
    return true;
}

Project: Chrome

bool HTMLTextAreaElement::isInteractiveContent() const
{
     return true;
 }

Project: Chrome

bool HTMLTextAreaElement::isKeyboardFocusable() const
{
    return isFocusable();
}

Project: Chrome

bool HTMLTextAreaElement::isPresentationAttribute(const QualifiedName& name) const
{
    if (name == alignAttr) {
        return false;
    }

    if (name == wrapAttr)
        return true;
    return HTMLTextFormControlElement::isPresentationAttribute(name);
}

Project: Chrome

bool HTMLTextAreaElement::isValidValue(const String& candidate) const
{
    return !valueMissing(candidate) && !tooLong(candidate, IgnoreDirtyFlag);
}

Project: Chrome

bool HTMLTextAreaElement::matchesReadOnlyPseudoClass() const
{
    return isReadOnly();
}

Project: Chrome

int HTMLTextAreaElement::maxLength() const
{
    bool ok;
    int value = getAttribute(maxlengthAttr).string().toInt(&ok);
    return ok && value >= 0 ? value : -1;
}

Project: Chrome

void HTMLTextAreaElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
    if (name == rowsAttr) {
        int rows = value.toInt();
        if (rows <= 0)
            rows = defaultRows;
        if (m_rows != rows) {
            m_rows = rows;
            if (renderer())
                renderer()->setNeedsLayoutAndPrefWidthsRecalc();
        }
    } else if (name == colsAttr) {
        int cols = value.toInt();
        if (cols <= 0)
            cols = defaultCols;
        if (m_cols != cols) {
            m_cols = cols;
            if (renderer())
                renderer()->setNeedsLayoutAndPrefWidthsRecalc();
        }
    } else if (name == wrapAttr) {
        WrapMethod wrap;
        if (equalIgnoringCase(value, "physical") || equalIgnoringCase(value, "hard") || equalIgnoringCase(value, "on"))
            wrap = HardWrap;
        else if (equalIgnoringCase(value, "off"))
            wrap = NoWrap;
        else
            wrap = SoftWrap;
        if (wrap != m_wrap) {
            m_wrap = wrap;
            if (renderer())
                renderer()->setNeedsLayoutAndPrefWidthsRecalc();
        }
    } else if (name == accesskeyAttr) {
    } else if (name == maxlengthAttr)
        setNeedsValidityCheck();
    else
        HTMLTextFormControlElement::parseAttribute(name, value);
}

Project: Chrome

void HTMLTextAreaElement::resetImpl()
{
    setNonDirtyValue(defaultValue());
}

Project: Chrome

void HTMLTextAreaElement::restoreFormControlState(const FormControlState& state)
{
    setValue(state[0]);
}

Project: Chrome

String HTMLTextAreaElement::sanitizeUserInputValue(const String& proposedValue, unsigned maxLength)
{
    if (maxLength > 0 && U16_IS_LEAD(proposedValue[maxLength - 1]))
        --maxLength;
    return proposedValue.left(maxLength);
}

Project: Chrome

void HTMLTextAreaElement::setCols(int cols)
{
    setIntegralAttribute(colsAttr, cols);
}

Project: Chrome

void HTMLTextAreaElement::setDefaultValue(const String& defaultValue)
{
    RefPtr<Node> protectFromMutationEvents(this);

    Vector<RefPtr<Node> > textNodes;
    for (Node* n = firstChild(); n; n = n->nextSibling()) {
        if (n->isTextNode())
            textNodes.append(n);
    }
    size_t size = textNodes.size();
    for (size_t i = 0; i < size; ++i)
        removeChild(textNodes[i].get(), IGNORE_EXCEPTION);

    String value = defaultValue;
    value.replace("\r\n", "\n");
    value.replace('\r', '\n');

    insertBefore(document().createTextNode(value), firstChild(), IGNORE_EXCEPTION);

    if (!m_isDirty)
        setNonDirtyValue(value);
}

Project: Chrome

void HTMLTextAreaElement::setMaxLength(int newValue, ExceptionState& exceptionState)
{
    if (newValue < 0)
        exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(newValue) + ") is not positive or 0.");
    else
        setIntegralAttribute(maxlengthAttr, newValue);
}

Project: Chrome

void HTMLTextAreaElement::setNonDirtyValue(const String& value)
{
    setValueCommon(value);
    m_isDirty = false;
    setNeedsValidityCheck();
}

Project: Chrome

void HTMLTextAreaElement::setSuggestedValue(const String& value)
{
    m_suggestedValue = value;
    setInnerTextValue(m_suggestedValue);
    updatePlaceholderVisibility(false);
    setNeedsStyleRecalc();
    setFormControlValueMatchesRenderer(true);
}

Project: Chrome

void HTMLTextAreaElement::setValue(const String& value)
{
    setValueCommon(value);
    m_isDirty = true;
    setNeedsValidityCheck();
}

Project: Chrome

void HTMLTextAreaElement::setValueCommon(const String& newValue)
{
    String normalizedValue = newValue.isNull() ? "" : newValue;
    normalizedValue.replace("\r\n", "\n");
    normalizedValue.replace('\r', '\n');

    if (normalizedValue == value())
        return;

    m_value = normalizedValue;
    setInnerTextValue(m_value);
    setLastChangeWasNotUserEdit();
    updatePlaceholderVisibility(false);
    setNeedsStyleRecalc();
    setFormControlValueMatchesRenderer(true);

    if (document().focusedElement() == this) {
        unsigned endOfString = m_value.length();
        setSelectionRange(endOfString, endOfString);
    }

    notifyFormStateChanged();
    setTextAsOfLastFormControlChangeEvent(normalizedValue);
}

Project: Chrome

bool HTMLTextAreaElement::shouldShowFocusRingOnMouseFocus() const
{
    return true;
}

Project: Chrome

bool HTMLTextAreaElement::shouldUseInputMethod()
{
    return true;
}

Project: Chrome

String HTMLTextAreaElement::suggestedValue() const
{
    return m_suggestedValue;
}

Project: Chrome

bool HTMLTextAreaElement::tooLong() const
{
    return willValidate() && tooLong(value(), CheckDirtyFlag);
}

Project: Chrome

bool HTMLTextAreaElement::tooLong(const String& value, NeedsToCheckDirtyFlag check) const
{
    if (check == CheckDirtyFlag && !lastChangeWasUserEdit())
        return false;

    int max = maxLength();
    if (max < 0)
        return false;
    return computeLengthForSubmission(value) > static_cast<unsigned>(max);
}

Project: Chrome

void HTMLTextAreaElement::updateFocusAppearance(bool restorePreviousSelection)
{
    if (!restorePreviousSelection || !hasCachedSelection()) {
        setSelectionRange(0, 0);
    } else
        restoreCachedSelection();

    if (document().frame())
        document().frame()->selection().revealSelection();
}

Project: Chrome

void HTMLTextAreaElement::updateValue() const
{
    if (formControlValueMatchesRenderer())
        return;

    ASSERT(renderer());
    m_value = innerTextValue();
    const_cast<HTMLTextAreaElement*>(this)->setFormControlValueMatchesRenderer(true);
    const_cast<HTMLTextAreaElement*>(this)->notifyFormStateChanged();
    m_isDirty = true;
    const_cast<HTMLTextAreaElement*>(this)->updatePlaceholderVisibility(false);
}

Project: Chrome

String HTMLTextAreaElement::value() const
{
    updateValue();
    return m_value;
}

Project: Chrome

bool HTMLTextAreaElement::valueMissing() const
{
    return willValidate() && valueMissing(value());
}