diff options
author | Steve Block <steveblock@google.com> | 2009-10-08 17:19:54 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2009-10-20 00:41:58 +0100 |
commit | 231d4e3152a9c27a73b6ac7badbe6be673aa3ddf (patch) | |
tree | a6c7e2d6cd7bfa7011cc39abbb436142d7a4a7c8 /WebCore/html/HTMLTextAreaElement.cpp | |
parent | e196732677050bd463301566a68a643b6d14b907 (diff) | |
download | external_webkit-231d4e3152a9c27a73b6ac7badbe6be673aa3ddf.zip external_webkit-231d4e3152a9c27a73b6ac7badbe6be673aa3ddf.tar.gz external_webkit-231d4e3152a9c27a73b6ac7badbe6be673aa3ddf.tar.bz2 |
Merge webkit.org at R49305 : Automatic merge by git.
Change-Id: I8968561bc1bfd72b8923b7118d3728579c6dbcc7
Diffstat (limited to 'WebCore/html/HTMLTextAreaElement.cpp')
-rw-r--r-- | WebCore/html/HTMLTextAreaElement.cpp | 131 |
1 files changed, 64 insertions, 67 deletions
diff --git a/WebCore/html/HTMLTextAreaElement.cpp b/WebCore/html/HTMLTextAreaElement.cpp index 884cf3f..8d8208d 100644 --- a/WebCore/html/HTMLTextAreaElement.cpp +++ b/WebCore/html/HTMLTextAreaElement.cpp @@ -26,21 +26,25 @@ #include "config.h" #include "HTMLTextAreaElement.h" +#include "BeforeTextInsertedEvent.h" #include "ChromeClient.h" #include "CSSValueKeywords.h" #include "Document.h" #include "Event.h" #include "EventNames.h" +#include "ExceptionCode.h" #include "FocusController.h" #include "FormDataList.h" #include "Frame.h" #include "HTMLNames.h" +#include "InputElement.h" #include "MappedAttribute.h" #include "Page.h" #include "RenderStyle.h" #include "RenderTextControlMultiLine.h" #include "ScriptEventListener.h" #include "Text.h" +#include "TextIterator.h" #include "VisibleSelection.h" #include <wtf/StdLibExtras.h> @@ -64,12 +68,13 @@ static inline void notifyFormStateChanged(const HTMLTextAreaElement* element) } HTMLTextAreaElement::HTMLTextAreaElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form) - : HTMLFormControlElementWithState(tagName, document, form) + : HTMLTextFormControlElement(tagName, document, form) , m_rows(defaultRows) , m_cols(defaultCols) , m_wrap(SoftWrap) , m_cachedSelectionStart(-1) , m_cachedSelectionEnd(-1) + , m_isDirty(false) { ASSERT(hasTagName(textareaTag)); setFormControlValueMatchesRenderer(true); @@ -93,54 +98,6 @@ void HTMLTextAreaElement::restoreFormControlState(const String& state) setDefaultValue(state); } -int HTMLTextAreaElement::selectionStart() -{ - if (!renderer()) - return 0; - if (document()->focusedNode() != this && m_cachedSelectionStart >= 0) - return m_cachedSelectionStart; - return toRenderTextControl(renderer())->selectionStart(); -} - -int HTMLTextAreaElement::selectionEnd() -{ - if (!renderer()) - return 0; - if (document()->focusedNode() != this && m_cachedSelectionEnd >= 0) - return m_cachedSelectionEnd; - return toRenderTextControl(renderer())->selectionEnd(); -} - -static RenderTextControl* rendererAfterUpdateLayout(HTMLTextAreaElement* element) -{ - element->document()->updateLayoutIgnorePendingStylesheets(); - return toRenderTextControl(element->renderer()); -} - -void HTMLTextAreaElement::setSelectionStart(int start) -{ - if (RenderTextControl* renderer = rendererAfterUpdateLayout(this)) - renderer->setSelectionStart(start); -} - -void HTMLTextAreaElement::setSelectionEnd(int end) -{ - if (RenderTextControl* renderer = rendererAfterUpdateLayout(this)) - renderer->setSelectionEnd(end); -} - -void HTMLTextAreaElement::select() -{ - if (RenderTextControl* renderer = rendererAfterUpdateLayout(this)) - renderer->select(); -} - -void HTMLTextAreaElement::setSelectionRange(int start, int end) -{ - if (RenderTextControl* renderer = rendererAfterUpdateLayout(this)) - renderer->setSelectionRange(start, end); -} - void HTMLTextAreaElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { setValue(defaultValue()); @@ -196,21 +153,13 @@ void HTMLTextAreaElement::parseMappedAttribute(MappedAttribute* attr) } else if (attr->name() == alignAttr) { // Don't map 'align' attribute. This matches what Firefox, Opera and IE do. // See http://bugs.webkit.org/show_bug.cgi?id=7075 - } else if (attr->name() == onfocusAttr) - setAttributeEventListener(eventNames().focusEvent, createAttributeEventListener(this, attr)); - else if (attr->name() == onblurAttr) - setAttributeEventListener(eventNames().blurEvent, createAttributeEventListener(this, attr)); - else if (attr->name() == onselectAttr) - setAttributeEventListener(eventNames().selectEvent, createAttributeEventListener(this, attr)); - else if (attr->name() == onchangeAttr) - setAttributeEventListener(eventNames().changeEvent, createAttributeEventListener(this, attr)); - else - HTMLFormControlElementWithState::parseMappedAttribute(attr); + } else + HTMLTextFormControlElement::parseMappedAttribute(attr); } RenderObject* HTMLTextAreaElement::createRenderer(RenderArena* arena, RenderStyle*) { - return new (arena) RenderTextControlMultiLine(this); + return new (arena) RenderTextControlMultiLine(this, placeholderShouldBeVisible()); } bool HTMLTextAreaElement::appendFormData(FormDataList& encoding, bool) @@ -229,6 +178,7 @@ bool HTMLTextAreaElement::appendFormData(FormDataList& encoding, bool) void HTMLTextAreaElement::reset() { setValue(defaultValue()); + m_isDirty = false; } bool HTMLTextAreaElement::isKeyboardFocusable(KeyboardEvent*) const @@ -272,10 +222,34 @@ void HTMLTextAreaElement::defaultEventHandler(Event* event) { if (renderer() && (event->isMouseEvent() || event->isDragEvent() || event->isWheelEvent() || event->type() == eventNames().blurEvent)) toRenderTextControlMultiLine(renderer())->forwardEvent(event); + else if (renderer() && event->isBeforeTextInsertedEvent()) + handleBeforeTextInsertedEvent(static_cast<BeforeTextInsertedEvent*>(event)); HTMLFormControlElementWithState::defaultEventHandler(event); } +void HTMLTextAreaElement::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent* event) const +{ + ASSERT(event); + ASSERT(renderer()); + int signedMaxLength = maxLength(); + if (signedMaxLength < 0) + return; + unsigned unsignedMaxLength = static_cast<unsigned>(signedMaxLength); + + unsigned currentLength = toRenderTextControl(renderer())->text().numGraphemeClusters(); + unsigned selectionLength = plainText(document()->frame()->selection()->selection().toNormalizedRange().get()).numGraphemeClusters(); + ASSERT(currentLength >= selectionLength); + unsigned baseLength = currentLength - selectionLength; + unsigned appendableLength = unsignedMaxLength > baseLength ? unsignedMaxLength - baseLength : 0; + event->setText(sanitizeUserInputValue(event->text(), appendableLength)); +} + +String HTMLTextAreaElement::sanitizeUserInputValue(const String& proposedValue, unsigned maxLength) +{ + return proposedValue.left(proposedValue.numCharactersInGraphemeClusters(maxLength)); +} + void HTMLTextAreaElement::rendererWillBeDestroyed() { updateValue(); @@ -290,6 +264,7 @@ void HTMLTextAreaElement::updateValue() const m_value = toRenderTextControl(renderer())->text(); const_cast<HTMLTextAreaElement*>(this)->setFormControlValueMatchesRenderer(true); notifyFormStateChanged(this); + m_isDirty = true; } String HTMLTextAreaElement::value() const @@ -313,6 +288,7 @@ void HTMLTextAreaElement::setValue(const String& value) m_value = normalizedValue; setFormControlValueMatchesRenderer(true); + updatePlaceholderVisibility(false); if (inDocument()) document()->updateStyleIfNeeded(); if (renderer()) @@ -330,6 +306,7 @@ void HTMLTextAreaElement::setValue(const String& value) setNeedsStyleRecalc(); notifyFormStateChanged(this); + updateValidity(); } String HTMLTextAreaElement::defaultValue() const @@ -379,6 +356,33 @@ void HTMLTextAreaElement::setDefaultValue(const String& defaultValue) setValue(value); } +int HTMLTextAreaElement::maxLength() const +{ + bool ok; + int value = getAttribute(maxlengthAttr).string().toInt(&ok); + return ok && value >= 0 ? value : -1; +} + +void HTMLTextAreaElement::setMaxLength(int newValue, ExceptionCode& ec) +{ + if (newValue < 0) + ec = INDEX_SIZE_ERR; + else + setAttribute(maxlengthAttr, String::number(newValue)); +} + +bool HTMLTextAreaElement::tooLong() const +{ + // Return false for the default value even if it is longer than maxLength. + if (!m_isDirty) + return false; + + int max = maxLength(); + if (max < 0) + return false; + return value().length() > static_cast<unsigned>(max); +} + void HTMLTextAreaElement::accessKeyAction(bool) { focus(); @@ -404,13 +408,6 @@ void HTMLTextAreaElement::setRows(int rows) setAttribute(rowsAttr, String::number(rows)); } -VisibleSelection HTMLTextAreaElement::selection() const -{ - if (!renderer() || m_cachedSelectionStart < 0 || m_cachedSelectionEnd < 0) - return VisibleSelection(); - return toRenderTextControl(renderer())->selection(m_cachedSelectionStart, m_cachedSelectionEnd); -} - bool HTMLTextAreaElement::shouldUseInputMethod() const { return true; |