diff options
Diffstat (limited to 'Source/WebCore/html/HTMLInputElement.cpp')
-rw-r--r-- | Source/WebCore/html/HTMLInputElement.cpp | 60 |
1 files changed, 43 insertions, 17 deletions
diff --git a/Source/WebCore/html/HTMLInputElement.cpp b/Source/WebCore/html/HTMLInputElement.cpp index 0d20389..14dd149 100644 --- a/Source/WebCore/html/HTMLInputElement.cpp +++ b/Source/WebCore/html/HTMLInputElement.cpp @@ -45,6 +45,7 @@ #include "KeyboardEvent.h" #include "LocalizedStrings.h" #include "MouseEvent.h" +#include "PlatformMouseEvent.h" #include "RenderTextControlSingleLine.h" #include "RenderTheme.h" #include "RuntimeEnabledFeatures.h" @@ -69,7 +70,7 @@ using namespace HTMLNames; const int maxSavedResults = 256; -HTMLInputElement::HTMLInputElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form) +HTMLInputElement::HTMLInputElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form, bool createdByParser) : HTMLTextFormControlElement(tagName, document, form) , m_maxResults(-1) , m_isChecked(false) @@ -79,14 +80,16 @@ HTMLInputElement::HTMLInputElement(const QualifiedName& tagName, Document* docum , m_isActivatedSubmit(false) , m_autocomplete(Uninitialized) , m_isAutofilled(false) + , m_stateRestored(false) + , m_parsingInProgress(createdByParser) , m_inputType(InputType::createText(this)) { ASSERT(hasTagName(inputTag) || hasTagName(isindexTag)); } -PassRefPtr<HTMLInputElement> HTMLInputElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form) +PassRefPtr<HTMLInputElement> HTMLInputElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form, bool createdByParser) { - return adoptRef(new HTMLInputElement(tagName, document, form)); + return adoptRef(new HTMLInputElement(tagName, document, form, createdByParser)); } HTMLInputElement::~HTMLInputElement() @@ -146,7 +149,7 @@ void HTMLInputElement::updateCheckedRadioButtons() control->setNeedsValidityCheck(); } } - + if (renderer() && renderer()->style()->hasAppearance()) renderer()->theme()->stateChanged(renderer(), CheckedState); } @@ -356,7 +359,7 @@ void HTMLInputElement::applyStep(double count, ExceptionCode& ec) if (newValue > m_inputType->maximum()) newValue = m_inputType->maximum(); setValueAsNumber(newValue, ec); - + if (AXObjectCache::accessibilityEnabled()) document()->axObjectCache()->postNotification(renderer(), AXObjectCache::AXValueChanged, true); } @@ -386,7 +389,7 @@ bool HTMLInputElement::isMouseFocusable() const } void HTMLInputElement::updateFocusAppearance(bool restorePreviousSelection) -{ +{ if (isTextField()) InputElement::updateFocusAppearance(m_data, this, this, restorePreviousSelection); else @@ -517,6 +520,7 @@ bool HTMLInputElement::saveFormControlState(String& result) const void HTMLInputElement::restoreFormControlState(const String& state) { m_inputType->restoreFormControlState(state); + m_stateRestored = true; } bool HTMLInputElement::canStartSelection() const @@ -539,11 +543,11 @@ void HTMLInputElement::accessKeyAction(bool sendToAnyElement) bool HTMLInputElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const { if (((attrName == heightAttr || attrName == widthAttr) && m_inputType->shouldRespectHeightAndWidthAttributes()) - || attrName == vspaceAttr + || attrName == vspaceAttr || attrName == hspaceAttr) { result = eUniversal; return false; - } + } if (attrName == alignAttr && m_inputType->shouldRespectAlignAttribute()) { // Share with <img> since the alignment behavior is the same. @@ -585,11 +589,14 @@ void HTMLInputElement::parseMappedAttribute(Attribute* attr) setFormControlValueMatchesRenderer(false); setNeedsValidityCheck(); } else if (attr->name() == checkedAttr) { - if (m_reflectsCheckedAttribute) { + // Another radio button in the same group might be checked by state + // restore. We shouldn't call setChecked() even if this has the checked + // attribute. So, delay the setChecked() call until + // finishParsingChildren() is called if parsing is in progress. + if (!m_parsingInProgress && m_reflectsCheckedAttribute) { setChecked(!attr->isNull()); m_reflectsCheckedAttribute = true; } - setNeedsValidityCheck(); } else if (attr->name() == maxlengthAttr) { InputElement::parseMaxLengthAttribute(m_data, this, this, attr); setNeedsValidityCheck(); @@ -658,6 +665,18 @@ void HTMLInputElement::parseMappedAttribute(Attribute* attr) HTMLTextFormControlElement::parseMappedAttribute(attr); } +void HTMLInputElement::finishParsingChildren() +{ + m_parsingInProgress = false; + HTMLFormControlElementWithState::finishParsingChildren(); + if (!m_stateRestored) { + bool checked = hasAttribute(checkedAttr); + if (checked) + setChecked(checked); + m_reflectsCheckedAttribute = true; + } +} + bool HTMLInputElement::rendererIsNeeded(RenderStyle* style) { return m_inputType->rendererIsNeeded() && HTMLFormControlElementWithState::rendererIsNeeded(style); @@ -756,6 +775,7 @@ void HTMLInputElement::setChecked(bool nowChecked, bool sendChangeEvent) setNeedsStyleRecalc(); updateCheckedRadioButtons(); + setNeedsValidityCheck(); // Ideally we'd do this from the render tree (matching // RenderTextView), but it's not possible to do it at the moment @@ -883,6 +903,7 @@ void HTMLInputElement::setValue(const String& value, bool sendChangeEvent) cacheSelection(max, max); m_data.setSuggestedValue(String()); } + m_inputType->valueChanged(); // Don't dispatch the change event when focused, it will be dispatched // when the control loses focus. @@ -958,6 +979,8 @@ void* HTMLInputElement::preDispatchEventHandler(Event* event) { if (event->type() != eventNames().clickEvent) return 0; + if (!event->isMouseEvent() || static_cast<MouseEvent*>(event)->button() != LeftButton) + return 0; // FIXME: Check whether there are any cases where this actually ends up leaking. return m_inputType->willDispatchClick().leakPtr(); } @@ -965,8 +988,6 @@ void* HTMLInputElement::preDispatchEventHandler(Event* event) void HTMLInputElement::postDispatchEventHandler(Event* event, void* dataFromPreDispatch) { OwnPtr<ClickHandlingState> state = adoptPtr(static_cast<ClickHandlingState*>(dataFromPreDispatch)); - if (event->type() != eventNames().clickEvent) - return; if (!state) return; m_inputType->didDispatchClick(event, *state); @@ -974,7 +995,7 @@ void HTMLInputElement::postDispatchEventHandler(Event* event, void* dataFromPreD void HTMLInputElement::defaultEventHandler(Event* evt) { - if (evt->isMouseEvent() && evt->type() == eventNames().clickEvent) { + if (evt->isMouseEvent() && evt->type() == eventNames().clickEvent && static_cast<MouseEvent*>(evt)->button() == LeftButton) { m_inputType->handleClickEvent(static_cast<MouseEvent*>(evt)); if (evt->defaultHandled()) return; @@ -1134,7 +1155,7 @@ void HTMLInputElement::setAutofilled(bool autofilled) { if (autofilled == m_isAutofilled) return; - + m_isAutofilled = autofilled; setNeedsStyleRecalc(); } @@ -1144,6 +1165,11 @@ FileList* HTMLInputElement::files() return m_inputType->files(); } +String HTMLInputElement::visibleValue() const +{ + return m_inputType->visibleValue(); +} + bool HTMLInputElement::isAcceptableValue(const String& proposedValue) const { return m_inputType->isAcceptableValue(proposedValue); @@ -1225,7 +1251,7 @@ void HTMLInputElement::willMoveToNewOwnerDocument() // Always unregister for cache callbacks when leaving a document, even if we would otherwise like to be registered if (needsActivationCallback()) document()->unregisterForDocumentActivationCallbacks(this); - + document()->checkedRadioButtons().removeButton(this); HTMLFormControlElementWithState::willMoveToNewOwnerDocument(); @@ -1234,10 +1260,10 @@ void HTMLInputElement::willMoveToNewOwnerDocument() void HTMLInputElement::didMoveToNewOwnerDocument() { registerForActivationCallbackIfNeeded(); - + HTMLFormControlElementWithState::didMoveToNewOwnerDocument(); } - + void HTMLInputElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const { HTMLFormControlElementWithState::addSubresourceAttributeURLs(urls); |