[CherryPick] Implement ValidityState::badInput
authorjinwoo jeong <jw00.jeong@samsung.com>
Wed, 27 Mar 2013 07:09:52 +0000 (16:09 +0900)
committerjinwoo jeong <jw00.jeong@samsung.com>
Thu, 28 Mar 2013 03:52:54 +0000 (12:52 +0900)
[Title] Implement ValidityState::badInput
[Issues] N_SE-28998
[Problem] Input type number not showing any error message in Jquery mobile single page application[Solution] Cherry picked.
[Cherry-Picker] Jinwoo Jeong <jw00.jeong@samsung.com>

Implement ValidityState::badInput
 https://bugs.webkit.org/show_bug.cgi?id=102861

 Reviewed by NOBODY (OOPS!).

 Add ValidityState::badInput, add hasBadInput, which always returns
 false, to FormAssociatedElement, HTMLInputElement, and InputType.

  For NumberInputType, we had hasUnacceptableValue, which was a hack to
  make an input element match to :invalid if the element had non-number
  strings. We don't need the hack any more because badInput affects :invalid
  style. hasUnacceptableValue is re-used for hasBadInput implementation.
  We cleared invalid numbers when elements lost focus to tell users that
  the element had invalid numbers. We don't need this behavior because the
  interactive validation tells it.

  For date/time input types, we should make an input badInput when the
  input has empty value but its sub-fields have values. It covers both of
  partial input cases such as 12/--/2012 and invalid dates such as
  02/31/2012.

  For other types, ValidityState::badInput always returns false.

  This patch doesn't contain tests for badInput validation messages. They
  will be added later.

  Tests: fast/forms/date-multiple-fields/date-multiple-fields-validity-badinput.html
         fast/forms/datetime-multiple-fields/datetime-multiple-fields-validity-badinput.html
         fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-validity-badinput.html
         fast/forms/month-multiple-fields/month-multiple-fields-validity-badinput.html
         fast/forms/number/number-validity-badinput.html
         fast/forms/time-multiple-fields/time-multiple-fields-validity-badinput.html
         fast/forms/week-multiple-fields/week-multiple-fields-validity-badinput.html

  * html/ValidityState.idl: Add badInput IDL attribute.
  * html/ValidityState.h:
  (ValidityState): Add badInput.
  * html/ValidityState.cpp:
  (WebCore::ValidityState::badInput):
  Added. Calls FormAssociatedElement::hasBadInput.

  * html/FormAssociatedElement.h:
  (FormAssociatedElement): Add hasBadInput.
  * html/FormAssociatedElement.cpp:
  (WebCore::FormAssociatedElement::hasBadInput):
  Added. It always returns false.
  (WebCore::FormAssociatedElement::valid): Takes account of hasBadInput().

  * html/HTMLInputElement.h:
  (HTMLInputElement):
  Remove hasUnacceptableValue, and add hasBadInput override.
  * html/HTMLInputElement.cpp:
  (WebCore::HTMLInputElement::hasBadInput):
  Added. Delegate to InputType::hasBadInput.
  (WebCore): Remove hasUnacceptableValue.

  * html/InputType.h:
  (InputType): Add hasBadInput and badInputText, and remove
  hasUnacceptableValue.
  * html/InputType.cpp:
  (WebCore::InputType::hasBadInput): Added. Returns false.
  (WebCore::InputType::badInputText):
  Added. This function should not be called because hasBadInput always
  returns false.
  (WebCore::InputType::validationMessage):
  Supports badInput. This returns badInputText if hasBadInput is true.

  * html/NumberInputType.h:
  (NumberInputType): Add hasBadInput and badInputTest. Remove
  handleBlurEvent and hasUnacceptableValue.
  * html/NumberInputType.cpp:
  Remove handleBlurEvent, which cleared invalid number strings.
  (WebCore::NumberInputType::hasBadInput):
  Added. We don't need to check existence of a renderer. The standard form
  validation feature doesn't care of it.
  (WebCore::NumberInputType::badInputText): Returns
  validationMessageBadInputForNumberText defined in LocalizedStrings.h.
  * css/SelectorChecker.cpp:
  (WebCore::SelectorChecker::checkOneSelector):
  Remove a hack for hasUnacceptableValue. isValidFormControlElement takes
  account of badInput.
  * dom/Element.h: Remove hasUnacceptableValue.

  * html/BaseMultipleFieldsDateAndTimeInputType.h:
  (BaseMultipleFieldsDateAndTimeInputType): Add hasBadInput and badInputText.
  * html/BaseMultipleFieldsDateAndTimeInputType.cpp:
  (WebCore::BaseMultipleFieldsDateAndTimeInputType::badInputText):
  Returns validationMessageBadInputForDateTimeText defined in LocalizedStrings.h.
  (WebCore::BaseMultipleFieldsDateAndTimeInputType::hasBadInput):
  Added.
  (WebCore::BaseMultipleFieldsDateAndTimeInputType::setValue):
  Add setNeedsValidityCheck call. It is needed because
  updateInnerTextValue can modify subfields empty state.

  * html/TextFieldInputType.cpp:
  (WebCore::TextFieldInputType::subtreeHasChanged): Update a comment.
  * platform/LocalizedStrings.h:
   (WebCore): Add validationMessageBadInputForNumberText and
   validationMessageBadInputForDateTimeText.
   * platform/LocalizedStrings.cpp:
   (WebCore::validationMessageBadInputForNumberText):
   Added a placeholder implementation. This should be fixed later.
   * platform/blackberry/LocalizedStringsBlackBerry.cpp:
   (WebCore::validationMessageBadInputForNumberText): Ditto.
   * platform/efl/LocalizedStringsEfl.cpp:
   (WebCore::validationMessageBadInputForNumberText): Ditto.
   * platform/qt/LocalizedStringsQt.cpp:
   (WebCore::validationMessageBadInputForNumberText): Ditto.

39 files changed:
LayoutTests/fast/forms/ValidityState-001.html
LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-validity-badinput-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-validity-badinput.html [new file with mode: 0644]
LayoutTests/fast/forms/datetime-multiple-fields/datetime-multiple-fields-validity-badinput-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/datetime-multiple-fields/datetime-multiple-fields-validity-badinput.html [new file with mode: 0644]
LayoutTests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-validity-badinput-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-validity-badinput.html [new file with mode: 0644]
LayoutTests/fast/forms/month-multiple-fields/month-multiple-fields-validity-badinput-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/month-multiple-fields/month-multiple-fields-validity-badinput.html [new file with mode: 0644]
LayoutTests/fast/forms/number/number-validity-badinput-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/number/number-validity-badinput.htm [moved from LayoutTests/fast/forms/number/number-unacceptable-style.html with 100% similarity]
LayoutTests/fast/forms/number/number-validity-badinput.html [new file with mode: 0644]
LayoutTests/fast/forms/resources/multiple-fields-validity-badinput.js [new file with mode: 0644]
LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-validity-badinput-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-validity-badinput.html [new file with mode: 0644]
LayoutTests/fast/forms/week-multiple-fields/week-multiple-fields-validity-badinput-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/week-multiple-fields/week-multiple-fields-validity-badinput.html [new file with mode: 0644]
Source/WebCore/css/SelectorChecker.cpp
Source/WebCore/dom/Element.h
Source/WebCore/html/FormAssociatedElement.cpp
Source/WebCore/html/FormAssociatedElement.h
Source/WebCore/html/HTMLInputElement.cpp
Source/WebCore/html/HTMLInputElement.h
Source/WebCore/html/InputType.cpp
Source/WebCore/html/InputType.h
Source/WebCore/html/NumberInputType.cpp
Source/WebCore/html/NumberInputType.h
Source/WebCore/html/TextFieldInputType.cpp
Source/WebCore/html/ValidityState.cpp
Source/WebCore/html/ValidityState.h
Source/WebCore/html/ValidityState.idl
Source/WebCore/platform/LocalizedStrings.cpp
Source/WebCore/platform/LocalizedStrings.h
Source/WebCore/platform/blackberry/LocalizedStringsBlackBerry.cpp
Source/WebCore/platform/efl/LocalizedStringsEfl.cpp
Source/WebCore/platform/efl/tizen/LocalizedStringsTizen.cpp
Source/WebCore/platform/gtk/LocalizedStringsGtk.cpp
Source/WebCore/platform/qt/LocalizedStringsQt.cpp
Source/WebKit/chromium/src/LocalizedStrings.cpp

index 3c5248e..59aab13 100644 (file)
@@ -22,7 +22,7 @@
         v = document.getElementsByName("victim");
 
         for (i = 0; i < v.length; i++)
-            log('Test for ' + v[i].tagName + ': ' + ((v[i].validity && countAttr(v[i].validity) == 9) ? "SUCCESS" : "FAILURE"));
+            log('Test for ' + v[i].tagName + ': ' + ((v[i].validity && countAttr(v[i].validity) == 10) ? "SUCCESS" : "FAILURE"));
     }
 </script>
 </head>
diff --git a/LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-validity-badinput-expected.txt b/LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-validity-badinput-expected.txt
new file mode 100644 (file)
index 0000000..1fe0a6f
--- /dev/null
@@ -0,0 +1,20 @@
+A date input fields with a bad user input should make validity.badInput true and have :invalid style.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Initial state. The elment has no value.
+PASS colorOf(input) is not invalidStyleColor
+PASS input.validity.badInput is false
+Set a value to the first sub-field. The element becomes badInput.
+PASS colorOf(input) is invalidStyleColor
+PASS input.validity.badInput is true
+Set an invalid date, 2012-02-31.
+PASS input.validity.badInput is false
+PASS input.value is ""
+PASS input.validity.badInput is true
+PASS colorOf(input) is invalidStyleColor
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-validity-badinput.html b/LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-validity-badinput.html
new file mode 100644 (file)
index 0000000..c1a789e
--- /dev/null
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<style>
+:invalid {
+    background-color: #ff0000;
+}
+</style>
+<body>
+<script src="../../js/resources/js-test-pre.js"></script>
+<script src="../resources/multiple-fields-validity-badinput.js"></script>
+<script>
+testBadInput('date');
+</script>
+<script src="../../js/resources/js-test-post.js"></script>
+</body>
diff --git a/LayoutTests/fast/forms/datetime-multiple-fields/datetime-multiple-fields-validity-badinput-expected.txt b/LayoutTests/fast/forms/datetime-multiple-fields/datetime-multiple-fields-validity-badinput-expected.txt
new file mode 100644 (file)
index 0000000..3a4ee45
--- /dev/null
@@ -0,0 +1,20 @@
+A datetime input fields with a bad user input should make validity.badInput true and have :invalid style.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Initial state. The elment has no value.
+PASS colorOf(input) is not invalidStyleColor
+PASS input.validity.badInput is false
+Set a value to the first sub-field. The element becomes badInput.
+PASS colorOf(input) is invalidStyleColor
+PASS input.validity.badInput is true
+Set an invalid date, 2012-02-31.
+PASS input.validity.badInput is false
+PASS input.value is ""
+PASS input.validity.badInput is true
+PASS colorOf(input) is invalidStyleColor
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/forms/datetime-multiple-fields/datetime-multiple-fields-validity-badinput.html b/LayoutTests/fast/forms/datetime-multiple-fields/datetime-multiple-fields-validity-badinput.html
new file mode 100644 (file)
index 0000000..882a0f1
--- /dev/null
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<style>
+:invalid {
+    background-color: #ff0000;
+}
+</style>
+<body>
+<script src="../../js/resources/js-test-pre.js"></script>
+<script src="../resources/multiple-fields-validity-badinput.js"></script>
+<script>
+testBadInput('datetime');
+</script>
+<script src="../../js/resources/js-test-post.js"></script>
+</body>
diff --git a/LayoutTests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-validity-badinput-expected.txt b/LayoutTests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-validity-badinput-expected.txt
new file mode 100644 (file)
index 0000000..165fa48
--- /dev/null
@@ -0,0 +1,20 @@
+A datetime-local input fields with a bad user input should make validity.badInput true and have :invalid style.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Initial state. The elment has no value.
+PASS colorOf(input) is not invalidStyleColor
+PASS input.validity.badInput is false
+Set a value to the first sub-field. The element becomes badInput.
+PASS colorOf(input) is invalidStyleColor
+PASS input.validity.badInput is true
+Set an invalid date, 2012-02-31.
+PASS input.validity.badInput is false
+PASS input.value is ""
+PASS input.validity.badInput is true
+PASS colorOf(input) is invalidStyleColor
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-validity-badinput.html b/LayoutTests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-validity-badinput.html
new file mode 100644 (file)
index 0000000..ce41fd3
--- /dev/null
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<style>
+:invalid {
+    background-color: #ff0000;
+}
+</style>
+<body>
+<script src="../../js/resources/js-test-pre.js"></script>
+<script src="../resources/multiple-fields-validity-badinput.js"></script>
+<script>
+testBadInput('datetime-local');
+</script>
+<script src="../../js/resources/js-test-post.js"></script>
+</body>
diff --git a/LayoutTests/fast/forms/month-multiple-fields/month-multiple-fields-validity-badinput-expected.txt b/LayoutTests/fast/forms/month-multiple-fields/month-multiple-fields-validity-badinput-expected.txt
new file mode 100644 (file)
index 0000000..080b539
--- /dev/null
@@ -0,0 +1,15 @@
+A month input fields with a bad user input should make validity.badInput true and have :invalid style.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Initial state. The elment has no value.
+PASS colorOf(input) is not invalidStyleColor
+PASS input.validity.badInput is false
+Set a value to the first sub-field. The element becomes badInput.
+PASS colorOf(input) is invalidStyleColor
+PASS input.validity.badInput is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/forms/month-multiple-fields/month-multiple-fields-validity-badinput.html b/LayoutTests/fast/forms/month-multiple-fields/month-multiple-fields-validity-badinput.html
new file mode 100644 (file)
index 0000000..356eea5
--- /dev/null
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<style>
+:invalid {
+    background-color: #ff0000;
+}
+</style>
+<body>
+<script src="../../js/resources/js-test-pre.js"></script>
+<script src="../resources/multiple-fields-validity-badinput.js"></script>
+<script>
+testBadInput('month');
+</script>
+<script src="../../js/resources/js-test-post.js"></script>
+</body>
diff --git a/LayoutTests/fast/forms/number/number-validity-badinput-expected.txt b/LayoutTests/fast/forms/number/number-validity-badinput-expected.txt
new file mode 100644 (file)
index 0000000..f8c7631
--- /dev/null
@@ -0,0 +1,32 @@
+A number input fields with a bad input string should make validity.badInput true and have :invalid style.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Initial state. The elment has no value.
+PASS colorOf(number) != invalidStyleColor is true
+PASS number.validity.badInput is false
+Type '-'. The element becomes badInput.
+PASS colorOf(number) is invalidStyleColor
+PASS number.validity.valid is false
+PASS number.validity.badInput is true
+PASS number.value is ""
+Type '1' additionally. The element becomes valid.
+PASS colorOf(number) != invalidStyleColor is true
+PASS number.validity.badInput is false
+PASS number.value is "-1"
+Type 'a' additionally. The element becomes badInput again.
+PASS colorOf(number) is invalidStyleColor
+PASS number.validity.badInput is true
+PASS number.value is ""
+The element losts focus. The element state should not be changed.
+PASS colorOf(number) is invalidStyleColor
+PASS number.validity.badInput is true
+PASS document.getSelection().toString() is "-1a"
+PASS number.value is ""
+The element losts a renderer. The element state should not be changed.
+PASS number.style.display = "none"; number.validity.badInput is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/forms/number/number-validity-badinput.html b/LayoutTests/fast/forms/number/number-validity-badinput.html
new file mode 100644 (file)
index 0000000..06c6c0a
--- /dev/null
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../fast/js/resources/js-test-pre.js"></script>
+<style>
+:invalid {
+  background-color: #ff0000;
+}
+</style>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<div id=parent>
+<input type=number id=number>
+<input id=another>
+</div>
+<script>
+description('A number input fields with a bad input string should make validity.badInput true and have :invalid style.');
+
+function colorOf(el) {
+    return document.defaultView.getComputedStyle(el, null).getPropertyValue('background-color');
+}
+var invalidStyleColor = 'rgb(255, 0, 0)';
+
+var number = document.getElementById('number');
+number.focus();
+debug('Initial state. The elment has no value.');
+shouldBeTrue('colorOf(number) != invalidStyleColor');
+shouldBeFalse('number.validity.badInput');
+
+debug("Type '-'. The element becomes badInput.");
+document.execCommand('InsertText', false, '-');
+shouldBe('colorOf(number)', 'invalidStyleColor');
+shouldBeFalse('number.validity.valid');
+shouldBeTrue('number.validity.badInput');
+shouldBeEqualToString('number.value', '');
+
+debug("Type '1' additionally. The element becomes valid.");
+document.execCommand('InsertText', false, '1');
+shouldBeTrue('colorOf(number) != invalidStyleColor');
+shouldBeFalse('number.validity.badInput');
+shouldBeEqualToString('number.value', '-1');
+
+debug("Type 'a' additionally. The element becomes badInput again.");
+document.execCommand('InsertText', false, 'a');
+shouldBe('colorOf(number)', 'invalidStyleColor');
+shouldBeTrue('number.validity.badInput');
+shouldBeEqualToString('number.value', '');
+
+debug("The element losts focus. The element state should not be changed.");
+document.getElementById('another').focus();
+shouldBe('colorOf(number)', 'invalidStyleColor');
+shouldBeTrue('number.validity.badInput');
+// Visible value is '-1a'.
+number.focus();
+document.execCommand('SelectAll');
+shouldBeEqualToString('document.getSelection().toString()', '-1a');
+shouldBeEqualToString('number.value', '');
+
+debug("The element losts a renderer. The element state should not be changed.");
+shouldBeTrue('number.style.display = "none"; number.validity.badInput');
+
+document.getElementById('parent').innerHTML = '';
+</script>
+<script src="../../../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/forms/resources/multiple-fields-validity-badinput.js b/LayoutTests/fast/forms/resources/multiple-fields-validity-badinput.js
new file mode 100644 (file)
index 0000000..081ed59
--- /dev/null
@@ -0,0 +1,44 @@
+var invalidStyleColor = 'rgb(255, 0, 0)';
+var input;
+var quiet = true;
+
+function colorOf(el) {
+    return document.defaultView.getComputedStyle(el, null).getPropertyValue('background-color');
+}
+function testBadInput(type) {
+    if (!window.eventSender) {
+        debug('Needs to run this on DRT/WTR.');
+        return;
+    }
+    description('A ' + type + ' input fields with a bad user input should make validity.badInput true and have :invalid style.');
+    input = document.createElement('input');
+    input.type = type;
+    document.body.appendChild(input);
+    input.focus();
+
+    debug('Initial state. The elment has no value.');
+    shouldNotBe('colorOf(input)', 'invalidStyleColor');
+    shouldBeFalse('input.validity.badInput');
+
+    debug('Set a value to the first sub-field. The element becomes badInput.');
+    eventSender.keyDown('upArrow');
+    shouldBe('colorOf(input)', 'invalidStyleColor');
+    shouldBeTrue('input.validity.badInput');
+
+    if (type == 'date' || type== 'datetime' || type == 'datetime-local') {
+        debug('Set an invalid date, 2012-02-31.');
+        if (type == 'date')
+            input.value = '2012-02-01';
+        else if (type == 'datetime')
+            input.value = '2012-02-01T03:04Z';
+        else
+            input.value = '2012-02-01T03:04';
+        shouldNotBe('colorOf(input)', 'invalidStyleColor', quiet);
+        shouldBeFalse('input.validity.badInput', quiet);
+        eventSender.keyDown('rightArrow'); // -> 02/[01]/2012 ...
+        eventSender.keyDown('downArrow'); //  -> 02/[31]/2012 ...
+        shouldBeEqualToString('input.value', '');
+        shouldBeTrue('input.validity.badInput');
+        shouldBe('colorOf(input)', 'invalidStyleColor');
+    }
+}
diff --git a/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-validity-badinput-expected.txt b/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-validity-badinput-expected.txt
new file mode 100644 (file)
index 0000000..480f561
--- /dev/null
@@ -0,0 +1,15 @@
+A time input fields with a bad user input should make validity.badInput true and have :invalid style.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Initial state. The elment has no value.
+PASS colorOf(input) is not invalidStyleColor
+PASS input.validity.badInput is false
+Set a value to the first sub-field. The element becomes badInput.
+PASS colorOf(input) is invalidStyleColor
+PASS input.validity.badInput is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-validity-badinput.html b/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-validity-badinput.html
new file mode 100644 (file)
index 0000000..8280f0e
--- /dev/null
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<style>
+:invalid {
+    background-color: #ff0000;
+}
+</style>
+<body>
+<script src="../../js/resources/js-test-pre.js"></script>
+<script src="../resources/multiple-fields-validity-badinput.js"></script>
+<script>
+testBadInput('time');
+</script>
+<script src="../../js/resources/js-test-post.js"></script>
+</body>
diff --git a/LayoutTests/fast/forms/week-multiple-fields/week-multiple-fields-validity-badinput-expected.txt b/LayoutTests/fast/forms/week-multiple-fields/week-multiple-fields-validity-badinput-expected.txt
new file mode 100644 (file)
index 0000000..2d61821
--- /dev/null
@@ -0,0 +1,15 @@
+A week input fields with a bad user input should make validity.badInput true and have :invalid style.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Initial state. The elment has no value.
+PASS colorOf(input) is not invalidStyleColor
+PASS input.validity.badInput is false
+Set a value to the first sub-field. The element becomes badInput.
+PASS colorOf(input) is invalidStyleColor
+PASS input.validity.badInput is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/forms/week-multiple-fields/week-multiple-fields-validity-badinput.html b/LayoutTests/fast/forms/week-multiple-fields/week-multiple-fields-validity-badinput.html
new file mode 100644 (file)
index 0000000..847a6ee
--- /dev/null
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<style>
+:invalid {
+    background-color: #ff0000;
+}
+</style>
+<body>
+<script src="../../js/resources/js-test-pre.js"></script>
+<script src="../resources/multiple-fields-validity-badinput.js"></script>
+<script>
+testBadInput('week');
+</script>
+<script src="../../js/resources/js-test-post.js"></script>
+</body>
index ef6ea82..68a8ede 100644 (file)
@@ -1084,7 +1084,7 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P
             if (!element)
                 return false;
             element->document()->setContainsValidityStyleRules();
-            return (element->willValidate() && !element->isValidFormControlElement()) || element->hasUnacceptableValue();
+            return element->willValidate() && !element->isValidFormControlElement();
         case CSSSelector::PseudoChecked:
             {
                 if (!element)
index 0159021..342a236 100644 (file)
@@ -381,7 +381,6 @@ public:
     virtual bool isDefaultButtonForForm() const { return false; }
     virtual bool willValidate() const { return false; }
     virtual bool isValidFormControlElement() { return false; }
-    virtual bool hasUnacceptableValue() const { return false; }
     virtual bool isInRange() const { return false; }
     virtual bool isOutOfRange() const { return false; }
     virtual bool isFrameElementBase() const { return false; }
index 99377df..dc3050d 100644 (file)
@@ -188,6 +188,11 @@ bool FormAssociatedElement::customError() const
     return element->willValidate() && !m_customValidationMessage.isEmpty();
 }
 
+bool FormAssociatedElement::hasBadInput() const
+{
+    return false;
+}
+
 bool FormAssociatedElement::patternMismatch() const
 {
     return false;
@@ -221,7 +226,7 @@ bool FormAssociatedElement::typeMismatch() const
 bool FormAssociatedElement::valid() const
 {
     bool someError = typeMismatch() || stepMismatch() || rangeUnderflow() || rangeOverflow()
-        || tooLong() || patternMismatch() || valueMissing() || customError();
+        || tooLong() || patternMismatch() || valueMissing() || hasBadInput() || customError();
     return !someError;
 }
 
index f981063..51ff3e3 100644 (file)
@@ -72,6 +72,7 @@ public:
 
     // Override functions for patterMismatch, rangeOverflow, rangerUnderflow,
     // stepMismatch, tooLong and valueMissing must call willValidate method.
+    virtual bool hasBadInput() const;
     virtual bool patternMismatch() const;
     virtual bool rangeOverflow() const;
     virtual bool rangeUnderflow() const;
index 094bc89..fd32fea 100755 (executable)
@@ -243,6 +243,11 @@ bool HTMLInputElement::valueMissing() const
     return willValidate() && m_inputType->valueMissing(value());
 }
 
+bool HTMLInputElement::hasBadInput() const
+{
+    return m_inputType->hasBadInput();
+}
+
 bool HTMLInputElement::patternMismatch() const
 {
     return willValidate() && m_inputType->patternMismatch(value());
@@ -1320,11 +1325,6 @@ String HTMLInputElement::localizeValue(const String& proposedValue) const
     return m_inputType->localizeValue(proposedValue);
 }
 
-bool HTMLInputElement::hasUnacceptableValue() const
-{
-    return m_inputType->hasUnacceptableValue();
-}
-
 bool HTMLInputElement::isInRange() const
 {
     return m_inputType->isInRange(value());
index c47078b..d2128b6 100755 (executable)
@@ -53,6 +53,7 @@ public:
     virtual bool shouldAutocomplete() const;
 
     // For ValidityState
+    virtual bool hasBadInput() const OVERRIDE;
     virtual bool patternMismatch() const OVERRIDE;
     virtual bool rangeUnderflow() const OVERRIDE;
     virtual bool rangeOverflow() const;
@@ -326,8 +327,6 @@ private:
 
     virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
 
-    virtual bool hasUnacceptableValue() const;
-
     virtual bool isInRange() const;
     virtual bool isOutOfRange() const;
 
index 32251ac..ee56250 100644 (file)
@@ -256,6 +256,11 @@ bool InputType::valueMissing(const String&) const
     return false;
 }
 
+bool InputType::hasBadInput() const
+{
+    return false;
+}
+
 bool InputType::patternMismatch(const String&) const
 {
     return false;
@@ -344,6 +349,12 @@ bool InputType::stepMismatch(const String& value) const
     return createStepRange(RejectAny).stepMismatch(numericValue);
 }
 
+String InputType::badInputText() const
+{
+    ASSERT_NOT_REACHED();
+    return validationMessageTypeMismatchText();
+}
+
 String InputType::typeMismatchText() const
 {
     return validationMessageTypeMismatchText();
@@ -366,6 +377,9 @@ String InputType::validationMessage() const
     if (typeMismatch())
         return typeMismatchText();
 
+    if (hasBadInput())
+        return badInputText();
+
     if (patternMismatch(value))
         return validationMessagePatternMismatchText();
 
@@ -676,11 +690,6 @@ String InputType::sanitizeValue(const String& proposedValue) const
     return proposedValue;
 }
 
-bool InputType::hasUnacceptableValue()
-{
-    return false;
-}
-
 bool InputType::receiveDroppedFiles(const DragData*)
 {
     ASSERT_NOT_REACHED();
index 749909d..bf0666c 100644 (file)
@@ -161,6 +161,7 @@ public:
     virtual bool typeMismatch() const;
     virtual bool supportsRequired() const;
     virtual bool valueMissing(const String&) const;
+    virtual bool hasBadInput() const;
     virtual bool patternMismatch(const String&) const;
     bool rangeUnderflow(const String&) const;
     bool rangeOverflow(const String&) const;
@@ -175,6 +176,7 @@ public:
     virtual StepRange createStepRange(AnyStepHandling) const;
     virtual void stepUp(int, ExceptionCode&);
     virtual void stepUpFromRenderer(int);
+    virtual String badInputText() const;
     virtual String typeMismatchText() const;
     virtual String valueMissingText() const;
     virtual bool canSetStringValue() const;
@@ -183,7 +185,6 @@ public:
     // Returing the null string means "use the default value."
     // This function must be called only by HTMLInputElement::sanitizeValue().
     virtual String sanitizeValue(const String&) const;
-    virtual bool hasUnacceptableValue();
 
     // Event handlers
 
index de18cfa..579feb1 100644 (file)
@@ -39,6 +39,8 @@
 #include "HTMLParserIdioms.h"
 #include "KeyboardEvent.h"
 #include "LocalizedNumber.h"
+#include "LocalizedStrings.h"
+//#include "PlatformLocale.h"
 #include "RenderTextControl.h"
 #include <limits>
 #include <wtf/ASCIICType.h>
@@ -217,16 +219,6 @@ String NumberInputType::serialize(const Decimal& value) const
     return serializeForNumberType(value);
 }
 
-void NumberInputType::handleBlurEvent()
-{
-    // Reset the renderer value, which might be unmatched with the element value.
-    element()->setFormControlValueMatchesRenderer(false);
-
-    // We need to reset the renderer value explicitly because an unacceptable
-    // renderer value should be purged before style calculation.
-    updateInnerTextValue();
-}
-
 static bool isE(UChar ch)
 {
     return ch == 'e' || ch == 'E';
@@ -270,14 +262,17 @@ String NumberInputType::sanitizeValue(const String& proposedValue) const
     return isfinite(parseToDoubleForNumberType(proposedValue)) ? proposedValue : emptyString();
 }
 
-bool NumberInputType::hasUnacceptableValue()
+bool NumberInputType::hasBadInput() const
 {
-    if (!element()->renderer())
-        return false;
     String standardValue = convertFromVisibleValue(element()->innerTextValue());
     return !standardValue.isEmpty() && !isfinite(parseToDoubleForNumberType(standardValue));
 }
 
+String NumberInputType::badInputText() const
+{
+    return validationMessageBadInputForNumberText();
+}
+
 bool NumberInputType::shouldRespectSpeechAttribute()
 {
     return true;
index f06e808..b9629fe 100644 (file)
@@ -54,12 +54,12 @@ private:
     virtual void handleWheelEvent(WheelEvent*) OVERRIDE;
     virtual Decimal parseToNumber(const String&, const Decimal&) const OVERRIDE;
     virtual String serialize(const Decimal&) const OVERRIDE;
-    virtual void handleBlurEvent() OVERRIDE;
     virtual String localizeValue(const String&) const OVERRIDE;
     virtual String visibleValue() const OVERRIDE;
     virtual String convertFromVisibleValue(const String&) const OVERRIDE;
     virtual String sanitizeValue(const String&) const OVERRIDE;
-    virtual bool hasUnacceptableValue() OVERRIDE;
+    virtual bool hasBadInput() const OVERRIDE;
+    virtual String badInputText() const OVERRIDE;
     virtual bool shouldRespectSpeechAttribute() OVERRIDE;
     virtual bool supportsPlaceholder() const OVERRIDE;
     virtual bool isNumberField() const OVERRIDE;
index 4a1cc47..8dc9cfc 100644 (file)
@@ -463,7 +463,7 @@ void TextFieldInputType::subtreeHasChanged()
     // sanitizeValue() is needed because IME input doesn't dispatch BeforeTextInsertedEvent.
     element()->setValueFromRenderer(sanitizeValue(convertFromVisibleValue(element()->innerTextValue())));
     element()->updatePlaceholderVisibility(false);
-    // Recalc for :invalid and hasUnacceptableValue() change.
+    // Recalc for :invalid change.
     element()->setNeedsStyleRecalc();
 
     didSetValueByUserEdit(wasChanged ? ValueChangeStateChanged : ValueChangeStateNone);
index 649765d..f04ea76 100644 (file)
@@ -76,6 +76,11 @@ bool ValidityState::stepMismatch() const
     return m_control->stepMismatch();
 }
 
+bool ValidityState::badInput() const
+{
+    return m_control->hasBadInput();
+}
+
 bool ValidityState::customError() const
 {
     return m_control->customError();
index 17e94c9..d51c967 100644 (file)
@@ -51,6 +51,7 @@ public:
     bool rangeUnderflow() const;
     bool rangeOverflow() const;
     bool stepMismatch() const;
+    bool badInput() const;
     bool customError() const;
     bool valid() const;
 
index 601bfaf..3e00a68 100644 (file)
@@ -32,6 +32,7 @@ module html {
         readonly attribute boolean         rangeUnderflow;
         readonly attribute boolean         rangeOverflow;
         readonly attribute boolean         stepMismatch;
+        readonly attribute boolean         badInput;
         readonly attribute boolean         customError;
         readonly attribute boolean         valid;
     };
index bc54b61..e82a567 100644 (file)
@@ -980,4 +980,10 @@ String validationMessageStepMismatchText(const String&, const String&)
     return WEB_UI_STRING("step mismatch", "Validation message for input form controls with value not respecting the step attribute");
 }
 
+String validationMessageBadInputForNumberText()
+{
+    notImplemented();
+    return validationMessageTypeMismatchText();
+}
+
 } // namespace WebCore
index 2233bc7..0cc2b6f 100755 (executable)
@@ -225,6 +225,10 @@ namespace WebCore {
     String validationMessageRangeUnderflowText(const String& minimum);
     String validationMessageRangeOverflowText(const String& maximum);
     String validationMessageStepMismatchText(const String& base, const String& step);
+    String validationMessageBadInputForNumberText();
+/*#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
+    String validationMessageBadInputForDateTimeText();
+#endif*/
 #if ENABLE(CALENDAR_PICKER)
     String calendarTodayText();
     String calendarClearText();
index 732c4df..c445004 100644 (file)
@@ -524,6 +524,12 @@ String validationMessageValueMissingForSelectText()
     return validationMessageValueMissingText();
 }
 
+String validationMessageBadInputForNumberText()
+{
+    notImplemented();
+    return validationMessageTypeMismatchText();
+}
+
 String localizedMediaControlElementString(const String&)
 {
     notImplemented();
index db03abf..dd24b6a 100755 (executable)
@@ -535,6 +535,12 @@ String validationMessageValueMissingForSelectText()
     return validationMessageValueMissingText();
 }
 
+String validationMessageBadInputForNumberText()
+{
+    notImplemented();
+    return validationMessageTypeMismatchText();
+}
+
 String missingPluginText()
 {
     return String::fromUTF8("missing plugin");
@@ -576,4 +582,4 @@ String localizedString(const char* key)
 {
     return String::fromUTF8(key, strlen(key));
 }
-}
\ No newline at end of file
+}
index a50de88..b7a9e90 100644 (file)
@@ -550,6 +550,12 @@ String validationMessageValueMissingForSelectText()
     return validationMessageValueMissingText();
 }
 
+String validationMessageBadInputForNumberText()
+{
+    notImplemented();
+    return validationMessageTypeMismatchText();
+}
+
 String missingPluginText()
 {
     return String::fromUTF8("missing plugin");
@@ -591,4 +597,4 @@ String localizedString(const char* key)
 {
     return String::fromUTF8(key, strlen(key));
 }
-}
\ No newline at end of file
+}
index 2ae8030..d02393f 100644 (file)
@@ -728,4 +728,10 @@ String localizedString(const char* key)
     return String::fromUTF8(key, strlen(key));
 }
 
+String validationMessageBadInputForNumberText()
+{
+    notImplemented();
+    return validationMessageTypeMismatchText();
+}
+
 }
index 5613fb1..2f00930 100644 (file)
@@ -652,6 +652,12 @@ String validationMessageTypeMismatchText()
     return String();
 }
 
+String validationMessageBadInputForNumberText()
+{
+    notImplemented();
+    return validationMessageTypeMismatchText();
+}
+
 String validationMessageTypeMismatchForEmailText()
 {
     notImplemented();
index cf978fd..e1663ed 100644 (file)
@@ -368,6 +368,20 @@ String validationMessageTypeMismatchText()
     return query(WebLocalizedString::ValidationTypeMismatch);
 }
 
+String validationMessageBadInputForNumberText()
+{
+    notImplemented();
+    return String("Bad number");
+}
+
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
+String validationMessageBadInputForDateTimeText()
+{
+    notImplemented();
+    return String("bad date");
+}
+#endif
+
 String validationMessageTypeMismatchForEmailText()
 {
     return query(WebLocalizedString::ValidationTypeMismatchForEmail);