Title: [182215] trunk
Revision
182215
Author
simon.fra...@apple.com
Date
2015-03-31 16:42:31 -0700 (Tue, 31 Mar 2015)

Log Message

Make it possible to compute a region for elements on the page that have wheel event handlers
https://bugs.webkit.org/show_bug.cgi?id=142807

Reviewed by David Hyatt.

Source/WebCore:

Make it possible to compute a region that covers the elements on the page that have
a wheel event handler. This region may overestimate, but must not underestimate the area.

Elements with wheel handlers are registered on the document, and when a document gains
its first wheel handler, it registers the ownerElement in the parent document. Thus, on
the main frame, the region encompasses elements with handlers, and iframes whose subdocuments
have handlers.

Element gains some functions that allow it to return a rect which is the bounds of the element's
renderer, and renders for its descendant elements, which is the size or larger than the event
handling region for that element. Some configurations (e.g. position:fixed) require special
treatment.

Document::absoluteRegionForEventTargets() can then iterate over all elements in the given set,
and build a Region for those (short-circuiting if the document itself has a handler).

The new code is exercised for the debug MouseWheelRegionOverlay, and also added to the
non-fast scrollable region, used by threaded scrolling.

Tests: platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/handlers-in-iframes.html
       platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-fixed-child.html
       platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-columns.html
       platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-region.html
       platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-inside-fixed.html
       platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-document.html
       platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-fixed.html
       platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-region-basic.html

* dom/ContainerNode.h:
(WebCore::ContainerNode::absoluteEventHandlerBounds): Base class implementation; returns empty rect.
* dom/Document.cpp:
(WebCore::Document::prepareForDestruction): Unregister from the parent document.
(WebCore::Document::didAddWheelEventHandler): Add to the wheel handler set. Tell the parent
document if we are adding wheel handlers for the first time. Eventually the wheelEventHandlerCountChanged()
code will be removed, now we have the set. Tell debug overlays that we changed.
(WebCore::Document::didRemoveWheelEventHandler): Remove from the set, and unregister with the parent
document if necessary. Tell debug overlays that we changed.
(WebCore::Document::didAddTouchEventHandler): Minor cleanup.
(WebCore::Document::didRemoveTouchEventHandler): Ditto.
(WebCore::Document::didRemoveEventTargetNode): Remove from wheel targets.
(WebCore::Document::absoluteEventHandlerBounds): Implementation of the ContainerNode
function, just return the document bounds.
(WebCore::Document::absoluteRegionForEventTargets): Iterate over the given event targets,
and call absoluteEventHandlerBounds() on each.
* dom/Document.h:
(WebCore::Document::wheelEventTargets):
* dom/Element.cpp:
(WebCore::layoutOverflowRectContainsAllDescendants): Return true if we can determine that the
layoutOverflow bounds of the given renderer contains the renderers of all descendant elements.
(WebCore::Element::eventBounds): Get the "event handling" bounds of this element (excluding
descendants), and while doing so, compute whether any descendants are position:fixed, and whether
these bounds are known to include descendants.
(WebCore::Element::eventBoundsOfElementAndDescendants): Recursive function that short-circuits
if it can determine that descendants are enclosed by the bounds.
(WebCore::Element::absoluteEventHandlerBounds):
* dom/Element.h:
* page/DebugPageOverlays.cpp:
(WebCore::MouseWheelRegionOverlay::updateRegion): Ask the document for the region of wheel
event handlers.
* page/scrolling/ScrollingCoordinator.cpp:
(WebCore::ScrollingCoordinator::computeNonFastScrollableRegion): Add the wheel handler region
to the non-fast scrollable region.
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::scrollTo): Overflow scrolling needs to dirty event regions.
* rendering/RenderObject.cpp:
(WebCore::RenderObject::absoluteBoundingBoxRect): Need to pass the "wasFixed" flag out
of this function.
(WebCore::RenderObject::localToAbsolute): Ditto.
* rendering/RenderObject.h:

LayoutTests:

Tests that dump the non-fast-scrollable region, for various rendering configurations.

* platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/handlers-in-iframes-expected.txt: Added.
* platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/handlers-in-iframes.html: Added.
* platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/resources/gain-wheel-handler.html: Added.
* platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/resources/lose-wheel-handler.html: Added.
* platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/resources/wheel-handler-region-helper.js: Added.
(rectsAsString):
(dumpRegion):
* platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-fixed-child-expected.txt: Added.
* platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-fixed-child.html: Added.
* platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-columns.html: Added.
* platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-region.html: Added.
* platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-inside-fixed-expected.txt: Added.
* platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-inside-fixed.html: Added.
* platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-document-expected.txt: Added.
* platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-document.html: Added.
* platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-fixed-expected.txt: Added.
* platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-fixed.html: Added.
* platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-region-basic-expected.txt: Added.
* platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-region-basic.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (182214 => 182215)


--- trunk/LayoutTests/ChangeLog	2015-03-31 23:38:49 UTC (rev 182214)
+++ trunk/LayoutTests/ChangeLog	2015-03-31 23:42:31 UTC (rev 182215)
@@ -1,3 +1,32 @@
+2015-03-31  Simon Fraser  <simon.fra...@apple.com>
+
+        Make it possible to compute a region for elements on the page that have wheel event handlers
+        https://bugs.webkit.org/show_bug.cgi?id=142807
+
+        Reviewed by David Hyatt.
+        
+        Tests that dump the non-fast-scrollable region, for various rendering configurations.
+
+        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/handlers-in-iframes-expected.txt: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/handlers-in-iframes.html: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/resources/gain-wheel-handler.html: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/resources/lose-wheel-handler.html: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/resources/wheel-handler-region-helper.js: Added.
+        (rectsAsString):
+        (dumpRegion):
+        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-fixed-child-expected.txt: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-fixed-child.html: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-columns.html: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-region.html: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-inside-fixed-expected.txt: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-inside-fixed.html: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-document-expected.txt: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-document.html: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-fixed-expected.txt: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-fixed.html: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-region-basic-expected.txt: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-region-basic.html: Added.
+
 2015-03-31  Dean Jackson  <d...@apple.com>
 
         accessibility/aria-hidden-hides-all-elements.html fails on Windows

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/handlers-in-iframes-expected.txt (0 => 182215)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/handlers-in-iframes-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/handlers-in-iframes-expected.txt	2015-03-31 23:42:31 UTC (rev 182215)
@@ -0,0 +1,2 @@
+
+20, 12 - 320, 162

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/handlers-in-iframes.html (0 => 182215)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/handlers-in-iframes.html	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/handlers-in-iframes.html	2015-03-31 23:42:31 UTC (rev 182215)
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        iframe {
+            display: block;
+            margin: 10px;
+        }
+    </style>
+    <script src=""
+    <script>
+        if (window.testRunner)
+            testRunner.waitUntilDone();
+
+        var notificationsPending = 3;
+
+        // Called from subframes.
+        function frameChanged()
+        {
+            receivedNotification();
+        }
+        
+        function mainFrameLoaded()
+        {
+            receivedNotification();
+        }
+        
+        function receivedNotification()
+        {
+            if (!--notificationsPending) {
+                dumpRegion();
+                if (window.testRunner)
+                    testRunner.notifyDone();
+            }
+        }
+        
+        window.addEventListener('load', mainFrameLoaded, false);
+    </script>
+</head>
+<body>
+
+<iframe src=""
+<iframe src=""
+
+<pre id="output"></pre>
+
+</body>
+</html>

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/resources/gain-wheel-handler.html (0 => 182215)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/resources/gain-wheel-handler.html	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/resources/gain-wheel-handler.html	2015-03-31 23:42:31 UTC (rev 182215)
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        .box {
+            width: 100px;
+            height: 100px;
+            border: 4px solid black;
+        }
+    </style>
+    <script>
+        function addHandler()
+        {
+            window.setTimeout(function() {
+                var target = document.getElementById('target');
+                target.addEventListener('mousewheel', function(e) { });
+                parent.frameChanged();
+            }, 0);
+        }
+        
+        window.addEventListener('load', addHandler, false);
+    </script>
+</head>
+<body>
+
+<div id="target" class="box">
+</div>
+
+<pre id="output"></pre>
+</body>
+</html>

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/resources/lose-wheel-handler.html (0 => 182215)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/resources/lose-wheel-handler.html	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/resources/lose-wheel-handler.html	2015-03-31 23:42:31 UTC (rev 182215)
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        .box {
+            width: 100px;
+            height: 100px;
+            border: 4px solid black;
+        }
+    </style>
+    <script>
+        function wheelHandler(e)
+        {
+        }
+
+        function removeHandler()
+        {
+            window.setTimeout(function() {
+                var target = document.getElementById('target');
+                target.removeEventListener('mousewheel', wheelHandler);
+                parent.frameChanged();
+            }, 0);
+        }
+        
+        window.addEventListener('load', removeHandler, false);
+    </script>
+</head>
+<body>
+
+<div id="target" class="box">
+</div>
+
+<pre id="output"></pre>
+
+<script>
+var target = document.getElementById('target');
+target.addEventListener('mousewheel', wheelHandler);
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/resources/wheel-handler-region-helper.js (0 => 182215)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/resources/wheel-handler-region-helper.js	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/resources/wheel-handler-region-helper.js	2015-03-31 23:42:31 UTC (rev 182215)
@@ -0,0 +1,22 @@
+if (window.testRunner)
+    testRunner.dumpAsText();
+
+function rectsAsString(rects)
+{
+    var result = "";
+    for (var i = 0; i < rects.length; ++i) {
+        var rect = rects[i];
+        if (i)
+            result += '\n';
+        result += rect.left + ', ' + rect.top + ' - ' + rect.right + ', ' + rect.bottom;
+    }
+    return result;
+}
+
+function dumpRegion()
+{
+    if (window.internals) {
+        var rects = window.internals.nonFastScrollableRects();
+        document.getElementById('output').textContent = rectsAsString(rects);
+    }
+}

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-fixed-child-expected.txt (0 => 182215)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-fixed-child-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-fixed-child-expected.txt	2015-03-31 23:42:31 UTC (rev 182215)
@@ -0,0 +1 @@
+50, 50 - 150, 150

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-fixed-child.html (0 => 182215)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-fixed-child.html	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-fixed-child.html	2015-03-31 23:42:31 UTC (rev 182215)
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        .fixed {
+            position: fixed;
+            top: 50px;
+            left: 50px;
+        }
+        
+        .box {
+            height: 100px;
+            width: 100px;
+            background-color: blue;
+        }
+        
+        .child {
+            position: relative;
+            left: 50px;
+            top: 50px;
+        }
+        #output {
+            margin-top: 520px;
+        }
+    </style>
+    <script src=""
+    <script>
+        function dumpRegion()
+        {
+            if (window.internals) {
+                var rects = window.internals.nonFastScrollableRects();
+                document.getElementById('output').textContent = rectsAsString(rects);
+            }
+        }
+
+        window.addEventListener('load', dumpRegion, false);
+    </script>
+</head>
+<body>
+
+<div class="box">
+    <div class="fixed box" _onmousewheel_="(void)0">
+    </div>
+</div>
+
+<pre id="output"></pre>
+
+</body>
+</html>

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-columns-expected.txt (0 => 182215)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-columns-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-columns-expected.txt	2015-03-31 23:42:31 UTC (rev 182215)
@@ -0,0 +1,7 @@
+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.
+
+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.
+
+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.
+
+28, 20 - 567, 380

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-columns.html (0 => 182215)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-columns.html	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-columns.html	2015-03-31 23:42:31 UTC (rev 182215)
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        .columns {
+            margin: 20px;
+            width: 400px;
+            height: 360px;
+            column-width: 120px;
+        }
+        .target {
+            color: blue;
+        }
+    </style>
+    <script src=""
+    <script>
+        function doTest()
+        {
+            dumpRegion();
+        }
+
+        window.addEventListener('load', doTest);
+    </script>
+</head>
+<body>
+
+<div class="columns">
+    <p>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.</p>
+    <p class="target" _onmousewheel_="(void)0">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.</p>
+    <p>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.</p>
+</div>
+<pre id="output"></pre>
+
+</body>
+</html>

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-overflow-scroll-expected.txt (0 => 182215)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-overflow-scroll-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-overflow-scroll-expected.txt	2015-03-31 23:42:31 UTC (rev 182215)
@@ -0,0 +1,9 @@
+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.
+
+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.
+
+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.
+
+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.
+
+8, 8 - 310, 310

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-overflow-scroll.html (0 => 182215)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-overflow-scroll.html	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-overflow-scroll.html	2015-03-31 23:42:31 UTC (rev 182215)
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        #container {
+            width: 300px;
+            height: 300px;
+            overflow: scroll;
+            border: 1px solid black;
+        }
+        .target {
+            color: blue;
+        }
+    </style>
+    <script src=""
+    <script>
+        if (window.testRunner)
+            testRunner.waitUntilDone();
+
+        function doTest()
+        {
+            window.setTimeout(function() {
+                var scroller = document.getElementById('container');
+                scroller.scrollTop = 200;
+                dumpRegion();
+                if (window.testRunner)
+                    testRunner.notifyDone();
+            }, 0)
+        }
+
+        window.addEventListener('load', doTest);
+    </script>
+</head>
+<body>
+
+<div id="container">
+    <p>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.</p>
+    <p>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.</p>
+    <p class="target" _onmousewheel_="(void)0">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.</p>
+    <p>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.</p>
+</div>
+
+<pre id="output"></pre>
+
+</body>
+</html>

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-region-expected.txt (0 => 182215)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-region-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-region-expected.txt	2015-03-31 23:42:31 UTC (rev 182215)
@@ -0,0 +1,7 @@
+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.
+
+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.
+
+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.
+
+39, 151 - 609, 401

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-region.html (0 => 182215)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-region.html	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-region.html	2015-03-31 23:42:31 UTC (rev 182215)
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        #content {
+            -webkit-flow-into: flow1;
+        }
+
+        #region1, #region2 {
+            margin: 10px;
+            border: 1px solid black;
+            -webkit-flow-from: flow1;
+        }
+
+        #region1 {
+            margin-left: 30px;
+            width: 300px;
+            height: 200px;
+        }
+
+        #region2 {
+            margin-top: 80px;
+            margin-left: 200px;
+            width: 400px;
+            height: 90px;
+        }
+
+        .target {
+            color: blue;
+        }
+    </style>
+    <script src=""
+    <script>
+        function doTest()
+        {
+            dumpRegion();
+        }
+
+        window.addEventListener('load', doTest);
+    </script>
+</head>
+<body>
+
+<div id="content">
+    <p>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.</p>
+    <p class="target" _onmousewheel_="(void)0">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.</p>
+    <p>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.</p>
+</div>
+
+<div id="container">
+    <div id="region1"></div>
+    <div id="region2"></div>
+</div>
+
+<pre id="output"></pre>
+
+</body>
+</html>

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-inside-fixed-expected.txt (0 => 182215)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-inside-fixed-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-inside-fixed-expected.txt	2015-03-31 23:42:31 UTC (rev 182215)
@@ -0,0 +1 @@
+60, 60 - 160, 160

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-inside-fixed.html (0 => 182215)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-inside-fixed.html	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-inside-fixed.html	2015-03-31 23:42:31 UTC (rev 182215)
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        .fixed {
+            position: fixed;
+            top: 10px;
+            left: 10px;
+        }
+        
+        .box {
+            height: 100px;
+            width: 100px;
+            background-color: blue;
+        }
+        
+        .child {
+            position: relative;
+            left: 50px;
+            top: 50px;
+        }
+        #output {
+            margin-top: 520px;
+        }
+    </style>
+    <script src=""
+    <script>
+        window.addEventListener('load', dumpRegion, false);
+    </script>
+</head>
+<body>
+
+<div class="fixed box">
+    <div class="child box" _onmousewheel_="(void)0">
+    </div>
+</div>
+
+<pre id="output"></pre>
+
+</body>
+</html>

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-document-expected.txt (0 => 182215)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-document-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-document-expected.txt	2015-03-31 23:42:31 UTC (rev 182215)
@@ -0,0 +1 @@
+0, 0 - 800, 600

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-document.html (0 => 182215)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-document.html	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-document.html	2015-03-31 23:42:31 UTC (rev 182215)
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <script src=""
+    <script>
+        function doTest()
+        {
+            document.addEventListener('mousewheel', function() { });
+            dumpRegion();
+        }
+
+        window.addEventListener('load', doTest);
+    </script>
+</head>
+<body>
+
+<pre id="output"></pre>
+
+</body>
+</html>

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-fixed-expected.txt (0 => 182215)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-fixed-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-fixed-expected.txt	2015-03-31 23:42:31 UTC (rev 182215)
@@ -0,0 +1 @@
+10, 10 - 110, 110

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-fixed.html (0 => 182215)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-fixed.html	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-fixed.html	2015-03-31 23:42:31 UTC (rev 182215)
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        .fixed {
+            position: fixed;
+            top: 10px;
+            left: 10px;
+        }
+        
+        .box {
+            height: 100px;
+            width: 100px;
+            background-color: blue;
+        }
+        #output {
+            margin-top: 520px;
+        }
+    </style>
+    <script src=""
+    <script>
+        window.addEventListener('load', dumpRegion, false);
+    </script>
+</head>
+<body>
+
+<div class="fixed box" _onmousewheel_="(void)0">
+</div>
+
+<pre id="output"></pre>
+
+</body>
+</html>

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-region-basic-expected.txt (0 => 182215)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-region-basic-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-region-basic-expected.txt	2015-03-31 23:42:31 UTC (rev 182215)
@@ -0,0 +1,10 @@
+Some text
+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. here Container
+Intermediate
+Child
+Container
+Intermediate
+Child
+8, 8 - 777, 329
+9, 369 - 290, 425
+9, 501 - 290, 601

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-region-basic.html (0 => 182215)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-region-basic.html	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-region-basic.html	2015-03-31 23:42:31 UTC (rev 182215)
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        .box {
+            width: 100px;
+            height: 100px;
+            border: 4px solid black;
+            position: relative;
+        }
+        
+        .overflowing-transformed {
+            position: absolute;
+            top: 100px;
+            left: 300px;
+            width: 200px;
+            height: 100px;
+            border: 1px solid green;
+            -webkit-transform: rotate(30deg);
+        }
+        
+        .container {
+            position: absolute;
+            top: 350px;
+            height: 100px;
+            border: 1px solid green;
+        }
+        
+        .inner {
+            position: relative;
+            top: 20px;
+            left: 200px;
+            background-color: orange;
+        }
+        
+        #output {
+            margin-top: 520px;
+        }
+    </style>
+    <script src=""
+    <script>
+        window.addEventListener('load', dumpRegion, false);
+    </script>
+</head>
+<body>
+
+<span id="target" _onmousewheel_="(void)0">Some text
+    <div class="box">
+        <div class="overflowing-transformed">
+            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.
+        </div>
+    </div>
+here</span>
+
+<!-- Handler on skipped containing block -->
+<div class="container" _onmousewheel_="(void)0" style="top: 500px;">
+    Container
+    <div class="intermediate">
+        Intermediate
+        <div class="inner">
+            Child
+        </div>
+    </div>
+</div>
+
+<div class="container">
+    Container
+    <!-- Handler on skipped containing block -->
+    <div class="intermediate" _onmousewheel_="(void)0">
+        Intermediate
+        <div class="inner">
+            Child
+        </div>
+    </div>
+</div>
+
+<pre id="output"></pre>
+
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (182214 => 182215)


--- trunk/Source/WebCore/ChangeLog	2015-03-31 23:38:49 UTC (rev 182214)
+++ trunk/Source/WebCore/ChangeLog	2015-03-31 23:42:31 UTC (rev 182215)
@@ -1,3 +1,80 @@
+2015-03-31  Simon Fraser  <simon.fra...@apple.com>
+
+        Make it possible to compute a region for elements on the page that have wheel event handlers
+        https://bugs.webkit.org/show_bug.cgi?id=142807
+
+        Reviewed by David Hyatt.
+        
+        Make it possible to compute a region that covers the elements on the page that have
+        a wheel event handler. This region may overestimate, but must not underestimate the area.
+        
+        Elements with wheel handlers are registered on the document, and when a document gains
+        its first wheel handler, it registers the ownerElement in the parent document. Thus, on 
+        the main frame, the region encompasses elements with handlers, and iframes whose subdocuments
+        have handlers.
+        
+        Element gains some functions that allow it to return a rect which is the bounds of the element's
+        renderer, and renders for its descendant elements, which is the size or larger than the event
+        handling region for that element. Some configurations (e.g. position:fixed) require special
+        treatment.
+        
+        Document::absoluteRegionForEventTargets() can then iterate over all elements in the given set,
+        and build a Region for those (short-circuiting if the document itself has a handler).
+        
+        The new code is exercised for the debug MouseWheelRegionOverlay, and also added to the
+        non-fast scrollable region, used by threaded scrolling.
+
+        Tests: platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/handlers-in-iframes.html
+               platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-fixed-child.html
+               platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-columns.html
+               platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-region.html
+               platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-inside-fixed.html
+               platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-document.html
+               platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-fixed.html
+               platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-region-basic.html
+
+        * dom/ContainerNode.h:
+        (WebCore::ContainerNode::absoluteEventHandlerBounds): Base class implementation; returns empty rect.
+        * dom/Document.cpp:
+        (WebCore::Document::prepareForDestruction): Unregister from the parent document.
+        (WebCore::Document::didAddWheelEventHandler): Add to the wheel handler set. Tell the parent
+        document if we are adding wheel handlers for the first time. Eventually the wheelEventHandlerCountChanged()
+        code will be removed, now we have the set. Tell debug overlays that we changed.
+        (WebCore::Document::didRemoveWheelEventHandler): Remove from the set, and unregister with the parent
+        document if necessary. Tell debug overlays that we changed.
+        (WebCore::Document::didAddTouchEventHandler): Minor cleanup.
+        (WebCore::Document::didRemoveTouchEventHandler): Ditto.
+        (WebCore::Document::didRemoveEventTargetNode): Remove from wheel targets.
+        (WebCore::Document::absoluteEventHandlerBounds): Implementation of the ContainerNode
+        function, just return the document bounds.
+        (WebCore::Document::absoluteRegionForEventTargets): Iterate over the given event targets,
+        and call absoluteEventHandlerBounds() on each.
+        * dom/Document.h:
+        (WebCore::Document::wheelEventTargets):
+        * dom/Element.cpp:
+        (WebCore::layoutOverflowRectContainsAllDescendants): Return true if we can determine that the
+        layoutOverflow bounds of the given renderer contains the renderers of all descendant elements.
+        (WebCore::Element::eventBounds): Get the "event handling" bounds of this element (excluding
+        descendants), and while doing so, compute whether any descendants are position:fixed, and whether
+        these bounds are known to include descendants.
+        (WebCore::Element::eventBoundsOfElementAndDescendants): Recursive function that short-circuits
+        if it can determine that descendants are enclosed by the bounds.
+        (WebCore::Element::absoluteEventHandlerBounds):
+        * dom/Element.h:
+        * page/DebugPageOverlays.cpp:
+        (WebCore::MouseWheelRegionOverlay::updateRegion): Ask the document for the region of wheel
+        event handlers.
+        * page/scrolling/ScrollingCoordinator.cpp:
+        (WebCore::ScrollingCoordinator::computeNonFastScrollableRegion): Add the wheel handler region
+        to the non-fast scrollable region.
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::scrollTo): Overflow scrolling needs to dirty event regions.
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::absoluteBoundingBoxRect): Need to pass the "wasFixed" flag out
+        of this function.
+        (WebCore::RenderObject::localToAbsolute): Ditto.
+        * rendering/RenderObject.h:
+
 2015-03-31  Alexey Proskuryakov  <a...@apple.com>
 
         Fix bindings tests results after <http://trac.webkit.org/changeset/182205>.

Modified: trunk/Source/WebCore/dom/ContainerNode.h (182214 => 182215)


--- trunk/Source/WebCore/dom/ContainerNode.h	2015-03-31 23:38:49 UTC (rev 182214)
+++ trunk/Source/WebCore/dom/ContainerNode.h	2015-03-31 23:42:31 UTC (rev 182215)
@@ -136,6 +136,10 @@
 
     RenderElement* renderer() const;
 
+    // Return a bounding box in absolute coordinates enclosing this node and all its descendants.
+    // This gives the area within which events may get handled by a hander registered on this node.
+    virtual LayoutRect absoluteEventHandlerBounds(bool& /* includesFixedPositionElements */) { return LayoutRect(); }
+
     Element* querySelector(const String& selectors, ExceptionCode&);
     RefPtr<NodeList> querySelectorAll(const String& selectors, ExceptionCode&);
 

Modified: trunk/Source/WebCore/dom/Document.cpp (182214 => 182215)


--- trunk/Source/WebCore/dom/Document.cpp	2015-03-31 23:38:49 UTC (rev 182214)
+++ trunk/Source/WebCore/dom/Document.cpp	2015-03-31 23:42:31 UTC (rev 182215)
@@ -47,6 +47,7 @@
 #include "DOMNamedFlowCollection.h"
 #include "DOMWindow.h"
 #include "DateComponents.h"
+#include "DebugPageOverlays.h"
 #include "Dictionary.h"
 #include "DocumentLoader.h"
 #include "DocumentMarkerController.h"
@@ -2245,6 +2246,9 @@
         parentDocument()->didRemoveEventTargetNode(*this);
 #endif
 
+    if (m_wheelEventTargets && m_wheelEventTargets->size() && parentDocument())
+        parentDocument()->didRemoveEventTargetNode(*this);
+
     if (m_mediaQueryMatcher)
         m_mediaQueryMatcher->documentDestroyed();
 
@@ -5998,29 +6002,61 @@
     scrollingCoordinator->frameViewWheelEventHandlerCountChanged(*frameView);
 }
 
-void Document::didAddWheelEventHandler(Node&)
+void Document::didAddWheelEventHandler(Node& node)
 {
     ++m_wheelEventHandlerCount;
+
+    if (!m_wheelEventTargets)
+        m_wheelEventTargets = std::make_unique<EventTargetSet>();
+
+    m_wheelEventTargets->add(&node);
+
+    if (Document* parent = parentDocument()) {
+        parent->didAddWheelEventHandler(*this);
+        return;
+    }
+
     wheelEventHandlerCountChanged(this);
+
+    if (Frame* frame = this->frame())
+        DebugPageOverlays::didChangeEventHandlers(*frame);
 }
 
-void Document::didRemoveWheelEventHandler(Node&)
+void Document::didRemoveWheelEventHandler(Node& node)
 {
     ASSERT(m_wheelEventHandlerCount > 0);
     --m_wheelEventHandlerCount;
+
+    if (!m_wheelEventTargets)
+        return;
+
+    ASSERT(m_wheelEventTargets->contains(&node));
+    m_wheelEventTargets->remove(&node);
+
+    if (Document* parent = parentDocument()) {
+        parent->didRemoveWheelEventHandler(*this);
+        return;
+    }
+
     wheelEventHandlerCountChanged(this);
+
+    if (Frame* frame = this->frame())
+        DebugPageOverlays::didChangeEventHandlers(*frame);
 }
 
 void Document::didAddTouchEventHandler(Node& handler)
 {
 #if ENABLE(TOUCH_EVENTS)
-    if (!m_touchEventTargets.get())
+    if (!m_touchEventTargets)
         m_touchEventTargets = std::make_unique<EventTargetSet>();
+
     m_touchEventTargets->add(&handler);
+
     if (Document* parent = parentDocument()) {
         parent->didAddTouchEventHandler(*this);
         return;
     }
+
     if (Page* page = this->page()) {
         if (m_touchEventTargets->size() == 1)
             page->chrome().client().needTouchEvents(true);
@@ -6033,10 +6069,12 @@
 void Document::didRemoveTouchEventHandler(Node& handler)
 {
 #if ENABLE(TOUCH_EVENTS)
-    if (!m_touchEventTargets.get())
+    if (!m_touchEventTargets)
         return;
+
     ASSERT(m_touchEventTargets->contains(&handler));
     m_touchEventTargets->remove(&handler);
+
     if (Document* parent = parentDocument()) {
         parent->didRemoveTouchEventHandler(*this);
         return;
@@ -6047,6 +6085,8 @@
         return;
     if (m_touchEventTargets->size())
         return;
+
+    // FIXME: why can't we trust m_touchEventTargets?
     for (const Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
         if (frame->document() && frame->document()->hasTouchEventHandlers())
             return;
@@ -6065,11 +6105,53 @@
         if ((&handler == this || m_touchEventTargets->isEmpty()) && parentDocument())
             parentDocument()->didRemoveEventTargetNode(*this);
     }
-#else
-    UNUSED_PARAM(handler);
 #endif
+
+    if (m_wheelEventTargets) {
+        m_wheelEventTargets->removeAll(&handler);
+        if ((&handler == this || m_wheelEventTargets->isEmpty()) && parentDocument())
+            parentDocument()->didRemoveEventTargetNode(*this);
+    }
 }
 
+LayoutRect Document::absoluteEventHandlerBounds(bool& includesFixedPositionElements)
+{
+    includesFixedPositionElements = false;
+    if (RenderView* renderView = this->renderView())
+        return renderView->documentRect();
+    
+    return LayoutRect();
+}
+
+Region Document::absoluteRegionForEventTargets(const EventTargetSet* targets)
+{
+    if (!targets)
+        return Region();
+
+    Region targetRegion;
+    bool insideFixedPosition = false;
+
+    for (auto it : *targets) {
+        LayoutRect rootRelativeBounds;
+        
+        if (is<Document>(it.key)) {
+            Document* document = downcast<Document>(it.key);
+            if (document == this)
+                rootRelativeBounds = absoluteEventHandlerBounds(insideFixedPosition);
+            else if (Element* element = document->ownerElement())
+                rootRelativeBounds = element->absoluteEventHandlerBounds(insideFixedPosition);
+        } else if (is<Element>(it.key)) {
+            Element* element = downcast<Element>(it.key);
+            rootRelativeBounds = element->absoluteEventHandlerBounds(insideFixedPosition);
+        }
+        
+        if (!rootRelativeBounds.isEmpty())
+            targetRegion.unite(Region(enclosingIntRect(rootRelativeBounds)));
+    }
+
+    return targetRegion;
+}
+
 void Document::updateLastHandledUserGestureTimestamp()
 {
     m_lastHandledUserGestureTimestamp = monotonicallyIncreasingTime();

Modified: trunk/Source/WebCore/dom/Document.h (182214 => 182215)


--- trunk/Source/WebCore/dom/Document.h	2015-03-31 23:38:49 UTC (rev 182214)
+++ trunk/Source/WebCore/dom/Document.h	2015-03-31 23:42:31 UTC (rev 182215)
@@ -41,6 +41,7 @@
 #include "PageVisibilityState.h"
 #include "PlatformScreen.h"
 #include "ReferrerPolicy.h"
+#include "Region.h"
 #include "RenderPtr.h"
 #include "ScriptExecutionContext.h"
 #include "StringWithDirection.h"
@@ -1148,6 +1149,12 @@
 #endif
     }
 
+    const EventTargetSet* wheelEventTargets() const { return m_wheelEventTargets.get(); }
+
+    Region absoluteRegionForEventTargets(const EventTargetSet*);
+
+    LayoutRect absoluteEventHandlerBounds(bool&) override final;
+
     bool visualUpdatesAllowed() const { return m_visualUpdatesAllowed; }
 
     bool isInDocumentWrite() { return m_writeRecursionDepth > 0; }
@@ -1561,6 +1568,7 @@
 #if ENABLE(TOUCH_EVENTS)
     std::unique_ptr<EventTargetSet> m_touchEventTargets;
 #endif
+    std::unique_ptr<EventTargetSet> m_wheelEventTargets;
 
     double m_lastHandledUserGestureTimestamp;
 

Modified: trunk/Source/WebCore/dom/Element.cpp (182214 => 182215)


--- trunk/Source/WebCore/dom/Element.cpp	2015-03-31 23:38:49 UTC (rev 182214)
+++ trunk/Source/WebCore/dom/Element.cpp	2015-03-31 23:42:31 UTC (rev 182215)
@@ -63,6 +63,7 @@
 #include "NodeRenderStyle.h"
 #include "PlatformWheelEvent.h"
 #include "PointerLockController.h"
+#include "RenderFlowThread.h"
 #include "RenderLayer.h"
 #include "RenderNamedFlowFragment.h"
 #include "RenderRegion.h"
@@ -925,6 +926,126 @@
     return result;
 }
 
+static bool layoutOverflowRectContainsAllDescendants(const RenderElement& renderer)
+{
+    if (renderer.isRenderView())
+        return true;
+
+    if (!renderer.element())
+        return false;
+
+    // If there are any position:fixed inside of us, game over.
+    if (auto viewPositionedObjects = renderer.view().positionedObjects()) {
+        for (RenderBox* it : *viewPositionedObjects) {
+            if (it != &renderer && it->style().position() == FixedPosition && renderer.element()->contains(it->element()))
+                return false;
+        }
+    }
+
+    if (renderer.canContainAbsolutelyPositionedObjects()) {
+        // Our layout overflow will include all descendant positioned elements.
+        return true;
+    }
+
+    // This renderer may have positioned descendants whose containing block is some ancestor.
+    if (auto containingBlock = renderer.containingBlockForAbsolutePosition()) {
+        if (auto positionedObjects = containingBlock->positionedObjects()) {
+            for (RenderBox* it : *positionedObjects) {
+                if (it != &renderer && renderer.element()->contains(it->element()))
+                    return false;
+            }
+        }
+    }
+    
+    return false;
+}
+
+LayoutRect Element::absoluteEventBounds(bool& boundsIncludeAllDescendantElements, bool& includesFixedPositionElements)
+{
+    boundsIncludeAllDescendantElements = false;
+    includesFixedPositionElements = false;
+
+    if (!renderer())
+        return LayoutRect();
+
+    LayoutRect result;
+    if (isSVGElement()) {
+        // Get the bounding rectangle from the SVG model.
+        SVGElement& svgElement = downcast<SVGElement>(*this);
+        FloatRect localRect;
+        if (svgElement.getBoundingBox(localRect))
+            result = LayoutRect(renderer()->localToAbsoluteQuad(localRect, UseTransforms, &includesFixedPositionElements).boundingBox());
+    } else {
+        if (is<RenderBox>(renderer())) {
+            RenderBox& box = *downcast<RenderBox>(renderer());
+
+            bool computedBounds = false;
+            
+            if (RenderFlowThread* flowThread = box.flowThreadContainingBlock()) {
+                bool wasFixed = false;
+                Vector<FloatQuad> quads;
+                FloatRect localRect(0, 0, box.width(), box.height());
+                if (flowThread->absoluteQuadsForBox(quads, &wasFixed, &box, localRect.y(), localRect.maxY())) {
+                    FloatRect quadBounds = quads[0].boundingBox();
+                    for (size_t i = 1; i < quads.size(); ++i)
+                        quadBounds.unite(quads[i].boundingBox());
+                    
+                    result = LayoutRect(quadBounds);
+                    computedBounds = true;
+                } else {
+                    // Probably columns. Just return the bounds of the multicol block for now.
+                    // FIXME: this doesn't handle nested columns.
+                    RenderElement* multicolContainer = flowThread->parent();
+                    if (multicolContainer && is<RenderBox>(multicolContainer)) {
+                        LayoutRect overflowRect = downcast<RenderBox>(multicolContainer)->layoutOverflowRect();
+                        result = LayoutRect(multicolContainer->localToAbsoluteQuad(FloatRect(overflowRect), UseTransforms, &includesFixedPositionElements).boundingBox());
+                        computedBounds = true;
+                    }
+                }
+            }
+
+            if (!computedBounds) {
+                LayoutRect overflowRect = box.layoutOverflowRect();
+                result = LayoutRect(box.localToAbsoluteQuad(FloatRect(overflowRect), UseTransforms, &includesFixedPositionElements).boundingBox());
+                boundsIncludeAllDescendantElements = layoutOverflowRectContainsAllDescendants(box);
+            }
+        } else
+            result = LayoutRect(renderer()->absoluteBoundingBoxRect(true /* useTransforms */, &includesFixedPositionElements));
+    }
+
+    return result;
+}
+
+LayoutRect Element::absoluteEventBoundsOfElementAndDescendants(bool& includesFixedPositionElements)
+{
+    bool boundsIncludeDescendants;
+    LayoutRect result = absoluteEventBounds(boundsIncludeDescendants, includesFixedPositionElements);
+    if (boundsIncludeDescendants)
+        return result;
+
+    for (auto& child : childrenOfType<Element>(*this)) {
+        bool includesFixedPosition = false;
+        LayoutRect childBounds = child.absoluteEventBoundsOfElementAndDescendants(includesFixedPosition);
+        includesFixedPositionElements |= includesFixedPosition;
+        result.unite(childBounds);
+    }
+
+    return result;
+}
+
+LayoutRect Element::absoluteEventHandlerBounds(bool& includesFixedPositionElements)
+{
+    // This is not web-exposed, so don't call the FOUC-inducing updateLayoutIgnorePendingStylesheets().
+    FrameView* frameView = document().view();
+    if (!frameView)
+        return LayoutRect();
+
+    if (frameView->needsLayout())
+        frameView->layout();
+
+    return absoluteEventBoundsOfElementAndDescendants(includesFixedPositionElements);
+}
+
 Ref<ClientRectList> Element::getClientRects()
 {
     document().updateLayoutIgnorePendingStylesheets();

Modified: trunk/Source/WebCore/dom/Element.h (182214 => 182215)


--- trunk/Source/WebCore/dom/Element.h	2015-03-31 23:38:49 UTC (rev 182214)
+++ trunk/Source/WebCore/dom/Element.h	2015-03-31 23:42:31 UTC (rev 182215)
@@ -484,6 +484,8 @@
     virtual void didDetachRenderers();
     virtual RefPtr<RenderStyle> customStyleForRenderer(RenderStyle& parentStyle);
 
+    LayoutRect absoluteEventHandlerBounds(bool& includesFixedPositionElements) override;
+
     void setBeforePseudoElement(Ref<PseudoElement>&&);
     void setAfterPseudoElement(Ref<PseudoElement>&&);
     void clearBeforePseudoElement();
@@ -562,6 +564,9 @@
     void addAttributeInternal(const QualifiedName&, const AtomicString& value, SynchronizationOfLazyAttribute);
     void removeAttributeInternal(unsigned index, SynchronizationOfLazyAttribute);
 
+    LayoutRect absoluteEventBounds(bool& boundsIncludeAllDescendantElements, bool& includesFixedPositionElements);
+    LayoutRect absoluteEventBoundsOfElementAndDescendants(bool& includesFixedPositionElements);
+    
 #if ENABLE(TREE_DEBUGGING)
     virtual void formatForDebugger(char* buffer, unsigned length) const override;
 #endif

Modified: trunk/Source/WebCore/page/DebugPageOverlays.cpp (182214 => 182215)


--- trunk/Source/WebCore/page/DebugPageOverlays.cpp	2015-03-31 23:38:49 UTC (rev 182214)
+++ trunk/Source/WebCore/page/DebugPageOverlays.cpp	2015-03-31 23:42:31 UTC (rev 182215)
@@ -90,16 +90,8 @@
 
 bool MouseWheelRegionOverlay::updateRegion()
 {
-    std::unique_ptr<Region> region = std::make_unique<Region>();
+    std::unique_ptr<Region> region = std::make_unique<Region>(m_frame.document()->absoluteRegionForEventTargets(m_frame.document()->wheelEventTargets()));
 
-    for (auto& element : descendantsOfType<Element>(*m_frame.document())) {
-        if (element.hasEventListeners(eventNames().mousewheelEvent) || element.hasEventListeners(eventNames().wheelEvent)) {
-            IntRect elementRect = element.boundsInRootViewSpace();
-            elementRect = m_frame.view()->rootViewToContents(elementRect);
-            region->unite(Region(elementRect));
-        }
-    }
-
     bool regionChanged = !m_region || !(*m_region == *region);
     m_region = WTF::move(region);
     return regionChanged;

Modified: trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp (182214 => 182215)


--- trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp	2015-03-31 23:38:49 UTC (rev 182214)
+++ trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp	2015-03-31 23:42:31 UTC (rev 182215)
@@ -98,6 +98,10 @@
 
 Region ScrollingCoordinator::computeNonFastScrollableRegion(const Frame& frame, const IntPoint& frameLocation) const
 {
+    RenderView* renderView = frame.contentRenderer();
+    if (!renderView || renderView->documentBeingDestroyed())
+        return Region();
+
 #if ENABLE(IOS_TOUCH_EVENTS)
     // On iOS, we use nonFastScrollableRegion to represent the region covered by elements with touch event handlers.
     ASSERT(frame.isMainFrame());
@@ -114,6 +118,7 @@
     for (const auto& rect : touchRects)
         touchRegion.unite(rect);
 
+    // FIXME: use absoluteRegionForEventTargets().
     return touchRegion;
 #else
     Region nonFastScrollableRegion;
@@ -148,6 +153,11 @@
     for (Frame* subframe = frame.tree().firstChild(); subframe; subframe = subframe->tree().nextSibling())
         nonFastScrollableRegion.unite(computeNonFastScrollableRegion(*subframe, offset));
 
+    // Include wheel event handler region for the main frame.
+    Region wheelHandlerRegion = frame.document()->absoluteRegionForEventTargets(frame.document()->wheelEventTargets());
+    wheelHandlerRegion.translate(toIntSize(offset));
+    nonFastScrollableRegion.unite(wheelHandlerRegion);
+
     return nonFastScrollableRegion;
 #endif
 }

Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (182214 => 182215)


--- trunk/Source/WebCore/rendering/RenderLayer.cpp	2015-03-31 23:38:49 UTC (rev 182214)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp	2015-03-31 23:42:31 UTC (rev 182215)
@@ -48,6 +48,7 @@
 #include "BoxShape.h"
 #include "CSSPropertyNames.h"
 #include "Chrome.h"
+#include "DebugPageOverlays.h"
 #include "Document.h"
 #include "DocumentEventQueue.h"
 #include "Element.h"
@@ -2391,6 +2392,7 @@
 #if PLATFORM(IOS) && ENABLE(TOUCH_EVENTS)
         renderer().document().dirtyTouchEventRects();
 #endif
+        DebugPageOverlays::didLayout(renderer().frame());
     }
 
     Frame& frame = renderer().frame();

Modified: trunk/Source/WebCore/rendering/RenderObject.cpp (182214 => 182215)


--- trunk/Source/WebCore/rendering/RenderObject.cpp	2015-03-31 23:38:49 UTC (rev 182214)
+++ trunk/Source/WebCore/rendering/RenderObject.cpp	2015-03-31 23:42:31 UTC (rev 182215)
@@ -1085,11 +1085,11 @@
 }
 #endif
 
-IntRect RenderObject::absoluteBoundingBoxRect(bool useTransforms) const
+IntRect RenderObject::absoluteBoundingBoxRect(bool useTransforms, bool* wasFixed) const
 {
     if (useTransforms) {
         Vector<FloatQuad> quads;
-        absoluteQuads(quads);
+        absoluteQuads(quads, wasFixed);
 
         size_t n = quads.size();
         if (!n)
@@ -1101,7 +1101,7 @@
         return result;
     }
 
-    FloatPoint absPos = localToAbsolute();
+    FloatPoint absPos = localToAbsolute(FloatPoint(), 0 /* ignore transforms */, wasFixed);
     Vector<IntRect> rects;
     absoluteRects(rects, flooredLayoutPoint(absPos));
 
@@ -1579,10 +1579,10 @@
     selectionRoot().selectionData().selectionStartEndPositions(spos, epos);
 }
 
-FloatPoint RenderObject::localToAbsolute(const FloatPoint& localPoint, MapCoordinatesFlags mode) const
+FloatPoint RenderObject::localToAbsolute(const FloatPoint& localPoint, MapCoordinatesFlags mode, bool* wasFixed) const
 {
     TransformState transformState(TransformState::ApplyTransformDirection, localPoint);
-    mapLocalToContainer(nullptr, transformState, mode | ApplyContainerFlip);
+    mapLocalToContainer(nullptr, transformState, mode | ApplyContainerFlip, wasFixed);
     transformState.flatten();
     
     return transformState.lastPlanarPoint();

Modified: trunk/Source/WebCore/rendering/RenderObject.h (182214 => 182215)


--- trunk/Source/WebCore/rendering/RenderObject.h	2015-03-31 23:38:49 UTC (rev 182214)
+++ trunk/Source/WebCore/rendering/RenderObject.h	2015-03-31 23:42:31 UTC (rev 182215)
@@ -652,7 +652,7 @@
     RenderBlock* containingBlock() const;
 
     // Convert the given local point to absolute coordinates. If MapCoordinatesFlags includes UseTransforms, take transforms into account.
-    WEBCORE_EXPORT FloatPoint localToAbsolute(const FloatPoint& localPoint = FloatPoint(), MapCoordinatesFlags = 0) const;
+    WEBCORE_EXPORT FloatPoint localToAbsolute(const FloatPoint& localPoint = FloatPoint(), MapCoordinatesFlags = 0, bool* wasFixed = nullptr) const;
     FloatPoint absoluteToLocal(const FloatPoint&, MapCoordinatesFlags = 0) const;
 
     // Convert a local quad to absolute coordinates, taking transforms into account.
@@ -681,7 +681,7 @@
     virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint&) const { }
 
     // FIXME: useTransforms should go away eventually
-    WEBCORE_EXPORT IntRect absoluteBoundingBoxRect(bool useTransform = true) const;
+    WEBCORE_EXPORT IntRect absoluteBoundingBoxRect(bool useTransform = true, bool* wasFixed = nullptr) const;
     IntRect absoluteBoundingBoxRectIgnoringTransforms() const { return absoluteBoundingBoxRect(false); }
 
     // Build an array of quads in absolute coords for line boxes
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to