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