summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/html/HTMLInputElement.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/html/HTMLInputElement.cpp')
-rw-r--r--Source/WebCore/html/HTMLInputElement.cpp60
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);