Changeset 138365 in webkit


Ignore:
Timestamp:
Dec 21, 2012 4:42:20 AM (11 years ago)
Author:
keishi@webkit.org
Message:

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:
Location:
trunk
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r138362 r138365  
     12012-12-21  Keishi Hattori  <keishi@webkit.org>
     2
     3        Fix typing zero into multiple field input
     4        https://bugs.webkit.org/show_bug.cgi?id=105501
     5
     6        Reviewed by Kent Tamura.
     7
     8        * fast/forms/date-multiple-fields/date-multiple-fields-keyboard-events-expected.txt:
     9        * fast/forms/date-multiple-fields/date-multiple-fields-keyboard-events.html:
     10        * fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-keyboard-events-expected.txt:
     11        * fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-keyboard-events.html:
     12        * fast/forms/month-multiple-fields/month-multiple-fields-keyboard-events-expected.txt:
     13        * fast/forms/time-multiple-fields/time-multiple-fields-keyboard-events-expected.txt:
     14        * fast/forms/time-multiple-fields/time-multiple-fields-keyboard-events.html:
     15        * fast/forms/week-multiple-fields/week-multiple-fields-keyboard-events-expected.txt:
     16        * fast/forms/week-multiple-fields/week-multiple-fields-keyboard-events.html:
     17
    1182012-12-21  János Badics  <jbadics@inf.u-szeged.hu>
    219
  • trunk/LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-keyboard-events-expected.txt

    r138255 r138365  
    1515== Digit keys ==
    1616PASS input.value is "0012-09-20"
     17== Digit keys starting with zero ==
     18PASS input.value is "0044-02-03"
     19== Digit keys and backspace key ==
     20PASS input.value is "0008-05-06"
    1721== Left/Right keys ==
    1822PASS input.value is "2012-09-06"
  • trunk/LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-keyboard-events.html

    r138255 r138365  
    5555shouldBeEqualToString('input.value', '0012-09-20');
    5656
     57beginTest('Digit keys starting with zero');
     58keyDown('0'); // -> [00]/dd/yyyy
     59keyDown('2'); // -> 02/[dd]/yyyy
     60keyDown('0'); // -> 02/[00]/yyyy
     61keyDown('3'); // -> 02/03/[yyyy]
     62keyDown('0'); // -> 02/03/[0000]
     63keyDown('0'); // -> 02/03/[0000]
     64keyDown('0'); // -> 02/03/[0000]
     65keyDown('4'); // -> 02/03/[0004]
     66keyDown('4'); // -> 02/03/[0044]
     67shouldBeEqualToString('input.value', '0044-02-03');
     68
     69beginTest('Digit keys and backspace key');
     70keyDown('1'); // -> [01]/dd/yyyy
     71keyDown("\b"); // -> [mm]/20/2012
     72keyDown('5'); // -> 05/[dd]/yyyy
     73keyDown('6'); // -> 05/06/[yyyy]
     74keyDown("\b"); // -> 05/06/[yyyy]
     75keyDown('7'); // -> 05/06/[0007]
     76keyDown("\b"); // -> 05/06/[yyyy]
     77keyDown('8'); // -> 05/06/[0008]
     78shouldBeEqualToString('input.value', '0008-05-06');
     79
    5780// FIXME: We should test type ahead time out. When event.leapForward() affects
    5881// keyboard event time stamp, we can uncomment this fragment.
  • trunk/LayoutTests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-keyboard-events-expected.txt

    r138255 r138365  
    1515== Digit keys ==
    1616PASS input.value is "98765-09-20T07:56"
     17== Digit keys starting with zero ==
     18PASS input.value is "0044-02-03T05:06"
     19== Digit keys and backspace key ==
     20PASS input.value is "0008-05-06T09:10"
    1721== Left/Right keys ==
    1822PASS input.value is "0004-09-05T19:05"
  • trunk/LayoutTests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-keyboard-events.html

    r138255 r138365  
    5959shouldBeEqualToString('input.value', '98765-09-20T07:56');
    6060
     61beginTest('Digit keys starting with zero', null, null, '9999-12-31T23:59');
     62keyDown('0'); // -> [00]/dd/yyyy --:-- --
     63keyDown('2'); // -> 02/[dd]/yyyy --:-- --
     64keyDown('0'); // -> 02/[00]/yyyy --:-- --
     65keyDown('3'); // -> 02/03/[yyyy] --:-- --
     66keyDown('0'); // -> 02/03/[0000] --:-- --
     67keyDown('0'); // -> 02/03/[0000] --:-- --
     68keyDown('4'); // -> 02/03/[0044] --:-- --
     69keyDown('4'); // -> 02/03/[0044] --:-- --
     70keyDown('0'); // -> 02/03/0044 [00]:-- --
     71keyDown('5'); // -> 02/03/0044 05:[--] --
     72keyDown('0'); // -> 02/03/0044 01:[01] --
     73keyDown('6'); // -> 02/03/0044 05:06 [--]
     74keyDown('A'); // -> 02/03/0044 05:06 AM
     75shouldBeEqualToString('input.value', '0044-02-03T05:06');
     76
     77beginTest('Digit keys and backspace key');
     78keyDown('1'); // -> [01]/dd/yyyy --:-- --
     79keyDown("\b"); // -> [mm]/20/2012 --:-- --
     80keyDown('5'); // -> 05/[dd]/yyyy --:-- --
     81keyDown('6'); // -> 05/06/[yyyy] --:-- --
     82keyDown("\b"); // -> 05/06/[yyyy] --:-- --
     83keyDown('7'); // -> 05/06/[0007] --:-- --
     84keyDown("\b"); // -> 05/06/[yyyy] --:-- --
     85keyDown('8'); // -> 05/06/[0008] --:-- --
     86keyDown('rightArrow'); // -> 05/06/0008 [--]:-- --
     87keyDown('9'); // -> 05/06/0008 09:[--] --
     88keyDown('1'); // -> 05/06/0008 09:[01] --
     89keyDown('0'); // -> 05/06/0008 09:10 [--]
     90keyDown('A'); // -> 05/06/0008 09:10 [AM]
     91shouldBeEqualToString('input.value', '0008-05-06T09:10');
     92
    6193// FIXME: We should test type ahead time out. When event.leapForward() affects
    6294// keyboard event time stamp, we can uncomment this fragment.
  • trunk/LayoutTests/fast/forms/month-multiple-fields/month-multiple-fields-keyboard-events-expected.txt

    r137275 r138365  
    1414 
    1515== Digit keys ==
    16 FAIL input.value should be 0012-09. Was 0112-09.
     16PASS input.value is "0012-09"
    1717== Left/Right keys ==
    1818PASS input.value is "0005-06"
  • trunk/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-keyboard-events-expected.txt

    r137275 r138365  
    1515== Digit keys ==
    1616PASS input.value is "07:56"
     17== Digit keys starting with zero ==
     18PASS input.value is "14:03"
     19== Digit keys and backspace key ==
     20PASS input.value is "17:06"
    1721== Left/Right keys ==
    1822PASS input.value is "06:05"
  • trunk/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-keyboard-events.html

    r137275 r138365  
    4848keyDown('A');
    4949shouldBeEqualToString('input.value', '07:56');
     50
     51beginTest('Digit keys starting with zero');
     52keyDown('0'); // -> [00]:-- --
     53keyDown('2'); // -> 02:[--] --
     54keyDown('0'); // -> 02:[00] --
     55keyDown('3'); // -> 02:03 [--]
     56keyDown('P'); // -> 02:03 [PM]
     57shouldBeEqualToString('input.value', '14:03');
     58
     59beginTest('Digit keys and backspace key','01:01');
     60keyDown('0'); // -> [00]:-- --
     61keyDown('\b'); // -> [--]:-- --
     62keyDown('5'); // -> 05:[--] --
     63keyDown('6'); // -> 05:06 [--]
     64keyDown('\b'); // -> 05:06 [--]
     65keyDown('P'); // -> 05:06 [PM]
     66shouldBeEqualToString('input.value', '17:06');
    5067
    5168// FIXME: We should test type ahead time out. When event.leapForward() affects
  • trunk/LayoutTests/fast/forms/week-multiple-fields/week-multiple-fields-keyboard-events-expected.txt

    r138255 r138365  
    1515== Digit keys ==
    1616PASS input.value is "0012-W09"
     17== Digit keys starting with zero ==
     18PASS input.value is "0300-W02"
     19== Digit keys and backspace key ==
     20PASS input.value is "0006-W01"
    1721== Left/Right keys ==
    1822PASS input.value is "0005-W06"
  • trunk/LayoutTests/fast/forms/week-multiple-fields/week-multiple-fields-keyboard-events.html

    r138255 r138365  
    5353shouldBeEqualToString('input.value', '0012-W09');
    5454
     55beginTest('Digit keys starting with zero');
     56keyDown('0'); // -> Week [00], yyyy
     57keyDown('2'); // -> Week 02, [yyyy]
     58keyDown('0'); // -> Week 02, [0000]
     59keyDown('3'); // -> Week 02, [0003]
     60keyDown('0'); // -> Week 02, [0030]
     61keyDown('0'); // -> Week 02, [0300]
     62shouldBeEqualToString('input.value', '0300-W02');
     63
     64beginTest('Digit keys and backspace key');
     65keyDown('0'); // -> Week [00], yyyy
     66keyDown('\b'); // -> Week [ww], yyyy
     67keyDown('0'); // -> Week [00], yyyy
     68keyDown('0'); // -> Week 01, [yyyy]
     69keyDown('0'); // -> Week 01, [0000]
     70keyDown('6'); // -> Week 05, [0006]
     71shouldBeEqualToString('input.value', '0006-W01');
     72
    5573// FIXME: We should test type ahead time out. When event.leapForward() affects
    5674// keyboard event time stamp, we can uncomment this fragment.
  • trunk/Source/WebCore/ChangeLog

    r138364 r138365  
     12012-12-21  Keishi Hattori  <keishi@webkit.org>
     2
     3        Fix typing zero into multiple field input
     4        https://bugs.webkit.org/show_bug.cgi?id=105501
     5
     6        Reviewed by Kent Tamura.
     7
     8        We have a couple of problems when handling zero in a multiple fields
     9        element.
     10        1. Typing '02' into a month field will set '12'.
     11        2. Typing '0' into 12 hour hour field will set '12' and move to the
     12           focus to the next field.
     13        This change adds a type ahead buffer so we can handle these cases
     14        properly. If the value in the type ahead buffer is valid we set it so a
     15        change event will fire.
     16
     17        Added tests to *-multiple-fields-keyboard-events.html.
     18
     19        * html/shadow/DateTimeNumericFieldElement.cpp:
     20        (WebCore::DateTimeNumericFieldElement::didBlur): Clear the type ahead
     21        buffer. handleKeyboardEvent() won't set the type ahead value if it is
     22        not in range, so we set the value here.
     23        (WebCore::DateTimeNumericFieldElement::handleKeyboardEvent):
     24        (WebCore::DateTimeNumericFieldElement::setEmptyValue): Clear type ahead buffer.
     25        (WebCore::DateTimeNumericFieldElement::setValueAsInteger):
     26        (WebCore::DateTimeNumericFieldElement::stepDown): Clear type ahead buffer.
     27        (WebCore::DateTimeNumericFieldElement::stepUp): Clear type ahead buffer.
     28        (WebCore::DateTimeNumericFieldElement::typeAheadValue): Returns integer
     29        value for the type ahead characters.
     30        (WebCore):
     31        (WebCore::DateTimeNumericFieldElement::visibleValue): If we have type
     32        ahead characters, show that.
     33        * html/shadow/DateTimeNumericFieldElement.h:
     34        (DateTimeNumericFieldElement):
     35
    1362012-12-21  Xabier Rodriguez Calvar  <calvaris@igalia.com>
    237
  • trunk/Source/WebCore/html/shadow/DateTimeNumericFieldElement.cpp

    r137712 r138365  
    108108void DateTimeNumericFieldElement::didBlur()
    109109{
    110     m_lastDigitCharTime = 0;
     110    int value = typeAheadValue();
     111    m_typeAheadBuffer.clear();
     112    if (value >= 0)
     113        setValueAsInteger(value, DispatchEvent);
    111114    DateTimeFieldElement::didBlur();
    112115}
     
    131134
    132135    UChar charCode = static_cast<UChar>(keyboardEvent->charCode());
    133     if (charCode < ' ')
    134         return;
    135 
    136     DOMTimeStamp delta = keyboardEvent->timeStamp() - m_lastDigitCharTime;
    137     m_lastDigitCharTime = 0;
    138 
    139136    String number = localeForOwner().convertFromLocalizedNumber(String(&charCode, 1));
    140137    const int digit = number[0] - '0';
     
    142139        return;
    143140
     141    DOMTimeStamp delta = keyboardEvent->timeStamp() - m_lastDigitCharTime;
     142    m_lastDigitCharTime = keyboardEvent->timeStamp();
     143
     144    if (delta > typeAheadTimeout)
     145        m_typeAheadBuffer.clear();
     146    m_typeAheadBuffer.append(number);
     147
     148    int newValue = typeAheadValue();
     149    if (m_range.isInRange(newValue))
     150        setValueAsInteger(newValue, DispatchEvent);
     151    else
     152        updateVisibleValue(DispatchEvent);
     153
     154    if (m_typeAheadBuffer.length() >= DateTimeNumericFieldElement::formatValue(m_range.maximum).length() || newValue * 10 > m_range.maximum)
     155        focusOnNextField();
     156
    144157    keyboardEvent->setDefaultHandled();
    145     setValueAsInteger(m_hasValue && delta < typeAheadTimeout ? m_value * 10 + digit : digit, DispatchEvent);
    146     if (m_value * 10 > m_range.maximum)
    147         focusOnNextField();
    148     else
    149         m_lastDigitCharTime = keyboardEvent->timeStamp();
    150158}
    151159
     
    167175void DateTimeNumericFieldElement::setEmptyValue(EventBehavior eventBehavior)
    168176{
    169     m_lastDigitCharTime = 0;
    170 
    171177    if (isReadOnly())
    172178        return;
     
    174180    m_hasValue = false;
    175181    m_value = 0;
     182    m_typeAheadBuffer.clear();
    176183    updateVisibleValue(eventBehavior);
    177184}
     
    182189    m_hasValue = true;
    183190    updateVisibleValue(eventBehavior);
    184     m_lastDigitCharTime = 0;
    185191}
    186192
     
    190196    if (!m_range.isInRange(newValue))
    191197        newValue = roundDown(m_range.maximum);
     198    m_typeAheadBuffer.clear();
    192199    setValueAsInteger(newValue, DispatchEvent);
    193200}
     
    198205    if (!m_range.isInRange(newValue))
    199206        newValue = roundUp(m_range.minimum);
     207    m_typeAheadBuffer.clear();
    200208    setValueAsInteger(newValue, DispatchEvent);
    201209}
     
    211219}
    212220
     221int DateTimeNumericFieldElement::typeAheadValue() const
     222{
     223    if (m_typeAheadBuffer.length())
     224        return m_typeAheadBuffer.toString().toInt();
     225    return -1;
     226}
     227
    213228String DateTimeNumericFieldElement::visibleValue() const
    214229{
     230    if (m_typeAheadBuffer.length())
     231        return formatValue(typeAheadValue());
    215232    return m_hasValue ? value() : m_placeholder;
    216233}
  • trunk/Source/WebCore/html/shadow/DateTimeNumericFieldElement.h

    r137712 r138365  
    8888    int roundUp(int) const;
    8989    int roundDown(int) const;
     90    int typeAheadValue() const;
    9091
    9192    DOMTimeStamp m_lastDigitCharTime;
     
    9697    int m_step;
    9798    int m_stepBase;
     99    mutable StringBuilder m_typeAheadBuffer;
    98100};
    99101
Note: See TracChangeset for help on using the changeset viewer.