summaryrefslogtreecommitdiffstats
path: root/WebCore
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore')
-rw-r--r--WebCore/config.h3
-rw-r--r--WebCore/page/EventHandler.cpp12
-rw-r--r--WebCore/page/EventHandler.h4
-rw-r--r--WebCore/rendering/EllipsisBox.cpp13
-rw-r--r--WebCore/rendering/HitTestResult.cpp63
-rw-r--r--WebCore/rendering/HitTestResult.h22
-rw-r--r--WebCore/rendering/InlineFlowBox.cpp16
-rw-r--r--WebCore/rendering/InlineTextBox.cpp12
-rw-r--r--WebCore/rendering/RenderBlock.cpp36
-rw-r--r--WebCore/rendering/RenderBox.cpp16
-rw-r--r--WebCore/rendering/RenderImage.cpp12
-rw-r--r--WebCore/rendering/RenderLayer.cpp68
-rw-r--r--WebCore/rendering/RenderLineBoxList.cpp11
-rw-r--r--WebCore/rendering/RenderSVGRoot.cpp10
-rw-r--r--WebCore/rendering/RenderTable.cpp20
-rw-r--r--WebCore/rendering/RenderTableSection.cpp7
-rw-r--r--WebCore/rendering/RenderWidget.cpp6
17 files changed, 331 insertions, 0 deletions
diff --git a/WebCore/config.h b/WebCore/config.h
index c812ee8..8e324a5 100644
--- a/WebCore/config.h
+++ b/WebCore/config.h
@@ -195,6 +195,9 @@
// Enable prefetching when specified via the rel element of <link> elements.
#define ENABLE_LINK_PREFETCH 1
+// Enable hit test with point plus a size
+#define ANDROID_HITTEST_WITHSIZE
+
#endif /* PLATFORM(ANDROID) */
#ifdef __cplusplus
diff --git a/WebCore/page/EventHandler.cpp b/WebCore/page/EventHandler.cpp
index 8f63144..042f3d4 100644
--- a/WebCore/page/EventHandler.cpp
+++ b/WebCore/page/EventHandler.cpp
@@ -865,9 +865,17 @@ void EventHandler::allowDHTMLDrag(bool& flagDHTML, bool& flagUA) const
}
#endif // ENABLE(DRAG_SUPPORT)
+#ifdef ANDROID_HITTEST_WITHSIZE
+HitTestResult EventHandler::hitTestResultAtPoint(const IntPoint& point, bool allowShadowContent, bool ignoreClipping, HitTestScrollbars testScrollbars, const IntSize& pointPadding)
+#else
HitTestResult EventHandler::hitTestResultAtPoint(const IntPoint& point, bool allowShadowContent, bool ignoreClipping, HitTestScrollbars testScrollbars)
+#endif
{
+#ifdef ANDROID_HITTEST_WITHSIZE
+ HitTestResult result(point, pointPadding);
+#else
HitTestResult result(point);
+#endif
if (!m_frame->contentRenderer())
return result;
int hitType = HitTestRequest::ReadOnly | HitTestRequest::Active;
@@ -889,7 +897,11 @@ HitTestResult EventHandler::hitTestResultAtPoint(const IntPoint& point, bool all
FrameView* view = static_cast<FrameView*>(widget);
IntPoint widgetPoint(result.localPoint().x() + view->scrollX() - renderWidget->borderLeft() - renderWidget->paddingLeft(),
result.localPoint().y() + view->scrollY() - renderWidget->borderTop() - renderWidget->paddingTop());
+#ifdef ANDROID_HITTEST_WITHSIZE
+ HitTestResult widgetHitTestResult(widgetPoint, pointPadding);
+#else
HitTestResult widgetHitTestResult(widgetPoint);
+#endif
frame->contentRenderer()->layer()->hitTest(HitTestRequest(hitType), widgetHitTestResult);
result = widgetHitTestResult;
diff --git a/WebCore/page/EventHandler.h b/WebCore/page/EventHandler.h
index c83925c..39b165d 100644
--- a/WebCore/page/EventHandler.h
+++ b/WebCore/page/EventHandler.h
@@ -105,7 +105,11 @@ public:
void dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad&);
+#ifdef ANDROID_HITTEST_WITHSIZE
+ HitTestResult hitTestResultAtPoint(const IntPoint&, bool allowShadowContent, bool ignoreClipping = false, HitTestScrollbars scrollbars = DontHitTestScrollbars, const IntSize& pointPadding = IntSize());
+#else
HitTestResult hitTestResultAtPoint(const IntPoint&, bool allowShadowContent, bool ignoreClipping = false, HitTestScrollbars scrollbars = DontHitTestScrollbars);
+#endif
bool mousePressed() const { return m_mousePressed; }
void setMousePressed(bool pressed) { m_mousePressed = pressed; }
diff --git a/WebCore/rendering/EllipsisBox.cpp b/WebCore/rendering/EllipsisBox.cpp
index 6f25861..4a64fe4 100644
--- a/WebCore/rendering/EllipsisBox.cpp
+++ b/WebCore/rendering/EllipsisBox.cpp
@@ -113,8 +113,21 @@ bool EllipsisBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
}
}
+#ifdef ANDROID_HITTEST_WITHSIZE
+ IntRect boundsRect = IntRect(tx, ty, m_width, m_height);
+ if (visibleToHitTesting() && result.intersects(x, y, boundsRect)) {
+#else
if (visibleToHitTesting() && IntRect(tx, ty, m_width, m_height).contains(x, y)) {
+#endif
renderer()->updateHitTestResult(result, IntPoint(x - tx, y - ty));
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (result.isRegionTest()) {
+ ASSERT(renderer()->node() || renderer()->isAnonymous());
+ result.addRawNode(renderer()->node());
+ if (!result.containedBy(x, y, boundsRect))
+ return false;
+ }
+#endif
return true;
}
diff --git a/WebCore/rendering/HitTestResult.cpp b/WebCore/rendering/HitTestResult.cpp
index 50933c6..8a4ef3c 100644
--- a/WebCore/rendering/HitTestResult.cpp
+++ b/WebCore/rendering/HitTestResult.cpp
@@ -52,6 +52,15 @@ HitTestResult::HitTestResult(const IntPoint& point)
{
}
+#ifdef ANDROID_HITTEST_WITHSIZE
+HitTestResult::HitTestResult(const IntPoint& point, const IntSize& padding)
+ : m_point(point)
+ , m_pointPadding(padding)
+ , m_isOverWidget(false)
+{
+}
+#endif
+
HitTestResult::HitTestResult(const HitTestResult& other)
: m_innerNode(other.innerNode())
, m_innerNonSharedNode(other.innerNonSharedNode())
@@ -60,6 +69,10 @@ HitTestResult::HitTestResult(const HitTestResult& other)
, m_innerURLElement(other.URLElement())
, m_scrollbar(other.scrollbar())
, m_isOverWidget(other.isOverWidget())
+#ifdef ANDROID_HITTEST_WITHSIZE
+ , m_pointPadding(other.pointPadding())
+ , m_rawNodeList(other.rawNodeList())
+#endif
{
}
@@ -76,6 +89,10 @@ HitTestResult& HitTestResult::operator=(const HitTestResult& other)
m_innerURLElement = other.URLElement();
m_scrollbar = other.scrollbar();
m_isOverWidget = other.isOverWidget();
+#ifdef ANDROID_HITTEST_WITHSIZE
+ m_pointPadding = other.pointPadding();
+ m_rawNodeList = other.rawNodeList();
+#endif
return *this;
}
@@ -362,4 +379,50 @@ bool HitTestResult::isContentEditable() const
return m_innerNonSharedNode->isContentEditable();
}
+#ifdef ANDROID_HITTEST_WITHSIZE
+
+bool HitTestResult::intersects(int x, int y, const IntRect& other) const
+{
+ IntRect pointRect(x - m_pointPadding.width(), y - m_pointPadding.height(), 2 * m_pointPadding.width() + 1, 2* m_pointPadding.height() + 1);
+ return other.intersects(pointRect);
+}
+
+bool HitTestResult::containedBy(int x, int y, const IntRect& other) const
+{
+ IntRect pointRect(x - m_pointPadding.width(), y - m_pointPadding.height(), 2 * m_pointPadding.width() + 1, 2* m_pointPadding.height() + 1);
+ return other.contains(pointRect);
+}
+
+void HitTestResult::merge(const HitTestResult& other)
+{
+ if (!m_innerNode && other.innerNode()) {
+ m_innerNode = other.innerNode();
+ m_innerNonSharedNode = other.innerNonSharedNode();
+ m_localPoint = other.localPoint();
+ m_innerURLElement = other.URLElement();
+ m_scrollbar = other.scrollbar();
+ m_isOverWidget = other.isOverWidget();
+ }
+
+ const Vector<RefPtr<Node> >& list = other.rawNodeList();
+ Vector<RefPtr<Node> >::const_iterator last = list.end();
+ for (Vector<RefPtr<Node> >::const_iterator it = list.begin(); it != last; ++it)
+ addRawNode(it->get());
+}
+
+void HitTestResult::addRawNode(Node* node)
+{
+ if (!node)
+ return;
+
+ Vector<RefPtr<Node> >::const_iterator last = m_rawNodeList.end();
+ for (Vector<RefPtr<Node> >::const_iterator it = m_rawNodeList.begin(); it != last; ++it)
+ if ((*it) == node)
+ return;
+
+ m_rawNodeList.append(node);
+}
+
+#endif // ANDROID_HITTEST_WITHSIZE
+
} // namespace WebCore
diff --git a/WebCore/rendering/HitTestResult.h b/WebCore/rendering/HitTestResult.h
index d1906ba..0f45900 100644
--- a/WebCore/rendering/HitTestResult.h
+++ b/WebCore/rendering/HitTestResult.h
@@ -22,6 +22,10 @@
#include "IntPoint.h"
#include "TextDirection.h"
+#ifdef ANDROID_HITTEST_WITHSIZE
+#include <IntSize.h>
+#include <wtf/Vector.h>
+#endif
#include <wtf/RefPtr.h>
namespace WebCore {
@@ -76,6 +80,19 @@ public:
bool isLiveLink() const;
bool isContentEditable() const;
+#ifdef ANDROID_HITTEST_WITHSIZE
+ HitTestResult(const IntPoint&, const IntSize&);
+
+ IntSize pointPadding() const { return m_pointPadding; }
+ bool isRegionTest() const { return !m_pointPadding.isEmpty(); }
+ bool intersects(int, int, const IntRect&) const;
+ bool containedBy(int, int, const IntRect&) const;
+
+ void merge(const HitTestResult&);
+ void addRawNode(Node*);
+ const Vector<RefPtr<Node> >& rawNodeList() const { return m_rawNodeList; }
+#endif
+
private:
RefPtr<Node> m_innerNode;
RefPtr<Node> m_innerNonSharedNode;
@@ -85,6 +102,11 @@ private:
RefPtr<Element> m_innerURLElement;
RefPtr<Scrollbar> m_scrollbar;
bool m_isOverWidget; // Returns true if we are over a widget (and not in the border/padding area of a RenderWidget for example).
+
+#ifdef ANDROID_HITTEST_WITHSIZE
+ IntSize m_pointPadding;
+ Vector<RefPtr<Node> > m_rawNodeList;
+#endif
};
String displayString(const String&, const Node*);
diff --git a/WebCore/rendering/InlineFlowBox.cpp b/WebCore/rendering/InlineFlowBox.cpp
index 6ee610d..e31bf4f 100644
--- a/WebCore/rendering/InlineFlowBox.cpp
+++ b/WebCore/rendering/InlineFlowBox.cpp
@@ -607,7 +607,11 @@ bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
{
IntRect overflowRect(visibleOverflowRect());
overflowRect.move(tx, ty);
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (!result.intersects(x, y, overflowRect))
+#else
if (!overflowRect.contains(x, y))
+#endif
return false;
// Check children first.
@@ -620,8 +624,20 @@ bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
// Now check ourselves.
IntRect rect(tx + m_x, ty + m_y, m_width, height());
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (visibleToHitTesting() && result.intersects(x, y, rect)) {
+#else
if (visibleToHitTesting() && rect.contains(x, y)) {
+#endif
renderer()->updateHitTestResult(result, IntPoint(x - tx, y - ty)); // Don't add in m_x or m_y here, we want coords in the containing block's space.
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (result.isRegionTest()) {
+ ASSERT(renderer()->node() || renderer()->isAnonymous());
+ result.addRawNode(renderer()->node());
+ if (!result.containedBy(x, y, rect))
+ return false;
+ }
+#endif
return true;
}
diff --git a/WebCore/rendering/InlineTextBox.cpp b/WebCore/rendering/InlineTextBox.cpp
index 9c28b42..0c5df41 100644
--- a/WebCore/rendering/InlineTextBox.cpp
+++ b/WebCore/rendering/InlineTextBox.cpp
@@ -266,8 +266,20 @@ bool InlineTextBox::nodeAtPoint(const HitTestRequest&, HitTestResult& result, in
return false;
IntRect rect(tx + m_x, ty + m_y, m_width, height());
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (m_truncation != cFullTruncation && visibleToHitTesting() && result.intersects(x, y, rect)) {
+#else
if (m_truncation != cFullTruncation && visibleToHitTesting() && rect.contains(x, y)) {
+#endif
renderer()->updateHitTestResult(result, IntPoint(x - tx, y - ty));
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (result.isRegionTest()) {
+ ASSERT(renderer()->node() || renderer()->isAnonymous());
+ result.addRawNode(renderer()->node());
+ if (!result.containedBy(x, y, rect))
+ return false;
+ }
+#endif
return true;
}
return false;
diff --git a/WebCore/rendering/RenderBlock.cpp b/WebCore/rendering/RenderBlock.cpp
index cf4101b..f8c8b8d 100644
--- a/WebCore/rendering/RenderBlock.cpp
+++ b/WebCore/rendering/RenderBlock.cpp
@@ -3317,19 +3317,34 @@ bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
// Check if we need to do anything at all.
IntRect overflowBox = visibleOverflowRect();
overflowBox.move(tx, ty);
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (!result.intersects(_x, _y, overflowBox))
+#else
if (!overflowBox.contains(_x, _y))
+#endif
return false;
}
if ((hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) && isPointInOverflowControl(result, _x, _y, tx, ty)) {
updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
+#ifdef ANDROID_HITTEST_WITHSIZE
+ // TODO: isPointInOverflowControl() doesn't handle region test yet.
+ if (result.isRegionTest()) {
+ ASSERT(node() || isAnonymous());
+ result.addRawNode(node());
+ } else
+#endif
return true;
}
// If we have clipping, then we can't have any spillout.
bool useOverflowClip = hasOverflowClip() && !hasSelfPaintingLayer();
bool useClip = (hasControlClip() || useOverflowClip);
+#ifdef ANDROID_HITTEST_WITHSIZE
+ bool checkChildren = !useClip || (hasControlClip() ? result.intersects(_x, _y, controlClipRect(tx, ty)) : result.intersects(_x, _y, overflowClipRect(tx, ty)));
+#else
bool checkChildren = !useClip || (hasControlClip() ? controlClipRect(tx, ty).contains(_x, _y) : overflowClipRect(tx, ty).contains(_x, _y));
+#endif
if (checkChildren) {
// Hit test descendants first.
int scrolledX = tx;
@@ -3373,8 +3388,20 @@ bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
// Now hit test our background
if (hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) {
IntRect boundsRect(tx, ty, width(), height());
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (visibleToHitTesting() && result.intersects(_x, _y, boundsRect)) {
+#else
if (visibleToHitTesting() && boundsRect.contains(_x, _y)) {
+#endif
updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (result.isRegionTest()) {
+ ASSERT(node() || isAnonymous());
+ result.addRawNode(node());
+ if (!result.containedBy(_x, _y, boundsRect))
+ return false;
+ }
+#endif
return true;
}
}
@@ -3395,12 +3422,21 @@ bool RenderBlock::hitTestColumns(const HitTestRequest& request, HitTestResult& r
IntRect colRect = colRects->at(i);
colRect.move(tx, ty);
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (result.intersects(x, y, colRect)) {
+#else
if (colRect.contains(x, y)) {
+#endif
// The point is inside this column.
// Adjust tx and ty to change where we hit test.
int finalX = tx + currXOffset;
int finalY = ty + currYOffset;
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (result.isRegionTest() && !result.containedBy(x, y, colRect))
+ hitTestContents(request, result, x, y, finalX, finalY, hitTestAction);
+ else
+#endif
return hitTestContents(request, result, x, y, finalX, finalY, hitTestAction);
}
diff --git a/WebCore/rendering/RenderBox.cpp b/WebCore/rendering/RenderBox.cpp
index 9204b64..4c5d702 100644
--- a/WebCore/rendering/RenderBox.cpp
+++ b/WebCore/rendering/RenderBox.cpp
@@ -34,6 +34,9 @@
#include "htmlediting.h"
#include "HTMLElement.h"
#include "HTMLNames.h"
+#ifdef ANDROID_HITTEST_WITHSIZE
+#include "HitTestResult.h"
+#endif
#include "ImageBuffer.h"
#include "FloatQuad.h"
#include "Frame.h"
@@ -556,10 +559,23 @@ bool RenderBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result
}
}
+#ifdef ANDROID_HITTEST_WITHSIZE
+ IntRect boundsRect = IntRect(tx, ty, width(), height());
+ if (visibleToHitTesting() && action == HitTestForeground && result.intersects(xPos, yPos, boundsRect)) {
+#else
// 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).
if (visibleToHitTesting() && action == HitTestForeground && IntRect(tx, ty, width(), height()).contains(xPos, yPos)) {
+#endif
updateHitTestResult(result, IntPoint(xPos - tx, yPos - ty));
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (result.isRegionTest()) {
+ ASSERT(node() || isAnonymous());
+ result.addRawNode(node());
+ if (!result.containedBy(xPos, yPos, boundsRect))
+ return false;
+ }
+#endif
return true;
}
diff --git a/WebCore/rendering/RenderImage.cpp b/WebCore/rendering/RenderImage.cpp
index 73cf73c..237dfb6 100644
--- a/WebCore/rendering/RenderImage.cpp
+++ b/WebCore/rendering/RenderImage.cpp
@@ -513,10 +513,18 @@ HTMLMapElement* RenderImage::imageMap() const
bool RenderImage::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
{
+#ifdef ANDROID_HITTEST_WITHSIZE
+ HitTestResult tempResult(result.point(), result.pointPadding());
+#else
HitTestResult tempResult(result.point());
+#endif
bool inside = RenderReplaced::nodeAtPoint(request, tempResult, x, y, tx, ty, hitTestAction);
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (tempResult.innerNode() && node()) {
+#else
if (inside && node()) {
+#endif
if (HTMLMapElement* map = imageMap()) {
IntRect contentBox = contentBoxRect();
float zoom = style()->effectiveZoom();
@@ -527,6 +535,10 @@ bool RenderImage::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
}
}
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (!inside && result.isRegionTest())
+ result.merge(tempResult);
+#endif
if (inside)
result = tempResult;
return inside;
diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp
index ea29087..37dbd38 100644
--- a/WebCore/rendering/RenderLayer.cpp
+++ b/WebCore/rendering/RenderLayer.cpp
@@ -2603,7 +2603,11 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
if (parent()) {
IntRect clipRect = backgroundClipRect(rootLayer, useTemporaryClipRects);
// Go ahead and test the enclosing clip now.
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (!result.intersects(hitTestPoint.x(), hitTestPoint.y(), clipRect))
+#else
if (!clipRect.contains(hitTestPoint))
+#endif
return 0;
}
@@ -2700,9 +2704,20 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
// Begin by walking our list of positive layers from highest z-index down to the lowest z-index.
if (m_posZOrderList) {
for (int i = m_posZOrderList->size() - 1; i >= 0; --i) {
+#ifdef ANDROID_HITTEST_WITHSIZE
+ HitTestResult tempResult(result.point(), result.pointPadding());
+#else
HitTestResult tempResult(result.point());
+#endif
RenderLayer* hitLayer = m_posZOrderList->at(i)->hitTestLayer(rootLayer, this, request, tempResult, hitTestRect, hitTestPoint, false, localTransformState.get(), zOffsetForDescendantsPtr);
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (result.isRegionTest())
+ result.merge(tempResult);
+#endif
if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedTransformState.get())) {
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (!result.isRegionTest())
+#endif
result = tempResult;
if (!depthSortDescendants)
return hitLayer;
@@ -2716,9 +2731,20 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
if (m_normalFlowList) {
for (int i = m_normalFlowList->size() - 1; i >= 0; --i) {
RenderLayer* currLayer = m_normalFlowList->at(i);
+#ifdef ANDROID_HITTEST_WITHSIZE
+ HitTestResult tempResult(result.point(), result.pointPadding());
+#else
HitTestResult tempResult(result.point());
+#endif
RenderLayer* hitLayer = currLayer->hitTestLayer(rootLayer, this, request, tempResult, hitTestRect, hitTestPoint, false, localTransformState.get(), zOffsetForDescendantsPtr);
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (result.isRegionTest())
+ result.merge(tempResult);
+#endif
if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedTransformState.get())) {
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (!result.isRegionTest())
+#endif
result = tempResult;
if (!depthSortDescendants)
return hitLayer;
@@ -2729,25 +2755,53 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
}
// Next we want to see if the mouse pos is inside the child RenderObjects of the layer.
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (result.intersects(hitTestPoint.x(), hitTestPoint.y(), fgRect) && isSelfPaintingLayer()) {
+#else
if (fgRect.contains(hitTestPoint) && isSelfPaintingLayer()) {
+#endif
// Hit test with a temporary HitTestResult, because we only want to commit to 'result' if we know we're frontmost.
+#ifdef ANDROID_HITTEST_WITHSIZE
+ HitTestResult tempResult(result.point(), result.pointPadding());
+#else
HitTestResult tempResult(result.point());
+#endif
if (hitTestContents(request, tempResult, layerBounds, hitTestPoint, HitTestDescendants) &&
isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) {
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (result.isRegionTest())
+ result.merge(tempResult);
+ else
+#endif
result = tempResult;
if (!depthSortDescendants)
return this;
// Foreground can depth-sort with descendant layers, so keep this as a candidate.
candidateLayer = this;
}
+#ifdef ANDROID_HITTEST_WITHSIZE
+ else if (result.isRegionTest())
+ result.merge(tempResult);
+#endif
}
// Now check our negative z-index children.
if (m_negZOrderList) {
for (int i = m_negZOrderList->size() - 1; i >= 0; --i) {
+#ifdef ANDROID_HITTEST_WITHSIZE
+ HitTestResult tempResult(result.point(), result.pointPadding());
+#else
HitTestResult tempResult(result.point());
+#endif
RenderLayer* hitLayer = m_negZOrderList->at(i)->hitTestLayer(rootLayer, this, request, tempResult, hitTestRect, hitTestPoint, false, localTransformState.get(), zOffsetForDescendantsPtr);
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (result.isRegionTest())
+ result.merge(tempResult);
+#endif
if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedTransformState.get())) {
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (!result.isRegionTest())
+#endif
result = tempResult;
if (!depthSortDescendants)
return hitLayer;
@@ -2761,13 +2815,27 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
if (candidateLayer)
return candidateLayer;
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (result.intersects(hitTestPoint.x(), hitTestPoint.y(), bgRect) && isSelfPaintingLayer()) {
+ HitTestResult tempResult(result.point(), result.pointPadding());
+#else
if (bgRect.contains(hitTestPoint) && isSelfPaintingLayer()) {
HitTestResult tempResult(result.point());
+#endif
if (hitTestContents(request, tempResult, layerBounds, hitTestPoint, HitTestSelf) &&
isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) {
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (result.isRegionTest())
+ result.merge(tempResult);
+ else
+#endif
result = tempResult;
return this;
}
+#ifdef ANDROID_HITTEST_WITHSIZE
+ else if (result.isRegionTest())
+ result.merge(tempResult);
+#endif
}
return 0;
diff --git a/WebCore/rendering/RenderLineBoxList.cpp b/WebCore/rendering/RenderLineBoxList.cpp
index 9736874..3395347 100644
--- a/WebCore/rendering/RenderLineBoxList.cpp
+++ b/WebCore/rendering/RenderLineBoxList.cpp
@@ -30,6 +30,9 @@
#include "RenderLineBoxList.h"
#include "InlineTextBox.h"
+#ifdef ANDROID_HITTEST_WITHSIZE
+#include "HitTestResult.h"
+#endif
#include "RenderArena.h"
#include "RenderInline.h"
#include "RenderView.h"
@@ -230,14 +233,22 @@ bool RenderLineBoxList::hitTest(RenderBoxModelObject* renderer, const HitTestReq
// contain the point. This is a quick short-circuit that we can take to avoid walking any lines.
// FIXME: This check is flawed in the following extremely obscure way:
// if some line in the middle has a huge overflow, it might actually extend below the last line.
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if ((y - result.pointPadding().height() >= ty + lastLineBox()->root()->bottomVisibleOverflow()) || (y + result.pointPadding().height() < ty + firstLineBox()->root()->topVisibleOverflow()))
+#else
if ((y >= ty + lastLineBox()->root()->bottomVisibleOverflow()) || (y < ty + firstLineBox()->root()->topVisibleOverflow()))
+#endif
return false;
// See if our root lines contain the point. If so, then we hit test
// them further. Note that boxes can easily overlap, so we can't make any assumptions
// based off positions of our first line box or our last line box.
for (InlineFlowBox* curr = lastLineBox(); curr; curr = curr->prevLineBox()) {
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (y + result.pointPadding().height() >= ty + curr->root()->topVisibleOverflow() && y - result.pointPadding().height() < ty + curr->root()->bottomVisibleOverflow()) {
+#else
if (y >= ty + curr->root()->topVisibleOverflow() && y < ty + curr->root()->bottomVisibleOverflow()) {
+#endif
bool inside = curr->nodeAtPoint(request, result, x, y, tx, ty);
if (inside) {
renderer->updateHitTestResult(result, IntPoint(x - tx, y - ty));
diff --git a/WebCore/rendering/RenderSVGRoot.cpp b/WebCore/rendering/RenderSVGRoot.cpp
index 67a3b2a..6017513 100644
--- a/WebCore/rendering/RenderSVGRoot.cpp
+++ b/WebCore/rendering/RenderSVGRoot.cpp
@@ -26,6 +26,9 @@
#include "RenderSVGRoot.h"
#include "GraphicsContext.h"
+#ifdef ANDROID_HITTEST_WITHSIZE
+#include "HitTestResult.h"
+#endif
#include "RenderSVGContainer.h"
#include "RenderView.h"
#include "SVGLength.h"
@@ -313,6 +316,13 @@ bool RenderSVGRoot::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
if (child->nodeAtFloatPoint(request, result, localPoint, hitTestAction)) {
// FIXME: CSS/HTML assumes the local point is relative to the border box, right?
updateHitTestResult(result, pointInBorderBox);
+#ifdef ANDROID_HITTEST_WITHSIZE
+ // TODO: nodeAtFloatPoint() doesn't handle region test yet.
+ if (result.isRegionTest()) {
+ ASSERT(node() || isAnonymous());
+ result.addRawNode(node());
+ } else
+#endif
return true;
}
}
diff --git a/WebCore/rendering/RenderTable.cpp b/WebCore/rendering/RenderTable.cpp
index 0a61a93..eac5c5d 100644
--- a/WebCore/rendering/RenderTable.cpp
+++ b/WebCore/rendering/RenderTable.cpp
@@ -31,6 +31,9 @@
#include "Document.h"
#include "FixedTableLayout.h"
#include "FrameView.h"
+#ifdef ANDROID_HITTEST_WITHSIZE
+#include "HitTestResult.h"
+#endif
#include "HTMLNames.h"
#include "RenderLayer.h"
#include "RenderTableCell.h"
@@ -1202,7 +1205,11 @@ bool RenderTable::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
ty += y();
// Check kids first.
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (!hasOverflowClip() || result.intersects(xPos, yPos, overflowClipRect(tx, ty))) {
+#else
if (!hasOverflowClip() || overflowClipRect(tx, ty).contains(xPos, yPos)) {
+#endif
for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && (child->isTableSection() || child == m_caption) &&
child->nodeAtPoint(request, result, xPos, yPos, tx, ty, action)) {
@@ -1213,8 +1220,21 @@ bool RenderTable::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
}
// Check our bounds next.
+#ifdef ANDROID_HITTEST_WITHSIZE
+ IntRect boundsRect = IntRect(tx, ty, width(), height());
+ if (visibleToHitTesting() && (action == HitTestBlockBackground || action == HitTestChildBlockBackground) && result.intersects(xPos, yPos, boundsRect)) {
+#else
if (visibleToHitTesting() && (action == HitTestBlockBackground || action == HitTestChildBlockBackground) && IntRect(tx, ty, width(), height()).contains(xPos, yPos)) {
+#endif
updateHitTestResult(result, IntPoint(xPos - tx, yPos - ty));
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (result.isRegionTest()) {
+ ASSERT(node() || isAnonymous());
+ result.addRawNode(node());
+ if (!result.containedBy(xPos, yPos, boundsRect))
+ return false;
+ }
+#endif
return true;
}
diff --git a/WebCore/rendering/RenderTableSection.cpp b/WebCore/rendering/RenderTableSection.cpp
index e8ab4a4..e8f9cc4 100644
--- a/WebCore/rendering/RenderTableSection.cpp
+++ b/WebCore/rendering/RenderTableSection.cpp
@@ -28,6 +28,9 @@
#include "CachedImage.h"
#include "Document.h"
+#ifdef ANDROID_HITTEST_WITHSIZE
+#include "HitTestResult.h"
+#endif
#include "HTMLNames.h"
#include "RenderTableCell.h"
#include "RenderTableCol.h"
@@ -1259,7 +1262,11 @@ bool RenderTableSection::nodeAtPoint(const HitTestRequest& request, HitTestResul
tx += x();
ty += y();
+#ifdef ANDROID_HITTEST_WITHSIZE
+ if (hasOverflowClip() && !result.intersects(xPos, yPos, overflowClipRect(tx, ty)))
+#else
if (hasOverflowClip() && !overflowClipRect(tx, ty).contains(xPos, yPos))
+#endif
return false;
for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
diff --git a/WebCore/rendering/RenderWidget.cpp b/WebCore/rendering/RenderWidget.cpp
index 15c75f1..2c53da4 100644
--- a/WebCore/rendering/RenderWidget.cpp
+++ b/WebCore/rendering/RenderWidget.cpp
@@ -378,6 +378,12 @@ bool RenderWidget::nodeAtPoint(const HitTestRequest& request, HitTestResult& res
// Check to see if we are really over the widget itself (and not just in the border/padding area).
if (inside && !hadResult && result.innerNode() == node())
result.setIsOverWidget(contentBoxRect().contains(result.localPoint()));
+#ifdef ANDROID_HITTEST_WITHSIZE
+ else if (result.isRegionTest() && !hadResult && result.innerNode() == node()) {
+ result.setIsOverWidget(contentBoxRect().contains(result.localPoint()));
+ return false;
+ }
+#endif
return inside;
}