Title: [200907] trunk
Revision
200907
Author
[email protected]
Date
2016-05-13 19:10:27 -0700 (Fri, 13 May 2016)

Log Message

Align window.scroll() / scrollTo() / scrollBy() with the CSSOM specification
https://bugs.webkit.org/show_bug.cgi?id=157666

Reviewed by Darin Adler.

Source/WebCore:

Align window.scroll() / scrollTo() / scrollBy() with Firefox and the CSSOM
specification:
https://drafts.csswg.org/cssom-view/#extensions-to-the-window-interface

In particular, the following changes were made:
1. Make parameters to scroll() / scrollTo() / scrollBy() mandatory.
2. Add overloads for scroll() / scrollTo() / scrollBy() that take an
   optional ScrollToOptions dictionary.
3. Update API to use "unrestricted double" typing for x/y instead of
   "long". This matches the specification but it does not really change
   our behavior at this point because the values are still casted to
   int in our implementation.

Web-Exposed behavior changes:
1. JS can now pass a dictionary to scroll() / scrollTo() / scrollBy().
   This a new feature that Firefox already supports (Chrome does not).
2. Passing only 1 parameter to scroll() / scrollTo() / scrollBy() that
   is not a dictionary will now throw a TypeError. The compatibility
   risky should be low because Firefox and Chrome already throw in this
   case (Chrome has been throwing for 2 years and a half).
3. Calling scrollTo() / scroll() without any parameter no longer
   scrolls to 0. Instead we use the current viewport's x/y which means
   we don't scroll at all. The new behavior matches Firefox, Chrome and
   IE 11. This fixes scrolling on the following Website:
   https://members.chosun.com/cms_subscribe/application/index.jsp

No new tests, extended existing testing.

* bindings/js/JSDOMConvert.h:
(WebCore::convert):
(WebCore::convertOptional):
* bindings/scripts/CodeGeneratorJS.pm:
(ShouldAllowNonFiniteForFloatingPointType):
(GenerateConversionRuleWithLeadingComma):
(GenerateDictionaryImplementationContent):
(JSValueToNative):
* bindings/scripts/test/JS/JSTestObj.cpp:
(WebCore::convert<TestObj::Dictionary>):
* bindings/scripts/test/TestObj.idl:
* page/DOMWindow.cpp:
(WebCore::DOMWindow::scrollBy):
(WebCore::DOMWindow::scrollTo):
* page/DOMWindow.h:
* page/DOMWindow.idl:

LayoutTests:

Update / improve testing coverage for the API.

* fast/dom/Window/window-scroll-arguments-expected.txt:
* fast/dom/Window/window-scroll-arguments.html:
* fast/dom/non-numeric-values-numeric-parameters-expected.txt:
* fast/dom/script-tests/non-numeric-values-numeric-parameters.js:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (200906 => 200907)


--- trunk/LayoutTests/ChangeLog	2016-05-14 02:03:10 UTC (rev 200906)
+++ trunk/LayoutTests/ChangeLog	2016-05-14 02:10:27 UTC (rev 200907)
@@ -1,3 +1,17 @@
+2016-05-13  Chris Dumez  <[email protected]>
+
+        Align window.scroll() / scrollTo() / scrollBy() with the CSSOM specification
+        https://bugs.webkit.org/show_bug.cgi?id=157666
+
+        Reviewed by Darin Adler.
+
+        Update / improve testing coverage for the API.
+
+        * fast/dom/Window/window-scroll-arguments-expected.txt:
+        * fast/dom/Window/window-scroll-arguments.html:
+        * fast/dom/non-numeric-values-numeric-parameters-expected.txt:
+        * fast/dom/script-tests/non-numeric-values-numeric-parameters.js:
+
 2016-05-13  Simon Fraser  <[email protected]>
 
         cross-fade() rendering doesn't match expectation

Modified: trunk/LayoutTests/fast/dom/Window/window-scroll-arguments-expected.txt (200906 => 200907)


--- trunk/LayoutTests/fast/dom/Window/window-scroll-arguments-expected.txt	2016-05-14 02:03:10 UTC (rev 200906)
+++ trunk/LayoutTests/fast/dom/Window/window-scroll-arguments-expected.txt	2016-05-14 02:10:27 UTC (rev 200907)
@@ -1,4 +1,4 @@
-This test makes sure that calling the window scrolling methods with less than 2 arguments treats the missing arguments as 0.
+This tests calling the window scrolling with only 1 argument
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
@@ -9,9 +9,19 @@
 Testing - scrollTo with 0 arguments
 PASS window.scrollX is resetX
 PASS window.scrollY is resetY
-Testing - scrollTo with 1 argument
-PASS window.scrollX is resetX + x
+PASS window.scrollX is x
+PASS window.scrollY is y
+Testing - scrollTo with 1 non-dictionary argument
+PASS scrollTo(0) threw exception TypeError: Type error.
+Testing - scrollTo with 1 dictionary argument
+PASS window.scrollX is x
 PASS window.scrollY is resetY
+PASS window.scrollX is resetX
+PASS window.scrollY is y
+PASS window.scrollX is x
+PASS window.scrollY is y
+PASS window.scrollX is 0
+PASS window.scrollY is 0
 Testing - scrollTo with more than 2 arguments
 PASS window.scrollX is x
 PASS window.scrollY is y
@@ -21,9 +31,19 @@
 Testing - scroll with 0 arguments
 PASS window.scrollX is resetX
 PASS window.scrollY is resetY
-Testing - scroll with 1 argument
-PASS window.scrollX is resetX + x
+PASS window.scrollX is x
+PASS window.scrollY is y
+Testing - scroll with 1 non-dictionary argument
+PASS scroll(0) threw exception TypeError: Type error.
+Testing - scroll with 1 dictionary argument
+PASS window.scrollX is x
 PASS window.scrollY is resetY
+PASS window.scrollX is resetX
+PASS window.scrollY is y
+PASS window.scrollX is x
+PASS window.scrollY is y
+PASS window.scrollX is 0
+PASS window.scrollY is 0
 Testing - scroll with more than 2 arguments
 PASS window.scrollX is x
 PASS window.scrollY is y
@@ -33,9 +53,19 @@
 Testing - scrollBy with 0 arguments
 PASS window.scrollX is resetX
 PASS window.scrollY is resetY
+PASS window.scrollX is x
+PASS window.scrollY is y
+Testing - scrollBy with 1 non-dictionary argument
+PASS scrollBy(0) threw exception TypeError: Type error.
 Testing - scrollBy with 1 argument
 PASS window.scrollX is resetX + x
 PASS window.scrollY is resetY
+PASS window.scrollX is resetX
+PASS window.scrollY is resetY + y
+PASS window.scrollX is resetX + x
+PASS window.scrollY is resetY + y
+PASS window.scrollX is resetX + x
+PASS window.scrollY is resetY + y
 Testing - scrollBy with more than 2 arguments
 PASS window.scrollX is resetX + x
 PASS window.scrollY is resetY + y

Modified: trunk/LayoutTests/fast/dom/Window/window-scroll-arguments.html (200906 => 200907)


--- trunk/LayoutTests/fast/dom/Window/window-scroll-arguments.html	2016-05-14 02:03:10 UTC (rev 200906)
+++ trunk/LayoutTests/fast/dom/Window/window-scroll-arguments.html	2016-05-14 02:10:27 UTC (rev 200907)
@@ -24,8 +24,7 @@
 
     reset();
 
-    description("This test makes sure that calling the window scrolling\
-    methods with less than 2 arguments treats the missing arguments as 0.");
+    description("This tests calling the window scrolling with only 1 argument");
 
     // scrollTo /////////////////////////
     debug('');
@@ -37,12 +36,34 @@
     shouldBe('window.scrollX', 'resetX');
     shouldBe('window.scrollY', 'resetY');
     reset();
+    window.scrollTo(x, y);
+    window.scrollTo();
+    shouldBe('window.scrollX', 'x');
+    shouldBe('window.scrollY', 'y');
+    reset();
 
-    debug("Testing - scrollTo with 1 argument");
-    window.scrollTo(x);
-    shouldBe('window.scrollX', 'resetX + x');
+    debug("Testing - scrollTo with 1 non-dictionary argument");
+    shouldThrow("scrollTo(0)");
+    reset();
+
+    debug("Testing - scrollTo with 1 dictionary argument");
+    window.scrollTo({ left: x });
+    shouldBe('window.scrollX', 'x');
     shouldBe('window.scrollY', 'resetY');
     reset();
+    window.scrollTo({ top: y });
+    shouldBe('window.scrollX', 'resetX');
+    shouldBe('window.scrollY', 'y');
+    reset();
+    window.scrollTo({ left: x, top: y });
+    shouldBe('window.scrollX', 'x');
+    shouldBe('window.scrollY', 'y');
+    reset();
+    window.scrollTo(x, y);
+    window.scrollTo({ left: NaN, top: NaN });
+    shouldBe('window.scrollX', '0');
+    shouldBe('window.scrollY', '0');
+    reset();
 
     debug("Testing - scrollTo with more than 2 arguments");
     window.scrollTo(x, y, 200, "text");
@@ -60,12 +81,34 @@
     shouldBe('window.scrollX', 'resetX');
     shouldBe('window.scrollY', 'resetY');
     reset();
+    window.scroll(x, y);
+    window.scroll();
+    shouldBe('window.scrollX', 'x');
+    shouldBe('window.scrollY', 'y');
+    reset();
 
-    debug("Testing - scroll with 1 argument");
-    window.scroll(x);
-    shouldBe('window.scrollX', 'resetX + x');
+    debug("Testing - scroll with 1 non-dictionary argument");
+    shouldThrow("scroll(0)");
+    reset();
+
+    debug("Testing - scroll with 1 dictionary argument");
+    window.scroll({ left: x });
+    shouldBe('window.scrollX', 'x');
     shouldBe('window.scrollY', 'resetY');
     reset();
+    window.scroll({ top: y });
+    shouldBe('window.scrollX', 'resetX');
+    shouldBe('window.scrollY', 'y');
+    reset();
+    window.scroll({ left: x, top: y });
+    shouldBe('window.scrollX', 'x');
+    shouldBe('window.scrollY', 'y');
+    reset();
+    window.scroll(x, y);
+    window.scroll({ left: NaN, top: NaN });
+    shouldBe('window.scrollX', '0');
+    shouldBe('window.scrollY', '0');
+    reset();
 
     debug("Testing - scroll with more than 2 arguments");
     window.scroll(x, y, 200, "text");
@@ -83,12 +126,34 @@
     shouldBe('window.scrollX', 'resetX');
     shouldBe('window.scrollY', 'resetY');
     reset();
+    window.scrollBy(x, y);
+    window.scrollBy();
+    shouldBe('window.scrollX', 'x');
+    shouldBe('window.scrollY', 'y');
+    reset();
 
+    debug("Testing - scrollBy with 1 non-dictionary argument");
+    shouldThrow("scrollBy(0)");
+    reset();
+
     debug("Testing - scrollBy with 1 argument");
-    window.scrollBy(x);
+    window.scrollBy({ left: x });
     shouldBe('window.scrollX', 'resetX + x');
     shouldBe('window.scrollY', 'resetY');
     reset();
+    window.scrollBy({ top: y });
+    shouldBe('window.scrollX', 'resetX');
+    shouldBe('window.scrollY', 'resetY + y');
+    reset();
+    window.scrollBy({ left: x, top: y });
+    shouldBe('window.scrollX', 'resetX + x');
+    shouldBe('window.scrollY', 'resetY + y');
+    reset();
+    window.scrollBy(x, y);
+    window.scrollBy({ left: NaN, top: NaN });
+    shouldBe('window.scrollX', 'resetX + x');
+    shouldBe('window.scrollY', 'resetY + y');
+    reset();
 
     debug("Testing - scrollBy with more than 2 arguments");
     window.scrollBy(x, y, 200, "text");

Modified: trunk/LayoutTests/fast/dom/non-numeric-values-numeric-parameters-expected.txt (200906 => 200907)


--- trunk/LayoutTests/fast/dom/non-numeric-values-numeric-parameters-expected.txt	2016-05-14 02:03:10 UTC (rev 200906)
+++ trunk/LayoutTests/fast/dom/non-numeric-values-numeric-parameters-expected.txt	2016-05-14 02:10:27 UTC (rev 200907)
@@ -66,11 +66,11 @@
 PASS nonNumericPolicy('document.createTreeWalker(document, x, null, false)') is 'any type allowed'
 PASS nonNumericPolicy('document.createEvent("UIEvent").initUIEvent("a", false, false, null, x)') is 'any type allowed'
 PASS nonNumericPolicy('window.scrollBy(x, 0)') is 'any type allowed'
-PASS nonNumericPolicy('window.scrollBy(0, x)') is 'any type allowed'
+PASS nonNumericPolicy('window.scrollBy(0, x)') is 'any type allowed (but not omitted)'
 PASS nonNumericPolicy('window.scrollTo(x, 0)') is 'any type allowed'
-PASS nonNumericPolicy('window.scrollTo(0, x)') is 'any type allowed'
+PASS nonNumericPolicy('window.scrollTo(0, x)') is 'any type allowed (but not omitted)'
 PASS nonNumericPolicy('window.scroll(x, 0)') is 'any type allowed'
-PASS nonNumericPolicy('window.scroll(0, x)') is 'any type allowed'
+PASS nonNumericPolicy('window.scroll(0, x)') is 'any type allowed (but not omitted)'
 PASS nonNumericPolicy('window.moveBy(x, 0)') is 'any type allowed'
 PASS nonNumericPolicy('window.moveBy(0, x)') is 'any type allowed'
 PASS nonNumericPolicy('window.moveTo(x, 0)') is 'any type allowed'

Modified: trunk/LayoutTests/fast/dom/script-tests/non-numeric-values-numeric-parameters.js (200906 => 200907)


--- trunk/LayoutTests/fast/dom/script-tests/non-numeric-values-numeric-parameters.js	2016-05-14 02:03:10 UTC (rev 200906)
+++ trunk/LayoutTests/fast/dom/script-tests/non-numeric-values-numeric-parameters.js	2016-05-14 02:10:27 UTC (rev 200907)
@@ -344,11 +344,11 @@
 // Window
 
 shouldBe("nonNumericPolicy('window.scrollBy(x, 0)')", "'any type allowed'");
-shouldBe("nonNumericPolicy('window.scrollBy(0, x)')", "'any type allowed'");
+shouldBe("nonNumericPolicy('window.scrollBy(0, x)')", "'any type allowed (but not omitted)'");
 shouldBe("nonNumericPolicy('window.scrollTo(x, 0)')", "'any type allowed'");
-shouldBe("nonNumericPolicy('window.scrollTo(0, x)')", "'any type allowed'");
+shouldBe("nonNumericPolicy('window.scrollTo(0, x)')", "'any type allowed (but not omitted)'");
 shouldBe("nonNumericPolicy('window.scroll(x, 0)')", "'any type allowed'");
-shouldBe("nonNumericPolicy('window.scroll(0, x)')", "'any type allowed'");
+shouldBe("nonNumericPolicy('window.scroll(0, x)')", "'any type allowed (but not omitted)'");
 shouldBe("nonNumericPolicy('window.moveBy(x, 0)')", "'any type allowed'");
 shouldBe("nonNumericPolicy('window.moveBy(0, x)')", "'any type allowed'");
 shouldBe("nonNumericPolicy('window.moveTo(x, 0)')", "'any type allowed'");

Modified: trunk/Source/WebCore/ChangeLog (200906 => 200907)


--- trunk/Source/WebCore/ChangeLog	2016-05-14 02:03:10 UTC (rev 200906)
+++ trunk/Source/WebCore/ChangeLog	2016-05-14 02:10:27 UTC (rev 200907)
@@ -1,3 +1,55 @@
+2016-05-13  Chris Dumez  <[email protected]>
+
+        Align window.scroll() / scrollTo() / scrollBy() with the CSSOM specification
+        https://bugs.webkit.org/show_bug.cgi?id=157666
+
+        Reviewed by Darin Adler.
+
+        Align window.scroll() / scrollTo() / scrollBy() with Firefox and the CSSOM
+        specification:
+        https://drafts.csswg.org/cssom-view/#extensions-to-the-window-interface
+
+        In particular, the following changes were made:
+        1. Make parameters to scroll() / scrollTo() / scrollBy() mandatory.
+        2. Add overloads for scroll() / scrollTo() / scrollBy() that take an
+           optional ScrollToOptions dictionary.
+        3. Update API to use "unrestricted double" typing for x/y instead of
+           "long". This matches the specification but it does not really change
+           our behavior at this point because the values are still casted to
+           int in our implementation.
+
+        Web-Exposed behavior changes:
+        1. JS can now pass a dictionary to scroll() / scrollTo() / scrollBy().
+           This a new feature that Firefox already supports (Chrome does not).
+        2. Passing only 1 parameter to scroll() / scrollTo() / scrollBy() that
+           is not a dictionary will now throw a TypeError. The compatibility
+           risky should be low because Firefox and Chrome already throw in this
+           case (Chrome has been throwing for 2 years and a half).
+        3. Calling scrollTo() / scroll() without any parameter no longer
+           scrolls to 0. Instead we use the current viewport's x/y which means
+           we don't scroll at all. The new behavior matches Firefox, Chrome and
+           IE 11. This fixes scrolling on the following Website:
+           https://members.chosun.com/cms_subscribe/application/index.jsp
+
+        No new tests, extended existing testing.
+
+        * bindings/js/JSDOMConvert.h:
+        (WebCore::convert):
+        (WebCore::convertOptional):
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (ShouldAllowNonFiniteForFloatingPointType):
+        (GenerateConversionRuleWithLeadingComma):
+        (GenerateDictionaryImplementationContent):
+        (JSValueToNative):
+        * bindings/scripts/test/JS/JSTestObj.cpp:
+        (WebCore::convert<TestObj::Dictionary>):
+        * bindings/scripts/test/TestObj.idl:
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::scrollBy):
+        (WebCore::DOMWindow::scrollTo):
+        * page/DOMWindow.h:
+        * page/DOMWindow.idl:
+
 2016-05-13  Commit Queue  <[email protected]>
 
         Unreviewed, rolling out r200894.

Modified: trunk/Source/WebCore/bindings/js/JSDOMConvert.h (200906 => 200907)


--- trunk/Source/WebCore/bindings/js/JSDOMConvert.h	2016-05-14 02:03:10 UTC (rev 200906)
+++ trunk/Source/WebCore/bindings/js/JSDOMConvert.h	2016-05-14 02:10:27 UTC (rev 200907)
@@ -32,7 +32,7 @@
 
 enum class ShouldAllowNonFinite { No, Yes };
 
-template<typename T> struct Converter;
+template<typename T, typename Enable = void> struct Converter;
 
 template<typename T> T convert(JSC::ExecState&, JSC::JSValue);
 template<typename T> T convert(JSC::ExecState&, JSC::JSValue, IntegerConversionConfiguration);
@@ -41,6 +41,9 @@
 template<typename T> typename Converter<T>::OptionalValue convertOptional(JSC::ExecState&, JSC::JSValue);
 template<typename T, typename U> T convertOptional(JSC::ExecState&, JSC::JSValue, U&& defaultValue);
 
+template<typename T> typename Converter<T>::OptionalValue convertOptional(JSC::ExecState&, JSC::JSValue, ShouldAllowNonFinite);
+template<typename T, typename U> T convertOptional(JSC::ExecState&, JSC::JSValue, ShouldAllowNonFinite, U&& defaultValue);
+
 // This is where the implementation of the things declared above begins:
 
 template<typename T> T convert(JSC::ExecState& state, JSC::JSValue value)
@@ -56,10 +59,7 @@
 template<typename T> inline T convert(JSC::ExecState& state, JSC::JSValue value, ShouldAllowNonFinite allow)
 {
     static_assert(std::is_same<T, float>::value || std::is_same<T, double>::value, "ShouldAllowNonFinite can only be used with float or double");
-    double number = value.toNumber(&state);
-    if (allow == ShouldAllowNonFinite::No && UNLIKELY(!std::isfinite(number)))
-        throwNonFiniteTypeError(state);
-    return static_cast<T>(number);
+    return Converter<T>::convert(state, value, allow);
 }
 
 template<typename T> typename Converter<T>::OptionalValue inline convertOptional(JSC::ExecState& state, JSC::JSValue value)
@@ -72,11 +72,21 @@
     return value.isUndefined() ? std::forward<U>(defaultValue) : convert<T>(state, value);
 }
 
+template<typename T> typename Converter<T>::OptionalValue inline convertOptional(JSC::ExecState& state, JSC::JSValue value, ShouldAllowNonFinite allow)
+{
+    return value.isUndefined() ? typename Converter<T>::OptionalValue() : convert<T>(state, value, allow);
+}
+
+template<typename T, typename U> inline T convertOptional(JSC::ExecState& state, JSC::JSValue value, ShouldAllowNonFinite allow, U&& defaultValue)
+{
+    return value.isUndefined() ? std::forward<U>(defaultValue) : convert<T>(state, value, allow);
+}
+
 template<typename T> struct DefaultConverter {
     using OptionalValue = Optional<T>;
 };
 
-template<typename T> struct Converter : DefaultConverter<T> {
+template<typename T, typename Enable> struct Converter : DefaultConverter<T> {
 };
 
 template<> struct Converter<bool> : DefaultConverter<bool> {
@@ -228,4 +238,14 @@
     }
 };
 
+template<typename T> struct Converter<T, typename std::enable_if<std::is_floating_point<T>::value>::type> : DefaultConverter<T> {
+    static T convert(JSC::ExecState& state, JSC::JSValue value, ShouldAllowNonFinite allow)
+    {
+        double number = value.toNumber(&state);
+        if (allow == ShouldAllowNonFinite::No && UNLIKELY(!std::isfinite(number)))
+            throwNonFiniteTypeError(state);
+        return static_cast<T>(number);
+    }
+};
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (200906 => 200907)


--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm	2016-05-14 02:03:10 UTC (rev 200906)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm	2016-05-14 02:10:27 UTC (rev 200907)
@@ -958,6 +958,25 @@
     return $value;
 }
 
+sub ShouldAllowNonFiniteForFloatingPointType
+{
+    my $type = shift;
+
+    die "Can only be called with floating point types" unless $codeGenerator->IsFloatingPointType($type);
+    return $type eq "unrestricted double" || $type eq "unrestricted float";
+}
+
+sub GenerateConversionRuleWithLeadingComma
+{
+    my ($interface, $member) = @_;
+
+    if ($codeGenerator->IsFloatingPointType($member->type)) {
+        return ", " . (ShouldAllowNonFiniteForFloatingPointType($member->type) ? "ShouldAllowNonFinite::Yes" : "ShouldAllowNonFinite::No");
+    }
+    # FIXME: Add support for integer types.
+    return "";
+}
+
 sub GenerateDefaultValueWithLeadingComma
 {
     my ($interface, $member) = @_;
@@ -1011,9 +1030,9 @@
             }
             # FIXME: Eventually we will want this to share a lot more code with JSValueToNative.
             my $function = $member->isOptional ? "convertOptional" : "convert";
-            my $defaultValueWithLeadingComma = $member->isOptional && defined $member->default ? ", " . $member->default : "";
             $result .= "    auto " . $member->name . " = " . $function . "<" . GetNativeTypeFromSignature($interface, $member) . ">"
                 . "(state, object->get(&state, Identifier::fromString(&state, \"" . $member->name . "\"))"
+                . GenerateConversionRuleWithLeadingComma($interface, $member)
                 . GenerateDefaultValueWithLeadingComma($interface, $member) . ");\n";
             $needExceptionCheck = 1;
         }
@@ -4425,11 +4444,9 @@
 
     if ($codeGenerator->IsFloatingPointType($type)) {
         AddToImplIncludes("JSDOMConvert.h");
-        return ("convert<double>(*state, $value, ShouldAllowNonFinite::No)", 1) if $type eq "double";
-        return ("convert<double>(*state, $value, ShouldAllowNonFinite::Yes)", 1) if $type eq "unrestricted double";
-        return ("convert<float>(*state, $value, ShouldAllowNonFinite::No)", 1) if $type eq "float";
-        return ("convert<float>(*state, $value, ShouldAllowNonFinite::Yes)", 1) if $type eq "unrestricted float";
-        die "Unhandled floating point type: " . $type;
+        my $allowNonFinite = ShouldAllowNonFiniteForFloatingPointType($type) ? "ShouldAllowNonFinite::Yes" : "ShouldAllowNonFinite::No";
+        my $nativeType = GetNativeType($interface, $type);
+        return ("convert<$nativeType>(*state, $value, $allowNonFinite)", 1);
     }
 
     return ("valueToDate(state, $value)", 1) if $type eq "Date";

Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp (200906 => 200907)


--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp	2016-05-14 02:03:10 UTC (rev 200906)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp	2016-05-14 02:10:27 UTC (rev 200907)
@@ -455,7 +455,7 @@
 template<> TestObj::Dictionary convert<TestObj::Dictionary>(ExecState& state, JSValue value)
 {
     if (value.isUndefinedOrNull())
-        return { { }, TestObj::EnumType::EnumValue1, TestObj::EnumType::EmptyString, "defaultString", { }, false, { }, { } };
+        return { { }, TestObj::EnumType::EnumValue1, TestObj::EnumType::EmptyString, "defaultString", { }, false, { }, { }, { }, { }, 0, 0, { }, { }, 0, 0 };
     auto* object = value.getObject();
     if (UNLIKELY(!object || object->type() == RegExpObjectType)) {
         throwTypeError(&state);
@@ -483,7 +483,31 @@
     if (UNLIKELY(state.hadException()))
         return { };
     auto sequenceOfStrings = convertOptional<Vector<String>>(state, object->get(&state, Identifier::fromString(&state, "sequenceOfStrings")));
-    return { WTFMove(enumerationValueWithoutDefault), WTFMove(enumerationValueWithDefault), WTFMove(enumerationValueWithEmptyStringDefault), WTFMove(stringWithDefault), WTFMove(stringWithoutDefault), WTFMove(booleanWithDefault), WTFMove(booleanWithoutDefault), WTFMove(sequenceOfStrings) };
+    if (UNLIKELY(state.hadException()))
+        return { };
+    auto restrictedDouble = convertOptional<double>(state, object->get(&state, Identifier::fromString(&state, "restrictedDouble")), ShouldAllowNonFinite::No);
+    if (UNLIKELY(state.hadException()))
+        return { };
+    auto unrestrictedDouble = convertOptional<double>(state, object->get(&state, Identifier::fromString(&state, "unrestrictedDouble")), ShouldAllowNonFinite::Yes);
+    if (UNLIKELY(state.hadException()))
+        return { };
+    auto restrictedDoubleWithDefault = convertOptional<double>(state, object->get(&state, Identifier::fromString(&state, "restrictedDoubleWithDefault")), ShouldAllowNonFinite::No, 0);
+    if (UNLIKELY(state.hadException()))
+        return { };
+    auto unrestrictedDoubleWithDefault = convertOptional<double>(state, object->get(&state, Identifier::fromString(&state, "unrestrictedDoubleWithDefault")), ShouldAllowNonFinite::Yes, 0);
+    if (UNLIKELY(state.hadException()))
+        return { };
+    auto restrictedFloat = convertOptional<float>(state, object->get(&state, Identifier::fromString(&state, "restrictedFloat")), ShouldAllowNonFinite::No);
+    if (UNLIKELY(state.hadException()))
+        return { };
+    auto unrestrictedFloat = convertOptional<float>(state, object->get(&state, Identifier::fromString(&state, "unrestrictedFloat")), ShouldAllowNonFinite::Yes);
+    if (UNLIKELY(state.hadException()))
+        return { };
+    auto restrictedFloatWithDefault = convertOptional<float>(state, object->get(&state, Identifier::fromString(&state, "restrictedFloatWithDefault")), ShouldAllowNonFinite::No, 0);
+    if (UNLIKELY(state.hadException()))
+        return { };
+    auto unrestrictedFloatWithDefault = convertOptional<float>(state, object->get(&state, Identifier::fromString(&state, "unrestrictedFloatWithDefault")), ShouldAllowNonFinite::Yes, 0);
+    return { WTFMove(enumerationValueWithoutDefault), WTFMove(enumerationValueWithDefault), WTFMove(enumerationValueWithEmptyStringDefault), WTFMove(stringWithDefault), WTFMove(stringWithoutDefault), WTFMove(booleanWithDefault), WTFMove(booleanWithoutDefault), WTFMove(sequenceOfStrings), WTFMove(restrictedDouble), WTFMove(unrestrictedDouble), WTFMove(restrictedDoubleWithDefault), WTFMove(unrestrictedDoubleWithDefault), WTFMove(restrictedFloat), WTFMove(unrestrictedFloat), WTFMove(restrictedFloatWithDefault), WTFMove(unrestrictedFloatWithDefault) };
 }
 
 template<> TestObj::DictionaryThatShouldNotTolerateNull convert<TestObj::DictionaryThatShouldNotTolerateNull>(ExecState& state, JSValue value)

Modified: trunk/Source/WebCore/bindings/scripts/test/TestObj.idl (200906 => 200907)


--- trunk/Source/WebCore/bindings/scripts/test/TestObj.idl	2016-05-14 02:03:10 UTC (rev 200906)
+++ trunk/Source/WebCore/bindings/scripts/test/TestObj.idl	2016-05-14 02:10:27 UTC (rev 200907)
@@ -391,6 +391,14 @@
     boolean booleanWithDefault = false;
     boolean booleanWithoutDefault;
     sequence<DOMString> sequenceOfStrings;
+    double restrictedDouble;
+    unrestricted double unrestrictedDouble;
+    double restrictedDoubleWithDefault = 0;
+    unrestricted double unrestrictedDoubleWithDefault = 0;
+    float restrictedFloat;
+    unrestricted float unrestrictedFloat;
+    float restrictedFloatWithDefault = 0;
+    unrestricted float unrestrictedFloatWithDefault = 0;
 };
 
 dictionary TestDictionaryThatShouldNotTolerateNull {

Modified: trunk/Source/WebCore/page/DOMWindow.cpp (200906 => 200907)


--- trunk/Source/WebCore/page/DOMWindow.cpp	2016-05-14 02:03:10 UTC (rev 200906)
+++ trunk/Source/WebCore/page/DOMWindow.cpp	2016-05-14 02:10:27 UTC (rev 200907)
@@ -1493,8 +1493,13 @@
     return page->deviceScaleFactor();
 }
 
-void DOMWindow::scrollBy(int x, int y) const
+void DOMWindow::scrollBy(const ScrollToOptions& options) const
 {
+    return scrollBy(options.left.valueOr(0), options.top.valueOr(0));
+}
+
+void DOMWindow::scrollBy(double x, double y) const
+{
     if (!isCurrentlyDisplayedInFrame())
         return;
 
@@ -1504,12 +1509,27 @@
     if (!view)
         return;
 
+    // Normalize non-finite values (https://drafts.csswg.org/cssom-view/#normalize-non-finite-values).
+    x = std::isfinite(x) ? x : 0;
+    y = std::isfinite(y) ? y : 0;
+
     IntSize scaledOffset(view->mapFromCSSToLayoutUnits(x), view->mapFromCSSToLayoutUnits(y));
     view->setContentsScrollPosition(view->contentsScrollPosition() + scaledOffset);
 }
 
-void DOMWindow::scrollTo(int x, int y) const
+void DOMWindow::scrollTo(const ScrollToOptions& options) const
 {
+    RefPtr<FrameView> view = m_frame->view();
+    if (!view)
+        return;
+
+    double x = options.left ? options.left.value() : view->contentsScrollPosition().x();
+    double y = options.top ? options.top.value() : view->contentsScrollPosition().y();
+    return scrollTo(x, y);
+}
+
+void DOMWindow::scrollTo(double x, double y) const
+{
     if (!isCurrentlyDisplayedInFrame())
         return;
 
@@ -1517,6 +1537,10 @@
     if (!view)
         return;
 
+    // Normalize non-finite values (https://drafts.csswg.org/cssom-view/#normalize-non-finite-values).
+    x = std::isfinite(x) ? x : 0;
+    y = std::isfinite(y) ? y : 0;
+
     if (!x && !y && view->contentsScrollPosition() == IntPoint(0, 0))
         return;
 

Modified: trunk/Source/WebCore/page/DOMWindow.h (200906 => 200907)


--- trunk/Source/WebCore/page/DOMWindow.h	2016-05-14 02:03:10 UTC (rev 200906)
+++ trunk/Source/WebCore/page/DOMWindow.h	2016-05-14 02:10:27 UTC (rev 200907)
@@ -248,10 +248,16 @@
         void postMessageTimerFired(PostMessageTimer&);
         void dispatchMessageEventWithOriginCheck(SecurityOrigin* intendedTargetOrigin, Event&, PassRefPtr<Inspector::ScriptCallStack>);
 
-        void scrollBy(int x, int y) const;
-        void scrollTo(int x, int y) const;
-        void scroll(int x, int y) const { scrollTo(x, y); }
+        struct ScrollToOptions {
+            Optional<double> left;
+            Optional<double> top;
+        };
 
+        void scrollBy(const ScrollToOptions&) const;
+        void scrollBy(double x, double y) const;
+        void scrollTo(const ScrollToOptions&) const;
+        void scrollTo(double x, double y) const;
+
         void moveBy(float x, float y) const;
         void moveTo(float x, float y) const;
 

Modified: trunk/Source/WebCore/page/DOMWindow.idl (200906 => 200907)


--- trunk/Source/WebCore/page/DOMWindow.idl	2016-05-14 02:03:10 UTC (rev 200906)
+++ trunk/Source/WebCore/page/DOMWindow.idl	2016-05-14 02:10:27 UTC (rev 200907)
@@ -102,9 +102,16 @@
     readonly attribute long pageXOffset;
     readonly attribute long pageYOffset;
 
-    void scrollBy(optional long x = 0, optional long y = 0);
-    void scrollTo(optional long x = 0, optional long y = 0);
-    void scroll(optional long x = 0, optional long y = 0);
+    void scrollBy(unrestricted double x, unrestricted double y);
+    void scrollTo(unrestricted double x, unrestricted double y);
+    [ImplementedAs=scrollTo] void scroll(unrestricted double x, unrestricted double y);
+
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
+    void scrollBy(optional ScrollToOptions option);
+    void scrollTo(optional ScrollToOptions options);
+    [ImplementedAs=scrollTo] void scroll(optional ScrollToOptions options);
+#endif
+
     void moveBy(optional unrestricted float x = NaN, optional unrestricted float y = NaN); // FIXME: this should take longs not floats.
     void moveTo(optional unrestricted float x = NaN, optional unrestricted float y = NaN); // FIXME: this should take longs not floats.
     void resizeBy(optional unrestricted float x = NaN, optional unrestricted float y = NaN); // FIXME: this should take longs not floats.
@@ -217,6 +224,12 @@
     [NotEnumerable, Conditional=PROXIMITY_EVENTS] attribute EventHandler onwebkitdeviceproximity;
 };
 
+// FIXME: Support ScrollBehavior.
+dictionary ScrollToOptions {
+    unrestricted double left;
+    unrestricted double top;
+};
+
 DOMWindow implements GlobalEventHandlers;
 DOMWindow implements WindowBase64;
 DOMWindow implements WindowEventHandlers;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to