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