2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
6 * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
26 #include "HTMLGenericFormElement.h"
29 #include "EventHandler.h"
30 #include "EventNames.h"
32 #include "HTMLFormElement.h"
33 #include "HTMLInputElement.h"
34 #include "HTMLNames.h"
35 #include "HTMLParser.h"
36 #include "HTMLTokenizer.h"
37 #include "RenderTheme.h"
38 #include "Tokenizer.h"
42 using namespace EventNames;
43 using namespace HTMLNames;
45 HTMLGenericFormElement::HTMLGenericFormElement(const QualifiedName& tagName, Document* doc, HTMLFormElement* f)
46 : HTMLElement(tagName, doc)
50 , m_valueMatchesRenderer(false)
53 m_form = findFormAncestor();
55 m_form->registerFormElement(this);
58 HTMLGenericFormElement::~HTMLGenericFormElement()
61 m_form->removeFormElement(this);
64 void HTMLGenericFormElement::parseMappedAttribute(MappedAttribute *attr)
66 if (attr->name() == nameAttr) {
68 } else if (attr->name() == disabledAttr) {
69 bool oldDisabled = m_disabled;
70 m_disabled = !attr->isNull();
71 if (oldDisabled != m_disabled) {
73 if (renderer() && renderer()->style()->hasAppearance())
74 theme()->stateChanged(renderer(), EnabledState);
76 } else if (attr->name() == readonlyAttr) {
77 bool oldReadOnly = m_readOnly;
78 m_readOnly = !attr->isNull();
79 if (oldReadOnly != m_readOnly) {
81 if (renderer() && renderer()->style()->hasAppearance())
82 theme()->stateChanged(renderer(), ReadOnlyState);
85 HTMLElement::parseMappedAttribute(attr);
88 void HTMLGenericFormElement::attach()
92 HTMLElement::attach();
94 // The call to updateFromElement() needs to go after the call through
95 // to the base class's attach() because that can sometimes do a close
98 renderer()->updateFromElement();
101 void HTMLGenericFormElement::insertedIntoTree(bool deep)
104 // This handles the case of a new form element being created by
105 // JavaScript and inserted inside a form. In the case of the parser
106 // setting a form, we will already have a non-null value for m_form,
107 // and so we don't need to do anything.
108 m_form = findFormAncestor();
110 m_form->registerFormElement(this);
112 document()->checkedRadioButtons().addButton(this);
115 HTMLElement::insertedIntoTree(deep);
118 static inline Node* findRoot(Node* n)
121 for (; n; n = n->parentNode())
126 void HTMLGenericFormElement::removedFromTree(bool deep)
128 // If the form and element are both in the same tree, preserve the connection to the form.
129 // Otherwise, null out our form and remove ourselves from the form's list of elements.
130 HTMLParser* parser = 0;
131 if (Tokenizer* tokenizer = document()->tokenizer())
132 if (tokenizer->isHTMLTokenizer())
133 parser = static_cast<HTMLTokenizer*>(tokenizer)->htmlParser();
135 if (m_form && !(parser && parser->isHandlingResidualStyleAcrossBlocks()) && findRoot(this) != findRoot(m_form)) {
136 m_form->removeFormElement(this);
140 HTMLElement::removedFromTree(deep);
143 const AtomicString& HTMLGenericFormElement::name() const
145 const AtomicString& n = getAttribute(nameAttr);
146 return n.isNull() ? emptyAtom : n;
149 void HTMLGenericFormElement::setName(const AtomicString &value)
151 setAttribute(nameAttr, value);
154 void HTMLGenericFormElement::onChange()
156 dispatchHTMLEvent(changeEvent, true, false);
159 bool HTMLGenericFormElement::disabled() const
164 void HTMLGenericFormElement::setDisabled(bool b)
166 setAttribute(disabledAttr, b ? "" : 0);
169 void HTMLGenericFormElement::setReadOnly(bool b)
171 setAttribute(readonlyAttr, b ? "" : 0);
174 void HTMLGenericFormElement::recalcStyle(StyleChange change)
176 HTMLElement::recalcStyle(change);
179 renderer()->updateFromElement();
182 bool HTMLGenericFormElement::isFocusable() const
184 if (disabled() || !renderer() ||
185 (renderer()->style() && renderer()->style()->visibility() != VISIBLE) ||
186 renderer()->width() == 0 || renderer()->height() == 0)
191 bool HTMLGenericFormElement::isKeyboardFocusable(KeyboardEvent* event) const
194 if (document()->frame())
195 return document()->frame()->eventHandler()->tabsToAllControls(event);
199 bool HTMLGenericFormElement::isMouseFocusable() const
204 void HTMLGenericFormElement::setTabIndex(int value)
206 setAttribute(tabindexAttr, String::number(value));
209 bool HTMLGenericFormElement::supportsFocus() const
211 return isFocusable() || (!disabled() && !document()->haveStylesheetsLoaded());
214 HTMLFormElement* HTMLGenericFormElement::virtualForm() const
219 HTMLFormControlElementWithState::HTMLFormControlElementWithState(const QualifiedName& tagName, Document* doc, HTMLFormElement* f)
220 : HTMLGenericFormElement(tagName, doc, f)
222 doc->registerFormElementWithState(this);
225 HTMLFormControlElementWithState::~HTMLFormControlElementWithState()
227 document()->unregisterFormElementWithState(this);
230 void HTMLFormControlElementWithState::willMoveToNewOwnerDocument()
232 document()->unregisterFormElementWithState(this);
233 HTMLGenericFormElement::willMoveToNewOwnerDocument();
236 void HTMLFormControlElementWithState::didMoveToNewOwnerDocument()
238 document()->registerFormElementWithState(this);
239 HTMLGenericFormElement::didMoveToNewOwnerDocument();
242 void HTMLFormControlElementWithState::finishedParsing()
244 Document* doc = document();
245 if (doc->hasStateForNewFormElements()) {
247 if (doc->takeStateForFormElement(name().impl(), type().impl(), state))
252 } // namespace Webcore