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) 2010 Google Inc. All rights reserved.
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.
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.
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.
28 #include "InputType.h"
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"
52 #include "PasswordInputType.h"
53 #include "RadioInputType.h"
54 #include "RangeInputType.h"
55 #include "RegularExpression.h"
56 #include "RenderObject.h"
57 #include "ResetInputType.h"
58 #include "SearchInputType.h"
59 #include "ShadowRoot.h"
60 #include "SubmitInputType.h"
61 #include "TelephoneInputType.h"
62 #include "TextInputType.h"
63 #include "TimeInputType.h"
64 #include "URLInputType.h"
65 #include "WeekInputType.h"
67 #include <wtf/Assertions.h>
68 #include <wtf/HashMap.h>
69 #include <wtf/text/StringHash.h>
75 typedef PassOwnPtr<InputType> (*InputTypeFactoryFunction)(HTMLInputElement*);
76 typedef HashMap<String, InputTypeFactoryFunction, CaseFoldingHash> InputTypeFactoryMap;
78 static PassOwnPtr<InputTypeFactoryMap> createInputTypeFactoryMap()
80 OwnPtr<InputTypeFactoryMap> map = adoptPtr(new InputTypeFactoryMap);
81 map->add(InputTypeNames::button(), ButtonInputType::create);
82 map->add(InputTypeNames::checkbox(), CheckboxInputType::create);
83 #if ENABLE(INPUT_COLOR)
84 map->add(InputTypeNames::color(), ColorInputType::create);
86 map->add(InputTypeNames::date(), DateInputType::create);
87 map->add(InputTypeNames::datetime(), DateTimeInputType::create);
88 map->add(InputTypeNames::datetimelocal(), DateTimeLocalInputType::create);
89 map->add(InputTypeNames::email(), EmailInputType::create);
90 map->add(InputTypeNames::file(), FileInputType::create);
91 map->add(InputTypeNames::hidden(), HiddenInputType::create);
92 map->add(InputTypeNames::image(), ImageInputType::create);
93 map->add(InputTypeNames::isindex(), IsIndexInputType::create);
94 map->add(InputTypeNames::month(), MonthInputType::create);
95 map->add(InputTypeNames::number(), NumberInputType::create);
96 map->add(InputTypeNames::password(), PasswordInputType::create);
97 map->add(InputTypeNames::radio(), RadioInputType::create);
98 map->add(InputTypeNames::range(), RangeInputType::create);
99 map->add(InputTypeNames::reset(), ResetInputType::create);
100 map->add(InputTypeNames::search(), SearchInputType::create);
101 map->add(InputTypeNames::submit(), SubmitInputType::create);
102 map->add(InputTypeNames::telephone(), TelephoneInputType::create);
103 map->add(InputTypeNames::time(), TimeInputType::create);
104 map->add(InputTypeNames::url(), URLInputType::create);
105 map->add(InputTypeNames::week(), WeekInputType::create);
106 // No need to register "text" because it is the default type.
107 return map.release();
110 PassOwnPtr<InputType> InputType::create(HTMLInputElement* element, const String& typeName)
112 static const InputTypeFactoryMap* factoryMap = createInputTypeFactoryMap().leakPtr();
113 PassOwnPtr<InputType> (*factory)(HTMLInputElement*) = typeName.isEmpty() ? 0 : factoryMap->get(typeName);
115 factory = TextInputType::create;
116 return factory(element);
119 PassOwnPtr<InputType> InputType::createText(HTMLInputElement* element)
121 return TextInputType::create(element);
124 InputType::~InputType()
128 bool InputType::isTextField() const
133 bool InputType::isTextType() const
138 bool InputType::isRangeControl() const
143 bool InputType::saveFormControlState(String& result) const
145 String currentValue = element()->value();
146 if (currentValue == element()->defaultValue())
148 result = currentValue;
152 void InputType::restoreFormControlState(const String& state) const
154 element()->setValue(state);
157 bool InputType::isFormDataAppendable() const
159 // There is no form data unless there's a name for non-image types.
160 return !element()->name().isEmpty();
163 bool InputType::appendFormData(FormDataList& encoding, bool) const
165 // Always successful.
166 encoding.appendData(element()->name(), element()->value());
170 double InputType::valueAsDate() const
172 return DateComponents::invalidMilliseconds();
175 void InputType::setValueAsDate(double, ExceptionCode& ec) const
177 ec = INVALID_STATE_ERR;
180 double InputType::valueAsNumber() const
182 return numeric_limits<double>::quiet_NaN();
185 void InputType::setValueAsNumber(double, bool, ExceptionCode& ec) const
187 ec = INVALID_STATE_ERR;
190 bool InputType::supportsValidation() const
195 bool InputType::typeMismatchFor(const String&) const
200 bool InputType::typeMismatch() const
205 bool InputType::supportsRequired() const
207 // Almost all validatable types support @required.
208 return supportsValidation();
211 bool InputType::valueMissing(const String&) const
216 bool InputType::patternMismatch(const String&) const
221 bool InputType::rangeUnderflow(const String&) const
226 bool InputType::rangeOverflow(const String&) const
231 bool InputType::supportsRangeLimitation() const
236 double InputType::defaultValueForStepUp() const
241 double InputType::minimum() const
243 ASSERT_NOT_REACHED();
247 double InputType::maximum() const
249 ASSERT_NOT_REACHED();
253 bool InputType::sizeShouldIncludeDecoration(int, int& preferredSize) const
255 preferredSize = element()->size();
259 bool InputType::stepMismatch(const String&, double) const
261 // Non-supported types should be rejected by HTMLInputElement::getAllowedValueStep().
262 ASSERT_NOT_REACHED();
266 double InputType::stepBase() const
268 ASSERT_NOT_REACHED();
272 double InputType::stepBaseWithDecimalPlaces(unsigned* decimalPlaces) const
279 double InputType::defaultStep() const
281 return numeric_limits<double>::quiet_NaN();
284 double InputType::stepScaleFactor() const
286 return numeric_limits<double>::quiet_NaN();
289 bool InputType::parsedStepValueShouldBeInteger() const
294 bool InputType::scaledStepValueShouldBeInteger() const
299 double InputType::acceptableError(double) const
304 String InputType::typeMismatchText() const
306 return validationMessageTypeMismatchText();
309 String InputType::valueMissingText() const
311 return validationMessageValueMissingText();
314 void InputType::handleClickEvent(MouseEvent*)
318 void InputType::handleMouseDownEvent(MouseEvent*)
322 void InputType::handleDOMActivateEvent(Event*)
326 void InputType::handleKeydownEvent(KeyboardEvent*)
330 void InputType::handleKeypressEvent(KeyboardEvent*)
334 void InputType::handleKeyupEvent(KeyboardEvent*)
338 void InputType::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent*)
342 void InputType::handleWheelEvent(WheelEvent*)
346 void InputType::forwardEvent(Event*)
350 bool InputType::shouldSubmitImplicitly(Event* event)
352 return event->isKeyboardEvent() && event->type() == eventNames().keypressEvent && static_cast<KeyboardEvent*>(event)->charCode() == '\r';
355 PassRefPtr<HTMLFormElement> InputType::formForSubmission() const
357 return element()->form();
360 RenderObject* InputType::createRenderer(RenderArena*, RenderStyle* style) const
362 return RenderObject::createObject(element(), style);
365 void InputType::createShadowSubtree()
369 void InputType::destroyShadowSubtree()
371 element()->removeShadowRoot();
374 double InputType::parseToDouble(const String&, double defaultValue) const
379 double InputType::parseToDoubleWithDecimalPlaces(const String& src, double defaultValue, unsigned *decimalPlaces) const
383 return parseToDouble(src, defaultValue);
386 bool InputType::parseToDateComponents(const String&, DateComponents*) const
388 ASSERT_NOT_REACHED();
392 String InputType::serialize(double) const
394 ASSERT_NOT_REACHED();
398 void InputType::dispatchSimulatedClickIfActive(KeyboardEvent* event) const
400 if (element()->active())
401 element()->dispatchSimulatedClick(event);
402 event->setDefaultHandled();
405 Chrome* InputType::chrome() const
407 if (Page* page = element()->document()->page())
408 return page->chrome();
412 bool InputType::canSetStringValue() const
417 bool InputType::isKeyboardFocusable() const
422 bool InputType::shouldUseInputMethod() const
427 void InputType::willBlur()
431 void InputType::accessKeyAction(bool)
433 element()->focus(false);
436 void InputType::attach()
440 void InputType::detach()
444 void InputType::altAttributeChanged()
448 void InputType::srcAttributeChanged()
452 void InputType::willMoveToNewOwnerDocument()
456 bool InputType::shouldRespectAlignAttribute()
461 bool InputType::canChangeFromAnotherType() const
466 void InputType::minOrMaxAttributeChanged()
470 void InputType::stepAttributeChanged()
474 bool InputType::canBeSuccessfulSubmitButton()
479 HTMLElement* InputType::placeholderElement() const
484 bool InputType::rendererIsNeeded()
489 FileList* InputType::files()
494 bool InputType::getTypeSpecificValue(String&)
499 String InputType::fallbackValue()
504 String InputType::defaultValue()
509 bool InputType::canSetSuggestedValue()
514 bool InputType::shouldSendChangeEventAfterCheckedChanged()
519 bool InputType::storesValueSeparateFromAttribute()
524 void InputType::setValue(const String& sanitizedValue, bool, bool sendChangeEvent)
526 element()->setValueInternal(sanitizedValue, sendChangeEvent);
527 element()->setNeedsStyleRecalc();
530 void InputType::dispatchChangeEventInResponseToSetValue()
532 element()->dispatchFormControlChangeEvent();
535 bool InputType::canSetValue(const String&)
540 PassOwnPtr<ClickHandlingState> InputType::willDispatchClick()
545 void InputType::didDispatchClick(Event*, const ClickHandlingState&)
549 String InputType::visibleValue() const
551 return element()->value();
554 String InputType::convertFromVisibleValue(const String& visibleValue) const
559 bool InputType::isAcceptableValue(const String&)
564 String InputType::sanitizeValue(const String& proposedValue)
566 return proposedValue;
569 bool InputType::hasUnacceptableValue()
574 void InputType::receiveDroppedFiles(const Vector<String>&)
576 ASSERT_NOT_REACHED();
579 Icon* InputType::icon() const
581 ASSERT_NOT_REACHED();
585 bool InputType::shouldResetOnDocumentActivation()
590 bool InputType::shouldRespectListAttribute()
595 bool InputType::shouldRespectSpeechAttribute()
600 bool InputType::isTextButton() const
605 bool InputType::isRadioButton() const
610 bool InputType::isSearchField() const
615 bool InputType::isHiddenType() const
620 bool InputType::isPasswordField() const
625 bool InputType::isCheckbox() const
630 bool InputType::isEmailField() const
635 bool InputType::isFileUpload() const
640 bool InputType::isImageButton() const
645 bool InputType::isNumberField() const
650 bool InputType::isSubmitButton() const
655 bool InputType::isTelephoneField() const
660 bool InputType::isURLField() const
665 bool InputType::isEnumeratable()
670 bool InputType::isCheckable()
675 bool InputType::isSteppable() const
680 #if ENABLE(INPUT_COLOR)
681 bool InputType::isColorControl() const
687 bool InputType::shouldRespectHeightAndWidthAttributes()
692 bool InputType::supportsPlaceholder() const
697 void InputType::updatePlaceholderText()
701 void InputType::multipleAttributeChanged()
705 void InputType::disabledAttributeChanged()
709 void InputType::readonlyAttributeChanged()
713 namespace InputTypeNames {
715 // The type names must be lowercased because they will be the return values of
716 // input.type and input.type must be lowercase according to DOM Level 2.
718 const AtomicString& button()
720 DEFINE_STATIC_LOCAL(AtomicString, name, ("button"));
724 const AtomicString& checkbox()
726 DEFINE_STATIC_LOCAL(AtomicString, name, ("checkbox"));
730 #if ENABLE(INPUT_COLOR)
731 const AtomicString& color()
733 DEFINE_STATIC_LOCAL(AtomicString, name, ("color"));
738 const AtomicString& date()
740 DEFINE_STATIC_LOCAL(AtomicString, name, ("date"));
744 const AtomicString& datetime()
746 DEFINE_STATIC_LOCAL(AtomicString, name, ("datetime"));
750 const AtomicString& datetimelocal()
752 DEFINE_STATIC_LOCAL(AtomicString, name, ("datetime-local"));
756 const AtomicString& email()
758 DEFINE_STATIC_LOCAL(AtomicString, name, ("email"));
762 const AtomicString& file()
764 DEFINE_STATIC_LOCAL(AtomicString, name, ("file"));
768 const AtomicString& hidden()
770 DEFINE_STATIC_LOCAL(AtomicString, name, ("hidden"));
774 const AtomicString& image()
776 DEFINE_STATIC_LOCAL(AtomicString, name, ("image"));
780 const AtomicString& isindex()
782 DEFINE_STATIC_LOCAL(AtomicString, name, ("khtml_isindex"));
786 const AtomicString& month()
788 DEFINE_STATIC_LOCAL(AtomicString, name, ("month"));
792 const AtomicString& number()
794 DEFINE_STATIC_LOCAL(AtomicString, name, ("number"));
798 const AtomicString& password()
800 DEFINE_STATIC_LOCAL(AtomicString, name, ("password"));
804 const AtomicString& radio()
806 DEFINE_STATIC_LOCAL(AtomicString, name, ("radio"));
810 const AtomicString& range()
812 DEFINE_STATIC_LOCAL(AtomicString, name, ("range"));
816 const AtomicString& reset()
818 DEFINE_STATIC_LOCAL(AtomicString, name, ("reset"));
822 const AtomicString& search()
824 DEFINE_STATIC_LOCAL(AtomicString, name, ("search"));
828 const AtomicString& submit()
830 DEFINE_STATIC_LOCAL(AtomicString, name, ("submit"));
834 const AtomicString& telephone()
836 DEFINE_STATIC_LOCAL(AtomicString, name, ("tel"));
840 const AtomicString& text()
842 DEFINE_STATIC_LOCAL(AtomicString, name, ("text"));
846 const AtomicString& time()
848 DEFINE_STATIC_LOCAL(AtomicString, name, ("time"));
852 const AtomicString& url()
854 DEFINE_STATIC_LOCAL(AtomicString, name, ("url"));
858 const AtomicString& week()
860 DEFINE_STATIC_LOCAL(AtomicString, name, ("week"));
864 } // namespace WebCore::InputTypeNames
866 } // namespace WebCore