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