• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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) 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 
createInputTypeFactoryMap()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 
create(HTMLInputElement * element,const String & typeName)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 
createText(HTMLInputElement * element)116 PassOwnPtr<InputType> InputType::createText(HTMLInputElement* element)
117 {
118     return TextInputType::create(element);
119 }
120 
~InputType()121 InputType::~InputType()
122 {
123 }
124 
isTextField() const125 bool InputType::isTextField() const
126 {
127     return false;
128 }
129 
isTextType() const130 bool InputType::isTextType() const
131 {
132     return false;
133 }
134 
isRangeControl() const135 bool InputType::isRangeControl() const
136 {
137     return false;
138 }
139 
saveFormControlState(String & result) const140 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 
restoreFormControlState(const String & state) const149 void InputType::restoreFormControlState(const String& state) const
150 {
151     element()->setValue(state);
152 }
153 
isFormDataAppendable() const154 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 
appendFormData(FormDataList & encoding,bool) const160 bool InputType::appendFormData(FormDataList& encoding, bool) const
161 {
162     // Always successful.
163     encoding.appendData(element()->name(), element()->value());
164     return true;
165 }
166 
valueAsDate() const167 double InputType::valueAsDate() const
168 {
169     return DateComponents::invalidMilliseconds();
170 }
171 
setValueAsDate(double,ExceptionCode & ec) const172 void InputType::setValueAsDate(double, ExceptionCode& ec) const
173 {
174     ec = INVALID_STATE_ERR;
175 }
176 
valueAsNumber() const177 double InputType::valueAsNumber() const
178 {
179     return numeric_limits<double>::quiet_NaN();
180 }
181 
setValueAsNumber(double,ExceptionCode & ec) const182 void InputType::setValueAsNumber(double, ExceptionCode& ec) const
183 {
184     ec = INVALID_STATE_ERR;
185 }
186 
supportsValidation() const187 bool InputType::supportsValidation() const
188 {
189     return true;
190 }
191 
typeMismatchFor(const String &) const192 bool InputType::typeMismatchFor(const String&) const
193 {
194     return false;
195 }
196 
typeMismatch() const197 bool InputType::typeMismatch() const
198 {
199     return false;
200 }
201 
supportsRequired() const202 bool InputType::supportsRequired() const
203 {
204     // Almost all validatable types support @required.
205     return supportsValidation();
206 }
207 
valueMissing(const String &) const208 bool InputType::valueMissing(const String&) const
209 {
210     return false;
211 }
212 
patternMismatch(const String &) const213 bool InputType::patternMismatch(const String&) const
214 {
215     return false;
216 }
217 
rangeUnderflow(const String &) const218 bool InputType::rangeUnderflow(const String&) const
219 {
220     return false;
221 }
222 
rangeOverflow(const String &) const223 bool InputType::rangeOverflow(const String&) const
224 {
225     return false;
226 }
227 
supportsRangeLimitation() const228 bool InputType::supportsRangeLimitation() const
229 {
230     return false;
231 }
232 
defaultValueForStepUp() const233 double InputType::defaultValueForStepUp() const
234 {
235     return 0;
236 }
237 
minimum() const238 double InputType::minimum() const
239 {
240     ASSERT_NOT_REACHED();
241     return 0;
242 }
243 
maximum() const244 double InputType::maximum() const
245 {
246     ASSERT_NOT_REACHED();
247     return 0;
248 }
249 
stepMismatch(const String &,double) const250 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 
stepBase() const257 double InputType::stepBase() const
258 {
259     ASSERT_NOT_REACHED();
260     return 0;
261 }
262 
stepBaseWithDecimalPlaces(unsigned * decimalPlaces) const263 double InputType::stepBaseWithDecimalPlaces(unsigned* decimalPlaces) const
264 {
265     if (decimalPlaces)
266         *decimalPlaces = 0;
267     return stepBase();
268 }
269 
defaultStep() const270 double InputType::defaultStep() const
271 {
272     return numeric_limits<double>::quiet_NaN();
273 }
274 
stepScaleFactor() const275 double InputType::stepScaleFactor() const
276 {
277     return numeric_limits<double>::quiet_NaN();
278 }
279 
parsedStepValueShouldBeInteger() const280 bool InputType::parsedStepValueShouldBeInteger() const
281 {
282     return false;
283 }
284 
scaledStepValueShouldBeInteger() const285 bool InputType::scaledStepValueShouldBeInteger() const
286 {
287     return false;
288 }
289 
acceptableError(double) const290 double InputType::acceptableError(double) const
291 {
292     return 0;
293 }
294 
typeMismatchText() const295 String InputType::typeMismatchText() const
296 {
297     return validationMessageTypeMismatchText();
298 }
299 
valueMissingText() const300 String InputType::valueMissingText() const
301 {
302     return validationMessageValueMissingText();
303 }
304 
handleClickEvent(MouseEvent *)305 void InputType::handleClickEvent(MouseEvent*)
306 {
307 }
308 
handleMouseDownEvent(MouseEvent *)309 void InputType::handleMouseDownEvent(MouseEvent*)
310 {
311 }
312 
313 #if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
handleTouchStartEvent(TouchEvent *)314 void InputType::handleTouchStartEvent(TouchEvent*)
315 {
316 }
317 #endif
318 
handleDOMActivateEvent(Event *)319 void InputType::handleDOMActivateEvent(Event*)
320 {
321 }
322 
handleKeydownEvent(KeyboardEvent *)323 void InputType::handleKeydownEvent(KeyboardEvent*)
324 {
325 }
326 
handleKeypressEvent(KeyboardEvent *)327 void InputType::handleKeypressEvent(KeyboardEvent*)
328 {
329 }
330 
handleKeyupEvent(KeyboardEvent *)331 void InputType::handleKeyupEvent(KeyboardEvent*)
332 {
333 }
334 
handleBeforeTextInsertedEvent(BeforeTextInsertedEvent * event)335 void InputType::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent* event)
336 {
337     element()->handleBeforeTextInsertedEvent(event);
338 }
339 
handleWheelEvent(WheelEvent *)340 void InputType::handleWheelEvent(WheelEvent*)
341 {
342 }
343 
forwardEvent(Event *)344 void InputType::forwardEvent(Event*)
345 {
346 }
347 
shouldSubmitImplicitly(Event * event)348 bool InputType::shouldSubmitImplicitly(Event* event)
349 {
350     return event->isKeyboardEvent() && event->type() == eventNames().keypressEvent && static_cast<KeyboardEvent*>(event)->charCode() == '\r';
351 }
352 
formForSubmission() const353 PassRefPtr<HTMLFormElement> InputType::formForSubmission() const
354 {
355     return element()->form();
356 }
357 
createRenderer(RenderArena *,RenderStyle * style) const358 RenderObject* InputType::createRenderer(RenderArena*, RenderStyle* style) const
359 {
360     return RenderObject::createObject(element(), style);
361 }
362 
createShadowSubtree()363 void InputType::createShadowSubtree()
364 {
365 }
366 
destroyShadowSubtree()367 void InputType::destroyShadowSubtree()
368 {
369     element()->removeShadowRoot();
370 }
371 
parseToDouble(const String &,double defaultValue) const372 double InputType::parseToDouble(const String&, double defaultValue) const
373 {
374     return defaultValue;
375 }
376 
parseToDoubleWithDecimalPlaces(const String & src,double defaultValue,unsigned * decimalPlaces) const377 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 
parseToDateComponents(const String &,DateComponents *) const384 bool InputType::parseToDateComponents(const String&, DateComponents*) const
385 {
386     ASSERT_NOT_REACHED();
387     return false;
388 }
389 
serialize(double) const390 String InputType::serialize(double) const
391 {
392     ASSERT_NOT_REACHED();
393     return String();
394 }
395 
dispatchSimulatedClickIfActive(KeyboardEvent * event) const396 void InputType::dispatchSimulatedClickIfActive(KeyboardEvent* event) const
397 {
398     if (element()->active())
399         element()->dispatchSimulatedClick(event);
400     event->setDefaultHandled();
401 }
402 
canSetStringValue() const403 bool InputType::canSetStringValue() const
404 {
405     return true;
406 }
407 
isKeyboardFocusable() const408 bool InputType::isKeyboardFocusable() const
409 {
410     return true;
411 }
412 
shouldUseInputMethod() const413 bool InputType::shouldUseInputMethod() const
414 {
415     return false;
416 }
417 
handleBlurEvent()418 void InputType::handleBlurEvent()
419 {
420 }
421 
accessKeyAction(bool)422 void InputType::accessKeyAction(bool)
423 {
424     element()->focus(false);
425 }
426 
attach()427 void InputType::attach()
428 {
429 }
430 
altAttributeChanged()431 void InputType::altAttributeChanged()
432 {
433 }
434 
srcAttributeChanged()435 void InputType::srcAttributeChanged()
436 {
437 }
438 
valueChanged()439 void InputType::valueChanged()
440 {
441 }
442 
willMoveToNewOwnerDocument()443 void InputType::willMoveToNewOwnerDocument()
444 {
445 }
446 
shouldRespectAlignAttribute()447 bool InputType::shouldRespectAlignAttribute()
448 {
449     return false;
450 }
451 
canChangeFromAnotherType() const452 bool InputType::canChangeFromAnotherType() const
453 {
454     return true;
455 }
456 
minOrMaxAttributeChanged()457 void InputType::minOrMaxAttributeChanged()
458 {
459 }
460 
canBeSuccessfulSubmitButton()461 bool InputType::canBeSuccessfulSubmitButton()
462 {
463     return false;
464 }
465 
rendererIsNeeded()466 bool InputType::rendererIsNeeded()
467 {
468     return true;
469 }
470 
files()471 FileList* InputType::files()
472 {
473     return 0;
474 }
475 
getTypeSpecificValue(String &)476 bool InputType::getTypeSpecificValue(String&)
477 {
478     return false;
479 }
480 
fallbackValue()481 String InputType::fallbackValue()
482 {
483     return String();
484 }
485 
defaultValue()486 String InputType::defaultValue()
487 {
488     return String();
489 }
490 
canSetSuggestedValue()491 bool InputType::canSetSuggestedValue()
492 {
493     return false;
494 }
495 
shouldSendChangeEventAfterCheckedChanged()496 bool InputType::shouldSendChangeEventAfterCheckedChanged()
497 {
498     return true;
499 }
500 
storesValueSeparateFromAttribute()501 bool InputType::storesValueSeparateFromAttribute()
502 {
503     return true;
504 }
505 
canSetValue(const String &)506 bool InputType::canSetValue(const String&)
507 {
508     return true;
509 }
510 
willDispatchClick()511 PassOwnPtr<ClickHandlingState> InputType::willDispatchClick()
512 {
513     return PassOwnPtr<ClickHandlingState>();
514 }
515 
didDispatchClick(Event *,const ClickHandlingState &)516 void InputType::didDispatchClick(Event*, const ClickHandlingState&)
517 {
518 }
519 
visibleValue() const520 String InputType::visibleValue() const
521 {
522     return element()->value();
523 }
524 
convertFromVisibleValue(const String & visibleValue) const525 String InputType::convertFromVisibleValue(const String& visibleValue) const
526 {
527     return visibleValue;
528 }
529 
isAcceptableValue(const String &)530 bool InputType::isAcceptableValue(const String&)
531 {
532     return true;
533 }
534 
sanitizeValue(const String & proposedValue)535 String InputType::sanitizeValue(const String& proposedValue)
536 {
537     return proposedValue;
538 }
539 
hasUnacceptableValue()540 bool InputType::hasUnacceptableValue()
541 {
542     return false;
543 }
544 
setFileList(const Vector<String> &)545 void InputType::setFileList(const Vector<String>&)
546 {
547     ASSERT_NOT_REACHED();
548 }
549 
shouldResetOnDocumentActivation()550 bool InputType::shouldResetOnDocumentActivation()
551 {
552     return false;
553 }
554 
shouldRespectListAttribute()555 bool InputType::shouldRespectListAttribute()
556 {
557     return false;
558 }
559 
shouldRespectSpeechAttribute()560 bool InputType::shouldRespectSpeechAttribute()
561 {
562     return false;
563 }
564 
isTextButton() const565 bool InputType::isTextButton() const
566 {
567     return false;
568 }
569 
isRadioButton() const570 bool InputType::isRadioButton() const
571 {
572     return false;
573 }
574 
isSearchField() const575 bool InputType::isSearchField() const
576 {
577     return false;
578 }
579 
isHiddenType() const580 bool InputType::isHiddenType() const
581 {
582     return false;
583 }
584 
isPasswordField() const585 bool InputType::isPasswordField() const
586 {
587     return false;
588 }
589 
isCheckbox() const590 bool InputType::isCheckbox() const
591 {
592     return false;
593 }
594 
isEmailField() const595 bool InputType::isEmailField() const
596 {
597     return false;
598 }
599 
isFileUpload() const600 bool InputType::isFileUpload() const
601 {
602     return false;
603 }
604 
isImageButton() const605 bool InputType::isImageButton() const
606 {
607     return false;
608 }
609 
isNumberField() const610 bool InputType::isNumberField() const
611 {
612     return false;
613 }
614 
isSubmitButton() const615 bool InputType::isSubmitButton() const
616 {
617     return false;
618 }
619 
isTelephoneField() const620 bool InputType::isTelephoneField() const
621 {
622     return false;
623 }
624 
isURLField() const625 bool InputType::isURLField() const
626 {
627     return false;
628 }
629 
isEnumeratable()630 bool InputType::isEnumeratable()
631 {
632     return true;
633 }
634 
isCheckable()635 bool InputType::isCheckable()
636 {
637     return false;
638 }
639 
hasSpinButton()640 bool InputType::hasSpinButton()
641 {
642     return false;
643 }
644 
shouldRespectHeightAndWidthAttributes()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 
button()655 const AtomicString& button()
656 {
657     DEFINE_STATIC_LOCAL(AtomicString, name, ("button"));
658     return name;
659 }
660 
checkbox()661 const AtomicString& checkbox()
662 {
663     DEFINE_STATIC_LOCAL(AtomicString, name, ("checkbox"));
664     return name;
665 }
666 
color()667 const AtomicString& color()
668 {
669     DEFINE_STATIC_LOCAL(AtomicString, name, ("color"));
670     return name;
671 }
672 
date()673 const AtomicString& date()
674 {
675     DEFINE_STATIC_LOCAL(AtomicString, name, ("date"));
676     return name;
677 }
678 
datetime()679 const AtomicString& datetime()
680 {
681     DEFINE_STATIC_LOCAL(AtomicString, name, ("datetime"));
682     return name;
683 }
684 
datetimelocal()685 const AtomicString& datetimelocal()
686 {
687     DEFINE_STATIC_LOCAL(AtomicString, name, ("datetime-local"));
688     return name;
689 }
690 
email()691 const AtomicString& email()
692 {
693     DEFINE_STATIC_LOCAL(AtomicString, name, ("email"));
694     return name;
695 }
696 
file()697 const AtomicString& file()
698 {
699     DEFINE_STATIC_LOCAL(AtomicString, name, ("file"));
700     return name;
701 }
702 
hidden()703 const AtomicString& hidden()
704 {
705     DEFINE_STATIC_LOCAL(AtomicString, name, ("hidden"));
706     return name;
707 }
708 
image()709 const AtomicString& image()
710 {
711     DEFINE_STATIC_LOCAL(AtomicString, name, ("image"));
712     return name;
713 }
714 
isindex()715 const AtomicString& isindex()
716 {
717     DEFINE_STATIC_LOCAL(AtomicString, name, ("khtml_isindex"));
718     return name;
719 }
720 
month()721 const AtomicString& month()
722 {
723     DEFINE_STATIC_LOCAL(AtomicString, name, ("month"));
724     return name;
725 }
726 
number()727 const AtomicString& number()
728 {
729     DEFINE_STATIC_LOCAL(AtomicString, name, ("number"));
730     return name;
731 }
732 
password()733 const AtomicString& password()
734 {
735     DEFINE_STATIC_LOCAL(AtomicString, name, ("password"));
736     return name;
737 }
738 
radio()739 const AtomicString& radio()
740 {
741     DEFINE_STATIC_LOCAL(AtomicString, name, ("radio"));
742     return name;
743 }
744 
range()745 const AtomicString& range()
746 {
747     DEFINE_STATIC_LOCAL(AtomicString, name, ("range"));
748     return name;
749 }
750 
reset()751 const AtomicString& reset()
752 {
753     DEFINE_STATIC_LOCAL(AtomicString, name, ("reset"));
754     return name;
755 }
756 
search()757 const AtomicString& search()
758 {
759     DEFINE_STATIC_LOCAL(AtomicString, name, ("search"));
760     return name;
761 }
762 
submit()763 const AtomicString& submit()
764 {
765     DEFINE_STATIC_LOCAL(AtomicString, name, ("submit"));
766     return name;
767 }
768 
telephone()769 const AtomicString& telephone()
770 {
771     DEFINE_STATIC_LOCAL(AtomicString, name, ("tel"));
772     return name;
773 }
774 
text()775 const AtomicString& text()
776 {
777     DEFINE_STATIC_LOCAL(AtomicString, name, ("text"));
778     return name;
779 }
780 
time()781 const AtomicString& time()
782 {
783     DEFINE_STATIC_LOCAL(AtomicString, name, ("time"));
784     return name;
785 }
786 
url()787 const AtomicString& url()
788 {
789     DEFINE_STATIC_LOCAL(AtomicString, name, ("url"));
790     return name;
791 }
792 
week()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