FeatureObserver: Input types are counted unexpectedly in a page with Modernizr
[WebKit-https.git] / Source / WebCore / html / InputType.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) 2009, 2010, 2011, 2012 Google Inc. All rights reserved.
9  * Copyright (C) 2012 Samsung Electronics. All rights reserved.
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Library General Public
13  * License as published by the Free Software Foundation; either
14  * version 2 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Library General Public License for more details.
20  *
21  * You should have received a copy of the GNU Library General Public License
22  * along with this library; see the file COPYING.LIB.  If not, write to
23  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24  * Boston, MA 02110-1301, USA.
25  *
26  */
27
28 #include "config.h"
29 #include "InputType.h"
30
31 #include "AXObjectCache.h"
32 #include "BeforeTextInsertedEvent.h"
33 #include "ButtonInputType.h"
34 #include "CheckboxInputType.h"
35 #include "ColorInputType.h"
36 #include "DateComponents.h"
37 #include "DateInputType.h"
38 #include "DateTimeInputType.h"
39 #include "DateTimeLocalInputType.h"
40 #include "ElementShadow.h"
41 #include "EmailInputType.h"
42 #include "ExceptionCode.h"
43 #include "FileInputType.h"
44 #include "FileList.h"
45 #include "FormController.h"
46 #include "FormDataList.h"
47 #include "HTMLFormElement.h"
48 #include "HTMLInputElement.h"
49 #include "HTMLNames.h"
50 #include "HTMLParserIdioms.h"
51 #include "HTMLShadowElement.h"
52 #include "HiddenInputType.h"
53 #include "ImageInputType.h"
54 #include "InputTypeNames.h"
55 #include "KeyboardEvent.h"
56 #include "LocalizedStrings.h"
57 #include "MonthInputType.h"
58 #include "NodeRenderStyle.h"
59 #include "NumberInputType.h"
60 #include "Page.h"
61 #include "PasswordInputType.h"
62 #include "RadioInputType.h"
63 #include "RangeInputType.h"
64 #include "RegularExpression.h"
65 #include "RenderObject.h"
66 #include "RenderTheme.h"
67 #include "ResetInputType.h"
68 #include "RuntimeEnabledFeatures.h"
69 #include "SearchInputType.h"
70 #include "ShadowRoot.h"
71 #include "SubmitInputType.h"
72 #include "TelephoneInputType.h"
73 #include "TextBreakIterator.h"
74 #include "TextInputType.h"
75 #include "TimeInputType.h"
76 #include "URLInputType.h"
77 #include "WeekInputType.h"
78 #include <limits>
79 #include <wtf/Assertions.h>
80 #include <wtf/HashMap.h>
81 #include <wtf/text/StringHash.h>
82
83 namespace WebCore {
84
85 using namespace HTMLNames;
86 using namespace std;
87
88 typedef PassOwnPtr<InputType> (*InputTypeFactoryFunction)(HTMLInputElement*);
89 typedef HashMap<AtomicString, InputTypeFactoryFunction, CaseFoldingHash> InputTypeFactoryMap;
90
91 static PassOwnPtr<InputTypeFactoryMap> createInputTypeFactoryMap()
92 {
93     OwnPtr<InputTypeFactoryMap> map = adoptPtr(new InputTypeFactoryMap);
94     map->add(InputTypeNames::button(), ButtonInputType::create);
95     map->add(InputTypeNames::checkbox(), CheckboxInputType::create);
96 #if ENABLE(INPUT_TYPE_COLOR)
97     map->add(InputTypeNames::color(), ColorInputType::create);
98 #endif
99 #if ENABLE(INPUT_TYPE_DATE)
100     if (RuntimeEnabledFeatures::inputTypeDateEnabled())
101         map->add(InputTypeNames::date(), DateInputType::create);
102 #endif
103 #if ENABLE(INPUT_TYPE_DATETIME)
104     if (RuntimeEnabledFeatures::inputTypeDateTimeEnabled())
105         map->add(InputTypeNames::datetime(), DateTimeInputType::create);
106 #endif
107 #if ENABLE(INPUT_TYPE_DATETIMELOCAL)
108     if (RuntimeEnabledFeatures::inputTypeDateTimeLocalEnabled())
109         map->add(InputTypeNames::datetimelocal(), DateTimeLocalInputType::create);
110 #endif
111     map->add(InputTypeNames::email(), EmailInputType::create);
112     map->add(InputTypeNames::file(), FileInputType::create);
113     map->add(InputTypeNames::hidden(), HiddenInputType::create);
114     map->add(InputTypeNames::image(), ImageInputType::create);
115 #if ENABLE(INPUT_TYPE_MONTH)
116     if (RuntimeEnabledFeatures::inputTypeMonthEnabled())
117         map->add(InputTypeNames::month(), MonthInputType::create);
118 #endif
119     map->add(InputTypeNames::number(), NumberInputType::create);
120     map->add(InputTypeNames::password(), PasswordInputType::create);
121     map->add(InputTypeNames::radio(), RadioInputType::create);
122     map->add(InputTypeNames::range(), RangeInputType::create);
123     map->add(InputTypeNames::reset(), ResetInputType::create);
124     map->add(InputTypeNames::search(), SearchInputType::create);
125     map->add(InputTypeNames::submit(), SubmitInputType::create);
126     map->add(InputTypeNames::telephone(), TelephoneInputType::create);
127 #if ENABLE(INPUT_TYPE_TIME)
128     if (RuntimeEnabledFeatures::inputTypeTimeEnabled())
129         map->add(InputTypeNames::time(), TimeInputType::create);
130 #endif
131     map->add(InputTypeNames::url(), URLInputType::create);
132 #if ENABLE(INPUT_TYPE_WEEK)
133     if (RuntimeEnabledFeatures::inputTypeWeekEnabled())
134         map->add(InputTypeNames::week(), WeekInputType::create);
135 #endif
136     // No need to register "text" because it is the default type.
137     return map.release();
138 }
139
140 PassOwnPtr<InputType> InputType::create(HTMLInputElement* element, const AtomicString& typeName)
141 {
142     static const InputTypeFactoryMap* factoryMap = createInputTypeFactoryMap().leakPtr();
143     PassOwnPtr<InputType> (*factory)(HTMLInputElement*) = typeName.isEmpty() ? 0 : factoryMap->get(typeName);
144     if (!factory)
145         factory = TextInputType::create;
146     return factory(element);
147 }
148
149 PassOwnPtr<InputType> InputType::createText(HTMLInputElement* element)
150 {
151     return TextInputType::create(element);
152 }
153
154 InputType::~InputType()
155 {
156 }
157
158 bool InputType::themeSupportsDataListUI(InputType* type)
159 {
160     Document* document = type->element()->document();
161     RefPtr<RenderTheme> theme = document->page() ? document->page()->theme() : RenderTheme::defaultTheme();
162     return theme->supportsDataListUI(type->formControlType());
163 }
164
165 bool InputType::isTextField() const
166 {
167     return false;
168 }
169
170 bool InputType::isTextType() const
171 {
172     return false;
173 }
174
175 bool InputType::isRangeControl() const
176 {
177     return false;
178 }
179
180 bool InputType::shouldSaveAndRestoreFormControlState() const
181 {
182     return true;
183 }
184
185 FormControlState InputType::saveFormControlState() const
186 {
187     String currentValue = element()->value();
188     if (currentValue == element()->defaultValue())
189         return FormControlState();
190     return FormControlState(currentValue);
191 }
192
193 void InputType::restoreFormControlState(const FormControlState& state)
194 {
195     element()->setValue(state[0]);
196 }
197
198 bool InputType::isFormDataAppendable() const
199 {
200     // There is no form data unless there's a name for non-image types.
201     return !element()->name().isEmpty();
202 }
203
204 bool InputType::appendFormData(FormDataList& encoding, bool) const
205 {
206     // Always successful.
207     encoding.appendData(element()->name(), element()->value());
208     return true;
209 }
210
211 double InputType::valueAsDate() const
212 {
213     return DateComponents::invalidMilliseconds();
214 }
215
216 void InputType::setValueAsDate(double, ExceptionCode& ec) const
217 {
218     ec = INVALID_STATE_ERR;
219 }
220
221 double InputType::valueAsDouble() const
222 {
223     return numeric_limits<double>::quiet_NaN();
224 }
225
226 void InputType::setValueAsDouble(double doubleValue, TextFieldEventBehavior eventBehavior, ExceptionCode& ec) const
227 {
228     setValueAsDecimal(Decimal::fromDouble(doubleValue), eventBehavior, ec);
229 }
230
231 void InputType::setValueAsDecimal(const Decimal&, TextFieldEventBehavior, ExceptionCode& ec) const
232 {
233     ec = INVALID_STATE_ERR;
234 }
235
236 bool InputType::supportsValidation() const
237 {
238     return true;
239 }
240
241 bool InputType::typeMismatchFor(const String&) const
242 {
243     return false;
244 }
245
246 bool InputType::typeMismatch() const
247 {
248     return false;
249 }
250
251 bool InputType::supportsRequired() const
252 {
253     // Almost all validatable types support @required.
254     return supportsValidation();
255 }
256
257 bool InputType::valueMissing(const String&) const
258 {
259     return false;
260 }
261
262 bool InputType::hasBadInput() const
263 {
264     return false;
265 }
266
267 bool InputType::patternMismatch(const String&) const
268 {
269     return false;
270 }
271
272 bool InputType::rangeUnderflow(const String& value) const
273 {
274     if (!isSteppable())
275         return false;
276
277     const Decimal numericValue = parseToNumberOrNaN(value);
278     if (!numericValue.isFinite())
279         return false;
280
281     return numericValue < createStepRange(RejectAny).minimum();
282 }
283
284 bool InputType::rangeOverflow(const String& value) const
285 {
286     if (!isSteppable())
287         return false;
288
289     const Decimal numericValue = parseToNumberOrNaN(value);
290     if (!numericValue.isFinite())
291         return false;
292
293     return numericValue > createStepRange(RejectAny).maximum();
294 }
295
296 Decimal InputType::defaultValueForStepUp() const
297 {
298     return 0;
299 }
300
301 double InputType::minimum() const
302 {
303     return createStepRange(RejectAny).minimum().toDouble();
304 }
305
306 double InputType::maximum() const
307 {
308     return createStepRange(RejectAny).maximum().toDouble();
309 }
310
311 bool InputType::sizeShouldIncludeDecoration(int, int& preferredSize) const
312 {
313     preferredSize = element()->size();
314     return false;
315 }
316
317 bool InputType::isInRange(const String& value) const
318 {
319     if (!isSteppable())
320         return false;
321
322     const Decimal numericValue = parseToNumberOrNaN(value);
323     if (!numericValue.isFinite())
324         return true;
325
326     StepRange stepRange(createStepRange(RejectAny));
327     return numericValue >= stepRange.minimum() && numericValue <= stepRange.maximum();
328 }
329
330 bool InputType::isOutOfRange(const String& value) const
331 {
332     if (!isSteppable())
333         return false;
334
335     const Decimal numericValue = parseToNumberOrNaN(value);
336     if (!numericValue.isFinite())
337         return true;
338
339     StepRange stepRange(createStepRange(RejectAny));
340     return numericValue < stepRange.minimum() || numericValue > stepRange.maximum();
341 }
342
343 bool InputType::stepMismatch(const String& value) const
344 {
345     if (!isSteppable())
346         return false;
347
348     const Decimal numericValue = parseToNumberOrNaN(value);
349     if (!numericValue.isFinite())
350         return false;
351
352     return createStepRange(RejectAny).stepMismatch(numericValue);
353 }
354
355 String InputType::badInputText() const
356 {
357     ASSERT_NOT_REACHED();
358     return validationMessageTypeMismatchText();
359 }
360
361 String InputType::typeMismatchText() const
362 {
363     return validationMessageTypeMismatchText();
364 }
365
366 String InputType::valueMissingText() const
367 {
368     return validationMessageValueMissingText();
369 }
370
371 String InputType::validationMessage() const
372 {
373     const String value = element()->value();
374
375     // The order of the following checks is meaningful. e.g. We'd like to show the
376     // valueMissing message even if the control has other validation errors.
377     if (valueMissing(value))
378         return valueMissingText();
379
380     if (typeMismatch())
381         return typeMismatchText();
382
383     if (hasBadInput())
384         return badInputText();
385
386     if (patternMismatch(value))
387         return validationMessagePatternMismatchText();
388
389     if (element()->tooLong())
390         return validationMessageTooLongText(numGraphemeClusters(value), element()->maxLength());
391
392     if (!isSteppable())
393         return emptyString();
394
395     const Decimal numericValue = parseToNumberOrNaN(value);
396     if (!numericValue.isFinite())
397         return emptyString();
398
399     StepRange stepRange(createStepRange(RejectAny));
400
401     if (numericValue < stepRange.minimum())
402         return validationMessageRangeUnderflowText(serialize(stepRange.minimum()));
403
404     if (numericValue > stepRange.maximum())
405         return validationMessageRangeOverflowText(serialize(stepRange.maximum()));
406
407     if (stepRange.stepMismatch(numericValue)) {
408         const String stepString = stepRange.hasStep() ? serializeForNumberType(stepRange.step() / stepRange.stepScaleFactor()) : emptyString();
409         return validationMessageStepMismatchText(serialize(stepRange.stepBase()), stepString);
410     }
411
412     return emptyString();
413 }
414
415 void InputType::handleClickEvent(MouseEvent*)
416 {
417 }
418
419 void InputType::handleMouseDownEvent(MouseEvent*)
420 {
421 }
422
423 void InputType::handleDOMActivateEvent(Event*)
424 {
425 }
426
427 void InputType::handleKeydownEvent(KeyboardEvent*)
428 {
429 }
430
431 void InputType::handleKeypressEvent(KeyboardEvent*)
432 {
433 }
434
435 void InputType::handleKeyupEvent(KeyboardEvent*)
436 {
437 }
438
439 void InputType::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent*)
440 {
441 }
442
443 #if ENABLE(TOUCH_EVENTS)
444 void InputType::handleTouchEvent(TouchEvent*)
445 {
446 }
447 #endif
448
449 void InputType::forwardEvent(Event*)
450 {
451 }
452
453 bool InputType::shouldSubmitImplicitly(Event* event)
454 {
455     return event->isKeyboardEvent() && event->type() == eventNames().keypressEvent && static_cast<KeyboardEvent*>(event)->charCode() == '\r';
456 }
457
458 PassRefPtr<HTMLFormElement> InputType::formForSubmission() const
459 {
460     return element()->form();
461 }
462
463 RenderObject* InputType::createRenderer(RenderArena*, RenderStyle* style) const
464 {
465     return RenderObject::createObject(element(), style);
466 }
467
468 void InputType::blur()
469 {
470     element()->defaultBlur();
471 }
472
473 void InputType::focus(bool restorePreviousSelection)
474 {
475     element()->defaultFocus(restorePreviousSelection);
476 }
477
478 void InputType::createShadowSubtree()
479 {
480 }
481
482 void InputType::destroyShadowSubtree()
483 {
484     ShadowRoot* root = element()->userAgentShadowRoot();
485     if (!root)
486         return;
487
488     root->removeChildren();
489
490     // It's ok to clear contents of all other ShadowRoots because they must have
491     // been created by TextFieldDecorationElement, and we don't allow adding
492     // AuthorShadowRoot to HTMLInputElement.
493     while ((root = root->youngerShadowRoot())) {
494 #if ENABLE(SHADOW_DOM)
495         root->removeChildren();
496         root->appendChild(HTMLShadowElement::create(shadowTag, element()->document()));
497 #else
498         ASSERT_NOT_REACHED();
499 #endif
500     }
501 }
502
503 Decimal InputType::parseToNumber(const String&, const Decimal& defaultValue) const
504 {
505     ASSERT_NOT_REACHED();
506     return defaultValue;
507 }
508
509 Decimal InputType::parseToNumberOrNaN(const String& string) const
510 {
511     return parseToNumber(string, Decimal::nan());
512 }
513
514 bool InputType::parseToDateComponents(const String&, DateComponents*) const
515 {
516     ASSERT_NOT_REACHED();
517     return false;
518 }
519
520 String InputType::serialize(const Decimal&) const
521 {
522     ASSERT_NOT_REACHED();
523     return String();
524 }
525
526 void InputType::dispatchSimulatedClickIfActive(KeyboardEvent* event) const
527 {
528     if (element()->active())
529         element()->dispatchSimulatedClick(event);
530     event->setDefaultHandled();
531 }
532
533 Chrome* InputType::chrome() const
534 {
535     if (Page* page = element()->document()->page())
536         return page->chrome();
537     return 0;
538 }
539
540 bool InputType::canSetStringValue() const
541 {
542     return true;
543 }
544
545 bool InputType::hasCustomFocusLogic() const
546 {
547     return true;
548 }
549
550 bool InputType::isKeyboardFocusable(KeyboardEvent* event) const
551 {
552     return element()->isTextFormControlKeyboardFocusable(event);
553 }
554
555 bool InputType::isMouseFocusable() const
556 {
557     return element()->isTextFormControlMouseFocusable();
558 }
559
560 bool InputType::shouldUseInputMethod() const
561 {
562     return false;
563 }
564
565 void InputType::handleFocusEvent()
566 {
567 }
568
569 void InputType::handleBlurEvent()
570 {
571 }
572
573 void InputType::accessKeyAction(bool)
574 {
575     element()->focus(false);
576 }
577
578 void InputType::addSearchResult()
579 {
580 }
581
582 void InputType::attach()
583 {
584 }
585
586 void InputType::detach()
587 {
588 }
589
590 void InputType::altAttributeChanged()
591 {
592 }
593
594 void InputType::srcAttributeChanged()
595 {
596 }
597
598 void InputType::willMoveToNewOwnerDocument()
599 {
600 }
601
602 bool InputType::shouldRespectAlignAttribute()
603 {
604     return false;
605 }
606
607 bool InputType::canChangeFromAnotherType() const
608 {
609     return true;
610 }
611
612 void InputType::minOrMaxAttributeChanged()
613 {
614 }
615
616 void InputType::stepAttributeChanged()
617 {
618 }
619
620 bool InputType::canBeSuccessfulSubmitButton()
621 {
622     return false;
623 }
624
625 HTMLElement* InputType::placeholderElement() const
626 {
627     return 0;
628 }
629
630 bool InputType::rendererIsNeeded()
631 {
632     return true;
633 }
634
635 FileList* InputType::files()
636 {
637     return 0;
638 }
639
640 void InputType::setFiles(PassRefPtr<FileList>)
641 {
642 }
643
644 bool InputType::getTypeSpecificValue(String&)
645 {
646     return false;
647 }
648
649 String InputType::fallbackValue() const
650 {
651     return String();
652 }
653
654 String InputType::defaultValue() const
655 {
656     return String();
657 }
658
659 bool InputType::canSetSuggestedValue()
660 {
661     return false;
662 }
663
664 bool InputType::shouldSendChangeEventAfterCheckedChanged()
665 {
666     return true;
667 }
668
669 bool InputType::storesValueSeparateFromAttribute()
670 {
671     return true;
672 }
673
674 void InputType::setValue(const String& sanitizedValue, bool valueChanged, TextFieldEventBehavior eventBehavior)
675 {
676     element()->setValueInternal(sanitizedValue, eventBehavior);
677     element()->setNeedsStyleRecalc();
678     if (!valueChanged)
679         return;
680     switch (eventBehavior) {
681     case DispatchChangeEvent:
682         element()->dispatchFormControlChangeEvent();
683         break;
684     case DispatchInputAndChangeEvent:
685         element()->dispatchFormControlInputEvent();
686         element()->dispatchFormControlChangeEvent();
687         break;
688     case DispatchNoEvent:
689         break;
690     }
691 }
692
693 bool InputType::canSetValue(const String&)
694 {
695     return true;
696 }
697
698 PassOwnPtr<ClickHandlingState> InputType::willDispatchClick()
699 {
700     return nullptr;
701 }
702
703 void InputType::didDispatchClick(Event*, const ClickHandlingState&)
704 {
705 }
706
707 String InputType::localizeValue(const String& proposedValue) const
708 {
709     return proposedValue;
710 }
711
712 String InputType::visibleValue() const
713 {
714     return element()->value();
715 }
716
717 String InputType::sanitizeValue(const String& proposedValue) const
718 {
719     return proposedValue;
720 }
721
722 bool InputType::receiveDroppedFiles(const DragData*)
723 {
724     ASSERT_NOT_REACHED();
725     return false;
726 }
727
728 #if ENABLE(FILE_SYSTEM)
729 String InputType::droppedFileSystemId()
730 {
731     ASSERT_NOT_REACHED();
732     return String();
733 }
734 #endif
735
736 Icon* InputType::icon() const
737 {
738     ASSERT_NOT_REACHED();
739     return 0;
740 }
741
742 bool InputType::shouldResetOnDocumentActivation()
743 {
744     return false;
745 }
746
747 bool InputType::shouldRespectListAttribute()
748 {
749     return false;
750 }
751
752 bool InputType::shouldRespectSpeechAttribute()
753 {
754     return false;
755 }
756
757 bool InputType::isTextButton() const
758 {
759     return false;
760 }
761
762 bool InputType::isRadioButton() const
763 {
764     return false;
765 }
766
767 bool InputType::isSearchField() const
768 {
769     return false;
770 }
771
772 bool InputType::isHiddenType() const
773 {
774     return false;
775 }
776
777 bool InputType::isPasswordField() const
778 {
779     return false;
780 }
781
782 bool InputType::isCheckbox() const
783 {
784     return false;
785 }
786
787 bool InputType::isEmailField() const
788 {
789     return false;
790 }
791
792 bool InputType::isFileUpload() const
793 {
794     return false;
795 }
796
797 bool InputType::isImageButton() const
798 {
799     return false;
800 }
801
802 bool InputType::supportLabels() const
803 {
804     return true;
805 }
806
807 bool InputType::isNumberField() const
808 {
809     return false;
810 }
811
812 bool InputType::isSubmitButton() const
813 {
814     return false;
815 }
816
817 bool InputType::isTelephoneField() const
818 {
819     return false;
820 }
821
822 bool InputType::isURLField() const
823 {
824     return false;
825 }
826
827 bool InputType::isDateField() const
828 {
829     return false;
830 }
831
832 bool InputType::isDateTimeField() const
833 {
834     return false;
835 }
836
837 bool InputType::isDateTimeLocalField() const
838 {
839     return false;
840 }
841
842 bool InputType::isMonthField() const
843 {
844     return false;
845 }
846
847 bool InputType::isTimeField() const
848 {
849     return false;
850 }
851
852 bool InputType::isWeekField() const
853 {
854     return false;
855 }
856
857 bool InputType::isEnumeratable()
858 {
859     return true;
860 }
861
862 bool InputType::isCheckable()
863 {
864     return false;
865 }
866
867 bool InputType::isSteppable() const
868 {
869     return false;
870 }
871
872 #if ENABLE(INPUT_TYPE_COLOR)
873 bool InputType::isColorControl() const
874 {
875     return false;
876 }
877 #endif
878
879 bool InputType::shouldRespectHeightAndWidthAttributes()
880 {
881     return false;
882 }
883
884 bool InputType::supportsPlaceholder() const
885 {
886     return false;
887 }
888
889 bool InputType::supportsReadOnly() const
890 {
891     return false;
892 }
893
894 void InputType::updateInnerTextValue()
895 {
896 }
897
898 void InputType::updatePlaceholderText()
899 {
900 }
901
902 void InputType::multipleAttributeChanged()
903 {
904 }
905
906 void InputType::disabledAttributeChanged()
907 {
908 }
909
910 void InputType::readonlyAttributeChanged()
911 {
912 }
913
914 void InputType::subtreeHasChanged()
915 {
916     ASSERT_NOT_REACHED();
917 }
918
919 #if ENABLE(TOUCH_EVENTS)
920 bool InputType::hasTouchEventHandler() const
921 {
922     return false;
923 }
924 #endif
925
926 String InputType::defaultToolTip() const
927 {
928     return String();
929 }
930
931 #if ENABLE(DATALIST_ELEMENT)
932 void InputType::listAttributeTargetChanged()
933 {
934 }
935
936 Decimal InputType::findClosestTickMarkValue(const Decimal&)
937 {
938     ASSERT_NOT_REACHED();
939     return Decimal::nan();
940 }
941 #endif
942
943 bool InputType::supportsIndeterminateAppearance() const
944 {
945     return false;
946 }
947
948 bool InputType::supportsSelectionAPI() const
949 {
950     return false;
951 }
952
953 unsigned InputType::height() const
954 {
955     return 0;
956 }
957
958 unsigned InputType::width() const
959 {
960     return 0;
961 }
962
963 void InputType::applyStep(int count, AnyStepHandling anyStepHandling, TextFieldEventBehavior eventBehavior, ExceptionCode& ec)
964 {
965     StepRange stepRange(createStepRange(anyStepHandling));
966     if (!stepRange.hasStep()) {
967         ec = INVALID_STATE_ERR;
968         return;
969     }
970
971     const Decimal current = parseToNumberOrNaN(element()->value());
972     if (!current.isFinite()) {
973         ec = INVALID_STATE_ERR;
974         return;
975     }
976     Decimal newValue = current + stepRange.step() * count;
977     if (!newValue.isFinite()) {
978         ec = INVALID_STATE_ERR;
979         return;
980     }
981
982     const Decimal acceptableErrorValue = stepRange.acceptableError();
983     if (newValue - stepRange.minimum() < -acceptableErrorValue) {
984         ec = INVALID_STATE_ERR;
985         return;
986     }
987     if (newValue < stepRange.minimum())
988         newValue = stepRange.minimum();
989
990     const AtomicString& stepString = element()->fastGetAttribute(stepAttr);
991     if (!equalIgnoringCase(stepString, "any"))
992         newValue = stepRange.alignValueForStep(current, newValue);
993
994     if (newValue - stepRange.maximum() > acceptableErrorValue) {
995         ec = INVALID_STATE_ERR;
996         return;
997     }
998     if (newValue > stepRange.maximum())
999         newValue = stepRange.maximum();
1000
1001     setValueAsDecimal(newValue, eventBehavior, ec);
1002
1003     if (AXObjectCache::accessibilityEnabled())
1004          element()->document()->axObjectCache()->postNotification(element(), AXObjectCache::AXValueChanged, true);
1005 }
1006
1007 bool InputType::getAllowedValueStep(Decimal* step) const
1008 {
1009     StepRange stepRange(createStepRange(RejectAny));
1010     *step = stepRange.step();
1011     return stepRange.hasStep();
1012 }
1013
1014 StepRange InputType::createStepRange(AnyStepHandling) const
1015 {
1016     ASSERT_NOT_REACHED();
1017     return StepRange();
1018 }
1019
1020 void InputType::stepUp(int n, ExceptionCode& ec)
1021 {
1022     if (!isSteppable()) {
1023         ec = INVALID_STATE_ERR;
1024         return;
1025     }
1026     applyStep(n, RejectAny, DispatchNoEvent, ec);
1027 }
1028
1029 void InputType::stepUpFromRenderer(int n)
1030 {
1031     // The differences from stepUp()/stepDown():
1032     //
1033     // Difference 1: the current value
1034     // If the current value is not a number, including empty, the current value is assumed as 0.
1035     //   * If 0 is in-range, and matches to step value
1036     //     - The value should be the +step if n > 0
1037     //     - The value should be the -step if n < 0
1038     //     If -step or +step is out of range, new value should be 0.
1039     //   * If 0 is smaller than the minimum value
1040     //     - The value should be the minimum value for any n
1041     //   * If 0 is larger than the maximum value
1042     //     - The value should be the maximum value for any n
1043     //   * If 0 is in-range, but not matched to step value
1044     //     - The value should be the larger matched value nearest to 0 if n > 0
1045     //       e.g. <input type=number min=-100 step=3> -> 2
1046     //     - The value should be the smaler matched value nearest to 0 if n < 0
1047     //       e.g. <input type=number min=-100 step=3> -> -1
1048     //   As for date/datetime-local/month/time/week types, the current value is assumed as "the current local date/time".
1049     //   As for datetime type, the current value is assumed as "the current date/time in UTC".
1050     // If the current value is smaller than the minimum value:
1051     //  - The value should be the minimum value if n > 0
1052     //  - Nothing should happen if n < 0
1053     // If the current value is larger than the maximum value:
1054     //  - The value should be the maximum value if n < 0
1055     //  - Nothing should happen if n > 0
1056     //
1057     // Difference 2: clamping steps
1058     // If the current value is not matched to step value:
1059     // - The value should be the larger matched value nearest to 0 if n > 0
1060     //   e.g. <input type=number value=3 min=-100 step=3> -> 5
1061     // - The value should be the smaler matched value nearest to 0 if n < 0
1062     //   e.g. <input type=number value=3 min=-100 step=3> -> 2
1063     //
1064     // n is assumed as -n if step < 0.
1065
1066     ASSERT(isSteppable());
1067     if (!isSteppable())
1068         return;
1069     ASSERT(n);
1070     if (!n)
1071         return;
1072
1073     StepRange stepRange(createStepRange(AnyIsDefaultStep));
1074
1075     // FIXME: Not any changes after stepping, even if it is an invalid value, may be better.
1076     // (e.g. Stepping-up for <input type="number" value="foo" step="any" /> => "foo")
1077     if (!stepRange.hasStep())
1078       return;
1079
1080     const Decimal step = stepRange.step();
1081
1082     int sign;
1083     if (step > 0)
1084         sign = n;
1085     else if (step < 0)
1086         sign = -n;
1087     else
1088         sign = 0;
1089
1090     String currentStringValue = element()->value();
1091     Decimal current = parseToNumberOrNaN(currentStringValue);
1092     if (!current.isFinite()) {
1093         ExceptionCode ec;
1094         current = defaultValueForStepUp();
1095         const Decimal nextDiff = step * n;
1096         if (current < stepRange.minimum() - nextDiff)
1097             current = stepRange.minimum() - nextDiff;
1098         if (current > stepRange.maximum() - nextDiff)
1099             current = stepRange.maximum() - nextDiff;
1100         setValueAsDecimal(current, DispatchInputAndChangeEvent, ec);
1101     }
1102     if ((sign > 0 && current < stepRange.minimum()) || (sign < 0 && current > stepRange.maximum())) {
1103         ExceptionCode ec;
1104         setValueAsDecimal(sign > 0 ? stepRange.minimum() : stepRange.maximum(), DispatchInputAndChangeEvent, ec);
1105     } else {
1106         ExceptionCode ec;
1107         if (stepMismatch(element()->value())) {
1108             ASSERT(!step.isZero());
1109             const Decimal base = stepRange.stepBase();
1110             Decimal newValue;
1111             if (sign < 0)
1112                 newValue = base + ((current - base) / step).floor() * step;
1113             else if (sign > 0)
1114                 newValue = base + ((current - base) / step).ceiling() * step;
1115             else
1116                 newValue = current;
1117
1118             if (newValue < stepRange.minimum())
1119                 newValue = stepRange.minimum();
1120             if (newValue > stepRange.maximum())
1121                 newValue = stepRange.maximum();
1122
1123             setValueAsDecimal(newValue, n == 1 || n == -1 ? DispatchInputAndChangeEvent : DispatchNoEvent, ec);
1124             if (n > 1)
1125                 applyStep(n - 1, AnyIsDefaultStep, DispatchInputAndChangeEvent, ec);
1126             else if (n < -1)
1127                 applyStep(n + 1, AnyIsDefaultStep, DispatchInputAndChangeEvent, ec);
1128         } else
1129             applyStep(n, AnyIsDefaultStep, DispatchInputAndChangeEvent, ec);
1130     }
1131 }
1132
1133 void InputType::observeFeatureIfVisible(FeatureObserver::Feature feature) const
1134 {
1135     if (RenderStyle* style = element()->renderStyle()) {
1136         if (style->visibility() != HIDDEN)
1137             FeatureObserver::observe(element()->document(), feature);
1138     }
1139 }
1140
1141 } // namespace WebCore