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