Change incorrect calls to the constructor "EventNames()" to the correct accessor
[WebKit-https.git] / WebCore / html / HTMLFormControlElement.cpp
1 /*
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)
7  *
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.
12  *
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.
17  *
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.
22  *
23  */
24
25 #include "config.h"
26 #include "HTMLFormControlElement.h"
27
28 #include "ChromeClient.h"
29 #include "Document.h"
30 #include "Event.h"
31 #include "EventHandler.h"
32 #include "EventNames.h"
33 #include "Frame.h"
34 #include "HTMLFormElement.h"
35 #include "HTMLInputElement.h"
36 #include "HTMLNames.h"
37 #include "HTMLParser.h"
38 #include "HTMLTokenizer.h"
39 #include "MappedAttribute.h"
40 #include "Page.h"
41 #include "RenderBox.h"
42 #include "RenderTextControl.h"
43 #include "RenderTheme.h"
44 #include "ScriptEventListener.h"
45 #include "ValidityState.h"
46
47 namespace WebCore {
48
49 using namespace HTMLNames;
50
51 HTMLFormControlElement::HTMLFormControlElement(const QualifiedName& tagName, Document* doc, HTMLFormElement* f)
52     : HTMLElement(tagName, doc)
53     , m_form(f)
54     , m_disabled(false)
55     , m_readOnly(false)
56     , m_required(false)
57     , m_valueMatchesRenderer(false)
58 {
59     if (!m_form)
60         m_form = findFormAncestor();
61     if (m_form)
62         m_form->registerFormElement(this);
63 }
64
65 HTMLFormControlElement::~HTMLFormControlElement()
66 {
67     if (m_form)
68         m_form->removeFormElement(this);
69 }
70
71 bool HTMLFormControlElement::formNoValidate() const
72 {
73     return !getAttribute(formnovalidateAttr).isNull();
74 }
75
76 void HTMLFormControlElement::setFormNoValidate(bool formnovalidate)
77 {
78     setAttribute(formnovalidateAttr, formnovalidate ? "" : 0);
79 }
80
81 ValidityState* HTMLFormControlElement::validity()
82 {
83     if (!m_validityState)
84         m_validityState = ValidityState::create(this);
85
86     return m_validityState.get();
87 }
88
89 void HTMLFormControlElement::parseMappedAttribute(MappedAttribute *attr)
90 {
91     if (attr->name() == nameAttr)
92         setNeedsStyleRecalc();
93     else if (attr->name() == disabledAttr) {
94         bool oldDisabled = m_disabled;
95         m_disabled = !attr->isNull();
96         if (oldDisabled != m_disabled) {
97             setNeedsStyleRecalc();
98             if (renderer() && renderer()->style()->hasAppearance())
99                 renderer()->theme()->stateChanged(renderer(), EnabledState);
100         }
101     } else if (attr->name() == readonlyAttr) {
102         bool oldReadOnly = m_readOnly;
103         m_readOnly = !attr->isNull();
104         if (oldReadOnly != m_readOnly) {
105             setNeedsStyleRecalc();
106             if (renderer() && renderer()->style()->hasAppearance())
107                 renderer()->theme()->stateChanged(renderer(), ReadOnlyState);
108         }
109     } else if (attr->name() == requiredAttr) {
110         bool oldRequired = m_required;
111         m_required = !attr->isNull();
112         if (oldRequired != m_required)
113             setNeedsStyleRecalc();
114     } else
115         HTMLElement::parseMappedAttribute(attr);
116 }
117
118 void HTMLFormControlElement::attach()
119 {
120     ASSERT(!attached());
121
122     HTMLElement::attach();
123
124     // The call to updateFromElement() needs to go after the call through
125     // to the base class's attach() because that can sometimes do a close
126     // on the renderer.
127     if (renderer())
128         renderer()->updateFromElement();
129         
130     // Focus the element if it should honour its autofocus attribute.
131     // We have to determine if the element is a TextArea/Input/Button/Select,
132     // if input type hidden ignore autofocus. So if disabled or readonly.
133     bool isInputTypeHidden = false;
134     if (hasTagName(inputTag))
135         isInputTypeHidden = static_cast<HTMLInputElement*>(this)->isInputTypeHidden();
136
137     if (autofocus() && renderer() && !document()->ignoreAutofocus() && !isReadOnlyFormControl() &&
138             ((hasTagName(inputTag) && !isInputTypeHidden) || hasTagName(selectTag) ||
139               hasTagName(buttonTag) || hasTagName(textareaTag)))
140          focus();
141 }
142
143 void HTMLFormControlElement::insertedIntoTree(bool deep)
144 {
145     if (!m_form) {
146         // This handles the case of a new form element being created by
147         // JavaScript and inserted inside a form.  In the case of the parser
148         // setting a form, we will already have a non-null value for m_form, 
149         // and so we don't need to do anything.
150         m_form = findFormAncestor();
151         if (m_form)
152             m_form->registerFormElement(this);
153         else
154             document()->checkedRadioButtons().addButton(this);
155     }
156
157     HTMLElement::insertedIntoTree(deep);
158 }
159
160 static inline Node* findRoot(Node* n)
161 {
162     Node* root = n;
163     for (; n; n = n->parentNode())
164         root = n;
165     return root;
166 }
167
168 void HTMLFormControlElement::removedFromTree(bool deep)
169 {
170     // If the form and element are both in the same tree, preserve the connection to the form.
171     // Otherwise, null out our form and remove ourselves from the form's list of elements.
172     HTMLParser* parser = 0;
173     if (Tokenizer* tokenizer = document()->tokenizer())
174         if (tokenizer->isHTMLTokenizer())
175             parser = static_cast<HTMLTokenizer*>(tokenizer)->htmlParser();
176     
177     if (m_form && !(parser && parser->isHandlingResidualStyleAcrossBlocks()) && findRoot(this) != findRoot(m_form)) {
178         m_form->removeFormElement(this);
179         m_form = 0;
180     }
181
182     HTMLElement::removedFromTree(deep);
183 }
184
185 const AtomicString& HTMLFormControlElement::formControlName() const
186 {
187     const AtomicString& n = getAttribute(nameAttr);
188     return n.isNull() ? emptyAtom : n;
189 }
190
191 void HTMLFormControlElement::setName(const AtomicString &value)
192 {
193     setAttribute(nameAttr, value);
194 }
195
196 void HTMLFormControlElement::dispatchFormControlChangeEvent()
197 {
198     dispatchEvent(Event::create(eventNames().changeEvent, true, false));
199 }
200
201 bool HTMLFormControlElement::disabled() const
202 {
203     return m_disabled;
204 }
205
206 void HTMLFormControlElement::setDisabled(bool b)
207 {
208     setAttribute(disabledAttr, b ? "" : 0);
209 }
210
211 void HTMLFormControlElement::setReadOnly(bool b)
212 {
213     setAttribute(readonlyAttr, b ? "" : 0);
214 }
215
216 bool HTMLFormControlElement::autofocus() const
217 {
218     return hasAttribute(autofocusAttr);
219 }
220
221 void HTMLFormControlElement::setAutofocus(bool b)
222 {
223     setAttribute(autofocusAttr, b ? "autofocus" : 0);
224 }
225
226 bool HTMLFormControlElement::required() const
227 {
228     return m_required;
229 }
230
231 void HTMLFormControlElement::setRequired(bool b)
232 {
233     setAttribute(requiredAttr, b ? "required" : 0);
234 }
235
236 void HTMLFormControlElement::recalcStyle(StyleChange change)
237 {
238     HTMLElement::recalcStyle(change);
239
240     if (renderer())
241         renderer()->updateFromElement();
242 }
243
244 bool HTMLFormControlElement::supportsFocus() const
245 {
246     return !disabled();
247 }
248
249 bool HTMLFormControlElement::isFocusable() const
250 {
251     if (!renderer() || 
252         !renderer()->isBox() || toRenderBox(renderer())->size().isEmpty())
253         return false;
254     // HTMLElement::isFocusable handles visibility and calls suportsFocus which
255     // will cover the disabled case.
256     return HTMLElement::isFocusable();
257 }
258
259 bool HTMLFormControlElement::isKeyboardFocusable(KeyboardEvent* event) const
260 {
261     if (isFocusable())
262         if (document()->frame())
263             return document()->frame()->eventHandler()->tabsToAllControls(event);
264     return false;
265 }
266
267 bool HTMLFormControlElement::isMouseFocusable() const
268 {
269 #if PLATFORM(GTK)
270     return HTMLElement::isMouseFocusable();
271 #else
272     return false;
273 #endif
274 }
275
276 short HTMLFormControlElement::tabIndex() const
277 {
278     // Skip the supportsFocus check in HTMLElement.
279     return Element::tabIndex();
280 }
281
282 bool HTMLFormControlElement::willValidate() const
283 {
284     // FIXME: Implementation shall be completed with these checks:
285     //      The control does not have a repetition template as an ancestor.
286     //      The control does not have a datalist element as an ancestor.
287     //      The control is not an output element.
288     return form() && !name().isEmpty() && !disabled() && !isReadOnlyFormControl();
289 }
290
291 String HTMLFormControlElement::validationMessage()
292 {
293     return validity()->validationMessage();
294 }
295
296 bool HTMLFormControlElement::checkValidity()
297 {
298     if (willValidate() && !isValidFormControlElement()) {
299         dispatchEvent(Event::create(eventNames().invalidEvent, false, true));
300         return false;
301     }
302
303     return true;
304 }
305
306 void HTMLFormControlElement::updateValidity()
307 {
308     if (willValidate()) {
309         // Update style for pseudo classes such as :valid :invalid.
310         setNeedsStyleRecalc();
311     }
312 }
313
314 void HTMLFormControlElement::setCustomValidity(const String& error)
315 {
316     validity()->setCustomErrorMessage(error);
317 }
318     
319 void HTMLFormControlElement::dispatchFocusEvent()
320 {
321     if (document()->frame() && document()->frame()->page())
322         document()->frame()->page()->chrome()->client()->formDidFocus(this);
323
324     HTMLElement::dispatchFocusEvent();
325 }
326
327 void HTMLFormControlElement::dispatchBlurEvent()
328 {
329     if (document()->frame() && document()->frame()->page())
330         document()->frame()->page()->chrome()->client()->formDidBlur(this);
331
332     HTMLElement::dispatchBlurEvent();
333 }
334
335 HTMLFormElement* HTMLFormControlElement::virtualForm() const
336 {
337     return m_form;
338 }
339
340 bool HTMLFormControlElement::isDefaultButtonForForm() const
341 {
342     return isSuccessfulSubmitButton() && m_form && m_form->defaultButton() == this;
343 }
344
345 bool HTMLFormControlElement::isValidFormControlElement()
346 {
347     return validity()->valid();
348 }
349
350 void HTMLFormControlElement::removeFromForm()
351 {
352     if (!m_form)
353         return;
354     m_form->removeFormElement(this);
355     m_form = 0;
356 }
357
358 HTMLFormControlElementWithState::HTMLFormControlElementWithState(const QualifiedName& tagName, Document* doc, HTMLFormElement* f)
359     : HTMLFormControlElement(tagName, doc, f)
360 {
361     document()->registerFormElementWithState(this);
362 }
363
364 HTMLFormControlElementWithState::~HTMLFormControlElementWithState()
365 {
366     document()->unregisterFormElementWithState(this);
367 }
368
369 void HTMLFormControlElementWithState::willMoveToNewOwnerDocument()
370 {
371     document()->unregisterFormElementWithState(this);
372     HTMLFormControlElement::willMoveToNewOwnerDocument();
373 }
374
375 void HTMLFormControlElementWithState::didMoveToNewOwnerDocument()
376 {
377     document()->registerFormElementWithState(this);
378     HTMLFormControlElement::didMoveToNewOwnerDocument();
379 }
380
381 void HTMLFormControlElementWithState::finishParsingChildren()
382 {
383     HTMLFormControlElement::finishParsingChildren();
384     Document* doc = document();
385     if (doc->hasStateForNewFormElements()) {
386         String state;
387         if (doc->takeStateForFormElement(name().impl(), type().impl(), state))
388             restoreFormControlState(state);
389     }
390 }
391
392 HTMLTextFormControlElement::HTMLTextFormControlElement(const QualifiedName& tagName, Document* doc, HTMLFormElement* form)
393     : HTMLFormControlElementWithState(tagName, doc, form)
394 {
395 }
396
397 HTMLTextFormControlElement::~HTMLTextFormControlElement()
398 {
399 }
400
401 void HTMLTextFormControlElement::dispatchFocusEvent()
402 {
403     if (supportsPlaceholder())
404         updatePlaceholderVisibility(false);
405     handleFocusEvent();
406     HTMLFormControlElementWithState::dispatchFocusEvent();
407 }
408
409 void HTMLTextFormControlElement::dispatchBlurEvent()
410 {
411     if (supportsPlaceholder())
412         updatePlaceholderVisibility(false);
413     handleBlurEvent();
414     HTMLFormControlElementWithState::dispatchBlurEvent();
415 }
416
417 bool HTMLTextFormControlElement::placeholderShouldBeVisible() const
418 {
419     return supportsPlaceholder()
420         && isEmptyValue()
421         && document()->focusedNode() != this
422         && !getAttribute(placeholderAttr).isEmpty();
423 }
424
425 void HTMLTextFormControlElement::updatePlaceholderVisibility(bool placeholderValueChanged)
426 {
427     if (supportsPlaceholder() && renderer())
428         toRenderTextControl(renderer())->updatePlaceholderVisibility(placeholderShouldBeVisible(), placeholderValueChanged);
429 }
430
431 RenderTextControl* HTMLTextFormControlElement::textRendererAfterUpdateLayout()
432 {
433     if (!isTextFormControl())
434         return 0;
435     document()->updateLayoutIgnorePendingStylesheets();
436     return toRenderTextControl(renderer());
437 }
438
439 void HTMLTextFormControlElement::setSelectionStart(int start)
440 {
441     if (RenderTextControl* renderer = textRendererAfterUpdateLayout())
442         renderer->setSelectionStart(start);
443 }
444
445 void HTMLTextFormControlElement::setSelectionEnd(int end)
446 {
447     if (RenderTextControl* renderer = textRendererAfterUpdateLayout())
448         renderer->setSelectionEnd(end);
449 }
450
451 void HTMLTextFormControlElement::select()
452 {
453     if (RenderTextControl* renderer = textRendererAfterUpdateLayout())
454         renderer->select();
455 }
456
457 void HTMLTextFormControlElement::setSelectionRange(int start, int end)
458 {
459     if (RenderTextControl* renderer = textRendererAfterUpdateLayout())
460         renderer->setSelectionRange(start, end);
461 }
462
463 int HTMLTextFormControlElement::selectionStart()
464 {
465     if (!isTextFormControl())
466         return 0;
467     if (document()->focusedNode() != this && cachedSelectionStart() >= 0)
468         return cachedSelectionStart();
469     if (!renderer())
470         return 0;
471     return toRenderTextControl(renderer())->selectionStart();
472 }
473
474 int HTMLTextFormControlElement::selectionEnd()
475 {
476     if (!isTextFormControl())
477         return 0;
478     if (document()->focusedNode() != this && cachedSelectionEnd() >= 0)
479         return cachedSelectionEnd();
480     if (!renderer())
481         return 0;
482     return toRenderTextControl(renderer())->selectionEnd();
483 }
484
485 VisibleSelection HTMLTextFormControlElement::selection() const
486 {
487     if (!renderer() || !isTextFormControl() || cachedSelectionStart() < 0 || cachedSelectionEnd() < 0)
488         return VisibleSelection();
489     return toRenderTextControl(renderer())->selection(cachedSelectionStart(), cachedSelectionEnd());
490 }
491
492 void HTMLTextFormControlElement::parseMappedAttribute(MappedAttribute* attr)
493 {
494     if (attr->name() == placeholderAttr)
495         updatePlaceholderVisibility(true);
496     else if (attr->name() == onfocusAttr)
497         setAttributeEventListener(eventNames().focusEvent, createAttributeEventListener(this, attr));
498     else if (attr->name() == onblurAttr)
499         setAttributeEventListener(eventNames().blurEvent, createAttributeEventListener(this, attr));
500     else if (attr->name() == onselectAttr)
501         setAttributeEventListener(eventNames().selectEvent, createAttributeEventListener(this, attr));
502     else if (attr->name() == onchangeAttr)
503         setAttributeEventListener(eventNames().changeEvent, createAttributeEventListener(this, attr));
504     else
505         HTMLFormControlElementWithState::parseMappedAttribute(attr);
506 }
507
508 } // namespace Webcore