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