Optimize strings copies in srcset parser
[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, 2013 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  * Copyright (C) 2012 Samsung Electronics. All rights reserved.
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Library General Public
14  * License as published by the Free Software Foundation; either
15  * version 2 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Library General Public License for more details.
21  *
22  * You should have received a copy of the GNU Library General Public License
23  * along with this library; see the file COPYING.LIB.  If not, write to
24  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25  * Boston, MA 02110-1301, USA.
26  *
27  */
28
29 #include "config.h"
30 #include "HTMLInputElement.h"
31
32 #include "AXObjectCache.h"
33 #include "BeforeTextInsertedEvent.h"
34 #include "CSSPropertyNames.h"
35 #include "DateTimeChooser.h"
36 #include "Document.h"
37 #include "Editor.h"
38 #include "EventNames.h"
39 #include "ExceptionCode.h"
40 #include "FeatureObserver.h"
41 #include "FileInputType.h"
42 #include "FileList.h"
43 #include "FormController.h"
44 #include "Frame.h"
45 #include "FrameSelection.h"
46 #include "FrameView.h"
47 #include "HTMLCollection.h"
48 #include "HTMLDataListElement.h"
49 #include "HTMLFormElement.h"
50 #include "HTMLImageLoader.h"
51 #include "HTMLNames.h"
52 #include "HTMLOptionElement.h"
53 #include "HTMLParserIdioms.h"
54 #include "IdTargetObserver.h"
55 #include "InputType.h"
56 #include "InsertionPoint.h"
57 #include "KeyboardEvent.h"
58 #include "Language.h"
59 #include "LocalizedStrings.h"
60 #include "MouseEvent.h"
61 #include "PlatformMouseEvent.h"
62 #include "RenderTextControlSingleLine.h"
63 #include "RenderTheme.h"
64 #include "RuntimeEnabledFeatures.h"
65 #include "ScopedEventQueue.h"
66 #include "SearchInputType.h"
67 #include "ShadowRoot.h"
68 #include "StyleResolver.h"
69 #include <wtf/MathExtras.h>
70 #include <wtf/Ref.h>
71
72 #if ENABLE(INPUT_TYPE_COLOR)
73 #include "ColorInputType.h"
74 #endif
75
76 #if ENABLE(INPUT_SPEECH)
77 #include "RuntimeEnabledFeatures.h"
78 #endif
79
80 #if ENABLE(TOUCH_EVENTS)
81 #include "TouchEvent.h"
82 #endif
83
84 using namespace std;
85
86 namespace WebCore {
87
88 using namespace HTMLNames;
89
90 #if ENABLE(DATALIST_ELEMENT)
91 class ListAttributeTargetObserver : IdTargetObserver {
92     WTF_MAKE_FAST_ALLOCATED;
93 public:
94     static OwnPtr<ListAttributeTargetObserver> create(const AtomicString& id, HTMLInputElement*);
95     virtual void idTargetChanged() OVERRIDE;
96
97 private:
98     ListAttributeTargetObserver(const AtomicString& id, HTMLInputElement*);
99
100     HTMLInputElement* m_element;
101 };
102 #endif
103
104 // FIXME: According to HTML4, the length attribute's value can be arbitrarily
105 // large. However, due to https://bugs.webkit.org/show_bug.cgi?id=14536 things
106 // get rather sluggish when a text field has a larger number of characters than
107 // this, even when just clicking in the text field.
108 const int HTMLInputElement::maximumLength = 524288;
109 const int defaultSize = 20;
110 const int maxSavedResults = 256;
111
112 HTMLInputElement::HTMLInputElement(const QualifiedName& tagName, Document& document, HTMLFormElement* form, bool createdByParser)
113     : HTMLTextFormControlElement(tagName, document, form)
114     , m_size(defaultSize)
115     , m_maxLength(maximumLength)
116     , m_maxResults(-1)
117     , m_isChecked(false)
118     , m_reflectsCheckedAttribute(true)
119     , m_isIndeterminate(false)
120     , m_hasType(false)
121     , m_isActivatedSubmit(false)
122     , m_autocomplete(Uninitialized)
123     , m_isAutofilled(false)
124 #if ENABLE(DATALIST_ELEMENT)
125     , m_hasNonEmptyList(false)
126 #endif
127     , m_stateRestored(false)
128     , m_parsingInProgress(createdByParser)
129     , m_valueAttributeWasUpdatedAfterParsing(false)
130     , m_wasModifiedByUser(false)
131     , m_canReceiveDroppedFiles(false)
132 #if ENABLE(TOUCH_EVENTS)
133     , m_hasTouchEventHandler(false)
134 #endif
135     , m_inputType(InputType::createText(*this))
136 {
137     ASSERT(hasTagName(inputTag) || hasTagName(isindexTag));
138     setHasCustomStyleResolveCallbacks();
139 }
140
141 PassRefPtr<HTMLInputElement> HTMLInputElement::create(const QualifiedName& tagName, Document& document, HTMLFormElement* form, bool createdByParser)
142 {
143     RefPtr<HTMLInputElement> inputElement = adoptRef(new HTMLInputElement(tagName, document, form, createdByParser));
144     inputElement->ensureUserAgentShadowRoot();
145     return inputElement.release();
146 }
147
148 HTMLImageLoader* HTMLInputElement::imageLoader()
149 {
150     if (!m_imageLoader)
151         m_imageLoader = adoptPtr(new HTMLImageLoader(this));
152     return m_imageLoader.get();
153 }
154
155 void HTMLInputElement::didAddUserAgentShadowRoot(ShadowRoot*)
156 {
157     m_inputType->createShadowSubtree();
158 }
159
160 HTMLInputElement::~HTMLInputElement()
161 {
162     if (needsSuspensionCallback())
163         document().unregisterForPageCacheSuspensionCallbacks(this);
164
165     // Need to remove form association while this is still an HTMLInputElement
166     // so that virtual functions are called correctly.
167     setForm(0);
168     // setForm(0) may register this to a document-level radio button group.
169     // We should unregister it to avoid accessing a deleted object.
170     if (isRadioButton())
171         document().formController().checkedRadioButtons().removeButton(this);
172 #if ENABLE(TOUCH_EVENTS)
173     if (m_hasTouchEventHandler)
174         document().didRemoveEventTargetNode(this);
175 #endif
176 }
177
178 const AtomicString& HTMLInputElement::name() const
179 {
180     return m_name.isNull() ? emptyAtom : m_name;
181 }
182
183 Vector<FileChooserFileInfo> HTMLInputElement::filesFromFileInputFormControlState(const FormControlState& state)
184 {
185     return FileInputType::filesFromFormControlState(state);
186 }
187
188 HTMLElement* HTMLInputElement::containerElement() const
189 {
190     return m_inputType->containerElement();
191 }
192
193 HTMLElement* HTMLInputElement::innerTextElement() const
194 {
195     return m_inputType->innerTextElement();
196 }
197
198 HTMLElement* HTMLInputElement::innerBlockElement() const
199 {
200     return m_inputType->innerBlockElement();
201 }
202
203 HTMLElement* HTMLInputElement::innerSpinButtonElement() const
204 {
205     return m_inputType->innerSpinButtonElement();
206 }
207
208 HTMLElement* HTMLInputElement::resultsButtonElement() const
209 {
210     return m_inputType->resultsButtonElement();
211 }
212
213 HTMLElement* HTMLInputElement::cancelButtonElement() const
214 {
215     return m_inputType->cancelButtonElement();
216 }
217
218 #if ENABLE(INPUT_SPEECH)
219 HTMLElement* HTMLInputElement::speechButtonElement() const
220 {
221     return m_inputType->speechButtonElement();
222 }
223 #endif
224
225 HTMLElement* HTMLInputElement::sliderThumbElement() const
226 {
227     return m_inputType->sliderThumbElement();
228 }
229
230 HTMLElement* HTMLInputElement::sliderTrackElement() const
231 {
232     return m_inputType->sliderTrackElement();
233 }
234
235 HTMLElement* HTMLInputElement::placeholderElement() const
236 {
237     return m_inputType->placeholderElement();
238 }
239
240 bool HTMLInputElement::shouldAutocomplete() const
241 {
242     if (m_autocomplete != Uninitialized)
243         return m_autocomplete == On;
244     return HTMLTextFormControlElement::shouldAutocomplete();
245 }
246
247 bool HTMLInputElement::isValidValue(const String& value) const
248 {
249     if (!m_inputType->canSetStringValue()) {
250         ASSERT_NOT_REACHED();
251         return false;
252     }
253     return !m_inputType->typeMismatchFor(value)
254         && !m_inputType->stepMismatch(value)
255         && !m_inputType->rangeUnderflow(value)
256         && !m_inputType->rangeOverflow(value)
257         && !tooLong(value, IgnoreDirtyFlag)
258         && !m_inputType->patternMismatch(value)
259         && !m_inputType->valueMissing(value);
260 }
261
262 bool HTMLInputElement::tooLong() const
263 {
264     return willValidate() && tooLong(value(), CheckDirtyFlag);
265 }
266
267 bool HTMLInputElement::typeMismatch() const
268 {
269     return willValidate() && m_inputType->typeMismatch();
270 }
271
272 bool HTMLInputElement::valueMissing() const
273 {
274     return willValidate() && m_inputType->valueMissing(value());
275 }
276
277 bool HTMLInputElement::hasBadInput() const
278 {
279     return willValidate() && m_inputType->hasBadInput();
280 }
281
282 bool HTMLInputElement::patternMismatch() const
283 {
284     return willValidate() && m_inputType->patternMismatch(value());
285 }
286
287 bool HTMLInputElement::tooLong(const String& value, NeedsToCheckDirtyFlag check) const
288 {
289     // We use isTextType() instead of supportsMaxLength() because of the
290     // 'virtual' overhead.
291     if (!isTextType())
292         return false;
293     int max = maxLength();
294     if (max < 0)
295         return false;
296     if (check == CheckDirtyFlag) {
297         // Return false for the default value or a value set by a script even if
298         // it is longer than maxLength.
299         if (!hasDirtyValue() || !m_wasModifiedByUser)
300             return false;
301     }
302     return numGraphemeClusters(value) > static_cast<unsigned>(max);
303 }
304
305 bool HTMLInputElement::rangeUnderflow() const
306 {
307     return willValidate() && m_inputType->rangeUnderflow(value());
308 }
309
310 bool HTMLInputElement::rangeOverflow() const
311 {
312     return willValidate() && m_inputType->rangeOverflow(value());
313 }
314
315 String HTMLInputElement::validationMessage() const
316 {
317     if (!willValidate())
318         return String();
319
320     if (customError())
321         return customValidationMessage();
322
323     return m_inputType->validationMessage();
324 }
325
326 double HTMLInputElement::minimum() const
327 {
328     return m_inputType->minimum();
329 }
330
331 double HTMLInputElement::maximum() const
332 {
333     return m_inputType->maximum();
334 }
335
336 bool HTMLInputElement::stepMismatch() const
337 {
338     return willValidate() && m_inputType->stepMismatch(value());
339 }
340
341 bool HTMLInputElement::getAllowedValueStep(Decimal* step) const
342 {
343     return m_inputType->getAllowedValueStep(step);
344 }
345
346 StepRange HTMLInputElement::createStepRange(AnyStepHandling anyStepHandling) const
347 {
348     return m_inputType->createStepRange(anyStepHandling);
349 }
350
351 #if ENABLE(DATALIST_ELEMENT)
352 Decimal HTMLInputElement::findClosestTickMarkValue(const Decimal& value)
353 {
354     return m_inputType->findClosestTickMarkValue(value);
355 }
356 #endif
357
358 void HTMLInputElement::stepUp(int n, ExceptionCode& ec)
359 {
360     m_inputType->stepUp(n, ec);
361 }
362
363 void HTMLInputElement::stepDown(int n, ExceptionCode& ec)
364 {
365     m_inputType->stepUp(-n, ec);
366 }
367
368 void HTMLInputElement::blur()
369 {
370     m_inputType->blur();
371 }
372
373 void HTMLInputElement::defaultBlur()
374 {
375     HTMLTextFormControlElement::blur();
376 }
377
378 bool HTMLInputElement::hasCustomFocusLogic() const
379 {
380     return m_inputType->hasCustomFocusLogic();
381 }
382
383 bool HTMLInputElement::isKeyboardFocusable(KeyboardEvent* event) const
384 {
385     return m_inputType->isKeyboardFocusable(event);
386 }
387
388 bool HTMLInputElement::isMouseFocusable() const
389 {
390     return m_inputType->isMouseFocusable();
391 }
392
393 bool HTMLInputElement::isTextFormControlFocusable() const
394 {
395     return HTMLTextFormControlElement::isFocusable();
396 }
397
398 bool HTMLInputElement::isTextFormControlKeyboardFocusable(KeyboardEvent* event) const
399 {
400     return HTMLTextFormControlElement::isKeyboardFocusable(event);
401 }
402
403 bool HTMLInputElement::isTextFormControlMouseFocusable() const
404 {
405     return HTMLTextFormControlElement::isMouseFocusable();
406 }
407
408 void HTMLInputElement::updateFocusAppearance(bool restorePreviousSelection)
409 {
410     if (isTextField()) {
411         if (!restorePreviousSelection || !hasCachedSelection())
412             select();
413         else
414             restoreCachedSelection();
415         if (document().frame())
416             document().frame()->selection().revealSelection();
417     } else
418         HTMLTextFormControlElement::updateFocusAppearance(restorePreviousSelection);
419 }
420
421 void HTMLInputElement::endEditing()
422 {
423     if (!isTextField())
424         return;
425
426     if (Frame* frame = document().frame())
427         frame->editor().textFieldDidEndEditing(this);
428 }
429
430 bool HTMLInputElement::shouldUseInputMethod()
431 {
432     return m_inputType->shouldUseInputMethod();
433 }
434
435 void HTMLInputElement::handleFocusEvent(Node* oldFocusedNode, FocusDirection direction)
436 {
437     m_inputType->handleFocusEvent(oldFocusedNode, direction);
438 }
439
440 void HTMLInputElement::handleBlurEvent()
441 {
442     m_inputType->handleBlurEvent();
443 }
444
445 void HTMLInputElement::setType(const String& type)
446 {
447     // FIXME: This should just call setAttribute. No reason to handle the empty string specially.
448     // We should write a test case to show that setting to the empty string does not remove the
449     // attribute in other browsers and then fix this. Note that setting to null *does* remove
450     // the attribute and setAttribute implements that.
451     if (type.isEmpty())
452         removeAttribute(typeAttr);
453     else
454         setAttribute(typeAttr, type);
455 }
456
457 void HTMLInputElement::updateType()
458 {
459     OwnPtr<InputType> newType = InputType::create(*this, fastGetAttribute(typeAttr));
460     bool hadType = m_hasType;
461     m_hasType = true;
462     if (m_inputType->formControlType() == newType->formControlType())
463         return;
464
465     if (hadType && !newType->canChangeFromAnotherType()) {
466         // Set the attribute back to the old value.
467         // Useful in case we were called from inside parseAttribute.
468         setAttribute(typeAttr, type());
469         return;
470     }
471
472     removeFromRadioButtonGroup();
473
474     bool didStoreValue = m_inputType->storesValueSeparateFromAttribute();
475     bool neededSuspensionCallback = needsSuspensionCallback();
476     bool didRespectHeightAndWidth = m_inputType->shouldRespectHeightAndWidthAttributes();
477
478     m_inputType->destroyShadowSubtree();
479
480     bool wasAttached = attached();
481     if (wasAttached)
482         Style::detachRenderTree(*this);
483
484     m_inputType = newType.release();
485     m_inputType->createShadowSubtree();
486
487 #if ENABLE(TOUCH_EVENTS)
488     bool hasTouchEventHandler = m_inputType->hasTouchEventHandler();
489     if (hasTouchEventHandler != m_hasTouchEventHandler) {
490         if (hasTouchEventHandler)
491             document().didAddTouchEventHandler(this);
492         else
493             document().didRemoveTouchEventHandler(this);
494         m_hasTouchEventHandler = hasTouchEventHandler;
495     }
496 #endif
497
498     setNeedsWillValidateCheck();
499
500     bool willStoreValue = m_inputType->storesValueSeparateFromAttribute();
501
502     if (didStoreValue && !willStoreValue && hasDirtyValue()) {
503         setAttribute(valueAttr, m_valueIfDirty);
504         m_valueIfDirty = String();
505     }
506     if (!didStoreValue && willStoreValue) {
507         AtomicString valueString = fastGetAttribute(valueAttr);
508         m_valueIfDirty = sanitizeValue(valueString);
509     } else
510         updateValueIfNeeded();
511
512     setFormControlValueMatchesRenderer(false);
513     m_inputType->updateInnerTextValue();
514
515     m_wasModifiedByUser = false;
516
517     if (neededSuspensionCallback)
518         unregisterForSuspensionCallbackIfNeeded();
519     else
520         registerForSuspensionCallbackIfNeeded();
521
522     if (didRespectHeightAndWidth != m_inputType->shouldRespectHeightAndWidthAttributes()) {
523         ASSERT(elementData());
524         if (const Attribute* height = findAttributeByName(heightAttr))
525             attributeChanged(heightAttr, height->value());
526         if (const Attribute* width = findAttributeByName(widthAttr))
527             attributeChanged(widthAttr, width->value());
528         if (const Attribute* align = findAttributeByName(alignAttr))
529             attributeChanged(alignAttr, align->value());
530     }
531
532     if (wasAttached) {
533         Style::attachRenderTree(*this);
534         if (document().focusedElement() == this)
535             updateFocusAppearance(true);
536     }
537
538     if (ShadowRoot* shadowRoot = shadowRootOfParentForDistribution(this))
539         shadowRoot->invalidateDistribution();
540
541     setChangedSinceLastFormControlChangeEvent(false);
542
543     addToRadioButtonGroup();
544
545     setNeedsValidityCheck();
546     notifyFormStateChanged();
547 }
548
549 void HTMLInputElement::subtreeHasChanged()
550 {
551     m_inputType->subtreeHasChanged();
552     // When typing in an input field, childrenChanged is not called, so we need to force the directionality check.
553     calculateAndAdjustDirectionality();
554 }
555
556 const AtomicString& HTMLInputElement::formControlType() const
557 {
558     return m_inputType->formControlType();
559 }
560
561 bool HTMLInputElement::shouldSaveAndRestoreFormControlState() const
562 {
563     if (!m_inputType->shouldSaveAndRestoreFormControlState())
564         return false;
565     return HTMLTextFormControlElement::shouldSaveAndRestoreFormControlState();
566 }
567
568 FormControlState HTMLInputElement::saveFormControlState() const
569 {
570     return m_inputType->saveFormControlState();
571 }
572
573 void HTMLInputElement::restoreFormControlState(const FormControlState& state)
574 {
575     m_inputType->restoreFormControlState(state);
576     m_stateRestored = true;
577 }
578
579 bool HTMLInputElement::canStartSelection() const
580 {
581     if (!isTextField())
582         return false;
583     return HTMLTextFormControlElement::canStartSelection();
584 }
585
586 bool HTMLInputElement::canHaveSelection() const
587 {
588     return isTextField();
589 }
590
591 void HTMLInputElement::accessKeyAction(bool sendMouseEvents)
592 {
593     m_inputType->accessKeyAction(sendMouseEvents);
594 }
595
596 bool HTMLInputElement::isPresentationAttribute(const QualifiedName& name) const
597 {
598     if (name == vspaceAttr || name == hspaceAttr || name == alignAttr || name == widthAttr || name == heightAttr || (name == borderAttr && isImageButton()))
599         return true;
600     return HTMLTextFormControlElement::isPresentationAttribute(name);
601 }
602
603 void HTMLInputElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style)
604 {
605     if (name == vspaceAttr) {
606         addHTMLLengthToStyle(style, CSSPropertyMarginTop, value);
607         addHTMLLengthToStyle(style, CSSPropertyMarginBottom, value);
608     } else if (name == hspaceAttr) {
609         addHTMLLengthToStyle(style, CSSPropertyMarginLeft, value);
610         addHTMLLengthToStyle(style, CSSPropertyMarginRight, value);
611     } else if (name == alignAttr) {
612         if (m_inputType->shouldRespectAlignAttribute())
613             applyAlignmentAttributeToStyle(value, style);
614     } else if (name == widthAttr) {
615         if (m_inputType->shouldRespectHeightAndWidthAttributes())
616             addHTMLLengthToStyle(style, CSSPropertyWidth, value);
617     } else if (name == heightAttr) {
618         if (m_inputType->shouldRespectHeightAndWidthAttributes())
619             addHTMLLengthToStyle(style, CSSPropertyHeight, value);
620     } else if (name == borderAttr && isImageButton())
621         applyBorderAttributeToStyle(value, style);
622     else
623         HTMLTextFormControlElement::collectStyleForPresentationAttribute(name, value, style);
624 }
625
626 void HTMLInputElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
627 {
628     if (name == nameAttr) {
629         removeFromRadioButtonGroup();
630         m_name = value;
631         addToRadioButtonGroup();
632         HTMLTextFormControlElement::parseAttribute(name, value);
633     } else if (name == autocompleteAttr) {
634         if (equalIgnoringCase(value, "off")) {
635             m_autocomplete = Off;
636             registerForSuspensionCallbackIfNeeded();
637         } else {
638             bool needsToUnregister = m_autocomplete == Off;
639
640             if (value.isEmpty())
641                 m_autocomplete = Uninitialized;
642             else
643                 m_autocomplete = On;
644
645             if (needsToUnregister)
646                 unregisterForSuspensionCallbackIfNeeded();
647         }
648     } else if (name == typeAttr)
649         updateType();
650     else if (name == valueAttr) {
651         // Changes to the value attribute may change whether or not this element has a default value.
652         // If this field is autocomplete=off that might affect the return value of needsSuspensionCallback.
653         if (m_autocomplete == Off) {
654             unregisterForSuspensionCallbackIfNeeded();
655             registerForSuspensionCallbackIfNeeded();
656         }
657         // We only need to setChanged if the form is looking at the default value right now.
658         if (!hasDirtyValue()) {
659             updatePlaceholderVisibility(false);
660             setNeedsStyleRecalc();
661         }
662         setFormControlValueMatchesRenderer(false);
663         setNeedsValidityCheck();
664         m_valueAttributeWasUpdatedAfterParsing = !m_parsingInProgress;
665         m_inputType->valueAttributeChanged();
666     } else if (name == checkedAttr) {
667         // Another radio button in the same group might be checked by state
668         // restore. We shouldn't call setChecked() even if this has the checked
669         // attribute. So, delay the setChecked() call until
670         // finishParsingChildren() is called if parsing is in progress.
671         if (!m_parsingInProgress && m_reflectsCheckedAttribute) {
672             setChecked(!value.isNull());
673             m_reflectsCheckedAttribute = true;
674         }
675     } else if (name == maxlengthAttr)
676         parseMaxLengthAttribute(value);
677     else if (name == sizeAttr) {
678         int oldSize = m_size;
679         int valueAsInteger = value.toInt();
680         m_size = valueAsInteger > 0 ? valueAsInteger : defaultSize;
681         if (m_size != oldSize && renderer())
682             renderer()->setNeedsLayoutAndPrefWidthsRecalc();
683     } else if (name == altAttr)
684         m_inputType->altAttributeChanged();
685     else if (name == srcAttr)
686         m_inputType->srcAttributeChanged();
687     else if (name == usemapAttr || name == accesskeyAttr) {
688         // FIXME: ignore for the moment
689     } else if (name == onsearchAttr) {
690         // Search field and slider attributes all just cause updateFromElement to be called through style recalcing.
691         setAttributeEventListener(eventNames().searchEvent, name, value);
692     } else if (name == resultsAttr) {
693         int oldResults = m_maxResults;
694         m_maxResults = !value.isNull() ? std::min(value.toInt(), maxSavedResults) : -1;
695         // FIXME: Detaching just for maxResults change is not ideal.  We should figure out the right
696         // time to relayout for this change.
697         if (m_maxResults != oldResults && (m_maxResults <= 0 || oldResults <= 0) && attached())
698             Style::reattachRenderTree(*this);
699         setNeedsStyleRecalc();
700         FeatureObserver::observe(&document(), FeatureObserver::ResultsAttribute);
701     } else if (name == autosaveAttr) {
702         setNeedsStyleRecalc();
703         FeatureObserver::observe(&document(), FeatureObserver::AutoSaveAttribute);
704     } else if (name == incrementalAttr) {
705         setNeedsStyleRecalc();
706         FeatureObserver::observe(&document(), FeatureObserver::IncrementalAttribute);
707     } else if (name == minAttr) {
708         m_inputType->minOrMaxAttributeChanged();
709         setNeedsValidityCheck();
710         FeatureObserver::observe(&document(), FeatureObserver::MinAttribute);
711     } else if (name == maxAttr) {
712         m_inputType->minOrMaxAttributeChanged();
713         setNeedsValidityCheck();
714         FeatureObserver::observe(&document(), FeatureObserver::MaxAttribute);
715     } else if (name == multipleAttr) {
716         m_inputType->multipleAttributeChanged();
717         setNeedsValidityCheck();
718     } else if (name == stepAttr) {
719         m_inputType->stepAttributeChanged();
720         setNeedsValidityCheck();
721         FeatureObserver::observe(&document(), FeatureObserver::StepAttribute);
722     } else if (name == patternAttr) {
723         setNeedsValidityCheck();
724         FeatureObserver::observe(&document(), FeatureObserver::PatternAttribute);
725     } else if (name == precisionAttr) {
726         setNeedsValidityCheck();
727         FeatureObserver::observe(&document(), FeatureObserver::PrecisionAttribute);
728     } else if (name == disabledAttr) {
729         HTMLTextFormControlElement::parseAttribute(name, value);
730         m_inputType->disabledAttributeChanged();
731     } else if (name == readonlyAttr) {
732         HTMLTextFormControlElement::parseAttribute(name, value);
733         m_inputType->readonlyAttributeChanged();
734     }
735 #if ENABLE(DATALIST_ELEMENT)
736     else if (name == listAttr) {
737         m_hasNonEmptyList = !value.isEmpty();
738         if (m_hasNonEmptyList) {
739             resetListAttributeTargetObserver();
740             listAttributeTargetChanged();
741         }
742         FeatureObserver::observe(&document(), FeatureObserver::ListAttribute);
743     }
744 #endif
745 #if ENABLE(INPUT_SPEECH)
746     else if (name == webkitspeechAttr) {
747         if (renderer()) {
748             // This renderer and its children have quite different layouts and styles depending on
749             // whether the speech button is visible or not. So we reset the whole thing and recreate
750             // to get the right styles and layout.
751             Style::detachRenderTree(*this);
752             m_inputType->destroyShadowSubtree();
753             m_inputType->createShadowSubtree();
754             if (!attached())
755                 Style::attachRenderTree(*this);
756         } else {
757             m_inputType->destroyShadowSubtree();
758             m_inputType->createShadowSubtree();
759         }
760         setFormControlValueMatchesRenderer(false);
761         setNeedsStyleRecalc();
762         FeatureObserver::observe(&document(), FeatureObserver::PrefixedSpeechAttribute);
763     } else if (name == onwebkitspeechchangeAttr)
764         setAttributeEventListener(eventNames().webkitspeechchangeEvent, name, value);
765 #endif
766 #if ENABLE(DIRECTORY_UPLOAD)
767     else if (name == webkitdirectoryAttr) {
768         HTMLTextFormControlElement::parseAttribute(name, value);
769         FeatureObserver::observe(&document(), FeatureObserver::PrefixedDirectoryAttribute);
770     }
771 #endif
772     else
773         HTMLTextFormControlElement::parseAttribute(name, value);
774     m_inputType->attributeChanged();
775 }
776
777 void HTMLInputElement::finishParsingChildren()
778 {
779     m_parsingInProgress = false;
780     HTMLTextFormControlElement::finishParsingChildren();
781     if (!m_stateRestored) {
782         bool checked = hasAttribute(checkedAttr);
783         if (checked)
784             setChecked(checked);
785         m_reflectsCheckedAttribute = true;
786     }
787 }
788
789 bool HTMLInputElement::rendererIsNeeded(const RenderStyle& style)
790 {
791     return m_inputType->rendererIsNeeded() && HTMLTextFormControlElement::rendererIsNeeded(style);
792 }
793
794 RenderElement* HTMLInputElement::createRenderer(RenderArena& arena, RenderStyle& style)
795 {
796     return m_inputType->createRenderer(arena, style);
797 }
798
799 void HTMLInputElement::willAttachRenderers()
800 {
801     if (!m_hasType)
802         updateType();
803 }
804
805 void HTMLInputElement::didAttachRenderers()
806 {
807     HTMLTextFormControlElement::didAttachRenderers();
808
809     m_inputType->attach();
810
811     if (document().focusedElement() == this)
812         document().updateFocusAppearanceSoon(true /* restore selection */);
813 }
814
815 void HTMLInputElement::didDetachRenderers()
816 {
817     setFormControlValueMatchesRenderer(false);
818     m_inputType->detach();
819 }
820
821 String HTMLInputElement::altText() const
822 {
823     // http://www.w3.org/TR/1998/REC-html40-19980424/appendix/notes.html#altgen
824     // also heavily discussed by Hixie on bugzilla
825     // note this is intentionally different to HTMLImageElement::altText()
826     String alt = fastGetAttribute(altAttr);
827     // fall back to title attribute
828     if (alt.isNull())
829         alt = getAttribute(titleAttr);
830     if (alt.isNull())
831         alt = getAttribute(valueAttr);
832     if (alt.isEmpty())
833         alt = inputElementAltText();
834     return alt;
835 }
836
837 bool HTMLInputElement::isSuccessfulSubmitButton() const
838 {
839     // HTML spec says that buttons must have names to be considered successful.
840     // However, other browsers do not impose this constraint. So we do not.
841     return !isDisabledFormControl() && m_inputType->canBeSuccessfulSubmitButton();
842 }
843
844 bool HTMLInputElement::isActivatedSubmit() const
845 {
846     return m_isActivatedSubmit;
847 }
848
849 void HTMLInputElement::setActivatedSubmit(bool flag)
850 {
851     m_isActivatedSubmit = flag;
852 }
853
854 bool HTMLInputElement::appendFormData(FormDataList& encoding, bool multipart)
855 {
856     return m_inputType->isFormDataAppendable() && m_inputType->appendFormData(encoding, multipart);
857 }
858
859 void HTMLInputElement::reset()
860 {
861     if (m_inputType->storesValueSeparateFromAttribute())
862         setValue(String());
863
864     setAutofilled(false);
865     setChecked(hasAttribute(checkedAttr));
866     m_reflectsCheckedAttribute = true;
867 }
868
869 bool HTMLInputElement::isTextField() const
870 {
871     return m_inputType->isTextField();
872 }
873
874 bool HTMLInputElement::isTextType() const
875 {
876     return m_inputType->isTextType();
877 }
878
879 void HTMLInputElement::setChecked(bool nowChecked, TextFieldEventBehavior eventBehavior)
880 {
881     if (checked() == nowChecked)
882         return;
883
884     m_reflectsCheckedAttribute = false;
885     m_isChecked = nowChecked;
886     setNeedsStyleRecalc();
887
888     if (CheckedRadioButtons* buttons = checkedRadioButtons())
889             buttons->updateCheckedState(this);
890     if (renderer() && renderer()->style()->hasAppearance())
891         renderer()->theme()->stateChanged(renderer(), CheckedState);
892     setNeedsValidityCheck();
893
894     // Ideally we'd do this from the render tree (matching
895     // RenderTextView), but it's not possible to do it at the moment
896     // because of the way the code is structured.
897     if (renderer()) {
898         if (AXObjectCache* cache = renderer()->document().existingAXObjectCache())
899             cache->checkedStateChanged(this);
900     }
901
902     // Only send a change event for items in the document (avoid firing during
903     // parsing) and don't send a change event for a radio button that's getting
904     // unchecked to match other browsers. DOM is not a useful standard for this
905     // because it says only to fire change events at "lose focus" time, which is
906     // definitely wrong in practice for these types of elements.
907     if (eventBehavior != DispatchNoEvent && inDocument() && m_inputType->shouldSendChangeEventAfterCheckedChanged()) {
908         setTextAsOfLastFormControlChangeEvent(String());
909         dispatchFormControlChangeEvent();
910     }
911
912     didAffectSelector(AffectedSelectorChecked);
913 }
914
915 void HTMLInputElement::setIndeterminate(bool newValue)
916 {
917     if (indeterminate() == newValue)
918         return;
919
920     m_isIndeterminate = newValue;
921
922     didAffectSelector(AffectedSelectorIndeterminate);
923
924     if (renderer() && renderer()->style()->hasAppearance())
925         renderer()->theme()->stateChanged(renderer(), CheckedState);
926 }
927
928 int HTMLInputElement::size() const
929 {
930     return m_size;
931 }
932
933 bool HTMLInputElement::sizeShouldIncludeDecoration(int& preferredSize) const
934 {
935     return m_inputType->sizeShouldIncludeDecoration(defaultSize, preferredSize);
936 }
937
938 float HTMLInputElement::decorationWidth() const
939 {
940     return m_inputType->decorationWidth();
941 }
942
943 void HTMLInputElement::copyNonAttributePropertiesFromElement(const Element& source)
944 {
945     const HTMLInputElement& sourceElement = static_cast<const HTMLInputElement&>(source);
946
947     m_valueIfDirty = sourceElement.m_valueIfDirty;
948     m_wasModifiedByUser = false;
949     setChecked(sourceElement.m_isChecked);
950     m_reflectsCheckedAttribute = sourceElement.m_reflectsCheckedAttribute;
951     m_isIndeterminate = sourceElement.m_isIndeterminate;
952
953     HTMLTextFormControlElement::copyNonAttributePropertiesFromElement(source);
954
955     setFormControlValueMatchesRenderer(false);
956     m_inputType->updateInnerTextValue();
957 }
958
959 String HTMLInputElement::value() const
960 {
961     String value;
962     if (m_inputType->getTypeSpecificValue(value))
963         return value;
964
965     value = m_valueIfDirty;
966     if (!value.isNull())
967         return value;
968
969     AtomicString valueString = fastGetAttribute(valueAttr);
970     value = sanitizeValue(valueString);
971     if (!value.isNull())
972         return value;
973
974     return m_inputType->fallbackValue();
975 }
976
977 String HTMLInputElement::valueWithDefault() const
978 {
979     String value = this->value();
980     if (!value.isNull())
981         return value;
982
983     return m_inputType->defaultValue();
984 }
985
986 void HTMLInputElement::setValueForUser(const String& value)
987 {
988     // Call setValue and make it send a change event.
989     setValue(value, DispatchChangeEvent);
990 }
991
992 const String& HTMLInputElement::suggestedValue() const
993 {
994     return m_suggestedValue;
995 }
996
997 void HTMLInputElement::setSuggestedValue(const String& value)
998 {
999     if (!m_inputType->canSetSuggestedValue())
1000         return;
1001     setFormControlValueMatchesRenderer(false);
1002     m_suggestedValue = sanitizeValue(value);
1003     setNeedsStyleRecalc();
1004     m_inputType->updateInnerTextValue();
1005 }
1006
1007 void HTMLInputElement::setEditingValue(const String& value)
1008 {
1009     if (!renderer() || !isTextField())
1010         return;
1011     setInnerTextValue(value);
1012     subtreeHasChanged();
1013
1014     unsigned max = value.length();
1015     if (focused())
1016         setSelectionRange(max, max);
1017     else
1018         cacheSelectionInResponseToSetValue(max);
1019
1020     dispatchInputEvent();
1021 }
1022
1023 void HTMLInputElement::setValue(const String& value, ExceptionCode& ec, TextFieldEventBehavior eventBehavior)
1024 {
1025     if (isFileUpload() && !value.isEmpty()) {
1026         ec = INVALID_STATE_ERR;
1027         return;
1028     }
1029     setValue(value, eventBehavior);
1030 }
1031
1032 void HTMLInputElement::setValue(const String& value, TextFieldEventBehavior eventBehavior)
1033 {
1034     if (!m_inputType->canSetValue(value))
1035         return;
1036
1037     Ref<HTMLInputElement> protect(*this);
1038     EventQueueScope scope;
1039     String sanitizedValue = sanitizeValue(value);
1040     bool valueChanged = sanitizedValue != this->value();
1041
1042     setLastChangeWasNotUserEdit();
1043     setFormControlValueMatchesRenderer(false);
1044     m_suggestedValue = String(); // Prevent TextFieldInputType::setValue from using the suggested value.
1045     m_inputType->setValue(sanitizedValue, valueChanged, eventBehavior);
1046
1047     if (!valueChanged)
1048         return;
1049
1050     notifyFormStateChanged();
1051 }
1052
1053 void HTMLInputElement::setValueInternal(const String& sanitizedValue, TextFieldEventBehavior eventBehavior)
1054 {
1055     m_valueIfDirty = sanitizedValue;
1056     m_wasModifiedByUser = eventBehavior != DispatchNoEvent;
1057     setNeedsValidityCheck();
1058 }
1059
1060 double HTMLInputElement::valueAsDate() const
1061 {
1062     return m_inputType->valueAsDate();
1063 }
1064
1065 void HTMLInputElement::setValueAsDate(double value, ExceptionCode& ec)
1066 {
1067     m_inputType->setValueAsDate(value, ec);
1068 }
1069
1070 double HTMLInputElement::valueAsNumber() const
1071 {
1072     return m_inputType->valueAsDouble();
1073 }
1074
1075 void HTMLInputElement::setValueAsNumber(double newValue, ExceptionCode& ec, TextFieldEventBehavior eventBehavior)
1076 {
1077     if (!std::isfinite(newValue)) {
1078         ec = NOT_SUPPORTED_ERR;
1079         return;
1080     }
1081     m_inputType->setValueAsDouble(newValue, eventBehavior, ec);
1082 }
1083
1084 void HTMLInputElement::setValueFromRenderer(const String& value)
1085 {
1086     // File upload controls will never use this.
1087     ASSERT(!isFileUpload());
1088
1089     m_suggestedValue = String();
1090
1091     // Renderer and our event handler are responsible for sanitizing values.
1092     ASSERT(value == sanitizeValue(value) || sanitizeValue(value).isEmpty());
1093
1094     // Workaround for bug where trailing \n is included in the result of textContent.
1095     // The assert macro above may also be simplified to: value == constrainValue(value)
1096     // http://bugs.webkit.org/show_bug.cgi?id=9661
1097     m_valueIfDirty = value == "\n" ? emptyString() : value;
1098
1099     setFormControlValueMatchesRenderer(true);
1100     m_wasModifiedByUser = true;
1101
1102     // Input event is fired by the Node::defaultEventHandler for editable controls.
1103     if (!isTextField())
1104         dispatchInputEvent();
1105     notifyFormStateChanged();
1106
1107     setNeedsValidityCheck();
1108
1109     // Clear autofill flag (and yellow background) on user edit.
1110     setAutofilled(false);
1111 }
1112
1113 void HTMLInputElement::willDispatchEvent(Event& event, InputElementClickState& state)
1114 {
1115     if (event.type() == eventNames().textInputEvent && m_inputType->shouldSubmitImplicitly(&event))
1116         event.stopPropagation();
1117     if (event.type() == eventNames().clickEvent && event.isMouseEvent() && toMouseEvent(&event)->button() == LeftButton) {
1118         m_inputType->willDispatchClick(state);
1119         state.stateful = true;
1120     }
1121 }
1122
1123 void HTMLInputElement::didDispatchClickEvent(Event& event, const InputElementClickState& state)
1124 {
1125     m_inputType->didDispatchClick(&event, state);
1126 }
1127
1128 void HTMLInputElement::defaultEventHandler(Event* evt)
1129 {
1130     if (evt->isMouseEvent() && evt->type() == eventNames().clickEvent && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
1131         m_inputType->handleClickEvent(static_cast<MouseEvent*>(evt));
1132         if (evt->defaultHandled())
1133             return;
1134     }
1135
1136 #if ENABLE(TOUCH_EVENTS)
1137     if (evt->isTouchEvent()) {
1138         m_inputType->handleTouchEvent(static_cast<TouchEvent*>(evt));
1139         if (evt->defaultHandled())
1140             return;
1141     }
1142 #endif
1143
1144     if (evt->isKeyboardEvent() && evt->type() == eventNames().keydownEvent) {
1145         m_inputType->handleKeydownEvent(static_cast<KeyboardEvent*>(evt));
1146         if (evt->defaultHandled())
1147             return;
1148     }
1149
1150     // Call the base event handler before any of our own event handling for almost all events in text fields.
1151     // Makes editing keyboard handling take precedence over the keydown and keypress handling in this function.
1152     bool callBaseClassEarly = isTextField() && (evt->type() == eventNames().keydownEvent || evt->type() == eventNames().keypressEvent);
1153     if (callBaseClassEarly) {
1154         HTMLTextFormControlElement::defaultEventHandler(evt);
1155         if (evt->defaultHandled())
1156             return;
1157     }
1158
1159     // DOMActivate events cause the input to be "activated" - in the case of image and submit inputs, this means
1160     // actually submitting the form. For reset inputs, the form is reset. These events are sent when the user clicks
1161     // on the element, or presses enter while it is the active element. JavaScript code wishing to activate the element
1162     // must dispatch a DOMActivate event - a click event will not do the job.
1163     if (evt->type() == eventNames().DOMActivateEvent) {
1164         m_inputType->handleDOMActivateEvent(evt);
1165         if (evt->defaultHandled())
1166             return;
1167     }
1168
1169     // Use key press event here since sending simulated mouse events
1170     // on key down blocks the proper sending of the key press event.
1171     if (evt->isKeyboardEvent() && evt->type() == eventNames().keypressEvent) {
1172         m_inputType->handleKeypressEvent(static_cast<KeyboardEvent*>(evt));
1173         if (evt->defaultHandled())
1174             return;
1175     }
1176
1177     if (evt->isKeyboardEvent() && evt->type() == eventNames().keyupEvent) {
1178         m_inputType->handleKeyupEvent(static_cast<KeyboardEvent*>(evt));
1179         if (evt->defaultHandled())
1180             return;
1181     }
1182
1183     if (m_inputType->shouldSubmitImplicitly(evt)) {
1184         if (isSearchField()) {
1185             addSearchResult();
1186             onSearch();
1187         }
1188         // Form submission finishes editing, just as loss of focus does.
1189         // If there was a change, send the event now.
1190         if (wasChangedSinceLastFormControlChangeEvent())
1191             dispatchFormControlChangeEvent();
1192
1193         RefPtr<HTMLFormElement> formForSubmission = m_inputType->formForSubmission();
1194         // Form may never have been present, or may have been destroyed by code responding to the change event.
1195         if (formForSubmission)
1196             formForSubmission->submitImplicitly(evt, canTriggerImplicitSubmission());
1197
1198         evt->setDefaultHandled();
1199         return;
1200     }
1201
1202     if (evt->isBeforeTextInsertedEvent())
1203         m_inputType->handleBeforeTextInsertedEvent(static_cast<BeforeTextInsertedEvent*>(evt));
1204
1205     if (evt->isMouseEvent() && evt->type() == eventNames().mousedownEvent) {
1206         m_inputType->handleMouseDownEvent(static_cast<MouseEvent*>(evt));
1207         if (evt->defaultHandled())
1208             return;
1209     }
1210
1211     m_inputType->forwardEvent(evt);
1212
1213     if (!callBaseClassEarly && !evt->defaultHandled())
1214         HTMLTextFormControlElement::defaultEventHandler(evt);
1215 }
1216
1217 bool HTMLInputElement::willRespondToMouseClickEvents()
1218 {
1219     // FIXME: Consider implementing willRespondToMouseClickEvents() in InputType if more accurate results are necessary.
1220     if (!isDisabledFormControl())
1221         return true;
1222
1223     return HTMLTextFormControlElement::willRespondToMouseClickEvents();
1224 }
1225
1226 bool HTMLInputElement::isURLAttribute(const Attribute& attribute) const
1227 {
1228     return attribute.name() == srcAttr || attribute.name() == formactionAttr || HTMLTextFormControlElement::isURLAttribute(attribute);
1229 }
1230
1231 String HTMLInputElement::defaultValue() const
1232 {
1233     return fastGetAttribute(valueAttr);
1234 }
1235
1236 void HTMLInputElement::setDefaultValue(const String &value)
1237 {
1238     setAttribute(valueAttr, value);
1239 }
1240
1241 static inline bool isRFC2616TokenCharacter(UChar ch)
1242 {
1243     return isASCII(ch) && ch > ' ' && ch != '"' && ch != '(' && ch != ')' && ch != ',' && ch != '/' && (ch < ':' || ch > '@') && (ch < '[' || ch > ']') && ch != '{' && ch != '}' && ch != 0x7f;
1244 }
1245
1246 static bool isValidMIMEType(const String& type)
1247 {
1248     size_t slashPosition = type.find('/');
1249     if (slashPosition == notFound || !slashPosition || slashPosition == type.length() - 1)
1250         return false;
1251     for (size_t i = 0; i < type.length(); ++i) {
1252         if (!isRFC2616TokenCharacter(type[i]) && i != slashPosition)
1253             return false;
1254     }
1255     return true;
1256 }
1257
1258 static bool isValidFileExtension(const String& type)
1259 {
1260     if (type.length() < 2)
1261         return false;
1262     return type[0] == '.';
1263 }
1264
1265 static Vector<String> parseAcceptAttribute(const String& acceptString, bool (*predicate)(const String&))
1266 {
1267     Vector<String> types;
1268     if (acceptString.isEmpty())
1269         return types;
1270
1271     Vector<String> splitTypes;
1272     acceptString.split(',', false, splitTypes);
1273     for (size_t i = 0; i < splitTypes.size(); ++i) {
1274         String trimmedType = stripLeadingAndTrailingHTMLSpaces(splitTypes[i]);
1275         if (trimmedType.isEmpty())
1276             continue;
1277         if (!predicate(trimmedType))
1278             continue;
1279         types.append(trimmedType.lower());
1280     }
1281
1282     return types;
1283 }
1284
1285 Vector<String> HTMLInputElement::acceptMIMETypes()
1286 {
1287     return parseAcceptAttribute(fastGetAttribute(acceptAttr), isValidMIMEType);
1288 }
1289
1290 Vector<String> HTMLInputElement::acceptFileExtensions()
1291 {
1292     return parseAcceptAttribute(fastGetAttribute(acceptAttr), isValidFileExtension);
1293 }
1294
1295 String HTMLInputElement::accept() const
1296 {
1297     return fastGetAttribute(acceptAttr);
1298 }
1299
1300 String HTMLInputElement::alt() const
1301 {
1302     return fastGetAttribute(altAttr);
1303 }
1304
1305 int HTMLInputElement::maxLength() const
1306 {
1307     return m_maxLength;
1308 }
1309
1310 void HTMLInputElement::setMaxLength(int maxLength, ExceptionCode& ec)
1311 {
1312     if (maxLength < 0)
1313         ec = INDEX_SIZE_ERR;
1314     else
1315         setAttribute(maxlengthAttr, String::number(maxLength));
1316 }
1317
1318 bool HTMLInputElement::multiple() const
1319 {
1320     return fastHasAttribute(multipleAttr);
1321 }
1322
1323 void HTMLInputElement::setSize(unsigned size)
1324 {
1325     setAttribute(sizeAttr, String::number(size));
1326 }
1327
1328 void HTMLInputElement::setSize(unsigned size, ExceptionCode& ec)
1329 {
1330     if (!size)
1331         ec = INDEX_SIZE_ERR;
1332     else
1333         setSize(size);
1334 }
1335
1336 URL HTMLInputElement::src() const
1337 {
1338     return document().completeURL(fastGetAttribute(srcAttr));
1339 }
1340
1341 void HTMLInputElement::setAutofilled(bool autofilled)
1342 {
1343     if (autofilled == m_isAutofilled)
1344         return;
1345
1346     m_isAutofilled = autofilled;
1347     setNeedsStyleRecalc();
1348 }
1349
1350 FileList* HTMLInputElement::files()
1351 {
1352     return m_inputType->files();
1353 }
1354
1355 void HTMLInputElement::setFiles(PassRefPtr<FileList> files)
1356 {
1357     m_inputType->setFiles(files);
1358 }
1359
1360 bool HTMLInputElement::receiveDroppedFiles(const DragData* dragData)
1361 {
1362     return m_inputType->receiveDroppedFiles(dragData);
1363 }
1364
1365 Icon* HTMLInputElement::icon() const
1366 {
1367     return m_inputType->icon();
1368 }
1369
1370 bool HTMLInputElement::canReceiveDroppedFiles() const
1371 {
1372     return m_canReceiveDroppedFiles;
1373 }
1374
1375 void HTMLInputElement::setCanReceiveDroppedFiles(bool canReceiveDroppedFiles)
1376 {
1377     if (m_canReceiveDroppedFiles == canReceiveDroppedFiles)
1378         return;
1379     m_canReceiveDroppedFiles = canReceiveDroppedFiles;
1380     if (renderer())
1381         renderer()->updateFromElement();
1382 }
1383
1384 String HTMLInputElement::visibleValue() const
1385 {
1386     return m_inputType->visibleValue();
1387 }
1388
1389 String HTMLInputElement::sanitizeValue(const String& proposedValue) const
1390 {
1391     if (proposedValue.isNull())
1392         return proposedValue;
1393     return m_inputType->sanitizeValue(proposedValue);
1394 }
1395
1396 String HTMLInputElement::localizeValue(const String& proposedValue) const
1397 {
1398     if (proposedValue.isNull())
1399         return proposedValue;
1400     return m_inputType->localizeValue(proposedValue);
1401 }
1402
1403 bool HTMLInputElement::isInRange() const
1404 {
1405     return m_inputType->isInRange(value());
1406 }
1407
1408 bool HTMLInputElement::isOutOfRange() const
1409 {
1410     return m_inputType->isOutOfRange(value());
1411 }
1412
1413 bool HTMLInputElement::needsSuspensionCallback()
1414 {
1415     if (m_inputType->shouldResetOnDocumentActivation())
1416         return true;
1417
1418     // Sensitive input elements are marked with autocomplete=off, and we want to wipe them out
1419     // when going back; returning true here arranges for us to call reset at the time
1420     // the page is restored. Non-empty textual default values indicate that the field
1421     // is not really sensitive -- there's no default value for an account number --
1422     // and we would see unexpected results if we reset to something other than blank.
1423     bool isSensitive = m_autocomplete == Off && !(m_inputType->isTextType() && !defaultValue().isEmpty());
1424
1425     return isSensitive;
1426 }
1427
1428 void HTMLInputElement::registerForSuspensionCallbackIfNeeded()
1429 {
1430     if (needsSuspensionCallback())
1431         document().registerForPageCacheSuspensionCallbacks(this);
1432 }
1433
1434 void HTMLInputElement::unregisterForSuspensionCallbackIfNeeded()
1435 {
1436     if (!needsSuspensionCallback())
1437         document().unregisterForPageCacheSuspensionCallbacks(this);
1438 }
1439
1440 bool HTMLInputElement::isRequiredFormControl() const
1441 {
1442     return m_inputType->supportsRequired() && isRequired();
1443 }
1444
1445 bool HTMLInputElement::matchesReadOnlyPseudoClass() const
1446 {
1447     return m_inputType->supportsReadOnly() && isReadOnly();
1448 }
1449
1450 bool HTMLInputElement::matchesReadWritePseudoClass() const
1451 {
1452     return m_inputType->supportsReadOnly() && !isDisabledOrReadOnly();
1453 }
1454
1455 void HTMLInputElement::addSearchResult()
1456 {
1457     m_inputType->addSearchResult();
1458 }
1459
1460 void HTMLInputElement::onSearch()
1461 {
1462     ASSERT(isSearchField());
1463     if (m_inputType)
1464         static_cast<SearchInputType*>(m_inputType.get())->stopSearchEventTimer();
1465     dispatchEvent(Event::create(eventNames().searchEvent, true, false));
1466 }
1467
1468 void HTMLInputElement::updateClearButtonVisibility()
1469 {
1470     m_inputType->updateClearButtonVisibility();
1471 }
1472
1473 void HTMLInputElement::documentDidResumeFromPageCache()
1474 {
1475     ASSERT(needsSuspensionCallback());
1476
1477 #if ENABLE(INPUT_TYPE_COLOR)
1478     // <input type=color> uses documentWillSuspendForPageCache to detach the color picker UI,
1479     // so it should not be reset when being loaded from page cache.
1480     if (isColorControl()) 
1481         return;
1482 #endif // ENABLE(INPUT_TYPE_COLOR)
1483     reset();
1484 }
1485
1486 #if ENABLE(INPUT_TYPE_COLOR)
1487 void HTMLInputElement::documentWillSuspendForPageCache()
1488 {
1489     if (!isColorControl())
1490         return;
1491     m_inputType->detach();
1492 }
1493 #endif // ENABLE(INPUT_TYPE_COLOR)
1494
1495
1496 void HTMLInputElement::willChangeForm()
1497 {
1498     removeFromRadioButtonGroup();
1499     HTMLTextFormControlElement::willChangeForm();
1500 }
1501
1502 void HTMLInputElement::didChangeForm()
1503 {
1504     HTMLTextFormControlElement::didChangeForm();
1505     addToRadioButtonGroup();
1506 }
1507
1508 Node::InsertionNotificationRequest HTMLInputElement::insertedInto(ContainerNode* insertionPoint)
1509 {
1510     HTMLTextFormControlElement::insertedInto(insertionPoint);
1511     if (insertionPoint->inDocument() && !form())
1512         addToRadioButtonGroup();
1513 #if ENABLE(DATALIST_ELEMENT)
1514     resetListAttributeTargetObserver();
1515 #endif
1516     return InsertionDone;
1517 }
1518
1519 void HTMLInputElement::removedFrom(ContainerNode* insertionPoint)
1520 {
1521     if (insertionPoint->inDocument() && !form())
1522         removeFromRadioButtonGroup();
1523     HTMLTextFormControlElement::removedFrom(insertionPoint);
1524     ASSERT(!inDocument());
1525 #if ENABLE(DATALIST_ELEMENT)
1526     resetListAttributeTargetObserver();
1527 #endif
1528 }
1529
1530 void HTMLInputElement::didMoveToNewDocument(Document* oldDocument)
1531 {
1532     if (hasImageLoader())
1533         imageLoader()->elementDidMoveToNewDocument();
1534
1535     bool needsSuspensionCallback = this->needsSuspensionCallback();
1536     if (oldDocument) {
1537         // Always unregister for cache callbacks when leaving a document, even if we would otherwise like to be registered
1538         if (needsSuspensionCallback)
1539             oldDocument->unregisterForPageCacheSuspensionCallbacks(this);
1540         if (isRadioButton())
1541             oldDocument->formController().checkedRadioButtons().removeButton(this);
1542 #if ENABLE(TOUCH_EVENTS)
1543         if (m_hasTouchEventHandler)
1544             oldDocument->didRemoveEventTargetNode(this);
1545 #endif
1546     }
1547
1548     if (needsSuspensionCallback)
1549         document().registerForPageCacheSuspensionCallbacks(this);
1550
1551 #if ENABLE(TOUCH_EVENTS)
1552     if (m_hasTouchEventHandler)
1553         document().didAddTouchEventHandler(this);
1554 #endif
1555
1556     HTMLTextFormControlElement::didMoveToNewDocument(oldDocument);
1557 }
1558
1559 void HTMLInputElement::addSubresourceAttributeURLs(ListHashSet<URL>& urls) const
1560 {
1561     HTMLTextFormControlElement::addSubresourceAttributeURLs(urls);
1562
1563     addSubresourceURL(urls, src());
1564 }
1565
1566 bool HTMLInputElement::recalcWillValidate() const
1567 {
1568     return m_inputType->supportsValidation() && HTMLTextFormControlElement::recalcWillValidate();
1569 }
1570
1571 void HTMLInputElement::requiredAttributeChanged()
1572 {
1573     HTMLTextFormControlElement::requiredAttributeChanged();
1574     if (CheckedRadioButtons* buttons = checkedRadioButtons())
1575         buttons->requiredAttributeChanged(this);
1576     m_inputType->requiredAttributeChanged();
1577 }
1578
1579 #if ENABLE(INPUT_TYPE_COLOR)
1580 void HTMLInputElement::selectColorInColorChooser(const Color& color)
1581 {
1582     if (!m_inputType->isColorControl())
1583         return;
1584     static_cast<ColorInputType*>(m_inputType.get())->didChooseColor(color);
1585 }
1586 #endif
1587     
1588 #if ENABLE(DATALIST_ELEMENT)
1589 HTMLElement* HTMLInputElement::list() const
1590 {
1591     return dataList();
1592 }
1593
1594 HTMLDataListElement* HTMLInputElement::dataList() const
1595 {
1596     if (!m_hasNonEmptyList)
1597         return 0;
1598
1599     if (!m_inputType->shouldRespectListAttribute())
1600         return 0;
1601
1602     Element* element = treeScope()->getElementById(fastGetAttribute(listAttr));
1603     if (!element)
1604         return 0;
1605     if (!element->hasTagName(datalistTag))
1606         return 0;
1607
1608     return static_cast<HTMLDataListElement*>(element);
1609 }
1610
1611 void HTMLInputElement::resetListAttributeTargetObserver()
1612 {
1613     if (inDocument())
1614         m_listAttributeTargetObserver = ListAttributeTargetObserver::create(fastGetAttribute(listAttr), this);
1615     else
1616         m_listAttributeTargetObserver = nullptr;
1617 }
1618
1619 void HTMLInputElement::listAttributeTargetChanged()
1620 {
1621     m_inputType->listAttributeTargetChanged();
1622 }
1623 #endif // ENABLE(DATALIST_ELEMENT)
1624
1625 bool HTMLInputElement::isSteppable() const
1626 {
1627     return m_inputType->isSteppable();
1628 }
1629
1630 #if ENABLE(INPUT_SPEECH)
1631
1632 bool HTMLInputElement::isSpeechEnabled() const
1633 {
1634     // FIXME: Add support for RANGE, EMAIL, URL, COLOR and DATE/TIME input types.
1635     return m_inputType->shouldRespectSpeechAttribute() && RuntimeEnabledFeatures::sharedFeatures().speechInputEnabled() && hasAttribute(webkitspeechAttr);
1636 }
1637
1638 #endif
1639
1640 bool HTMLInputElement::isTextButton() const
1641 {
1642     return m_inputType->isTextButton();
1643 }
1644
1645 bool HTMLInputElement::isRadioButton() const
1646 {
1647     return m_inputType->isRadioButton();
1648 }
1649
1650 bool HTMLInputElement::isSearchField() const
1651 {
1652     return m_inputType->isSearchField();
1653 }
1654
1655 bool HTMLInputElement::isInputTypeHidden() const
1656 {
1657     return m_inputType->isHiddenType();
1658 }
1659
1660 bool HTMLInputElement::isPasswordField() const
1661 {
1662     return m_inputType->isPasswordField();
1663 }
1664
1665 bool HTMLInputElement::isCheckbox() const
1666 {
1667     return m_inputType->isCheckbox();
1668 }
1669
1670 bool HTMLInputElement::isRangeControl() const
1671 {
1672     return m_inputType->isRangeControl();
1673 }
1674
1675 #if ENABLE(INPUT_TYPE_COLOR)
1676 bool HTMLInputElement::isColorControl() const
1677 {
1678     return m_inputType->isColorControl();
1679 }
1680 #endif
1681
1682 bool HTMLInputElement::isText() const
1683 {
1684     return m_inputType->isTextType();
1685 }
1686
1687 bool HTMLInputElement::isEmailField() const
1688 {
1689     return m_inputType->isEmailField();
1690 }
1691
1692 bool HTMLInputElement::isFileUpload() const
1693 {
1694     return m_inputType->isFileUpload();
1695 }
1696
1697 bool HTMLInputElement::isImageButton() const
1698 {
1699     return m_inputType->isImageButton();
1700 }
1701
1702 bool HTMLInputElement::isNumberField() const
1703 {
1704     return m_inputType->isNumberField();
1705 }
1706
1707 bool HTMLInputElement::isSubmitButton() const
1708 {
1709     return m_inputType->isSubmitButton();
1710 }
1711
1712 bool HTMLInputElement::isTelephoneField() const
1713 {
1714     return m_inputType->isTelephoneField();
1715 }
1716
1717 bool HTMLInputElement::isURLField() const
1718 {
1719     return m_inputType->isURLField();
1720 }
1721
1722 bool HTMLInputElement::isDateField() const
1723 {
1724     return m_inputType->isDateField();
1725 }
1726
1727 bool HTMLInputElement::isDateTimeField() const
1728 {
1729     return m_inputType->isDateTimeField();
1730 }
1731
1732 bool HTMLInputElement::isDateTimeLocalField() const
1733 {
1734     return m_inputType->isDateTimeLocalField();
1735 }
1736
1737 bool HTMLInputElement::isMonthField() const
1738 {
1739     return m_inputType->isMonthField();
1740 }
1741
1742 bool HTMLInputElement::isTimeField() const
1743 {
1744     return m_inputType->isTimeField();
1745 }
1746
1747 bool HTMLInputElement::isWeekField() const
1748 {
1749     return m_inputType->isWeekField();
1750 }
1751
1752 bool HTMLInputElement::isEnumeratable() const
1753 {
1754     return m_inputType->isEnumeratable();
1755 }
1756
1757 bool HTMLInputElement::supportLabels() const
1758 {
1759     return m_inputType->supportLabels();
1760 }
1761
1762 bool HTMLInputElement::shouldAppearChecked() const
1763 {
1764     return checked() && m_inputType->isCheckable();
1765 }
1766
1767 bool HTMLInputElement::supportsPlaceholder() const
1768 {
1769     return m_inputType->supportsPlaceholder();
1770 }
1771
1772 void HTMLInputElement::updatePlaceholderText()
1773 {
1774     return m_inputType->updatePlaceholderText();
1775 }
1776
1777 void HTMLInputElement::parseMaxLengthAttribute(const AtomicString& value)
1778 {
1779     int maxLength;
1780     if (!parseHTMLInteger(value, maxLength))
1781         maxLength = maximumLength;
1782     if (maxLength < 0 || maxLength > maximumLength)
1783         maxLength = maximumLength;
1784     int oldMaxLength = m_maxLength;
1785     m_maxLength = maxLength;
1786     if (oldMaxLength != maxLength)
1787         updateValueIfNeeded();
1788     setNeedsStyleRecalc();
1789     setNeedsValidityCheck();
1790 }
1791
1792 void HTMLInputElement::updateValueIfNeeded()
1793 {
1794     String newValue = sanitizeValue(m_valueIfDirty);
1795     ASSERT(!m_valueIfDirty.isNull() || newValue.isNull());
1796     if (newValue != m_valueIfDirty)
1797         setValue(newValue);
1798 }
1799
1800 String HTMLInputElement::defaultToolTip() const
1801 {
1802     return m_inputType->defaultToolTip();
1803 }
1804
1805 bool HTMLInputElement::shouldAppearIndeterminate() const 
1806 {
1807     return m_inputType->supportsIndeterminateAppearance() && indeterminate();
1808 }
1809
1810 #if ENABLE(MEDIA_CAPTURE)
1811 String HTMLInputElement::capture() const
1812 {
1813     if (!isFileUpload())
1814         return String();
1815
1816     String capture = fastGetAttribute(captureAttr).lower();
1817     if (capture == "camera"
1818         || capture == "camcorder"
1819         || capture == "microphone"
1820         || capture == "filesystem")
1821         return capture;
1822
1823     return "filesystem";
1824 }
1825
1826 void HTMLInputElement::setCapture(const String& value)
1827 {
1828     setAttribute(captureAttr, value);
1829 }
1830
1831 #endif
1832
1833 bool HTMLInputElement::isInRequiredRadioButtonGroup()
1834 {
1835     ASSERT(isRadioButton());
1836     if (CheckedRadioButtons* buttons = checkedRadioButtons())
1837         return buttons->isInRequiredGroup(this);
1838     return false;
1839 }
1840
1841 HTMLInputElement* HTMLInputElement::checkedRadioButtonForGroup() const
1842 {
1843     if (CheckedRadioButtons* buttons = checkedRadioButtons())
1844         return buttons->checkedButtonForGroup(name());
1845     return 0;
1846 }
1847
1848 CheckedRadioButtons* HTMLInputElement::checkedRadioButtons() const
1849 {
1850     if (!isRadioButton())
1851         return 0;
1852     if (HTMLFormElement* formElement = form())
1853         return &formElement->checkedRadioButtons();
1854     if (inDocument())
1855         return &document().formController().checkedRadioButtons();
1856     return 0;
1857 }
1858
1859 inline void HTMLInputElement::addToRadioButtonGroup()
1860 {
1861     if (CheckedRadioButtons* buttons = checkedRadioButtons())
1862         buttons->addButton(this);
1863 }
1864
1865 inline void HTMLInputElement::removeFromRadioButtonGroup()
1866 {
1867     if (CheckedRadioButtons* buttons = checkedRadioButtons())
1868         buttons->removeButton(this);
1869 }
1870
1871 unsigned HTMLInputElement::height() const
1872 {
1873     return m_inputType->height();
1874 }
1875
1876 unsigned HTMLInputElement::width() const
1877 {
1878     return m_inputType->width();
1879 }
1880
1881 void HTMLInputElement::setHeight(unsigned height)
1882 {
1883     setAttribute(heightAttr, String::number(height));
1884 }
1885
1886 void HTMLInputElement::setWidth(unsigned width)
1887 {
1888     setAttribute(widthAttr, String::number(width));
1889 }
1890
1891 #if ENABLE(DATALIST_ELEMENT)
1892 OwnPtr<ListAttributeTargetObserver> ListAttributeTargetObserver::create(const AtomicString& id, HTMLInputElement* element)
1893 {
1894     return adoptPtr(new ListAttributeTargetObserver(id, element));
1895 }
1896
1897 ListAttributeTargetObserver::ListAttributeTargetObserver(const AtomicString& id, HTMLInputElement* element)
1898     : IdTargetObserver(element->treeScope()->idTargetObserverRegistry(), id)
1899     , m_element(element)
1900 {
1901 }
1902
1903 void ListAttributeTargetObserver::idTargetChanged()
1904 {
1905     m_element->listAttributeTargetChanged();
1906 }
1907 #endif
1908
1909 void HTMLInputElement::setRangeText(const String& replacement, ExceptionCode& ec)
1910 {
1911     if (!m_inputType->supportsSelectionAPI()) {
1912         ec = INVALID_STATE_ERR;
1913         return;
1914     }
1915
1916     HTMLTextFormControlElement::setRangeText(replacement, ec);
1917 }
1918
1919 void HTMLInputElement::setRangeText(const String& replacement, unsigned start, unsigned end, const String& selectionMode, ExceptionCode& ec)
1920 {
1921     if (!m_inputType->supportsSelectionAPI()) {
1922         ec = INVALID_STATE_ERR;
1923         return;
1924     }
1925
1926     HTMLTextFormControlElement::setRangeText(replacement, start, end, selectionMode, ec);
1927 }
1928
1929 #if ENABLE(DATE_AND_TIME_INPUT_TYPES)
1930 bool HTMLInputElement::setupDateTimeChooserParameters(DateTimeChooserParameters& parameters)
1931 {
1932     if (!document().view())
1933         return false;
1934
1935     parameters.type = type();
1936     parameters.minimum = minimum();
1937     parameters.maximum = maximum();
1938     parameters.required = isRequired();
1939     if (!RuntimeEnabledFeatures::sharedFeatures().langAttributeAwareFormControlUIEnabled())
1940         parameters.locale = defaultLanguage();
1941     else {
1942         AtomicString computedLocale = computeInheritedLanguage();
1943         parameters.locale = computedLocale.isEmpty() ? AtomicString(defaultLanguage()) : computedLocale;
1944     }
1945
1946     StepRange stepRange = createStepRange(RejectAny);
1947     if (stepRange.hasStep()) {
1948         parameters.step = stepRange.step().toDouble();
1949         parameters.stepBase = stepRange.stepBase().toDouble();
1950     } else {
1951         parameters.step = 1.0;
1952         parameters.stepBase = 0;
1953     }
1954
1955     parameters.anchorRectInRootView = document().view()->contentsToRootView(pixelSnappedBoundingBox());
1956     parameters.currentValue = value();
1957     parameters.isAnchorElementRTL = computedStyle()->direction() == RTL;
1958 #if ENABLE(DATALIST_ELEMENT)
1959     if (HTMLDataListElement* dataList = this->dataList()) {
1960         RefPtr<HTMLCollection> options = dataList->options();
1961         for (unsigned i = 0; HTMLOptionElement* option = toHTMLOptionElement(options->item(i)); ++i) {
1962             if (!isValidValue(option->value()))
1963                 continue;
1964             parameters.suggestionValues.append(sanitizeValue(option->value()));
1965             parameters.localizedSuggestionValues.append(localizeValue(option->value()));
1966             parameters.suggestionLabels.append(option->value() == option->label() ? String() : option->label());
1967         }
1968     }
1969 #endif
1970     return true;
1971 }
1972 #endif
1973
1974 } // namespace