Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Side by Side Diff: Source/core/html/HTMLTextAreaElement.cpp

Issue 22590003: input/textarea: Count value length with the standard way. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: comment in a test Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org) 4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Apple Inc. All rights reserv ed. 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Apple Inc. All rights reserv ed.
6 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) 6 * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
7 * Copyright (C) 2007 Samuel Weinig (sam@webkit.org) 7 * Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
8 * 8 *
9 * This library is free software; you can redistribute it and/or 9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public 10 * modify it under the terms of the GNU Library General Public
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 52
53 using namespace HTMLNames; 53 using namespace HTMLNames;
54 54
55 static const int defaultRows = 2; 55 static const int defaultRows = 2;
56 static const int defaultCols = 20; 56 static const int defaultCols = 20;
57 57
58 // On submission, LF characters are converted into CRLF. 58 // On submission, LF characters are converted into CRLF.
59 // This function returns number of characters considering this. 59 // This function returns number of characters considering this.
60 static inline unsigned computeLengthForSubmission(const String& text, unsigned n umberOfLineBreaks) 60 static inline unsigned computeLengthForSubmission(const String& text, unsigned n umberOfLineBreaks)
61 { 61 {
62 return numGraphemeClusters(text) + numberOfLineBreaks; 62 return text.length() + numberOfLineBreaks;
63 } 63 }
64 64
65 static unsigned numberOfLineBreaks(const String& text) 65 static unsigned numberOfLineBreaks(const String& text)
66 { 66 {
67 unsigned length = text.length(); 67 unsigned length = text.length();
68 unsigned count = 0; 68 unsigned count = 0;
69 for (unsigned i = 0; i < length; i++) { 69 for (unsigned i = 0; i < length; i++) {
70 if (text[i] == '\n') 70 if (text[i] == '\n')
71 count++; 71 count++;
72 } 72 }
73 return count; 73 return count;
74 } 74 }
75 75
76 static inline unsigned computeLengthForSubmission(const String& text) 76 static inline unsigned computeLengthForSubmission(const String& text)
77 { 77 {
78 return numGraphemeClusters(text) + numberOfLineBreaks(text); 78 return text.length() + numberOfLineBreaks(text);
79 }
80
81 static inline unsigned upperBoundForLengthForSubmission(const String& text, unsi gned numberOfLineBreaks)
82 {
83 return text.length() + numberOfLineBreaks;
84 } 79 }
85 80
86 HTMLTextAreaElement::HTMLTextAreaElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form) 81 HTMLTextAreaElement::HTMLTextAreaElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
87 : HTMLTextFormControlElement(tagName, document, form) 82 : HTMLTextFormControlElement(tagName, document, form)
88 , m_rows(defaultRows) 83 , m_rows(defaultRows)
89 , m_cols(defaultCols) 84 , m_cols(defaultCols)
90 , m_wrap(SoftWrap) 85 , m_wrap(SoftWrap)
91 , m_placeholder(0) 86 , m_placeholder(0)
92 , m_isDirty(false) 87 , m_isDirty(false)
93 , m_wasModifiedByUser(false) 88 , m_wasModifiedByUser(false)
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 void HTMLTextAreaElement::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent* event) const 282 void HTMLTextAreaElement::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent* event) const
288 { 283 {
289 ASSERT(event); 284 ASSERT(event);
290 ASSERT(renderer()); 285 ASSERT(renderer());
291 int signedMaxLength = maxLength(); 286 int signedMaxLength = maxLength();
292 if (signedMaxLength < 0) 287 if (signedMaxLength < 0)
293 return; 288 return;
294 unsigned unsignedMaxLength = static_cast<unsigned>(signedMaxLength); 289 unsigned unsignedMaxLength = static_cast<unsigned>(signedMaxLength);
295 290
296 const String& currentValue = innerTextValue(); 291 const String& currentValue = innerTextValue();
297 unsigned numberOfLineBreaksInCurrentValue = numberOfLineBreaks(currentValue) ; 292 unsigned currentLength = computeLengthForSubmission(currentValue);
298 if (upperBoundForLengthForSubmission(currentValue, numberOfLineBreaksInCurre ntValue) 293 if (currentLength + computeLengthForSubmission(event->text()) < unsignedMaxL ength)
299 + upperBoundForLengthForSubmission(event->text(), numberOfLineBreaks(eve nt->text())) < unsignedMaxLength)
300 return; 294 return;
301 295
302 unsigned currentLength = computeLengthForSubmission(currentValue, numberOfLi neBreaksInCurrentValue);
303 // selectionLength represents the selection length of this text field to be 296 // selectionLength represents the selection length of this text field to be
304 // removed by this insertion. 297 // removed by this insertion.
305 // If the text field has no focus, we don't need to take account of the 298 // If the text field has no focus, we don't need to take account of the
306 // selection length. The selection is the source of text drag-and-drop in 299 // selection length. The selection is the source of text drag-and-drop in
307 // that case, and nothing in the text field will be removed. 300 // that case, and nothing in the text field will be removed.
308 unsigned selectionLength = focused() ? computeLengthForSubmission(plainText( document()->frame()->selection()->selection().toNormalizedRange().get())) : 0; 301 unsigned selectionLength = focused() ? computeLengthForSubmission(plainText( document()->frame()->selection()->selection().toNormalizedRange().get())) : 0;
309 ASSERT(currentLength >= selectionLength); 302 ASSERT(currentLength >= selectionLength);
310 unsigned baseLength = currentLength - selectionLength; 303 unsigned baseLength = currentLength - selectionLength;
311 unsigned appendableLength = unsignedMaxLength > baseLength ? unsignedMaxLeng th - baseLength : 0; 304 unsigned appendableLength = unsignedMaxLength > baseLength ? unsignedMaxLeng th - baseLength : 0;
312 event->setText(sanitizeUserInputValue(event->text(), appendableLength)); 305 event->setText(sanitizeUserInputValue(event->text(), appendableLength));
313 } 306 }
314 307
315 String HTMLTextAreaElement::sanitizeUserInputValue(const String& proposedValue, unsigned maxLength) 308 String HTMLTextAreaElement::sanitizeUserInputValue(const String& proposedValue, unsigned maxLength)
316 { 309 {
317 return proposedValue.left(numCharactersInGraphemeClusters(proposedValue, max Length)); 310 if (maxLength > 0 && U16_IS_LEAD(proposedValue[maxLength - 1]))
311 --maxLength;
312 return proposedValue.left(maxLength);
318 } 313 }
319 314
320 HTMLElement* HTMLTextAreaElement::innerTextElement() const 315 HTMLElement* HTMLTextAreaElement::innerTextElement() const
321 { 316 {
322 Node* node = userAgentShadowRoot()->firstChild(); 317 Node* node = userAgentShadowRoot()->firstChild();
323 ASSERT(!node || node->hasTagName(divTag)); 318 ASSERT(!node || node->hasTagName(divTag));
324 return toHTMLElement(node); 319 return toHTMLElement(node);
325 } 320 }
326 321
327 void HTMLTextAreaElement::rendererWillBeDestroyed() 322 void HTMLTextAreaElement::rendererWillBeDestroyed()
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 bool HTMLTextAreaElement::tooLong(const String& value, NeedsToCheckDirtyFlag che ck) const 472 bool HTMLTextAreaElement::tooLong(const String& value, NeedsToCheckDirtyFlag che ck) const
478 { 473 {
479 // Return false for the default value or value set by script even if it is 474 // Return false for the default value or value set by script even if it is
480 // longer than maxLength. 475 // longer than maxLength.
481 if (check == CheckDirtyFlag && !m_wasModifiedByUser) 476 if (check == CheckDirtyFlag && !m_wasModifiedByUser)
482 return false; 477 return false;
483 478
484 int max = maxLength(); 479 int max = maxLength();
485 if (max < 0) 480 if (max < 0)
486 return false; 481 return false;
487 unsigned unsignedMax = static_cast<unsigned>(max); 482 return computeLengthForSubmission(value) > static_cast<unsigned>(max);
488 unsigned numberOfLineBreaksInValue = numberOfLineBreaks(value);
489 return upperBoundForLengthForSubmission(value, numberOfLineBreaksInValue) > unsignedMax
490 && computeLengthForSubmission(value, numberOfLineBreaksInValue) > unsign edMax;
491 } 483 }
492 484
493 bool HTMLTextAreaElement::isValidValue(const String& candidate) const 485 bool HTMLTextAreaElement::isValidValue(const String& candidate) const
494 { 486 {
495 return !valueMissing(candidate) && !tooLong(candidate, IgnoreDirtyFlag); 487 return !valueMissing(candidate) && !tooLong(candidate, IgnoreDirtyFlag);
496 } 488 }
497 489
498 void HTMLTextAreaElement::accessKeyAction(bool) 490 void HTMLTextAreaElement::accessKeyAction(bool)
499 { 491 {
500 focus(); 492 focus();
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 RefPtr<HTMLDivElement> placeholder = HTMLDivElement::create(document()); 542 RefPtr<HTMLDivElement> placeholder = HTMLDivElement::create(document());
551 m_placeholder = placeholder.get(); 543 m_placeholder = placeholder.get();
552 m_placeholder->setPseudo(AtomicString("-webkit-input-placeholder", Atomi cString::ConstructFromLiteral)); 544 m_placeholder->setPseudo(AtomicString("-webkit-input-placeholder", Atomi cString::ConstructFromLiteral));
553 userAgentShadowRoot()->insertBefore(m_placeholder, innerTextElement()->n extSibling(), ASSERT_NO_EXCEPTION); 545 userAgentShadowRoot()->insertBefore(m_placeholder, innerTextElement()->n extSibling(), ASSERT_NO_EXCEPTION);
554 } 546 }
555 m_placeholder->setInnerText(placeholderText, ASSERT_NO_EXCEPTION); 547 m_placeholder->setInnerText(placeholderText, ASSERT_NO_EXCEPTION);
556 fixPlaceholderRenderer(m_placeholder, innerTextElement()); 548 fixPlaceholderRenderer(m_placeholder, innerTextElement());
557 } 549 }
558 550
559 } 551 }
OLDNEW
« no previous file with comments | « LayoutTests/fast/forms/textarea-maxlength-expected.txt ('k') | Source/core/html/TextFieldInputType.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698