18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *           (C) 1999 Antti Koivisto (koivisto@kde.org)
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *           (C) 2001 Dirk Mueller (mueller@kde.org)
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *           (C) 2006 Alexey Proskuryakov (ap@nypop.com)
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version.
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful,
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details.
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB.  If not, write to
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA.
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLFormControlElement.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block#include "Attribute.h"
29d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "Chrome.h"
300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "ChromeClient.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Document.h"
32f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick#include "DocumentParser.h"
335af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke#include "ElementRareData.h"
34231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "Event.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "EventHandler.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "EventNames.h"
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h"
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLFormElement.h"
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLInputElement.h"
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLNames.h"
415af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke#include "LabelsNodeList.h"
420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "Page.h"
438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "RenderBox.h"
44231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "RenderTextControl.h"
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderTheme.h"
46231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "ScriptEventListener.h"
4728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu#include "ValidationMessage.h"
480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "ValidityState.h"
49e14391e94c850b8bd03680c23b38978db68687a8John Reck#include <limits>
506c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen#include <wtf/Vector.h>
512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <wtf/unicode/CharacterNames.h>
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace HTMLNames;
56e14391e94c850b8bd03680c23b38978db68687a8John Reckusing namespace std;
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian MonsenHTMLFormControlElement::HTMLFormControlElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
5906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    : HTMLElement(tagName, document)
60f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    , FormAssociatedElement(form)
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_disabled(false)
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_readOnly(false)
63231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    , m_required(false)
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_valueMatchesRenderer(false)
65dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    , m_willValidateInitialized(false)
66dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    , m_willValidate(true)
67dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    , m_isValid(true)
6881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_wasChangedSinceLastFormControlChangeEvent(false)
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
70f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!this->form())
71f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        setForm(findFormAncestor());
72f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (this->form())
73f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        this->form()->registerFormElement(this);
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHTMLFormControlElement::~HTMLFormControlElement()
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
78f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (form())
79f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        form()->removeFormElement(this);
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhuvoid HTMLFormControlElement::detach()
8328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu{
8465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    m_validationMessage = 0;
8528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    HTMLElement::detach();
8628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu}
8728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
88231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockbool HTMLFormControlElement::formNoValidate() const
89231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
90f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    return fastHasAttribute(formnovalidateAttr);
910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
93e78cbe89e6f337f2f1fe40315be88f742b547151Steve Blockvoid HTMLFormControlElement::parseMappedAttribute(Attribute* attr)
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
95dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (attr->name() == disabledAttr) {
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool oldDisabled = m_disabled;
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_disabled = !attr->isNull();
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (oldDisabled != m_disabled) {
995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            setNeedsStyleRecalc();
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (renderer() && renderer()->style()->hasAppearance())
1010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                renderer()->theme()->stateChanged(renderer(), EnabledState);
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (attr->name() == readonlyAttr) {
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool oldReadOnly = m_readOnly;
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_readOnly = !attr->isNull();
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (oldReadOnly != m_readOnly) {
1075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            setNeedsStyleRecalc();
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (renderer() && renderer()->style()->hasAppearance())
1090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                renderer()->theme()->stateChanged(renderer(), ReadOnlyState);
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
111231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    } else if (attr->name() == requiredAttr) {
112231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        bool oldRequired = m_required;
113231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        m_required = !attr->isNull();
114dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (oldRequired != m_required) {
115dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            setNeedsValidityCheck();
116dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            setNeedsStyleRecalc(); // Updates for :required :optional classes.
117dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        HTMLElement::parseMappedAttribute(attr);
120dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    setNeedsWillValidateCheck();
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Blockstatic bool shouldAutofocus(HTMLFormControlElement* element)
12454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block{
12554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    if (!element->autofocus())
12654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        return false;
12754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    if (!element->renderer())
12854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        return false;
12954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    if (element->document()->ignoreAutofocus())
13054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        return false;
13154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    if (element->isReadOnlyFormControl())
13254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        return false;
13354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
13454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    // FIXME: Should this set of hasTagName checks be replaced by a
13554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    // virtual member function?
13654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    if (element->hasTagName(inputTag))
13754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        return !static_cast<HTMLInputElement*>(element)->isInputTypeHidden();
13854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    if (element->hasTagName(selectTag))
13954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        return true;
14054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    if (element->hasTagName(keygenTag))
14154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        return true;
14254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    if (element->hasTagName(buttonTag))
14354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        return true;
14454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    if (element->hasTagName(textareaTag))
14554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        return true;
14654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
14754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    return false;
14854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block}
14954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
15054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Blockstatic void focusPostAttach(Node* element)
15154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block{
15254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    static_cast<Element*>(element)->focus();
15354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    element->deref();
15454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block}
15554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLFormControlElement::attach()
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!attached());
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    suspendPostAttachCallbacks();
16154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLElement::attach();
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // The call to updateFromElement() needs to go after the call through
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // to the base class's attach() because that can sometimes do a close
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // on the renderer.
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (renderer())
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        renderer()->updateFromElement();
16981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
17054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    if (shouldAutofocus(this)) {
17154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        ref();
17254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        queuePostAttachCallback(focusPostAttach, this);
17354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    }
17454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
17554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    resumePostAttachCallbacks();
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid HTMLFormControlElement::willMoveToNewOwnerDocument()
17965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
18065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    FormAssociatedElement::willMoveToNewOwnerDocument();
18165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    HTMLElement::willMoveToNewOwnerDocument();
18265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
18365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLFormControlElement::insertedIntoTree(bool deep)
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
186f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    FormAssociatedElement::insertedIntoTree();
187f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!form())
188f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        document()->checkedRadioButtons().addButton(this);
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLElement::insertedIntoTree(deep);
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLFormControlElement::removedFromTree(bool deep)
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
195f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    FormAssociatedElement::removedFromTree();
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLElement::removedFromTree(deep);
1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1992fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid HTMLFormControlElement::insertedIntoDocument()
2002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
2012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    HTMLElement::insertedIntoDocument();
2022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    FormAssociatedElement::insertedIntoDocument();
2032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
2042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
2052fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid HTMLFormControlElement::removedFromDocument()
2062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
2072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    HTMLElement::removedFromDocument();
2082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    FormAssociatedElement::removedFromDocument();
2092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
2102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
2115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianconst AtomicString& HTMLFormControlElement::formControlName() const
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2136c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    const AtomicString& name = fastGetAttribute(nameAttr);
2146c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    return name.isNull() ? emptyAtom : name;
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
217ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockvoid HTMLFormControlElement::setName(const AtomicString& value)
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setAttribute(nameAttr, value);
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochbool HTMLFormControlElement::wasChangedSinceLastFormControlChangeEvent() const
22381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
22481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return m_wasChangedSinceLastFormControlChangeEvent;
22581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
22681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
22781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid HTMLFormControlElement::setChangedSinceLastFormControlChangeEvent(bool changed)
22881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
22981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_wasChangedSinceLastFormControlChangeEvent = changed;
23081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
23181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
2325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid HTMLFormControlElement::dispatchFormControlChangeEvent()
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    HTMLElement::dispatchChangeEvent();
23581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    setChangedSinceLastFormControlChangeEvent(false);
236ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch}
237ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch
238ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochvoid HTMLFormControlElement::dispatchFormControlInputEvent()
239ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{
24081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    setChangedSinceLastFormControlChangeEvent(true);
2412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    HTMLElement::dispatchInputEvent();
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLFormControlElement::setDisabled(bool b)
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setAttribute(disabledAttr, b ? "" : 0);
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLFormControlElement::autofocus() const
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return hasAttribute(autofocusAttr);
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochbool HTMLFormControlElement::required() const
2550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
256231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return m_required;
2570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
2580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
259d0825bca7fe65beaee391d30da42e937db621564Steve Blockstatic void updateFromElementCallback(Node* node)
260d0825bca7fe65beaee391d30da42e937db621564Steve Block{
261d0825bca7fe65beaee391d30da42e937db621564Steve Block    ASSERT_ARG(node, node->isElementNode());
262d0825bca7fe65beaee391d30da42e937db621564Steve Block    ASSERT_ARG(node, static_cast<Element*>(node)->isFormControlElement());
263d0825bca7fe65beaee391d30da42e937db621564Steve Block    ASSERT(node->renderer());
264d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (RenderObject* renderer = node->renderer())
265d0825bca7fe65beaee391d30da42e937db621564Steve Block        renderer->updateFromElement();
266d0825bca7fe65beaee391d30da42e937db621564Steve Block}
267d0825bca7fe65beaee391d30da42e937db621564Steve Block
2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLFormControlElement::recalcStyle(StyleChange change)
2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLElement::recalcStyle(change);
2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
272d0825bca7fe65beaee391d30da42e937db621564Steve Block    // updateFromElement() can cause the selection to change, and in turn
273d0825bca7fe65beaee391d30da42e937db621564Steve Block    // trigger synchronous layout, so it must not be called during style recalc.
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (renderer())
275d0825bca7fe65beaee391d30da42e937db621564Steve Block        queuePostAttachCallback(updateFromElementCallback, this);
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
278231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockbool HTMLFormControlElement::supportsFocus() const
279231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
280f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    return !m_disabled;
281231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
282231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLFormControlElement::isFocusable() const
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
285231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!renderer() ||
286635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        !renderer()->isBox() || toRenderBox(renderer())->size().isEmpty())
2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
288231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // HTMLElement::isFocusable handles visibility and calls suportsFocus which
289231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // will cover the disabled case.
290231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return HTMLElement::isFocusable();
2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLFormControlElement::isKeyboardFocusable(KeyboardEvent* event) const
2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isFocusable())
2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (document()->frame())
29781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            return document()->frame()->eventHandler()->tabsToAllFormControls(event);
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLFormControlElement::isMouseFocusable() const
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
303a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#if PLATFORM(GTK) || PLATFORM(QT)
3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return HTMLElement::isMouseFocusable();
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else
3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectshort HTMLFormControlElement::tabIndex() const
3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Skip the supportsFocus check in HTMLElement.
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return Element::tabIndex();
3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
316dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool HTMLFormControlElement::recalcWillValidate() const
3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
318dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // FIXME: Should return false if this element has a datalist element as an
319dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // ancestor. See HTML5 4.10.10 'The datalist element.'
320dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return !m_disabled && !m_readOnly;
321231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
322231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
323dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool HTMLFormControlElement::willValidate() const
324643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
325dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!m_willValidateInitialized) {
326dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_willValidateInitialized = true;
327dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_willValidate = recalcWillValidate();
328dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    } else {
329dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // If the following assertion fails, setNeedsWillValidateCheck() is not
330dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // called correctly when something which changes recalcWillValidate() result
331dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // is updated.
332dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ASSERT(m_willValidate == recalcWillValidate());
333dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
334dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return m_willValidate;
335643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
336643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
3375e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blockvoid HTMLFormControlElement::setNeedsWillValidateCheck()
3385e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{
339dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // We need to recalculate willValidte immediately because willValidate
340dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // change can causes style change.
341dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    bool newWillValidate = recalcWillValidate();
342dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (m_willValidateInitialized && m_willValidate == newWillValidate)
343dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return;
344dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    m_willValidateInitialized = true;
345dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    m_willValidate = newWillValidate;
3465e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block    setNeedsStyleRecalc();
34728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (!m_willValidate)
34828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        hideVisibleValidationMessage();
3495e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block}
3505e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block
351dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockString HTMLFormControlElement::validationMessage()
352231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
353dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return validity()->validationMessage();
354dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
355231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
35628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhuvoid HTMLFormControlElement::updateVisibleValidationMessage()
35728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu{
35828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    Page* page = document()->page();
35928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (!page)
36028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        return;
36128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    String message;
36228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (renderer() && willValidate()) {
36328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        message = validationMessage().stripWhiteSpace();
36428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        // HTML5 specification doesn't ask UA to show the title attribute value
36528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        // with the validationMessage.  However, this behavior is same as Opera
36628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        // and the specification describes such behavior as an example.
36728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        const AtomicString& title = getAttribute(titleAttr);
36828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        if (!message.isEmpty() && !title.isEmpty()) {
36928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            message.append('\n');
37028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            message.append(title);
37128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        }
37228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    }
37365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (message.isEmpty()) {
37465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        hideVisibleValidationMessage();
37565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
37665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
37728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (!m_validationMessage) {
37828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        m_validationMessage = ValidationMessage::create(this);
37928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        m_validationMessage->setMessage(message);
38065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    } else {
38165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        // Call setMessage() even if m_validationMesage->message() == message
38265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        // because the existing message might be to be hidden.
38328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        m_validationMessage->setMessage(message);
38465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
38528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu}
38628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
38728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhuvoid HTMLFormControlElement::hideVisibleValidationMessage()
38828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu{
38965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (m_validationMessage)
39065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        m_validationMessage->requestToHideMessage();
39128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu}
39228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
39328040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuString HTMLFormControlElement::visibleValidationMessage() const
39428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu{
39528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    return m_validationMessage ? m_validationMessage->message() : String();
39628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu}
39728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
398f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochbool HTMLFormControlElement::checkValidity(Vector<RefPtr<FormAssociatedElement> >* unhandledInvalidControls)
399dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
400dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!willValidate() || isValidFormControlElement())
401dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return true;
402dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // An event handler can deref this object.
403dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    RefPtr<HTMLFormControlElement> protector(this);
404dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    RefPtr<Document> originalDocument(document());
405dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    bool needsDefaultAction = dispatchEvent(Event::create(eventNames().invalidEvent, false, true));
406dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (needsDefaultAction && unhandledInvalidControls && inDocument() && originalDocument == document())
407dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        unhandledInvalidControls->append(this);
408dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return false;
409dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
410dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
411dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool HTMLFormControlElement::isValidFormControlElement()
412dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
413dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // If the following assertion fails, setNeedsValidityCheck() is not called
414dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // correctly when something which changes validity is updated.
415dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    ASSERT(m_isValid == validity()->valid());
416dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return m_isValid;
417231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
418231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
4195e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blockvoid HTMLFormControlElement::setNeedsValidityCheck()
420231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
421dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    bool newIsValid = validity()->valid();
422dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (willValidate() && newIsValid != m_isValid) {
423231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // Update style for pseudo classes such as :valid :invalid.
424231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        setNeedsStyleRecalc();
425231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
426dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    m_isValid = newIsValid;
42728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
42828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    // Updates only if this control already has a validtion message.
42928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (!visibleValidationMessage().isEmpty()) {
43028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        // Calls updateVisibleValidationMessage() even if m_isValid is not
43128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        // changed because a validation message can be chagned.
43228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        updateVisibleValidationMessage();
43328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    }
4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid HTMLFormControlElement::setCustomValidity(const String& error)
4370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
4380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    validity()->setCustomErrorMessage(error);
4390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
440f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
4410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid HTMLFormControlElement::dispatchFocusEvent()
4420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
443dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (document()->page())
444dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        document()->page()->chrome()->client()->formDidFocus(this);
4450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    HTMLElement::dispatchFocusEvent();
4470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
4480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid HTMLFormControlElement::dispatchBlurEvent()
4500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
451dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (document()->page())
452dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        document()->page()->chrome()->client()->formDidBlur(this);
4530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    HTMLElement::dispatchBlurEvent();
45528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    hideVisibleValidationMessage();
4560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
4570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
458231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockHTMLFormElement* HTMLFormControlElement::virtualForm() const
4598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
460f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    return FormAssociatedElement::form();
4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
463231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockbool HTMLFormControlElement::isDefaultButtonForForm() const
4648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
465f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    return isSuccessfulSubmitButton() && form() && form()->defaultButton() == this;
4666b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner}
4676b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
4686b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennervoid HTMLFormControlElement::attributeChanged(Attribute* attr, bool preserveDecls)
4696b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{
4706b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (attr->name() == formAttr) {
471f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        formAttributeChanged();
472f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (!form())
473f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            document()->checkedRadioButtons().addButton(this);
474f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    } else
475f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        HTMLElement::attributeChanged(attr, preserveDecls);
4766b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner}
4776b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
4786c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenbool HTMLFormControlElement::isLabelable() const
4796c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen{
4806c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    // FIXME: Add meterTag and outputTag to the list once we support them.
4816c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    return hasTagName(buttonTag) || hasTagName(inputTag) || hasTagName(keygenTag)
4825af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke#if ENABLE(METER_TAG)
4835af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        || hasTagName(meterTag)
4845af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke#endif
4856c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen#if ENABLE(PROGRESS_TAG)
4866c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        || hasTagName(progressTag)
4876c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen#endif
4886c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        || hasTagName(selectTag) || hasTagName(textareaTag);
4896c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen}
4905af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
4915af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkePassRefPtr<NodeList> HTMLFormControlElement::labels()
4925af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
4935af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (!isLabelable())
4945af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return 0;
4955af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (!document())
4965af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return 0;
49781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
4985af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    NodeRareData* data = Node::ensureRareData();
4995af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (!data->nodeLists()) {
5005af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        data->setNodeLists(NodeListsNodeData::create());
5015af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        document()->addNodeListCache();
5025af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    }
50381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
5045af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    return LabelsNodeList::create(this);
5055af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
506f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
5078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHTMLFormControlElementWithState::HTMLFormControlElementWithState(const QualifiedName& tagName, Document* doc, HTMLFormElement* f)
5088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    : HTMLFormControlElement(tagName, doc, f)
5098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    document()->registerFormElementWithState(this);
5118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHTMLFormControlElementWithState::~HTMLFormControlElementWithState()
5148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    document()->unregisterFormElementWithState(this);
5168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLFormControlElementWithState::willMoveToNewOwnerDocument()
5198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    document()->unregisterFormElementWithState(this);
5218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLFormControlElement::willMoveToNewOwnerDocument();
5228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLFormControlElementWithState::didMoveToNewOwnerDocument()
5258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    document()->registerFormElementWithState(this);
5278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLFormControlElement::didMoveToNewOwnerDocument();
5288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
530dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool HTMLFormControlElementWithState::autoComplete() const
531dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
532dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!form())
533dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return true;
534dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return form()->autoComplete();
535dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
536dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
537dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool HTMLFormControlElementWithState::shouldSaveAndRestoreFormControlState() const
538dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
539dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // We don't save/restore control state in a form with autocomplete=off.
540a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return attached() && autoComplete();
541dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
542dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
5438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLFormControlElementWithState::finishParsingChildren()
5448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLFormControlElement::finishParsingChildren();
546dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
547dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // We don't save state of a control with shouldSaveAndRestoreFormControlState()=false.
548dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // But we need to skip restoring process too because a control in another
549dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // form might have the same pair of name and type and saved its state.
550dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!shouldSaveAndRestoreFormControlState())
551dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return;
552dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
5538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Document* doc = document();
5548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (doc->hasStateForNewFormElements()) {
5558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        String state;
5568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (doc->takeStateForFormElement(name().impl(), type().impl(), state))
5575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            restoreFormControlState(state);
5588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
56121939df44de1705786c545cd1bf519d47250322dBen Murdochvoid HTMLFormControlElementWithState::defaultEventHandler(Event* event)
56221939df44de1705786c545cd1bf519d47250322dBen Murdoch{
56321939df44de1705786c545cd1bf519d47250322dBen Murdoch    if (event->type() == eventNames().webkitEditableContentChangedEvent && renderer() && renderer()->isTextControl()) {
56421939df44de1705786c545cd1bf519d47250322dBen Murdoch        toRenderTextControl(renderer())->subtreeHasChanged();
56521939df44de1705786c545cd1bf519d47250322dBen Murdoch        return;
56621939df44de1705786c545cd1bf519d47250322dBen Murdoch    }
56721939df44de1705786c545cd1bf519d47250322dBen Murdoch
56821939df44de1705786c545cd1bf519d47250322dBen Murdoch    HTMLFormControlElement::defaultEventHandler(event);
56921939df44de1705786c545cd1bf519d47250322dBen Murdoch}
57021939df44de1705786c545cd1bf519d47250322dBen Murdoch
571231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockHTMLTextFormControlElement::HTMLTextFormControlElement(const QualifiedName& tagName, Document* doc, HTMLFormElement* form)
572231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    : HTMLFormControlElementWithState(tagName, doc, form)
573231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
574231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
575231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
576231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockHTMLTextFormControlElement::~HTMLTextFormControlElement()
577231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
578231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
579231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
5802bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid HTMLTextFormControlElement::insertedIntoDocument()
5812bde8e466a4451c7319e3a072d118917957d6554Steve Block{
5822bde8e466a4451c7319e3a072d118917957d6554Steve Block    HTMLFormControlElement::insertedIntoDocument();
5832bde8e466a4451c7319e3a072d118917957d6554Steve Block    setTextAsOfLastFormControlChangeEvent(value());
5842bde8e466a4451c7319e3a072d118917957d6554Steve Block}
5852bde8e466a4451c7319e3a072d118917957d6554Steve Block
586231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid HTMLTextFormControlElement::dispatchFocusEvent()
587231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
588231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (supportsPlaceholder())
589231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        updatePlaceholderVisibility(false);
590231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    handleFocusEvent();
591231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    HTMLFormControlElementWithState::dispatchFocusEvent();
592231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
593231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
594231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid HTMLTextFormControlElement::dispatchBlurEvent()
595231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
596231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (supportsPlaceholder())
597231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        updatePlaceholderVisibility(false);
598231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    handleBlurEvent();
599231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    HTMLFormControlElementWithState::dispatchBlurEvent();
600231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
601231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
6026c2af9490927c3c5959b5cb07461b646f8b32f6cKristian MonsenString HTMLTextFormControlElement::strippedPlaceholder() const
6036c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen{
6046c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    // According to the HTML5 specification, we need to remove CR and LF from
6056c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    // the attribute value.
6066c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    const AtomicString& attributeValue = getAttribute(placeholderAttr);
6076c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (!attributeValue.contains(newlineCharacter) && !attributeValue.contains(carriageReturn))
6086c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        return attributeValue;
6096c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
6106c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    Vector<UChar> stripped;
6116c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    unsigned length = attributeValue.length();
6126c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    stripped.reserveCapacity(length);
6136c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    for (unsigned i = 0; i < length; ++i) {
6146c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        UChar character = attributeValue[i];
6156c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if (character == newlineCharacter || character == carriageReturn)
6166c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            continue;
6176c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        stripped.append(character);
6186c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    }
6196c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    return String::adopt(stripped);
6206c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen}
6216c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
6226c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenstatic bool isNotLineBreak(UChar ch) { return ch != newlineCharacter && ch != carriageReturn; }
6236c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
6246c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenbool HTMLTextFormControlElement::isPlaceholderEmpty() const
6256c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen{
6266c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    const AtomicString& attributeValue = getAttribute(placeholderAttr);
627f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    return attributeValue.string().find(isNotLineBreak) == notFound;
6286c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen}
6296c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
630231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockbool HTMLTextFormControlElement::placeholderShouldBeVisible() const
631231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
632231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return supportsPlaceholder()
633231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        && isEmptyValue()
63481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        && isEmptySuggestedValue()
6352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        && !isPlaceholderEmpty()
6362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        && (document()->focusedNode() != this || (renderer() && renderer()->theme()->shouldShowPlaceholderWhenFocused()));
637231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
638231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
639231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid HTMLTextFormControlElement::updatePlaceholderVisibility(bool placeholderValueChanged)
640231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
641231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (supportsPlaceholder() && renderer())
642231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        toRenderTextControl(renderer())->updatePlaceholderVisibility(placeholderShouldBeVisible(), placeholderValueChanged);
643231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
644231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
645231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockRenderTextControl* HTMLTextFormControlElement::textRendererAfterUpdateLayout()
646231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
647231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!isTextFormControl())
648231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return 0;
649231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    document()->updateLayoutIgnorePendingStylesheets();
650231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return toRenderTextControl(renderer());
651231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
652231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
653231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid HTMLTextFormControlElement::setSelectionStart(int start)
654231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
655e14391e94c850b8bd03680c23b38978db68687a8John Reck    setSelectionRange(start, max(start, selectionEnd()));
656231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
657231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
658231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid HTMLTextFormControlElement::setSelectionEnd(int end)
659231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
660e14391e94c850b8bd03680c23b38978db68687a8John Reck    setSelectionRange(min(end, selectionStart()), end);
661231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
662231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
663231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid HTMLTextFormControlElement::select()
664231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
665e14391e94c850b8bd03680c23b38978db68687a8John Reck    setSelectionRange(0, numeric_limits<int>::max());
666231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
667231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
6682bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid HTMLTextFormControlElement::dispatchFormControlChangeEvent()
6692bde8e466a4451c7319e3a072d118917957d6554Steve Block{
6702bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (m_textAsOfLastFormControlChangeEvent != value()) {
6712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        HTMLElement::dispatchChangeEvent();
6722bde8e466a4451c7319e3a072d118917957d6554Steve Block        setTextAsOfLastFormControlChangeEvent(value());
6732bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
6742bde8e466a4451c7319e3a072d118917957d6554Steve Block    setChangedSinceLastFormControlChangeEvent(false);
6752bde8e466a4451c7319e3a072d118917957d6554Steve Block}
6762bde8e466a4451c7319e3a072d118917957d6554Steve Block
677231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid HTMLTextFormControlElement::setSelectionRange(int start, int end)
678231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
679e14391e94c850b8bd03680c23b38978db68687a8John Reck    WebCore::setSelectionRange(this, start, end);
680231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
681231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
68228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhuint HTMLTextFormControlElement::selectionStart() const
683231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
684231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!isTextFormControl())
685231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return 0;
686231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (document()->focusedNode() != this && cachedSelectionStart() >= 0)
687231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return cachedSelectionStart();
688231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!renderer())
689231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return 0;
690231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return toRenderTextControl(renderer())->selectionStart();
691231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
692231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
69328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhuint HTMLTextFormControlElement::selectionEnd() const
694231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
695231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!isTextFormControl())
696231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return 0;
697231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (document()->focusedNode() != this && cachedSelectionEnd() >= 0)
698231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return cachedSelectionEnd();
699231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!renderer())
700231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return 0;
701231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return toRenderTextControl(renderer())->selectionEnd();
702231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
703231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
704a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochPassRefPtr<Range> HTMLTextFormControlElement::selection() const
705231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
706231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!renderer() || !isTextFormControl() || cachedSelectionStart() < 0 || cachedSelectionEnd() < 0)
707a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return 0;
708231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return toRenderTextControl(renderer())->selection(cachedSelectionStart(), cachedSelectionEnd());
709231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
710231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
711e78cbe89e6f337f2f1fe40315be88f742b547151Steve Blockvoid HTMLTextFormControlElement::parseMappedAttribute(Attribute* attr)
712231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
713231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (attr->name() == placeholderAttr)
714231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        updatePlaceholderVisibility(true);
715231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    else if (attr->name() == onselectAttr)
716231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        setAttributeEventListener(eventNames().selectEvent, createAttributeEventListener(this, attr));
717231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    else if (attr->name() == onchangeAttr)
718231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        setAttributeEventListener(eventNames().changeEvent, createAttributeEventListener(this, attr));
719231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    else
720231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        HTMLFormControlElementWithState::parseMappedAttribute(attr);
721231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
722231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
7238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace Webcore
724