Title: [138417] branches/chromium/1312
Revision
138417
Author
[email protected]
Date
2012-12-23 01:28:26 -0800 (Sun, 23 Dec 2012)

Log Message

Merge 138365

> Fix typing zero into multiple field input
> https://bugs.webkit.org/show_bug.cgi?id=105501
> 
> Reviewed by Kent Tamura.
> 
> Source/WebCore:
> 
> We have a couple of problems when handling zero in a multiple fields
> element.
> 1. Typing '02' into a month field will set '12'.
> 2. Typing '0' into 12 hour hour field will set '12' and move to the
>    focus to the next field.
> This change adds a type ahead buffer so we can handle these cases
> properly. If the value in the type ahead buffer is valid we set it so a
> change event will fire.
> 
> Added tests to *-multiple-fields-keyboard-events.html.
> 
> * html/shadow/DateTimeNumericFieldElement.cpp:
> (WebCore::DateTimeNumericFieldElement::didBlur): Clear the type ahead
> buffer. handleKeyboardEvent() won't set the type ahead value if it is
> not in range, so we set the value here.
> (WebCore::DateTimeNumericFieldElement::handleKeyboardEvent):
> (WebCore::DateTimeNumericFieldElement::setEmptyValue): Clear type ahead buffer.
> (WebCore::DateTimeNumericFieldElement::setValueAsInteger):
> (WebCore::DateTimeNumericFieldElement::stepDown): Clear type ahead buffer.
> (WebCore::DateTimeNumericFieldElement::stepUp): Clear type ahead buffer.
> (WebCore::DateTimeNumericFieldElement::typeAheadValue): Returns integer
> value for the type ahead characters.
> (WebCore):
> (WebCore::DateTimeNumericFieldElement::visibleValue): If we have type
> ahead characters, show that.
> * html/shadow/DateTimeNumericFieldElement.h:
> (DateTimeNumericFieldElement):
> 
> LayoutTests:
> 
> * fast/forms/date-multiple-fields/date-multiple-fields-keyboard-events-expected.txt:
> * fast/forms/date-multiple-fields/date-multiple-fields-keyboard-events.html:
> * fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-keyboard-events-expected.txt:
> * fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-keyboard-events.html:
> * fast/forms/month-multiple-fields/month-multiple-fields-keyboard-events-expected.txt:
> * fast/forms/time-multiple-fields/time-multiple-fields-keyboard-events-expected.txt:
> * fast/forms/time-multiple-fields/time-multiple-fields-keyboard-events.html:
> * fast/forms/week-multiple-fields/week-multiple-fields-keyboard-events-expected.txt:
> * fast/forms/week-multiple-fields/week-multiple-fields-keyboard-events.html:
> 

[email protected]
BUG=crbug.com/167020
Review URL: https://codereview.chromium.org/11665021

Modified Paths

Diff

Modified: branches/chromium/1312/LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-keyboard-events-expected.txt (138416 => 138417)


--- branches/chromium/1312/LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-keyboard-events-expected.txt	2012-12-23 08:53:25 UTC (rev 138416)
+++ branches/chromium/1312/LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-keyboard-events-expected.txt	2012-12-23 09:28:26 UTC (rev 138417)
@@ -14,6 +14,10 @@
   
 == Digit keys ==
 PASS input.value is "0012-09-20"
+== Digit keys starting with zero ==
+PASS input.value is "0044-02-03"
+== Digit keys and backspace key ==
+PASS input.value is "0008-05-06"
 == Left/Right keys ==
 PASS input.value is "2012-09-06"
 PASS document.activeElement.id is "input"

Modified: branches/chromium/1312/LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-keyboard-events.html (138416 => 138417)


--- branches/chromium/1312/LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-keyboard-events.html	2012-12-23 08:53:25 UTC (rev 138416)
+++ branches/chromium/1312/LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-keyboard-events.html	2012-12-23 09:28:26 UTC (rev 138417)
@@ -54,6 +54,29 @@
 keyDown('A'); // Ignored.
 shouldBeEqualToString('input.value', '0012-09-20');
 
+beginTest('Digit keys starting with zero');
+keyDown('0'); // -> [00]/dd/yyyy
+keyDown('2'); // -> 02/[dd]/yyyy
+keyDown('0'); // -> 02/[00]/yyyy
+keyDown('3'); // -> 02/03/[yyyy]
+keyDown('0'); // -> 02/03/[0000]
+keyDown('0'); // -> 02/03/[0000]
+keyDown('0'); // -> 02/03/[0000]
+keyDown('4'); // -> 02/03/[0004]
+keyDown('4'); // -> 02/03/[0044]
+shouldBeEqualToString('input.value', '0044-02-03');
+
+beginTest('Digit keys and backspace key');
+keyDown('1'); // -> [01]/dd/yyyy
+keyDown("\b"); // -> [mm]/20/2012
+keyDown('5'); // -> 05/[dd]/yyyy
+keyDown('6'); // -> 05/06/[yyyy]
+keyDown("\b"); // -> 05/06/[yyyy]
+keyDown('7'); // -> 05/06/[0007]
+keyDown("\b"); // -> 05/06/[yyyy]
+keyDown('8'); // -> 05/06/[0008]
+shouldBeEqualToString('input.value', '0008-05-06');
+
 // FIXME: We should test type ahead time out. When event.leapForward() affects
 // keyboard event time stamp, we can uncomment this fragment.
 /*

Modified: branches/chromium/1312/LayoutTests/fast/forms/month-multiple-fields/month-multiple-fields-keyboard-events-expected.txt (138416 => 138417)


--- branches/chromium/1312/LayoutTests/fast/forms/month-multiple-fields/month-multiple-fields-keyboard-events-expected.txt	2012-12-23 08:53:25 UTC (rev 138416)
+++ branches/chromium/1312/LayoutTests/fast/forms/month-multiple-fields/month-multiple-fields-keyboard-events-expected.txt	2012-12-23 09:28:26 UTC (rev 138417)
@@ -13,7 +13,7 @@
 Backspace - Make value empty
   
 == Digit keys ==
-FAIL input.value should be 0012-09. Was 0112-09.
+PASS input.value is "0012-09"
 == Left/Right keys ==
 FAIL input.value should be 0005-06. Was 0005-09.
 PASS document.activeElement.id is "input"

Modified: branches/chromium/1312/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-keyboard-events-expected.txt (138416 => 138417)


--- branches/chromium/1312/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-keyboard-events-expected.txt	2012-12-23 08:53:25 UTC (rev 138416)
+++ branches/chromium/1312/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-keyboard-events-expected.txt	2012-12-23 09:28:26 UTC (rev 138417)
@@ -14,6 +14,10 @@
   
 == Digit keys ==
 PASS input.value is "07:56"
+== Digit keys starting with zero ==
+PASS input.value is "14:03"
+== Digit keys and backspace key ==
+PASS input.value is "17:06"
 == Left/Right keys ==
 PASS input.value is "06:05"
 PASS document.activeElement.id is "input"

Modified: branches/chromium/1312/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-keyboard-events.html (138416 => 138417)


--- branches/chromium/1312/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-keyboard-events.html	2012-12-23 08:53:25 UTC (rev 138416)
+++ branches/chromium/1312/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-keyboard-events.html	2012-12-23 09:28:26 UTC (rev 138417)
@@ -48,6 +48,23 @@
 keyDown('A');
 shouldBeEqualToString('input.value', '07:56');
 
+beginTest('Digit keys starting with zero');
+keyDown('0'); // -> [00]:-- --
+keyDown('2'); // -> 02:[--] --
+keyDown('0'); // -> 02:[00] --
+keyDown('3'); // -> 02:03 [--]
+keyDown('P'); // -> 02:03 [PM]
+shouldBeEqualToString('input.value', '14:03');
+
+beginTest('Digit keys and backspace key','01:01');
+keyDown('0'); // -> [00]:-- --
+keyDown('\b'); // -> [--]:-- --
+keyDown('5'); // -> 05:[--] --
+keyDown('6'); // -> 05:06 [--]
+keyDown('\b'); // -> 05:06 [--]
+keyDown('P'); // -> 05:06 [PM]
+shouldBeEqualToString('input.value', '17:06');
+
 // FIXME: We should test type ahead time out. When event.leapForward() affects
 // keyboard event time stamp, we can uncomment this fragment.
 /*

Modified: branches/chromium/1312/Source/WebCore/html/shadow/DateTimeNumericFieldElement.cpp (138416 => 138417)


--- branches/chromium/1312/Source/WebCore/html/shadow/DateTimeNumericFieldElement.cpp	2012-12-23 08:53:25 UTC (rev 138416)
+++ branches/chromium/1312/Source/WebCore/html/shadow/DateTimeNumericFieldElement.cpp	2012-12-23 09:28:26 UTC (rev 138417)
@@ -104,7 +104,10 @@
 
 void DateTimeNumericFieldElement::didBlur()
 {
-    m_lastDigitCharTime = 0;
+    int value = typeAheadValue();
+    m_typeAheadBuffer.clear();
+    if (value >= 0)
+        setValueAsInteger(value, DispatchEvent);
     DateTimeFieldElement::didBlur();
 }
 
@@ -127,23 +130,28 @@
         return;
 
     UChar charCode = static_cast<UChar>(keyboardEvent->charCode());
-    if (charCode < ' ')
-        return;
-
-    DOMTimeStamp delta = keyboardEvent->timeStamp() - m_lastDigitCharTime;
-    m_lastDigitCharTime = 0;
-
     String number = localeForOwner().convertFromLocalizedNumber(String(&charCode, 1));
     const int digit = number[0] - '0';
     if (digit < 0 || digit > 9)
         return;
 
+    DOMTimeStamp delta = keyboardEvent->timeStamp() - m_lastDigitCharTime;
+    m_lastDigitCharTime = keyboardEvent->timeStamp();
+
+    if (delta > typeAheadTimeout)
+        m_typeAheadBuffer.clear();
+    m_typeAheadBuffer.append(number);
+
+    int newValue = typeAheadValue();
+    if (m_range.isInRange(newValue))
+        setValueAsInteger(newValue, DispatchEvent);
+    else
+        updateVisibleValue(DispatchEvent);
+
+    if (m_typeAheadBuffer.length() >= DateTimeNumericFieldElement::formatValue(m_range.maximum).length() || newValue * 10 > m_range.maximum)
+        focusOnNextField();
+
     keyboardEvent->setDefaultHandled();
-    setValueAsInteger(m_hasValue && delta < typeAheadTimeout ? m_value * 10 + digit : digit, DispatchEvent);
-    if (m_value * 10 > m_range.maximum)
-        focusOnNextField();
-    else
-        m_lastDigitCharTime = keyboardEvent->timeStamp();
 }
 
 bool DateTimeNumericFieldElement::hasValue() const
@@ -163,13 +171,12 @@
 
 void DateTimeNumericFieldElement::setEmptyValue(EventBehavior eventBehavior)
 {
-    m_lastDigitCharTime = 0;
-
     if (isReadOnly())
         return;
 
     m_hasValue = false;
     m_value = 0;
+    m_typeAheadBuffer.clear();
     updateVisibleValue(eventBehavior);
 }
 
@@ -178,11 +185,11 @@
     m_value = clampValueForHardLimits(value);
     m_hasValue = true;
     updateVisibleValue(eventBehavior);
-    m_lastDigitCharTime = 0;
 }
 
 void DateTimeNumericFieldElement::stepDown()
 {
+    m_typeAheadBuffer.clear();
     if (m_hasValue)
         setValueAsInteger(m_value == m_range.minimum ? m_range.maximum : clampValue(m_value - 1), DispatchEvent);
     else
@@ -191,6 +198,7 @@
 
 void DateTimeNumericFieldElement::stepUp()
 {
+    m_typeAheadBuffer.clear();
     if (m_hasValue)
         setValueAsInteger(m_value == m_range.maximum ? m_range.minimum : clampValue(m_value + 1), DispatchEvent);
     else
@@ -207,8 +215,17 @@
     return m_hasValue ? m_value : -1;
 }
 
+int DateTimeNumericFieldElement::typeAheadValue() const
+{
+    if (m_typeAheadBuffer.length())
+        return m_typeAheadBuffer.toString().toInt();
+    return -1;
+}
+
 String DateTimeNumericFieldElement::visibleValue() const
 {
+    if (m_typeAheadBuffer.length())
+        return formatValue(typeAheadValue());
     return m_hasValue ? value() : m_placeholder;
 }
 

Modified: branches/chromium/1312/Source/WebCore/html/shadow/DateTimeNumericFieldElement.h (138416 => 138417)


--- branches/chromium/1312/Source/WebCore/html/shadow/DateTimeNumericFieldElement.h	2012-12-23 08:53:25 UTC (rev 138416)
+++ branches/chromium/1312/Source/WebCore/html/shadow/DateTimeNumericFieldElement.h	2012-12-23 09:28:26 UTC (rev 138417)
@@ -78,12 +78,14 @@
     virtual String value() const OVERRIDE FINAL;
 
     String formatValue(int) const;
+    int typeAheadValue() const;
 
     DOMTimeStamp m_lastDigitCharTime;
     const String m_placeholder;
     const Range m_range;
     int m_value;
     bool m_hasValue;
+    mutable StringBuilder m_typeAheadBuffer;
 };
 
 } // namespace WebCore
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to