summaryrefslogtreecommitdiff
path: root/Source/WebCore/html/HTMLInputElement.cpp
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@digia.com>2013-09-13 12:51:20 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-19 20:50:05 +0200
commitd441d6f39bb846989d95bcf5caf387b42414718d (patch)
treee367e64a75991c554930278175d403c072de6bb8 /Source/WebCore/html/HTMLInputElement.cpp
parent0060b2994c07842f4c59de64b5e3e430525c4b90 (diff)
downloadqtwebkit-d441d6f39bb846989d95bcf5caf387b42414718d.tar.gz
Import Qt5x2 branch of QtWebkit for Qt 5.2
Importing a new snapshot of webkit. Change-Id: I2d01ad12cdc8af8cb015387641120a9d7ea5f10c Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
Diffstat (limited to 'Source/WebCore/html/HTMLInputElement.cpp')
-rw-r--r--Source/WebCore/html/HTMLInputElement.cpp240
1 files changed, 132 insertions, 108 deletions
diff --git a/Source/WebCore/html/HTMLInputElement.cpp b/Source/WebCore/html/HTMLInputElement.cpp
index 124af4e60..f01cbf24d 100644
--- a/Source/WebCore/html/HTMLInputElement.cpp
+++ b/Source/WebCore/html/HTMLInputElement.cpp
@@ -32,20 +32,23 @@
#include "AXObjectCache.h"
#include "BeforeTextInsertedEvent.h"
#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
#include "DateTimeChooser.h"
#include "Document.h"
+#include "Editor.h"
#include "ElementShadow.h"
#include "EventNames.h"
#include "ExceptionCode.h"
+#include "FeatureObserver.h"
#include "FileInputType.h"
#include "FileList.h"
#include "FormController.h"
#include "Frame.h"
+#include "FrameSelection.h"
#include "FrameView.h"
#include "HTMLCollection.h"
#include "HTMLDataListElement.h"
#include "HTMLFormElement.h"
+#include "HTMLImageLoader.h"
#include "HTMLNames.h"
#include "HTMLOptionElement.h"
#include "HTMLParserIdioms.h"
@@ -56,6 +59,7 @@
#include "Language.h"
#include "LocalizedStrings.h"
#include "MouseEvent.h"
+#include "PlatformMouseEvent.h"
#include "RenderTextControlSingleLine.h"
#include "RenderTheme.h"
#include "RuntimeEnabledFeatures.h"
@@ -63,8 +67,8 @@
#include "SearchInputType.h"
#include "ShadowRoot.h"
#include "ScriptEventListener.h"
+#include "StyleResolver.h"
#include <wtf/MathExtras.h>
-#include <wtf/StdLibExtras.h>
#if ENABLE(INPUT_TYPE_COLOR)
#include "ColorInputType.h"
@@ -137,15 +141,19 @@ HTMLInputElement::HTMLInputElement(const QualifiedName& tagName, Document* docum
PassRefPtr<HTMLInputElement> HTMLInputElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form, bool createdByParser)
{
RefPtr<HTMLInputElement> inputElement = adoptRef(new HTMLInputElement(tagName, document, form, createdByParser));
- inputElement->createShadowSubtree();
+ inputElement->ensureUserAgentShadowRoot();
return inputElement.release();
}
-void HTMLInputElement::createShadowSubtree()
+HTMLImageLoader* HTMLInputElement::imageLoader()
{
- ASSERT(!shadow());
- ShadowRoot::create(this, ShadowRoot::UserAgentShadowRoot, ASSERT_NO_EXCEPTION);
+ if (!m_imageLoader)
+ m_imageLoader = adoptPtr(new HTMLImageLoader(this));
+ return m_imageLoader.get();
+}
+void HTMLInputElement::didAddUserAgentShadowRoot(ShadowRoot*)
+{
m_inputType->createShadowSubtree();
}
@@ -160,10 +168,10 @@ HTMLInputElement::~HTMLInputElement()
// setForm(0) may register this to a document-level radio button group.
// We should unregister it to avoid accessing a deleted object.
if (isRadioButton())
- document()->formController()->checkedRadioButtons().removeButton(this);
+ document()->formController().checkedRadioButtons().removeButton(this);
#if ENABLE(TOUCH_EVENTS)
if (m_hasTouchEventHandler)
- document()->didRemoveTouchEventHandler();
+ document()->didRemoveEventTargetNode(this);
#endif
}
@@ -367,16 +375,6 @@ void HTMLInputElement::defaultBlur()
HTMLTextFormControlElement::blur();
}
-void HTMLInputElement::defaultFocus(bool restorePreviousSelection)
-{
- HTMLTextFormControlElement::focus(restorePreviousSelection);
-}
-
-void HTMLInputElement::focus(bool restorePreviousSelection)
-{
- m_inputType->focus(restorePreviousSelection);
-}
-
bool HTMLInputElement::hasCustomFocusLogic() const
{
return m_inputType->hasCustomFocusLogic();
@@ -426,7 +424,7 @@ void HTMLInputElement::endEditing()
return;
if (Frame* frame = document()->frame())
- frame->editor()->textFieldDidEndEditing(this);
+ frame->editor().textFieldDidEndEditing(this);
}
bool HTMLInputElement::shouldUseInputMethod()
@@ -434,9 +432,9 @@ bool HTMLInputElement::shouldUseInputMethod()
return m_inputType->shouldUseInputMethod();
}
-void HTMLInputElement::handleFocusEvent()
+void HTMLInputElement::handleFocusEvent(Node* oldFocusedNode, FocusDirection direction)
{
- m_inputType->handleFocusEvent();
+ m_inputType->handleFocusEvent(oldFocusedNode, direction);
}
void HTMLInputElement::handleBlurEvent()
@@ -473,26 +471,27 @@ void HTMLInputElement::updateType()
removeFromRadioButtonGroup();
- bool wasAttached = attached();
- if (wasAttached)
- detach();
-
bool didStoreValue = m_inputType->storesValueSeparateFromAttribute();
bool neededSuspensionCallback = needsSuspensionCallback();
bool didRespectHeightAndWidth = m_inputType->shouldRespectHeightAndWidthAttributes();
m_inputType->destroyShadowSubtree();
+
+ bool wasAttached = attached();
+ if (wasAttached)
+ detach();
+
m_inputType = newType.release();
m_inputType->createShadowSubtree();
#if ENABLE(TOUCH_EVENTS)
bool hasTouchEventHandler = m_inputType->hasTouchEventHandler();
if (hasTouchEventHandler != m_hasTouchEventHandler) {
- if (hasTouchEventHandler)
- document()->didAddTouchEventHandler();
- else
- document()->didRemoveTouchEventHandler();
- m_hasTouchEventHandler = hasTouchEventHandler;
+ if (hasTouchEventHandler)
+ document()->didAddTouchEventHandler(this);
+ else
+ document()->didRemoveTouchEventHandler(this);
+ m_hasTouchEventHandler = hasTouchEventHandler;
}
#endif
@@ -521,18 +520,18 @@ void HTMLInputElement::updateType()
registerForSuspensionCallbackIfNeeded();
if (didRespectHeightAndWidth != m_inputType->shouldRespectHeightAndWidthAttributes()) {
- ASSERT(attributeData());
- if (Attribute* height = getAttributeItem(heightAttr))
+ ASSERT(elementData());
+ if (const Attribute* height = getAttributeItem(heightAttr))
attributeChanged(heightAttr, height->value());
- if (Attribute* width = getAttributeItem(widthAttr))
+ if (const Attribute* width = getAttributeItem(widthAttr))
attributeChanged(widthAttr, width->value());
- if (Attribute* align = getAttributeItem(alignAttr))
+ if (const Attribute* align = getAttributeItem(alignAttr))
attributeChanged(alignAttr, align->value());
}
if (wasAttached) {
attach();
- if (document()->focusedNode() == this)
+ if (document()->focusedElement() == this)
updateFocusAppearance(true);
}
@@ -601,27 +600,27 @@ bool HTMLInputElement::isPresentationAttribute(const QualifiedName& name) const
return HTMLTextFormControlElement::isPresentationAttribute(name);
}
-void HTMLInputElement::collectStyleForPresentationAttribute(const Attribute& attribute, StylePropertySet* style)
+void HTMLInputElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style)
{
- if (attribute.name() == vspaceAttr) {
- addHTMLLengthToStyle(style, CSSPropertyMarginTop, attribute.value());
- addHTMLLengthToStyle(style, CSSPropertyMarginBottom, attribute.value());
- } else if (attribute.name() == hspaceAttr) {
- addHTMLLengthToStyle(style, CSSPropertyMarginLeft, attribute.value());
- addHTMLLengthToStyle(style, CSSPropertyMarginRight, attribute.value());
- } else if (attribute.name() == alignAttr) {
+ if (name == vspaceAttr) {
+ addHTMLLengthToStyle(style, CSSPropertyMarginTop, value);
+ addHTMLLengthToStyle(style, CSSPropertyMarginBottom, value);
+ } else if (name == hspaceAttr) {
+ addHTMLLengthToStyle(style, CSSPropertyMarginLeft, value);
+ addHTMLLengthToStyle(style, CSSPropertyMarginRight, value);
+ } else if (name == alignAttr) {
if (m_inputType->shouldRespectAlignAttribute())
- applyAlignmentAttributeToStyle(attribute, style);
- } else if (attribute.name() == widthAttr) {
+ applyAlignmentAttributeToStyle(value, style);
+ } else if (name == widthAttr) {
if (m_inputType->shouldRespectHeightAndWidthAttributes())
- addHTMLLengthToStyle(style, CSSPropertyWidth, attribute.value());
- } else if (attribute.name() == heightAttr) {
+ addHTMLLengthToStyle(style, CSSPropertyWidth, value);
+ } else if (name == heightAttr) {
if (m_inputType->shouldRespectHeightAndWidthAttributes())
- addHTMLLengthToStyle(style, CSSPropertyHeight, attribute.value());
- } else if (attribute.name() == borderAttr && isImageButton())
- applyBorderAttributeToStyle(attribute, style);
+ addHTMLLengthToStyle(style, CSSPropertyHeight, value);
+ } else if (name == borderAttr && isImageButton())
+ applyBorderAttributeToStyle(value, style);
else
- HTMLTextFormControlElement::collectStyleForPresentationAttribute(attribute, style);
+ HTMLTextFormControlElement::collectStyleForPresentationAttribute(name, value, style);
}
void HTMLInputElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
@@ -663,6 +662,7 @@ void HTMLInputElement::parseAttribute(const QualifiedName& name, const AtomicStr
setFormControlValueMatchesRenderer(false);
setNeedsValidityCheck();
m_valueAttributeWasUpdatedAfterParsing = !m_parsingInProgress;
+ m_inputType->valueAttributeChanged();
} else if (name == checkedAttr) {
// Another radio button in the same group might be checked by state
// restore. We shouldn't call setChecked() even if this has the checked
@@ -697,20 +697,35 @@ void HTMLInputElement::parseAttribute(const QualifiedName& name, const AtomicStr
if (m_maxResults != oldResults && (m_maxResults <= 0 || oldResults <= 0))
reattachIfAttached();
setNeedsStyleRecalc();
- } else if (name == autosaveAttr || name == incrementalAttr)
+ FeatureObserver::observe(document(), FeatureObserver::ResultsAttribute);
+ } else if (name == autosaveAttr) {
setNeedsStyleRecalc();
- else if (name == minAttr || name == maxAttr) {
+ FeatureObserver::observe(document(), FeatureObserver::AutoSaveAttribute);
+ } else if (name == incrementalAttr) {
+ setNeedsStyleRecalc();
+ FeatureObserver::observe(document(), FeatureObserver::IncrementalAttribute);
+ } else if (name == minAttr) {
+ m_inputType->minOrMaxAttributeChanged();
+ setNeedsValidityCheck();
+ FeatureObserver::observe(document(), FeatureObserver::MinAttribute);
+ } else if (name == maxAttr) {
m_inputType->minOrMaxAttributeChanged();
setNeedsValidityCheck();
+ FeatureObserver::observe(document(), FeatureObserver::MaxAttribute);
} else if (name == multipleAttr) {
m_inputType->multipleAttributeChanged();
setNeedsValidityCheck();
} else if (name == stepAttr) {
m_inputType->stepAttributeChanged();
setNeedsValidityCheck();
- } else if (name == patternAttr || name == precisionAttr)
+ FeatureObserver::observe(document(), FeatureObserver::StepAttribute);
+ } else if (name == patternAttr) {
setNeedsValidityCheck();
- else if (name == disabledAttr) {
+ FeatureObserver::observe(document(), FeatureObserver::PatternAttribute);
+ } else if (name == precisionAttr) {
+ setNeedsValidityCheck();
+ FeatureObserver::observe(document(), FeatureObserver::PrecisionAttribute);
+ } else if (name == disabledAttr) {
HTMLTextFormControlElement::parseAttribute(name, value);
m_inputType->disabledAttributeChanged();
} else if (name == readonlyAttr) {
@@ -724,6 +739,7 @@ void HTMLInputElement::parseAttribute(const QualifiedName& name, const AtomicStr
resetListAttributeTargetObserver();
listAttributeTargetChanged();
}
+ FeatureObserver::observe(document(), FeatureObserver::ListAttribute);
}
#endif
#if ENABLE(INPUT_SPEECH)
@@ -735,19 +751,27 @@ void HTMLInputElement::parseAttribute(const QualifiedName& name, const AtomicStr
detach();
m_inputType->destroyShadowSubtree();
m_inputType->createShadowSubtree();
- attach();
+ if (!attached())
+ attach();
} else {
m_inputType->destroyShadowSubtree();
m_inputType->createShadowSubtree();
}
setFormControlValueMatchesRenderer(false);
setNeedsStyleRecalc();
+ FeatureObserver::observe(document(), FeatureObserver::PrefixedSpeechAttribute);
} else if (name == onwebkitspeechchangeAttr)
setAttributeEventListener(eventNames().webkitspeechchangeEvent, createAttributeEventListener(this, name, value));
#endif
+#if ENABLE(DIRECTORY_UPLOAD)
+ else if (name == webkitdirectoryAttr) {
+ HTMLTextFormControlElement::parseAttribute(name, value);
+ FeatureObserver::observe(document(), FeatureObserver::PrefixedDirectoryAttribute);
+ }
+#endif
else
HTMLTextFormControlElement::parseAttribute(name, value);
- m_inputType->updateInnerTextValue();
+ m_inputType->attributeChanged();
}
void HTMLInputElement::finishParsingChildren()
@@ -772,26 +796,24 @@ RenderObject* HTMLInputElement::createRenderer(RenderArena* arena, RenderStyle*
return m_inputType->createRenderer(arena, style);
}
-void HTMLInputElement::attach()
+void HTMLInputElement::attach(const AttachContext& context)
{
- suspendPostAttachCallbacks();
+ PostAttachCallbackDisabler disabler(this);
if (!m_hasType)
updateType();
- HTMLTextFormControlElement::attach();
+ HTMLTextFormControlElement::attach(context);
m_inputType->attach();
- if (document()->focusedNode() == this)
+ if (document()->focusedElement() == this)
document()->updateFocusAppearanceSoon(true /* restore selection */);
-
- resumePostAttachCallbacks();
}
-void HTMLInputElement::detach()
+void HTMLInputElement::detach(const AttachContext& context)
{
- HTMLTextFormControlElement::detach();
+ HTMLTextFormControlElement::detach(context);
setFormControlValueMatchesRenderer(false);
m_inputType->detach();
}
@@ -816,7 +838,7 @@ bool HTMLInputElement::isSuccessfulSubmitButton() const
{
// HTML spec says that buttons must have names to be considered successful.
// However, other browsers do not impose this constraint. So we do not.
- return !disabled() && m_inputType->canBeSuccessfulSubmitButton();
+ return !isDisabledFormControl() && m_inputType->canBeSuccessfulSubmitButton();
}
bool HTMLInputElement::isActivatedSubmit() const
@@ -872,8 +894,10 @@ void HTMLInputElement::setChecked(bool nowChecked, TextFieldEventBehavior eventB
// Ideally we'd do this from the render tree (matching
// RenderTextView), but it's not possible to do it at the moment
// because of the way the code is structured.
- if (renderer() && AXObjectCache::accessibilityEnabled())
- renderer()->document()->axObjectCache()->checkedStateChanged(this);
+ if (renderer()) {
+ if (AXObjectCache* cache = renderer()->document()->existingAXObjectCache())
+ cache->checkedStateChanged(this);
+ }
// Only send a change event for items in the document (avoid firing during
// parsing) and don't send a change event for a radio button that's getting
@@ -885,7 +909,7 @@ void HTMLInputElement::setChecked(bool nowChecked, TextFieldEventBehavior eventB
dispatchFormControlChangeEvent();
}
- invalidateParentDistributionIfNecessary(this, SelectRuleFeatureSet::RuleFeatureChecked);
+ didAffectSelector(AffectedSelectorChecked);
}
void HTMLInputElement::setIndeterminate(bool newValue)
@@ -895,8 +919,7 @@ void HTMLInputElement::setIndeterminate(bool newValue)
m_isIndeterminate = newValue;
- setNeedsStyleRecalc();
- invalidateParentDistributionIfNecessary(this, SelectRuleFeatureSet::RuleFeatureIndeterminate);
+ didAffectSelector(AffectedSelectorIndeterminate);
if (renderer() && renderer()->style()->hasAppearance())
renderer()->theme()->stateChanged(renderer(), CheckedState);
@@ -1046,23 +1069,13 @@ double HTMLInputElement::valueAsNumber() const
void HTMLInputElement::setValueAsNumber(double newValue, ExceptionCode& ec, TextFieldEventBehavior eventBehavior)
{
- if (!isfinite(newValue)) {
+ if (!std::isfinite(newValue)) {
ec = NOT_SUPPORTED_ERR;
return;
}
m_inputType->setValueAsDouble(newValue, eventBehavior, ec);
}
-String HTMLInputElement::placeholder() const
-{
- return fastGetAttribute(placeholderAttr).string();
-}
-
-void HTMLInputElement::setPlaceholder(const String& value)
-{
- setAttribute(placeholderAttr, value);
-}
-
void HTMLInputElement::setValueFromRenderer(const String& value)
{
// File upload controls will never use this.
@@ -1206,7 +1219,7 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
bool HTMLInputElement::willRespondToMouseClickEvents()
{
// FIXME: Consider implementing willRespondToMouseClickEvents() in InputType if more accurate results are necessary.
- if (!disabled())
+ if (!isDisabledFormControl())
return true;
return HTMLTextFormControlElement::willRespondToMouseClickEvents();
@@ -1435,17 +1448,17 @@ void HTMLInputElement::unregisterForSuspensionCallbackIfNeeded()
bool HTMLInputElement::isRequiredFormControl() const
{
- return m_inputType->supportsRequired() && required();
+ return m_inputType->supportsRequired() && isRequired();
}
-bool HTMLInputElement::shouldMatchReadOnlySelector() const
+bool HTMLInputElement::matchesReadOnlyPseudoClass() const
{
- return m_inputType->supportsReadOnly() && readOnly();
+ return m_inputType->supportsReadOnly() && isReadOnly();
}
-bool HTMLInputElement::shouldMatchReadWriteSelector() const
+bool HTMLInputElement::matchesReadWritePseudoClass() const
{
- return m_inputType->supportsReadOnly() && !readOnly();
+ return m_inputType->supportsReadOnly() && !isReadOnly();
}
void HTMLInputElement::addSearchResult()
@@ -1461,6 +1474,11 @@ void HTMLInputElement::onSearch()
dispatchEvent(Event::create(eventNames().searchEvent, true, false));
}
+void HTMLInputElement::updateClearButtonVisibility()
+{
+ m_inputType->updateClearButtonVisibility();
+}
+
void HTMLInputElement::documentDidResumeFromPageCache()
{
ASSERT(needsSuspensionCallback());
@@ -1503,19 +1521,30 @@ void HTMLInputElement::removedFrom(ContainerNode* insertionPoint)
void HTMLInputElement::didMoveToNewDocument(Document* oldDocument)
{
- m_inputType->willMoveToNewOwnerDocument();
+ if (hasImageLoader())
+ imageLoader()->elementDidMoveToNewDocument();
+
bool needsSuspensionCallback = this->needsSuspensionCallback();
if (oldDocument) {
// Always unregister for cache callbacks when leaving a document, even if we would otherwise like to be registered
if (needsSuspensionCallback)
oldDocument->unregisterForPageCacheSuspensionCallbacks(this);
if (isRadioButton())
- oldDocument->formController()->checkedRadioButtons().removeButton(this);
+ oldDocument->formController().checkedRadioButtons().removeButton(this);
+#if ENABLE(TOUCH_EVENTS)
+ if (m_hasTouchEventHandler)
+ oldDocument->didRemoveEventTargetNode(this);
+#endif
}
if (needsSuspensionCallback)
document()->registerForPageCacheSuspensionCallbacks(this);
+#if ENABLE(TOUCH_EVENTS)
+ if (m_hasTouchEventHandler)
+ document()->didAddTouchEventHandler(this);
+#endif
+
HTMLTextFormControlElement::didMoveToNewDocument(oldDocument);
}
@@ -1536,6 +1565,7 @@ void HTMLInputElement::requiredAttributeChanged()
HTMLTextFormControlElement::requiredAttributeChanged();
if (CheckedRadioButtons* buttons = checkedRadioButtons())
buttons->requiredAttributeChanged(this);
+ m_inputType->requiredAttributeChanged();
}
#if ENABLE(INPUT_TYPE_COLOR)
@@ -1634,6 +1664,13 @@ bool HTMLInputElement::isRangeControl() const
return m_inputType->isRangeControl();
}
+#if ENABLE(INPUT_TYPE_COLOR)
+bool HTMLInputElement::isColorControl() const
+{
+ return m_inputType->isColorControl();
+}
+#endif
+
bool HTMLInputElement::isText() const
{
return m_inputType->isTextType();
@@ -1757,7 +1794,7 @@ String HTMLInputElement::defaultToolTip() const
return m_inputType->defaultToolTip();
}
-bool HTMLInputElement::isIndeterminate() const
+bool HTMLInputElement::shouldAppearIndeterminate() const
{
return m_inputType->supportsIndeterminateAppearance() && indeterminate();
}
@@ -1785,11 +1822,11 @@ void HTMLInputElement::setCapture(const String& value)
#endif
-bool HTMLInputElement::isInRequiredRadioButtonGroup() const
+bool HTMLInputElement::isInRequiredRadioButtonGroup()
{
ASSERT(isRadioButton());
if (CheckedRadioButtons* buttons = checkedRadioButtons())
- return buttons->isRequiredGroup(name());
+ return buttons->isInRequiredGroup(this);
return false;
}
@@ -1807,7 +1844,7 @@ CheckedRadioButtons* HTMLInputElement::checkedRadioButtons() const
if (HTMLFormElement* formElement = form())
return &formElement->checkedRadioButtons();
if (inDocument())
- return &document()->formController()->checkedRadioButtons();
+ return &document()->formController().checkedRadioButtons();
return 0;
}
@@ -1890,7 +1927,7 @@ bool HTMLInputElement::setupDateTimeChooserParameters(DateTimeChooserParameters&
parameters.type = type();
parameters.minimum = minimum();
parameters.maximum = maximum();
- parameters.required = required();
+ parameters.required = isRequired();
if (!RuntimeEnabledFeatures::langAttributeAwareFormControlUIEnabled())
parameters.locale = defaultLanguage();
else {
@@ -1926,17 +1963,4 @@ bool HTMLInputElement::setupDateTimeChooserParameters(DateTimeChooserParameters&
}
#endif
-void HTMLInputElement::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
-{
- MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM);
- HTMLTextFormControlElement::reportMemoryUsage(memoryObjectInfo);
- info.addMember(m_name);
- info.addMember(m_valueIfDirty);
- info.addMember(m_suggestedValue);
- info.addMember(m_inputType);
-#if ENABLE(DATALIST_ELEMENT)
- info.addMember(m_listAttributeTargetObserver);
-#endif
-}
-
} // namespace