Title: [143727] trunk
Revision
143727
Author
[email protected]
Date
2013-02-22 06:46:35 -0800 (Fri, 22 Feb 2013)

Log Message

Allow child-frame content in hit-tests.
https://bugs.webkit.org/show_bug.cgi?id=95204

Reviewed by Julien Chaffraix.

Source/WebCore:

Refactors how EventHandler::hitTestResultAtPoint handles child-frame content,
it is now handled by the hit test itself controlled by the AllowChildFrameContent
flag in HitTestRequest.

This means that area-based hit-tests can now return elements from all the child frames
they intersect instead of just the one frame containing the center point. The improved
results from area-based hit-tests will among other things also improve touch adjustment
near frame boundaries.

Tests: fast/dom/nodesFromRect/nodesFromRect-child-frame-content.html

* page/EventHandler.cpp:
(WebCore::EventHandler::hitTestResultAtPoint):
    Recursion into child-frames have been moved to RenderFrameBase::nodeAtPoint, so
    now hitTestResultAtPoint just needs to set AllowChildFrameContent.
* page/TouchAdjustment.cpp:
(WebCore::TouchAdjustment::parentShadowHostOrOwner):
    New function to iterate up across frame boundaries.
(WebCore::TouchAdjustment::compileSubtargetList):
    We need to iterate up across frame boundaries to avoid iframes competing with their
    own content for touch adjustment.
* rendering/HitTestRequest.h:
(WebCore::HitTestRequest::allowsChildFrameContent):
(WebCore::HitTestRequest::isChildFrameHitTest):
* rendering/HitTestResult.cpp:
(WebCore::HitTestResult::HitTestResult):
(WebCore::HitTestResult::operator=):
(WebCore::HitTestResult::append):
(WebCore::HitTestResult::dictationAlternatives):
* rendering/HitTestResult.h:
(WebCore::HitTestResult::pointInMainFrame):
(WebCore::HitTestResult::pointInInnerNodeFrame):
(HitTestResult):
    m_hitTestLocation is now in main frame coordinates, which make m_pointInMainFrame
    unnecessary, but requires the introduction of m_pointInInnerFrame, to remember
    the coordinates of inner-node in its own frame.
* rendering/RenderFrameBase.cpp:
(WebCore::RenderFrameBase::nodeAtPoint):
    The recursion into child-frames is now handled here instead of in hitTestResultAtPoint, this
    allows us to recurse into multiple frames, instead of just one.
* rendering/RenderFrameBase.h:
(RenderFrameBase):
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::hitTest):
    RenderLayer should not lie about being hit if the request is child-frame request.
* testing/Internals.cpp:
(WebCore::Internals::nodesFromRect):
* testing/Internals.h:
(Internals):
* testing/Internals.idl:
    Extended so nodesFromRect with child-frame content can be tested.

LayoutTests:

A new tests for nodesFromRect that returns result from child frames.

* fast/dom/nodesFromRect/nodesFromRect-child-frame-content-expected.txt: Added.
* fast/dom/nodesFromRect/nodesFromRect-child-frame-content.html: Added.
* fast/dom/nodesFromRect/nodesFromRect-continuation-crash.html:
* fast/dom/nodesFromRect/resources/child-frame.html: Added.
* fast/dom/nodesFromRect/resources/nodesFromRect.js:
(check):
(checkShadowContent):
(nodesFromRectAsString):

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (143726 => 143727)


--- trunk/LayoutTests/ChangeLog	2013-02-22 14:39:42 UTC (rev 143726)
+++ trunk/LayoutTests/ChangeLog	2013-02-22 14:46:35 UTC (rev 143727)
@@ -1,3 +1,21 @@
+2013-02-22  Allan Sandfeld Jensen  <[email protected]>
+
+        Allow child-frame content in hit-tests.
+        https://bugs.webkit.org/show_bug.cgi?id=95204
+
+        Reviewed by Julien Chaffraix.
+
+        A new tests for nodesFromRect that returns result from child frames.
+
+        * fast/dom/nodesFromRect/nodesFromRect-child-frame-content-expected.txt: Added.
+        * fast/dom/nodesFromRect/nodesFromRect-child-frame-content.html: Added.
+        * fast/dom/nodesFromRect/nodesFromRect-continuation-crash.html:
+        * fast/dom/nodesFromRect/resources/child-frame.html: Added.
+        * fast/dom/nodesFromRect/resources/nodesFromRect.js:
+        (check):
+        (checkShadowContent):
+        (nodesFromRectAsString):
+
 2013-02-22  Zan Dobersek  <[email protected]>
 
         Unreviewed GTK gardening.

Added: trunk/LayoutTests/fast/dom/nodesFromRect/nodesFromRect-child-frame-content-expected.txt (0 => 143727)


--- trunk/LayoutTests/fast/dom/nodesFromRect/nodesFromRect-child-frame-content-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/nodesFromRect/nodesFromRect-child-frame-content-expected.txt	2013-02-22 14:46:35 UTC (rev 143727)
@@ -0,0 +1,18 @@
+
+Document::nodesFromRect : Allow child-frame content - bug 95204
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS All correct nodes found for rect
+PASS All correct nodes found for rect
+PASS All correct nodes found for rect
+PASS All correct nodes found for rect
+PASS All correct nodes found for rect
+PASS All correct nodes found for rect
+PASS All correct nodes found for rect
+PASS All correct nodes found for rect
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/dom/nodesFromRect/nodesFromRect-child-frame-content.html (0 => 143727)


--- trunk/LayoutTests/fast/dom/nodesFromRect/nodesFromRect-child-frame-content.html	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/nodesFromRect/nodesFromRect-child-frame-content.html	2013-02-22 14:46:35 UTC (rev 143727)
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>Document::nodesFromRect : Allow child-frame content - bug 95204</title>
+    <script src=""
+    <script src=""
+    <style>
+        body { margin: 0px; }
+        #sandbox {
+            width: 400px;
+            height: 200px;
+        }
+        #sandbox #layer {
+            float: right;
+        }
+        #sandbox iframe {
+            display: block;
+            box-sizing: border-box;
+            width: 200px;
+            height: 200px;
+            border: none;
+        }
+        .rotate180 { -webkit-transform: rotate(180deg); }
+        .rotate90 { -webkit-transform: rotate(90deg); }
+        #sandbox .box {
+            box-sizing: border-box;
+            height: 100px;
+            width: 200px;
+            border: 1px solid black;
+        }
+    </style>
+</head>
+<body id="body">
+    <div id=sandbox>
+        <div id=layer>
+            <iframe id="iframe1" src=""
+        </div>
+        <div id=div1 class=box></div>
+        <div id=div2 class=box></div>
+    </div>
+
+    <p id='description'></p>
+    <div id="console"></div>
+    <script type="application/_javascript_">
+        function runTest()
+        {
+            description(document.title);
+
+            // Set up shortcut access to elements
+            var e = {};
+            ['sandbox', 'layer'].forEach(function(a) {
+                e[a] = document.getElementById(a);
+            });
+
+            checkRect(25, 25, 100, 100, "DIV#div2, DIV#div1, DIV#sandbox");
+            checkRect(220, 20, 70, 70, "DIV#left");
+            checkRect(250, 20, 100, 70, "DIV#right, DIV#left, HTML");
+
+            checkRect(150, 50, 100, 100, "DIV#left, HTML, #document, IFRAME#iframe1, DIV#layer, DIV#div2, DIV#div1, DIV#sandbox");
+
+            e.layer.setAttribute('class', 'rotate180');
+            checkRect(220, 20, 70, 70, "DIV#right");
+            checkRect(150, 50, 100, 100, "DIV#right, HTML, #document, IFRAME#iframe1, DIV#layer, DIV#div2, DIV#div1, DIV#sandbox");
+
+            e.layer.setAttribute('class', 'rotate90');
+            checkRect(250, 20, 100, 70, "DIV#left");
+            checkRect(150, 20, 200, 60, "DIV#left, HTML, #document, IFRAME#iframe1, DIV#layer, DIV#div1, DIV#sandbox");
+
+            e.sandbox.display = 'none';
+            finishJSTest();
+        }
+        jsTestIsAsync = true;
+        window._onload_ = runTest;
+    </script>
+    <script src=""
+</body>
+</html>

Modified: trunk/LayoutTests/fast/dom/nodesFromRect/nodesFromRect-continuation-crash.html (143726 => 143727)


--- trunk/LayoutTests/fast/dom/nodesFromRect/nodesFromRect-continuation-crash.html	2013-02-22 14:39:42 UTC (rev 143726)
+++ trunk/LayoutTests/fast/dom/nodesFromRect/nodesFromRect-continuation-crash.html	2013-02-22 14:46:35 UTC (rev 143727)
@@ -7,7 +7,7 @@
 window._onload_ = function() {
     if (!window.internals)
         alert("This test requires window.internals");
-    var nodes = internals.nodesFromRect(document, 100, 100, 20, 20, 20, 20, false, false);
+    var nodes = internals.nodesFromRect(document, 100, 100, 20, 20, 20, 20, false, false, false);
     alert("PASS: This test did not trigger an ASSERT");
 };
 </script>

Added: trunk/LayoutTests/fast/dom/nodesFromRect/resources/child-frame.html (0 => 143727)


--- trunk/LayoutTests/fast/dom/nodesFromRect/resources/child-frame.html	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/nodesFromRect/resources/child-frame.html	2013-02-22 14:46:35 UTC (rev 143727)
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style type="text/css">
+    body { margin: 0px; }
+    div { 
+        box-sizing: border-box;
+        border: 1px solid black;
+    }
+    #left {
+        float:left;
+        width: 90px;
+        height: 190px;
+    }
+    #right {
+        float:right;
+        width: 90px;
+        height: 190px;
+    }
+</style>
+</head>
+<body>
+    <div id=left></div>
+    <div id=right></div>
+</body>
+</html>
+

Modified: trunk/LayoutTests/fast/dom/nodesFromRect/resources/nodesFromRect.js (143726 => 143727)


--- trunk/LayoutTests/fast/dom/nodesFromRect/resources/nodesFromRect.js	2013-02-22 14:39:42 UTC (rev 143726)
+++ trunk/LayoutTests/fast/dom/nodesFromRect/resources/nodesFromRect.js	2013-02-22 14:46:35 UTC (rev 143727)
@@ -1,7 +1,8 @@
 /*
  * Contributors:
  *     * Antonio Gomes <[email protected]>
- **/
+ *     * Allan Sandfeld Jensen <[email protected]>
+**/
 
 function check(x, y, topPadding, rightPadding, bottomPadding, leftPadding, list, doc)
 {
@@ -11,7 +12,7 @@
   if (!doc)
     doc = document;
 
-  var nodes = internals.nodesFromRect(doc, x, y, topPadding, rightPadding, bottomPadding, leftPadding, true /* ignoreClipping */, false /* allow shadow content */);
+  var nodes = internals.nodesFromRect(doc, x, y, topPadding, rightPadding, bottomPadding, leftPadding, true /* ignoreClipping */, false /* allow shadow content */, false /* allow child-frame content */);
   if (!nodes)
     return;
 
@@ -45,7 +46,7 @@
   if (!doc)
     doc = document;
 
-  var nodes = internals.nodesFromRect(doc, x, y, topPadding, rightPadding, bottomPadding, leftPadding, true /* ignoreClipping */, true /* allowShadowContent */);
+  var nodes = internals.nodesFromRect(doc, x, y, topPadding, rightPadding, bottomPadding, leftPadding, true /* ignoreClipping */, true /* allowShadowContent */, false /* allow child-frame content */);
   if (!nodes)
     return;
 
@@ -96,7 +97,7 @@
 function nodesFromRectAsString(doc, x, y, topPadding, rightPadding, bottomPadding, leftPadding)
 {
     var nodeString = "";
-    var nodes = internals.nodesFromRect(doc, x, y, topPadding, rightPadding, bottomPadding, leftPadding, true /* ignoreClipping */, false /* allow shadow content */);
+    var nodes = internals.nodesFromRect(doc, x, y, topPadding, rightPadding, bottomPadding, leftPadding, true /* ignoreClipping */, false /* allow shadow content */, true /* allow child-frame content */);
     if (!nodes)
         return nodeString;
 
@@ -110,6 +111,8 @@
             }
         } else if (nodes[i].nodeType == 3) {
             nodeString += "'" + nodes[i].data + "'";
+        } else if (nodes[i].nodeType == 9) {
+            nodeString += "#document";
         } else {
             continue;
         }
@@ -120,7 +123,6 @@
     return nodeString;
 }
 
-
 function getCenterFor(element)
 {
   var rect = element.getBoundingClientRect();

Modified: trunk/Source/WebCore/ChangeLog (143726 => 143727)


--- trunk/Source/WebCore/ChangeLog	2013-02-22 14:39:42 UTC (rev 143726)
+++ trunk/Source/WebCore/ChangeLog	2013-02-22 14:46:35 UTC (rev 143727)
@@ -1,3 +1,62 @@
+2013-02-22  Allan Sandfeld Jensen  <[email protected]>
+
+        Allow child-frame content in hit-tests.
+        https://bugs.webkit.org/show_bug.cgi?id=95204
+
+        Reviewed by Julien Chaffraix.
+
+        Refactors how EventHandler::hitTestResultAtPoint handles child-frame content,
+        it is now handled by the hit test itself controlled by the AllowChildFrameContent
+        flag in HitTestRequest.
+
+        This means that area-based hit-tests can now return elements from all the child frames
+        they intersect instead of just the one frame containing the center point. The improved
+        results from area-based hit-tests will among other things also improve touch adjustment
+        near frame boundaries.
+
+        Tests: fast/dom/nodesFromRect/nodesFromRect-child-frame-content.html
+
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::hitTestResultAtPoint):
+            Recursion into child-frames have been moved to RenderFrameBase::nodeAtPoint, so
+            now hitTestResultAtPoint just needs to set AllowChildFrameContent.
+        * page/TouchAdjustment.cpp:
+        (WebCore::TouchAdjustment::parentShadowHostOrOwner):
+            New function to iterate up across frame boundaries.
+        (WebCore::TouchAdjustment::compileSubtargetList):
+            We need to iterate up across frame boundaries to avoid iframes competing with their
+            own content for touch adjustment.
+        * rendering/HitTestRequest.h:
+        (WebCore::HitTestRequest::allowsChildFrameContent):
+        (WebCore::HitTestRequest::isChildFrameHitTest):
+        * rendering/HitTestResult.cpp:
+        (WebCore::HitTestResult::HitTestResult):
+        (WebCore::HitTestResult::operator=):
+        (WebCore::HitTestResult::append):
+        (WebCore::HitTestResult::dictationAlternatives):
+        * rendering/HitTestResult.h:
+        (WebCore::HitTestResult::pointInMainFrame):
+        (WebCore::HitTestResult::pointInInnerNodeFrame):
+        (HitTestResult):
+            m_hitTestLocation is now in main frame coordinates, which make m_pointInMainFrame
+            unnecessary, but requires the introduction of m_pointInInnerFrame, to remember
+            the coordinates of inner-node in its own frame.
+        * rendering/RenderFrameBase.cpp:
+        (WebCore::RenderFrameBase::nodeAtPoint):
+            The recursion into child-frames is now handled here instead of in hitTestResultAtPoint, this
+            allows us to recurse into multiple frames, instead of just one.
+        * rendering/RenderFrameBase.h:
+        (RenderFrameBase):
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::hitTest):
+            RenderLayer should not lie about being hit if the request is child-frame request.
+        * testing/Internals.cpp:
+        (WebCore::Internals::nodesFromRect):
+        * testing/Internals.h:
+        (Internals):
+        * testing/Internals.idl:
+            Extended so nodesFromRect with child-frame content can be tested.
+
 2013-02-22  Andreas Kling  <[email protected]>
 
         ShareableElementData should use zero-length array for storage.

Modified: trunk/Source/WebCore/page/EventHandler.cpp (143726 => 143727)


--- trunk/Source/WebCore/page/EventHandler.cpp	2013-02-22 14:39:42 UTC (rev 143726)
+++ trunk/Source/WebCore/page/EventHandler.cpp	2013-02-22 14:46:35 UTC (rev 143727)
@@ -1026,35 +1026,10 @@
     if (!m_frame->contentRenderer())
         return result;
 
-    HitTestRequest request(hitType);
+    // hitTestResultAtPoint is specifically used to hitTest into all frames, thus it always allows child frame content.
+    HitTestRequest request(hitType | HitTestRequest::AllowChildFrameContent);
     m_frame->contentRenderer()->hitTest(request, result);
 
-    while (true) {
-        Node* n = result.innerNode();
-        if (!result.isOverWidget() || !n || !n->renderer() || !n->renderer()->isWidget())
-            break;
-        RenderWidget* renderWidget = toRenderWidget(n->renderer());
-        Widget* widget = renderWidget->widget();
-        if (!widget || !widget->isFrameView())
-            break;
-        Frame* frame = static_cast<HTMLFrameElementBase*>(n)->contentFrame();
-        if (!frame || !frame->contentRenderer())
-            break;
-        FrameView* view = static_cast<FrameView*>(widget);
-        LayoutPoint widgetPoint(result.localPoint().x() + view->scrollX() - renderWidget->borderLeft() - renderWidget->paddingLeft(), 
-            result.localPoint().y() + view->scrollY() - renderWidget->borderTop() - renderWidget->paddingTop());
-        HitTestResult widgetHitTestResult(widgetPoint, padding.height(), padding.width(), padding.height(), padding.width());
-        widgetHitTestResult.setPointInMainFrame(result.pointInMainFrame());
-        frame->contentRenderer()->hitTest(request, widgetHitTestResult);
-        result = widgetHitTestResult;
-
-        if (request.allowsFrameScrollbars()) {
-            Scrollbar* eventScrollbar = view->scrollbarAtPoint(roundedIntPoint(point));
-            if (eventScrollbar)
-                result.setScrollbar(eventScrollbar);
-        }
-    }
-
     if (!request.allowsShadowContent())
         result.setToNonShadowAncestor();
 

Modified: trunk/Source/WebCore/page/TouchAdjustment.cpp (143726 => 143727)


--- trunk/Source/WebCore/page/TouchAdjustment.cpp	2013-02-22 14:39:42 UTC (rev 143726)
+++ trunk/Source/WebCore/page/TouchAdjustment.cpp	2013-02-22 14:46:35 UTC (rev 143727)
@@ -25,6 +25,7 @@
 #include "FloatPoint.h"
 #include "FloatQuad.h"
 #include "FrameView.h"
+#include "HTMLFrameOwnerElement.h"
 #include "HTMLInputElement.h"
 #include "HTMLLabelElement.h"
 #include "HTMLNames.h"
@@ -221,6 +222,15 @@
         subtargets.append(SubtargetGeometry(node, *it));
 }
 
+static inline Node* parentShadowHostOrOwner(const Node* node)
+{
+    if (Node* ancestor = node->parentOrShadowHostNode())
+        return ancestor;
+    if (node->isDocumentNode())
+        return static_cast<const Document*>(node)->ownerElement();
+    return 0;
+}
+
 // Compiles a list of subtargets of all the relevant target nodes.
 void compileSubtargetList(const NodeList& intersectedNodes, SubtargetGeometryList& subtargets, NodeFilter nodeFilter, AppendSubtargetsForNode appendSubtargetsForNode)
 {
@@ -248,7 +258,7 @@
             if (nodeFilter(visitedNode)) {
                 respondingNode = visitedNode;
                 // Continue the iteration to collect the ancestors of the responder, which we will need later.
-                for (visitedNode = visitedNode->parentOrShadowHostNode(); visitedNode; visitedNode = visitedNode->parentOrShadowHostNode()) {
+                for (visitedNode = parentShadowHostOrOwner(visitedNode); visitedNode; visitedNode = parentShadowHostOrOwner(visitedNode)) {
                     HashSet<Node*>::AddResult addResult = ancestorsToRespondersSet.add(visitedNode);
                     if (!addResult.isNewEntry)
                         break;

Modified: trunk/Source/WebCore/rendering/HitTestRequest.h (143726 => 143727)


--- trunk/Source/WebCore/rendering/HitTestRequest.h	2013-02-22 14:39:42 UTC (rev 143726)
+++ trunk/Source/WebCore/rendering/HitTestRequest.h	2013-02-22 14:46:35 UTC (rev 143727)
@@ -36,7 +36,9 @@
         SVGClipContent = 1 << 6,
         TouchEvent = 1 << 7,
         AllowShadowContent = 1 << 8,
-        AllowFrameScrollbars = 1 << 9
+        AllowFrameScrollbars = 1 << 9,
+        AllowChildFrameContent = 1 << 10,
+        ChildFrameHitTest = 1 << 11
     };
 
     typedef unsigned HitTestRequestType;
@@ -56,6 +58,8 @@
     bool mouseEvent() const { return !touchEvent(); }
     bool allowsShadowContent() const { return m_requestType & AllowShadowContent; }
     bool allowsFrameScrollbars() const { return m_requestType & AllowFrameScrollbars; }
+    bool allowsChildFrameContent() const { return m_requestType & AllowChildFrameContent; }
+    bool isChildFrameHitTest() const { return m_requestType & ChildFrameHitTest; }
 
     // Convenience functions
     bool touchMove() const { return move() && touchEvent(); }

Modified: trunk/Source/WebCore/rendering/HitTestResult.cpp (143726 => 143727)


--- trunk/Source/WebCore/rendering/HitTestResult.cpp	2013-02-22 14:39:42 UTC (rev 143726)
+++ trunk/Source/WebCore/rendering/HitTestResult.cpp	2013-02-22 14:46:35 UTC (rev 143727)
@@ -199,21 +199,21 @@
 
 HitTestResult::HitTestResult(const LayoutPoint& point)
     : m_hitTestLocation(point)
-    , m_pointInMainFrame(point)
+    , m_pointInInnerNodeFrame(point)
     , m_isOverWidget(false)
 {
 }
 
 HitTestResult::HitTestResult(const LayoutPoint& centerPoint, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding)
     : m_hitTestLocation(centerPoint, topPadding, rightPadding, bottomPadding, leftPadding)
-    , m_pointInMainFrame(centerPoint)
+    , m_pointInInnerNodeFrame(centerPoint)
     , m_isOverWidget(false)
 {
 }
 
 HitTestResult::HitTestResult(const HitTestLocation& other)
     : m_hitTestLocation(other)
-    , m_pointInMainFrame(m_hitTestLocation.point())
+    , m_pointInInnerNodeFrame(m_hitTestLocation.point())
     , m_isOverWidget(false)
 {
 }
@@ -222,7 +222,7 @@
     : m_hitTestLocation(other.m_hitTestLocation)
     , m_innerNode(other.innerNode())
     , m_innerNonSharedNode(other.innerNonSharedNode())
-    , m_pointInMainFrame(other.m_pointInMainFrame)
+    , m_pointInInnerNodeFrame(other.m_pointInInnerNodeFrame)
     , m_localPoint(other.localPoint())
     , m_innerURLElement(other.URLElement())
     , m_scrollbar(other.scrollbar())
@@ -241,7 +241,7 @@
     m_hitTestLocation = other.m_hitTestLocation;
     m_innerNode = other.innerNode();
     m_innerNonSharedNode = other.innerNonSharedNode();
-    m_pointInMainFrame = other.m_pointInMainFrame;
+    m_pointInInnerNodeFrame = other.m_pointInInnerNodeFrame;
     m_localPoint = other.localPoint();
     m_innerURLElement = other.URLElement();
     m_scrollbar = other.scrollbar();
@@ -735,7 +735,7 @@
         m_innerNode = other.innerNode();
         m_innerNonSharedNode = other.innerNonSharedNode();
         m_localPoint = other.localPoint();
-        m_pointInMainFrame = other.m_pointInMainFrame;
+        m_pointInInnerNodeFrame = other.m_pointInInnerNodeFrame;
         m_innerURLElement = other.URLElement();
         m_scrollbar = other.scrollbar();
         m_isOverWidget = other.isOverWidget();
@@ -768,7 +768,7 @@
     if (!m_innerNonSharedNode)
         return Vector<String>();
 
-    DocumentMarker* marker = m_innerNonSharedNode->document()->markers()->markerContainingPoint(hitTestLocation().point(), DocumentMarker::DictationAlternatives);
+    DocumentMarker* marker = m_innerNonSharedNode->document()->markers()->markerContainingPoint(pointInInnerNodeFrame(), DocumentMarker::DictationAlternatives);
     if (!marker)
         return Vector<String>();
 

Modified: trunk/Source/WebCore/rendering/HitTestResult.h (143726 => 143727)


--- trunk/Source/WebCore/rendering/HitTestResult.h	2013-02-22 14:39:42 UTC (rev 143726)
+++ trunk/Source/WebCore/rendering/HitTestResult.h	2013-02-22 14:46:35 UTC (rev 143727)
@@ -125,12 +125,11 @@
     bool isRectBasedTest() const { return m_hitTestLocation.isRectBasedTest(); }
 
     // The hit-tested point in the coordinates of the main frame.
-    const LayoutPoint& pointInMainFrame() const { return m_pointInMainFrame; }
+    const LayoutPoint& pointInMainFrame() const { return m_hitTestLocation.point(); }
     IntPoint roundedPointInMainFrame() const { return roundedIntPoint(pointInMainFrame()); }
-    void setPointInMainFrame(const LayoutPoint& p) { m_pointInMainFrame = p; }
 
     // The hit-tested point in the coordinates of the innerNode frame, the frame containing innerNode.
-    const LayoutPoint& pointInInnerNodeFrame() const { return m_hitTestLocation.point(); }
+    const LayoutPoint& pointInInnerNodeFrame() const { return m_pointInInnerNodeFrame; }
     IntPoint roundedPointInInnerNodeFrame() const { return roundedIntPoint(pointInInnerNodeFrame()); }
     Frame* innerNodeFrame() const;
 
@@ -203,7 +202,7 @@
 
     RefPtr<Node> m_innerNode;
     RefPtr<Node> m_innerNonSharedNode;
-    LayoutPoint m_pointInMainFrame; // The hit-tested point in main-frame coordinates.
+    LayoutPoint m_pointInInnerNodeFrame; // The hit-tested point in innerNode frame coordinates.
     LayoutPoint m_localPoint; // A point in the local coordinate space of m_innerNonSharedNode's renderer. Allows us to efficiently
                               // determine where inside the renderer we hit on subsequent operations.
     RefPtr<Element> m_innerURLElement;

Modified: trunk/Source/WebCore/rendering/RenderFrameBase.cpp (143726 => 143727)


--- trunk/Source/WebCore/rendering/RenderFrameBase.cpp	2013-02-22 14:39:42 UTC (rev 143726)
+++ trunk/Source/WebCore/rendering/RenderFrameBase.cpp	2013-02-22 14:46:35 UTC (rev 143727)
@@ -29,6 +29,8 @@
 #include "Frame.h"
 #include "FrameView.h"
 #include "HTMLFrameElementBase.h"
+#include "HitTestResult.h"
+#include "RenderLayer.h"
 #include "RenderView.h"
 
 namespace WebCore {
@@ -102,4 +104,38 @@
     setNeedsLayout(false);
 }
 
+bool RenderFrameBase::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action)
+{
+    if (!request.allowsChildFrameContent())
+        return RenderPart::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, action);
+
+    ASSERT_WITH_SECURITY_IMPLICATION(!widget() || widget()->isFrameView());
+    FrameView* childFrameView = static_cast<FrameView*>(widget());
+    RenderView* childRoot = childFrameView ? childFrameView->renderView() : 0;
+
+    if (childRoot) {
+        LayoutPoint adjustedLocation = accumulatedOffset + location();
+        LayoutPoint contentOffset = LayoutPoint(borderLeft() + paddingLeft(), borderTop() + paddingTop()) - childFrameView->scrollOffset();
+        HitTestLocation newHitTestLocation(locationInContainer, -adjustedLocation - contentOffset);
+        HitTestRequest newHitTestRequest(request.type() | HitTestRequest::ChildFrameHitTest);
+        HitTestResult childFrameResult(newHitTestLocation);
+
+        bool isInsideChildFrame = childRoot->hitTest(newHitTestRequest, newHitTestLocation, childFrameResult);
+        result.append(childFrameResult);
+        if (isInsideChildFrame)
+            return true;
+
+        if (request.allowsFrameScrollbars()) {
+            // ScrollView scrollbars are not the same as RenderLayer scrollbars tested by RenderLayer::hitTestOverflowControls,
+            // so we need to test ScrollView scrollbars separately here.
+            // FIXME: Consider if this test could be done unconditionally.
+            Scrollbar* frameScrollbar = childFrameView->scrollbarAtPoint(newHitTestLocation.roundedPoint());
+            if (frameScrollbar)
+                result.setScrollbar(frameScrollbar);
+        }
+    }
+
+    return RenderPart::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, action);
 }
+
+}

Modified: trunk/Source/WebCore/rendering/RenderFrameBase.h (143726 => 143727)


--- trunk/Source/WebCore/rendering/RenderFrameBase.h	2013-02-22 14:39:42 UTC (rev 143726)
+++ trunk/Source/WebCore/rendering/RenderFrameBase.h	2013-02-22 14:46:35 UTC (rev 143727)
@@ -36,6 +36,7 @@
     explicit RenderFrameBase(Element*);
 
 public:
+    virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
     void layoutWithFlattening(bool fixedWidth, bool fixedHeight);
 };
 

Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (143726 => 143727)


--- trunk/Source/WebCore/rendering/RenderLayer.cpp	2013-02-22 14:39:42 UTC (rev 143726)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp	2013-02-22 14:46:35 UTC (rev 143727)
@@ -4013,7 +4013,7 @@
         // We didn't hit any layer. If we are the root layer and the mouse is -- or just was -- down, 
         // return ourselves. We do this so mouse events continue getting delivered after a drag has 
         // exited the WebView, and so hit testing over a scrollbar hits the content document.
-        if ((request.active() || request.release()) && isRootLayer()) {
+        if (!request.isChildFrameHitTest() && (request.active() || request.release()) && isRootLayer()) {
             renderer()->updateHitTestResult(result, toRenderView(renderer())->flipForWritingMode(hitTestLocation.point()));
             insideLayer = this;
         }

Modified: trunk/Source/WebCore/testing/Internals.cpp (143726 => 143727)


--- trunk/Source/WebCore/testing/Internals.cpp	2013-02-22 14:39:42 UTC (rev 143726)
+++ trunk/Source/WebCore/testing/Internals.cpp	2013-02-22 14:46:35 UTC (rev 143727)
@@ -1398,7 +1398,7 @@
 #endif
 
 PassRefPtr<NodeList> Internals::nodesFromRect(Document* document, int x, int y, unsigned topPadding, unsigned rightPadding,
-    unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent, ExceptionCode& ec) const
+    unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent, bool allowChildFrameContent, ExceptionCode& ec) const
 {
     if (!document || !document->frame() || !document->frame()->view()) {
         ec = INVALID_ACCESS_ERR;
@@ -1410,6 +1410,8 @@
         hitType |= HitTestRequest::IgnoreClipping;
     if (allowShadowContent)
         hitType |= HitTestRequest::AllowShadowContent;
+    if (allowChildFrameContent)
+        hitType |= HitTestRequest::AllowChildFrameContent;
 
     return document->nodesFromRect(x, y, topPadding, rightPadding, bottomPadding, leftPadding, hitType);
 }

Modified: trunk/Source/WebCore/testing/Internals.h (143726 => 143727)


--- trunk/Source/WebCore/testing/Internals.h	2013-02-22 14:39:42 UTC (rev 143726)
+++ trunk/Source/WebCore/testing/Internals.h	2013-02-22 14:46:35 UTC (rev 143727)
@@ -190,7 +190,7 @@
 #endif
 
     PassRefPtr<NodeList> nodesFromRect(Document*, int x, int y, unsigned topPadding, unsigned rightPadding,
-        unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent, ExceptionCode&) const;
+        unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent, bool allowChildFrameContent, ExceptionCode&) const;
 
     void emitInspectorDidBeginFrame();
     void emitInspectorDidCancelFrame();

Modified: trunk/Source/WebCore/testing/Internals.idl (143726 => 143727)


--- trunk/Source/WebCore/testing/Internals.idl	2013-02-22 14:39:42 UTC (rev 143726)
+++ trunk/Source/WebCore/testing/Internals.idl	2013-02-22 14:46:35 UTC (rev 143727)
@@ -158,7 +158,7 @@
 
     NodeList nodesFromRect(in Document document, in long x, in long y,
         in unsigned long topPadding, in unsigned long rightPadding, in unsigned long bottomPadding, in unsigned long leftPadding,
-        in boolean ignoreClipping, in boolean allowShadowContent) raises (DOMException);
+        in boolean ignoreClipping, in boolean allowShadowContent, in boolean allowChildFrameContent) raises (DOMException);
 
     void emitInspectorDidBeginFrame();
     void emitInspectorDidCancelFrame();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to