007639b21adde038050b72502b204a1017b1d44e
[WebKit.git] / Source / WebCore / html / HTMLInputElement.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, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
6  *           (C) 2006 Alexey Proskuryakov (ap@nypop.com)
7  * Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
8  * Copyright (C) 2010 Google Inc. All rights reserved.
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public License
21  * along with this library; see the file COPYING.LIB.  If not, write to
22  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23  * Boston, MA 02110-1301, USA.
24  *
25  */
26
27 #include "config.h"
28 #include "HTMLInputElement.h"
29
30 #include "AXObjectCache.h"
31 #include "Attribute.h"
32 #include "BeforeTextInsertedEvent.h"
33 #include "CSSPropertyNames.h"
34 #include "Document.h"
35 #include "EventNames.h"
36 #include "ExceptionCode.h"
37 #include "FileList.h"
38 #include "HTMLCollection.h"
39 #include "HTMLDataListElement.h"
40 #include "HTMLFormElement.h"
41 #include "HTMLNames.h"
42 #include "HTMLOptionElement.h"
43 #include "HTMLParserIdioms.h"
44 #include "InputType.h"
45 #include "KeyboardEvent.h"
46 #include "LocalizedStrings.h"
47 #include "MouseEvent.h"
48 #include "RenderTextControlSingleLine.h"
49 #include "RenderTheme.h"
50 #include "RuntimeEnabledFeatures.h"
51 #include "ScriptEventListener.h"
52 #include "WheelEvent.h"
53 #include <wtf/MathExtras.h>
54 #include <wtf/StdLibExtras.h>
55
56 using namespace std;
57
58 namespace WebCore {
59
60 using namespace HTMLNames;
61
62 const int maxSavedResults = 256;
63
64 HTMLInputElement::HTMLInputElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
65     : HTMLTextFormControlElement(tagName, document, form)
66     , m_maxResults(-1)
67     , m_isChecked(false)
68     , m_reflectsCheckedAttribute(true)
69     , m_isIndeterminate(false)
70     , m_hasType(false)
71     , m_isActivatedSubmit(false)
72     , m_autocomplete(Uninitialized)
73     , m_isAutofilled(false)
74     , m_inputType(InputType::createText(this))
75 {
76     ASSERT(hasTagName(inputTag) || hasTagName(isindexTag));
77 }
78
79 PassRefPtr<HTMLInputElement> HTMLInputElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
80 {
81     return adoptRef(new HTMLInputElement(tagName, document, form));
82 }
83
84 HTMLInputElement::~HTMLInputElement()
85 {
86     if (needsActivationCallback())
87         document()->unregisterForDocumentActivationCallbacks(this);
88
89     document()->checkedRadioButtons().removeButton(this);
90
91     // Need to remove this from the form while it is still an HTMLInputElement,
92     // so can't wait for the base class's destructor to do it.
93     removeFromForm();
94 }
95
96 const AtomicString& HTMLInputElement::formControlName() const
97 {
98     return m_data.name();
99 }
100
101 bool HTMLInputElement::autoComplete() const
102 {
103     if (m_autocomplete != Uninitialized)
104         return m_autocomplete == On;
105     return HTMLTextFormControlElement::autoComplete();
106 }
107
108 void HTMLInputElement::updateCheckedRadioButtons()
109 {
110     if (attached() && checked())
111         checkedRadioButtons().addButton(this);
112
113     if (form()) {
114         const Vector<FormAssociatedElement*>& controls = form()->associatedElements();
115         for (unsigned i = 0; i < controls.size(); ++i) {
116             if (!controls[i]->isFormControlElement())
117                 continue;
118             HTMLFormControlElement* control = static_cast<HTMLFormControlElement*>(controls[i]);
119             if (control->name() != name())
120                 continue;
121             if (control->type() != type())
122                 continue;
123             control->setNeedsValidityCheck();
124         }
125     } else {
126         // FIXME: Traversing the document is inefficient.
127         for (Node* node = document()->body(); node; node = node->traverseNextNode()) {
128             if (!node->isElementNode())
129                 continue;
130             Element* element = static_cast<Element*>(node);
131             if (element->formControlName() != name())
132                 continue;
133             if (element->formControlType() != type())
134                 continue;
135             HTMLFormControlElement* control = static_cast<HTMLFormControlElement*>(element);
136             if (control->form())
137                 continue;
138             control->setNeedsValidityCheck();
139         }
140     }
141    
142     if (renderer() && renderer()->style()->hasAppearance())
143         renderer()->theme()->stateChanged(renderer(), CheckedState);
144 }
145
146 bool HTMLInputElement::isValidValue(const String& value) const
147 {
148     if (!m_inputType->canSetStringValue()) {
149         ASSERT_NOT_REACHED();
150         return false;
151     }
152     return !m_inputType->typeMismatchFor(value)
153         && !stepMismatch(value)
154         && !rangeUnderflow(value)
155         && !rangeOverflow(value)
156         && !tooLong(value, IgnoreDirtyFlag)
157         && !patternMismatch(value)
158         && !valueMissing(value);
159 }
160
161 bool HTMLInputElement::typeMismatch() const
162 {
163     return m_inputType->typeMismatch();
164 }
165
166 bool HTMLInputElement::valueMissing(const String& value) const
167 {
168     if (!isRequiredFormControl() || readOnly() || disabled())
169         return false;
170     return m_inputType->valueMissing(value);
171 }
172
173 bool HTMLInputElement::patternMismatch(const String& value) const
174 {
175     return m_inputType->patternMismatch(value);
176 }
177
178 bool HTMLInputElement::tooLong(const String& value, NeedsToCheckDirtyFlag check) const
179 {
180     // We use isTextType() instead of supportsMaxLength() because of the
181     // 'virtual' overhead.
182     if (!isTextType())
183         return false;
184     int max = maxLength();
185     if (max < 0)
186         return false;
187     if (check == CheckDirtyFlag) {
188         // Return false for the default value even if it is longer than maxLength.
189         bool userEdited = !m_data.value().isNull();
190         if (!userEdited)
191             return false;
192     }
193     return numGraphemeClusters(value) > static_cast<unsigned>(max);
194 }
195
196 bool HTMLInputElement::rangeUnderflow(const String& value) const
197 {
198     return m_inputType->rangeUnderflow(value);
199 }
200
201 bool HTMLInputElement::rangeOverflow(const String& value) const
202 {
203     return m_inputType->rangeOverflow(value);
204 }
205
206 double HTMLInputElement::minimum() const
207 {
208     return m_inputType->minimum();
209 }
210
211 double HTMLInputElement::maximum() const
212 {
213     return m_inputType->maximum();
214 }
215
216 bool HTMLInputElement::stepMismatch(const String& value) const
217 {
218     double step;
219     if (!getAllowedValueStep(&step))
220         return false;
221     return m_inputType->stepMismatch(value, step);
222 }
223
224 String HTMLInputElement::minimumString() const
225 {
226     return m_inputType->serialize(minimum());
227 }
228
229 String HTMLInputElement::maximumString() const
230 {
231     return m_inputType->serialize(maximum());
232 }
233
234 String HTMLInputElement::stepBaseString() const
235 {
236     return m_inputType->serialize(m_inputType->stepBase());
237 }
238
239 String HTMLInputElement::stepString() const
240 {
241     double step;
242     if (!getAllowedValueStep(&step)) {
243         // stepString() should be called only if stepMismatch() can be true.
244         ASSERT_NOT_REACHED();
245         return String();
246     }
247     return serializeForNumberType(step / m_inputType->stepScaleFactor());
248 }
249
250 String HTMLInputElement::typeMismatchText() const
251 {
252     return m_inputType->typeMismatchText();
253 }
254
255 String HTMLInputElement::valueMissingText() const
256 {
257     return m_inputType->valueMissingText();
258 }
259
260 bool HTMLInputElement::getAllowedValueStep(double* step) const
261 {
262     return getAllowedValueStepWithDecimalPlaces(step, 0);
263 }
264
265 bool HTMLInputElement::getAllowedValueStepWithDecimalPlaces(double* step, unsigned* decimalPlaces) const
266 {
267     ASSERT(step);
268     double defaultStep = m_inputType->defaultStep();
269     double stepScaleFactor = m_inputType->stepScaleFactor();
270     if (!isfinite(defaultStep) || !isfinite(stepScaleFactor))
271         return false;
272     const AtomicString& stepString = fastGetAttribute(stepAttr);
273     if (stepString.isEmpty()) {
274         *step = defaultStep * stepScaleFactor;
275         if (decimalPlaces)
276             *decimalPlaces = 0;
277         return true;
278     }
279     if (equalIgnoringCase(stepString, "any"))
280         return false;
281     double parsed;
282     if (!decimalPlaces) {
283         if (!parseToDoubleForNumberType(stepString, &parsed) || parsed <= 0.0) {
284             *step = defaultStep * stepScaleFactor;
285             return true;
286         }
287     } else {
288         if (!parseToDoubleForNumberTypeWithDecimalPlaces(stepString, &parsed, decimalPlaces) || parsed <= 0.0) {
289             *step = defaultStep * stepScaleFactor;
290             *decimalPlaces = 0;
291             return true;
292         }
293     }
294     // For date, month, week, the parsed value should be an integer for some types.
295     if (m_inputType->parsedStepValueShouldBeInteger())
296         parsed = max(round(parsed), 1.0);
297     double result = parsed * stepScaleFactor;
298     // For datetime, datetime-local, time, the result should be an integer.
299     if (m_inputType->scaledStepValueShouldBeInteger())
300         result = max(round(result), 1.0);
301     ASSERT(result > 0);
302     *step = result;
303     return true;
304 }
305
306 void HTMLInputElement::applyStep(double count, ExceptionCode& ec)
307 {
308     double step;
309     unsigned stepDecimalPlaces, currentDecimalPlaces;
310     if (!getAllowedValueStepWithDecimalPlaces(&step, &stepDecimalPlaces)) {
311         ec = INVALID_STATE_ERR;
312         return;
313     }
314     const double nan = numeric_limits<double>::quiet_NaN();
315     double current = m_inputType->parseToDoubleWithDecimalPlaces(value(), nan, &currentDecimalPlaces);
316     if (!isfinite(current)) {
317         ec = INVALID_STATE_ERR;
318         return;
319     }
320     double newValue = current + step * count;
321     if (isinf(newValue)) {
322         ec = INVALID_STATE_ERR;
323         return;
324     }
325     double acceptableError = m_inputType->acceptableError(step);
326     if (newValue - m_inputType->minimum() < -acceptableError) {
327         ec = INVALID_STATE_ERR;
328         return;
329     }
330     if (newValue < m_inputType->minimum())
331         newValue = m_inputType->minimum();
332     unsigned baseDecimalPlaces;
333     double base = m_inputType->stepBaseWithDecimalPlaces(&baseDecimalPlaces);
334     baseDecimalPlaces = min(baseDecimalPlaces, 16u);
335     if (newValue < pow(10.0, 21.0)) {
336       if (stepMismatch(value())) {
337             double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, currentDecimalPlaces)));
338             newValue = round(newValue * scale) / scale;
339         } else {
340             double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces)));
341             newValue = round((base + round((newValue - base) / step) * step) * scale) / scale;
342         }
343     }
344     if (newValue - m_inputType->maximum() > acceptableError) {
345         ec = INVALID_STATE_ERR;
346         return;
347     }
348     if (newValue > m_inputType->maximum())
349         newValue = m_inputType->maximum();
350     setValueAsNumber(newValue, ec);
351     
352     if (AXObjectCache::accessibilityEnabled())
353          document()->axObjectCache()->postNotification(renderer(), AXObjectCache::AXValueChanged, true);
354 }
355
356 void HTMLInputElement::stepUp(int n, ExceptionCode& ec)
357 {
358     applyStep(n, ec);
359 }
360
361 void HTMLInputElement::stepDown(int n, ExceptionCode& ec)
362 {
363     applyStep(-n, ec);
364 }
365
366 bool HTMLInputElement::isKeyboardFocusable(KeyboardEvent* event) const
367 {
368     if (isTextField())
369         return HTMLFormControlElementWithState::isFocusable();
370     return HTMLFormControlElementWithState::isKeyboardFocusable(event) && m_inputType->isKeyboardFocusable();
371 }
372
373 bool HTMLInputElement::isMouseFocusable() const
374 {
375     if (isTextField())
376         return HTMLFormControlElementWithState::isFocusable();
377     return HTMLFormControlElementWithState::isMouseFocusable();
378 }
379
380 void HTMLInputElement::updateFocusAppearance(bool restorePreviousSelection)
381 {        
382     if (isTextField())
383         InputElement::updateFocusAppearance(m_data, this, this, restorePreviousSelection);
384     else
385         HTMLFormControlElementWithState::updateFocusAppearance(restorePreviousSelection);
386 }
387
388 void HTMLInputElement::aboutToUnload()
389 {
390     InputElement::aboutToUnload(this, this);
391 }
392
393 bool HTMLInputElement::shouldUseInputMethod() const
394 {
395     return m_inputType->shouldUseInputMethod();
396 }
397
398 void HTMLInputElement::handleFocusEvent()
399 {
400     InputElement::dispatchFocusEvent(this, this);
401 }
402
403 void HTMLInputElement::handleBlurEvent()
404 {
405     m_inputType->handleBlurEvent();
406     InputElement::dispatchBlurEvent(this, this);
407 }
408
409 void HTMLInputElement::setType(const String& type)
410 {
411     // FIXME: This should just call setAttribute. No reason to handle the empty string specially.
412     // We should write a test case to show that setting to the empty string does not remove the
413     // attribute in other browsers and then fix this. Note that setting to null *does* remove
414     // the attribute and setAttribute implements that.
415     if (type.isEmpty()) {
416         ExceptionCode ec;
417         removeAttribute(typeAttr, ec);
418     } else
419         setAttribute(typeAttr, type);
420 }
421
422 void HTMLInputElement::updateType()
423 {
424     const AtomicString& typeString = fastGetAttribute(typeAttr);
425
426     OwnPtr<InputType> newType = InputType::create(this, typeString);
427
428     if (m_hasType && !newType->canChangeFromAnotherType()) {
429         // Set the attribute back to the old value.
430         // Useful in case we were called from inside parseMappedAttribute.
431         setAttribute(typeAttr, type());
432         return;
433     }
434
435     m_hasType = true;
436
437     if (m_inputType->formControlType() == newType->formControlType())
438         return;
439
440     checkedRadioButtons().removeButton(this);
441
442     bool wasAttached = attached();
443     if (wasAttached)
444         detach();
445
446     bool didStoreValue = m_inputType->storesValueSeparateFromAttribute();
447     bool neededActivationCallback = needsActivationCallback();
448     bool didRespectHeightAndWidth = m_inputType->shouldRespectHeightAndWidthAttributes();
449
450     m_inputType = newType.release();
451
452     setNeedsWillValidateCheck();
453
454     bool willStoreValue = m_inputType->storesValueSeparateFromAttribute();
455
456     if (didStoreValue && !willStoreValue && !m_data.value().isNull()) {
457         setAttribute(valueAttr, m_data.value());
458         m_data.setValue(String());
459     }
460     if (!didStoreValue && willStoreValue)
461         m_data.setValue(sanitizeValue(fastGetAttribute(valueAttr)));
462     else
463         InputElement::updateValueIfNeeded(m_data, this);
464
465     if (neededActivationCallback)
466         unregisterForActivationCallbackIfNeeded();
467     else
468         registerForActivationCallbackIfNeeded();
469
470     if (didRespectHeightAndWidth != m_inputType->shouldRespectHeightAndWidthAttributes()) {
471         NamedNodeMap* map = attributeMap();
472         ASSERT(map);
473         if (Attribute* height = map->getAttributeItem(heightAttr))
474             attributeChanged(height, false);
475         if (Attribute* width = map->getAttributeItem(widthAttr))
476             attributeChanged(width, false);
477         if (Attribute* align = map->getAttributeItem(alignAttr))
478             attributeChanged(align, false);
479     }
480
481     if (wasAttached) {
482         attach();
483         if (document()->focusedNode() == this)
484             updateFocusAppearance(true);
485     }
486
487     checkedRadioButtons().addButton(this);
488
489     setNeedsValidityCheck();
490     InputElement::notifyFormStateChanged(this);
491 }
492
493 const AtomicString& HTMLInputElement::formControlType() const
494 {
495     return m_inputType->formControlType();
496 }
497
498 bool HTMLInputElement::saveFormControlState(String& result) const
499 {
500     return m_inputType->saveFormControlState(result);
501 }
502
503 void HTMLInputElement::restoreFormControlState(const String& state)
504 {
505     m_inputType->restoreFormControlState(state);
506 }
507
508 bool HTMLInputElement::canStartSelection() const
509 {
510     if (!isTextField())
511         return false;
512     return HTMLFormControlElementWithState::canStartSelection();
513 }
514
515 bool HTMLInputElement::canHaveSelection() const
516 {
517     return isTextField();
518 }
519
520 void HTMLInputElement::accessKeyAction(bool sendToAnyElement)
521 {
522     m_inputType->accessKeyAction(sendToAnyElement);
523 }
524
525 bool HTMLInputElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
526 {
527     if (((attrName == heightAttr || attrName == widthAttr) && m_inputType->shouldRespectHeightAndWidthAttributes())
528         || attrName == vspaceAttr 
529         || attrName == hspaceAttr) {
530         result = eUniversal;
531         return false;
532     } 
533
534     if (attrName == alignAttr && m_inputType->shouldRespectAlignAttribute()) {
535         // Share with <img> since the alignment behavior is the same.
536         result = eReplaced;
537         return false;
538     }
539
540     return HTMLElement::mapToEntry(attrName, result);
541 }
542
543 void HTMLInputElement::parseMappedAttribute(Attribute* attr)
544 {
545     if (attr->name() == nameAttr) {
546         checkedRadioButtons().removeButton(this);
547         m_data.setName(attr->value());
548         checkedRadioButtons().addButton(this);
549         HTMLFormControlElementWithState::parseMappedAttribute(attr);
550     } else if (attr->name() == autocompleteAttr) {
551         if (equalIgnoringCase(attr->value(), "off")) {
552             m_autocomplete = Off;
553             registerForActivationCallbackIfNeeded();
554         } else {
555             bool needsToUnregister = m_autocomplete == Off;
556
557             if (attr->isEmpty())
558                 m_autocomplete = Uninitialized;
559             else
560                 m_autocomplete = On;
561
562             if (needsToUnregister)
563                 unregisterForActivationCallbackIfNeeded();
564         }
565     } else if (attr->name() == typeAttr) {
566         updateType();
567     } else if (attr->name() == valueAttr) {
568         // We only need to setChanged if the form is looking at the default value right now.
569         if (m_data.value().isNull())
570             setNeedsStyleRecalc();
571         setFormControlValueMatchesRenderer(false);
572         setNeedsValidityCheck();
573     } else if (attr->name() == checkedAttr) {
574         if (m_reflectsCheckedAttribute) {
575             setChecked(!attr->isNull());
576             m_reflectsCheckedAttribute = true;
577         }
578         setNeedsValidityCheck();
579     } else if (attr->name() == maxlengthAttr) {
580         InputElement::parseMaxLengthAttribute(m_data, this, this, attr);
581         setNeedsValidityCheck();
582     } else if (attr->name() == sizeAttr)
583         InputElement::parseSizeAttribute(m_data, this, attr);
584     else if (attr->name() == altAttr)
585         m_inputType->altAttributeChanged();
586     else if (attr->name() == srcAttr)
587         m_inputType->srcAttributeChanged();
588     else if (attr->name() == usemapAttr || attr->name() == accesskeyAttr) {
589         // FIXME: ignore for the moment
590     } else if (attr->name() == vspaceAttr) {
591         addCSSLength(attr, CSSPropertyMarginTop, attr->value());
592         addCSSLength(attr, CSSPropertyMarginBottom, attr->value());
593     } else if (attr->name() == hspaceAttr) {
594         addCSSLength(attr, CSSPropertyMarginLeft, attr->value());
595         addCSSLength(attr, CSSPropertyMarginRight, attr->value());
596     } else if (attr->name() == alignAttr) {
597         if (m_inputType->shouldRespectAlignAttribute())
598             addHTMLAlignment(attr);
599     } else if (attr->name() == widthAttr) {
600         if (m_inputType->shouldRespectHeightAndWidthAttributes())
601             addCSSLength(attr, CSSPropertyWidth, attr->value());
602     } else if (attr->name() == heightAttr) {
603         if (m_inputType->shouldRespectHeightAndWidthAttributes())
604             addCSSLength(attr, CSSPropertyHeight, attr->value());
605     } else if (attr->name() == onsearchAttr) {
606         // Search field and slider attributes all just cause updateFromElement to be called through style recalcing.
607         setAttributeEventListener(eventNames().searchEvent, createAttributeEventListener(this, attr));
608     } else if (attr->name() == resultsAttr) {
609         int oldResults = m_maxResults;
610         m_maxResults = !attr->isNull() ? std::min(attr->value().toInt(), maxSavedResults) : -1;
611         // FIXME: Detaching just for maxResults change is not ideal.  We should figure out the right
612         // time to relayout for this change.
613         if (m_maxResults != oldResults && (m_maxResults <= 0 || oldResults <= 0) && attached()) {
614             detach();
615             attach();
616         }
617         setNeedsStyleRecalc();
618     } else if (attr->name() == autosaveAttr || attr->name() == incrementalAttr)
619         setNeedsStyleRecalc();
620     else if (attr->name() == minAttr || attr->name() == maxAttr) {
621         m_inputType->minOrMaxAttributeChanged();
622         setNeedsValidityCheck();
623     } else if (attr->name() == multipleAttr || attr->name() == patternAttr || attr->name() == precisionAttr || attr->name() == stepAttr)
624         setNeedsValidityCheck();
625 #if ENABLE(DATALIST)
626     else if (attr->name() == listAttr)
627         m_hasNonEmptyList = !attr->isEmpty();
628         // FIXME: we need to tell this change to a renderer if the attribute affects the appearance.
629 #endif
630 #if ENABLE(INPUT_SPEECH)
631     else if (attr->name() == webkitspeechAttr) {
632       if (renderer())
633           toRenderTextControlSingleLine(renderer())->speechAttributeChanged();
634       setNeedsStyleRecalc();
635     } else if (attr->name() == onwebkitspeechchangeAttr)
636         setAttributeEventListener(eventNames().webkitspeechchangeEvent, createAttributeEventListener(this, attr));
637 #endif
638     else
639         HTMLTextFormControlElement::parseMappedAttribute(attr);
640 }
641
642 bool HTMLInputElement::rendererIsNeeded(RenderStyle* style)
643 {
644     return m_inputType->rendererIsNeeded() && HTMLFormControlElementWithState::rendererIsNeeded(style);
645 }
646
647 RenderObject* HTMLInputElement::createRenderer(RenderArena* arena, RenderStyle* style)
648 {
649     return m_inputType->createRenderer(arena, style);
650 }
651
652 void HTMLInputElement::attach()
653 {
654     if (!m_hasType)
655         updateType();
656
657     HTMLFormControlElementWithState::attach();
658
659     m_inputType->attach();
660
661     if (document()->focusedNode() == this)
662         document()->updateFocusAppearanceSoon(true /* restore selection */);
663 }
664
665 void HTMLInputElement::detach()
666 {
667     HTMLFormControlElementWithState::detach();
668     setFormControlValueMatchesRenderer(false);
669 }
670
671 String HTMLInputElement::altText() const
672 {
673     // http://www.w3.org/TR/1998/REC-html40-19980424/appendix/notes.html#altgen
674     // also heavily discussed by Hixie on bugzilla
675     // note this is intentionally different to HTMLImageElement::altText()
676     String alt = fastGetAttribute(altAttr);
677     // fall back to title attribute
678     if (alt.isNull())
679         alt = getAttribute(titleAttr);
680     if (alt.isNull())
681         alt = getAttribute(valueAttr);
682     if (alt.isEmpty())
683         alt = inputElementAltText();
684     return alt;
685 }
686
687 bool HTMLInputElement::isSuccessfulSubmitButton() const
688 {
689     // HTML spec says that buttons must have names to be considered successful.
690     // However, other browsers do not impose this constraint. So we do not.
691     return !disabled() && m_inputType->canBeSuccessfulSubmitButton();
692 }
693
694 bool HTMLInputElement::isActivatedSubmit() const
695 {
696     return m_isActivatedSubmit;
697 }
698
699 void HTMLInputElement::setActivatedSubmit(bool flag)
700 {
701     m_isActivatedSubmit = flag;
702 }
703
704 bool HTMLInputElement::appendFormData(FormDataList& encoding, bool multipart)
705 {
706     return m_inputType->isFormDataAppendable() && m_inputType->appendFormData(encoding, multipart);
707 }
708
709 void HTMLInputElement::reset()
710 {
711     if (m_inputType->storesValueSeparateFromAttribute())
712         setValue(String());
713
714     setChecked(hasAttribute(checkedAttr));
715     m_reflectsCheckedAttribute = true;
716 }
717
718 bool HTMLInputElement::isTextField() const
719 {
720     return m_inputType->isTextField();
721 }
722
723 bool HTMLInputElement::isTextType() const
724 {
725     return m_inputType->isTextType();
726 }
727
728 void HTMLInputElement::setChecked(bool nowChecked, bool sendChangeEvent)
729 {
730     if (checked() == nowChecked)
731         return;
732
733     checkedRadioButtons().removeButton(this);
734
735     m_reflectsCheckedAttribute = false;
736     m_isChecked = nowChecked;
737     setNeedsStyleRecalc();
738
739     updateCheckedRadioButtons();
740
741     // Ideally we'd do this from the render tree (matching
742     // RenderTextView), but it's not possible to do it at the moment
743     // because of the way the code is structured.
744     if (renderer() && AXObjectCache::accessibilityEnabled())
745         renderer()->document()->axObjectCache()->postNotification(renderer(), AXObjectCache::AXCheckedStateChanged, true);
746
747     // Only send a change event for items in the document (avoid firing during
748     // parsing) and don't send a change event for a radio button that's getting
749     // unchecked to match other browsers. DOM is not a useful standard for this
750     // because it says only to fire change events at "lose focus" time, which is
751     // definitely wrong in practice for these types of elements.
752     if (sendChangeEvent && inDocument() && m_inputType->shouldSendChangeEventAfterCheckedChanged())
753         dispatchFormControlChangeEvent();
754 }
755
756 void HTMLInputElement::setIndeterminate(bool newValue)
757 {
758     if (!m_inputType->isCheckable() || indeterminate() == newValue)
759         return;
760
761     m_isIndeterminate = newValue;
762
763     setNeedsStyleRecalc();
764
765     if (renderer() && renderer()->style()->hasAppearance())
766         renderer()->theme()->stateChanged(renderer(), CheckedState);
767 }
768
769 int HTMLInputElement::size() const
770 {
771     return m_data.size();
772 }
773
774 void HTMLInputElement::copyNonAttributeProperties(const Element* source)
775 {
776     const HTMLInputElement* sourceElement = static_cast<const HTMLInputElement*>(source);
777
778     m_data.setValue(sourceElement->m_data.value());
779     setChecked(sourceElement->m_isChecked);
780     m_reflectsCheckedAttribute = sourceElement->m_reflectsCheckedAttribute;
781     m_isIndeterminate = sourceElement->m_isIndeterminate;
782
783     HTMLFormControlElementWithState::copyNonAttributeProperties(source);
784 }
785
786 String HTMLInputElement::value() const
787 {
788     String value;
789     if (m_inputType->getTypeSpecificValue(value))
790         return value;
791
792     value = m_data.value();
793     if (!value.isNull())
794         return value;
795
796     value = sanitizeValue(fastGetAttribute(valueAttr));
797     if (!value.isNull())
798         return value;
799
800     return m_inputType->fallbackValue();
801 }
802
803 String HTMLInputElement::valueWithDefault() const
804 {
805     String value = this->value();
806     if (!value.isNull())
807         return value;
808
809     return m_inputType->defaultValue();
810 }
811
812 void HTMLInputElement::setValueForUser(const String& value)
813 {
814     // Call setValue and make it send a change event.
815     setValue(value, true);
816 }
817
818 const String& HTMLInputElement::suggestedValue() const
819 {
820     return m_data.suggestedValue();
821 }
822
823 void HTMLInputElement::setSuggestedValue(const String& value)
824 {
825     if (!m_inputType->canSetSuggestedValue())
826         return;
827     setFormControlValueMatchesRenderer(false);
828     m_data.setSuggestedValue(sanitizeValue(value));
829     updatePlaceholderVisibility(false);
830     if (renderer())
831         renderer()->updateFromElement();
832     setNeedsStyleRecalc();
833 }
834
835 void HTMLInputElement::setValue(const String& value, bool sendChangeEvent)
836 {
837     if (!m_inputType->canSetValue(value))
838         return;
839
840     setFormControlValueMatchesRenderer(false);
841     if (m_inputType->storesValueSeparateFromAttribute()) {
842         if (files())
843             files()->clear();
844         else {
845             m_data.setValue(sanitizeValue(value));
846             if (isTextField())
847                 updatePlaceholderVisibility(false);
848         }
849         setNeedsStyleRecalc();
850     } else
851         setAttribute(valueAttr, sanitizeValue(value));
852
853     setNeedsValidityCheck();
854
855     if (isTextField()) {
856         unsigned max = m_data.value().length();
857         if (document()->focusedNode() == this)
858             InputElement::updateSelectionRange(this, this, max, max);
859         else
860             cacheSelection(max, max);
861         m_data.setSuggestedValue(String());
862     }
863
864     // Don't dispatch the change event when focused, it will be dispatched
865     // when the control loses focus.
866     if (sendChangeEvent && document()->focusedNode() != this)
867         dispatchFormControlChangeEvent();
868
869     InputElement::notifyFormStateChanged(this);
870 }
871
872 double HTMLInputElement::valueAsDate() const
873 {
874     return m_inputType->valueAsDate();
875 }
876
877 void HTMLInputElement::setValueAsDate(double value, ExceptionCode& ec)
878 {
879     m_inputType->setValueAsDate(value, ec);
880 }
881
882 double HTMLInputElement::valueAsNumber() const
883 {
884     return m_inputType->valueAsNumber();
885 }
886
887 void HTMLInputElement::setValueAsNumber(double newValue, ExceptionCode& ec)
888 {
889     if (!isfinite(newValue)) {
890         ec = NOT_SUPPORTED_ERR;
891         return;
892     }
893     m_inputType->setValueAsNumber(newValue, ec);
894 }
895
896 String HTMLInputElement::placeholder() const
897 {
898     return fastGetAttribute(placeholderAttr).string();
899 }
900
901 void HTMLInputElement::setPlaceholder(const String& value)
902 {
903     setAttribute(placeholderAttr, value);
904 }
905
906 bool HTMLInputElement::searchEventsShouldBeDispatched() const
907 {
908     return hasAttribute(incrementalAttr);
909 }
910
911 void HTMLInputElement::setValueFromRenderer(const String& value)
912 {
913     // File upload controls will always use setFileListFromRenderer.
914     ASSERT(!isFileUpload());
915
916     m_data.setSuggestedValue(String());
917     InputElement::setValueFromRenderer(m_data, this, this, value);
918     updatePlaceholderVisibility(false);
919     setNeedsValidityCheck();
920
921     // Clear autofill flag (and yellow background) on user edit.
922     setAutofilled(false);
923 }
924
925 void HTMLInputElement::setFileListFromRenderer(const Vector<String>& paths)
926 {
927     m_inputType->setFileList(paths);
928
929     setFormControlValueMatchesRenderer(true);
930     InputElement::notifyFormStateChanged(this);
931     setNeedsValidityCheck();
932 }
933
934 void* HTMLInputElement::preDispatchEventHandler(Event* event)
935 {
936     if (event->type() != eventNames().clickEvent)
937         return 0;
938     // FIXME: Check whether there are any cases where this actually ends up leaking.
939     return m_inputType->willDispatchClick().leakPtr();
940 }
941
942 void HTMLInputElement::postDispatchEventHandler(Event* event, void* dataFromPreDispatch)
943 {
944     OwnPtr<ClickHandlingState> state = adoptPtr(static_cast<ClickHandlingState*>(dataFromPreDispatch));
945     if (event->type() != eventNames().clickEvent)
946         return;
947     if (!state)
948         return;
949     m_inputType->didDispatchClick(event, *state);
950 }
951
952 void HTMLInputElement::defaultEventHandler(Event* evt)
953 {
954     if (evt->isMouseEvent() && evt->type() == eventNames().clickEvent) {
955         m_inputType->handleClickEvent(static_cast<MouseEvent*>(evt));
956         if (evt->defaultHandled())
957             return;
958     }
959
960     if (evt->isKeyboardEvent() && evt->type() == eventNames().keydownEvent) {
961         m_inputType->handleKeydownEvent(static_cast<KeyboardEvent*>(evt));
962         if (evt->defaultHandled())
963             return;
964     }
965
966     // Call the base event handler before any of our own event handling for almost all events in text fields.
967     // Makes editing keyboard handling take precedence over the keydown and keypress handling in this function.
968     bool callBaseClassEarly = isTextField() && (evt->type() == eventNames().keydownEvent || evt->type() == eventNames().keypressEvent);
969     if (callBaseClassEarly) {
970         HTMLFormControlElementWithState::defaultEventHandler(evt);
971         if (evt->defaultHandled())
972             return;
973     }
974
975     // DOMActivate events cause the input to be "activated" - in the case of image and submit inputs, this means
976     // actually submitting the form. For reset inputs, the form is reset. These events are sent when the user clicks
977     // on the element, or presses enter while it is the active element. JavaScript code wishing to activate the element
978     // must dispatch a DOMActivate event - a click event will not do the job.
979     if (evt->type() == eventNames().DOMActivateEvent) {
980         m_inputType->handleDOMActivateEvent(evt);
981         if (evt->defaultHandled())
982             return;
983     }
984
985     // Use key press event here since sending simulated mouse events
986     // on key down blocks the proper sending of the key press event.
987     if (evt->isKeyboardEvent() && evt->type() == eventNames().keypressEvent) {
988         m_inputType->handleKeypressEvent(static_cast<KeyboardEvent*>(evt));
989         if (evt->defaultHandled())
990             return;
991     }
992
993     if (evt->isKeyboardEvent() && evt->type() == eventNames().keyupEvent) {
994         m_inputType->handleKeyupEvent(static_cast<KeyboardEvent*>(evt));
995         if (evt->defaultHandled())
996             return;
997     }
998
999     if (m_inputType->shouldSubmitImplicitly(evt)) {
1000         if (isSearchField()) {
1001             addSearchResult();
1002             onSearch();
1003         }
1004         // Fire onChange for text fields.
1005         RenderObject* r = renderer();
1006         if (r && r->isTextField() && toRenderTextControl(r)->wasChangedSinceLastChangeEvent()) {
1007             dispatchFormControlChangeEvent();
1008             // Refetch the renderer since arbitrary JS code run during onchange can do anything, including destroying it.
1009             r = renderer();
1010             if (r && r->isTextField())
1011                 toRenderTextControl(r)->setChangedSinceLastChangeEvent(false);
1012         }
1013
1014         RefPtr<HTMLFormElement> formForSubmission = m_inputType->formForSubmission();
1015         // Form may never have been present, or may have been destroyed by code responding to the change event.
1016         if (formForSubmission)
1017             formForSubmission->submitImplicitly(evt, canTriggerImplicitSubmission());
1018
1019         evt->setDefaultHandled();
1020         return;
1021     }
1022
1023     if (evt->isBeforeTextInsertedEvent())
1024         m_inputType->handleBeforeTextInsertedEvent(static_cast<BeforeTextInsertedEvent*>(evt));
1025
1026     if (evt->isWheelEvent()) {
1027         m_inputType->handleWheelEvent(static_cast<WheelEvent*>(evt));
1028         if (evt->defaultHandled())
1029             return;
1030     }
1031
1032     m_inputType->forwardEvent(evt);
1033
1034     if (!callBaseClassEarly && !evt->defaultHandled())
1035         HTMLFormControlElementWithState::defaultEventHandler(evt);
1036 }
1037
1038 bool HTMLInputElement::isURLAttribute(Attribute *attr) const
1039 {
1040     return (attr->name() == srcAttr || attr->name() == formactionAttr);
1041 }
1042
1043 String HTMLInputElement::defaultValue() const
1044 {
1045     return fastGetAttribute(valueAttr);
1046 }
1047
1048 void HTMLInputElement::setDefaultValue(const String &value)
1049 {
1050     setAttribute(valueAttr, value);
1051 }
1052
1053 void HTMLInputElement::setDefaultName(const AtomicString& name)
1054 {
1055     m_data.setName(name);
1056 }
1057
1058 String HTMLInputElement::accept() const
1059 {
1060     return fastGetAttribute(acceptAttr);
1061 }
1062
1063 String HTMLInputElement::alt() const
1064 {
1065     return fastGetAttribute(altAttr);
1066 }
1067
1068 int HTMLInputElement::maxLength() const
1069 {
1070     return m_data.maxLength();
1071 }
1072
1073 void HTMLInputElement::setMaxLength(int maxLength, ExceptionCode& ec)
1074 {
1075     if (maxLength < 0)
1076         ec = INDEX_SIZE_ERR;
1077     else
1078         setAttribute(maxlengthAttr, String::number(maxLength));
1079 }
1080
1081 bool HTMLInputElement::multiple() const
1082 {
1083     return fastHasAttribute(multipleAttr);
1084 }
1085
1086 void HTMLInputElement::setSize(unsigned size)
1087 {
1088     setAttribute(sizeAttr, String::number(size));
1089 }
1090
1091 KURL HTMLInputElement::src() const
1092 {
1093     return document()->completeURL(fastGetAttribute(srcAttr));
1094 }
1095
1096 void HTMLInputElement::setAutofilled(bool autofilled)
1097 {
1098     if (autofilled == m_isAutofilled)
1099         return;
1100         
1101     m_isAutofilled = autofilled;
1102     setNeedsStyleRecalc();
1103 }
1104
1105 FileList* HTMLInputElement::files()
1106 {
1107     return m_inputType->files();
1108 }
1109
1110 bool HTMLInputElement::isAcceptableValue(const String& proposedValue) const
1111 {
1112     return m_inputType->isAcceptableValue(proposedValue);
1113 }
1114
1115 String HTMLInputElement::sanitizeValue(const String& proposedValue) const
1116 {
1117     return m_inputType->sanitizeValue(proposedValue);
1118 }
1119
1120 bool HTMLInputElement::hasUnacceptableValue() const
1121 {
1122     return m_inputType->hasUnacceptableValue();
1123 }
1124
1125 bool HTMLInputElement::isInRange() const
1126 {
1127     return m_inputType->supportsRangeLimitation() && !rangeUnderflow(value()) && !rangeOverflow(value());
1128 }
1129
1130 bool HTMLInputElement::isOutOfRange() const
1131 {
1132     return m_inputType->supportsRangeLimitation() && (rangeUnderflow(value()) || rangeOverflow(value()));
1133 }
1134
1135 bool HTMLInputElement::needsActivationCallback()
1136 {
1137     return m_autocomplete == Off || m_inputType->shouldResetOnDocumentActivation();
1138 }
1139
1140 void HTMLInputElement::registerForActivationCallbackIfNeeded()
1141 {
1142     if (needsActivationCallback())
1143         document()->registerForDocumentActivationCallbacks(this);
1144 }
1145
1146 void HTMLInputElement::unregisterForActivationCallbackIfNeeded()
1147 {
1148     if (!needsActivationCallback())
1149         document()->unregisterForDocumentActivationCallbacks(this);
1150 }
1151
1152 bool HTMLInputElement::isRequiredFormControl() const
1153 {
1154     return m_inputType->supportsRequired() && required();
1155 }
1156
1157 void HTMLInputElement::cacheSelection(int start, int end)
1158 {
1159     m_data.setCachedSelectionStart(start);
1160     m_data.setCachedSelectionEnd(end);
1161 }
1162
1163 void HTMLInputElement::addSearchResult()
1164 {
1165     ASSERT(isSearchField());
1166     if (renderer())
1167         toRenderTextControlSingleLine(renderer())->addSearchResult();
1168 }
1169
1170 void HTMLInputElement::onSearch()
1171 {
1172     ASSERT(isSearchField());
1173     if (renderer())
1174         toRenderTextControlSingleLine(renderer())->stopSearchEventTimer();
1175     dispatchEvent(Event::create(eventNames().searchEvent, true, false));
1176 }
1177
1178 void HTMLInputElement::documentDidBecomeActive()
1179 {
1180     ASSERT(needsActivationCallback());
1181     reset();
1182 }
1183
1184 void HTMLInputElement::willMoveToNewOwnerDocument()
1185 {
1186     m_inputType->willMoveToNewOwnerDocument();
1187
1188     // Always unregister for cache callbacks when leaving a document, even if we would otherwise like to be registered
1189     if (needsActivationCallback())
1190         document()->unregisterForDocumentActivationCallbacks(this);
1191         
1192     document()->checkedRadioButtons().removeButton(this);
1193
1194     HTMLFormControlElementWithState::willMoveToNewOwnerDocument();
1195 }
1196
1197 void HTMLInputElement::didMoveToNewOwnerDocument()
1198 {
1199     registerForActivationCallbackIfNeeded();
1200         
1201     HTMLFormControlElementWithState::didMoveToNewOwnerDocument();
1202 }
1203     
1204 void HTMLInputElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
1205 {
1206     HTMLFormControlElementWithState::addSubresourceAttributeURLs(urls);
1207
1208     addSubresourceURL(urls, src());
1209 }
1210
1211 bool HTMLInputElement::recalcWillValidate() const
1212 {
1213     return m_inputType->supportsValidation() && HTMLFormControlElementWithState::recalcWillValidate();
1214 }
1215
1216 #if ENABLE(DATALIST)
1217
1218 HTMLElement* HTMLInputElement::list() const
1219 {
1220     return dataList();
1221 }
1222
1223 HTMLDataListElement* HTMLInputElement::dataList() const
1224 {
1225     if (!m_hasNonEmptyList)
1226         return 0;
1227
1228     if (!m_inputType->shouldRespectListAttribute())
1229         return 0;
1230
1231     Element* element = document()->getElementById(fastGetAttribute(listAttr));
1232     if (!element)
1233         return 0;
1234     if (!element->hasTagName(datalistTag))
1235         return 0;
1236
1237     return static_cast<HTMLDataListElement*>(element);
1238 }
1239
1240 HTMLOptionElement* HTMLInputElement::selectedOption() const
1241 {
1242     String value = this->value();
1243
1244     // The empty string never matches to a datalist option because it
1245     // doesn't represent a suggestion according to the standard.
1246     if (value.isEmpty())
1247         return 0;
1248
1249     HTMLDataListElement* sourceElement = dataList();
1250     if (!sourceElement)
1251         return 0;
1252     RefPtr<HTMLCollection> options = sourceElement->options();
1253     if (!options)
1254         return 0;
1255     unsigned length = options->length();
1256     for (unsigned i = 0; i < length; ++i) {
1257         HTMLOptionElement* option = static_cast<HTMLOptionElement*>(options->item(i));
1258         if (!option->disabled() && value == option->value())
1259             return option;
1260     }
1261     return 0;
1262 }
1263
1264 #endif // ENABLE(DATALIST)
1265
1266 void HTMLInputElement::stepUpFromRenderer(int n)
1267 {
1268     // The differences from stepUp()/stepDown():
1269     //
1270     // Difference 1: the current value
1271     // If the current value is not a number, including empty, the current value is assumed as 0.
1272     //   * If 0 is in-range, and matches to step value
1273     //     - The value should be the +step if n > 0
1274     //     - The value should be the -step if n < 0
1275     //     If -step or +step is out of range, new value should be 0.
1276     //   * If 0 is smaller than the minimum value
1277     //     - The value should be the minimum value for any n
1278     //   * If 0 is larger than the maximum value
1279     //     - The value should be the maximum value for any n
1280     //   * If 0 is in-range, but not matched to step value
1281     //     - The value should be the larger matched value nearest to 0 if n > 0
1282     //       e.g. <input type=number min=-100 step=3> -> 2
1283     //     - The value should be the smaler matched value nearest to 0 if n < 0
1284     //       e.g. <input type=number min=-100 step=3> -> -1
1285     //   As for date/datetime-local/month/time/week types, the current value is assumed as "the current local date/time".
1286     //   As for datetime type, the current value is assumed as "the current date/time in UTC".
1287     // If the current value is smaller than the minimum value:
1288     //  - The value should be the minimum value if n > 0
1289     //  - Nothing should happen if n < 0
1290     // If the current value is larger than the maximum value:
1291     //  - The value should be the maximum value if n < 0
1292     //  - Nothing should happen if n > 0
1293     //
1294     // Difference 2: clamping steps
1295     // If the current value is not matched to step value:
1296     // - The value should be the larger matched value nearest to 0 if n > 0
1297     //   e.g. <input type=number value=3 min=-100 step=3> -> 5
1298     // - The value should be the smaler matched value nearest to 0 if n < 0
1299     //   e.g. <input type=number value=3 min=-100 step=3> -> 2
1300     //
1301     // n is assumed as -n if step < 0.
1302
1303     ASSERT(hasSpinButton() || m_inputType->isRangeControl());
1304     if (!hasSpinButton() && !m_inputType->isRangeControl())
1305         return;
1306     ASSERT(n);
1307     if (!n)
1308         return;
1309
1310     unsigned stepDecimalPlaces, baseDecimalPlaces;
1311     double step, base;
1312     // The value will be the default value after stepping for <input value=(empty/invalid) step="any" />
1313     // FIXME: Not any changes after stepping, even if it is an invalid value, may be better.
1314     // (e.g. Stepping-up for <input type="number" value="foo" step="any" /> => "foo")
1315     if (equalIgnoringCase(fastGetAttribute(stepAttr), "any"))
1316         step = 0;
1317     else if (!getAllowedValueStepWithDecimalPlaces(&step, &stepDecimalPlaces))
1318         return;
1319     base = m_inputType->stepBaseWithDecimalPlaces(&baseDecimalPlaces);
1320     baseDecimalPlaces = min(baseDecimalPlaces, 16u);
1321
1322     int sign;
1323     if (step > 0)
1324         sign = n;
1325     else if (step < 0)
1326         sign = -n;
1327     else
1328         sign = 0;
1329
1330     const double nan = numeric_limits<double>::quiet_NaN();
1331     String currentStringValue = value();
1332     double current = m_inputType->parseToDouble(currentStringValue, nan);
1333     if (!isfinite(current)) {
1334         ExceptionCode ec;
1335         current = m_inputType->defaultValueForStepUp();
1336         setValueAsNumber(current, ec);
1337     }
1338     if ((sign > 0 && current < m_inputType->minimum()) || (sign < 0 && current > m_inputType->maximum()))
1339         setValue(m_inputType->serialize(sign > 0 ? m_inputType->minimum() : m_inputType->maximum()));
1340     else {
1341         ExceptionCode ec;
1342         if (stepMismatch(currentStringValue)) {
1343             ASSERT(step);
1344             double newValue;
1345             double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces)));
1346
1347             if (sign < 0)
1348                 newValue = round((base + floor((current - base) / step) * step) * scale) / scale;
1349             else if (sign > 0)
1350                 newValue = round((base + ceil((current - base) / step) * step) * scale) / scale;
1351             else
1352                 newValue = current;
1353
1354             if (newValue < m_inputType->minimum())
1355                 newValue = m_inputType->minimum();
1356             if (newValue > m_inputType->maximum())
1357                 newValue = m_inputType->maximum();
1358
1359             setValueAsNumber(newValue, ec);
1360             current = newValue;
1361             if (n > 1)
1362                 applyStep(n - 1, ec);
1363             else if (n < -1)
1364                 applyStep(n + 1, ec);
1365         } else
1366             applyStep(n, ec);
1367     }
1368
1369     if (currentStringValue != value()) {
1370         if (renderer() && renderer()->isTextField())
1371             toRenderTextControl(renderer())->setChangedSinceLastChangeEvent(true);
1372         if (m_inputType->isRangeControl())
1373             dispatchFormControlChangeEvent();
1374         else
1375             dispatchEvent(Event::create(eventNames().inputEvent, true, false));
1376     }
1377 }
1378
1379 #if ENABLE(WCSS)
1380
1381 void HTMLInputElement::setWapInputFormat(String& mask)
1382 {
1383     String validateMask = validateInputMask(m_data, mask);
1384     if (!validateMask.isEmpty())
1385         m_data.setInputFormatMask(validateMask);
1386 }
1387
1388 #endif
1389
1390 #if ENABLE(INPUT_SPEECH)
1391
1392 bool HTMLInputElement::isSpeechEnabled() const
1393 {
1394     // FIXME: Add support for RANGE, EMAIL, URL, COLOR and DATE/TIME input types.
1395     return m_inputType->shouldRespectSpeechAttribute() && RuntimeEnabledFeatures::speechInputEnabled() && hasAttribute(webkitspeechAttr);
1396 }
1397
1398 #endif
1399
1400 bool HTMLInputElement::isTextButton() const
1401 {
1402     return m_inputType->isTextButton();
1403 }
1404
1405 bool HTMLInputElement::isRadioButton() const
1406 {
1407     return m_inputType->isRadioButton();
1408 }
1409
1410 bool HTMLInputElement::isSearchField() const
1411 {
1412     return m_inputType->isSearchField();
1413 }
1414
1415 bool HTMLInputElement::isInputTypeHidden() const
1416 {
1417     return m_inputType->isHiddenType();
1418 }
1419
1420 bool HTMLInputElement::isPasswordField() const
1421 {
1422     return m_inputType->isPasswordField();
1423 }
1424
1425 bool HTMLInputElement::isCheckbox() const
1426 {
1427     return m_inputType->isCheckbox();
1428 }
1429
1430 bool HTMLInputElement::isText() const
1431 {
1432     return m_inputType->isTextType();
1433 }
1434
1435 bool HTMLInputElement::isEmailField() const
1436 {
1437     return m_inputType->isEmailField();
1438 }
1439
1440 bool HTMLInputElement::isFileUpload() const
1441 {
1442     return m_inputType->isFileUpload();
1443 }
1444
1445 bool HTMLInputElement::isImageButton() const
1446 {
1447     return m_inputType->isImageButton();
1448 }
1449
1450 bool HTMLInputElement::isNumberField() const
1451 {
1452     return m_inputType->isNumberField();
1453 }
1454
1455 bool HTMLInputElement::isSubmitButton() const
1456 {
1457     return m_inputType->isSubmitButton();
1458 }
1459
1460 bool HTMLInputElement::isTelephoneField() const
1461 {
1462     return m_inputType->isTelephoneField();
1463 }
1464
1465 bool HTMLInputElement::isURLField() const
1466 {
1467     return m_inputType->isURLField();
1468 }
1469
1470 bool HTMLInputElement::isEnumeratable() const
1471 {
1472     return m_inputType->isEnumeratable();
1473 }
1474
1475 bool HTMLInputElement::isChecked() const
1476 {
1477     return checked() && m_inputType->isCheckable();
1478 }
1479
1480 bool HTMLInputElement::hasSpinButton() const
1481 {
1482     return m_inputType->hasSpinButton();
1483 }
1484
1485 bool HTMLInputElement::supportsPlaceholder() const
1486 {
1487     return isTextType();
1488 }
1489
1490 CheckedRadioButtons& HTMLInputElement::checkedRadioButtons() const
1491 {
1492     if (HTMLFormElement* formElement = form())
1493         return formElement->checkedRadioButtons();
1494     return document()->checkedRadioButtons();
1495 }
1496
1497 void HTMLInputElement::handleBeforeTextInsertedEvent(Event* event)
1498 {
1499     InputElement::handleBeforeTextInsertedEvent(m_data, this, this, event);
1500 }
1501
1502 } // namespace