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