Changeset 71622 in webkit
- Timestamp:
- Nov 9, 2010 4:26:45 AM (13 years ago)
- Location:
- trunk
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r71621 r71622 1 2010-11-09 Dai Mikurube <dmikurube@google.com> 2 3 Reviewed by Kent Tamura. 4 5 Too precise serialization from floating point number to string for "number" input elements 6 https://bugs.webkit.org/show_bug.cgi?id=48308 7 8 * fast/forms/input-stepup-stepdown-expected.txt: 9 * fast/forms/script-tests/input-stepup-stepdown.js: 10 1 11 2010-11-09 Yuzo Fujishima <yuzo@google.com> 2 12 -
trunk/LayoutTests/fast/forms/input-stepup-stepdown-expected.txt
r70549 r71622 166 166 PASS input.min = "0"; stepUp("0", "0.003921568627450980", "1", 255) is "1" 167 167 PASS for (var i = 0; i < 255; i++) { input.stepDown(); }; input.value is "0" 168 Rounding 169 PASS stepUp("5.005", "0.005", "", 2) is "5.015" 170 PASS stepUp("5.005", "0.005", "", 11) is "5.06" 171 PASS stepUp("5.005", "0.005", "", 12) is "5.065" 172 PASS stepUpExplicitBounds("4", "9", "0.005", "5.005", 2) is "5.015" 173 PASS stepUpExplicitBounds("4", "9", "0.005", "5.005", 11) is "5.06" 174 PASS stepUpExplicitBounds("4", "9", "0.005", "5.005", 12) is "5.065" 168 175 169 176 Range type -
trunk/LayoutTests/fast/forms/script-tests/input-stepup-stepdown.js
r70549 r71622 222 222 shouldBe('input.min = "0"; stepUp("0", "0.003921568627450980", "1", 255)', '"1"'); 223 223 shouldBe('for (var i = 0; i < 255; i++) { input.stepDown(); }; input.value', '"0"'); 224 debug('Rounding'); 225 shouldBe('stepUp("5.005", "0.005", "", 2)', '"5.015"'); 226 shouldBe('stepUp("5.005", "0.005", "", 11)', '"5.06"'); 227 shouldBe('stepUp("5.005", "0.005", "", 12)', '"5.065"'); 228 shouldBe('stepUpExplicitBounds("4", "9", "0.005", "5.005", 2)', '"5.015"'); 229 shouldBe('stepUpExplicitBounds("4", "9", "0.005", "5.005", 11)', '"5.06"'); 230 shouldBe('stepUpExplicitBounds("4", "9", "0.005", "5.005", 12)', '"5.065"'); 224 231 225 232 debug(''); -
trunk/WebCore/ChangeLog
r71621 r71622 1 2010-11-09 Dai Mikurube <dmikurube@google.com> 2 3 Reviewed by Kent Tamura. 4 5 Too precise serialization from floating point number to string for "number" input elements 6 https://bugs.webkit.org/show_bug.cgi?id=48308 7 8 Modified to consider decimal places when handling step and base in applyStep(). 9 10 * html/HTMLInputElement.cpp: Considering decimal places of the given "step" attribtue. 11 (WebCore::HTMLInputElement::getAllowedValueStep): 12 (WebCore::HTMLInputElement::getAllowedValueStepWithDecimalPlaces): 13 (WebCore::HTMLInputElement::applyStep): 14 * html/HTMLInputElement.h: 15 * html/InputType.cpp: Added virtual functions for decimal places and an acceptable error. 16 (WebCore::InputType::stepBaseWithDecimalPlaces): 17 (WebCore::InputType::acceptableError): 18 (WebCore::InputType::parseToDoubleWithDecimalPlaces): 19 * html/InputType.h: 20 * html/NumberInputType.cpp: 21 (WebCore::NumberInputType::stepMismatch): Using the virtual function acceptableError(). 22 (WebCore::NumberInputType::stepBaseWithDecimalPlaces): Considering decimal places of the given "base" attribute. 23 (WebCore::NumberInputType::parseToDoubleWithDecimalPlaces): 24 (WebCore::NumberInputType::acceptableError): Concrete acceptableError() for the number type. 25 * html/NumberInputType.h: 26 * html/parser/HTMLParserIdioms.cpp: 27 (WebCore::parseToDoubleForNumberTypeWithDecimalPlaces): Parsing numbers with decimal places. 28 * html/parser/HTMLParserIdioms.h: 29 1 30 2010-11-09 Yuzo Fujishima <yuzo@google.com> 2 31 -
trunk/WebCore/html/HTMLInputElement.cpp
r71479 r71622 254 254 bool HTMLInputElement::getAllowedValueStep(double* step) const 255 255 { 256 return getAllowedValueStepWithDecimalPlaces(step, 0); 257 } 258 259 bool HTMLInputElement::getAllowedValueStepWithDecimalPlaces(double* step, unsigned* decimalPlaces) const 260 { 256 261 ASSERT(step); 257 262 double defaultStep = m_inputType->defaultStep(); … … 262 267 if (stepString.isEmpty()) { 263 268 *step = defaultStep * stepScaleFactor; 269 if (decimalPlaces) 270 *decimalPlaces = 0; 264 271 return true; 265 272 } … … 267 274 return false; 268 275 double parsed; 269 if (!parseToDoubleForNumberType(stepString, &parsed) || parsed <= 0.0) { 270 *step = defaultStep * stepScaleFactor; 271 return true; 276 if (!decimalPlaces) { 277 if (!parseToDoubleForNumberType(stepString, &parsed) || parsed <= 0.0) { 278 *step = defaultStep * stepScaleFactor; 279 return true; 280 } 281 } else { 282 if (!parseToDoubleForNumberTypeWithDecimalPlaces(stepString, &parsed, decimalPlaces) || parsed <= 0.0) { 283 *step = defaultStep * stepScaleFactor; 284 *decimalPlaces = 0; 285 return true; 286 } 272 287 } 273 288 // For date, month, week, the parsed value should be an integer for some types. … … 286 301 { 287 302 double step; 288 if (!getAllowedValueStep(&step)) { 303 unsigned stepDecimalPlaces; 304 if (!getAllowedValueStepWithDecimalPlaces(&step, &stepDecimalPlaces)) { 289 305 ec = INVALID_STATE_ERR; 290 306 return; … … 301 317 return; 302 318 } 303 if (newValue < m_inputType->minimum()) { 319 double acceptableError = m_inputType->acceptableError(step); 320 if (newValue - m_inputType->minimum() < -acceptableError) { 304 321 ec = INVALID_STATE_ERR; 305 322 return; 306 323 } 307 double base = m_inputType->stepBase(); 308 newValue = base + round((newValue - base) / step) * step; 309 if (newValue > m_inputType->maximum()) { 324 if (newValue < m_inputType->minimum()) 325 newValue = m_inputType->minimum(); 326 unsigned baseDecimalPlaces; 327 double base = m_inputType->stepBaseWithDecimalPlaces(&baseDecimalPlaces); 328 baseDecimalPlaces = min(baseDecimalPlaces, 16u); 329 if (newValue < pow(10.0, 21.0)) { 330 double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces))); 331 newValue = round((base + round((newValue - base) / step) * step) * scale) / scale; 332 } 333 if (newValue - m_inputType->maximum() > acceptableError) { 310 334 ec = INVALID_STATE_ERR; 311 335 return; 312 336 } 337 if (newValue > m_inputType->maximum()) 338 newValue = m_inputType->maximum(); 313 339 setValueAsNumber(newValue, ec); 314 340 } -
trunk/WebCore/html/HTMLInputElement.h
r70511 r71622 66 66 // Returns false if there is no "allowed value step." 67 67 bool getAllowedValueStep(double*) const; 68 bool getAllowedValueStepWithDecimalPlaces(double*, unsigned*) const; 68 69 // For ValidityState. 69 70 bool stepMismatch(const String&) const; -
trunk/WebCore/html/InputType.cpp
r70511 r71622 238 238 } 239 239 240 double InputType::stepBaseWithDecimalPlaces(unsigned* decimalPlaces) const 241 { 242 if (decimalPlaces) 243 *decimalPlaces = 0; 244 return stepBase(); 245 } 246 240 247 double InputType::defaultStep() const 241 248 { … … 258 265 } 259 266 267 double InputType::acceptableError(double) const 268 { 269 return 0; 270 } 271 260 272 RenderObject* InputType::createRenderer(RenderArena*, RenderStyle* style) const 261 273 { … … 266 278 { 267 279 return defaultValue; 280 } 281 282 double InputType::parseToDoubleWithDecimalPlaces(const String& src, double defaultValue, unsigned *decimalPlaces) const 283 { 284 if (decimalPlaces) 285 *decimalPlaces = 0; 286 return parseToDouble(src, defaultValue); 268 287 } 269 288 -
trunk/WebCore/html/InputType.h
r70511 r71622 91 91 virtual bool stepMismatch(const String&, double) const; 92 92 virtual double stepBase() const; 93 virtual double stepBaseWithDecimalPlaces(unsigned*) const; 93 94 virtual double defaultStep() const; 94 95 virtual double stepScaleFactor() const; 95 96 virtual bool parsedStepValueShouldBeInteger() const; 96 97 virtual bool scaledStepValeuShouldBeInteger() const; 98 virtual double acceptableError(double) const; 97 99 98 100 // Miscellaneous functions … … 105 107 // return NaN or Infinity only if defaultValue is NaN or Infinity. 106 108 virtual double parseToDouble(const String&, double defaultValue) const; 109 // Parses the specified string for the type as parseToDouble() does. 110 // In addition, it stores the number of digits after the decimal point 111 // into *decimalPlaces. 112 virtual double parseToDoubleWithDecimalPlaces(const String& src, double defaultValue, unsigned *decimalPlaces) const; 107 113 // Parses the specified string for this InputType, and returns true if it 108 114 // is successfully parsed. An instance pointed by the DateComponents* -
trunk/WebCore/html/NumberInputType.cpp
r70615 r71622 132 132 // Accepts erros in lower fractional part which IEEE 754 single-precision 133 133 // can't represent. 134 double acceptableError = step / pow(2.0, FLT_MANT_DIG);135 return acceptableError < remainder && remainder < (step - acceptableError);134 double computedAcceptableError = acceptableError(step); 135 return computedAcceptableError < remainder && remainder < (step - computedAcceptableError); 136 136 } 137 137 … … 139 139 { 140 140 return parseToDouble(element()->fastGetAttribute(minAttr), defaultStepBase()); 141 } 142 143 double NumberInputType::stepBaseWithDecimalPlaces(unsigned* decimalPlaces) const 144 { 145 return parseToDoubleWithDecimalPlaces(element()->fastGetAttribute(minAttr), defaultStepBase(), decimalPlaces); 141 146 } 142 147 … … 160 165 } 161 166 167 double NumberInputType::parseToDoubleWithDecimalPlaces(const String& src, double defaultValue, unsigned *decimalPlaces) const 168 { 169 double numberValue; 170 if (!parseToDoubleForNumberTypeWithDecimalPlaces(src, &numberValue, decimalPlaces)) 171 return defaultValue; 172 ASSERT(isfinite(numberValue)); 173 return numberValue; 174 } 175 162 176 String NumberInputType::serialize(double value) const 163 177 { … … 167 181 } 168 182 183 double NumberInputType::acceptableError(double step) const 184 { 185 return step / pow(2.0, FLT_MANT_DIG); 186 } 187 188 169 189 } // namespace WebCore -
trunk/WebCore/html/NumberInputType.h
r69445 r71622 53 53 virtual bool stepMismatch(const String&, double) const; 54 54 virtual double stepBase() const; 55 virtual double stepBaseWithDecimalPlaces(unsigned*) const; 55 56 virtual double defaultStep() const; 56 57 virtual double stepScaleFactor() const; 57 58 virtual double parseToDouble(const String&, double) const; 59 virtual double parseToDoubleWithDecimalPlaces(const String&, double, unsigned*) const; 58 60 virtual String serialize(double) const; 61 virtual double acceptableError(double) const; 59 62 }; 60 63 -
trunk/WebCore/html/parser/HTMLParserIdioms.cpp
r70549 r71622 97 97 } 98 98 99 bool parseToDoubleForNumberTypeWithDecimalPlaces(const String& string, double *result, unsigned *decimalPlaces) 100 { 101 if (decimalPlaces) 102 *decimalPlaces = 0; 103 104 if (!parseToDoubleForNumberType(string, result)) 105 return false; 106 107 if (!decimalPlaces) 108 return true; 109 110 size_t dotIndex = string.find('.'); 111 size_t eIndex = string.find('e'); 112 if (eIndex == notFound) 113 eIndex = string.find('E'); 114 115 unsigned baseDecimalPlaces = 0; 116 if (dotIndex != notFound) { 117 if (eIndex == notFound) 118 baseDecimalPlaces = string.length() - dotIndex - 1; 119 else 120 baseDecimalPlaces = eIndex - dotIndex - 1; 121 } 122 123 int exponent = 0; 124 if (eIndex != notFound) { 125 unsigned cursor = eIndex + 1, cursorSaved; 126 int digit, exponentSign; 127 int32_t exponent32; 128 size_t length = string.length(); 129 130 // Not using String.toInt() in order to perform the same computation as dtoa() does. 131 exponentSign = 0; 132 switch (digit = string[cursor]) { 133 case '-': 134 exponentSign = 1; 135 case '+': 136 digit = string[++cursor]; 137 } 138 if (digit >= '0' && digit <= '9') { 139 while (cursor < length && digit == '0') 140 digit = string[++cursor]; 141 if (digit > '0' && digit <= '9') { 142 exponent32 = digit - '0'; 143 cursorSaved = cursor; 144 while (cursor < length && (digit = string[++cursor]) >= '0' && digit <= '9') 145 exponent32 = (10 * exponent32) + digit - '0'; 146 if (cursor - cursorSaved > 8 || exponent32 > 19999) 147 /* Avoid confusion from exponents 148 * so large that e might overflow. 149 */ 150 exponent = 19999; /* safe for 16 bit ints */ 151 else 152 exponent = static_cast<int>(exponent32); 153 if (exponentSign) 154 exponent = -exponent; 155 } else 156 exponent = 0; 157 } 158 } 159 160 int intDecimalPlaces = baseDecimalPlaces - exponent; 161 if (intDecimalPlaces < 0) 162 *decimalPlaces = 0; 163 else if (intDecimalPlaces > 19999) 164 *decimalPlaces = 19999; 165 else 166 *decimalPlaces = static_cast<unsigned>(intDecimalPlaces); 167 168 return true; 169 } 170 99 171 // http://www.whatwg.org/specs/web-apps/current-work/#rules-for-parsing-integers 100 172 bool parseHTMLInteger(const String& input, int& value) -
trunk/WebCore/html/parser/HTMLParserIdioms.h
r69044 r71622 45 45 // The double* parameter may be 0 to check if the string can be parsed without getting the result. 46 46 bool parseToDoubleForNumberType(const String&, double*); 47 bool parseToDoubleForNumberTypeWithDecimalPlaces(const String&, double*, unsigned*); 47 48 48 49 // http://www.whatwg.org/specs/web-apps/current-work/#rules-for-parsing-integers
Note: See TracChangeset
for help on using the changeset viewer.