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