initial import
[vuplus_webkit] / Source / WebCore / html / InputType.cpp
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 "Page.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"
66 #include <limits>
67 #include <wtf/Assertions.h>
68 #include <wtf/HashMap.h>
69 #include <wtf/text/StringHash.h>
70
71 namespace WebCore {
72
73 using namespace std;
74
75 typedef PassOwnPtr<InputType> (*InputTypeFactoryFunction)(HTMLInputElement*);
76 typedef HashMap<String, InputTypeFactoryFunction, CaseFoldingHash> InputTypeFactoryMap;
77
78 static PassOwnPtr<InputTypeFactoryMap> createInputTypeFactoryMap()
79 {
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);
85 #endif
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();
108 }
109
110 PassOwnPtr<InputType> InputType::create(HTMLInputElement* element, const String& typeName)
111 {
112     static const InputTypeFactoryMap* factoryMap = createInputTypeFactoryMap().leakPtr();
113     PassOwnPtr<InputType> (*factory)(HTMLInputElement*) = typeName.isEmpty() ? 0 : factoryMap->get(typeName);
114     if (!factory)
115         factory = TextInputType::create;
116     return factory(element);
117 }
118
119 PassOwnPtr<InputType> InputType::createText(HTMLInputElement* element)
120 {
121     return TextInputType::create(element);
122 }
123
124 InputType::~InputType()
125 {
126 }
127
128 bool InputType::isTextField() const
129 {
130     return false;
131 }
132
133 bool InputType::isTextType() const
134 {
135     return false;
136 }
137
138 bool InputType::isRangeControl() const
139 {
140     return false;
141 }
142
143 bool InputType::saveFormControlState(String& result) const
144 {
145     String currentValue = element()->value();
146     if (currentValue == element()->defaultValue())
147         return false;
148     result = currentValue;
149     return true;
150 }
151
152 void InputType::restoreFormControlState(const String& state) const
153 {
154     element()->setValue(state);
155 }
156
157 bool InputType::isFormDataAppendable() const
158 {
159     // There is no form data unless there's a name for non-image types.
160     return !element()->name().isEmpty();
161 }
162
163 bool InputType::appendFormData(FormDataList& encoding, bool) const
164 {
165     // Always successful.
166     encoding.appendData(element()->name(), element()->value());
167     return true;
168 }
169
170 double InputType::valueAsDate() const
171 {
172     return DateComponents::invalidMilliseconds();
173 }
174
175 void InputType::setValueAsDate(double, ExceptionCode& ec) const
176 {
177     ec = INVALID_STATE_ERR;
178 }
179
180 double InputType::valueAsNumber() const
181 {
182     return numeric_limits<double>::quiet_NaN();
183 }
184
185 void InputType::setValueAsNumber(double, bool, ExceptionCode& ec) const
186 {
187     ec = INVALID_STATE_ERR;
188 }
189
190 bool InputType::supportsValidation() const
191 {
192     return true;
193 }
194
195 bool InputType::typeMismatchFor(const String&) const
196 {
197     return false;
198 }
199
200 bool InputType::typeMismatch() const
201 {
202     return false;
203 }
204
205 bool InputType::supportsRequired() const
206 {
207     // Almost all validatable types support @required.
208     return supportsValidation();
209 }
210
211 bool InputType::valueMissing(const String&) const
212 {
213     return false;
214 }
215
216 bool InputType::patternMismatch(const String&) const
217 {
218     return false;
219 }
220
221 bool InputType::rangeUnderflow(const String&) const
222 {
223     return false;
224 }
225
226 bool InputType::rangeOverflow(const String&) const
227 {
228     return false;
229 }
230
231 bool InputType::supportsRangeLimitation() const
232 {
233     return false;
234 }
235
236 double InputType::defaultValueForStepUp() const
237 {
238     return 0;
239 }
240
241 double InputType::minimum() const
242 {
243     ASSERT_NOT_REACHED();
244     return 0;
245 }
246
247 double InputType::maximum() const
248 {
249     ASSERT_NOT_REACHED();
250     return 0;
251 }
252
253 bool InputType::sizeShouldIncludeDecoration(int, int& preferredSize) const
254 {
255     preferredSize = element()->size();
256     return false;
257 }
258
259 bool InputType::stepMismatch(const String&, double) const
260 {
261     // Non-supported types should be rejected by HTMLInputElement::getAllowedValueStep().
262     ASSERT_NOT_REACHED();
263     return false;
264 }
265
266 double InputType::stepBase() const
267 {
268     ASSERT_NOT_REACHED();
269     return 0;
270 }
271
272 double InputType::stepBaseWithDecimalPlaces(unsigned* decimalPlaces) const
273 {
274     if (decimalPlaces)
275         *decimalPlaces = 0;
276     return stepBase();
277 }
278
279 double InputType::defaultStep() const
280 {
281     return numeric_limits<double>::quiet_NaN();
282 }
283
284 double InputType::stepScaleFactor() const
285 {
286     return numeric_limits<double>::quiet_NaN();
287 }
288
289 bool InputType::parsedStepValueShouldBeInteger() const
290 {
291     return false;
292 }
293
294 bool InputType::scaledStepValueShouldBeInteger() const
295 {
296     return false;
297 }
298
299 double InputType::acceptableError(double) const
300 {
301     return 0;
302 }
303
304 String InputType::typeMismatchText() const
305 {
306     return validationMessageTypeMismatchText();
307 }
308
309 String InputType::valueMissingText() const
310 {
311     return validationMessageValueMissingText();
312 }
313
314 void InputType::handleClickEvent(MouseEvent*)
315 {
316 }
317
318 void InputType::handleMouseDownEvent(MouseEvent*)
319 {
320 }
321
322 void InputType::handleDOMActivateEvent(Event*)
323 {
324 }
325
326 void InputType::handleKeydownEvent(KeyboardEvent*)
327 {
328 }
329
330 void InputType::handleKeypressEvent(KeyboardEvent*)
331 {
332 }
333
334 void InputType::handleKeyupEvent(KeyboardEvent*)
335 {
336 }
337
338 void InputType::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent*)
339 {
340 }
341
342 void InputType::handleWheelEvent(WheelEvent*)
343 {
344 }
345
346 void InputType::forwardEvent(Event*)
347 {
348 }
349
350 bool InputType::shouldSubmitImplicitly(Event* event)
351 {
352     return event->isKeyboardEvent() && event->type() == eventNames().keypressEvent && static_cast<KeyboardEvent*>(event)->charCode() == '\r';
353 }
354
355 PassRefPtr<HTMLFormElement> InputType::formForSubmission() const
356 {
357     return element()->form();
358 }
359
360 RenderObject* InputType::createRenderer(RenderArena*, RenderStyle* style) const
361 {
362     return RenderObject::createObject(element(), style);
363 }
364
365 void InputType::createShadowSubtree()
366 {
367 }
368
369 void InputType::destroyShadowSubtree()
370 {
371     element()->removeShadowRoot();
372 }
373
374 double InputType::parseToDouble(const String&, double defaultValue) const
375 {
376     return defaultValue;
377 }
378
379 double InputType::parseToDoubleWithDecimalPlaces(const String& src, double defaultValue, unsigned *decimalPlaces) const
380 {
381     if (decimalPlaces)
382         *decimalPlaces = 0;
383     return parseToDouble(src, defaultValue);
384 }
385
386 bool InputType::parseToDateComponents(const String&, DateComponents*) const
387 {
388     ASSERT_NOT_REACHED();
389     return false;
390 }
391
392 String InputType::serialize(double) const
393 {
394     ASSERT_NOT_REACHED();
395     return String();
396 }
397
398 void InputType::dispatchSimulatedClickIfActive(KeyboardEvent* event) const
399 {
400     if (element()->active())
401         element()->dispatchSimulatedClick(event);
402     event->setDefaultHandled();
403 }
404
405 Chrome* InputType::chrome() const
406 {
407     if (Page* page = element()->document()->page())
408         return page->chrome();
409     return 0;
410 }
411
412 bool InputType::canSetStringValue() const
413 {
414     return true;
415 }
416
417 bool InputType::isKeyboardFocusable() const
418 {
419     return true;
420 }
421
422 bool InputType::shouldUseInputMethod() const
423 {
424     return false;
425 }
426
427 void InputType::willBlur()
428 {
429 }
430
431 void InputType::accessKeyAction(bool)
432 {
433     element()->focus(false);
434 }
435
436 void InputType::attach()
437 {
438 }
439
440 void InputType::detach()
441 {
442 }
443
444 void InputType::altAttributeChanged()
445 {
446 }
447
448 void InputType::srcAttributeChanged()
449 {
450 }
451
452 void InputType::willMoveToNewOwnerDocument()
453 {
454 }
455
456 bool InputType::shouldRespectAlignAttribute()
457 {
458     return false;
459 }
460
461 bool InputType::canChangeFromAnotherType() const
462 {
463     return true;
464 }
465
466 void InputType::minOrMaxAttributeChanged()
467 {
468 }
469
470 void InputType::stepAttributeChanged()
471 {
472 }
473
474 bool InputType::canBeSuccessfulSubmitButton()
475 {
476     return false;
477 }
478
479 HTMLElement* InputType::placeholderElement() const
480 {
481     return 0;
482 }
483
484 bool InputType::rendererIsNeeded()
485 {
486     return true;
487 }
488
489 FileList* InputType::files()
490 {
491     return 0;
492 }
493
494 bool InputType::getTypeSpecificValue(String&)
495 {
496     return false;
497 }
498
499 String InputType::fallbackValue()
500 {
501     return String();
502 }
503
504 String InputType::defaultValue()
505 {
506     return String();
507 }
508
509 bool InputType::canSetSuggestedValue()
510 {
511     return false;
512 }
513
514 bool InputType::shouldSendChangeEventAfterCheckedChanged()
515 {
516     return true;
517 }
518
519 bool InputType::storesValueSeparateFromAttribute()
520 {
521     return true;
522 }
523
524 void InputType::setValue(const String& sanitizedValue, bool, bool sendChangeEvent)
525 {
526     element()->setValueInternal(sanitizedValue, sendChangeEvent);
527     element()->setNeedsStyleRecalc();
528 }
529
530 void InputType::dispatchChangeEventInResponseToSetValue()
531 {
532     element()->dispatchFormControlChangeEvent();
533 }
534
535 bool InputType::canSetValue(const String&)
536 {
537     return true;
538 }
539
540 PassOwnPtr<ClickHandlingState> InputType::willDispatchClick()
541 {
542     return nullptr;
543 }
544
545 void InputType::didDispatchClick(Event*, const ClickHandlingState&)
546 {
547 }
548
549 String InputType::visibleValue() const
550 {
551     return element()->value();
552 }
553
554 String InputType::convertFromVisibleValue(const String& visibleValue) const
555 {
556     return visibleValue;
557 }
558
559 bool InputType::isAcceptableValue(const String&)
560 {
561     return true;
562 }
563
564 String InputType::sanitizeValue(const String& proposedValue)
565 {
566     return proposedValue;
567 }
568
569 bool InputType::hasUnacceptableValue()
570 {
571     return false;
572 }
573
574 void InputType::receiveDroppedFiles(const Vector<String>&)
575 {
576     ASSERT_NOT_REACHED();
577 }
578
579 Icon* InputType::icon() const
580 {
581     ASSERT_NOT_REACHED();
582     return 0;
583 }
584
585 bool InputType::shouldResetOnDocumentActivation()
586 {
587     return false;
588 }
589
590 bool InputType::shouldRespectListAttribute()
591 {
592     return false;
593 }
594
595 bool InputType::shouldRespectSpeechAttribute()
596 {
597     return false;
598 }
599
600 bool InputType::isTextButton() const
601 {
602     return false;
603 }
604
605 bool InputType::isRadioButton() const
606 {
607     return false;
608 }
609
610 bool InputType::isSearchField() const
611 {
612     return false;
613 }
614
615 bool InputType::isHiddenType() const
616 {
617     return false;
618 }
619
620 bool InputType::isPasswordField() const
621 {
622     return false;
623 }
624
625 bool InputType::isCheckbox() const
626 {
627     return false;
628 }
629
630 bool InputType::isEmailField() const
631 {
632     return false;
633 }
634
635 bool InputType::isFileUpload() const
636 {
637     return false;
638 }
639
640 bool InputType::isImageButton() const
641 {
642     return false;
643 }
644
645 bool InputType::isNumberField() const
646 {
647     return false;
648 }
649
650 bool InputType::isSubmitButton() const
651 {
652     return false;
653 }
654
655 bool InputType::isTelephoneField() const
656 {
657     return false;
658 }
659
660 bool InputType::isURLField() const
661 {
662     return false;
663 }
664
665 bool InputType::isEnumeratable()
666 {
667     return true;
668 }
669
670 bool InputType::isCheckable()
671 {
672     return false;
673 }
674
675 bool InputType::isSteppable() const
676 {
677     return false;
678 }
679
680 #if ENABLE(INPUT_COLOR)
681 bool InputType::isColorControl() const
682 {
683     return false;
684 }
685 #endif
686
687 bool InputType::shouldRespectHeightAndWidthAttributes()
688 {
689     return false;
690 }
691
692 bool InputType::supportsPlaceholder() const
693 {
694     return false;
695 }
696
697 void InputType::updatePlaceholderText()
698 {
699 }
700
701 void InputType::multipleAttributeChanged()
702 {
703 }
704
705 void InputType::disabledAttributeChanged()
706 {
707 }
708
709 void InputType::readonlyAttributeChanged()
710 {
711 }
712
713 namespace InputTypeNames {
714
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.
717
718 const AtomicString& button()
719 {
720     DEFINE_STATIC_LOCAL(AtomicString, name, ("button"));
721     return name;
722 }
723
724 const AtomicString& checkbox()
725 {
726     DEFINE_STATIC_LOCAL(AtomicString, name, ("checkbox"));
727     return name;
728 }
729
730 #if ENABLE(INPUT_COLOR)
731 const AtomicString& color()
732 {
733     DEFINE_STATIC_LOCAL(AtomicString, name, ("color"));
734     return name;
735 }
736 #endif
737
738 const AtomicString& date()
739 {
740     DEFINE_STATIC_LOCAL(AtomicString, name, ("date"));
741     return name;
742 }
743
744 const AtomicString& datetime()
745 {
746     DEFINE_STATIC_LOCAL(AtomicString, name, ("datetime"));
747     return name;
748 }
749
750 const AtomicString& datetimelocal()
751 {
752     DEFINE_STATIC_LOCAL(AtomicString, name, ("datetime-local"));
753     return name;
754 }
755
756 const AtomicString& email()
757 {
758     DEFINE_STATIC_LOCAL(AtomicString, name, ("email"));
759     return name;
760 }
761
762 const AtomicString& file()
763 {
764     DEFINE_STATIC_LOCAL(AtomicString, name, ("file"));
765     return name;
766 }
767
768 const AtomicString& hidden()
769 {
770     DEFINE_STATIC_LOCAL(AtomicString, name, ("hidden"));
771     return name;
772 }
773
774 const AtomicString& image()
775 {
776     DEFINE_STATIC_LOCAL(AtomicString, name, ("image"));
777     return name;
778 }
779
780 const AtomicString& isindex()
781 {
782     DEFINE_STATIC_LOCAL(AtomicString, name, ("khtml_isindex"));
783     return name;
784 }
785
786 const AtomicString& month()
787 {
788     DEFINE_STATIC_LOCAL(AtomicString, name, ("month"));
789     return name;
790 }
791
792 const AtomicString& number()
793 {
794     DEFINE_STATIC_LOCAL(AtomicString, name, ("number"));
795     return name;
796 }
797
798 const AtomicString& password()
799 {
800     DEFINE_STATIC_LOCAL(AtomicString, name, ("password"));
801     return name;
802 }
803
804 const AtomicString& radio()
805 {
806     DEFINE_STATIC_LOCAL(AtomicString, name, ("radio"));
807     return name;
808 }
809
810 const AtomicString& range()
811 {
812     DEFINE_STATIC_LOCAL(AtomicString, name, ("range"));
813     return name;
814 }
815
816 const AtomicString& reset()
817 {
818     DEFINE_STATIC_LOCAL(AtomicString, name, ("reset"));
819     return name;
820 }
821
822 const AtomicString& search()
823 {
824     DEFINE_STATIC_LOCAL(AtomicString, name, ("search"));
825     return name;
826 }
827
828 const AtomicString& submit()
829 {
830     DEFINE_STATIC_LOCAL(AtomicString, name, ("submit"));
831     return name;
832 }
833
834 const AtomicString& telephone()
835 {
836     DEFINE_STATIC_LOCAL(AtomicString, name, ("tel"));
837     return name;
838 }
839
840 const AtomicString& text()
841 {
842     DEFINE_STATIC_LOCAL(AtomicString, name, ("text"));
843     return name;
844 }
845
846 const AtomicString& time()
847 {
848     DEFINE_STATIC_LOCAL(AtomicString, name, ("time"));
849     return name;
850 }
851
852 const AtomicString& url()
853 {
854     DEFINE_STATIC_LOCAL(AtomicString, name, ("url"));
855     return name;
856 }
857
858 const AtomicString& week()
859 {
860     DEFINE_STATIC_LOCAL(AtomicString, name, ("week"));
861     return name;
862 }
863
864 } // namespace WebCore::InputTypeNames
865
866 } // namespace WebCore