[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