Diff
Modified: trunk/LayoutTests/ChangeLog (92992 => 92993)
--- trunk/LayoutTests/ChangeLog 2011-08-12 21:01:45 UTC (rev 92992)
+++ trunk/LayoutTests/ChangeLog 2011-08-12 21:02:19 UTC (rev 92993)
@@ -1,3 +1,17 @@
+2011-08-12 David Hyatt <[email protected]>
+
+ https://bugs.webkit.org/show_bug.cgi?id=66133
+
+ Make hit testing work on RenderRegions. Pass off the hit testing to the RenderFlowThread
+ layer tree (just as we did with painting).
+
+ Reviewed by Sam Weinig.
+
+ Added hit-test-float.html to demonstrate basic hit testing of content flowed into regions.
+
+ * fast/regions/hit-test-float-expected.txt: Added.
+ * fast/regions/hit-test-float.html: Added.
+
2011-08-12 Ryosuke Niwa <[email protected]>
Skip the test added by r92982 on Qt since it uses a new layoutTestController method
Added: trunk/LayoutTests/fast/regions/hit-test-float-expected.txt (0 => 92993)
--- trunk/LayoutTests/fast/regions/hit-test-float-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/regions/hit-test-float-expected.txt 2011-08-12 21:02:19 UTC (rev 92993)
@@ -0,0 +1,3 @@
+Test for hit-testing of floats inside CSS Regions.
+
+PASS
Added: trunk/LayoutTests/fast/regions/hit-test-float.html (0 => 92993)
--- trunk/LayoutTests/fast/regions/hit-test-float.html (rev 0)
+++ trunk/LayoutTests/fast/regions/hit-test-float.html 2011-08-12 21:02:19 UTC (rev 92993)
@@ -0,0 +1,28 @@
+<style>
+ #target { width: 50px; height: 50px; background-color: green; margin: 10px; }
+</style>
+<p>
+ Test for hit-testing of floats inside CSS Regions.
+</p>
+<div style="position:relative; margin: 100px; width: 300px; height: 200px; outline: solid black;">
+ <div style="position:absolute;left:0;top:0;content: -webkit-from-flow('flow'); width:150px;height:200px;"></div>
+ <div style="position:absolute;left:150px;top:0;content: -webkit-from-flow('flow'); width:150px;height:200px"></div>
+ <div style="-webkit-flow: 'flow'">
+ <div style="height: 250px; background-color: purple;"></div>
+ <div style="float: right; background-color: lightyellow; margin: 5px;">
+ <div id="target"></div>
+ </div>
+ </div>
+</div>
+<div id="result">FAIL: Test did not run.</div>
+<script>
+ if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+ var result = document.getElementById("result");
+ var hitElement = document.elementFromPoint(370, 230);
+ if (hitElement === document.getElementById("target"))
+ result.innerText = "PASS";
+ else
+ result.innerText = "FAIL: Hit " + hitElement;
+</script>
Modified: trunk/Source/WebCore/ChangeLog (92992 => 92993)
--- trunk/Source/WebCore/ChangeLog 2011-08-12 21:01:45 UTC (rev 92992)
+++ trunk/Source/WebCore/ChangeLog 2011-08-12 21:02:19 UTC (rev 92993)
@@ -1,3 +1,24 @@
+2011-08-12 David Hyatt <[email protected]>
+
+ https://bugs.webkit.org/show_bug.cgi?id=66133
+
+ Make hit testing work on RenderRegions. Pass off the hit testing to the RenderFlowThread
+ layer tree (just as we did with painting).
+
+ Reviewed by Sam Weinig.
+
+ Added hit-test-float.html to demonstrate basic hit testing of content flowed into regions.
+
+ * rendering/HitTestRequest.h:
+ (WebCore::HitTestRequest::type):
+ * rendering/RenderFlowThread.cpp:
+ (WebCore::RenderFlowThread::hitTestRegion):
+ * rendering/RenderFlowThread.h:
+ * rendering/RenderRegion.cpp:
+ (WebCore::RenderRegion::paintReplaced):
+ (WebCore::RenderRegion::nodeAtPoint):
+ * rendering/RenderRegion.h:
+
2011-08-12 Levi Weintraub <[email protected]>
Switch RenderTable* to new layout types
Modified: trunk/Source/WebCore/rendering/HitTestRequest.h (92992 => 92993)
--- trunk/Source/WebCore/rendering/HitTestRequest.h 2011-08-12 21:01:45 UTC (rev 92992)
+++ trunk/Source/WebCore/rendering/HitTestRequest.h 2011-08-12 21:02:19 UTC (rev 92993)
@@ -49,6 +49,8 @@
bool ignoreClipping() const { return m_requestType & IgnoreClipping; }
bool svgClipContent() const { return m_requestType & SVGClipContent; }
+ HitTestRequestType type() const { return m_requestType; }
+
private:
HitTestRequestType m_requestType;
};
Modified: trunk/Source/WebCore/rendering/RenderFlowThread.cpp (92992 => 92993)
--- trunk/Source/WebCore/rendering/RenderFlowThread.cpp 2011-08-12 21:01:45 UTC (rev 92992)
+++ trunk/Source/WebCore/rendering/RenderFlowThread.cpp 2011-08-12 21:02:19 UTC (rev 92993)
@@ -30,6 +30,8 @@
#include "config.h"
#include "RenderFlowThread.h"
+#include "HitTestRequest.h"
+#include "HitTestResult.h"
#include "Node.h"
#include "PaintInfo.h"
#include "RenderLayer.h"
@@ -263,4 +265,34 @@
}
}
+bool RenderFlowThread::hitTestRegion(const LayoutRect& regionRect, const HitTestRequest& request, HitTestResult& result, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset)
+{
+ LayoutRect regionClippingRect(accumulatedOffset, regionRect.size());
+ if (!regionClippingRect.contains(pointInContainer))
+ return false;
+
+ LayoutPoint renderFlowThreadOffset;
+ if (style()->isFlippedBlocksWritingMode()) {
+ LayoutRect flippedRegionRect(regionRect);
+ flipForWritingMode(flippedRegionRect);
+ renderFlowThreadOffset = LayoutPoint(regionClippingRect.location() - flippedRegionRect.location());
+ } else
+ renderFlowThreadOffset = LayoutPoint(regionClippingRect.location() - regionRect.location());
+
+ LayoutPoint transformedPoint(pointInContainer.x() - renderFlowThreadOffset.x(), pointInContainer.y() - renderFlowThreadOffset.y());
+
+ // Always ignore clipping, since the RenderFlowThread has nothing to do with the bounds of the FrameView.
+ HitTestRequest newRequest(request.type() & HitTestRequest::IgnoreClipping);
+
+ LayoutPoint oldPoint = result.point();
+ result.setPoint(transformedPoint);
+ bool isPointInsideFlowThread = layer()->hitTest(newRequest, result);
+ result.setPoint(oldPoint);
+
+ // FIXME: Should we set result.m_localPoint back to the RenderRegion's coordinate space or leave it in the RenderFlowThread's coordinate
+ // space? Right now it's staying in the RenderFlowThread's coordinate space, which may end up being ok. We will know more when we get around to
+ // patching positionForPoint.
+ return isPointInsideFlowThread;
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/rendering/RenderFlowThread.h (92992 => 92993)
--- trunk/Source/WebCore/rendering/RenderFlowThread.h 2011-08-12 21:01:45 UTC (rev 92992)
+++ trunk/Source/WebCore/rendering/RenderFlowThread.h 2011-08-12 21:02:19 UTC (rev 92993)
@@ -77,7 +77,8 @@
void computeLogicalWidth();
void computeLogicalHeight();
- void paintIntoRegion(PaintInfo&, const LayoutRect&, const LayoutPoint&);
+ void paintIntoRegion(PaintInfo&, const LayoutRect& regionRect, const LayoutPoint& paintOffset);
+ bool hitTestRegion(const LayoutRect& regionRect, const HitTestRequest&, HitTestResult&, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset);
bool hasRegions() const { return m_regionList.size(); }
Modified: trunk/Source/WebCore/rendering/RenderRegion.cpp (92992 => 92993)
--- trunk/Source/WebCore/rendering/RenderRegion.cpp 2011-08-12 21:01:45 UTC (rev 92992)
+++ trunk/Source/WebCore/rendering/RenderRegion.cpp 2011-08-12 21:02:19 UTC (rev 92993)
@@ -31,6 +31,7 @@
#include "RenderRegion.h"
#include "GraphicsContext.h"
+#include "HitTestResult.h"
#include "IntRect.h"
#include "PaintInfo.h"
#include "RenderFlowThread.h"
@@ -54,9 +55,31 @@
void RenderRegion::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
// Delegate painting of content in region to RenderFlowThread.
+ if (!m_flowThread)
+ return;
m_flowThread->paintIntoRegion(paintInfo, regionRect(), LayoutPoint(paintOffset.x() + borderLeft() + paddingLeft(), paintOffset.y() + borderTop() + paddingTop()));
}
+// Hit Testing
+bool RenderRegion::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action)
+{
+ LayoutPoint adjustedLocation = accumulatedOffset + location();
+
+ // Check our bounds next. For this purpose always assume that we can only be hit in the
+ // foreground phase (which is true for replaced elements like images).
+ LayoutRect boundsRect(adjustedLocation, size());
+ if (visibleToHitTesting() && action == HitTestForeground && boundsRect.intersects(result.rectForPoint(pointInContainer))) {
+ // Check the contents of the RenderFlowThread.
+ if (m_flowThread && m_flowThread->hitTestRegion(regionRect(), request, result, pointInContainer, LayoutPoint(adjustedLocation.x() + borderLeft() + paddingLeft(), adjustedLocation.y() + borderTop() + paddingTop())))
+ return true;
+ updateHitTestResult(result, pointInContainer - toLayoutSize(adjustedLocation));
+ if (!result.addNodeToRectBasedTestResult(node(), pointInContainer, boundsRect))
+ return true;
+ }
+
+ return false;
+}
+
void RenderRegion::styleDidChange(StyleDifference difference, const RenderStyle* oldStyle)
{
RenderReplaced::styleDidChange(difference, oldStyle);
Modified: trunk/Source/WebCore/rendering/RenderRegion.h (92992 => 92993)
--- trunk/Source/WebCore/rendering/RenderRegion.h 2011-08-12 21:01:45 UTC (rev 92992)
+++ trunk/Source/WebCore/rendering/RenderRegion.h 2011-08-12 21:02:19 UTC (rev 92993)
@@ -44,6 +44,7 @@
virtual bool isRenderRegion() const { return true; }
virtual void paintReplaced(PaintInfo&, const LayoutPoint&);
+ virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset, HitTestAction);
void setRegionRect(const IntRect& rect) { m_regionRect = rect; }
IntRect regionRect() const { return m_regionRect; }