2009-09-30 Kent Tamura <tkent@chromium.org>
authoreric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 1 Oct 2009 05:49:39 +0000 (05:49 +0000)
committereric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 1 Oct 2009 05:49:39 +0000 (05:49 +0000)
        Reviewed by Darin Adler.

        Add ValidityState.tooLong support for <input> and <textarea>.
        https://bugs.webkit.org/show_bug.cgi?id=27454

        * fast/forms/ValidityState-tooLong-input-expected.txt: Added.
        * fast/forms/ValidityState-tooLong-input.html: Added.
        * fast/forms/ValidityState-tooLong-textarea-expected.txt: Added.
        * fast/forms/ValidityState-tooLong-textarea.html: Added.
        * fast/forms/script-tests/ValidityState-tooLong-input.js: Added.
        * fast/forms/script-tests/ValidityState-tooLong-textarea.js: Added.
2009-09-30  Kent Tamura  <tkent@chromium.org>

        Reviewed by Darin Adler.

        Adds ValidityState.tooLong support for <input> and <textarea>.

        Introduces tooLong() in HTMLFormControlElement and it always returns false.
        HTMLInputElement and HTMLTextAreaElement overrides it and checks the text
        length and maxLength.  tooLong() should work only for `dirty' values.
        So, introduces m_isDirty flag for HTMLTextAreaElement, and
        !m_data.value().isNull() works as a dirty flag for HTMLInputElement.

        Renames parameter names of setMaxLength().

        https://bugs.webkit.org/show_bug.cgi?id=27454

        Tests: fast/forms/ValidityState-tooLong-input.html
               fast/forms/ValidityState-tooLong-textarea.html

        * html/HTMLFormControlElement.h:
        (WebCore::HTMLFormControlElement::tooLong):
        * html/HTMLInputElement.cpp:
        (WebCore::HTMLInputElement::tooLong):
        (WebCore::HTMLInputElement::setMaxLength):
        * html/HTMLInputElement.h:
        * html/HTMLTextAreaElement.cpp:
        (WebCore::HTMLTextAreaElement::HTMLTextAreaElement):
        (WebCore::HTMLTextAreaElement::reset):
        (WebCore::HTMLTextAreaElement::updateValue):
        (WebCore::HTMLTextAreaElement::setMaxLength):
        (WebCore::HTMLTextAreaElement::tooLong):
        * html/HTMLTextAreaElement.h:
        * html/ValidityState.h:
        (WebCore::ValidityState::tooLong):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@48959 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/forms/ValidityState-tooLong-input-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/ValidityState-tooLong-input.html [new file with mode: 0644]
LayoutTests/fast/forms/ValidityState-tooLong-textarea-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/ValidityState-tooLong-textarea.html [new file with mode: 0644]
LayoutTests/fast/forms/script-tests/ValidityState-tooLong-input.js [new file with mode: 0644]
LayoutTests/fast/forms/script-tests/ValidityState-tooLong-textarea.js [new file with mode: 0644]
WebCore/ChangeLog
WebCore/html/HTMLFormControlElement.h
WebCore/html/HTMLInputElement.cpp
WebCore/html/HTMLInputElement.h
WebCore/html/HTMLTextAreaElement.cpp
WebCore/html/HTMLTextAreaElement.h
WebCore/html/ValidityState.h

index 823eafb..46c9f3b 100644 (file)
@@ -1,3 +1,17 @@
+2009-09-30  Kent Tamura  <tkent@chromium.org>
+
+        Reviewed by Darin Adler.
+
+        Add ValidityState.tooLong support for <input> and <textarea>.
+        https://bugs.webkit.org/show_bug.cgi?id=27454
+
+        * fast/forms/ValidityState-tooLong-input-expected.txt: Added.
+        * fast/forms/ValidityState-tooLong-input.html: Added.
+        * fast/forms/ValidityState-tooLong-textarea-expected.txt: Added.
+        * fast/forms/ValidityState-tooLong-textarea.html: Added.
+        * fast/forms/script-tests/ValidityState-tooLong-input.js: Added.
+        * fast/forms/script-tests/ValidityState-tooLong-textarea.js: Added.
+
 2009-09-30  Maciej Stachowiak  <mjs@apple.com>
 
         Reviewed by Brady Eidson.
diff --git a/LayoutTests/fast/forms/ValidityState-tooLong-input-expected.txt b/LayoutTests/fast/forms/ValidityState-tooLong-input-expected.txt
new file mode 100644 (file)
index 0000000..945b9b3
--- /dev/null
@@ -0,0 +1,20 @@
+Tests for tooLong flag with <input> elements.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS input.validity.tooLong is false
+PASS input.value.length is 5
+PASS input.validity.tooLong is false
+PASS input.value.length is 6
+PASS input.validity.tooLong is false
+PASS input.value.length is 4
+PASS input.validity.tooLong is true
+PASS input.validity.tooLong is false
+PASS input.validity.tooLong is true
+PASS input.validity.tooLong is true
+PASS input.validity.tooLong is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/forms/ValidityState-tooLong-input.html b/LayoutTests/fast/forms/ValidityState-tooLong-input.html
new file mode 100644 (file)
index 0000000..826f8b2
--- /dev/null
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
+<script src="../../fast/js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/ValidityState-tooLong-input.js"></script>
+<script src="../../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/forms/ValidityState-tooLong-textarea-expected.txt b/LayoutTests/fast/forms/ValidityState-tooLong-textarea-expected.txt
new file mode 100644 (file)
index 0000000..d9e5bb5
--- /dev/null
@@ -0,0 +1,18 @@
+Tests for tooLong flag with <textarea> elements.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS textarea.validity.tooLong is false
+PASS textarea.value.length is 5
+PASS textarea.validity.tooLong is false
+PASS textarea.value.length is 6
+PASS textarea.validity.tooLong is false
+PASS textarea.value.length is 4
+PASS textarea.validity.tooLong is true
+PASS textarea.validity.tooLong is false
+PASS textarea.validity.tooLong is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/forms/ValidityState-tooLong-textarea.html b/LayoutTests/fast/forms/ValidityState-tooLong-textarea.html
new file mode 100644 (file)
index 0000000..b1d8030
--- /dev/null
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
+<script src="../../fast/js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/ValidityState-tooLong-textarea.js"></script>
+<script src="../../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/forms/script-tests/ValidityState-tooLong-input.js b/LayoutTests/fast/forms/script-tests/ValidityState-tooLong-input.js
new file mode 100644 (file)
index 0000000..dc6109e
--- /dev/null
@@ -0,0 +1,44 @@
+description('Tests for tooLong flag with &lt;input> elements.');
+
+var input = document.createElement('input');
+document.body.appendChild(input);
+
+// No maxlength and no value
+shouldBeFalse('input.validity.tooLong');
+
+// Non-dirty value.
+input.setAttribute('value', 'abcde');
+input.maxLength = 3;
+shouldBe('input.value.length', '5');
+shouldBeFalse('input.validity.tooLong');
+
+input.setAttribute('value', 'abcdef');
+shouldBe('input.value.length', '6');
+shouldBeFalse('input.validity.tooLong');
+
+// Dirty value and longer than maxLength.
+input = document.createElement('input');
+document.body.appendChild(input);
+input.setAttribute('value', 'abcde');
+input.maxLength = 3;
+input.focus();
+input.setSelectionRange(5, 5);  // Move the cursor at the end.
+document.execCommand('delete');
+shouldBe('input.value.length', '4');
+shouldBeTrue('input.validity.tooLong');
+// Make the value <=maxLength.
+document.execCommand('delete');
+shouldBeFalse('input.validity.tooLong');
+
+// Sets a value via DOM property.
+input.value = 'abcde';
+shouldBeTrue('input.validity.tooLong');
+
+// Change the type with a too long value.
+input.type = 'search';
+shouldBeTrue('input.validity.tooLong');
+
+input.type = 'number';
+shouldBeFalse('input.validity.tooLong');
+
+var successfullyParsed = true;
diff --git a/LayoutTests/fast/forms/script-tests/ValidityState-tooLong-textarea.js b/LayoutTests/fast/forms/script-tests/ValidityState-tooLong-textarea.js
new file mode 100644 (file)
index 0000000..4a1fe17
--- /dev/null
@@ -0,0 +1,37 @@
+description('Tests for tooLong flag with &lt;textarea> elements.');
+
+var textarea = document.createElement('textarea');
+document.body.appendChild(textarea);
+
+// No maxlength and no value
+shouldBeFalse('textarea.validity.tooLong');
+
+// Non-dirty value.
+textarea.defaultValue = 'abcde';
+textarea.maxLength = 3;
+shouldBe('textarea.value.length', '5');
+shouldBeFalse('textarea.validity.tooLong');
+
+textarea.defaultValue = 'abcdef';
+shouldBe('textarea.value.length', '6');
+shouldBeFalse('textarea.validity.tooLong');
+
+// Dirty value and longer than maxLength.
+textarea = document.createElement('textarea');
+document.body.appendChild(textarea);
+textarea.defaultValue = 'abcde';
+textarea.maxLength = 3;
+textarea.focus();
+textarea.setSelectionRange(5, 5);  // Move the cursor at the end.
+document.execCommand('delete');
+shouldBe('textarea.value.length', '4');
+shouldBeTrue('textarea.validity.tooLong');
+// Make the value <=maxLength.
+document.execCommand('delete');
+shouldBeFalse('textarea.validity.tooLong');
+
+// Sets a value via DOM property.
+textarea.value = 'abcde';
+shouldBeTrue('textarea.validity.tooLong');
+
+var successfullyParsed = true;
index 6b01fc5..3639def 100644 (file)
@@ -1,3 +1,38 @@
+2009-09-30  Kent Tamura  <tkent@chromium.org>
+
+        Reviewed by Darin Adler.
+
+        Adds ValidityState.tooLong support for <input> and <textarea>.
+
+        Introduces tooLong() in HTMLFormControlElement and it always returns false.
+        HTMLInputElement and HTMLTextAreaElement overrides it and checks the text
+        length and maxLength.  tooLong() should work only for `dirty' values.
+        So, introduces m_isDirty flag for HTMLTextAreaElement, and
+        !m_data.value().isNull() works as a dirty flag for HTMLInputElement.
+
+        Renames parameter names of setMaxLength().
+
+        https://bugs.webkit.org/show_bug.cgi?id=27454
+
+        Tests: fast/forms/ValidityState-tooLong-input.html
+               fast/forms/ValidityState-tooLong-textarea.html
+
+        * html/HTMLFormControlElement.h:
+        (WebCore::HTMLFormControlElement::tooLong):
+        * html/HTMLInputElement.cpp:
+        (WebCore::HTMLInputElement::tooLong):
+        (WebCore::HTMLInputElement::setMaxLength):
+        * html/HTMLInputElement.h:
+        * html/HTMLTextAreaElement.cpp:
+        (WebCore::HTMLTextAreaElement::HTMLTextAreaElement):
+        (WebCore::HTMLTextAreaElement::reset):
+        (WebCore::HTMLTextAreaElement::updateValue):
+        (WebCore::HTMLTextAreaElement::setMaxLength):
+        (WebCore::HTMLTextAreaElement::tooLong):
+        * html/HTMLTextAreaElement.h:
+        * html/ValidityState.h:
+        (WebCore::ValidityState::tooLong):
+
 2009-09-30  Adam Barth  <abarth@webkit.org>
 
         Reviewed by Maciej Stachowiak.
index 7b3cfbd..4323e1b 100644 (file)
@@ -110,6 +110,7 @@ public:
 
     virtual bool valueMissing() const { return false; }
     virtual bool patternMismatch() const { return false; }
+    virtual bool tooLong() const { return false; }
 
     void formDestroyed() { m_form = 0; }
 
index e6b8228..7cc5565 100644 (file)
@@ -196,6 +196,42 @@ bool HTMLInputElement::patternMismatch() const
     return false;
 }
 
+bool HTMLInputElement::tooLong() const
+{
+    switch (inputType()) {
+    case EMAIL:
+    case PASSWORD:
+    case SEARCH:
+    case TELEPHONE:
+    case TEXT:
+    case URL: {
+        int max = maxLength();
+        if (max < 0)
+            return false;
+        // Return false for the default value even if it is longer than maxLength.
+        bool userEdited = !m_data.value().isNull();
+        if (!userEdited)
+            return false;
+        return value().length() > static_cast<unsigned>(max);
+    }
+    case BUTTON:
+    case CHECKBOX:
+    case COLOR:
+    case FILE:
+    case HIDDEN:
+    case IMAGE:
+    case ISINDEX:
+    case NUMBER:
+    case RADIO:
+    case RANGE:
+    case RESET:
+    case SUBMIT:
+        return false;
+    }
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
 static inline CheckedRadioButtons& checkedRadioButtons(const HTMLInputElement *element)
 {
     if (HTMLFormElement* form = element->form())
@@ -1610,12 +1646,12 @@ int HTMLInputElement::maxLength() const
     return m_data.maxLength();
 }
 
-void HTMLInputElement::setMaxLength(int _maxLength, ExceptionCode& exceptionCode)
+void HTMLInputElement::setMaxLength(int maxLength, ExceptionCode& ec)
 {
-    if (_maxLength < 0)
-        exceptionCode = INDEX_SIZE_ERR;
+    if (maxLength < 0)
+        ec = INDEX_SIZE_ERR;
     else
-        setAttribute(maxlengthAttr, String::number(_maxLength));
+        setAttribute(maxlengthAttr, String::number(maxLength));
 }
 
 bool HTMLInputElement::multiple() const
index 16e3b58..0e7df73 100644 (file)
@@ -93,6 +93,7 @@ public:
 
     virtual bool valueMissing() const;
     virtual bool patternMismatch() const;
+    virtual bool tooLong() const;
 
     bool isTextButton() const { return m_type == SUBMIT || m_type == RESET || m_type == BUTTON; }
     virtual bool isRadioButton() const { return m_type == RADIO; }
index b5e4ced..6f60ae3 100644 (file)
@@ -70,6 +70,7 @@ HTMLTextAreaElement::HTMLTextAreaElement(const QualifiedName& tagName, Document*
     , m_wrap(SoftWrap)
     , m_cachedSelectionStart(-1)
     , m_cachedSelectionEnd(-1)
+    , m_isDirty(false)
 {
     ASSERT(hasTagName(textareaTag));
     setFormControlValueMatchesRenderer(true);
@@ -231,6 +232,7 @@ bool HTMLTextAreaElement::appendFormData(FormDataList& encoding, bool)
 void HTMLTextAreaElement::reset()
 {
     setValue(defaultValue());
+    m_isDirty = false;
 }
 
 bool HTMLTextAreaElement::isKeyboardFocusable(KeyboardEvent*) const
@@ -316,6 +318,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
@@ -409,14 +412,26 @@ int HTMLTextAreaElement::maxLength() const
     return ok && value >= 0 ? value : -1;
 }
 
-void HTMLTextAreaElement::setMaxLength(int newValue, ExceptionCode& exceptionCode)
+void HTMLTextAreaElement::setMaxLength(int newValue, ExceptionCode& ec)
 {
     if (newValue < 0)
-        exceptionCode = INDEX_SIZE_ERR;
+        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();
index cfd471a..baf7c70 100644 (file)
@@ -81,6 +81,7 @@ public:
     int textLength() const { return value().length(); }
     int maxLength() const;
     void setMaxLength(int, ExceptionCode&);
+    virtual bool tooLong() const;
     
     void rendererWillBeDestroyed();
     
@@ -116,6 +117,7 @@ private:
     mutable String m_value;
     int m_cachedSelectionStart;
     int m_cachedSelectionEnd;
+    mutable bool m_isDirty;
 };
 
 } //namespace
index 1b87f99..9adc8fd 100644 (file)
@@ -43,7 +43,7 @@ namespace WebCore {
         bool valueMissing() { return control()->valueMissing(); }
         bool typeMismatch();
         bool patternMismatch() { return control()->patternMismatch(); }
-        bool tooLong() { return false; }
+        bool tooLong() { return control()->tooLong(); }
         bool rangeUnderflow() { return false; }
         bool rangeOverflow() { return false; }
         bool stepMismatch() { return false; }