Home | History | Annotate | Download | only in html
      1 /*
      2  * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org)
      3  *           (C) 1999 Antti Koivisto (koivisto (at) kde.org)
      4  *           (C) 2001 Dirk Mueller (mueller (at) kde.org)
      5  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
      6  *           (C) 2006 Alexey Proskuryakov (ap (at) nypop.com)
      7  * Copyright (C) 2007 Samuel Weinig (sam (at) 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 "HTMLInputElement.h"
     29 
     30 #include "AXObjectCache.h"
     31 #include "Attribute.h"
     32 #include "BeforeTextInsertedEvent.h"
     33 #include "CSSPropertyNames.h"
     34 #include "Document.h"
     35 #include "EventNames.h"
     36 #include "ExceptionCode.h"
     37 #include "FileList.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 "PlatformMouseEvent.h"
     49 #include "RenderTextControlSingleLine.h"
     50 #include "RenderTheme.h"
     51 #include "RuntimeEnabledFeatures.h"
     52 #include "ScriptEventListener.h"
     53 #include "WheelEvent.h"
     54 #include <wtf/MathExtras.h>
     55 #include <wtf/StdLibExtras.h>
     56 
     57 #ifdef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS
     58 #include "PlatformBridge.h"
     59 #endif
     60 
     61 #if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
     62 #include "TouchEvent.h"
     63 #endif
     64 
     65 using namespace std;
     66 
     67 namespace WebCore {
     68 
     69 using namespace HTMLNames;
     70 
     71 const int maxSavedResults = 256;
     72 
     73 HTMLInputElement::HTMLInputElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form, bool createdByParser)
     74     : HTMLTextFormControlElement(tagName, document, form)
     75     , m_maxResults(-1)
     76     , m_isChecked(false)
     77     , m_reflectsCheckedAttribute(true)
     78     , m_isIndeterminate(false)
     79     , m_hasType(false)
     80     , m_isActivatedSubmit(false)
     81     , m_autocomplete(Uninitialized)
     82     , m_isAutofilled(false)
     83     , m_stateRestored(false)
     84     , m_parsingInProgress(createdByParser)
     85     , m_inputType(InputType::createText(this))
     86 {
     87     ASSERT(hasTagName(inputTag) || hasTagName(isindexTag));
     88 }
     89 
     90 PassRefPtr<HTMLInputElement> HTMLInputElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form, bool createdByParser)
     91 {
     92     return adoptRef(new HTMLInputElement(tagName, document, form, createdByParser));
     93 }
     94 
     95 HTMLInputElement::~HTMLInputElement()
     96 {
     97     if (needsActivationCallback())
     98         document()->unregisterForDocumentActivationCallbacks(this);
     99 
    100     document()->checkedRadioButtons().removeButton(this);
    101 
    102     // Need to remove this from the form while it is still an HTMLInputElement,
    103     // so can't wait for the base class's destructor to do it.
    104     removeFromForm();
    105 }
    106 
    107 const AtomicString& HTMLInputElement::formControlName() const
    108 {
    109     return m_data.name();
    110 }
    111 
    112 bool HTMLInputElement::autoComplete() const
    113 {
    114     if (m_autocomplete != Uninitialized)
    115         return m_autocomplete == On;
    116     return HTMLTextFormControlElement::autoComplete();
    117 }
    118 
    119 void HTMLInputElement::updateCheckedRadioButtons()
    120 {
    121     if (attached() && checked())
    122         checkedRadioButtons().addButton(this);
    123 
    124     if (form()) {
    125         const Vector<FormAssociatedElement*>& controls = form()->associatedElements();
    126         for (unsigned i = 0; i < controls.size(); ++i) {
    127             if (!controls[i]->isFormControlElement())
    128                 continue;
    129             HTMLFormControlElement* control = static_cast<HTMLFormControlElement*>(controls[i]);
    130             if (control->name() != name())
    131                 continue;
    132             if (control->type() != type())
    133                 continue;
    134             control->setNeedsValidityCheck();
    135         }
    136     } else {
    137         // FIXME: Traversing the document is inefficient.
    138         for (Node* node = document()->body(); node; node = node->traverseNextNode()) {
    139             if (!node->isElementNode())
    140                 continue;
    141             Element* element = static_cast<Element*>(node);
    142             if (element->formControlName() != name())
    143                 continue;
    144             if (element->formControlType() != type())
    145                 continue;
    146             HTMLFormControlElement* control = static_cast<HTMLFormControlElement*>(element);
    147             if (control->form())
    148                 continue;
    149             control->setNeedsValidityCheck();
    150         }
    151     }
    152 
    153     if (renderer() && renderer()->style()->hasAppearance())
    154         renderer()->theme()->stateChanged(renderer(), CheckedState);
    155 }
    156 
    157 bool HTMLInputElement::lastChangeWasUserEdit() const
    158 {
    159     if (!isTextField())
    160         return false;
    161 
    162     if (!renderer())
    163         return false;
    164 
    165     return toRenderTextControl(renderer())->lastChangeWasUserEdit();
    166 }
    167 
    168 bool HTMLInputElement::isValidValue(const String& value) const
    169 {
    170     if (!m_inputType->canSetStringValue()) {
    171         ASSERT_NOT_REACHED();
    172         return false;
    173     }
    174     return !m_inputType->typeMismatchFor(value)
    175         && !stepMismatch(value)
    176         && !rangeUnderflow(value)
    177         && !rangeOverflow(value)
    178         && !tooLong(value, IgnoreDirtyFlag)
    179         && !patternMismatch(value)
    180         && !valueMissing(value);
    181 }
    182 
    183 bool HTMLInputElement::typeMismatch() const
    184 {
    185     return m_inputType->typeMismatch();
    186 }
    187 
    188 bool HTMLInputElement::valueMissing(const String& value) const
    189 {
    190     if (!isRequiredFormControl() || readOnly() || disabled())
    191         return false;
    192     return m_inputType->valueMissing(value);
    193 }
    194 
    195 bool HTMLInputElement::patternMismatch(const String& value) const
    196 {
    197     return m_inputType->patternMismatch(value);
    198 }
    199 
    200 bool HTMLInputElement::tooLong(const String& value, NeedsToCheckDirtyFlag check) const
    201 {
    202     // We use isTextType() instead of supportsMaxLength() because of the
    203     // 'virtual' overhead.
    204     if (!isTextType())
    205         return false;
    206     int max = maxLength();
    207     if (max < 0)
    208         return false;
    209     if (check == CheckDirtyFlag) {
    210         // Return false for the default value even if it is longer than maxLength.
    211         bool userEdited = !m_data.value().isNull();
    212         if (!userEdited)
    213             return false;
    214     }
    215     return numGraphemeClusters(value) > static_cast<unsigned>(max);
    216 }
    217 
    218 bool HTMLInputElement::rangeUnderflow(const String& value) const
    219 {
    220     return m_inputType->rangeUnderflow(value);
    221 }
    222 
    223 bool HTMLInputElement::rangeOverflow(const String& value) const
    224 {
    225     return m_inputType->rangeOverflow(value);
    226 }
    227 
    228 double HTMLInputElement::minimum() const
    229 {
    230     return m_inputType->minimum();
    231 }
    232 
    233 double HTMLInputElement::maximum() const
    234 {
    235     return m_inputType->maximum();
    236 }
    237 
    238 bool HTMLInputElement::stepMismatch(const String& value) const
    239 {
    240     double step;
    241     if (!getAllowedValueStep(&step))
    242         return false;
    243     return m_inputType->stepMismatch(value, step);
    244 }
    245 
    246 String HTMLInputElement::minimumString() const
    247 {
    248     return m_inputType->serialize(minimum());
    249 }
    250 
    251 String HTMLInputElement::maximumString() const
    252 {
    253     return m_inputType->serialize(maximum());
    254 }
    255 
    256 String HTMLInputElement::stepBaseString() const
    257 {
    258     return m_inputType->serialize(m_inputType->stepBase());
    259 }
    260 
    261 String HTMLInputElement::stepString() const
    262 {
    263     double step;
    264     if (!getAllowedValueStep(&step)) {
    265         // stepString() should be called only if stepMismatch() can be true.
    266         ASSERT_NOT_REACHED();
    267         return String();
    268     }
    269     return serializeForNumberType(step / m_inputType->stepScaleFactor());
    270 }
    271 
    272 String HTMLInputElement::typeMismatchText() const
    273 {
    274     return m_inputType->typeMismatchText();
    275 }
    276 
    277 String HTMLInputElement::valueMissingText() const
    278 {
    279     return m_inputType->valueMissingText();
    280 }
    281 
    282 bool HTMLInputElement::getAllowedValueStep(double* step) const
    283 {
    284     return getAllowedValueStepWithDecimalPlaces(step, 0);
    285 }
    286 
    287 bool HTMLInputElement::getAllowedValueStepWithDecimalPlaces(double* step, unsigned* decimalPlaces) const
    288 {
    289     ASSERT(step);
    290     double defaultStep = m_inputType->defaultStep();
    291     double stepScaleFactor = m_inputType->stepScaleFactor();
    292     if (!isfinite(defaultStep) || !isfinite(stepScaleFactor))
    293         return false;
    294     const AtomicString& stepString = fastGetAttribute(stepAttr);
    295     if (stepString.isEmpty()) {
    296         *step = defaultStep * stepScaleFactor;
    297         if (decimalPlaces)
    298             *decimalPlaces = 0;
    299         return true;
    300     }
    301     if (equalIgnoringCase(stepString, "any"))
    302         return false;
    303     double parsed;
    304     if (!decimalPlaces) {
    305         if (!parseToDoubleForNumberType(stepString, &parsed) || parsed <= 0.0) {
    306             *step = defaultStep * stepScaleFactor;
    307             return true;
    308         }
    309     } else {
    310         if (!parseToDoubleForNumberTypeWithDecimalPlaces(stepString, &parsed, decimalPlaces) || parsed <= 0.0) {
    311             *step = defaultStep * stepScaleFactor;
    312             *decimalPlaces = 0;
    313             return true;
    314         }
    315     }
    316     // For date, month, week, the parsed value should be an integer for some types.
    317     if (m_inputType->parsedStepValueShouldBeInteger())
    318         parsed = max(round(parsed), 1.0);
    319     double result = parsed * stepScaleFactor;
    320     // For datetime, datetime-local, time, the result should be an integer.
    321     if (m_inputType->scaledStepValueShouldBeInteger())
    322         result = max(round(result), 1.0);
    323     ASSERT(result > 0);
    324     *step = result;
    325     return true;
    326 }
    327 
    328 void HTMLInputElement::applyStep(double count, ExceptionCode& ec)
    329 {
    330     double step;
    331     unsigned stepDecimalPlaces, currentDecimalPlaces;
    332     if (!getAllowedValueStepWithDecimalPlaces(&step, &stepDecimalPlaces)) {
    333         ec = INVALID_STATE_ERR;
    334         return;
    335     }
    336     const double nan = numeric_limits<double>::quiet_NaN();
    337     double current = m_inputType->parseToDoubleWithDecimalPlaces(value(), nan, &currentDecimalPlaces);
    338     if (!isfinite(current)) {
    339         ec = INVALID_STATE_ERR;
    340         return;
    341     }
    342     double newValue = current + step * count;
    343     if (isinf(newValue)) {
    344         ec = INVALID_STATE_ERR;
    345         return;
    346     }
    347     double acceptableError = m_inputType->acceptableError(step);
    348     if (newValue - m_inputType->minimum() < -acceptableError) {
    349         ec = INVALID_STATE_ERR;
    350         return;
    351     }
    352     if (newValue < m_inputType->minimum())
    353         newValue = m_inputType->minimum();
    354     unsigned baseDecimalPlaces;
    355     double base = m_inputType->stepBaseWithDecimalPlaces(&baseDecimalPlaces);
    356     baseDecimalPlaces = min(baseDecimalPlaces, 16u);
    357     if (newValue < pow(10.0, 21.0)) {
    358       if (stepMismatch(value())) {
    359             double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, currentDecimalPlaces)));
    360             newValue = round(newValue * scale) / scale;
    361         } else {
    362             double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces)));
    363             newValue = round((base + round((newValue - base) / step) * step) * scale) / scale;
    364         }
    365     }
    366     if (newValue - m_inputType->maximum() > acceptableError) {
    367         ec = INVALID_STATE_ERR;
    368         return;
    369     }
    370     if (newValue > m_inputType->maximum())
    371         newValue = m_inputType->maximum();
    372     setValueAsNumber(newValue, ec);
    373 
    374     if (AXObjectCache::accessibilityEnabled())
    375          document()->axObjectCache()->postNotification(renderer(), AXObjectCache::AXValueChanged, true);
    376 }
    377 
    378 void HTMLInputElement::stepUp(int n, ExceptionCode& ec)
    379 {
    380     applyStep(n, ec);
    381 }
    382 
    383 void HTMLInputElement::stepDown(int n, ExceptionCode& ec)
    384 {
    385     applyStep(-n, ec);
    386 }
    387 
    388 bool HTMLInputElement::isKeyboardFocusable(KeyboardEvent* event) const
    389 {
    390     if (isTextField())
    391         return HTMLFormControlElementWithState::isFocusable();
    392     return HTMLFormControlElementWithState::isKeyboardFocusable(event) && m_inputType->isKeyboardFocusable();
    393 }
    394 
    395 bool HTMLInputElement::isMouseFocusable() const
    396 {
    397     if (isTextField())
    398         return HTMLFormControlElementWithState::isFocusable();
    399     return HTMLFormControlElementWithState::isMouseFocusable();
    400 }
    401 
    402 void HTMLInputElement::updateFocusAppearance(bool restorePreviousSelection)
    403 {
    404     if (isTextField())
    405         InputElement::updateFocusAppearance(m_data, this, this, restorePreviousSelection);
    406     else
    407         HTMLFormControlElementWithState::updateFocusAppearance(restorePreviousSelection);
    408 }
    409 
    410 void HTMLInputElement::aboutToUnload()
    411 {
    412     InputElement::aboutToUnload(this, this);
    413 }
    414 
    415 bool HTMLInputElement::shouldUseInputMethod() const
    416 {
    417     return m_inputType->shouldUseInputMethod();
    418 }
    419 
    420 void HTMLInputElement::handleFocusEvent()
    421 {
    422     InputElement::dispatchFocusEvent(this, this);
    423 }
    424 
    425 void HTMLInputElement::handleBlurEvent()
    426 {
    427     m_inputType->handleBlurEvent();
    428     InputElement::dispatchBlurEvent(this, this);
    429 }
    430 
    431 void HTMLInputElement::setType(const String& type)
    432 {
    433     // FIXME: This should just call setAttribute. No reason to handle the empty string specially.
    434     // We should write a test case to show that setting to the empty string does not remove the
    435     // attribute in other browsers and then fix this. Note that setting to null *does* remove
    436     // the attribute and setAttribute implements that.
    437     if (type.isEmpty()) {
    438         ExceptionCode ec;
    439         removeAttribute(typeAttr, ec);
    440     } else
    441         setAttribute(typeAttr, type);
    442 }
    443 
    444 void HTMLInputElement::updateType()
    445 {
    446     OwnPtr<InputType> newType = InputType::create(this, fastGetAttribute(typeAttr));
    447 #ifdef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS
    448     if (newType->isPasswordField() && document()->focusedNode() == this)
    449         PlatformBridge::updateTextfield(document()->view(), this, true, String());
    450 #endif
    451     bool hadType = m_hasType;
    452     m_hasType = true;
    453     if (m_inputType->formControlType() == newType->formControlType())
    454         return;
    455 
    456     if (hadType && !newType->canChangeFromAnotherType()) {
    457         // Set the attribute back to the old value.
    458         // Useful in case we were called from inside parseMappedAttribute.
    459         setAttribute(typeAttr, type());
    460         return;
    461     }
    462 
    463     checkedRadioButtons().removeButton(this);
    464 
    465     bool wasAttached = attached();
    466     if (wasAttached)
    467         detach();
    468 
    469     bool didStoreValue = m_inputType->storesValueSeparateFromAttribute();
    470     bool neededActivationCallback = needsActivationCallback();
    471     bool didRespectHeightAndWidth = m_inputType->shouldRespectHeightAndWidthAttributes();
    472 
    473     m_inputType->destroyShadowSubtree();
    474     m_inputType = newType.release();
    475     m_inputType->createShadowSubtree();
    476 
    477     setNeedsWillValidateCheck();
    478 
    479     bool willStoreValue = m_inputType->storesValueSeparateFromAttribute();
    480 
    481     if (didStoreValue && !willStoreValue && !m_data.value().isNull()) {
    482         setAttribute(valueAttr, m_data.value());
    483         m_data.setValue(String());
    484     }
    485     if (!didStoreValue && willStoreValue)
    486         m_data.setValue(sanitizeValue(fastGetAttribute(valueAttr)));
    487     else
    488         InputElement::updateValueIfNeeded(m_data, this);
    489 
    490     if (neededActivationCallback)
    491         unregisterForActivationCallbackIfNeeded();
    492     else
    493         registerForActivationCallbackIfNeeded();
    494 
    495     if (didRespectHeightAndWidth != m_inputType->shouldRespectHeightAndWidthAttributes()) {
    496         NamedNodeMap* map = attributeMap();
    497         ASSERT(map);
    498         if (Attribute* height = map->getAttributeItem(heightAttr))
    499             attributeChanged(height, false);
    500         if (Attribute* width = map->getAttributeItem(widthAttr))
    501             attributeChanged(width, false);
    502         if (Attribute* align = map->getAttributeItem(alignAttr))
    503             attributeChanged(align, false);
    504     }
    505 
    506     if (wasAttached) {
    507         attach();
    508         if (document()->focusedNode() == this)
    509             updateFocusAppearance(true);
    510     }
    511 
    512     setChangedSinceLastFormControlChangeEvent(false);
    513 
    514     checkedRadioButtons().addButton(this);
    515 
    516     setNeedsValidityCheck();
    517     InputElement::notifyFormStateChanged(this);
    518 }
    519 
    520 const AtomicString& HTMLInputElement::formControlType() const
    521 {
    522     return m_inputType->formControlType();
    523 }
    524 
    525 bool HTMLInputElement::saveFormControlState(String& result) const
    526 {
    527     return m_inputType->saveFormControlState(result);
    528 }
    529 
    530 void HTMLInputElement::restoreFormControlState(const String& state)
    531 {
    532     m_inputType->restoreFormControlState(state);
    533     m_stateRestored = true;
    534 }
    535 
    536 bool HTMLInputElement::canStartSelection() const
    537 {
    538     if (!isTextField())
    539         return false;
    540     return HTMLFormControlElementWithState::canStartSelection();
    541 }
    542 
    543 bool HTMLInputElement::canHaveSelection() const
    544 {
    545     return isTextField();
    546 }
    547 
    548 void HTMLInputElement::accessKeyAction(bool sendToAnyElement)
    549 {
    550     m_inputType->accessKeyAction(sendToAnyElement);
    551 }
    552 
    553 bool HTMLInputElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
    554 {
    555     if (((attrName == heightAttr || attrName == widthAttr) && m_inputType->shouldRespectHeightAndWidthAttributes())
    556         || attrName == vspaceAttr
    557         || attrName == hspaceAttr) {
    558         result = eUniversal;
    559         return false;
    560     }
    561 
    562     if (attrName == alignAttr && m_inputType->shouldRespectAlignAttribute()) {
    563         // Share with <img> since the alignment behavior is the same.
    564         result = eReplaced;
    565         return false;
    566     }
    567 
    568     return HTMLElement::mapToEntry(attrName, result);
    569 }
    570 
    571 void HTMLInputElement::parseMappedAttribute(Attribute* attr)
    572 {
    573     if (attr->name() == nameAttr) {
    574         checkedRadioButtons().removeButton(this);
    575         m_data.setName(attr->value());
    576         checkedRadioButtons().addButton(this);
    577         HTMLFormControlElementWithState::parseMappedAttribute(attr);
    578     } else if (attr->name() == autocompleteAttr) {
    579         if (equalIgnoringCase(attr->value(), "off")) {
    580             m_autocomplete = Off;
    581             registerForActivationCallbackIfNeeded();
    582         } else {
    583             bool needsToUnregister = m_autocomplete == Off;
    584 
    585             if (attr->isEmpty())
    586                 m_autocomplete = Uninitialized;
    587             else
    588                 m_autocomplete = On;
    589 
    590             if (needsToUnregister)
    591                 unregisterForActivationCallbackIfNeeded();
    592         }
    593     } else if (attr->name() == typeAttr) {
    594         updateType();
    595     } else if (attr->name() == valueAttr) {
    596         // We only need to setChanged if the form is looking at the default value right now.
    597         if (m_data.value().isNull())
    598             setNeedsStyleRecalc();
    599         setFormControlValueMatchesRenderer(false);
    600         setNeedsValidityCheck();
    601     } else if (attr->name() == checkedAttr) {
    602         // Another radio button in the same group might be checked by state
    603         // restore. We shouldn't call setChecked() even if this has the checked
    604         // attribute. So, delay the setChecked() call until
    605         // finishParsingChildren() is called if parsing is in progress.
    606         if (!m_parsingInProgress && m_reflectsCheckedAttribute) {
    607             setChecked(!attr->isNull());
    608             m_reflectsCheckedAttribute = true;
    609         }
    610     } else if (attr->name() == maxlengthAttr) {
    611         InputElement::parseMaxLengthAttribute(m_data, this, this, attr);
    612         setNeedsValidityCheck();
    613     } else if (attr->name() == sizeAttr)
    614         InputElement::parseSizeAttribute(m_data, this, attr);
    615     else if (attr->name() == altAttr)
    616         m_inputType->altAttributeChanged();
    617     else if (attr->name() == srcAttr)
    618         m_inputType->srcAttributeChanged();
    619     else if (attr->name() == usemapAttr || attr->name() == accesskeyAttr) {
    620         // FIXME: ignore for the moment
    621     } else if (attr->name() == vspaceAttr) {
    622         addCSSLength(attr, CSSPropertyMarginTop, attr->value());
    623         addCSSLength(attr, CSSPropertyMarginBottom, attr->value());
    624     } else if (attr->name() == hspaceAttr) {
    625         addCSSLength(attr, CSSPropertyMarginLeft, attr->value());
    626         addCSSLength(attr, CSSPropertyMarginRight, attr->value());
    627     } else if (attr->name() == alignAttr) {
    628         if (m_inputType->shouldRespectAlignAttribute())
    629             addHTMLAlignment(attr);
    630     } else if (attr->name() == widthAttr) {
    631         if (m_inputType->shouldRespectHeightAndWidthAttributes())
    632             addCSSLength(attr, CSSPropertyWidth, attr->value());
    633     } else if (attr->name() == heightAttr) {
    634         if (m_inputType->shouldRespectHeightAndWidthAttributes())
    635             addCSSLength(attr, CSSPropertyHeight, attr->value());
    636     } else if (attr->name() == onsearchAttr) {
    637         // Search field and slider attributes all just cause updateFromElement to be called through style recalcing.
    638         setAttributeEventListener(eventNames().searchEvent, createAttributeEventListener(this, attr));
    639     } else if (attr->name() == resultsAttr) {
    640         int oldResults = m_maxResults;
    641         m_maxResults = !attr->isNull() ? std::min(attr->value().toInt(), maxSavedResults) : -1;
    642         // FIXME: Detaching just for maxResults change is not ideal.  We should figure out the right
    643         // time to relayout for this change.
    644         if (m_maxResults != oldResults && (m_maxResults <= 0 || oldResults <= 0) && attached()) {
    645             detach();
    646             attach();
    647         }
    648         setNeedsStyleRecalc();
    649     } else if (attr->name() == autosaveAttr || attr->name() == incrementalAttr)
    650         setNeedsStyleRecalc();
    651     else if (attr->name() == minAttr || attr->name() == maxAttr) {
    652         m_inputType->minOrMaxAttributeChanged();
    653         setNeedsValidityCheck();
    654     } else if (attr->name() == multipleAttr || attr->name() == patternAttr || attr->name() == precisionAttr || attr->name() == stepAttr)
    655         setNeedsValidityCheck();
    656 #if ENABLE(DATALIST)
    657     else if (attr->name() == listAttr)
    658         m_hasNonEmptyList = !attr->isEmpty();
    659         // FIXME: we need to tell this change to a renderer if the attribute affects the appearance.
    660 #endif
    661 #if ENABLE(INPUT_SPEECH)
    662     else if (attr->name() == webkitspeechAttr) {
    663         if (renderer()) {
    664             // This renderer and its children have quite different layouts and styles depending on
    665             // whether the speech button is visible or not. So we reset the whole thing and recreate
    666             // to get the right styles and layout.
    667             detach();
    668             attach();
    669         }
    670         setNeedsStyleRecalc();
    671     } else if (attr->name() == onwebkitspeechchangeAttr)
    672         setAttributeEventListener(eventNames().webkitspeechchangeEvent, createAttributeEventListener(this, attr));
    673 #endif
    674     else
    675         HTMLTextFormControlElement::parseMappedAttribute(attr);
    676 }
    677 
    678 void HTMLInputElement::finishParsingChildren()
    679 {
    680     m_parsingInProgress = false;
    681     HTMLFormControlElementWithState::finishParsingChildren();
    682     if (!m_stateRestored) {
    683         bool checked = hasAttribute(checkedAttr);
    684         if (checked)
    685             setChecked(checked);
    686         m_reflectsCheckedAttribute = true;
    687     }
    688 }
    689 
    690 bool HTMLInputElement::rendererIsNeeded(RenderStyle* style)
    691 {
    692     return m_inputType->rendererIsNeeded() && HTMLFormControlElementWithState::rendererIsNeeded(style);
    693 }
    694 
    695 RenderObject* HTMLInputElement::createRenderer(RenderArena* arena, RenderStyle* style)
    696 {
    697     return m_inputType->createRenderer(arena, style);
    698 }
    699 
    700 void HTMLInputElement::attach()
    701 {
    702     suspendPostAttachCallbacks();
    703 
    704     if (!m_hasType)
    705         updateType();
    706 
    707     HTMLFormControlElementWithState::attach();
    708 
    709     m_inputType->attach();
    710 
    711     if (document()->focusedNode() == this)
    712         document()->updateFocusAppearanceSoon(true /* restore selection */);
    713 
    714     resumePostAttachCallbacks();
    715 }
    716 
    717 void HTMLInputElement::detach()
    718 {
    719     HTMLFormControlElementWithState::detach();
    720     setFormControlValueMatchesRenderer(false);
    721 }
    722 
    723 String HTMLInputElement::altText() const
    724 {
    725     // http://www.w3.org/TR/1998/REC-html40-19980424/appendix/notes.html#altgen
    726     // also heavily discussed by Hixie on bugzilla
    727     // note this is intentionally different to HTMLImageElement::altText()
    728     String alt = fastGetAttribute(altAttr);
    729     // fall back to title attribute
    730     if (alt.isNull())
    731         alt = getAttribute(titleAttr);
    732     if (alt.isNull())
    733         alt = getAttribute(valueAttr);
    734     if (alt.isEmpty())
    735         alt = inputElementAltText();
    736     return alt;
    737 }
    738 
    739 bool HTMLInputElement::isSuccessfulSubmitButton() const
    740 {
    741     // HTML spec says that buttons must have names to be considered successful.
    742     // However, other browsers do not impose this constraint. So we do not.
    743     return !disabled() && m_inputType->canBeSuccessfulSubmitButton();
    744 }
    745 
    746 bool HTMLInputElement::isActivatedSubmit() const
    747 {
    748     return m_isActivatedSubmit;
    749 }
    750 
    751 void HTMLInputElement::setActivatedSubmit(bool flag)
    752 {
    753     m_isActivatedSubmit = flag;
    754 }
    755 
    756 bool HTMLInputElement::appendFormData(FormDataList& encoding, bool multipart)
    757 {
    758     return m_inputType->isFormDataAppendable() && m_inputType->appendFormData(encoding, multipart);
    759 }
    760 
    761 void HTMLInputElement::reset()
    762 {
    763     if (m_inputType->storesValueSeparateFromAttribute())
    764         setValue(String());
    765 
    766     setAutofilled(false);
    767     setChecked(hasAttribute(checkedAttr));
    768     m_reflectsCheckedAttribute = true;
    769 }
    770 
    771 bool HTMLInputElement::isTextField() const
    772 {
    773     return m_inputType->isTextField();
    774 }
    775 
    776 bool HTMLInputElement::isTextType() const
    777 {
    778     return m_inputType->isTextType();
    779 }
    780 
    781 void HTMLInputElement::setChecked(bool nowChecked, bool sendChangeEvent)
    782 {
    783     if (checked() == nowChecked)
    784         return;
    785 
    786     checkedRadioButtons().removeButton(this);
    787 
    788     m_reflectsCheckedAttribute = false;
    789     m_isChecked = nowChecked;
    790     setNeedsStyleRecalc();
    791 
    792     updateCheckedRadioButtons();
    793     setNeedsValidityCheck();
    794 
    795     // Ideally we'd do this from the render tree (matching
    796     // RenderTextView), but it's not possible to do it at the moment
    797     // because of the way the code is structured.
    798     if (renderer() && AXObjectCache::accessibilityEnabled())
    799         renderer()->document()->axObjectCache()->postNotification(renderer(), AXObjectCache::AXCheckedStateChanged, true);
    800 
    801     // Only send a change event for items in the document (avoid firing during
    802     // parsing) and don't send a change event for a radio button that's getting
    803     // unchecked to match other browsers. DOM is not a useful standard for this
    804     // because it says only to fire change events at "lose focus" time, which is
    805     // definitely wrong in practice for these types of elements.
    806     if (sendChangeEvent && inDocument() && m_inputType->shouldSendChangeEventAfterCheckedChanged()) {
    807         setTextAsOfLastFormControlChangeEvent(String());
    808         dispatchFormControlChangeEvent();
    809     }
    810 }
    811 
    812 void HTMLInputElement::setIndeterminate(bool newValue)
    813 {
    814     if (!m_inputType->isCheckable() || indeterminate() == newValue)
    815         return;
    816 
    817     m_isIndeterminate = newValue;
    818 
    819     setNeedsStyleRecalc();
    820 
    821     if (renderer() && renderer()->style()->hasAppearance())
    822         renderer()->theme()->stateChanged(renderer(), CheckedState);
    823 }
    824 
    825 int HTMLInputElement::size() const
    826 {
    827     return m_data.size();
    828 }
    829 
    830 void HTMLInputElement::copyNonAttributeProperties(const Element* source)
    831 {
    832     const HTMLInputElement* sourceElement = static_cast<const HTMLInputElement*>(source);
    833 
    834     m_data.setValue(sourceElement->m_data.value());
    835     setChecked(sourceElement->m_isChecked);
    836     m_reflectsCheckedAttribute = sourceElement->m_reflectsCheckedAttribute;
    837     m_isIndeterminate = sourceElement->m_isIndeterminate;
    838 
    839     HTMLFormControlElementWithState::copyNonAttributeProperties(source);
    840 }
    841 
    842 String HTMLInputElement::value() const
    843 {
    844     String value;
    845     if (m_inputType->getTypeSpecificValue(value))
    846         return value;
    847 
    848     value = m_data.value();
    849     if (!value.isNull())
    850         return value;
    851 
    852     value = sanitizeValue(fastGetAttribute(valueAttr));
    853     if (!value.isNull())
    854         return value;
    855 
    856     return m_inputType->fallbackValue();
    857 }
    858 
    859 String HTMLInputElement::valueWithDefault() const
    860 {
    861     String value = this->value();
    862     if (!value.isNull())
    863         return value;
    864 
    865     return m_inputType->defaultValue();
    866 }
    867 
    868 void HTMLInputElement::setValueForUser(const String& value)
    869 {
    870     // Call setValue and make it send a change event.
    871     setValue(value, true);
    872 }
    873 
    874 const String& HTMLInputElement::suggestedValue() const
    875 {
    876     return m_data.suggestedValue();
    877 }
    878 
    879 void HTMLInputElement::setSuggestedValue(const String& value)
    880 {
    881     if (!m_inputType->canSetSuggestedValue())
    882         return;
    883     setFormControlValueMatchesRenderer(false);
    884     m_data.setSuggestedValue(sanitizeValue(value));
    885     updatePlaceholderVisibility(false);
    886     if (renderer())
    887         renderer()->updateFromElement();
    888     setNeedsStyleRecalc();
    889 }
    890 
    891 void HTMLInputElement::setValue(const String& value, bool sendChangeEvent)
    892 {
    893     if (!m_inputType->canSetValue(value))
    894         return;
    895 
    896     setFormControlValueMatchesRenderer(false);
    897     if (m_inputType->storesValueSeparateFromAttribute()) {
    898         if (files())
    899             files()->clear();
    900         else {
    901             m_data.setValue(sanitizeValue(value));
    902             if (isTextField())
    903                 updatePlaceholderVisibility(false);
    904         }
    905         setNeedsStyleRecalc();
    906     } else
    907         setAttribute(valueAttr, sanitizeValue(value));
    908 
    909     setNeedsValidityCheck();
    910 
    911     if (isTextField()) {
    912         unsigned max = m_data.value().length();
    913 #ifdef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS
    914         // Make sure our UI side textfield changes to match the RenderTextControl
    915         PlatformBridge::updateTextfield(document()->view(), this, false, value);
    916 #endif
    917         if (document()->focusedNode() == this)
    918             InputElement::updateSelectionRange(this, this, max, max);
    919         else
    920             cacheSelection(max, max);
    921         m_data.setSuggestedValue(String());
    922     }
    923     m_inputType->valueChanged();
    924 
    925     if (sendChangeEvent) {
    926         // If the user is still editing this field, dispatch an input event rather than a change event.
    927         // The change event will be dispatched when editing finishes.
    928         if (isTextField() && focused())
    929             dispatchFormControlInputEvent();
    930         else
    931             dispatchFormControlChangeEvent();
    932     }
    933 
    934     if (isText() && (!focused() || !sendChangeEvent))
    935         setTextAsOfLastFormControlChangeEvent(value);
    936 
    937     InputElement::notifyFormStateChanged(this);
    938 }
    939 
    940 double HTMLInputElement::valueAsDate() const
    941 {
    942     return m_inputType->valueAsDate();
    943 }
    944 
    945 void HTMLInputElement::setValueAsDate(double value, ExceptionCode& ec)
    946 {
    947     m_inputType->setValueAsDate(value, ec);
    948 }
    949 
    950 double HTMLInputElement::valueAsNumber() const
    951 {
    952     return m_inputType->valueAsNumber();
    953 }
    954 
    955 void HTMLInputElement::setValueAsNumber(double newValue, ExceptionCode& ec)
    956 {
    957     if (!isfinite(newValue)) {
    958         ec = NOT_SUPPORTED_ERR;
    959         return;
    960     }
    961     m_inputType->setValueAsNumber(newValue, ec);
    962 }
    963 
    964 String HTMLInputElement::placeholder() const
    965 {
    966     return fastGetAttribute(placeholderAttr).string();
    967 }
    968 
    969 void HTMLInputElement::setPlaceholder(const String& value)
    970 {
    971     setAttribute(placeholderAttr, value);
    972 }
    973 
    974 bool HTMLInputElement::searchEventsShouldBeDispatched() const
    975 {
    976     return hasAttribute(incrementalAttr);
    977 }
    978 
    979 void HTMLInputElement::setValueFromRenderer(const String& value)
    980 {
    981     // File upload controls will always use setFileListFromRenderer.
    982     ASSERT(!isFileUpload());
    983 
    984     m_data.setSuggestedValue(String());
    985     InputElement::setValueFromRenderer(m_data, this, this, value);
    986     updatePlaceholderVisibility(false);
    987     setNeedsValidityCheck();
    988 
    989     // Clear autofill flag (and yellow background) on user edit.
    990     setAutofilled(false);
    991 }
    992 
    993 void HTMLInputElement::setFileListFromRenderer(const Vector<String>& paths)
    994 {
    995     m_inputType->setFileList(paths);
    996 
    997     setFormControlValueMatchesRenderer(true);
    998     InputElement::notifyFormStateChanged(this);
    999     setNeedsValidityCheck();
   1000 }
   1001 
   1002 void* HTMLInputElement::preDispatchEventHandler(Event* event)
   1003 {
   1004     if (event->type() == eventNames().textInputEvent && m_inputType->shouldSubmitImplicitly(event)) {
   1005         event->stopPropagation();
   1006         return 0;
   1007     }
   1008     if (event->type() != eventNames().clickEvent)
   1009         return 0;
   1010     if (!event->isMouseEvent() || static_cast<MouseEvent*>(event)->button() != LeftButton)
   1011         return 0;
   1012     // FIXME: Check whether there are any cases where this actually ends up leaking.
   1013     return m_inputType->willDispatchClick().leakPtr();
   1014 }
   1015 
   1016 void HTMLInputElement::postDispatchEventHandler(Event* event, void* dataFromPreDispatch)
   1017 {
   1018     OwnPtr<ClickHandlingState> state = adoptPtr(static_cast<ClickHandlingState*>(dataFromPreDispatch));
   1019     if (!state)
   1020         return;
   1021     m_inputType->didDispatchClick(event, *state);
   1022 }
   1023 
   1024 void HTMLInputElement::defaultEventHandler(Event* evt)
   1025 {
   1026     if (evt->isMouseEvent() && evt->type() == eventNames().clickEvent && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
   1027         m_inputType->handleClickEvent(static_cast<MouseEvent*>(evt));
   1028         if (evt->defaultHandled())
   1029             return;
   1030     }
   1031 
   1032     if (evt->isKeyboardEvent() && evt->type() == eventNames().keydownEvent) {
   1033         m_inputType->handleKeydownEvent(static_cast<KeyboardEvent*>(evt));
   1034         if (evt->defaultHandled())
   1035             return;
   1036     }
   1037 
   1038     // Call the base event handler before any of our own event handling for almost all events in text fields.
   1039     // Makes editing keyboard handling take precedence over the keydown and keypress handling in this function.
   1040     bool callBaseClassEarly = isTextField() && (evt->type() == eventNames().keydownEvent || evt->type() == eventNames().keypressEvent);
   1041     if (callBaseClassEarly) {
   1042         HTMLFormControlElementWithState::defaultEventHandler(evt);
   1043         if (evt->defaultHandled())
   1044             return;
   1045     }
   1046 
   1047     // DOMActivate events cause the input to be "activated" - in the case of image and submit inputs, this means
   1048     // actually submitting the form. For reset inputs, the form is reset. These events are sent when the user clicks
   1049     // on the element, or presses enter while it is the active element. JavaScript code wishing to activate the element
   1050     // must dispatch a DOMActivate event - a click event will not do the job.
   1051     if (evt->type() == eventNames().DOMActivateEvent) {
   1052         m_inputType->handleDOMActivateEvent(evt);
   1053         if (evt->defaultHandled())
   1054             return;
   1055     }
   1056 
   1057     // Use key press event here since sending simulated mouse events
   1058     // on key down blocks the proper sending of the key press event.
   1059     if (evt->isKeyboardEvent() && evt->type() == eventNames().keypressEvent) {
   1060         m_inputType->handleKeypressEvent(static_cast<KeyboardEvent*>(evt));
   1061         if (evt->defaultHandled())
   1062             return;
   1063     }
   1064 
   1065     if (evt->isKeyboardEvent() && evt->type() == eventNames().keyupEvent) {
   1066         m_inputType->handleKeyupEvent(static_cast<KeyboardEvent*>(evt));
   1067         if (evt->defaultHandled())
   1068             return;
   1069     }
   1070 
   1071     if (m_inputType->shouldSubmitImplicitly(evt)) {
   1072         if (isSearchField()) {
   1073             addSearchResult();
   1074             onSearch();
   1075         }
   1076         // Form submission finishes editing, just as loss of focus does.
   1077         // If there was a change, send the event now.
   1078         if (wasChangedSinceLastFormControlChangeEvent())
   1079             dispatchFormControlChangeEvent();
   1080 
   1081         RefPtr<HTMLFormElement> formForSubmission = m_inputType->formForSubmission();
   1082         // Form may never have been present, or may have been destroyed by code responding to the change event.
   1083         if (formForSubmission)
   1084             formForSubmission->submitImplicitly(evt, canTriggerImplicitSubmission());
   1085 
   1086         evt->setDefaultHandled();
   1087         return;
   1088     }
   1089 
   1090     if (evt->isBeforeTextInsertedEvent())
   1091         m_inputType->handleBeforeTextInsertedEvent(static_cast<BeforeTextInsertedEvent*>(evt));
   1092 
   1093     if (evt->isWheelEvent()) {
   1094         m_inputType->handleWheelEvent(static_cast<WheelEvent*>(evt));
   1095         if (evt->defaultHandled())
   1096             return;
   1097     }
   1098 
   1099     if (evt->isMouseEvent() && evt->type() == eventNames().mousedownEvent) {
   1100         m_inputType->handleMouseDownEvent(static_cast<MouseEvent*>(evt));
   1101         if (evt->defaultHandled())
   1102             return;
   1103     }
   1104 
   1105 #if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
   1106     if (evt->isTouchEvent() && evt->type() == eventNames().touchstartEvent) {
   1107         m_inputType->handleTouchStartEvent(static_cast<TouchEvent*>(evt));
   1108         if (evt->defaultHandled())
   1109             return;
   1110     }
   1111 #endif
   1112 
   1113     m_inputType->forwardEvent(evt);
   1114 
   1115     if (!callBaseClassEarly && !evt->defaultHandled())
   1116         HTMLFormControlElementWithState::defaultEventHandler(evt);
   1117 }
   1118 
   1119 bool HTMLInputElement::isURLAttribute(Attribute *attr) const
   1120 {
   1121     return (attr->name() == srcAttr || attr->name() == formactionAttr);
   1122 }
   1123 
   1124 String HTMLInputElement::defaultValue() const
   1125 {
   1126     return fastGetAttribute(valueAttr);
   1127 }
   1128 
   1129 void HTMLInputElement::setDefaultValue(const String &value)
   1130 {
   1131     setAttribute(valueAttr, value);
   1132 }
   1133 
   1134 void HTMLInputElement::setDefaultName(const AtomicString& name)
   1135 {
   1136     m_data.setName(name);
   1137 }
   1138 
   1139 String HTMLInputElement::accept() const
   1140 {
   1141     return fastGetAttribute(acceptAttr);
   1142 }
   1143 
   1144 String HTMLInputElement::alt() const
   1145 {
   1146     return fastGetAttribute(altAttr);
   1147 }
   1148 
   1149 int HTMLInputElement::maxLength() const
   1150 {
   1151     return m_data.maxLength();
   1152 }
   1153 
   1154 void HTMLInputElement::setMaxLength(int maxLength, ExceptionCode& ec)
   1155 {
   1156     if (maxLength < 0)
   1157         ec = INDEX_SIZE_ERR;
   1158     else
   1159         setAttribute(maxlengthAttr, String::number(maxLength));
   1160 }
   1161 
   1162 bool HTMLInputElement::multiple() const
   1163 {
   1164     return fastHasAttribute(multipleAttr);
   1165 }
   1166 
   1167 void HTMLInputElement::setSize(unsigned size)
   1168 {
   1169     setAttribute(sizeAttr, String::number(size));
   1170 }
   1171 
   1172 KURL HTMLInputElement::src() const
   1173 {
   1174     return document()->completeURL(fastGetAttribute(srcAttr));
   1175 }
   1176 
   1177 void HTMLInputElement::setAutofilled(bool autofilled)
   1178 {
   1179     if (autofilled == m_isAutofilled)
   1180         return;
   1181 
   1182     m_isAutofilled = autofilled;
   1183     setNeedsStyleRecalc();
   1184 }
   1185 
   1186 FileList* HTMLInputElement::files()
   1187 {
   1188     return m_inputType->files();
   1189 }
   1190 
   1191 String HTMLInputElement::visibleValue() const
   1192 {
   1193     return m_inputType->visibleValue();
   1194 }
   1195 
   1196 String HTMLInputElement::convertFromVisibleValue(const String& visibleValue) const
   1197 {
   1198     return m_inputType->convertFromVisibleValue(visibleValue);
   1199 }
   1200 
   1201 bool HTMLInputElement::isAcceptableValue(const String& proposedValue) const
   1202 {
   1203     return m_inputType->isAcceptableValue(proposedValue);
   1204 }
   1205 
   1206 String HTMLInputElement::sanitizeValue(const String& proposedValue) const
   1207 {
   1208     return m_inputType->sanitizeValue(proposedValue);
   1209 }
   1210 
   1211 bool HTMLInputElement::hasUnacceptableValue() const
   1212 {
   1213     return m_inputType->hasUnacceptableValue();
   1214 }
   1215 
   1216 bool HTMLInputElement::isInRange() const
   1217 {
   1218     return m_inputType->supportsRangeLimitation() && !rangeUnderflow(value()) && !rangeOverflow(value());
   1219 }
   1220 
   1221 bool HTMLInputElement::isOutOfRange() const
   1222 {
   1223     return m_inputType->supportsRangeLimitation() && (rangeUnderflow(value()) || rangeOverflow(value()));
   1224 }
   1225 
   1226 bool HTMLInputElement::needsActivationCallback()
   1227 {
   1228     return m_autocomplete == Off || m_inputType->shouldResetOnDocumentActivation();
   1229 }
   1230 
   1231 void HTMLInputElement::registerForActivationCallbackIfNeeded()
   1232 {
   1233     if (needsActivationCallback())
   1234         document()->registerForDocumentActivationCallbacks(this);
   1235 }
   1236 
   1237 void HTMLInputElement::unregisterForActivationCallbackIfNeeded()
   1238 {
   1239     if (!needsActivationCallback())
   1240         document()->unregisterForDocumentActivationCallbacks(this);
   1241 }
   1242 
   1243 bool HTMLInputElement::isRequiredFormControl() const
   1244 {
   1245     return m_inputType->supportsRequired() && required();
   1246 }
   1247 
   1248 void HTMLInputElement::cacheSelection(int start, int end)
   1249 {
   1250     m_data.setCachedSelectionStart(start);
   1251     m_data.setCachedSelectionEnd(end);
   1252 }
   1253 
   1254 void HTMLInputElement::addSearchResult()
   1255 {
   1256     ASSERT(isSearchField());
   1257     if (renderer())
   1258         toRenderTextControlSingleLine(renderer())->addSearchResult();
   1259 }
   1260 
   1261 void HTMLInputElement::onSearch()
   1262 {
   1263     ASSERT(isSearchField());
   1264     if (renderer())
   1265         toRenderTextControlSingleLine(renderer())->stopSearchEventTimer();
   1266     dispatchEvent(Event::create(eventNames().searchEvent, true, false));
   1267 }
   1268 
   1269 void HTMLInputElement::documentDidBecomeActive()
   1270 {
   1271     ASSERT(needsActivationCallback());
   1272     reset();
   1273 }
   1274 
   1275 void HTMLInputElement::willMoveToNewOwnerDocument()
   1276 {
   1277     m_inputType->willMoveToNewOwnerDocument();
   1278 
   1279     // Always unregister for cache callbacks when leaving a document, even if we would otherwise like to be registered
   1280     if (needsActivationCallback())
   1281         document()->unregisterForDocumentActivationCallbacks(this);
   1282 
   1283     document()->checkedRadioButtons().removeButton(this);
   1284 
   1285     HTMLFormControlElementWithState::willMoveToNewOwnerDocument();
   1286 }
   1287 
   1288 void HTMLInputElement::didMoveToNewOwnerDocument()
   1289 {
   1290     registerForActivationCallbackIfNeeded();
   1291 
   1292     HTMLFormControlElementWithState::didMoveToNewOwnerDocument();
   1293 }
   1294 
   1295 void HTMLInputElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
   1296 {
   1297     HTMLFormControlElementWithState::addSubresourceAttributeURLs(urls);
   1298 
   1299     addSubresourceURL(urls, src());
   1300 }
   1301 
   1302 bool HTMLInputElement::recalcWillValidate() const
   1303 {
   1304     return m_inputType->supportsValidation() && HTMLFormControlElementWithState::recalcWillValidate();
   1305 }
   1306 
   1307 #if ENABLE(DATALIST)
   1308 
   1309 HTMLElement* HTMLInputElement::list() const
   1310 {
   1311     return dataList();
   1312 }
   1313 
   1314 HTMLDataListElement* HTMLInputElement::dataList() const
   1315 {
   1316     if (!m_hasNonEmptyList)
   1317         return 0;
   1318 
   1319     if (!m_inputType->shouldRespectListAttribute())
   1320         return 0;
   1321 
   1322     Element* element = document()->getElementById(fastGetAttribute(listAttr));
   1323     if (!element)
   1324         return 0;
   1325     if (!element->hasTagName(datalistTag))
   1326         return 0;
   1327 
   1328     return static_cast<HTMLDataListElement*>(element);
   1329 }
   1330 
   1331 HTMLOptionElement* HTMLInputElement::selectedOption() const
   1332 {
   1333     String value = this->value();
   1334 
   1335     // The empty string never matches to a datalist option because it
   1336     // doesn't represent a suggestion according to the standard.
   1337     if (value.isEmpty())
   1338         return 0;
   1339 
   1340     HTMLDataListElement* sourceElement = dataList();
   1341     if (!sourceElement)
   1342         return 0;
   1343     RefPtr<HTMLCollection> options = sourceElement->options();
   1344     if (!options)
   1345         return 0;
   1346     unsigned length = options->length();
   1347     for (unsigned i = 0; i < length; ++i) {
   1348         HTMLOptionElement* option = static_cast<HTMLOptionElement*>(options->item(i));
   1349         if (!option->disabled() && value == option->value())
   1350             return option;
   1351     }
   1352     return 0;
   1353 }
   1354 
   1355 #endif // ENABLE(DATALIST)
   1356 
   1357 void HTMLInputElement::stepUpFromRenderer(int n)
   1358 {
   1359     // The differences from stepUp()/stepDown():
   1360     //
   1361     // Difference 1: the current value
   1362     // If the current value is not a number, including empty, the current value is assumed as 0.
   1363     //   * If 0 is in-range, and matches to step value
   1364     //     - The value should be the +step if n > 0
   1365     //     - The value should be the -step if n < 0
   1366     //     If -step or +step is out of range, new value should be 0.
   1367     //   * If 0 is smaller than the minimum value
   1368     //     - The value should be the minimum value for any n
   1369     //   * If 0 is larger than the maximum value
   1370     //     - The value should be the maximum value for any n
   1371     //   * If 0 is in-range, but not matched to step value
   1372     //     - The value should be the larger matched value nearest to 0 if n > 0
   1373     //       e.g. <input type=number min=-100 step=3> -> 2
   1374     //     - The value should be the smaler matched value nearest to 0 if n < 0
   1375     //       e.g. <input type=number min=-100 step=3> -> -1
   1376     //   As for date/datetime-local/month/time/week types, the current value is assumed as "the current local date/time".
   1377     //   As for datetime type, the current value is assumed as "the current date/time in UTC".
   1378     // If the current value is smaller than the minimum value:
   1379     //  - The value should be the minimum value if n > 0
   1380     //  - Nothing should happen if n < 0
   1381     // If the current value is larger than the maximum value:
   1382     //  - The value should be the maximum value if n < 0
   1383     //  - Nothing should happen if n > 0
   1384     //
   1385     // Difference 2: clamping steps
   1386     // If the current value is not matched to step value:
   1387     // - The value should be the larger matched value nearest to 0 if n > 0
   1388     //   e.g. <input type=number value=3 min=-100 step=3> -> 5
   1389     // - The value should be the smaler matched value nearest to 0 if n < 0
   1390     //   e.g. <input type=number value=3 min=-100 step=3> -> 2
   1391     //
   1392     // n is assumed as -n if step < 0.
   1393 
   1394     ASSERT(hasSpinButton() || m_inputType->isRangeControl());
   1395     if (!hasSpinButton() && !m_inputType->isRangeControl())
   1396         return;
   1397     ASSERT(n);
   1398     if (!n)
   1399         return;
   1400 
   1401     unsigned stepDecimalPlaces, baseDecimalPlaces;
   1402     double step, base;
   1403     // The value will be the default value after stepping for <input value=(empty/invalid) step="any" />
   1404     // FIXME: Not any changes after stepping, even if it is an invalid value, may be better.
   1405     // (e.g. Stepping-up for <input type="number" value="foo" step="any" /> => "foo")
   1406     if (equalIgnoringCase(fastGetAttribute(stepAttr), "any"))
   1407         step = 0;
   1408     else if (!getAllowedValueStepWithDecimalPlaces(&step, &stepDecimalPlaces))
   1409         return;
   1410     base = m_inputType->stepBaseWithDecimalPlaces(&baseDecimalPlaces);
   1411     baseDecimalPlaces = min(baseDecimalPlaces, 16u);
   1412 
   1413     int sign;
   1414     if (step > 0)
   1415         sign = n;
   1416     else if (step < 0)
   1417         sign = -n;
   1418     else
   1419         sign = 0;
   1420 
   1421     const double nan = numeric_limits<double>::quiet_NaN();
   1422     String currentStringValue = value();
   1423     double current = m_inputType->parseToDouble(currentStringValue, nan);
   1424     if (!isfinite(current)) {
   1425         ExceptionCode ec;
   1426         current = m_inputType->defaultValueForStepUp();
   1427         setValueAsNumber(current, ec);
   1428     }
   1429     if ((sign > 0 && current < m_inputType->minimum()) || (sign < 0 && current > m_inputType->maximum()))
   1430         setValue(m_inputType->serialize(sign > 0 ? m_inputType->minimum() : m_inputType->maximum()));
   1431     else {
   1432         ExceptionCode ec;
   1433         if (stepMismatch(currentStringValue)) {
   1434             ASSERT(step);
   1435             double newValue;
   1436             double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces)));
   1437 
   1438             if (sign < 0)
   1439                 newValue = round((base + floor((current - base) / step) * step) * scale) / scale;
   1440             else if (sign > 0)
   1441                 newValue = round((base + ceil((current - base) / step) * step) * scale) / scale;
   1442             else
   1443                 newValue = current;
   1444 
   1445             if (newValue < m_inputType->minimum())
   1446                 newValue = m_inputType->minimum();
   1447             if (newValue > m_inputType->maximum())
   1448                 newValue = m_inputType->maximum();
   1449 
   1450             setValueAsNumber(newValue, ec);
   1451             current = newValue;
   1452             if (n > 1)
   1453                 applyStep(n - 1, ec);
   1454             else if (n < -1)
   1455                 applyStep(n + 1, ec);
   1456         } else
   1457             applyStep(n, ec);
   1458     }
   1459 
   1460     if (currentStringValue != value()) {
   1461         if (m_inputType->isRangeControl())
   1462             dispatchFormControlChangeEvent();
   1463         else
   1464             dispatchFormControlInputEvent();
   1465     }
   1466 }
   1467 
   1468 #if ENABLE(WCSS)
   1469 
   1470 void HTMLInputElement::setWapInputFormat(String& mask)
   1471 {
   1472     String validateMask = validateInputMask(m_data, mask);
   1473     if (!validateMask.isEmpty())
   1474         m_data.setInputFormatMask(validateMask);
   1475 }
   1476 
   1477 #endif
   1478 
   1479 #if ENABLE(INPUT_SPEECH)
   1480 
   1481 bool HTMLInputElement::isSpeechEnabled() const
   1482 {
   1483     // FIXME: Add support for RANGE, EMAIL, URL, COLOR and DATE/TIME input types.
   1484     return m_inputType->shouldRespectSpeechAttribute() && RuntimeEnabledFeatures::speechInputEnabled() && hasAttribute(webkitspeechAttr);
   1485 }
   1486 
   1487 #endif
   1488 
   1489 bool HTMLInputElement::isTextButton() const
   1490 {
   1491     return m_inputType->isTextButton();
   1492 }
   1493 
   1494 bool HTMLInputElement::isRadioButton() const
   1495 {
   1496     return m_inputType->isRadioButton();
   1497 }
   1498 
   1499 bool HTMLInputElement::isSearchField() const
   1500 {
   1501     return m_inputType->isSearchField();
   1502 }
   1503 
   1504 bool HTMLInputElement::isInputTypeHidden() const
   1505 {
   1506     return m_inputType->isHiddenType();
   1507 }
   1508 
   1509 bool HTMLInputElement::isPasswordField() const
   1510 {
   1511     return m_inputType->isPasswordField();
   1512 }
   1513 
   1514 bool HTMLInputElement::isCheckbox() const
   1515 {
   1516     return m_inputType->isCheckbox();
   1517 }
   1518 
   1519 bool HTMLInputElement::isText() const
   1520 {
   1521     return m_inputType->isTextType();
   1522 }
   1523 
   1524 bool HTMLInputElement::isEmailField() const
   1525 {
   1526     return m_inputType->isEmailField();
   1527 }
   1528 
   1529 bool HTMLInputElement::isFileUpload() const
   1530 {
   1531     return m_inputType->isFileUpload();
   1532 }
   1533 
   1534 bool HTMLInputElement::isImageButton() const
   1535 {
   1536     return m_inputType->isImageButton();
   1537 }
   1538 
   1539 bool HTMLInputElement::isNumberField() const
   1540 {
   1541     return m_inputType->isNumberField();
   1542 }
   1543 
   1544 bool HTMLInputElement::isSubmitButton() const
   1545 {
   1546     return m_inputType->isSubmitButton();
   1547 }
   1548 
   1549 bool HTMLInputElement::isTelephoneField() const
   1550 {
   1551     return m_inputType->isTelephoneField();
   1552 }
   1553 
   1554 bool HTMLInputElement::isURLField() const
   1555 {
   1556     return m_inputType->isURLField();
   1557 }
   1558 
   1559 bool HTMLInputElement::isEnumeratable() const
   1560 {
   1561     return m_inputType->isEnumeratable();
   1562 }
   1563 
   1564 bool HTMLInputElement::isChecked() const
   1565 {
   1566     return checked() && m_inputType->isCheckable();
   1567 }
   1568 
   1569 bool HTMLInputElement::hasSpinButton() const
   1570 {
   1571     return m_inputType->hasSpinButton();
   1572 }
   1573 
   1574 bool HTMLInputElement::supportsPlaceholder() const
   1575 {
   1576     return isTextType();
   1577 }
   1578 
   1579 CheckedRadioButtons& HTMLInputElement::checkedRadioButtons() const
   1580 {
   1581     if (HTMLFormElement* formElement = form())
   1582         return formElement->checkedRadioButtons();
   1583     return document()->checkedRadioButtons();
   1584 }
   1585 
   1586 void HTMLInputElement::handleBeforeTextInsertedEvent(Event* event)
   1587 {
   1588     InputElement::handleBeforeTextInsertedEvent(m_data, this, this, event);
   1589 }
   1590 
   1591 } // namespace
   1592