[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
commit-queue at webkit.org
commit-queue at webkit.org
Wed Dec 22 15:37:04 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit 823c4a7cb1b0e1adfe5e91a1b23305d70d83c69b
Author: commit-queue at webkit.org <commit-queue at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Tue Nov 9 12:26:45 2010 +0000
2010-11-09 Dai Mikurube <dmikurube at google.com>
Reviewed by Kent Tamura.
Too precise serialization from floating point number to string for "number" input elements
https://bugs.webkit.org/show_bug.cgi?id=48308
* fast/forms/input-stepup-stepdown-expected.txt:
* fast/forms/script-tests/input-stepup-stepdown.js:
2010-11-09 Dai Mikurube <dmikurube at google.com>
Reviewed by Kent Tamura.
Too precise serialization from floating point number to string for "number" input elements
https://bugs.webkit.org/show_bug.cgi?id=48308
Modified to consider decimal places when handling step and base in applyStep().
* html/HTMLInputElement.cpp: Considering decimal places of the given "step" attribtue.
(WebCore::HTMLInputElement::getAllowedValueStep):
(WebCore::HTMLInputElement::getAllowedValueStepWithDecimalPlaces):
(WebCore::HTMLInputElement::applyStep):
* html/HTMLInputElement.h:
* html/InputType.cpp: Added virtual functions for decimal places and an acceptable error.
(WebCore::InputType::stepBaseWithDecimalPlaces):
(WebCore::InputType::acceptableError):
(WebCore::InputType::parseToDoubleWithDecimalPlaces):
* html/InputType.h:
* html/NumberInputType.cpp:
(WebCore::NumberInputType::stepMismatch): Using the virtual function acceptableError().
(WebCore::NumberInputType::stepBaseWithDecimalPlaces): Considering decimal places of the given "base" attribute.
(WebCore::NumberInputType::parseToDoubleWithDecimalPlaces):
(WebCore::NumberInputType::acceptableError): Concrete acceptableError() for the number type.
* html/NumberInputType.h:
* html/parser/HTMLParserIdioms.cpp:
(WebCore::parseToDoubleForNumberTypeWithDecimalPlaces): Parsing numbers with decimal places.
* html/parser/HTMLParserIdioms.h:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@71622 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index b846fb1..c369cb1 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,13 @@
+2010-11-09 Dai Mikurube <dmikurube at google.com>
+
+ Reviewed by Kent Tamura.
+
+ Too precise serialization from floating point number to string for "number" input elements
+ https://bugs.webkit.org/show_bug.cgi?id=48308
+
+ * fast/forms/input-stepup-stepdown-expected.txt:
+ * fast/forms/script-tests/input-stepup-stepdown.js:
+
2010-11-09 Yuzo Fujishima <yuzo at google.com>
Reviewed by Shinichiro Hamaji.
diff --git a/LayoutTests/fast/forms/input-stepup-stepdown-expected.txt b/LayoutTests/fast/forms/input-stepup-stepdown-expected.txt
index fabb787..1ded86d 100644
--- a/LayoutTests/fast/forms/input-stepup-stepdown-expected.txt
+++ b/LayoutTests/fast/forms/input-stepup-stepdown-expected.txt
@@ -165,6 +165,13 @@ PASS stepUp("1", "0.1", "", 10) is "2"
PASS input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.value is "3"
PASS input.min = "0"; stepUp("0", "0.003921568627450980", "1", 255) is "1"
PASS for (var i = 0; i < 255; i++) { input.stepDown(); }; input.value is "0"
+Rounding
+PASS stepUp("5.005", "0.005", "", 2) is "5.015"
+PASS stepUp("5.005", "0.005", "", 11) is "5.06"
+PASS stepUp("5.005", "0.005", "", 12) is "5.065"
+PASS stepUpExplicitBounds("4", "9", "0.005", "5.005", 2) is "5.015"
+PASS stepUpExplicitBounds("4", "9", "0.005", "5.005", 11) is "5.06"
+PASS stepUpExplicitBounds("4", "9", "0.005", "5.005", 12) is "5.065"
Range type
function arguments are (min, max, step, value, [stepCount])
diff --git a/LayoutTests/fast/forms/script-tests/input-stepup-stepdown.js b/LayoutTests/fast/forms/script-tests/input-stepup-stepdown.js
index cd4a07c..1bbc978 100644
--- a/LayoutTests/fast/forms/script-tests/input-stepup-stepdown.js
+++ b/LayoutTests/fast/forms/script-tests/input-stepup-stepdown.js
@@ -221,6 +221,13 @@ shouldBe('stepUp("1", "0.1", "", 10)', '"2"');
shouldBe('input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.value', '"3"');
shouldBe('input.min = "0"; stepUp("0", "0.003921568627450980", "1", 255)', '"1"');
shouldBe('for (var i = 0; i < 255; i++) { input.stepDown(); }; input.value', '"0"');
+debug('Rounding');
+shouldBe('stepUp("5.005", "0.005", "", 2)', '"5.015"');
+shouldBe('stepUp("5.005", "0.005", "", 11)', '"5.06"');
+shouldBe('stepUp("5.005", "0.005", "", 12)', '"5.065"');
+shouldBe('stepUpExplicitBounds("4", "9", "0.005", "5.005", 2)', '"5.015"');
+shouldBe('stepUpExplicitBounds("4", "9", "0.005", "5.005", 11)', '"5.06"');
+shouldBe('stepUpExplicitBounds("4", "9", "0.005", "5.005", 12)', '"5.065"');
debug('');
debug('Range type');
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 3667bbc..229a85d 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,32 @@
+2010-11-09 Dai Mikurube <dmikurube at google.com>
+
+ Reviewed by Kent Tamura.
+
+ Too precise serialization from floating point number to string for "number" input elements
+ https://bugs.webkit.org/show_bug.cgi?id=48308
+
+ Modified to consider decimal places when handling step and base in applyStep().
+
+ * html/HTMLInputElement.cpp: Considering decimal places of the given "step" attribtue.
+ (WebCore::HTMLInputElement::getAllowedValueStep):
+ (WebCore::HTMLInputElement::getAllowedValueStepWithDecimalPlaces):
+ (WebCore::HTMLInputElement::applyStep):
+ * html/HTMLInputElement.h:
+ * html/InputType.cpp: Added virtual functions for decimal places and an acceptable error.
+ (WebCore::InputType::stepBaseWithDecimalPlaces):
+ (WebCore::InputType::acceptableError):
+ (WebCore::InputType::parseToDoubleWithDecimalPlaces):
+ * html/InputType.h:
+ * html/NumberInputType.cpp:
+ (WebCore::NumberInputType::stepMismatch): Using the virtual function acceptableError().
+ (WebCore::NumberInputType::stepBaseWithDecimalPlaces): Considering decimal places of the given "base" attribute.
+ (WebCore::NumberInputType::parseToDoubleWithDecimalPlaces):
+ (WebCore::NumberInputType::acceptableError): Concrete acceptableError() for the number type.
+ * html/NumberInputType.h:
+ * html/parser/HTMLParserIdioms.cpp:
+ (WebCore::parseToDoubleForNumberTypeWithDecimalPlaces): Parsing numbers with decimal places.
+ * html/parser/HTMLParserIdioms.h:
+
2010-11-09 Yuzo Fujishima <yuzo at google.com>
Reviewed by Shinichiro Hamaji.
diff --git a/WebCore/html/HTMLInputElement.cpp b/WebCore/html/HTMLInputElement.cpp
index 361a8c9..5406524 100644
--- a/WebCore/html/HTMLInputElement.cpp
+++ b/WebCore/html/HTMLInputElement.cpp
@@ -253,6 +253,11 @@ bool HTMLInputElement::stepMismatch(const String& value) const
bool HTMLInputElement::getAllowedValueStep(double* step) const
{
+ return getAllowedValueStepWithDecimalPlaces(step, 0);
+}
+
+bool HTMLInputElement::getAllowedValueStepWithDecimalPlaces(double* step, unsigned* decimalPlaces) const
+{
ASSERT(step);
double defaultStep = m_inputType->defaultStep();
double stepScaleFactor = m_inputType->stepScaleFactor();
@@ -261,14 +266,24 @@ bool HTMLInputElement::getAllowedValueStep(double* step) const
const AtomicString& stepString = getAttribute(stepAttr);
if (stepString.isEmpty()) {
*step = defaultStep * stepScaleFactor;
+ if (decimalPlaces)
+ *decimalPlaces = 0;
return true;
}
if (equalIgnoringCase(stepString, "any"))
return false;
double parsed;
- if (!parseToDoubleForNumberType(stepString, &parsed) || parsed <= 0.0) {
- *step = defaultStep * stepScaleFactor;
- return true;
+ if (!decimalPlaces) {
+ if (!parseToDoubleForNumberType(stepString, &parsed) || parsed <= 0.0) {
+ *step = defaultStep * stepScaleFactor;
+ return true;
+ }
+ } else {
+ if (!parseToDoubleForNumberTypeWithDecimalPlaces(stepString, &parsed, decimalPlaces) || parsed <= 0.0) {
+ *step = defaultStep * stepScaleFactor;
+ *decimalPlaces = 0;
+ return true;
+ }
}
// For date, month, week, the parsed value should be an integer for some types.
if (m_inputType->parsedStepValueShouldBeInteger())
@@ -285,7 +300,8 @@ bool HTMLInputElement::getAllowedValueStep(double* step) const
void HTMLInputElement::applyStep(double count, ExceptionCode& ec)
{
double step;
- if (!getAllowedValueStep(&step)) {
+ unsigned stepDecimalPlaces;
+ if (!getAllowedValueStepWithDecimalPlaces(&step, &stepDecimalPlaces)) {
ec = INVALID_STATE_ERR;
return;
}
@@ -300,16 +316,26 @@ void HTMLInputElement::applyStep(double count, ExceptionCode& ec)
ec = INVALID_STATE_ERR;
return;
}
- if (newValue < m_inputType->minimum()) {
+ double acceptableError = m_inputType->acceptableError(step);
+ if (newValue - m_inputType->minimum() < -acceptableError) {
ec = INVALID_STATE_ERR;
return;
}
- double base = m_inputType->stepBase();
- newValue = base + round((newValue - base) / step) * step;
- if (newValue > m_inputType->maximum()) {
+ if (newValue < m_inputType->minimum())
+ newValue = m_inputType->minimum();
+ unsigned baseDecimalPlaces;
+ double base = m_inputType->stepBaseWithDecimalPlaces(&baseDecimalPlaces);
+ baseDecimalPlaces = min(baseDecimalPlaces, 16u);
+ if (newValue < pow(10.0, 21.0)) {
+ double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces)));
+ newValue = round((base + round((newValue - base) / step) * step) * scale) / scale;
+ }
+ if (newValue - m_inputType->maximum() > acceptableError) {
ec = INVALID_STATE_ERR;
return;
}
+ if (newValue > m_inputType->maximum())
+ newValue = m_inputType->maximum();
setValueAsNumber(newValue, ec);
}
diff --git a/WebCore/html/HTMLInputElement.h b/WebCore/html/HTMLInputElement.h
index 1a0490e..0acf21e 100644
--- a/WebCore/html/HTMLInputElement.h
+++ b/WebCore/html/HTMLInputElement.h
@@ -65,6 +65,7 @@ public:
// Sets the "allowed value step" defined in the HTML spec to the specified double pointer.
// Returns false if there is no "allowed value step."
bool getAllowedValueStep(double*) const;
+ bool getAllowedValueStepWithDecimalPlaces(double*, unsigned*) const;
// For ValidityState.
bool stepMismatch(const String&) const;
diff --git a/WebCore/html/InputType.cpp b/WebCore/html/InputType.cpp
index c870c69..c0cc342 100644
--- a/WebCore/html/InputType.cpp
+++ b/WebCore/html/InputType.cpp
@@ -237,6 +237,13 @@ double InputType::stepBase() const
return 0;
}
+double InputType::stepBaseWithDecimalPlaces(unsigned* decimalPlaces) const
+{
+ if (decimalPlaces)
+ *decimalPlaces = 0;
+ return stepBase();
+}
+
double InputType::defaultStep() const
{
return numeric_limits<double>::quiet_NaN();
@@ -257,6 +264,11 @@ bool InputType::scaledStepValeuShouldBeInteger() const
return false;
}
+double InputType::acceptableError(double) const
+{
+ return 0;
+}
+
RenderObject* InputType::createRenderer(RenderArena*, RenderStyle* style) const
{
return RenderObject::createObject(element(), style);
@@ -267,6 +279,13 @@ double InputType::parseToDouble(const String&, double defaultValue) const
return defaultValue;
}
+double InputType::parseToDoubleWithDecimalPlaces(const String& src, double defaultValue, unsigned *decimalPlaces) const
+{
+ if (decimalPlaces)
+ *decimalPlaces = 0;
+ return parseToDouble(src, defaultValue);
+}
+
bool InputType::parseToDateComponents(const String&, DateComponents*) const
{
ASSERT_NOT_REACHED();
diff --git a/WebCore/html/InputType.h b/WebCore/html/InputType.h
index f601051..78aab7c 100644
--- a/WebCore/html/InputType.h
+++ b/WebCore/html/InputType.h
@@ -90,10 +90,12 @@ public:
virtual double maximum() const;
virtual bool stepMismatch(const String&, double) const;
virtual double stepBase() const;
+ virtual double stepBaseWithDecimalPlaces(unsigned*) const;
virtual double defaultStep() const;
virtual double stepScaleFactor() const;
virtual bool parsedStepValueShouldBeInteger() const;
virtual bool scaledStepValeuShouldBeInteger() const;
+ virtual double acceptableError(double) const;
// Miscellaneous functions
@@ -104,6 +106,10 @@ public:
// succeeds; Returns defaultValue otherwise. This function can
// return NaN or Infinity only if defaultValue is NaN or Infinity.
virtual double parseToDouble(const String&, double defaultValue) const;
+ // Parses the specified string for the type as parseToDouble() does.
+ // In addition, it stores the number of digits after the decimal point
+ // into *decimalPlaces.
+ virtual double parseToDoubleWithDecimalPlaces(const String& src, double defaultValue, unsigned *decimalPlaces) const;
// Parses the specified string for this InputType, and returns true if it
// is successfully parsed. An instance pointed by the DateComponents*
// parameter will have parsed values and be modified even if the parsing
diff --git a/WebCore/html/NumberInputType.cpp b/WebCore/html/NumberInputType.cpp
index 28f510c..7a4d504 100644
--- a/WebCore/html/NumberInputType.cpp
+++ b/WebCore/html/NumberInputType.cpp
@@ -131,8 +131,8 @@ bool NumberInputType::stepMismatch(const String& value, double step) const
double remainder = fabs(doubleValue - step * round(doubleValue / step));
// Accepts erros in lower fractional part which IEEE 754 single-precision
// can't represent.
- double acceptableError = step / pow(2.0, FLT_MANT_DIG);
- return acceptableError < remainder && remainder < (step - acceptableError);
+ double computedAcceptableError = acceptableError(step);
+ return computedAcceptableError < remainder && remainder < (step - computedAcceptableError);
}
double NumberInputType::stepBase() const
@@ -140,6 +140,11 @@ double NumberInputType::stepBase() const
return parseToDouble(element()->fastGetAttribute(minAttr), defaultStepBase());
}
+double NumberInputType::stepBaseWithDecimalPlaces(unsigned* decimalPlaces) const
+{
+ return parseToDoubleWithDecimalPlaces(element()->fastGetAttribute(minAttr), defaultStepBase(), decimalPlaces);
+}
+
double NumberInputType::defaultStep() const
{
return numberDefaultStep;
@@ -159,6 +164,15 @@ double NumberInputType::parseToDouble(const String& src, double defaultValue) co
return numberValue;
}
+double NumberInputType::parseToDoubleWithDecimalPlaces(const String& src, double defaultValue, unsigned *decimalPlaces) const
+{
+ double numberValue;
+ if (!parseToDoubleForNumberTypeWithDecimalPlaces(src, &numberValue, decimalPlaces))
+ return defaultValue;
+ ASSERT(isfinite(numberValue));
+ return numberValue;
+}
+
String NumberInputType::serialize(double value) const
{
if (!isfinite(value))
@@ -166,4 +180,10 @@ String NumberInputType::serialize(double value) const
return serializeForNumberType(value);
}
+double NumberInputType::acceptableError(double step) const
+{
+ return step / pow(2.0, FLT_MANT_DIG);
+}
+
+
} // namespace WebCore
diff --git a/WebCore/html/NumberInputType.h b/WebCore/html/NumberInputType.h
index 262955e..1f0b881 100644
--- a/WebCore/html/NumberInputType.h
+++ b/WebCore/html/NumberInputType.h
@@ -52,10 +52,13 @@ private:
virtual double maximum() const;
virtual bool stepMismatch(const String&, double) const;
virtual double stepBase() const;
+ virtual double stepBaseWithDecimalPlaces(unsigned*) const;
virtual double defaultStep() const;
virtual double stepScaleFactor() const;
virtual double parseToDouble(const String&, double) const;
+ virtual double parseToDoubleWithDecimalPlaces(const String&, double, unsigned*) const;
virtual String serialize(double) const;
+ virtual double acceptableError(double) const;
};
} // namespace WebCore
diff --git a/WebCore/html/parser/HTMLParserIdioms.cpp b/WebCore/html/parser/HTMLParserIdioms.cpp
index 0ce5e4d..91ff8d3 100644
--- a/WebCore/html/parser/HTMLParserIdioms.cpp
+++ b/WebCore/html/parser/HTMLParserIdioms.cpp
@@ -96,6 +96,78 @@ bool parseToDoubleForNumberType(const String& string, double* result)
return true;
}
+bool parseToDoubleForNumberTypeWithDecimalPlaces(const String& string, double *result, unsigned *decimalPlaces)
+{
+ if (decimalPlaces)
+ *decimalPlaces = 0;
+
+ if (!parseToDoubleForNumberType(string, result))
+ return false;
+
+ if (!decimalPlaces)
+ return true;
+
+ size_t dotIndex = string.find('.');
+ size_t eIndex = string.find('e');
+ if (eIndex == notFound)
+ eIndex = string.find('E');
+
+ unsigned baseDecimalPlaces = 0;
+ if (dotIndex != notFound) {
+ if (eIndex == notFound)
+ baseDecimalPlaces = string.length() - dotIndex - 1;
+ else
+ baseDecimalPlaces = eIndex - dotIndex - 1;
+ }
+
+ int exponent = 0;
+ if (eIndex != notFound) {
+ unsigned cursor = eIndex + 1, cursorSaved;
+ int digit, exponentSign;
+ int32_t exponent32;
+ size_t length = string.length();
+
+ // Not using String.toInt() in order to perform the same computation as dtoa() does.
+ exponentSign = 0;
+ switch (digit = string[cursor]) {
+ case '-':
+ exponentSign = 1;
+ case '+':
+ digit = string[++cursor];
+ }
+ if (digit >= '0' && digit <= '9') {
+ while (cursor < length && digit == '0')
+ digit = string[++cursor];
+ if (digit > '0' && digit <= '9') {
+ exponent32 = digit - '0';
+ cursorSaved = cursor;
+ while (cursor < length && (digit = string[++cursor]) >= '0' && digit <= '9')
+ exponent32 = (10 * exponent32) + digit - '0';
+ if (cursor - cursorSaved > 8 || exponent32 > 19999)
+ /* Avoid confusion from exponents
+ * so large that e might overflow.
+ */
+ exponent = 19999; /* safe for 16 bit ints */
+ else
+ exponent = static_cast<int>(exponent32);
+ if (exponentSign)
+ exponent = -exponent;
+ } else
+ exponent = 0;
+ }
+ }
+
+ int intDecimalPlaces = baseDecimalPlaces - exponent;
+ if (intDecimalPlaces < 0)
+ *decimalPlaces = 0;
+ else if (intDecimalPlaces > 19999)
+ *decimalPlaces = 19999;
+ else
+ *decimalPlaces = static_cast<unsigned>(intDecimalPlaces);
+
+ return true;
+}
+
// http://www.whatwg.org/specs/web-apps/current-work/#rules-for-parsing-integers
bool parseHTMLInteger(const String& input, int& value)
{
diff --git a/WebCore/html/parser/HTMLParserIdioms.h b/WebCore/html/parser/HTMLParserIdioms.h
index 4839138..4e8e58f 100644
--- a/WebCore/html/parser/HTMLParserIdioms.h
+++ b/WebCore/html/parser/HTMLParserIdioms.h
@@ -44,6 +44,7 @@ String serializeForNumberType(double);
// Leading or trailing illegal characters cause failure, as does passing an empty string.
// The double* parameter may be 0 to check if the string can be parsed without getting the result.
bool parseToDoubleForNumberType(const String&, double*);
+bool parseToDoubleForNumberTypeWithDecimalPlaces(const String&, double*, unsigned*);
// http://www.whatwg.org/specs/web-apps/current-work/#rules-for-parsing-integers
bool parseHTMLInteger(const String&, int&);
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list