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"
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 "SubmitInputType.h"
59 #include "TelephoneInputType.h"
60 #include "TextInputType.h"
61 #include "TimeInputType.h"
62 #include "URLInputType.h"
63 #include "WeekInputType.h"
65 #include <wtf/Assertions.h>
66 #include <wtf/HashMap.h>
67 #include <wtf/text/StringHash.h>
73 typedef PassOwnPtr<InputType> (*InputTypeFactoryFunction)(HTMLInputElement*);
74 typedef HashMap<String, InputTypeFactoryFunction, CaseFoldingHash> InputTypeFactoryMap;
76 static PassOwnPtr<InputTypeFactoryMap> createInputTypeFactoryMap()
78 OwnPtr<InputTypeFactoryMap> map = adoptPtr(new InputTypeFactoryMap);
79 map->add(InputTypeNames::button(), ButtonInputType::create);
80 map->add(InputTypeNames::checkbox(), CheckboxInputType::create);
81 map->add(InputTypeNames::color(), ColorInputType::create);
82 map->add(InputTypeNames::date(), DateInputType::create);
83 map->add(InputTypeNames::datetime(), DateTimeInputType::create);
84 map->add(InputTypeNames::datetimelocal(), DateTimeLocalInputType::create);
85 map->add(InputTypeNames::email(), EmailInputType::create);
86 map->add(InputTypeNames::file(), FileInputType::create);
87 map->add(InputTypeNames::hidden(), HiddenInputType::create);
88 map->add(InputTypeNames::image(), ImageInputType::create);
89 map->add(InputTypeNames::isindex(), IsIndexInputType::create);
90 map->add(InputTypeNames::month(), MonthInputType::create);
91 map->add(InputTypeNames::number(), NumberInputType::create);
92 map->add(InputTypeNames::password(), PasswordInputType::create);
93 map->add(InputTypeNames::radio(), RadioInputType::create);
94 map->add(InputTypeNames::range(), RangeInputType::create);
95 map->add(InputTypeNames::reset(), ResetInputType::create);
96 map->add(InputTypeNames::search(), SearchInputType::create);
97 map->add(InputTypeNames::submit(), SubmitInputType::create);
98 map->add(InputTypeNames::telephone(), TelephoneInputType::create);
99 map->add(InputTypeNames::time(), TimeInputType::create);
100 map->add(InputTypeNames::url(), URLInputType::create);
101 map->add(InputTypeNames::week(), WeekInputType::create);
102 // No need to register "text" because it is the default type.
103 return map.release();
106 PassOwnPtr<InputType> InputType::create(HTMLInputElement* element, const String& typeName)
108 static const InputTypeFactoryMap* factoryMap = createInputTypeFactoryMap().leakPtr();
109 PassOwnPtr<InputType> (*factory)(HTMLInputElement*) = typeName.isEmpty() ? 0 : factoryMap->get(typeName);
111 factory = TextInputType::create;
112 return factory(element);
115 PassOwnPtr<InputType> InputType::createText(HTMLInputElement* element)
117 return TextInputType::create(element);
120 InputType::~InputType()
124 bool InputType::isTextField() const
129 bool InputType::isTextType() const
134 bool InputType::isRangeControl() const
139 bool InputType::saveFormControlState(String& result) const
141 String currentValue = element()->value();
142 if (currentValue == element()->defaultValue())
144 result = currentValue;
148 void InputType::restoreFormControlState(const String& state) const
150 element()->setValue(state);
153 bool InputType::isFormDataAppendable() const
155 // There is no form data unless there's a name for non-image types.
156 return !element()->name().isEmpty();
159 bool InputType::appendFormData(FormDataList& encoding, bool) const
161 // Always successful.
162 encoding.appendData(element()->name(), element()->value());
166 double InputType::valueAsDate() const
168 return DateComponents::invalidMilliseconds();
171 void InputType::setValueAsDate(double, ExceptionCode& ec) const
173 ec = INVALID_STATE_ERR;
176 double InputType::valueAsNumber() const
178 return numeric_limits<double>::quiet_NaN();
181 void InputType::setValueAsNumber(double, ExceptionCode& ec) const
183 ec = INVALID_STATE_ERR;
186 bool InputType::supportsValidation() const
191 bool InputType::typeMismatchFor(const String&) const
196 bool InputType::typeMismatch() const
201 bool InputType::supportsRequired() const
203 // Almost all validatable types support @required.
204 return supportsValidation();
207 bool InputType::valueMissing(const String&) const
212 bool InputType::patternMismatch(const String&) const
217 bool InputType::rangeUnderflow(const String&) const
222 bool InputType::rangeOverflow(const String&) const
227 bool InputType::supportsRangeLimitation() const
232 double InputType::defaultValueForStepUp() const
237 double InputType::minimum() const
239 ASSERT_NOT_REACHED();
243 double InputType::maximum() const
245 ASSERT_NOT_REACHED();
249 bool InputType::stepMismatch(const String&, double) const
251 // Non-supported types should be rejected by HTMLInputElement::getAllowedValueStep().
252 ASSERT_NOT_REACHED();
256 double InputType::stepBase() const
258 ASSERT_NOT_REACHED();
262 double InputType::stepBaseWithDecimalPlaces(unsigned* decimalPlaces) const
269 double InputType::defaultStep() const
271 return numeric_limits<double>::quiet_NaN();
274 double InputType::stepScaleFactor() const
276 return numeric_limits<double>::quiet_NaN();
279 bool InputType::parsedStepValueShouldBeInteger() const
284 bool InputType::scaledStepValueShouldBeInteger() const
289 double InputType::acceptableError(double) const
294 String InputType::typeMismatchText() const
296 return validationMessageTypeMismatchText();
299 String InputType::valueMissingText() const
301 return validationMessageValueMissingText();
304 void InputType::handleClickEvent(MouseEvent*)
308 void InputType::handleDOMActivateEvent(Event*)
312 void InputType::handleKeydownEvent(KeyboardEvent*)
316 void InputType::handleKeypressEvent(KeyboardEvent*)
320 void InputType::handleKeyupEvent(KeyboardEvent*)
324 void InputType::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent* event)
326 element()->handleBeforeTextInsertedEvent(event);
329 void InputType::handleWheelEvent(WheelEvent*)
333 void InputType::forwardEvent(Event*)
337 bool InputType::shouldSubmitImplicitly(Event* event)
339 return event->isKeyboardEvent() && event->type() == eventNames().keypressEvent && static_cast<KeyboardEvent*>(event)->charCode() == '\r';
342 PassRefPtr<HTMLFormElement> InputType::formForSubmission() const
344 return element()->form();
347 RenderObject* InputType::createRenderer(RenderArena*, RenderStyle* style) const
349 return RenderObject::createObject(element(), style);
352 double InputType::parseToDouble(const String&, double defaultValue) const
357 double InputType::parseToDoubleWithDecimalPlaces(const String& src, double defaultValue, unsigned *decimalPlaces) const
361 return parseToDouble(src, defaultValue);
364 bool InputType::parseToDateComponents(const String&, DateComponents*) const
366 ASSERT_NOT_REACHED();
370 String InputType::serialize(double) const
372 ASSERT_NOT_REACHED();
376 void InputType::dispatchSimulatedClickIfActive(KeyboardEvent* event) const
378 if (element()->active())
379 element()->dispatchSimulatedClick(event);
380 event->setDefaultHandled();
383 bool InputType::canSetStringValue() const
388 bool InputType::isKeyboardFocusable() const
393 bool InputType::shouldUseInputMethod() const
398 void InputType::handleBlurEvent()
402 void InputType::accessKeyAction(bool)
404 element()->focus(false);
407 void InputType::attach()
411 void InputType::altAttributeChanged()
415 void InputType::srcAttributeChanged()
419 void InputType::willMoveToNewOwnerDocument()
423 bool InputType::shouldRespectAlignAttribute()
428 bool InputType::canChangeFromAnotherType() const
433 void InputType::minOrMaxAttributeChanged()
437 bool InputType::canBeSuccessfulSubmitButton()
442 bool InputType::rendererIsNeeded()
447 FileList* InputType::files()
452 bool InputType::getTypeSpecificValue(String&)
457 String InputType::fallbackValue()
462 String InputType::defaultValue()
467 bool InputType::canSetSuggestedValue()
472 bool InputType::shouldSendChangeEventAfterCheckedChanged()
477 bool InputType::storesValueSeparateFromAttribute()
482 bool InputType::canSetValue(const String&)
487 PassOwnPtr<ClickHandlingState> InputType::willDispatchClick()
489 return PassOwnPtr<ClickHandlingState>();
492 void InputType::didDispatchClick(Event*, const ClickHandlingState&)
496 bool InputType::isAcceptableValue(const String&)
501 String InputType::sanitizeValue(const String& proposedValue)
503 return proposedValue;
506 bool InputType::hasUnacceptableValue()
511 void InputType::setFileList(const Vector<String>&)
513 ASSERT_NOT_REACHED();
516 bool InputType::shouldResetOnDocumentActivation()
521 bool InputType::shouldRespectListAttribute()
526 bool InputType::shouldRespectSpeechAttribute()
531 bool InputType::isTextButton() const
536 bool InputType::isRadioButton() const
541 bool InputType::isSearchField() const
546 bool InputType::isHiddenType() const
551 bool InputType::isPasswordField() const
556 bool InputType::isCheckbox() const
561 bool InputType::isEmailField() const
566 bool InputType::isFileUpload() const
571 bool InputType::isImageButton() const
576 bool InputType::isNumberField() const
581 bool InputType::isSubmitButton() const
586 bool InputType::isTelephoneField() const
591 bool InputType::isURLField() const
596 bool InputType::isEnumeratable()
601 bool InputType::isCheckable()
606 bool InputType::hasSpinButton()
611 bool InputType::shouldRespectHeightAndWidthAttributes()
616 namespace InputTypeNames {
618 // The type names must be lowercased because they will be the return values of
619 // input.type and input.type must be lowercase according to DOM Level 2.
621 const AtomicString& button()
623 DEFINE_STATIC_LOCAL(AtomicString, name, ("button"));
627 const AtomicString& checkbox()
629 DEFINE_STATIC_LOCAL(AtomicString, name, ("checkbox"));
633 const AtomicString& color()
635 DEFINE_STATIC_LOCAL(AtomicString, name, ("color"));
639 const AtomicString& date()
641 DEFINE_STATIC_LOCAL(AtomicString, name, ("date"));
645 const AtomicString& datetime()
647 DEFINE_STATIC_LOCAL(AtomicString, name, ("datetime"));
651 const AtomicString& datetimelocal()
653 DEFINE_STATIC_LOCAL(AtomicString, name, ("datetime-local"));
657 const AtomicString& email()
659 DEFINE_STATIC_LOCAL(AtomicString, name, ("email"));
663 const AtomicString& file()
665 DEFINE_STATIC_LOCAL(AtomicString, name, ("file"));
669 const AtomicString& hidden()
671 DEFINE_STATIC_LOCAL(AtomicString, name, ("hidden"));
675 const AtomicString& image()
677 DEFINE_STATIC_LOCAL(AtomicString, name, ("image"));
681 const AtomicString& isindex()
683 DEFINE_STATIC_LOCAL(AtomicString, name, ("khtml_isindex"));
687 const AtomicString& month()
689 DEFINE_STATIC_LOCAL(AtomicString, name, ("month"));
693 const AtomicString& number()
695 DEFINE_STATIC_LOCAL(AtomicString, name, ("number"));
699 const AtomicString& password()
701 DEFINE_STATIC_LOCAL(AtomicString, name, ("password"));
705 const AtomicString& radio()
707 DEFINE_STATIC_LOCAL(AtomicString, name, ("radio"));
711 const AtomicString& range()
713 DEFINE_STATIC_LOCAL(AtomicString, name, ("range"));
717 const AtomicString& reset()
719 DEFINE_STATIC_LOCAL(AtomicString, name, ("reset"));
723 const AtomicString& search()
725 DEFINE_STATIC_LOCAL(AtomicString, name, ("search"));
729 const AtomicString& submit()
731 DEFINE_STATIC_LOCAL(AtomicString, name, ("submit"));
735 const AtomicString& telephone()
737 DEFINE_STATIC_LOCAL(AtomicString, name, ("tel"));
741 const AtomicString& text()
743 DEFINE_STATIC_LOCAL(AtomicString, name, ("text"));
747 const AtomicString& time()
749 DEFINE_STATIC_LOCAL(AtomicString, name, ("time"));
753 const AtomicString& url()
755 DEFINE_STATIC_LOCAL(AtomicString, name, ("url"));
759 const AtomicString& week()
761 DEFINE_STATIC_LOCAL(AtomicString, name, ("week"));
765 } // namespace WebCore::InputTypeNames
767 } // namespace WebCore