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