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) 2010 Google Inc. All rights reserved.
      9  *
     10  * This library is free software; you can redistribute it and/or
     11  * modify it under the terms of the GNU Library General Public
     12  * License as published by the Free Software Foundation; either
     13  * version 2 of the License, or (at your option) any later version.
     14  *
     15  * This library is distributed in the hope that it will be useful,
     16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     18  * Library General Public License for more details.
     19  *
     20  * You should have received a copy of the GNU Library General Public License
     21  * along with this library; see the file COPYING.LIB.  If not, write to
     22  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     23  * Boston, MA 02110-1301, USA.
     24  *
     25  */
     26 
     27 #include "config.h"
     28 #include "InputType.h"
     29 
     30 #include "BeforeTextInsertedEvent.h"
     31 #include "ButtonInputType.h"
     32 #include "CheckboxInputType.h"
     33 #include "ColorInputType.h"
     34 #include "DateComponents.h"
     35 #include "DateInputType.h"
     36 #include "DateTimeInputType.h"
     37 #include "DateTimeLocalInputType.h"
     38 #include "EmailInputType.h"
     39 #include "ExceptionCode.h"
     40 #include "FileInputType.h"
     41 #include "FormDataList.h"
     42 #include "HTMLFormElement.h"
     43 #include "HTMLInputElement.h"
     44 #include "HiddenInputType.h"
     45 #include "ImageInputType.h"
     46 #include "IsIndexInputType.h"
     47 #include "KeyboardEvent.h"
     48 #include "LocalizedStrings.h"
     49 #include "MonthInputType.h"
     50 #include "NumberInputType.h"
     51 #include "PasswordInputType.h"
     52 #include "RadioInputType.h"
     53 #include "RangeInputType.h"
     54 #include "RegularExpression.h"
     55 #include "RenderObject.h"
     56 #include "ResetInputType.h"
     57 #include "SearchInputType.h"
     58 #include "ShadowRoot.h"
     59 #include "SubmitInputType.h"
     60 #include "TelephoneInputType.h"
     61 #include "TextInputType.h"
     62 #include "TimeInputType.h"
     63 #include "URLInputType.h"
     64 #include "WeekInputType.h"
     65 #include <limits>
     66 #include <wtf/Assertions.h>
     67 #include <wtf/HashMap.h>
     68 #include <wtf/text/StringHash.h>
     69 
     70 namespace WebCore {
     71 
     72 using namespace std;
     73 
     74 typedef PassOwnPtr<InputType> (*InputTypeFactoryFunction)(HTMLInputElement*);
     75 typedef HashMap<String, InputTypeFactoryFunction, CaseFoldingHash> InputTypeFactoryMap;
     76 
     77 static PassOwnPtr<InputTypeFactoryMap> createInputTypeFactoryMap()
     78 {
     79     OwnPtr<InputTypeFactoryMap> map = adoptPtr(new InputTypeFactoryMap);
     80     map->add(InputTypeNames::button(), ButtonInputType::create);
     81     map->add(InputTypeNames::checkbox(), CheckboxInputType::create);
     82     map->add(InputTypeNames::color(), ColorInputType::create);
     83     map->add(InputTypeNames::date(), DateInputType::create);
     84     map->add(InputTypeNames::datetime(), DateTimeInputType::create);
     85     map->add(InputTypeNames::datetimelocal(), DateTimeLocalInputType::create);
     86     map->add(InputTypeNames::email(), EmailInputType::create);
     87     map->add(InputTypeNames::file(), FileInputType::create);
     88     map->add(InputTypeNames::hidden(), HiddenInputType::create);
     89     map->add(InputTypeNames::image(), ImageInputType::create);
     90     map->add(InputTypeNames::isindex(), IsIndexInputType::create);
     91     map->add(InputTypeNames::month(), MonthInputType::create);
     92     map->add(InputTypeNames::number(), NumberInputType::create);
     93     map->add(InputTypeNames::password(), PasswordInputType::create);
     94     map->add(InputTypeNames::radio(), RadioInputType::create);
     95     map->add(InputTypeNames::range(), RangeInputType::create);
     96     map->add(InputTypeNames::reset(), ResetInputType::create);
     97     map->add(InputTypeNames::search(), SearchInputType::create);
     98     map->add(InputTypeNames::submit(), SubmitInputType::create);
     99     map->add(InputTypeNames::telephone(), TelephoneInputType::create);
    100     map->add(InputTypeNames::time(), TimeInputType::create);
    101     map->add(InputTypeNames::url(), URLInputType::create);
    102     map->add(InputTypeNames::week(), WeekInputType::create);
    103     // No need to register "text" because it is the default type.
    104     return map.release();
    105 }
    106 
    107 PassOwnPtr<InputType> InputType::create(HTMLInputElement* element, const String& typeName)
    108 {
    109     static const InputTypeFactoryMap* factoryMap = createInputTypeFactoryMap().leakPtr();
    110     PassOwnPtr<InputType> (*factory)(HTMLInputElement*) = typeName.isEmpty() ? 0 : factoryMap->get(typeName);
    111     if (!factory)
    112         factory = TextInputType::create;
    113     return factory(element);
    114 }
    115 
    116 PassOwnPtr<InputType> InputType::createText(HTMLInputElement* element)
    117 {
    118     return TextInputType::create(element);
    119 }
    120 
    121 InputType::~InputType()
    122 {
    123 }
    124 
    125 bool InputType::isTextField() const
    126 {
    127     return false;
    128 }
    129 
    130 bool InputType::isTextType() const
    131 {
    132     return false;
    133 }
    134 
    135 bool InputType::isRangeControl() const
    136 {
    137     return false;
    138 }
    139 
    140 bool InputType::saveFormControlState(String& result) const
    141 {
    142     String currentValue = element()->value();
    143     if (currentValue == element()->defaultValue())
    144         return false;
    145     result = currentValue;
    146     return true;
    147 }
    148 
    149 void InputType::restoreFormControlState(const String& state) const
    150 {
    151     element()->setValue(state);
    152 }
    153 
    154 bool InputType::isFormDataAppendable() const
    155 {
    156     // There is no form data unless there's a name for non-image types.
    157     return !element()->name().isEmpty();
    158 }
    159 
    160 bool InputType::appendFormData(FormDataList& encoding, bool) const
    161 {
    162     // Always successful.
    163     encoding.appendData(element()->name(), element()->value());
    164     return true;
    165 }
    166 
    167 double InputType::valueAsDate() const
    168 {
    169     return DateComponents::invalidMilliseconds();
    170 }
    171 
    172 void InputType::setValueAsDate(double, ExceptionCode& ec) const
    173 {
    174     ec = INVALID_STATE_ERR;
    175 }
    176 
    177 double InputType::valueAsNumber() const
    178 {
    179     return numeric_limits<double>::quiet_NaN();
    180 }
    181 
    182 void InputType::setValueAsNumber(double, ExceptionCode& ec) const
    183 {
    184     ec = INVALID_STATE_ERR;
    185 }
    186 
    187 bool InputType::supportsValidation() const
    188 {
    189     return true;
    190 }
    191 
    192 bool InputType::typeMismatchFor(const String&) const
    193 {
    194     return false;
    195 }
    196 
    197 bool InputType::typeMismatch() const
    198 {
    199     return false;
    200 }
    201 
    202 bool InputType::supportsRequired() const
    203 {
    204     // Almost all validatable types support @required.
    205     return supportsValidation();
    206 }
    207 
    208 bool InputType::valueMissing(const String&) const
    209 {
    210     return false;
    211 }
    212 
    213 bool InputType::patternMismatch(const String&) const
    214 {
    215     return false;
    216 }
    217 
    218 bool InputType::rangeUnderflow(const String&) const
    219 {
    220     return false;
    221 }
    222 
    223 bool InputType::rangeOverflow(const String&) const
    224 {
    225     return false;
    226 }
    227 
    228 bool InputType::supportsRangeLimitation() const
    229 {
    230     return false;
    231 }
    232 
    233 double InputType::defaultValueForStepUp() const
    234 {
    235     return 0;
    236 }
    237 
    238 double InputType::minimum() const
    239 {
    240     ASSERT_NOT_REACHED();
    241     return 0;
    242 }
    243 
    244 double InputType::maximum() const
    245 {
    246     ASSERT_NOT_REACHED();
    247     return 0;
    248 }
    249 
    250 bool InputType::stepMismatch(const String&, double) const
    251 {
    252     // Non-supported types should be rejected by HTMLInputElement::getAllowedValueStep().
    253     ASSERT_NOT_REACHED();
    254     return false;
    255 }
    256 
    257 double InputType::stepBase() const
    258 {
    259     ASSERT_NOT_REACHED();
    260     return 0;
    261 }
    262 
    263 double InputType::stepBaseWithDecimalPlaces(unsigned* decimalPlaces) const
    264 {
    265     if (decimalPlaces)
    266         *decimalPlaces = 0;
    267     return stepBase();
    268 }
    269 
    270 double InputType::defaultStep() const
    271 {
    272     return numeric_limits<double>::quiet_NaN();
    273 }
    274 
    275 double InputType::stepScaleFactor() const
    276 {
    277     return numeric_limits<double>::quiet_NaN();
    278 }
    279 
    280 bool InputType::parsedStepValueShouldBeInteger() const
    281 {
    282     return false;
    283 }
    284 
    285 bool InputType::scaledStepValueShouldBeInteger() const
    286 {
    287     return false;
    288 }
    289 
    290 double InputType::acceptableError(double) const
    291 {
    292     return 0;
    293 }
    294 
    295 String InputType::typeMismatchText() const
    296 {
    297     return validationMessageTypeMismatchText();
    298 }
    299 
    300 String InputType::valueMissingText() const
    301 {
    302     return validationMessageValueMissingText();
    303 }
    304 
    305 void InputType::handleClickEvent(MouseEvent*)
    306 {
    307 }
    308 
    309 void InputType::handleMouseDownEvent(MouseEvent*)
    310 {
    311 }
    312 
    313 #if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
    314 void InputType::handleTouchStartEvent(TouchEvent*)
    315 {
    316 }
    317 #endif
    318 
    319 void InputType::handleDOMActivateEvent(Event*)
    320 {
    321 }
    322 
    323 void InputType::handleKeydownEvent(KeyboardEvent*)
    324 {
    325 }
    326 
    327 void InputType::handleKeypressEvent(KeyboardEvent*)
    328 {
    329 }
    330 
    331 void InputType::handleKeyupEvent(KeyboardEvent*)
    332 {
    333 }
    334 
    335 void InputType::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent* event)
    336 {
    337     element()->handleBeforeTextInsertedEvent(event);
    338 }
    339 
    340 void InputType::handleWheelEvent(WheelEvent*)
    341 {
    342 }
    343 
    344 void InputType::forwardEvent(Event*)
    345 {
    346 }
    347 
    348 bool InputType::shouldSubmitImplicitly(Event* event)
    349 {
    350     return event->isKeyboardEvent() && event->type() == eventNames().keypressEvent && static_cast<KeyboardEvent*>(event)->charCode() == '\r';
    351 }
    352 
    353 PassRefPtr<HTMLFormElement> InputType::formForSubmission() const
    354 {
    355     return element()->form();
    356 }
    357 
    358 RenderObject* InputType::createRenderer(RenderArena*, RenderStyle* style) const
    359 {
    360     return RenderObject::createObject(element(), style);
    361 }
    362 
    363 void InputType::createShadowSubtree()
    364 {
    365 }
    366 
    367 void InputType::destroyShadowSubtree()
    368 {
    369     element()->removeShadowRoot();
    370 }
    371 
    372 double InputType::parseToDouble(const String&, double defaultValue) const
    373 {
    374     return defaultValue;
    375 }
    376 
    377 double InputType::parseToDoubleWithDecimalPlaces(const String& src, double defaultValue, unsigned *decimalPlaces) const
    378 {
    379     if (decimalPlaces)
    380         *decimalPlaces = 0;
    381     return parseToDouble(src, defaultValue);
    382 }
    383 
    384 bool InputType::parseToDateComponents(const String&, DateComponents*) const
    385 {
    386     ASSERT_NOT_REACHED();
    387     return false;
    388 }
    389 
    390 String InputType::serialize(double) const
    391 {
    392     ASSERT_NOT_REACHED();
    393     return String();
    394 }
    395 
    396 void InputType::dispatchSimulatedClickIfActive(KeyboardEvent* event) const
    397 {
    398     if (element()->active())
    399         element()->dispatchSimulatedClick(event);
    400     event->setDefaultHandled();
    401 }
    402 
    403 bool InputType::canSetStringValue() const
    404 {
    405     return true;
    406 }
    407 
    408 bool InputType::isKeyboardFocusable() const
    409 {
    410     return true;
    411 }
    412 
    413 bool InputType::shouldUseInputMethod() const
    414 {
    415     return false;
    416 }
    417 
    418 void InputType::handleBlurEvent()
    419 {
    420 }
    421 
    422 void InputType::accessKeyAction(bool)
    423 {
    424     element()->focus(false);
    425 }
    426 
    427 void InputType::attach()
    428 {
    429 }
    430 
    431 void InputType::altAttributeChanged()
    432 {
    433 }
    434 
    435 void InputType::srcAttributeChanged()
    436 {
    437 }
    438 
    439 void InputType::valueChanged()
    440 {
    441 }
    442 
    443 void InputType::willMoveToNewOwnerDocument()
    444 {
    445 }
    446 
    447 bool InputType::shouldRespectAlignAttribute()
    448 {
    449     return false;
    450 }
    451 
    452 bool InputType::canChangeFromAnotherType() const
    453 {
    454     return true;
    455 }
    456 
    457 void InputType::minOrMaxAttributeChanged()
    458 {
    459 }
    460 
    461 bool InputType::canBeSuccessfulSubmitButton()
    462 {
    463     return false;
    464 }
    465 
    466 bool InputType::rendererIsNeeded()
    467 {
    468     return true;
    469 }
    470 
    471 FileList* InputType::files()
    472 {
    473     return 0;
    474 }
    475 
    476 bool InputType::getTypeSpecificValue(String&)
    477 {
    478     return false;
    479 }
    480 
    481 String InputType::fallbackValue()
    482 {
    483     return String();
    484 }
    485 
    486 String InputType::defaultValue()
    487 {
    488     return String();
    489 }
    490 
    491 bool InputType::canSetSuggestedValue()
    492 {
    493     return false;
    494 }
    495 
    496 bool InputType::shouldSendChangeEventAfterCheckedChanged()
    497 {
    498     return true;
    499 }
    500 
    501 bool InputType::storesValueSeparateFromAttribute()
    502 {
    503     return true;
    504 }
    505 
    506 bool InputType::canSetValue(const String&)
    507 {
    508     return true;
    509 }
    510 
    511 PassOwnPtr<ClickHandlingState> InputType::willDispatchClick()
    512 {
    513     return PassOwnPtr<ClickHandlingState>();
    514 }
    515 
    516 void InputType::didDispatchClick(Event*, const ClickHandlingState&)
    517 {
    518 }
    519 
    520 String InputType::visibleValue() const
    521 {
    522     return element()->value();
    523 }
    524 
    525 String InputType::convertFromVisibleValue(const String& visibleValue) const
    526 {
    527     return visibleValue;
    528 }
    529 
    530 bool InputType::isAcceptableValue(const String&)
    531 {
    532     return true;
    533 }
    534 
    535 String InputType::sanitizeValue(const String& proposedValue)
    536 {
    537     return proposedValue;
    538 }
    539 
    540 bool InputType::hasUnacceptableValue()
    541 {
    542     return false;
    543 }
    544 
    545 void InputType::setFileList(const Vector<String>&)
    546 {
    547     ASSERT_NOT_REACHED();
    548 }
    549 
    550 bool InputType::shouldResetOnDocumentActivation()
    551 {
    552     return false;
    553 }
    554 
    555 bool InputType::shouldRespectListAttribute()
    556 {
    557     return false;
    558 }
    559 
    560 bool InputType::shouldRespectSpeechAttribute()
    561 {
    562     return false;
    563 }
    564 
    565 bool InputType::isTextButton() const
    566 {
    567     return false;
    568 }
    569 
    570 bool InputType::isRadioButton() const
    571 {
    572     return false;
    573 }
    574 
    575 bool InputType::isSearchField() const
    576 {
    577     return false;
    578 }
    579 
    580 bool InputType::isHiddenType() const
    581 {
    582     return false;
    583 }
    584 
    585 bool InputType::isPasswordField() const
    586 {
    587     return false;
    588 }
    589 
    590 bool InputType::isCheckbox() const
    591 {
    592     return false;
    593 }
    594 
    595 bool InputType::isEmailField() const
    596 {
    597     return false;
    598 }
    599 
    600 bool InputType::isFileUpload() const
    601 {
    602     return false;
    603 }
    604 
    605 bool InputType::isImageButton() const
    606 {
    607     return false;
    608 }
    609 
    610 bool InputType::isNumberField() const
    611 {
    612     return false;
    613 }
    614 
    615 bool InputType::isSubmitButton() const
    616 {
    617     return false;
    618 }
    619 
    620 bool InputType::isTelephoneField() const
    621 {
    622     return false;
    623 }
    624 
    625 bool InputType::isURLField() const
    626 {
    627     return false;
    628 }
    629 
    630 bool InputType::isEnumeratable()
    631 {
    632     return true;
    633 }
    634 
    635 bool InputType::isCheckable()
    636 {
    637     return false;
    638 }
    639 
    640 bool InputType::hasSpinButton()
    641 {
    642     return false;
    643 }
    644 
    645 bool InputType::shouldRespectHeightAndWidthAttributes()
    646 {
    647     return false;
    648 }
    649 
    650 namespace InputTypeNames {
    651 
    652 // The type names must be lowercased because they will be the return values of
    653 // input.type and input.type must be lowercase according to DOM Level 2.
    654 
    655 const AtomicString& button()
    656 {
    657     DEFINE_STATIC_LOCAL(AtomicString, name, ("button"));
    658     return name;
    659 }
    660 
    661 const AtomicString& checkbox()
    662 {
    663     DEFINE_STATIC_LOCAL(AtomicString, name, ("checkbox"));
    664     return name;
    665 }
    666 
    667 const AtomicString& color()
    668 {
    669     DEFINE_STATIC_LOCAL(AtomicString, name, ("color"));
    670     return name;
    671 }
    672 
    673 const AtomicString& date()
    674 {
    675     DEFINE_STATIC_LOCAL(AtomicString, name, ("date"));
    676     return name;
    677 }
    678 
    679 const AtomicString& datetime()
    680 {
    681     DEFINE_STATIC_LOCAL(AtomicString, name, ("datetime"));
    682     return name;
    683 }
    684 
    685 const AtomicString& datetimelocal()
    686 {
    687     DEFINE_STATIC_LOCAL(AtomicString, name, ("datetime-local"));
    688     return name;
    689 }
    690 
    691 const AtomicString& email()
    692 {
    693     DEFINE_STATIC_LOCAL(AtomicString, name, ("email"));
    694     return name;
    695 }
    696 
    697 const AtomicString& file()
    698 {
    699     DEFINE_STATIC_LOCAL(AtomicString, name, ("file"));
    700     return name;
    701 }
    702 
    703 const AtomicString& hidden()
    704 {
    705     DEFINE_STATIC_LOCAL(AtomicString, name, ("hidden"));
    706     return name;
    707 }
    708 
    709 const AtomicString& image()
    710 {
    711     DEFINE_STATIC_LOCAL(AtomicString, name, ("image"));
    712     return name;
    713 }
    714 
    715 const AtomicString& isindex()
    716 {
    717     DEFINE_STATIC_LOCAL(AtomicString, name, ("khtml_isindex"));
    718     return name;
    719 }
    720 
    721 const AtomicString& month()
    722 {
    723     DEFINE_STATIC_LOCAL(AtomicString, name, ("month"));
    724     return name;
    725 }
    726 
    727 const AtomicString& number()
    728 {
    729     DEFINE_STATIC_LOCAL(AtomicString, name, ("number"));
    730     return name;
    731 }
    732 
    733 const AtomicString& password()
    734 {
    735     DEFINE_STATIC_LOCAL(AtomicString, name, ("password"));
    736     return name;
    737 }
    738 
    739 const AtomicString& radio()
    740 {
    741     DEFINE_STATIC_LOCAL(AtomicString, name, ("radio"));
    742     return name;
    743 }
    744 
    745 const AtomicString& range()
    746 {
    747     DEFINE_STATIC_LOCAL(AtomicString, name, ("range"));
    748     return name;
    749 }
    750 
    751 const AtomicString& reset()
    752 {
    753     DEFINE_STATIC_LOCAL(AtomicString, name, ("reset"));
    754     return name;
    755 }
    756 
    757 const AtomicString& search()
    758 {
    759     DEFINE_STATIC_LOCAL(AtomicString, name, ("search"));
    760     return name;
    761 }
    762 
    763 const AtomicString& submit()
    764 {
    765     DEFINE_STATIC_LOCAL(AtomicString, name, ("submit"));
    766     return name;
    767 }
    768 
    769 const AtomicString& telephone()
    770 {
    771     DEFINE_STATIC_LOCAL(AtomicString, name, ("tel"));
    772     return name;
    773 }
    774 
    775 const AtomicString& text()
    776 {
    777     DEFINE_STATIC_LOCAL(AtomicString, name, ("text"));
    778     return name;
    779 }
    780 
    781 const AtomicString& time()
    782 {
    783     DEFINE_STATIC_LOCAL(AtomicString, name, ("time"));
    784     return name;
    785 }
    786 
    787 const AtomicString& url()
    788 {
    789     DEFINE_STATIC_LOCAL(AtomicString, name, ("url"));
    790     return name;
    791 }
    792 
    793 const AtomicString& week()
    794 {
    795     DEFINE_STATIC_LOCAL(AtomicString, name, ("week"));
    796     return name;
    797 }
    798 
    799 } // namespace WebCore::InputTypeNames
    800 
    801 } // namespace WebCore
    802