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