<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[200907] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/200907">200907</a></dd>
<dt>Author</dt> <dd>cdumez@apple.com</dd>
<dt>Date</dt> <dd>2016-05-13 19:10:27 -0700 (Fri, 13 May 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>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 &quot;unrestricted double&quot; typing for x/y instead of
   &quot;long&quot;. 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&lt;TestObj::Dictionary&gt;):
* 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:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsfastdomWindowwindowscrollargumentsexpectedtxt">trunk/LayoutTests/fast/dom/Window/window-scroll-arguments-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastdomWindowwindowscrollargumentshtml">trunk/LayoutTests/fast/dom/Window/window-scroll-arguments.html</a></li>
<li><a href="#trunkLayoutTestsfastdomnonnumericvaluesnumericparametersexpectedtxt">trunk/LayoutTests/fast/dom/non-numeric-values-numeric-parameters-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastdomscripttestsnonnumericvaluesnumericparametersjs">trunk/LayoutTests/fast/dom/script-tests/non-numeric-values-numeric-parameters.js</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMConverth">trunk/Source/WebCore/bindings/js/JSDOMConvert.h</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptsCodeGeneratorJSpm">trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptstestJSJSTestObjcpp">trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptstestTestObjidl">trunk/Source/WebCore/bindings/scripts/test/TestObj.idl</a></li>
<li><a href="#trunkSourceWebCorepageDOMWindowcpp">trunk/Source/WebCore/page/DOMWindow.cpp</a></li>
<li><a href="#trunkSourceWebCorepageDOMWindowh">trunk/Source/WebCore/page/DOMWindow.h</a></li>
<li><a href="#trunkSourceWebCorepageDOMWindowidl">trunk/Source/WebCore/page/DOMWindow.idl</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (200906 => 200907)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-05-14 02:03:10 UTC (rev 200906)
+++ trunk/LayoutTests/ChangeLog        2016-05-14 02:10:27 UTC (rev 200907)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2016-05-13  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        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:
+
</ins><span class="cx"> 2016-05-13  Simon Fraser  &lt;simon.fraser@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         cross-fade() rendering doesn't match expectation
</span></span></pre></div>
<a id="trunkLayoutTestsfastdomWindowwindowscrollargumentsexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/dom/Window/window-scroll-arguments-expected.txt (200906 => 200907)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,4 +1,4 @@
</span><del>-This test makes sure that calling the window scrolling methods with less than 2 arguments treats the missing arguments as 0.
</del><ins>+This tests calling the window scrolling with only 1 argument
</ins><span class="cx"> 
</span><span class="cx"> On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
</span><span class="cx"> 
</span><span class="lines">@@ -9,9 +9,19 @@
</span><span class="cx"> Testing - scrollTo with 0 arguments
</span><span class="cx"> PASS window.scrollX is resetX
</span><span class="cx"> PASS window.scrollY is resetY
</span><del>-Testing - scrollTo with 1 argument
-PASS window.scrollX is resetX + x
</del><ins>+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
</ins><span class="cx"> PASS window.scrollY is resetY
</span><ins>+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
</ins><span class="cx"> Testing - scrollTo with more than 2 arguments
</span><span class="cx"> PASS window.scrollX is x
</span><span class="cx"> PASS window.scrollY is y
</span><span class="lines">@@ -21,9 +31,19 @@
</span><span class="cx"> Testing - scroll with 0 arguments
</span><span class="cx"> PASS window.scrollX is resetX
</span><span class="cx"> PASS window.scrollY is resetY
</span><del>-Testing - scroll with 1 argument
-PASS window.scrollX is resetX + x
</del><ins>+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
</ins><span class="cx"> PASS window.scrollY is resetY
</span><ins>+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
</ins><span class="cx"> Testing - scroll with more than 2 arguments
</span><span class="cx"> PASS window.scrollX is x
</span><span class="cx"> PASS window.scrollY is y
</span><span class="lines">@@ -33,9 +53,19 @@
</span><span class="cx"> Testing - scrollBy with 0 arguments
</span><span class="cx"> PASS window.scrollX is resetX
</span><span class="cx"> PASS window.scrollY is resetY
</span><ins>+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.
</ins><span class="cx"> Testing - scrollBy with 1 argument
</span><span class="cx"> PASS window.scrollX is resetX + x
</span><span class="cx"> PASS window.scrollY is resetY
</span><ins>+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
</ins><span class="cx"> Testing - scrollBy with more than 2 arguments
</span><span class="cx"> PASS window.scrollX is resetX + x
</span><span class="cx"> PASS window.scrollY is resetY + y
</span></span></pre></div>
<a id="trunkLayoutTestsfastdomWindowwindowscrollargumentshtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/dom/Window/window-scroll-arguments.html (200906 => 200907)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -24,8 +24,7 @@
</span><span class="cx"> 
</span><span class="cx">     reset();
</span><span class="cx"> 
</span><del>-    description(&quot;This test makes sure that calling the window scrolling\
-    methods with less than 2 arguments treats the missing arguments as 0.&quot;);
</del><ins>+    description(&quot;This tests calling the window scrolling with only 1 argument&quot;);
</ins><span class="cx"> 
</span><span class="cx">     // scrollTo /////////////////////////
</span><span class="cx">     debug('');
</span><span class="lines">@@ -37,12 +36,34 @@
</span><span class="cx">     shouldBe('window.scrollX', 'resetX');
</span><span class="cx">     shouldBe('window.scrollY', 'resetY');
</span><span class="cx">     reset();
</span><ins>+    window.scrollTo(x, y);
+    window.scrollTo();
+    shouldBe('window.scrollX', 'x');
+    shouldBe('window.scrollY', 'y');
+    reset();
</ins><span class="cx"> 
</span><del>-    debug(&quot;Testing - scrollTo with 1 argument&quot;);
-    window.scrollTo(x);
-    shouldBe('window.scrollX', 'resetX + x');
</del><ins>+    debug(&quot;Testing - scrollTo with 1 non-dictionary argument&quot;);
+    shouldThrow(&quot;scrollTo(0)&quot;);
+    reset();
+
+    debug(&quot;Testing - scrollTo with 1 dictionary argument&quot;);
+    window.scrollTo({ left: x });
+    shouldBe('window.scrollX', 'x');
</ins><span class="cx">     shouldBe('window.scrollY', 'resetY');
</span><span class="cx">     reset();
</span><ins>+    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();
</ins><span class="cx"> 
</span><span class="cx">     debug(&quot;Testing - scrollTo with more than 2 arguments&quot;);
</span><span class="cx">     window.scrollTo(x, y, 200, &quot;text&quot;);
</span><span class="lines">@@ -60,12 +81,34 @@
</span><span class="cx">     shouldBe('window.scrollX', 'resetX');
</span><span class="cx">     shouldBe('window.scrollY', 'resetY');
</span><span class="cx">     reset();
</span><ins>+    window.scroll(x, y);
+    window.scroll();
+    shouldBe('window.scrollX', 'x');
+    shouldBe('window.scrollY', 'y');
+    reset();
</ins><span class="cx"> 
</span><del>-    debug(&quot;Testing - scroll with 1 argument&quot;);
-    window.scroll(x);
-    shouldBe('window.scrollX', 'resetX + x');
</del><ins>+    debug(&quot;Testing - scroll with 1 non-dictionary argument&quot;);
+    shouldThrow(&quot;scroll(0)&quot;);
+    reset();
+
+    debug(&quot;Testing - scroll with 1 dictionary argument&quot;);
+    window.scroll({ left: x });
+    shouldBe('window.scrollX', 'x');
</ins><span class="cx">     shouldBe('window.scrollY', 'resetY');
</span><span class="cx">     reset();
</span><ins>+    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();
</ins><span class="cx"> 
</span><span class="cx">     debug(&quot;Testing - scroll with more than 2 arguments&quot;);
</span><span class="cx">     window.scroll(x, y, 200, &quot;text&quot;);
</span><span class="lines">@@ -83,12 +126,34 @@
</span><span class="cx">     shouldBe('window.scrollX', 'resetX');
</span><span class="cx">     shouldBe('window.scrollY', 'resetY');
</span><span class="cx">     reset();
</span><ins>+    window.scrollBy(x, y);
+    window.scrollBy();
+    shouldBe('window.scrollX', 'x');
+    shouldBe('window.scrollY', 'y');
+    reset();
</ins><span class="cx"> 
</span><ins>+    debug(&quot;Testing - scrollBy with 1 non-dictionary argument&quot;);
+    shouldThrow(&quot;scrollBy(0)&quot;);
+    reset();
+
</ins><span class="cx">     debug(&quot;Testing - scrollBy with 1 argument&quot;);
</span><del>-    window.scrollBy(x);
</del><ins>+    window.scrollBy({ left: x });
</ins><span class="cx">     shouldBe('window.scrollX', 'resetX + x');
</span><span class="cx">     shouldBe('window.scrollY', 'resetY');
</span><span class="cx">     reset();
</span><ins>+    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();
</ins><span class="cx"> 
</span><span class="cx">     debug(&quot;Testing - scrollBy with more than 2 arguments&quot;);
</span><span class="cx">     window.scrollBy(x, y, 200, &quot;text&quot;);
</span></span></pre></div>
<a id="trunkLayoutTestsfastdomnonnumericvaluesnumericparametersexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/dom/non-numeric-values-numeric-parameters-expected.txt (200906 => 200907)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -66,11 +66,11 @@
</span><span class="cx"> PASS nonNumericPolicy('document.createTreeWalker(document, x, null, false)') is 'any type allowed'
</span><span class="cx"> PASS nonNumericPolicy('document.createEvent(&quot;UIEvent&quot;).initUIEvent(&quot;a&quot;, false, false, null, x)') is 'any type allowed'
</span><span class="cx"> PASS nonNumericPolicy('window.scrollBy(x, 0)') is 'any type allowed'
</span><del>-PASS nonNumericPolicy('window.scrollBy(0, x)') is 'any type allowed'
</del><ins>+PASS nonNumericPolicy('window.scrollBy(0, x)') is 'any type allowed (but not omitted)'
</ins><span class="cx"> PASS nonNumericPolicy('window.scrollTo(x, 0)') is 'any type allowed'
</span><del>-PASS nonNumericPolicy('window.scrollTo(0, x)') is 'any type allowed'
</del><ins>+PASS nonNumericPolicy('window.scrollTo(0, x)') is 'any type allowed (but not omitted)'
</ins><span class="cx"> PASS nonNumericPolicy('window.scroll(x, 0)') is 'any type allowed'
</span><del>-PASS nonNumericPolicy('window.scroll(0, x)') is 'any type allowed'
</del><ins>+PASS nonNumericPolicy('window.scroll(0, x)') is 'any type allowed (but not omitted)'
</ins><span class="cx"> PASS nonNumericPolicy('window.moveBy(x, 0)') is 'any type allowed'
</span><span class="cx"> PASS nonNumericPolicy('window.moveBy(0, x)') is 'any type allowed'
</span><span class="cx"> PASS nonNumericPolicy('window.moveTo(x, 0)') is 'any type allowed'
</span></span></pre></div>
<a id="trunkLayoutTestsfastdomscripttestsnonnumericvaluesnumericparametersjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/dom/script-tests/non-numeric-values-numeric-parameters.js (200906 => 200907)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -344,11 +344,11 @@
</span><span class="cx"> // Window
</span><span class="cx"> 
</span><span class="cx"> shouldBe(&quot;nonNumericPolicy('window.scrollBy(x, 0)')&quot;, &quot;'any type allowed'&quot;);
</span><del>-shouldBe(&quot;nonNumericPolicy('window.scrollBy(0, x)')&quot;, &quot;'any type allowed'&quot;);
</del><ins>+shouldBe(&quot;nonNumericPolicy('window.scrollBy(0, x)')&quot;, &quot;'any type allowed (but not omitted)'&quot;);
</ins><span class="cx"> shouldBe(&quot;nonNumericPolicy('window.scrollTo(x, 0)')&quot;, &quot;'any type allowed'&quot;);
</span><del>-shouldBe(&quot;nonNumericPolicy('window.scrollTo(0, x)')&quot;, &quot;'any type allowed'&quot;);
</del><ins>+shouldBe(&quot;nonNumericPolicy('window.scrollTo(0, x)')&quot;, &quot;'any type allowed (but not omitted)'&quot;);
</ins><span class="cx"> shouldBe(&quot;nonNumericPolicy('window.scroll(x, 0)')&quot;, &quot;'any type allowed'&quot;);
</span><del>-shouldBe(&quot;nonNumericPolicy('window.scroll(0, x)')&quot;, &quot;'any type allowed'&quot;);
</del><ins>+shouldBe(&quot;nonNumericPolicy('window.scroll(0, x)')&quot;, &quot;'any type allowed (but not omitted)'&quot;);
</ins><span class="cx"> shouldBe(&quot;nonNumericPolicy('window.moveBy(x, 0)')&quot;, &quot;'any type allowed'&quot;);
</span><span class="cx"> shouldBe(&quot;nonNumericPolicy('window.moveBy(0, x)')&quot;, &quot;'any type allowed'&quot;);
</span><span class="cx"> shouldBe(&quot;nonNumericPolicy('window.moveTo(x, 0)')&quot;, &quot;'any type allowed'&quot;);
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (200906 => 200907)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,3 +1,55 @@
</span><ins>+2016-05-13  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        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 &quot;unrestricted double&quot; typing for x/y instead of
+           &quot;long&quot;. 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&lt;TestObj::Dictionary&gt;):
+        * bindings/scripts/test/TestObj.idl:
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::scrollBy):
+        (WebCore::DOMWindow::scrollTo):
+        * page/DOMWindow.h:
+        * page/DOMWindow.idl:
+
</ins><span class="cx"> 2016-05-13  Commit Queue  &lt;commit-queue@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r200894.
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMConverth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMConvert.h (200906 => 200907)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -32,7 +32,7 @@
</span><span class="cx"> 
</span><span class="cx"> enum class ShouldAllowNonFinite { No, Yes };
</span><span class="cx"> 
</span><del>-template&lt;typename T&gt; struct Converter;
</del><ins>+template&lt;typename T, typename Enable = void&gt; struct Converter;
</ins><span class="cx"> 
</span><span class="cx"> template&lt;typename T&gt; T convert(JSC::ExecState&amp;, JSC::JSValue);
</span><span class="cx"> template&lt;typename T&gt; T convert(JSC::ExecState&amp;, JSC::JSValue, IntegerConversionConfiguration);
</span><span class="lines">@@ -41,6 +41,9 @@
</span><span class="cx"> template&lt;typename T&gt; typename Converter&lt;T&gt;::OptionalValue convertOptional(JSC::ExecState&amp;, JSC::JSValue);
</span><span class="cx"> template&lt;typename T, typename U&gt; T convertOptional(JSC::ExecState&amp;, JSC::JSValue, U&amp;&amp; defaultValue);
</span><span class="cx"> 
</span><ins>+template&lt;typename T&gt; typename Converter&lt;T&gt;::OptionalValue convertOptional(JSC::ExecState&amp;, JSC::JSValue, ShouldAllowNonFinite);
+template&lt;typename T, typename U&gt; T convertOptional(JSC::ExecState&amp;, JSC::JSValue, ShouldAllowNonFinite, U&amp;&amp; defaultValue);
+
</ins><span class="cx"> // This is where the implementation of the things declared above begins:
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename T&gt; T convert(JSC::ExecState&amp; state, JSC::JSValue value)
</span><span class="lines">@@ -56,10 +59,7 @@
</span><span class="cx"> template&lt;typename T&gt; inline T convert(JSC::ExecState&amp; state, JSC::JSValue value, ShouldAllowNonFinite allow)
</span><span class="cx"> {
</span><span class="cx">     static_assert(std::is_same&lt;T, float&gt;::value || std::is_same&lt;T, double&gt;::value, &quot;ShouldAllowNonFinite can only be used with float or double&quot;);
</span><del>-    double number = value.toNumber(&amp;state);
-    if (allow == ShouldAllowNonFinite::No &amp;&amp; UNLIKELY(!std::isfinite(number)))
-        throwNonFiniteTypeError(state);
-    return static_cast&lt;T&gt;(number);
</del><ins>+    return Converter&lt;T&gt;::convert(state, value, allow);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename T&gt; typename Converter&lt;T&gt;::OptionalValue inline convertOptional(JSC::ExecState&amp; state, JSC::JSValue value)
</span><span class="lines">@@ -72,11 +72,21 @@
</span><span class="cx">     return value.isUndefined() ? std::forward&lt;U&gt;(defaultValue) : convert&lt;T&gt;(state, value);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+template&lt;typename T&gt; typename Converter&lt;T&gt;::OptionalValue inline convertOptional(JSC::ExecState&amp; state, JSC::JSValue value, ShouldAllowNonFinite allow)
+{
+    return value.isUndefined() ? typename Converter&lt;T&gt;::OptionalValue() : convert&lt;T&gt;(state, value, allow);
+}
+
+template&lt;typename T, typename U&gt; inline T convertOptional(JSC::ExecState&amp; state, JSC::JSValue value, ShouldAllowNonFinite allow, U&amp;&amp; defaultValue)
+{
+    return value.isUndefined() ? std::forward&lt;U&gt;(defaultValue) : convert&lt;T&gt;(state, value, allow);
+}
+
</ins><span class="cx"> template&lt;typename T&gt; struct DefaultConverter {
</span><span class="cx">     using OptionalValue = Optional&lt;T&gt;;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-template&lt;typename T&gt; struct Converter : DefaultConverter&lt;T&gt; {
</del><ins>+template&lt;typename T, typename Enable&gt; struct Converter : DefaultConverter&lt;T&gt; {
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> template&lt;&gt; struct Converter&lt;bool&gt; : DefaultConverter&lt;bool&gt; {
</span><span class="lines">@@ -228,4 +238,14 @@
</span><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+template&lt;typename T&gt; struct Converter&lt;T, typename std::enable_if&lt;std::is_floating_point&lt;T&gt;::value&gt;::type&gt; : DefaultConverter&lt;T&gt; {
+    static T convert(JSC::ExecState&amp; state, JSC::JSValue value, ShouldAllowNonFinite allow)
+    {
+        double number = value.toNumber(&amp;state);
+        if (allow == ShouldAllowNonFinite::No &amp;&amp; UNLIKELY(!std::isfinite(number)))
+            throwNonFiniteTypeError(state);
+        return static_cast&lt;T&gt;(number);
+    }
+};
+
</ins><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptsCodeGeneratorJSpm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (200906 => 200907)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -958,6 +958,25 @@
</span><span class="cx">     return $value;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+sub ShouldAllowNonFiniteForFloatingPointType
+{
+    my $type = shift;
+
+    die &quot;Can only be called with floating point types&quot; unless $codeGenerator-&gt;IsFloatingPointType($type);
+    return $type eq &quot;unrestricted double&quot; || $type eq &quot;unrestricted float&quot;;
+}
+
+sub GenerateConversionRuleWithLeadingComma
+{
+    my ($interface, $member) = @_;
+
+    if ($codeGenerator-&gt;IsFloatingPointType($member-&gt;type)) {
+        return &quot;, &quot; . (ShouldAllowNonFiniteForFloatingPointType($member-&gt;type) ? &quot;ShouldAllowNonFinite::Yes&quot; : &quot;ShouldAllowNonFinite::No&quot;);
+    }
+    # FIXME: Add support for integer types.
+    return &quot;&quot;;
+}
+
</ins><span class="cx"> sub GenerateDefaultValueWithLeadingComma
</span><span class="cx"> {
</span><span class="cx">     my ($interface, $member) = @_;
</span><span class="lines">@@ -1011,9 +1030,9 @@
</span><span class="cx">             }
</span><span class="cx">             # FIXME: Eventually we will want this to share a lot more code with JSValueToNative.
</span><span class="cx">             my $function = $member-&gt;isOptional ? &quot;convertOptional&quot; : &quot;convert&quot;;
</span><del>-            my $defaultValueWithLeadingComma = $member-&gt;isOptional &amp;&amp; defined $member-&gt;default ? &quot;, &quot; . $member-&gt;default : &quot;&quot;;
</del><span class="cx">             $result .= &quot;    auto &quot; . $member-&gt;name . &quot; = &quot; . $function . &quot;&lt;&quot; . GetNativeTypeFromSignature($interface, $member) . &quot;&gt;&quot;
</span><span class="cx">                 . &quot;(state, object-&gt;get(&amp;state, Identifier::fromString(&amp;state, \&quot;&quot; . $member-&gt;name . &quot;\&quot;))&quot;
</span><ins>+                . GenerateConversionRuleWithLeadingComma($interface, $member)
</ins><span class="cx">                 . GenerateDefaultValueWithLeadingComma($interface, $member) . &quot;);\n&quot;;
</span><span class="cx">             $needExceptionCheck = 1;
</span><span class="cx">         }
</span><span class="lines">@@ -4425,11 +4444,9 @@
</span><span class="cx"> 
</span><span class="cx">     if ($codeGenerator-&gt;IsFloatingPointType($type)) {
</span><span class="cx">         AddToImplIncludes(&quot;JSDOMConvert.h&quot;);
</span><del>-        return (&quot;convert&lt;double&gt;(*state, $value, ShouldAllowNonFinite::No)&quot;, 1) if $type eq &quot;double&quot;;
-        return (&quot;convert&lt;double&gt;(*state, $value, ShouldAllowNonFinite::Yes)&quot;, 1) if $type eq &quot;unrestricted double&quot;;
-        return (&quot;convert&lt;float&gt;(*state, $value, ShouldAllowNonFinite::No)&quot;, 1) if $type eq &quot;float&quot;;
-        return (&quot;convert&lt;float&gt;(*state, $value, ShouldAllowNonFinite::Yes)&quot;, 1) if $type eq &quot;unrestricted float&quot;;
-        die &quot;Unhandled floating point type: &quot; . $type;
</del><ins>+        my $allowNonFinite = ShouldAllowNonFiniteForFloatingPointType($type) ? &quot;ShouldAllowNonFinite::Yes&quot; : &quot;ShouldAllowNonFinite::No&quot;;
+        my $nativeType = GetNativeType($interface, $type);
+        return (&quot;convert&lt;$nativeType&gt;(*state, $value, $allowNonFinite)&quot;, 1);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return (&quot;valueToDate(state, $value)&quot;, 1) if $type eq &quot;Date&quot;;
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptstestJSJSTestObjcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp (200906 => 200907)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -455,7 +455,7 @@
</span><span class="cx"> template&lt;&gt; TestObj::Dictionary convert&lt;TestObj::Dictionary&gt;(ExecState&amp; state, JSValue value)
</span><span class="cx"> {
</span><span class="cx">     if (value.isUndefinedOrNull())
</span><del>-        return { { }, TestObj::EnumType::EnumValue1, TestObj::EnumType::EmptyString, &quot;defaultString&quot;, { }, false, { }, { } };
</del><ins>+        return { { }, TestObj::EnumType::EnumValue1, TestObj::EnumType::EmptyString, &quot;defaultString&quot;, { }, false, { }, { }, { }, { }, 0, 0, { }, { }, 0, 0 };
</ins><span class="cx">     auto* object = value.getObject();
</span><span class="cx">     if (UNLIKELY(!object || object-&gt;type() == RegExpObjectType)) {
</span><span class="cx">         throwTypeError(&amp;state);
</span><span class="lines">@@ -483,7 +483,31 @@
</span><span class="cx">     if (UNLIKELY(state.hadException()))
</span><span class="cx">         return { };
</span><span class="cx">     auto sequenceOfStrings = convertOptional&lt;Vector&lt;String&gt;&gt;(state, object-&gt;get(&amp;state, Identifier::fromString(&amp;state, &quot;sequenceOfStrings&quot;)));
</span><del>-    return { WTFMove(enumerationValueWithoutDefault), WTFMove(enumerationValueWithDefault), WTFMove(enumerationValueWithEmptyStringDefault), WTFMove(stringWithDefault), WTFMove(stringWithoutDefault), WTFMove(booleanWithDefault), WTFMove(booleanWithoutDefault), WTFMove(sequenceOfStrings) };
</del><ins>+    if (UNLIKELY(state.hadException()))
+        return { };
+    auto restrictedDouble = convertOptional&lt;double&gt;(state, object-&gt;get(&amp;state, Identifier::fromString(&amp;state, &quot;restrictedDouble&quot;)), ShouldAllowNonFinite::No);
+    if (UNLIKELY(state.hadException()))
+        return { };
+    auto unrestrictedDouble = convertOptional&lt;double&gt;(state, object-&gt;get(&amp;state, Identifier::fromString(&amp;state, &quot;unrestrictedDouble&quot;)), ShouldAllowNonFinite::Yes);
+    if (UNLIKELY(state.hadException()))
+        return { };
+    auto restrictedDoubleWithDefault = convertOptional&lt;double&gt;(state, object-&gt;get(&amp;state, Identifier::fromString(&amp;state, &quot;restrictedDoubleWithDefault&quot;)), ShouldAllowNonFinite::No, 0);
+    if (UNLIKELY(state.hadException()))
+        return { };
+    auto unrestrictedDoubleWithDefault = convertOptional&lt;double&gt;(state, object-&gt;get(&amp;state, Identifier::fromString(&amp;state, &quot;unrestrictedDoubleWithDefault&quot;)), ShouldAllowNonFinite::Yes, 0);
+    if (UNLIKELY(state.hadException()))
+        return { };
+    auto restrictedFloat = convertOptional&lt;float&gt;(state, object-&gt;get(&amp;state, Identifier::fromString(&amp;state, &quot;restrictedFloat&quot;)), ShouldAllowNonFinite::No);
+    if (UNLIKELY(state.hadException()))
+        return { };
+    auto unrestrictedFloat = convertOptional&lt;float&gt;(state, object-&gt;get(&amp;state, Identifier::fromString(&amp;state, &quot;unrestrictedFloat&quot;)), ShouldAllowNonFinite::Yes);
+    if (UNLIKELY(state.hadException()))
+        return { };
+    auto restrictedFloatWithDefault = convertOptional&lt;float&gt;(state, object-&gt;get(&amp;state, Identifier::fromString(&amp;state, &quot;restrictedFloatWithDefault&quot;)), ShouldAllowNonFinite::No, 0);
+    if (UNLIKELY(state.hadException()))
+        return { };
+    auto unrestrictedFloatWithDefault = convertOptional&lt;float&gt;(state, object-&gt;get(&amp;state, Identifier::fromString(&amp;state, &quot;unrestrictedFloatWithDefault&quot;)), 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) };
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template&lt;&gt; TestObj::DictionaryThatShouldNotTolerateNull convert&lt;TestObj::DictionaryThatShouldNotTolerateNull&gt;(ExecState&amp; state, JSValue value)
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptstestTestObjidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/test/TestObj.idl (200906 => 200907)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -391,6 +391,14 @@
</span><span class="cx">     boolean booleanWithDefault = false;
</span><span class="cx">     boolean booleanWithoutDefault;
</span><span class="cx">     sequence&lt;DOMString&gt; sequenceOfStrings;
</span><ins>+    double restrictedDouble;
+    unrestricted double unrestrictedDouble;
+    double restrictedDoubleWithDefault = 0;
+    unrestricted double unrestrictedDoubleWithDefault = 0;
+    float restrictedFloat;
+    unrestricted float unrestrictedFloat;
+    float restrictedFloatWithDefault = 0;
+    unrestricted float unrestrictedFloatWithDefault = 0;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> dictionary TestDictionaryThatShouldNotTolerateNull {
</span></span></pre></div>
<a id="trunkSourceWebCorepageDOMWindowcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/DOMWindow.cpp (200906 => 200907)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1493,8 +1493,13 @@
</span><span class="cx">     return page-&gt;deviceScaleFactor();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void DOMWindow::scrollBy(int x, int y) const
</del><ins>+void DOMWindow::scrollBy(const ScrollToOptions&amp; options) const
</ins><span class="cx"> {
</span><ins>+    return scrollBy(options.left.valueOr(0), options.top.valueOr(0));
+}
+
+void DOMWindow::scrollBy(double x, double y) const
+{
</ins><span class="cx">     if (!isCurrentlyDisplayedInFrame())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="lines">@@ -1504,12 +1509,27 @@
</span><span class="cx">     if (!view)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    // 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;
+
</ins><span class="cx">     IntSize scaledOffset(view-&gt;mapFromCSSToLayoutUnits(x), view-&gt;mapFromCSSToLayoutUnits(y));
</span><span class="cx">     view-&gt;setContentsScrollPosition(view-&gt;contentsScrollPosition() + scaledOffset);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void DOMWindow::scrollTo(int x, int y) const
</del><ins>+void DOMWindow::scrollTo(const ScrollToOptions&amp; options) const
</ins><span class="cx"> {
</span><ins>+    RefPtr&lt;FrameView&gt; view = m_frame-&gt;view();
+    if (!view)
+        return;
+
+    double x = options.left ? options.left.value() : view-&gt;contentsScrollPosition().x();
+    double y = options.top ? options.top.value() : view-&gt;contentsScrollPosition().y();
+    return scrollTo(x, y);
+}
+
+void DOMWindow::scrollTo(double x, double y) const
+{
</ins><span class="cx">     if (!isCurrentlyDisplayedInFrame())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="lines">@@ -1517,6 +1537,10 @@
</span><span class="cx">     if (!view)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    // 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;
+
</ins><span class="cx">     if (!x &amp;&amp; !y &amp;&amp; view-&gt;contentsScrollPosition() == IntPoint(0, 0))
</span><span class="cx">         return;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorepageDOMWindowh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/DOMWindow.h (200906 => 200907)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -248,10 +248,16 @@
</span><span class="cx">         void postMessageTimerFired(PostMessageTimer&amp;);
</span><span class="cx">         void dispatchMessageEventWithOriginCheck(SecurityOrigin* intendedTargetOrigin, Event&amp;, PassRefPtr&lt;Inspector::ScriptCallStack&gt;);
</span><span class="cx"> 
</span><del>-        void scrollBy(int x, int y) const;
-        void scrollTo(int x, int y) const;
-        void scroll(int x, int y) const { scrollTo(x, y); }
</del><ins>+        struct ScrollToOptions {
+            Optional&lt;double&gt; left;
+            Optional&lt;double&gt; top;
+        };
</ins><span class="cx"> 
</span><ins>+        void scrollBy(const ScrollToOptions&amp;) const;
+        void scrollBy(double x, double y) const;
+        void scrollTo(const ScrollToOptions&amp;) const;
+        void scrollTo(double x, double y) const;
+
</ins><span class="cx">         void moveBy(float x, float y) const;
</span><span class="cx">         void moveTo(float x, float y) const;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorepageDOMWindowidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/DOMWindow.idl (200906 => 200907)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -102,9 +102,16 @@
</span><span class="cx">     readonly attribute long pageXOffset;
</span><span class="cx">     readonly attribute long pageYOffset;
</span><span class="cx"> 
</span><del>-    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);
</del><ins>+    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) &amp;&amp; LANGUAGE_JAVASCRIPT
+    void scrollBy(optional ScrollToOptions option);
+    void scrollTo(optional ScrollToOptions options);
+    [ImplementedAs=scrollTo] void scroll(optional ScrollToOptions options);
+#endif
+
</ins><span class="cx">     void moveBy(optional unrestricted float x = NaN, optional unrestricted float y = NaN); // FIXME: this should take longs not floats.
</span><span class="cx">     void moveTo(optional unrestricted float x = NaN, optional unrestricted float y = NaN); // FIXME: this should take longs not floats.
</span><span class="cx">     void resizeBy(optional unrestricted float x = NaN, optional unrestricted float y = NaN); // FIXME: this should take longs not floats.
</span><span class="lines">@@ -217,6 +224,12 @@
</span><span class="cx">     [NotEnumerable, Conditional=PROXIMITY_EVENTS] attribute EventHandler onwebkitdeviceproximity;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+// FIXME: Support ScrollBehavior.
+dictionary ScrollToOptions {
+    unrestricted double left;
+    unrestricted double top;
+};
+
</ins><span class="cx"> DOMWindow implements GlobalEventHandlers;
</span><span class="cx"> DOMWindow implements WindowBase64;
</span><span class="cx"> DOMWindow implements WindowEventHandlers;
</span></span></pre>
</div>
</div>

</body>
</html>