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 "HTMLInputElement.h"
30 #include "AXObjectCache.h"
31 #include "Attribute.h"
32 #include "BeforeTextInsertedEvent.h"
33 #include "CSSPropertyNames.h"
35 #include "EventNames.h"
36 #include "ExceptionCode.h"
38 #include "HTMLCollection.h"
39 #include "HTMLDataListElement.h"
40 #include "HTMLFormElement.h"
41 #include "HTMLNames.h"
42 #include "HTMLOptionElement.h"
43 #include "HTMLParserIdioms.h"
44 #include "InputType.h"
45 #include "KeyboardEvent.h"
46 #include "LocalizedStrings.h"
47 #include "MouseEvent.h"
48 #include "RenderTextControlSingleLine.h"
49 #include "RenderTheme.h"
50 #include "RuntimeEnabledFeatures.h"
51 #include "ScriptEventListener.h"
52 #include "WheelEvent.h"
53 #include <wtf/MathExtras.h>
54 #include <wtf/StdLibExtras.h>
60 using namespace HTMLNames;
62 const int maxSavedResults = 256;
64 HTMLInputElement::HTMLInputElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
65 : HTMLTextFormControlElement(tagName, document, form)
68 , m_reflectsCheckedAttribute(true)
69 , m_isIndeterminate(false)
71 , m_isActivatedSubmit(false)
72 , m_autocomplete(Uninitialized)
73 , m_isAutofilled(false)
74 , m_inputType(InputType::createText(this))
76 ASSERT(hasTagName(inputTag) || hasTagName(isindexTag));
79 PassRefPtr<HTMLInputElement> HTMLInputElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
81 return adoptRef(new HTMLInputElement(tagName, document, form));
84 HTMLInputElement::~HTMLInputElement()
86 if (needsActivationCallback())
87 document()->unregisterForDocumentActivationCallbacks(this);
89 document()->checkedRadioButtons().removeButton(this);
91 // Need to remove this from the form while it is still an HTMLInputElement,
92 // so can't wait for the base class's destructor to do it.
96 const AtomicString& HTMLInputElement::formControlName() const
101 bool HTMLInputElement::autoComplete() const
103 if (m_autocomplete != Uninitialized)
104 return m_autocomplete == On;
105 return HTMLTextFormControlElement::autoComplete();
108 void HTMLInputElement::updateCheckedRadioButtons()
110 if (attached() && checked())
111 checkedRadioButtons().addButton(this);
114 const Vector<FormAssociatedElement*>& controls = form()->associatedElements();
115 for (unsigned i = 0; i < controls.size(); ++i) {
116 if (!controls[i]->isFormControlElement())
118 HTMLFormControlElement* control = static_cast<HTMLFormControlElement*>(controls[i]);
119 if (control->name() != name())
121 if (control->type() != type())
123 control->setNeedsValidityCheck();
126 // FIXME: Traversing the document is inefficient.
127 for (Node* node = document()->body(); node; node = node->traverseNextNode()) {
128 if (!node->isElementNode())
130 Element* element = static_cast<Element*>(node);
131 if (element->formControlName() != name())
133 if (element->formControlType() != type())
135 HTMLFormControlElement* control = static_cast<HTMLFormControlElement*>(element);
138 control->setNeedsValidityCheck();
142 if (renderer() && renderer()->style()->hasAppearance())
143 renderer()->theme()->stateChanged(renderer(), CheckedState);
146 bool HTMLInputElement::isValidValue(const String& value) const
148 if (!m_inputType->canSetStringValue()) {
149 ASSERT_NOT_REACHED();
152 return !m_inputType->typeMismatchFor(value)
153 && !stepMismatch(value)
154 && !rangeUnderflow(value)
155 && !rangeOverflow(value)
156 && !tooLong(value, IgnoreDirtyFlag)
157 && !patternMismatch(value)
158 && !valueMissing(value);
161 bool HTMLInputElement::typeMismatch() const
163 return m_inputType->typeMismatch();
166 bool HTMLInputElement::valueMissing(const String& value) const
168 if (!isRequiredFormControl() || readOnly() || disabled())
170 return m_inputType->valueMissing(value);
173 bool HTMLInputElement::patternMismatch(const String& value) const
175 return m_inputType->patternMismatch(value);
178 bool HTMLInputElement::tooLong(const String& value, NeedsToCheckDirtyFlag check) const
180 // We use isTextType() instead of supportsMaxLength() because of the
181 // 'virtual' overhead.
184 int max = maxLength();
187 if (check == CheckDirtyFlag) {
188 // Return false for the default value even if it is longer than maxLength.
189 bool userEdited = !m_data.value().isNull();
193 return numGraphemeClusters(value) > static_cast<unsigned>(max);
196 bool HTMLInputElement::rangeUnderflow(const String& value) const
198 return m_inputType->rangeUnderflow(value);
201 bool HTMLInputElement::rangeOverflow(const String& value) const
203 return m_inputType->rangeOverflow(value);
206 double HTMLInputElement::minimum() const
208 return m_inputType->minimum();
211 double HTMLInputElement::maximum() const
213 return m_inputType->maximum();
216 bool HTMLInputElement::stepMismatch(const String& value) const
219 if (!getAllowedValueStep(&step))
221 return m_inputType->stepMismatch(value, step);
224 String HTMLInputElement::minimumString() const
226 return m_inputType->serialize(minimum());
229 String HTMLInputElement::maximumString() const
231 return m_inputType->serialize(maximum());
234 String HTMLInputElement::stepBaseString() const
236 return m_inputType->serialize(m_inputType->stepBase());
239 String HTMLInputElement::stepString() const
242 if (!getAllowedValueStep(&step)) {
243 // stepString() should be called only if stepMismatch() can be true.
244 ASSERT_NOT_REACHED();
247 return serializeForNumberType(step / m_inputType->stepScaleFactor());
250 String HTMLInputElement::typeMismatchText() const
252 return m_inputType->typeMismatchText();
255 String HTMLInputElement::valueMissingText() const
257 return m_inputType->valueMissingText();
260 bool HTMLInputElement::getAllowedValueStep(double* step) const
262 return getAllowedValueStepWithDecimalPlaces(step, 0);
265 bool HTMLInputElement::getAllowedValueStepWithDecimalPlaces(double* step, unsigned* decimalPlaces) const
268 double defaultStep = m_inputType->defaultStep();
269 double stepScaleFactor = m_inputType->stepScaleFactor();
270 if (!isfinite(defaultStep) || !isfinite(stepScaleFactor))
272 const AtomicString& stepString = fastGetAttribute(stepAttr);
273 if (stepString.isEmpty()) {
274 *step = defaultStep * stepScaleFactor;
279 if (equalIgnoringCase(stepString, "any"))
282 if (!decimalPlaces) {
283 if (!parseToDoubleForNumberType(stepString, &parsed) || parsed <= 0.0) {
284 *step = defaultStep * stepScaleFactor;
288 if (!parseToDoubleForNumberTypeWithDecimalPlaces(stepString, &parsed, decimalPlaces) || parsed <= 0.0) {
289 *step = defaultStep * stepScaleFactor;
294 // For date, month, week, the parsed value should be an integer for some types.
295 if (m_inputType->parsedStepValueShouldBeInteger())
296 parsed = max(round(parsed), 1.0);
297 double result = parsed * stepScaleFactor;
298 // For datetime, datetime-local, time, the result should be an integer.
299 if (m_inputType->scaledStepValueShouldBeInteger())
300 result = max(round(result), 1.0);
306 void HTMLInputElement::applyStep(double count, ExceptionCode& ec)
309 unsigned stepDecimalPlaces, currentDecimalPlaces;
310 if (!getAllowedValueStepWithDecimalPlaces(&step, &stepDecimalPlaces)) {
311 ec = INVALID_STATE_ERR;
314 const double nan = numeric_limits<double>::quiet_NaN();
315 double current = m_inputType->parseToDoubleWithDecimalPlaces(value(), nan, ¤tDecimalPlaces);
316 if (!isfinite(current)) {
317 ec = INVALID_STATE_ERR;
320 double newValue = current + step * count;
321 if (isinf(newValue)) {
322 ec = INVALID_STATE_ERR;
325 double acceptableError = m_inputType->acceptableError(step);
326 if (newValue - m_inputType->minimum() < -acceptableError) {
327 ec = INVALID_STATE_ERR;
330 if (newValue < m_inputType->minimum())
331 newValue = m_inputType->minimum();
332 unsigned baseDecimalPlaces;
333 double base = m_inputType->stepBaseWithDecimalPlaces(&baseDecimalPlaces);
334 baseDecimalPlaces = min(baseDecimalPlaces, 16u);
335 if (newValue < pow(10.0, 21.0)) {
336 if (stepMismatch(value())) {
337 double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, currentDecimalPlaces)));
338 newValue = round(newValue * scale) / scale;
340 double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces)));
341 newValue = round((base + round((newValue - base) / step) * step) * scale) / scale;
344 if (newValue - m_inputType->maximum() > acceptableError) {
345 ec = INVALID_STATE_ERR;
348 if (newValue > m_inputType->maximum())
349 newValue = m_inputType->maximum();
350 setValueAsNumber(newValue, ec);
352 if (AXObjectCache::accessibilityEnabled())
353 document()->axObjectCache()->postNotification(renderer(), AXObjectCache::AXValueChanged, true);
356 void HTMLInputElement::stepUp(int n, ExceptionCode& ec)
361 void HTMLInputElement::stepDown(int n, ExceptionCode& ec)
366 bool HTMLInputElement::isKeyboardFocusable(KeyboardEvent* event) const
369 return HTMLFormControlElementWithState::isFocusable();
370 return HTMLFormControlElementWithState::isKeyboardFocusable(event) && m_inputType->isKeyboardFocusable();
373 bool HTMLInputElement::isMouseFocusable() const
376 return HTMLFormControlElementWithState::isFocusable();
377 return HTMLFormControlElementWithState::isMouseFocusable();
380 void HTMLInputElement::updateFocusAppearance(bool restorePreviousSelection)
383 InputElement::updateFocusAppearance(m_data, this, this, restorePreviousSelection);
385 HTMLFormControlElementWithState::updateFocusAppearance(restorePreviousSelection);
388 void HTMLInputElement::aboutToUnload()
390 InputElement::aboutToUnload(this, this);
393 bool HTMLInputElement::shouldUseInputMethod() const
395 return m_inputType->shouldUseInputMethod();
398 void HTMLInputElement::handleFocusEvent()
400 InputElement::dispatchFocusEvent(this, this);
403 void HTMLInputElement::handleBlurEvent()
405 m_inputType->handleBlurEvent();
406 InputElement::dispatchBlurEvent(this, this);
409 void HTMLInputElement::setType(const String& type)
411 // FIXME: This should just call setAttribute. No reason to handle the empty string specially.
412 // We should write a test case to show that setting to the empty string does not remove the
413 // attribute in other browsers and then fix this. Note that setting to null *does* remove
414 // the attribute and setAttribute implements that.
415 if (type.isEmpty()) {
417 removeAttribute(typeAttr, ec);
419 setAttribute(typeAttr, type);
422 void HTMLInputElement::updateType()
424 const AtomicString& typeString = fastGetAttribute(typeAttr);
426 OwnPtr<InputType> newType = InputType::create(this, typeString);
428 if (m_hasType && !newType->canChangeFromAnotherType()) {
429 // Set the attribute back to the old value.
430 // Useful in case we were called from inside parseMappedAttribute.
431 setAttribute(typeAttr, type());
437 if (m_inputType->formControlType() == newType->formControlType())
440 checkedRadioButtons().removeButton(this);
442 bool wasAttached = attached();
446 bool didStoreValue = m_inputType->storesValueSeparateFromAttribute();
447 bool neededActivationCallback = needsActivationCallback();
448 bool didRespectHeightAndWidth = m_inputType->shouldRespectHeightAndWidthAttributes();
450 m_inputType = newType.release();
452 setNeedsWillValidateCheck();
454 bool willStoreValue = m_inputType->storesValueSeparateFromAttribute();
456 if (didStoreValue && !willStoreValue && !m_data.value().isNull()) {
457 setAttribute(valueAttr, m_data.value());
458 m_data.setValue(String());
460 if (!didStoreValue && willStoreValue)
461 m_data.setValue(sanitizeValue(fastGetAttribute(valueAttr)));
463 InputElement::updateValueIfNeeded(m_data, this);
465 if (neededActivationCallback)
466 unregisterForActivationCallbackIfNeeded();
468 registerForActivationCallbackIfNeeded();
470 if (didRespectHeightAndWidth != m_inputType->shouldRespectHeightAndWidthAttributes()) {
471 NamedNodeMap* map = attributeMap();
473 if (Attribute* height = map->getAttributeItem(heightAttr))
474 attributeChanged(height, false);
475 if (Attribute* width = map->getAttributeItem(widthAttr))
476 attributeChanged(width, false);
477 if (Attribute* align = map->getAttributeItem(alignAttr))
478 attributeChanged(align, false);
483 if (document()->focusedNode() == this)
484 updateFocusAppearance(true);
487 checkedRadioButtons().addButton(this);
489 setNeedsValidityCheck();
490 InputElement::notifyFormStateChanged(this);
493 const AtomicString& HTMLInputElement::formControlType() const
495 return m_inputType->formControlType();
498 bool HTMLInputElement::saveFormControlState(String& result) const
500 return m_inputType->saveFormControlState(result);
503 void HTMLInputElement::restoreFormControlState(const String& state)
505 m_inputType->restoreFormControlState(state);
508 bool HTMLInputElement::canStartSelection() const
512 return HTMLFormControlElementWithState::canStartSelection();
515 bool HTMLInputElement::canHaveSelection() const
517 return isTextField();
520 void HTMLInputElement::accessKeyAction(bool sendToAnyElement)
522 m_inputType->accessKeyAction(sendToAnyElement);
525 bool HTMLInputElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
527 if (((attrName == heightAttr || attrName == widthAttr) && m_inputType->shouldRespectHeightAndWidthAttributes())
528 || attrName == vspaceAttr
529 || attrName == hspaceAttr) {
534 if (attrName == alignAttr && m_inputType->shouldRespectAlignAttribute()) {
535 // Share with <img> since the alignment behavior is the same.
540 return HTMLElement::mapToEntry(attrName, result);
543 void HTMLInputElement::parseMappedAttribute(Attribute* attr)
545 if (attr->name() == nameAttr) {
546 checkedRadioButtons().removeButton(this);
547 m_data.setName(attr->value());
548 checkedRadioButtons().addButton(this);
549 HTMLFormControlElementWithState::parseMappedAttribute(attr);
550 } else if (attr->name() == autocompleteAttr) {
551 if (equalIgnoringCase(attr->value(), "off")) {
552 m_autocomplete = Off;
553 registerForActivationCallbackIfNeeded();
555 bool needsToUnregister = m_autocomplete == Off;
558 m_autocomplete = Uninitialized;
562 if (needsToUnregister)
563 unregisterForActivationCallbackIfNeeded();
565 } else if (attr->name() == typeAttr) {
567 } else if (attr->name() == valueAttr) {
568 // We only need to setChanged if the form is looking at the default value right now.
569 if (m_data.value().isNull())
570 setNeedsStyleRecalc();
571 setFormControlValueMatchesRenderer(false);
572 setNeedsValidityCheck();
573 } else if (attr->name() == checkedAttr) {
574 if (m_reflectsCheckedAttribute) {
575 setChecked(!attr->isNull());
576 m_reflectsCheckedAttribute = true;
578 setNeedsValidityCheck();
579 } else if (attr->name() == maxlengthAttr) {
580 InputElement::parseMaxLengthAttribute(m_data, this, this, attr);
581 setNeedsValidityCheck();
582 } else if (attr->name() == sizeAttr)
583 InputElement::parseSizeAttribute(m_data, this, attr);
584 else if (attr->name() == altAttr)
585 m_inputType->altAttributeChanged();
586 else if (attr->name() == srcAttr)
587 m_inputType->srcAttributeChanged();
588 else if (attr->name() == usemapAttr || attr->name() == accesskeyAttr) {
589 // FIXME: ignore for the moment
590 } else if (attr->name() == vspaceAttr) {
591 addCSSLength(attr, CSSPropertyMarginTop, attr->value());
592 addCSSLength(attr, CSSPropertyMarginBottom, attr->value());
593 } else if (attr->name() == hspaceAttr) {
594 addCSSLength(attr, CSSPropertyMarginLeft, attr->value());
595 addCSSLength(attr, CSSPropertyMarginRight, attr->value());
596 } else if (attr->name() == alignAttr) {
597 if (m_inputType->shouldRespectAlignAttribute())
598 addHTMLAlignment(attr);
599 } else if (attr->name() == widthAttr) {
600 if (m_inputType->shouldRespectHeightAndWidthAttributes())
601 addCSSLength(attr, CSSPropertyWidth, attr->value());
602 } else if (attr->name() == heightAttr) {
603 if (m_inputType->shouldRespectHeightAndWidthAttributes())
604 addCSSLength(attr, CSSPropertyHeight, attr->value());
605 } else if (attr->name() == onsearchAttr) {
606 // Search field and slider attributes all just cause updateFromElement to be called through style recalcing.
607 setAttributeEventListener(eventNames().searchEvent, createAttributeEventListener(this, attr));
608 } else if (attr->name() == resultsAttr) {
609 int oldResults = m_maxResults;
610 m_maxResults = !attr->isNull() ? std::min(attr->value().toInt(), maxSavedResults) : -1;
611 // FIXME: Detaching just for maxResults change is not ideal. We should figure out the right
612 // time to relayout for this change.
613 if (m_maxResults != oldResults && (m_maxResults <= 0 || oldResults <= 0) && attached()) {
617 setNeedsStyleRecalc();
618 } else if (attr->name() == autosaveAttr || attr->name() == incrementalAttr)
619 setNeedsStyleRecalc();
620 else if (attr->name() == minAttr || attr->name() == maxAttr) {
621 m_inputType->minOrMaxAttributeChanged();
622 setNeedsValidityCheck();
623 } else if (attr->name() == multipleAttr || attr->name() == patternAttr || attr->name() == precisionAttr || attr->name() == stepAttr)
624 setNeedsValidityCheck();
626 else if (attr->name() == listAttr)
627 m_hasNonEmptyList = !attr->isEmpty();
628 // FIXME: we need to tell this change to a renderer if the attribute affects the appearance.
630 #if ENABLE(INPUT_SPEECH)
631 else if (attr->name() == webkitspeechAttr) {
633 toRenderTextControlSingleLine(renderer())->speechAttributeChanged();
634 setNeedsStyleRecalc();
635 } else if (attr->name() == onwebkitspeechchangeAttr)
636 setAttributeEventListener(eventNames().webkitspeechchangeEvent, createAttributeEventListener(this, attr));
639 HTMLTextFormControlElement::parseMappedAttribute(attr);
642 bool HTMLInputElement::rendererIsNeeded(RenderStyle* style)
644 return m_inputType->rendererIsNeeded() && HTMLFormControlElementWithState::rendererIsNeeded(style);
647 RenderObject* HTMLInputElement::createRenderer(RenderArena* arena, RenderStyle* style)
649 return m_inputType->createRenderer(arena, style);
652 void HTMLInputElement::attach()
657 HTMLFormControlElementWithState::attach();
659 m_inputType->attach();
661 if (document()->focusedNode() == this)
662 document()->updateFocusAppearanceSoon(true /* restore selection */);
665 void HTMLInputElement::detach()
667 HTMLFormControlElementWithState::detach();
668 setFormControlValueMatchesRenderer(false);
671 String HTMLInputElement::altText() const
673 // http://www.w3.org/TR/1998/REC-html40-19980424/appendix/notes.html#altgen
674 // also heavily discussed by Hixie on bugzilla
675 // note this is intentionally different to HTMLImageElement::altText()
676 String alt = fastGetAttribute(altAttr);
677 // fall back to title attribute
679 alt = getAttribute(titleAttr);
681 alt = getAttribute(valueAttr);
683 alt = inputElementAltText();
687 bool HTMLInputElement::isSuccessfulSubmitButton() const
689 // HTML spec says that buttons must have names to be considered successful.
690 // However, other browsers do not impose this constraint. So we do not.
691 return !disabled() && m_inputType->canBeSuccessfulSubmitButton();
694 bool HTMLInputElement::isActivatedSubmit() const
696 return m_isActivatedSubmit;
699 void HTMLInputElement::setActivatedSubmit(bool flag)
701 m_isActivatedSubmit = flag;
704 bool HTMLInputElement::appendFormData(FormDataList& encoding, bool multipart)
706 return m_inputType->isFormDataAppendable() && m_inputType->appendFormData(encoding, multipart);
709 void HTMLInputElement::reset()
711 if (m_inputType->storesValueSeparateFromAttribute())
714 setChecked(hasAttribute(checkedAttr));
715 m_reflectsCheckedAttribute = true;
718 bool HTMLInputElement::isTextField() const
720 return m_inputType->isTextField();
723 bool HTMLInputElement::isTextType() const
725 return m_inputType->isTextType();
728 void HTMLInputElement::setChecked(bool nowChecked, bool sendChangeEvent)
730 if (checked() == nowChecked)
733 checkedRadioButtons().removeButton(this);
735 m_reflectsCheckedAttribute = false;
736 m_isChecked = nowChecked;
737 setNeedsStyleRecalc();
739 updateCheckedRadioButtons();
741 // Ideally we'd do this from the render tree (matching
742 // RenderTextView), but it's not possible to do it at the moment
743 // because of the way the code is structured.
744 if (renderer() && AXObjectCache::accessibilityEnabled())
745 renderer()->document()->axObjectCache()->postNotification(renderer(), AXObjectCache::AXCheckedStateChanged, true);
747 // Only send a change event for items in the document (avoid firing during
748 // parsing) and don't send a change event for a radio button that's getting
749 // unchecked to match other browsers. DOM is not a useful standard for this
750 // because it says only to fire change events at "lose focus" time, which is
751 // definitely wrong in practice for these types of elements.
752 if (sendChangeEvent && inDocument() && m_inputType->shouldSendChangeEventAfterCheckedChanged())
753 dispatchFormControlChangeEvent();
756 void HTMLInputElement::setIndeterminate(bool newValue)
758 if (!m_inputType->isCheckable() || indeterminate() == newValue)
761 m_isIndeterminate = newValue;
763 setNeedsStyleRecalc();
765 if (renderer() && renderer()->style()->hasAppearance())
766 renderer()->theme()->stateChanged(renderer(), CheckedState);
769 int HTMLInputElement::size() const
771 return m_data.size();
774 void HTMLInputElement::copyNonAttributeProperties(const Element* source)
776 const HTMLInputElement* sourceElement = static_cast<const HTMLInputElement*>(source);
778 m_data.setValue(sourceElement->m_data.value());
779 setChecked(sourceElement->m_isChecked);
780 m_reflectsCheckedAttribute = sourceElement->m_reflectsCheckedAttribute;
781 m_isIndeterminate = sourceElement->m_isIndeterminate;
783 HTMLFormControlElementWithState::copyNonAttributeProperties(source);
786 String HTMLInputElement::value() const
789 if (m_inputType->getTypeSpecificValue(value))
792 value = m_data.value();
796 value = sanitizeValue(fastGetAttribute(valueAttr));
800 return m_inputType->fallbackValue();
803 String HTMLInputElement::valueWithDefault() const
805 String value = this->value();
809 return m_inputType->defaultValue();
812 void HTMLInputElement::setValueForUser(const String& value)
814 // Call setValue and make it send a change event.
815 setValue(value, true);
818 const String& HTMLInputElement::suggestedValue() const
820 return m_data.suggestedValue();
823 void HTMLInputElement::setSuggestedValue(const String& value)
825 if (!m_inputType->canSetSuggestedValue())
827 setFormControlValueMatchesRenderer(false);
828 m_data.setSuggestedValue(sanitizeValue(value));
829 updatePlaceholderVisibility(false);
831 renderer()->updateFromElement();
832 setNeedsStyleRecalc();
835 void HTMLInputElement::setValue(const String& value, bool sendChangeEvent)
837 if (!m_inputType->canSetValue(value))
840 setFormControlValueMatchesRenderer(false);
841 if (m_inputType->storesValueSeparateFromAttribute()) {
845 m_data.setValue(sanitizeValue(value));
847 updatePlaceholderVisibility(false);
849 setNeedsStyleRecalc();
851 setAttribute(valueAttr, sanitizeValue(value));
853 setNeedsValidityCheck();
856 unsigned max = m_data.value().length();
857 if (document()->focusedNode() == this)
858 InputElement::updateSelectionRange(this, this, max, max);
860 cacheSelection(max, max);
861 m_data.setSuggestedValue(String());
864 // Don't dispatch the change event when focused, it will be dispatched
865 // when the control loses focus.
866 if (sendChangeEvent && document()->focusedNode() != this)
867 dispatchFormControlChangeEvent();
869 InputElement::notifyFormStateChanged(this);
872 double HTMLInputElement::valueAsDate() const
874 return m_inputType->valueAsDate();
877 void HTMLInputElement::setValueAsDate(double value, ExceptionCode& ec)
879 m_inputType->setValueAsDate(value, ec);
882 double HTMLInputElement::valueAsNumber() const
884 return m_inputType->valueAsNumber();
887 void HTMLInputElement::setValueAsNumber(double newValue, ExceptionCode& ec)
889 if (!isfinite(newValue)) {
890 ec = NOT_SUPPORTED_ERR;
893 m_inputType->setValueAsNumber(newValue, ec);
896 String HTMLInputElement::placeholder() const
898 return fastGetAttribute(placeholderAttr).string();
901 void HTMLInputElement::setPlaceholder(const String& value)
903 setAttribute(placeholderAttr, value);
906 bool HTMLInputElement::searchEventsShouldBeDispatched() const
908 return hasAttribute(incrementalAttr);
911 void HTMLInputElement::setValueFromRenderer(const String& value)
913 // File upload controls will always use setFileListFromRenderer.
914 ASSERT(!isFileUpload());
916 m_data.setSuggestedValue(String());
917 InputElement::setValueFromRenderer(m_data, this, this, value);
918 updatePlaceholderVisibility(false);
919 setNeedsValidityCheck();
921 // Clear autofill flag (and yellow background) on user edit.
922 setAutofilled(false);
925 void HTMLInputElement::setFileListFromRenderer(const Vector<String>& paths)
927 m_inputType->setFileList(paths);
929 setFormControlValueMatchesRenderer(true);
930 InputElement::notifyFormStateChanged(this);
931 setNeedsValidityCheck();
934 void* HTMLInputElement::preDispatchEventHandler(Event* event)
936 if (event->type() != eventNames().clickEvent)
938 // FIXME: Check whether there are any cases where this actually ends up leaking.
939 return m_inputType->willDispatchClick().leakPtr();
942 void HTMLInputElement::postDispatchEventHandler(Event* event, void* dataFromPreDispatch)
944 OwnPtr<ClickHandlingState> state = adoptPtr(static_cast<ClickHandlingState*>(dataFromPreDispatch));
945 if (event->type() != eventNames().clickEvent)
949 m_inputType->didDispatchClick(event, *state);
952 void HTMLInputElement::defaultEventHandler(Event* evt)
954 if (evt->isMouseEvent() && evt->type() == eventNames().clickEvent) {
955 m_inputType->handleClickEvent(static_cast<MouseEvent*>(evt));
956 if (evt->defaultHandled())
960 if (evt->isKeyboardEvent() && evt->type() == eventNames().keydownEvent) {
961 m_inputType->handleKeydownEvent(static_cast<KeyboardEvent*>(evt));
962 if (evt->defaultHandled())
966 // Call the base event handler before any of our own event handling for almost all events in text fields.
967 // Makes editing keyboard handling take precedence over the keydown and keypress handling in this function.
968 bool callBaseClassEarly = isTextField() && (evt->type() == eventNames().keydownEvent || evt->type() == eventNames().keypressEvent);
969 if (callBaseClassEarly) {
970 HTMLFormControlElementWithState::defaultEventHandler(evt);
971 if (evt->defaultHandled())
975 // DOMActivate events cause the input to be "activated" - in the case of image and submit inputs, this means
976 // actually submitting the form. For reset inputs, the form is reset. These events are sent when the user clicks
977 // on the element, or presses enter while it is the active element. JavaScript code wishing to activate the element
978 // must dispatch a DOMActivate event - a click event will not do the job.
979 if (evt->type() == eventNames().DOMActivateEvent) {
980 m_inputType->handleDOMActivateEvent(evt);
981 if (evt->defaultHandled())
985 // Use key press event here since sending simulated mouse events
986 // on key down blocks the proper sending of the key press event.
987 if (evt->isKeyboardEvent() && evt->type() == eventNames().keypressEvent) {
988 m_inputType->handleKeypressEvent(static_cast<KeyboardEvent*>(evt));
989 if (evt->defaultHandled())
993 if (evt->isKeyboardEvent() && evt->type() == eventNames().keyupEvent) {
994 m_inputType->handleKeyupEvent(static_cast<KeyboardEvent*>(evt));
995 if (evt->defaultHandled())
999 if (m_inputType->shouldSubmitImplicitly(evt)) {
1000 if (isSearchField()) {
1004 // Fire onChange for text fields.
1005 RenderObject* r = renderer();
1006 if (r && r->isTextField() && toRenderTextControl(r)->wasChangedSinceLastChangeEvent()) {
1007 dispatchFormControlChangeEvent();
1008 // Refetch the renderer since arbitrary JS code run during onchange can do anything, including destroying it.
1010 if (r && r->isTextField())
1011 toRenderTextControl(r)->setChangedSinceLastChangeEvent(false);
1014 RefPtr<HTMLFormElement> formForSubmission = m_inputType->formForSubmission();
1015 // Form may never have been present, or may have been destroyed by code responding to the change event.
1016 if (formForSubmission)
1017 formForSubmission->submitImplicitly(evt, canTriggerImplicitSubmission());
1019 evt->setDefaultHandled();
1023 if (evt->isBeforeTextInsertedEvent())
1024 m_inputType->handleBeforeTextInsertedEvent(static_cast<BeforeTextInsertedEvent*>(evt));
1026 if (evt->isWheelEvent()) {
1027 m_inputType->handleWheelEvent(static_cast<WheelEvent*>(evt));
1028 if (evt->defaultHandled())
1032 m_inputType->forwardEvent(evt);
1034 if (!callBaseClassEarly && !evt->defaultHandled())
1035 HTMLFormControlElementWithState::defaultEventHandler(evt);
1038 bool HTMLInputElement::isURLAttribute(Attribute *attr) const
1040 return (attr->name() == srcAttr || attr->name() == formactionAttr);
1043 String HTMLInputElement::defaultValue() const
1045 return fastGetAttribute(valueAttr);
1048 void HTMLInputElement::setDefaultValue(const String &value)
1050 setAttribute(valueAttr, value);
1053 void HTMLInputElement::setDefaultName(const AtomicString& name)
1055 m_data.setName(name);
1058 String HTMLInputElement::accept() const
1060 return fastGetAttribute(acceptAttr);
1063 String HTMLInputElement::alt() const
1065 return fastGetAttribute(altAttr);
1068 int HTMLInputElement::maxLength() const
1070 return m_data.maxLength();
1073 void HTMLInputElement::setMaxLength(int maxLength, ExceptionCode& ec)
1076 ec = INDEX_SIZE_ERR;
1078 setAttribute(maxlengthAttr, String::number(maxLength));
1081 bool HTMLInputElement::multiple() const
1083 return fastHasAttribute(multipleAttr);
1086 void HTMLInputElement::setSize(unsigned size)
1088 setAttribute(sizeAttr, String::number(size));
1091 KURL HTMLInputElement::src() const
1093 return document()->completeURL(fastGetAttribute(srcAttr));
1096 void HTMLInputElement::setAutofilled(bool autofilled)
1098 if (autofilled == m_isAutofilled)
1101 m_isAutofilled = autofilled;
1102 setNeedsStyleRecalc();
1105 FileList* HTMLInputElement::files()
1107 return m_inputType->files();
1110 bool HTMLInputElement::isAcceptableValue(const String& proposedValue) const
1112 return m_inputType->isAcceptableValue(proposedValue);
1115 String HTMLInputElement::sanitizeValue(const String& proposedValue) const
1117 return m_inputType->sanitizeValue(proposedValue);
1120 bool HTMLInputElement::hasUnacceptableValue() const
1122 return m_inputType->hasUnacceptableValue();
1125 bool HTMLInputElement::isInRange() const
1127 return m_inputType->supportsRangeLimitation() && !rangeUnderflow(value()) && !rangeOverflow(value());
1130 bool HTMLInputElement::isOutOfRange() const
1132 return m_inputType->supportsRangeLimitation() && (rangeUnderflow(value()) || rangeOverflow(value()));
1135 bool HTMLInputElement::needsActivationCallback()
1137 return m_autocomplete == Off || m_inputType->shouldResetOnDocumentActivation();
1140 void HTMLInputElement::registerForActivationCallbackIfNeeded()
1142 if (needsActivationCallback())
1143 document()->registerForDocumentActivationCallbacks(this);
1146 void HTMLInputElement::unregisterForActivationCallbackIfNeeded()
1148 if (!needsActivationCallback())
1149 document()->unregisterForDocumentActivationCallbacks(this);
1152 bool HTMLInputElement::isRequiredFormControl() const
1154 return m_inputType->supportsRequired() && required();
1157 void HTMLInputElement::cacheSelection(int start, int end)
1159 m_data.setCachedSelectionStart(start);
1160 m_data.setCachedSelectionEnd(end);
1163 void HTMLInputElement::addSearchResult()
1165 ASSERT(isSearchField());
1167 toRenderTextControlSingleLine(renderer())->addSearchResult();
1170 void HTMLInputElement::onSearch()
1172 ASSERT(isSearchField());
1174 toRenderTextControlSingleLine(renderer())->stopSearchEventTimer();
1175 dispatchEvent(Event::create(eventNames().searchEvent, true, false));
1178 void HTMLInputElement::documentDidBecomeActive()
1180 ASSERT(needsActivationCallback());
1184 void HTMLInputElement::willMoveToNewOwnerDocument()
1186 m_inputType->willMoveToNewOwnerDocument();
1188 // Always unregister for cache callbacks when leaving a document, even if we would otherwise like to be registered
1189 if (needsActivationCallback())
1190 document()->unregisterForDocumentActivationCallbacks(this);
1192 document()->checkedRadioButtons().removeButton(this);
1194 HTMLFormControlElementWithState::willMoveToNewOwnerDocument();
1197 void HTMLInputElement::didMoveToNewOwnerDocument()
1199 registerForActivationCallbackIfNeeded();
1201 HTMLFormControlElementWithState::didMoveToNewOwnerDocument();
1204 void HTMLInputElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
1206 HTMLFormControlElementWithState::addSubresourceAttributeURLs(urls);
1208 addSubresourceURL(urls, src());
1211 bool HTMLInputElement::recalcWillValidate() const
1213 return m_inputType->supportsValidation() && HTMLFormControlElementWithState::recalcWillValidate();
1216 #if ENABLE(DATALIST)
1218 HTMLElement* HTMLInputElement::list() const
1223 HTMLDataListElement* HTMLInputElement::dataList() const
1225 if (!m_hasNonEmptyList)
1228 if (!m_inputType->shouldRespectListAttribute())
1231 Element* element = document()->getElementById(fastGetAttribute(listAttr));
1234 if (!element->hasTagName(datalistTag))
1237 return static_cast<HTMLDataListElement*>(element);
1240 HTMLOptionElement* HTMLInputElement::selectedOption() const
1242 String value = this->value();
1244 // The empty string never matches to a datalist option because it
1245 // doesn't represent a suggestion according to the standard.
1246 if (value.isEmpty())
1249 HTMLDataListElement* sourceElement = dataList();
1252 RefPtr<HTMLCollection> options = sourceElement->options();
1255 unsigned length = options->length();
1256 for (unsigned i = 0; i < length; ++i) {
1257 HTMLOptionElement* option = static_cast<HTMLOptionElement*>(options->item(i));
1258 if (!option->disabled() && value == option->value())
1264 #endif // ENABLE(DATALIST)
1266 void HTMLInputElement::stepUpFromRenderer(int n)
1268 // The differences from stepUp()/stepDown():
1270 // Difference 1: the current value
1271 // If the current value is not a number, including empty, the current value is assumed as 0.
1272 // * If 0 is in-range, and matches to step value
1273 // - The value should be the +step if n > 0
1274 // - The value should be the -step if n < 0
1275 // If -step or +step is out of range, new value should be 0.
1276 // * If 0 is smaller than the minimum value
1277 // - The value should be the minimum value for any n
1278 // * If 0 is larger than the maximum value
1279 // - The value should be the maximum value for any n
1280 // * If 0 is in-range, but not matched to step value
1281 // - The value should be the larger matched value nearest to 0 if n > 0
1282 // e.g. <input type=number min=-100 step=3> -> 2
1283 // - The value should be the smaler matched value nearest to 0 if n < 0
1284 // e.g. <input type=number min=-100 step=3> -> -1
1285 // As for date/datetime-local/month/time/week types, the current value is assumed as "the current local date/time".
1286 // As for datetime type, the current value is assumed as "the current date/time in UTC".
1287 // If the current value is smaller than the minimum value:
1288 // - The value should be the minimum value if n > 0
1289 // - Nothing should happen if n < 0
1290 // If the current value is larger than the maximum value:
1291 // - The value should be the maximum value if n < 0
1292 // - Nothing should happen if n > 0
1294 // Difference 2: clamping steps
1295 // If the current value is not matched to step value:
1296 // - The value should be the larger matched value nearest to 0 if n > 0
1297 // e.g. <input type=number value=3 min=-100 step=3> -> 5
1298 // - The value should be the smaler matched value nearest to 0 if n < 0
1299 // e.g. <input type=number value=3 min=-100 step=3> -> 2
1301 // n is assumed as -n if step < 0.
1303 ASSERT(hasSpinButton() || m_inputType->isRangeControl());
1304 if (!hasSpinButton() && !m_inputType->isRangeControl())
1310 unsigned stepDecimalPlaces, baseDecimalPlaces;
1312 // The value will be the default value after stepping for <input value=(empty/invalid) step="any" />
1313 // FIXME: Not any changes after stepping, even if it is an invalid value, may be better.
1314 // (e.g. Stepping-up for <input type="number" value="foo" step="any" /> => "foo")
1315 if (equalIgnoringCase(fastGetAttribute(stepAttr), "any"))
1317 else if (!getAllowedValueStepWithDecimalPlaces(&step, &stepDecimalPlaces))
1319 base = m_inputType->stepBaseWithDecimalPlaces(&baseDecimalPlaces);
1320 baseDecimalPlaces = min(baseDecimalPlaces, 16u);
1330 const double nan = numeric_limits<double>::quiet_NaN();
1331 String currentStringValue = value();
1332 double current = m_inputType->parseToDouble(currentStringValue, nan);
1333 if (!isfinite(current)) {
1335 current = m_inputType->defaultValueForStepUp();
1336 setValueAsNumber(current, ec);
1338 if ((sign > 0 && current < m_inputType->minimum()) || (sign < 0 && current > m_inputType->maximum()))
1339 setValue(m_inputType->serialize(sign > 0 ? m_inputType->minimum() : m_inputType->maximum()));
1342 if (stepMismatch(currentStringValue)) {
1345 double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces)));
1348 newValue = round((base + floor((current - base) / step) * step) * scale) / scale;
1350 newValue = round((base + ceil((current - base) / step) * step) * scale) / scale;
1354 if (newValue < m_inputType->minimum())
1355 newValue = m_inputType->minimum();
1356 if (newValue > m_inputType->maximum())
1357 newValue = m_inputType->maximum();
1359 setValueAsNumber(newValue, ec);
1362 applyStep(n - 1, ec);
1364 applyStep(n + 1, ec);
1369 if (currentStringValue != value()) {
1370 if (renderer() && renderer()->isTextField())
1371 toRenderTextControl(renderer())->setChangedSinceLastChangeEvent(true);
1372 if (m_inputType->isRangeControl())
1373 dispatchFormControlChangeEvent();
1375 dispatchEvent(Event::create(eventNames().inputEvent, true, false));
1381 void HTMLInputElement::setWapInputFormat(String& mask)
1383 String validateMask = validateInputMask(m_data, mask);
1384 if (!validateMask.isEmpty())
1385 m_data.setInputFormatMask(validateMask);
1390 #if ENABLE(INPUT_SPEECH)
1392 bool HTMLInputElement::isSpeechEnabled() const
1394 // FIXME: Add support for RANGE, EMAIL, URL, COLOR and DATE/TIME input types.
1395 return m_inputType->shouldRespectSpeechAttribute() && RuntimeEnabledFeatures::speechInputEnabled() && hasAttribute(webkitspeechAttr);
1400 bool HTMLInputElement::isTextButton() const
1402 return m_inputType->isTextButton();
1405 bool HTMLInputElement::isRadioButton() const
1407 return m_inputType->isRadioButton();
1410 bool HTMLInputElement::isSearchField() const
1412 return m_inputType->isSearchField();
1415 bool HTMLInputElement::isInputTypeHidden() const
1417 return m_inputType->isHiddenType();
1420 bool HTMLInputElement::isPasswordField() const
1422 return m_inputType->isPasswordField();
1425 bool HTMLInputElement::isCheckbox() const
1427 return m_inputType->isCheckbox();
1430 bool HTMLInputElement::isText() const
1432 return m_inputType->isTextType();
1435 bool HTMLInputElement::isEmailField() const
1437 return m_inputType->isEmailField();
1440 bool HTMLInputElement::isFileUpload() const
1442 return m_inputType->isFileUpload();
1445 bool HTMLInputElement::isImageButton() const
1447 return m_inputType->isImageButton();
1450 bool HTMLInputElement::isNumberField() const
1452 return m_inputType->isNumberField();
1455 bool HTMLInputElement::isSubmitButton() const
1457 return m_inputType->isSubmitButton();
1460 bool HTMLInputElement::isTelephoneField() const
1462 return m_inputType->isTelephoneField();
1465 bool HTMLInputElement::isURLField() const
1467 return m_inputType->isURLField();
1470 bool HTMLInputElement::isEnumeratable() const
1472 return m_inputType->isEnumeratable();
1475 bool HTMLInputElement::isChecked() const
1477 return checked() && m_inputType->isCheckable();
1480 bool HTMLInputElement::hasSpinButton() const
1482 return m_inputType->hasSpinButton();
1485 bool HTMLInputElement::supportsPlaceholder() const
1487 return isTextType();
1490 CheckedRadioButtons& HTMLInputElement::checkedRadioButtons() const
1492 if (HTMLFormElement* formElement = form())
1493 return formElement->checkedRadioButtons();
1494 return document()->checkedRadioButtons();
1497 void HTMLInputElement::handleBeforeTextInsertedEvent(Event* event)
1499 InputElement::handleBeforeTextInsertedEvent(m_data, this, this, event);