| Index: Source/WebCore/html/shadow/DateTimeNumericFieldElement.cpp
 | 
| ===================================================================
 | 
| --- Source/WebCore/html/shadow/DateTimeNumericFieldElement.cpp	(revision 139034)
 | 
| +++ Source/WebCore/html/shadow/DateTimeNumericFieldElement.cpp	(working copy)
 | 
| @@ -107,7 +107,10 @@
 | 
|  
 | 
|  void DateTimeNumericFieldElement::didBlur()
 | 
|  {
 | 
| -    m_lastDigitCharTime = 0;
 | 
| +    int value = typeAheadValue();
 | 
| +    m_typeAheadBuffer.clear();
 | 
| +    if (value >= 0)
 | 
| +        setValueAsInteger(value, DispatchEvent);
 | 
|      DateTimeFieldElement::didBlur();
 | 
|  }
 | 
|  
 | 
| @@ -130,23 +133,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
 | 
| @@ -166,13 +174,12 @@
 | 
|  
 | 
|  void DateTimeNumericFieldElement::setEmptyValue(EventBehavior eventBehavior)
 | 
|  {
 | 
| -    m_lastDigitCharTime = 0;
 | 
| -
 | 
|      if (isReadOnly())
 | 
|          return;
 | 
|  
 | 
|      m_hasValue = false;
 | 
|      m_value = 0;
 | 
| +    m_typeAheadBuffer.clear();
 | 
|      updateVisibleValue(eventBehavior);
 | 
|  }
 | 
|  
 | 
| @@ -181,7 +188,6 @@
 | 
|      m_value = clampValueForHardLimits(value);
 | 
|      m_hasValue = true;
 | 
|      updateVisibleValue(eventBehavior);
 | 
| -    m_lastDigitCharTime = 0;
 | 
|  }
 | 
|  
 | 
|  void DateTimeNumericFieldElement::stepDown()
 | 
| @@ -189,6 +195,7 @@
 | 
|      int newValue = roundDown(m_hasValue ? m_value - 1 : defaultValueForStepDown());
 | 
|      if (!m_range.isInRange(newValue))
 | 
|          newValue = roundDown(m_range.maximum);
 | 
| +    m_typeAheadBuffer.clear();
 | 
|      setValueAsInteger(newValue, DispatchEvent);
 | 
|  }
 | 
|  
 | 
| @@ -197,6 +204,7 @@
 | 
|      int newValue = roundUp(m_hasValue ? m_value + 1 : defaultValueForStepUp());
 | 
|      if (!m_range.isInRange(newValue))
 | 
|          newValue = roundUp(m_range.minimum);
 | 
| +    m_typeAheadBuffer.clear();
 | 
|      setValueAsInteger(newValue, DispatchEvent);
 | 
|  }
 | 
|  
 | 
| @@ -210,8 +218,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;
 | 
|  }
 | 
|  
 | 
| 
 |