[SCM] WebKit Debian packaging branch, webkit-1.3, updated. upstream/1.3.7-4207-g178b198

mihaip at chromium.org mihaip at chromium.org
Sun Feb 20 22:49:32 UTC 2011


The following commit has been merged in the webkit-1.3 branch:
commit 5ed30ae156b40b70bb24381fb656532d449ca313
Author: mihaip at chromium.org <mihaip at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Jan 11 22:47:10 2011 +0000

    2011-01-11  Mihai Parparita  <mihaip at chromium.org>
    
            Reviewed by Darin Fisher.
    
            Scroll event should be fired asynchronously
            https://bugs.webkit.org/show_bug.cgi?id=45631
    
            Update existing tests that assumed that scroll events fired
            synchronously.
    
            * editing/input/page-up-down-scrolls-expected.txt:
            * editing/input/page-up-down-scrolls.html:
            * fast/events/fire-scroll-event-element-expected.txt: Copied from LayoutTests/fast/events/fire-scroll-event-expected.txt.
            * fast/events/fire-scroll-event-element.html: Added. Does the same
                tests as fire-scroll-event.html, but on an individual element instead
                of the whole document.
            * fast/events/fire-scroll-event-expected.txt:
            * fast/events/fire-scroll-event.html: Now explicitly tests for
                synchronous behavior when scrolling the document, and that we don't
                fire the event more than once.
            * fast/events/remove-child-onscroll.html:
            * fast/events/scroll-during-zoom-change.html:
            * fast/events/scroll-event-does-not-bubble.html:
            * fast/events/scroll-event-phase-expected.txt: Added.
            * fast/events/scroll-event-phase.html: Added. Checks that we can listen
                for scroll events in both the capture and bubble phase.
            * fast/layers/removed-by-scroll-handler.html:
            * fast/overflow/onscroll-layer-self-destruct.html:
            * fast/repaint/repaint-during-scroll.html:
    2011-01-11  Mihai Parparita  <mihaip at chromium.org>
    
            Reviewed by Darin Fisher.
    
            Scroll event should be fired asynchronously
            https://bugs.webkit.org/show_bug.cgi?id=45631
    
            Tests: fast/events/fire-scroll-event.html
                   fast/events/fire-scroll-event-element.html
                   fast/events/scroll-event-phase.html
    
            Makes scroll events fire asynchronously to be in compliance with the
            CSSOM View Module and consistent with Gecko, Opera and (to some degree)
            IE.
    
            Implemented via the EventQueue class added by r74062 (EventQueue now
            has a convenience enqueueScrollEvent method).
    
            * dom/EventQueue.cpp:
            (WebCore::EventQueue::enqueueScrollEvent):
            (WebCore::EventQueue::pendingEventTimerFired):
            * dom/EventQueue.h:
            * page/EventHandler.cpp:
            (WebCore::EventHandler::sendScrollEvent):
            * rendering/RenderLayer.cpp:
            (WebCore::RenderLayer::scrollToOffset):
            * rendering/RenderListBox.cpp:
            (WebCore::RenderListBox::valueChanged):
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@75555 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index e8ca425..27de42e 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,5 +1,35 @@
 2011-01-11  Mihai Parparita  <mihaip at chromium.org>
 
+        Reviewed by Darin Fisher.
+
+        Scroll event should be fired asynchronously
+        https://bugs.webkit.org/show_bug.cgi?id=45631
+        
+        Update existing tests that assumed that scroll events fired
+        synchronously.
+
+        * editing/input/page-up-down-scrolls-expected.txt:
+        * editing/input/page-up-down-scrolls.html:
+        * fast/events/fire-scroll-event-element-expected.txt: Copied from LayoutTests/fast/events/fire-scroll-event-expected.txt.
+        * fast/events/fire-scroll-event-element.html: Added. Does the same
+            tests as fire-scroll-event.html, but on an individual element instead
+            of the whole document.
+        * fast/events/fire-scroll-event-expected.txt:
+        * fast/events/fire-scroll-event.html: Now explicitly tests for
+            synchronous behavior when scrolling the document, and that we don't
+            fire the event more than once.
+        * fast/events/remove-child-onscroll.html:
+        * fast/events/scroll-during-zoom-change.html:
+        * fast/events/scroll-event-does-not-bubble.html:
+        * fast/events/scroll-event-phase-expected.txt: Added.
+        * fast/events/scroll-event-phase.html: Added. Checks that we can listen
+            for scroll events in both the capture and bubble phase.
+        * fast/layers/removed-by-scroll-handler.html:
+        * fast/overflow/onscroll-layer-self-destruct.html:
+        * fast/repaint/repaint-during-scroll.html:
+
+2011-01-11  Mihai Parparita  <mihaip at chromium.org>
+
         Unreviewed; new and updated mac-leopard baselines.
 
         Update stale or missing Leopard baselines (tests currently pass on Snow
diff --git a/LayoutTests/editing/input/page-up-down-scrolls-expected.txt b/LayoutTests/editing/input/page-up-down-scrolls-expected.txt
index 24dee4d..b5b0cf0 100644
--- a/LayoutTests/editing/input/page-up-down-scrolls-expected.txt
+++ b/LayoutTests/editing/input/page-up-down-scrolls-expected.txt
@@ -1,4 +1,4 @@
 xx
-This test simulates hitting page up and page down once each. Both keypresses should generate exactly one scroll event. This test requires DRT to pass.
+This test simulates hitting page up and page down once each. Both keypresses should generate exactly one scroll event. If running manually, press the keys now.
 PASS
 (just here to force scrollbars)
diff --git a/LayoutTests/editing/input/page-up-down-scrolls.html b/LayoutTests/editing/input/page-up-down-scrolls.html
index fc83b14..e5babc7 100644
--- a/LayoutTests/editing/input/page-up-down-scrolls.html
+++ b/LayoutTests/editing/input/page-up-down-scrolls.html
@@ -2,38 +2,41 @@
 <html>
 <head>
 <script>
-if (window.layoutTestController)
+if (window.layoutTestController) {
     layoutTestController.dumpAsText();
+    layoutTestController.waitUntilDone();
+}
 
-function scr()
-{
+var step = 0;
+
+onscroll = function() {
     document.getElementById('log').innerText += 'x';
+
+    switch (step) {
+    case 0:
+        if (window.eventSender)
+            eventSender.keyDown('pageUp');
+            break;
+    case 1:
+        document.getElementById('results').innerText = 'PASS';
+        if (window.layoutTestController)
+            layoutTestController.notifyDone();
+        break;
+    }
+    
+    step++;
 }
 
 function runTest()
 {
-    if (!window.eventSender)
-        return;
-
-    window.addEventListener('scroll', scr, false);
-
-    eventSender.keyDown("pageDown");
-    var text = document.getElementById('log').innerText;
-    if (text != "x")
-        throw "log should contain x, not " + text;
-
-    eventSender.keyDown("pageUp");
-    var text = document.getElementById('log').innerText;
-    if (text != "xx")
-        throw "log should contain xx, not " + text;
-
-    document.getElementById("results").innerText = "PASS";
+    if (window.eventSender)
+        eventSender.keyDown('pageDown');
 }
 </script>
 </head>
 <body onload="runTest()"> 
 <span id="log" style="position:fixed"></span> 
-<div>This test simulates hitting page up and page down once each. Both keypresses should generate exactly one scroll event. This test requires DRT to pass.</div>
+<div>This test simulates hitting page up and page down once each. Both keypresses should generate exactly one scroll event. If running manually, press the keys now.</div>
 <div id="results">FAIL</div>
 <div style="height:50000px">(just here to force scrollbars)</div> 
 <script> 
diff --git a/LayoutTests/fast/events/fire-scroll-event-element-expected.txt b/LayoutTests/fast/events/fire-scroll-event-element-expected.txt
new file mode 100644
index 0000000..cfe6a56
--- /dev/null
+++ b/LayoutTests/fast/events/fire-scroll-event-element-expected.txt
@@ -0,0 +1,11 @@
+Checks that the scroll event fires on elements asychronously and only once.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Scroll event bubbles: false
+PASS Scroll position: (0, 200)
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/events/fire-scroll-event-element.html b/LayoutTests/fast/events/fire-scroll-event-element.html
new file mode 100644
index 0000000..7c98bad
--- /dev/null
+++ b/LayoutTests/fast/events/fire-scroll-event-element.html
@@ -0,0 +1,51 @@
+<html>
+<link rel="stylesheet" href="../js/resources/js-test-style.css">
+<script src="../js/resources/js-test-pre.js"></script>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<div id="container" style="overflow: auto; width: 500px; height: 500px">
+  <div style="height: 5000px; width: 5000px;"></div>
+</div>
+<script>
+description('Checks that the scroll event fires on elements asychronously and only once.');
+
+var eventCount = 0;
+var doneTimeout;
+
+function scrollHandler(event)
+{
+    eventCount++;
+    if (eventCount == 1) {
+        debug('Scroll event bubbles: ' + event.bubbles);
+        var container = document.getElementById('container');
+        var scrollX = container.scrollLeft;
+        var scrollY = container.scrollTop;
+        testPassed('Scroll position: (' + scrollX + ', ' + scrollY + ')');
+        // Don't call notifyDone straight away, in case there's another scroll event coming.
+        doneTimeout = setTimeout(finishJSTest, 100);
+    } else {
+        clearTimeout(doneTimeout);
+        testFailed('Scroll handler was invoked ' + eventCount + ' times');
+        finishJSTest();
+    }
+}
+
+onload = function()
+{
+    var container = document.getElementById('container');
+    container.addEventListener('scroll', scrollHandler, false);
+    container.scrollTop = 100;
+    if (eventCount > 0) {
+      testFailed('Scroll event fired synchronously');
+      finishJSTest();
+    }
+    container.scrollTop = 200;
+}
+
+var successfullyParsed = true;
+var jsTestIsAsync = true;
+</script>
+<script src="../js/resources/js-test-post.js"></script>
+</body>
+</html>
\ No newline at end of file
diff --git a/LayoutTests/fast/events/fire-scroll-event-expected.txt b/LayoutTests/fast/events/fire-scroll-event-expected.txt
index 1686ced..e766669 100644
--- a/LayoutTests/fast/events/fire-scroll-event-expected.txt
+++ b/LayoutTests/fast/events/fire-scroll-event-expected.txt
@@ -1,59 +1,11 @@
-PASSED
+Checks that the scroll event fires on the document asychronously and only once.
 
-If the word 'PASSED' does not appear above, then the test has failed. If the test fails, it means that a scroll event did not fire.
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
-a
+
+Scroll event bubbles: true
+PASS Scroll position: (200, 200)
+PASS successfullyParsed is true
+
+TEST COMPLETE
 
diff --git a/LayoutTests/fast/events/fire-scroll-event.html b/LayoutTests/fast/events/fire-scroll-event.html
index a056c06..8170b12 100644
--- a/LayoutTests/fast/events/fire-scroll-event.html
+++ b/LayoutTests/fast/events/fire-scroll-event.html
@@ -1,30 +1,45 @@
 <html>
+<link rel="stylesheet" href="../js/resources/js-test-style.css">
+<script src="../js/resources/js-test-pre.js"></script>
+<body style="min-width: 5000px; min-height: 5000px">
+<p id="description"></p>
+<div id="console"></div>
 <script>
-var eventFired = false;
+description('Checks that the scroll event fires on the document asychronously and only once.');
 
-function scroller() {
-    if (!eventFired) {
-        eventFired = true;
-        document.getElementById("passed").innerHTML = "<p style='color:red'>PASSED</p>";
+var eventCount = 0;
+var doneTimeout;
+
+onscroll = function(event)
+{
+    eventCount++;
+    if (eventCount == 1) {
+        debug('Scroll event bubbles: ' + event.bubbles);
+        var scrollX = document.body.scrollLeft;
+        var scrollY = document.body.scrollTop;
+        testPassed('Scroll position: (' + scrollX + ', ' + scrollY + ')');
+        // Don't call notifyDone straight away, in case there's another scroll event coming.
+        doneTimeout = setTimeout(finishJSTest, 100);
+    } else {
+        clearTimeout(doneTimeout);
+        testFailed('Scroll handler was invoked ' + eventCount + ' times');
+        finishJSTest();
     }
 }
 
-window.onload = function() {
-    window.addEventListener('scroll', scroller, false);
-    window.scrollTo(500, 500);
-    if (window.layoutTestController) {
-        layoutTestController.dumpAsText();
+onload = function()
+{
+    window.scrollTo(100, 100);
+    if (eventCount > 0) {
+        testFailed('Scroll event fired synchronously');
+        finishJSTest();
     }
+    window.scrollTo(200, 200);
 }
 
+var successfullyParsed = true;
+var jsTestIsAsync = true;
 </script>
-<body>
-<div id="passed"></div>
-
-<p>If the word 'PASSED' does not appear above, then the test has failed. If the test fails, it means that a scroll event did not fire.</p>
-
-a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>
-a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>
-a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>
+<script src="../js/resources/js-test-post.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/LayoutTests/fast/events/remove-child-onscroll.html b/LayoutTests/fast/events/remove-child-onscroll.html
index 252cfea..109a5d6 100644
--- a/LayoutTests/fast/events/remove-child-onscroll.html
+++ b/LayoutTests/fast/events/remove-child-onscroll.html
@@ -9,17 +9,28 @@
             function dispatchScrollEvents()
             {
                 if (window.eventSender && window.layoutTestController) {
+                    layoutTestController.waitUntilDone();
                     eventSender.mouseMoveTo(100, 100);
                     eventSender.mouseScrollBy(0, -1);
-                    eventSender.mouseScrollBy(-1, -1);
-                    layoutTestController.notifyDone();
+                    var scrollCount = 0;
+                    document.getElementById('dv').addEventListener(
+                        'scroll',
+                        function(event) {
+                            this.removeChild(this.firstChild);
+                            scrollCount++;
+                            if (scrollCount == 1)
+                                eventSender.mouseScrollBy(-1, -1);
+                            else
+                                layoutTestController.notifyDone();
+                        },
+                        false);
                 }
             }
         </script>
     </head>
     <body onload="setTimeout('dispatchScrollEvents();', 1);">
         This test verifies that children can be removed by their parent element's onscroll event handler.  The test succeeds if this is the only text remaining after the two scroll events are dispatched.  The test fails if the inner div remains in the output or if WebKit crashes.<br><br>
-        <div id="dv" style="overflow: auto; width: 200px; height: 200px; whitespace: nowrap;" onscroll="this.removeChild(this.firstChild)">
+        <div id="dv" style="overflow: auto; width: 200px; height: 200px; whitespace: nowrap;">
         <div style="width:300px; height:300px">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum
         </div>
         </div>
diff --git a/LayoutTests/fast/events/scroll-during-zoom-change.html b/LayoutTests/fast/events/scroll-during-zoom-change.html
index 4fc1528..ae12a79 100644
--- a/LayoutTests/fast/events/scroll-during-zoom-change.html
+++ b/LayoutTests/fast/events/scroll-during-zoom-change.html
@@ -16,6 +16,9 @@
     function scrolled(event)
     {
         event.target.parentNode.removeChild(event.target);
+        if (window.layoutTestController) {
+            layoutTestController.notifyDone();
+        }
     }
 
     function test()
@@ -27,7 +30,9 @@
         document.body.style.zoom = 2;
     }
 
-    if (window.layoutTestController)
+    if (window.layoutTestController) {
         layoutTestController.dumpAsText();
+        layoutTestController.waitUntilDone();
+    }
     test();
 </script>
diff --git a/LayoutTests/fast/events/scroll-event-does-not-bubble.html b/LayoutTests/fast/events/scroll-event-does-not-bubble.html
index 222ada8..1e85113 100644
--- a/LayoutTests/fast/events/scroll-event-does-not-bubble.html
+++ b/LayoutTests/fast/events/scroll-event-does-not-bubble.html
@@ -1,11 +1,22 @@
 <html>
 <script>
+var windowWasScrolled = false;
+var doneTimeout;
+
 function windowScrolled() {
+    windowWasScrolled = true;
     document.getElementById('result').innerHTML = 'FAILURE: window.onscroll was called.'; 
+    clearTimeout(doneTimeout);    
 }
 
 function divScrolled() {
-    document.getElementById('result').innerHTML = 'SUCCESS: div.onscroll was called, but window.onscroll was not.'; 
+    if (!windowWasScrolled)
+        document.getElementById('result').innerHTML = 'SUCCESS: div.onscroll was called, but window.onscroll was not.'; 
+    // Don't call notifyDone straight away, in case there's another scroll event coming/bubbling.
+    doneTimeout = setTimeout(function() {
+        if (window.layoutTestController)
+            layoutTestController.notifyDone();
+        }, 100);    
 }
 
 function runTest() {
@@ -24,10 +35,6 @@ function runTest() {
     
     // Don't pollute the test result with nonsense.
     div.innerHTML = '';
-    
-    if (window.layoutTestController) 
-        layoutTestController.notifyDone();
-    
 }
 
 </script>
diff --git a/LayoutTests/fast/events/scroll-event-phase-expected.txt b/LayoutTests/fast/events/scroll-event-phase-expected.txt
new file mode 100644
index 0000000..3e94a30
--- /dev/null
+++ b/LayoutTests/fast/events/scroll-event-phase-expected.txt
@@ -0,0 +1,10 @@
+Tests that we can listen for scroll events on the document in both the capture and bubble phases.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Both capture and bubble phase listeners were invoked.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/events/scroll-event-phase.html b/LayoutTests/fast/events/scroll-event-phase.html
new file mode 100644
index 0000000..c0ce5c0
--- /dev/null
+++ b/LayoutTests/fast/events/scroll-event-phase.html
@@ -0,0 +1,45 @@
+<html>
+<link rel="stylesheet" href="../js/resources/js-test-style.css">
+<script src="../js/resources/js-test-pre.js"></script>
+<body style="min-height: 2000px"> 
+<p id="description"></p>
+<div id="console"></div>
+
+<script type="text/javascript">
+description('Tests that we can listen for scroll events on the document in both the capture and bubble phases.');
+
+var triggeredCaptureListener = false;
+var triggeredBubbleListener = false;
+
+window.addEventListener(
+    'scroll',
+    function() {
+        triggeredCaptureListener = true;
+        checkComplete();
+    },
+    true);
+
+window.addEventListener(
+    'scroll',
+    function(event) {
+        triggeredBubbleListener = true;
+        checkComplete();
+    },
+    false);
+
+function checkComplete()
+{
+    if (triggeredCaptureListener && triggeredBubbleListener) {
+        debug('Both capture and bubble phase listeners were invoked.');
+        finishJSTest();
+    }
+}
+
+window.scrollTo(200, 200);
+
+var successfullyParsed = true;
+var jsTestIsAsync = true;
+</script>
+<script src="../js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/layers/removed-by-scroll-handler.html b/LayoutTests/fast/layers/removed-by-scroll-handler.html
index ba1a351..d2f9ac6 100644
--- a/LayoutTests/fast/layers/removed-by-scroll-handler.html
+++ b/LayoutTests/fast/layers/removed-by-scroll-handler.html
@@ -11,29 +11,33 @@
 <p>
     Result: <span id="result">test did not complete.</span>
 </p>
-<div id="t" style="overflow: auto; width: 200px; height: 100px;" onscroll="if (overflowRemove) this.parentNode.removeChild(this);">
+<div id="t" style="overflow: auto; width: 200px; height: 100px;" onscroll="this.parentNode.removeChild(this);handleScroll(0);">
     <div style="height: 200px;"></div>
 </div>
 
-<div style="overflow: auto; width: 200px; height: 100px;" onscroll="if (secondOverflowRemove) this.parentNode.removeChild(this);">
+<div style="overflow: auto; width: 200px; height: 100px;" onscroll="this.parentNode.removeChild(this);handleScroll(1);">
     <div style="height: 200px;"></div>
     <div id="d"></div>
 </div>
 
 <script>
-    var overflowRemove = false;
-    var secondOverflowRemove = false;
+    var scrolledFirstContainer = false;
+    var scrolledSecondContainer = false;
 
     document.body.offsetTop; t.scrollTop = 20;
 
-    overflowRemove = true;
-    document.getElementById('t').innerHTML = '';
-
-    secondOverflowRemove = true;
     document.getElementById('d').scrollIntoView();
     
-    document.getElementById('result').innerText = "SUCCESS";
-
-    if (window.layoutTestController)
-        layoutTestController.notifyDone();
+    function handleScroll(index)
+    {
+        if (index == 0) scrolledFirstContainer = true;
+        else if (index == 1) scrolledSecondContainer = true;
+        
+        if (scrolledFirstContainer && scrolledSecondContainer) {
+            document.getElementById('result').innerText = "SUCCESS";
+        
+            if (window.layoutTestController)
+                layoutTestController.notifyDone();
+        }
+    }
 </script>
diff --git a/LayoutTests/fast/overflow/onscroll-layer-self-destruct.html b/LayoutTests/fast/overflow/onscroll-layer-self-destruct.html
index 64b20ac..357412f 100644
--- a/LayoutTests/fast/overflow/onscroll-layer-self-destruct.html
+++ b/LayoutTests/fast/overflow/onscroll-layer-self-destruct.html
@@ -1,14 +1,16 @@
 <head>
 <script>
 function test() {
-    if (window.layoutTestController)
+    if (window.layoutTestController) {
         layoutTestController.dumpAsText();
+        layoutTestController.waitUntilDone();
+    }
     document.getElementById("it").scrollTop = 100;
 }
 </script>
 <body onload="test()">
 <p>This test involves a layer that self-destructs when scrolled. If there's no crash, then the test succeeded.</p>
-<div id="it" style="height: 100%; overflow: auto;" onscroll="style.display = 'none'">
+<div id="it" style="height: 100%; overflow: auto;" onscroll="style.display = 'none';if (window.layoutTestController) layoutTestController.notifyDone();">
 <div style="height: 2000px;"></div>
 </div>
 </body>
diff --git a/LayoutTests/fast/repaint/repaint-during-scroll.html b/LayoutTests/fast/repaint/repaint-during-scroll.html
index e3f0ac4..dc69712 100644
--- a/LayoutTests/fast/repaint/repaint-during-scroll.html
+++ b/LayoutTests/fast/repaint/repaint-during-scroll.html
@@ -3,6 +3,8 @@
     <script>
         function repaintTest()
         {
+            if (window.layoutTestController)
+                layoutTestController.waitUntilDone();
             var target = document.getElementById("target");
             scrollBy(0, 100);
         }
@@ -11,6 +13,8 @@
         {
             var target = document.getElementById("target");
             target.style.backgroundColor = "green";
+            if (window.layoutTestController)
+                layoutTestController.notifyDone();
         }
     </script>
 </head>
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 6757f39..0a2b6e2 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,32 @@
+2011-01-11  Mihai Parparita  <mihaip at chromium.org>
+
+        Reviewed by Darin Fisher.
+
+        Scroll event should be fired asynchronously
+        https://bugs.webkit.org/show_bug.cgi?id=45631
+
+        Tests: fast/events/fire-scroll-event.html
+               fast/events/fire-scroll-event-element.html
+               fast/events/scroll-event-phase.html
+
+        Makes scroll events fire asynchronously to be in compliance with the
+        CSSOM View Module and consistent with Gecko, Opera and (to some degree)
+        IE.
+        
+        Implemented via the EventQueue class added by r74062 (EventQueue now
+        has a convenience enqueueScrollEvent method).
+
+        * dom/EventQueue.cpp:
+        (WebCore::EventQueue::enqueueScrollEvent):
+        (WebCore::EventQueue::pendingEventTimerFired):
+        * dom/EventQueue.h:
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::sendScrollEvent):
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::scrollToOffset):
+        * rendering/RenderListBox.cpp:
+        (WebCore::RenderListBox::valueChanged):
+
 2011-01-11  Patrick Gansterer  <paroga at webkit.org>
 
         Unreviewed WinCE build fix for r75523.
diff --git a/Source/WebCore/dom/EventQueue.cpp b/Source/WebCore/dom/EventQueue.cpp
index 27cd802..a43929e 100644
--- a/Source/WebCore/dom/EventQueue.cpp
+++ b/Source/WebCore/dom/EventQueue.cpp
@@ -48,12 +48,26 @@ void EventQueue::enqueueEvent(PassRefPtr<Event> event)
         m_pendingEventTimer.startOneShot(0);
 }
 
+void EventQueue::enqueueScrollEvent(PassRefPtr<Node> target, ScrollEventTargetType targetType)
+{
+    if (!m_nodesWithQueuedScrollEvents.add(target.get()).second)
+        return;
+
+    // Per the W3C CSSOM View Module, scroll events fired at the document should bubble, others should not.
+    bool canBubble = targetType == ScrollEventDocumentTarget;
+    RefPtr<Event> scrollEvent = Event::create(eventNames().scrollEvent, canBubble, false /* non cancelleable */);
+    scrollEvent->setTarget(target);
+    enqueueEvent(scrollEvent.release());
+}
+
 void EventQueue::pendingEventTimerFired(Timer<EventQueue>*)
 {
     ASSERT(!m_pendingEventTimer.isActive());
 
     Vector<RefPtr<Event> > queuedEvents;
     queuedEvents.swap(m_queuedEvents);
+    
+    m_nodesWithQueuedScrollEvents.clear();
 
     for (size_t i = 0; i < queuedEvents.size(); i++)
         dispatchEvent(queuedEvents[i].release());
diff --git a/Source/WebCore/dom/EventQueue.h b/Source/WebCore/dom/EventQueue.h
index 8dd7ec9..7f8d5fb 100644
--- a/Source/WebCore/dom/EventQueue.h
+++ b/Source/WebCore/dom/EventQueue.h
@@ -28,6 +28,7 @@
 #define EventQueue_h
 
 #include "Timer.h"
+#include <wtf/HashSet.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/RefPtr.h>
 #include <wtf/Vector.h>
@@ -41,9 +42,15 @@ class EventQueue {
     WTF_MAKE_NONCOPYABLE(EventQueue);
 
 public:
+    enum ScrollEventTargetType {
+        ScrollEventDocumentTarget,
+        ScrollEventElementTarget
+    };
+
     EventQueue();
 
     void enqueueEvent(PassRefPtr<Event>);
+    void enqueueScrollEvent(PassRefPtr<Node>, ScrollEventTargetType);
 
 private:
     void pendingEventTimerFired(Timer<EventQueue>*);
@@ -51,6 +58,7 @@ private:
 
     Timer<EventQueue> m_pendingEventTimer;
     Vector<RefPtr<Event> > m_queuedEvents;
+    HashSet<Node*> m_nodesWithQueuedScrollEvents;
 };
 
 }
diff --git a/Source/WebCore/page/EventHandler.cpp b/Source/WebCore/page/EventHandler.cpp
index 048a3cc..d0f1756 100644
--- a/Source/WebCore/page/EventHandler.cpp
+++ b/Source/WebCore/page/EventHandler.cpp
@@ -36,6 +36,7 @@
 #include "DragController.h"
 #include "Editor.h"
 #include "EventNames.h"
+#include "EventQueue.h"
 #include "FloatPoint.h"
 #include "FloatRect.h"
 #include "FocusController.h"
@@ -2798,7 +2799,7 @@ void EventHandler::sendScrollEvent()
 {
     setFrameWasScrolledByUser();
     if (m_frame->view() && m_frame->document())
-        m_frame->document()->dispatchEvent(Event::create(eventNames().scrollEvent, true, false));
+        m_frame->document()->eventQueue()->enqueueScrollEvent(m_frame->document(), EventQueue::ScrollEventDocumentTarget);
 }
 
 void EventHandler::setFrameWasScrolledByUser()
diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp
index 541614c..ed4639e 100644
--- a/Source/WebCore/rendering/RenderLayer.cpp
+++ b/Source/WebCore/rendering/RenderLayer.cpp
@@ -51,7 +51,7 @@
 #include "Chrome.h"
 #include "Document.h"
 #include "EventHandler.h"
-#include "EventNames.h"
+#include "EventQueue.h"
 #include "FloatPoint3D.h"
 #include "FloatRect.h"
 #include "FocusController.h"
@@ -1397,10 +1397,7 @@ void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repai
     }
 
     // Schedule the scroll DOM event.
-    if (view) {
-        if (FrameView* frameView = view->frameView())
-            frameView->scheduleEvent(Event::create(eventNames().scrollEvent, false, false), renderer()->node());
-    }
+    renderer()->node()->document()->eventQueue()->enqueueScrollEvent(renderer()->node(), EventQueue::ScrollEventElementTarget);
 }
 
 void RenderLayer::scrollRectToVisible(const IntRect& rect, bool scrollToAnchor, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
diff --git a/Source/WebCore/rendering/RenderListBox.cpp b/Source/WebCore/rendering/RenderListBox.cpp
index 66a2342..a7cf075 100644
--- a/Source/WebCore/rendering/RenderListBox.cpp
+++ b/Source/WebCore/rendering/RenderListBox.cpp
@@ -36,7 +36,7 @@
 #include "CSSStyleSelector.h"
 #include "Document.h"
 #include "EventHandler.h"
-#include "EventNames.h"
+#include "EventQueue.h"
 #include "FocusController.h"
 #include "Frame.h"
 #include "FrameView.h"
@@ -539,7 +539,7 @@ void RenderListBox::valueChanged(Scrollbar*)
     if (newOffset != m_indexOffset) {
         m_indexOffset = newOffset;
         repaint();
-        node()->dispatchEvent(Event::create(eventNames().scrollEvent, false, false));
+        node()->document()->eventQueue()->enqueueScrollEvent(node(), EventQueue::ScrollEventElementTarget);
     }
 }
 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list