Index: Source/core/layout/line/InlineFlowBox.cpp |
diff --git a/Source/core/layout/line/InlineFlowBox.cpp b/Source/core/layout/line/InlineFlowBox.cpp |
index 1d413227f88586c19536846b8d2321b97aa40ccd..d25ceeb6b5a0aea72b25ae3abb730d8a283fc78d 100644 |
--- a/Source/core/layout/line/InlineFlowBox.cpp |
+++ b/Source/core/layout/line/InlineFlowBox.cpp |
@@ -1009,42 +1009,42 @@ bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re |
if (!locationInContainer.intersects(overflowRect)) |
return false; |
- // We need to hit test both our inline children (InlineBoxes) and culled inlines |
- // (LayoutObjects). We check our inlines in the same order as line layout but |
- // for each inline we additionally need to hit test its culled inline parents. |
- // While hit testing culled inline parents, we can stop once we reach |
- // a non-inline parent or a culled inline associated with a different inline box. |
- InlineBox* prev; |
- for (InlineBox* curr = lastChild(); curr; curr = prev) { |
- prev = curr->prevOnLine(); |
- |
- // Layers will handle hit testing themselves. |
- if (curr->boxModelObject() && curr->boxModelObject()->hasSelfPaintingLayer()) |
- continue; |
- |
- if (curr->nodeAtPoint(request, result, locationInContainer, accumulatedOffset, lineTop, lineBottom)) { |
- renderer().updateHitTestResult(result, locationInContainer.point() - toLayoutSize(accumulatedOffset)); |
- return true; |
- } |
- |
- // If the current inlinebox's renderer and the previous inlinebox's renderer are same, |
- // we should yield the hit-test to the previous inlinebox. |
- if (prev && curr->renderer() == prev->renderer()) |
- continue; |
- |
- LayoutObject* culledParent = &curr->renderer(); |
- while (true) { |
- LayoutObject* sibling = culledParent->style()->isLeftToRightDirection() ? culledParent->previousSibling() : culledParent->nextSibling(); |
- culledParent = culledParent->parent(); |
- ASSERT(culledParent); |
- |
- if (culledParent == renderer() || (sibling && prev && prev->renderer().isDescendantOf(culledParent))) |
- break; |
- |
- if (culledParent->isRenderInline() && toRenderInline(culledParent)->hitTestCulledInline(request, result, locationInContainer, accumulatedOffset)) |
+ // Check children first. |
+ // We need to account for culled inline parents of the hit-tested nodes, so that they may also get included in area-based hit-tests. |
+ LayoutObject* culledParent = 0; |
+ for (InlineBox* curr = lastChild(); curr; curr = curr->prevOnLine()) { |
+ if (curr->renderer().isText() || !curr->boxModelObject()->hasSelfPaintingLayer()) { |
+ LayoutObject* newParent = 0; |
+ // Culled parents are only relevant for area-based hit-tests, so ignore it in point-based ones. |
+ if (locationInContainer.isRectBasedTest()) { |
+ newParent = curr->renderer().parent(); |
+ if (newParent == renderer()) |
+ newParent = 0; |
+ } |
+ // Check the culled parent after all its children have been checked, to do this we wait until |
+ // we are about to test an element with a different parent. |
+ if (newParent != culledParent) { |
+ if (!newParent || !newParent->isDescendantOf(culledParent)) { |
+ while (culledParent && culledParent != renderer() && culledParent != newParent) { |
+ if (culledParent->isRenderInline() && toRenderInline(culledParent)->hitTestCulledInline(request, result, locationInContainer, accumulatedOffset)) |
+ return true; |
+ culledParent = culledParent->parent(); |
+ } |
+ } |
+ culledParent = newParent; |
+ } |
+ if (curr->nodeAtPoint(request, result, locationInContainer, accumulatedOffset, lineTop, lineBottom)) { |
+ renderer().updateHitTestResult(result, locationInContainer.point() - toLayoutSize(accumulatedOffset)); |
return true; |
+ } |
} |
} |
+ // Check any culled ancestor of the final children tested. |
+ while (culledParent && culledParent != renderer()) { |
+ if (culledParent->isRenderInline() && toRenderInline(culledParent)->hitTestCulledInline(request, result, locationInContainer, accumulatedOffset)) |
+ return true; |
+ culledParent = culledParent->parent(); |
+ } |
// Now check ourselves. Pixel snap hit testing. |
LayoutRect frameRect = roundedFrameRect(); |