summaryrefslogtreecommitdiff
path: root/Source/WebCore/html/HTMLTextAreaElement.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/html/HTMLTextAreaElement.cpp')
-rw-r--r--Source/WebCore/html/HTMLTextAreaElement.cpp32
1 files changed, 28 insertions, 4 deletions
diff --git a/Source/WebCore/html/HTMLTextAreaElement.cpp b/Source/WebCore/html/HTMLTextAreaElement.cpp
index a42aa7831..db98ccc9f 100644
--- a/Source/WebCore/html/HTMLTextAreaElement.cpp
+++ b/Source/WebCore/html/HTMLTextAreaElement.cpp
@@ -56,10 +56,15 @@ static const int defaultCols = 20;
// On submission, LF characters are converted into CRLF.
// This function returns number of characters considering this.
-static unsigned computeLengthForSubmission(const String& text)
+static inline unsigned computeLengthForSubmission(const String& text, unsigned numberOfLineBreaks)
+{
+ return numGraphemeClusters(text) + numberOfLineBreaks;
+}
+
+static unsigned numberOfLineBreaks(const String& text)
{
- unsigned count = numGraphemeClusters(text);
unsigned length = text.length();
+ unsigned count = 0;
for (unsigned i = 0; i < length; i++) {
if (text[i] == '\n')
count++;
@@ -67,6 +72,16 @@ static unsigned computeLengthForSubmission(const String& text)
return count;
}
+static inline unsigned computeLengthForSubmission(const String& text)
+{
+ return numGraphemeClusters(text) + numberOfLineBreaks(text);
+}
+
+static inline unsigned upperBoundForLengthForSubmission(const String& text, unsigned numberOfLineBreaks)
+{
+ return text.length() + numberOfLineBreaks;
+}
+
HTMLTextAreaElement::HTMLTextAreaElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
: HTMLTextFormControlElement(tagName, document, form)
, m_rows(defaultRows)
@@ -280,7 +295,13 @@ void HTMLTextAreaElement::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent*
return;
unsigned unsignedMaxLength = static_cast<unsigned>(signedMaxLength);
- unsigned currentLength = computeLengthForSubmission(innerTextValue());
+ const String& currentValue = innerTextValue();
+ unsigned numberOfLineBreaksInCurrentValue = numberOfLineBreaks(currentValue);
+ if (upperBoundForLengthForSubmission(currentValue, numberOfLineBreaksInCurrentValue)
+ + upperBoundForLengthForSubmission(event->text(), numberOfLineBreaks(event->text())) < unsignedMaxLength)
+ return;
+
+ unsigned currentLength = computeLengthForSubmission(currentValue, numberOfLineBreaksInCurrentValue);
// selectionLength represents the selection length of this text field to be
// removed by this insertion.
// If the text field has no focus, we don't need to take account of the
@@ -466,7 +487,10 @@ bool HTMLTextAreaElement::tooLong(const String& value, NeedsToCheckDirtyFlag che
int max = maxLength();
if (max < 0)
return false;
- return computeLengthForSubmission(value) > static_cast<unsigned>(max);
+ unsigned unsignedMax = static_cast<unsigned>(max);
+ unsigned numberOfLineBreaksInValue = numberOfLineBreaks(value);
+ return upperBoundForLengthForSubmission(value, numberOfLineBreaksInValue) > unsignedMax
+ && computeLengthForSubmission(value, numberOfLineBreaksInValue) > unsignedMax;
}
bool HTMLTextAreaElement::isValidValue(const String& candidate) const