OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 return m_range.maximum; | 100 return m_range.maximum; |
101 } | 101 } |
102 | 102 |
103 int DateTimeNumericFieldElement::defaultValueForStepUp() const | 103 int DateTimeNumericFieldElement::defaultValueForStepUp() const |
104 { | 104 { |
105 return m_range.minimum; | 105 return m_range.minimum; |
106 } | 106 } |
107 | 107 |
108 void DateTimeNumericFieldElement::didBlur() | 108 void DateTimeNumericFieldElement::didBlur() |
109 { | 109 { |
110 m_lastDigitCharTime = 0; | 110 int value = typeAheadValue(); |
| 111 m_typeAheadBuffer.clear(); |
| 112 if (value >= 0) |
| 113 setValueAsInteger(value, DispatchEvent); |
111 DateTimeFieldElement::didBlur(); | 114 DateTimeFieldElement::didBlur(); |
112 } | 115 } |
113 | 116 |
114 String DateTimeNumericFieldElement::formatValue(int value) const | 117 String DateTimeNumericFieldElement::formatValue(int value) const |
115 { | 118 { |
116 Locale& locale = localeForOwner(); | 119 Locale& locale = localeForOwner(); |
117 if (m_range.maximum > 999) | 120 if (m_range.maximum > 999) |
118 return locale.convertToLocalizedNumber(String::format("%04d", value)); | 121 return locale.convertToLocalizedNumber(String::format("%04d", value)); |
119 if (m_range.maximum > 99) | 122 if (m_range.maximum > 99) |
120 return locale.convertToLocalizedNumber(String::format("%03d", value)); | 123 return locale.convertToLocalizedNumber(String::format("%03d", value)); |
121 return locale.convertToLocalizedNumber(String::format("%02d", value)); | 124 return locale.convertToLocalizedNumber(String::format("%02d", value)); |
122 } | 125 } |
123 | 126 |
124 void DateTimeNumericFieldElement::handleKeyboardEvent(KeyboardEvent* keyboardEve
nt) | 127 void DateTimeNumericFieldElement::handleKeyboardEvent(KeyboardEvent* keyboardEve
nt) |
125 { | 128 { |
126 if (isReadOnly()) | 129 if (isReadOnly()) |
127 return; | 130 return; |
128 | 131 |
129 if (keyboardEvent->type() != eventNames().keypressEvent) | 132 if (keyboardEvent->type() != eventNames().keypressEvent) |
130 return; | 133 return; |
131 | 134 |
132 UChar charCode = static_cast<UChar>(keyboardEvent->charCode()); | 135 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 | |
139 String number = localeForOwner().convertFromLocalizedNumber(String(&charCode
, 1)); | 136 String number = localeForOwner().convertFromLocalizedNumber(String(&charCode
, 1)); |
140 const int digit = number[0] - '0'; | 137 const int digit = number[0] - '0'; |
141 if (digit < 0 || digit > 9) | 138 if (digit < 0 || digit > 9) |
142 return; | 139 return; |
143 | 140 |
| 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 |
144 keyboardEvent->setDefaultHandled(); | 157 keyboardEvent->setDefaultHandled(); |
145 setValueAsInteger(m_hasValue && delta < typeAheadTimeout ? m_value * 10 + di
git : digit, DispatchEvent); | |
146 if (m_value * 10 > m_range.maximum) | |
147 focusOnNextField(); | |
148 else | |
149 m_lastDigitCharTime = keyboardEvent->timeStamp(); | |
150 } | 158 } |
151 | 159 |
152 bool DateTimeNumericFieldElement::hasValue() const | 160 bool DateTimeNumericFieldElement::hasValue() const |
153 { | 161 { |
154 return m_hasValue; | 162 return m_hasValue; |
155 } | 163 } |
156 | 164 |
157 int DateTimeNumericFieldElement::maximum() const | 165 int DateTimeNumericFieldElement::maximum() const |
158 { | 166 { |
159 return m_range.maximum; | 167 return m_range.maximum; |
160 } | 168 } |
161 | 169 |
162 int DateTimeNumericFieldElement::minimum() const | 170 int DateTimeNumericFieldElement::minimum() const |
163 { | 171 { |
164 return m_range.minimum; | 172 return m_range.minimum; |
165 } | 173 } |
166 | 174 |
167 void DateTimeNumericFieldElement::setEmptyValue(EventBehavior eventBehavior) | 175 void DateTimeNumericFieldElement::setEmptyValue(EventBehavior eventBehavior) |
168 { | 176 { |
169 m_lastDigitCharTime = 0; | |
170 | |
171 if (isReadOnly()) | 177 if (isReadOnly()) |
172 return; | 178 return; |
173 | 179 |
174 m_hasValue = false; | 180 m_hasValue = false; |
175 m_value = 0; | 181 m_value = 0; |
| 182 m_typeAheadBuffer.clear(); |
176 updateVisibleValue(eventBehavior); | 183 updateVisibleValue(eventBehavior); |
177 } | 184 } |
178 | 185 |
179 void DateTimeNumericFieldElement::setValueAsInteger(int value, EventBehavior eve
ntBehavior) | 186 void DateTimeNumericFieldElement::setValueAsInteger(int value, EventBehavior eve
ntBehavior) |
180 { | 187 { |
181 m_value = clampValueForHardLimits(value); | 188 m_value = clampValueForHardLimits(value); |
182 m_hasValue = true; | 189 m_hasValue = true; |
183 updateVisibleValue(eventBehavior); | 190 updateVisibleValue(eventBehavior); |
184 m_lastDigitCharTime = 0; | |
185 } | 191 } |
186 | 192 |
187 void DateTimeNumericFieldElement::stepDown() | 193 void DateTimeNumericFieldElement::stepDown() |
188 { | 194 { |
189 int newValue = roundDown(m_hasValue ? m_value - 1 : defaultValueForStepDown(
)); | 195 int newValue = roundDown(m_hasValue ? m_value - 1 : defaultValueForStepDown(
)); |
190 if (!m_range.isInRange(newValue)) | 196 if (!m_range.isInRange(newValue)) |
191 newValue = roundDown(m_range.maximum); | 197 newValue = roundDown(m_range.maximum); |
| 198 m_typeAheadBuffer.clear(); |
192 setValueAsInteger(newValue, DispatchEvent); | 199 setValueAsInteger(newValue, DispatchEvent); |
193 } | 200 } |
194 | 201 |
195 void DateTimeNumericFieldElement::stepUp() | 202 void DateTimeNumericFieldElement::stepUp() |
196 { | 203 { |
197 int newValue = roundUp(m_hasValue ? m_value + 1 : defaultValueForStepUp()); | 204 int newValue = roundUp(m_hasValue ? m_value + 1 : defaultValueForStepUp()); |
198 if (!m_range.isInRange(newValue)) | 205 if (!m_range.isInRange(newValue)) |
199 newValue = roundUp(m_range.minimum); | 206 newValue = roundUp(m_range.minimum); |
| 207 m_typeAheadBuffer.clear(); |
200 setValueAsInteger(newValue, DispatchEvent); | 208 setValueAsInteger(newValue, DispatchEvent); |
201 } | 209 } |
202 | 210 |
203 String DateTimeNumericFieldElement::value() const | 211 String DateTimeNumericFieldElement::value() const |
204 { | 212 { |
205 return m_hasValue ? formatValue(m_value) : emptyString(); | 213 return m_hasValue ? formatValue(m_value) : emptyString(); |
206 } | 214 } |
207 | 215 |
208 int DateTimeNumericFieldElement::valueAsInteger() const | 216 int DateTimeNumericFieldElement::valueAsInteger() const |
209 { | 217 { |
210 return m_hasValue ? m_value : -1; | 218 return m_hasValue ? m_value : -1; |
211 } | 219 } |
212 | 220 |
| 221 int DateTimeNumericFieldElement::typeAheadValue() const |
| 222 { |
| 223 if (m_typeAheadBuffer.length()) |
| 224 return m_typeAheadBuffer.toString().toInt(); |
| 225 return -1; |
| 226 } |
| 227 |
213 String DateTimeNumericFieldElement::visibleValue() const | 228 String DateTimeNumericFieldElement::visibleValue() const |
214 { | 229 { |
| 230 if (m_typeAheadBuffer.length()) |
| 231 return formatValue(typeAheadValue()); |
215 return m_hasValue ? value() : m_placeholder; | 232 return m_hasValue ? value() : m_placeholder; |
216 } | 233 } |
217 | 234 |
218 int DateTimeNumericFieldElement::roundDown(int n) const | 235 int DateTimeNumericFieldElement::roundDown(int n) const |
219 { | 236 { |
220 n -= m_stepBase; | 237 n -= m_stepBase; |
221 if (n >= 0) | 238 if (n >= 0) |
222 n = n / m_step * m_step; | 239 n = n / m_step * m_step; |
223 else | 240 else |
224 n = -((-n + m_step - 1) / m_step * m_step); | 241 n = -((-n + m_step - 1) / m_step * m_step); |
225 return n + m_stepBase; | 242 return n + m_stepBase; |
226 } | 243 } |
227 | 244 |
228 int DateTimeNumericFieldElement::roundUp(int n) const | 245 int DateTimeNumericFieldElement::roundUp(int n) const |
229 { | 246 { |
230 n -= m_stepBase; | 247 n -= m_stepBase; |
231 if (n >= 0) | 248 if (n >= 0) |
232 n = (n + m_step - 1) / m_step * m_step; | 249 n = (n + m_step - 1) / m_step * m_step; |
233 else | 250 else |
234 n = -(-n / m_step * m_step); | 251 n = -(-n / m_step * m_step); |
235 return n + m_stepBase; | 252 return n + m_stepBase; |
236 } | 253 } |
237 | 254 |
238 } // namespace WebCore | 255 } // namespace WebCore |
239 | 256 |
240 #endif | 257 #endif |
OLD | NEW |