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();