| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights
reserved. | 2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights
reserved. |
| 3 * | 3 * |
| 4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
| 5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
| 6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
| 7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
| 8 * | 8 * |
| 9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| (...skipping 957 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 968 } | 968 } |
| 969 | 969 |
| 970 bool InlineFlowBox::nodeAtPoint(HitTestResult& result, const HitTestLocation& lo
cationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, Lay
outUnit lineBottom) | 970 bool InlineFlowBox::nodeAtPoint(HitTestResult& result, const HitTestLocation& lo
cationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, Lay
outUnit lineBottom) |
| 971 { | 971 { |
| 972 LayoutRect overflowRect(visualOverflowRect(lineTop, lineBottom)); | 972 LayoutRect overflowRect(visualOverflowRect(lineTop, lineBottom)); |
| 973 flipForWritingMode(overflowRect); | 973 flipForWritingMode(overflowRect); |
| 974 overflowRect.moveBy(accumulatedOffset); | 974 overflowRect.moveBy(accumulatedOffset); |
| 975 if (!locationInContainer.intersects(overflowRect)) | 975 if (!locationInContainer.intersects(overflowRect)) |
| 976 return false; | 976 return false; |
| 977 | 977 |
| 978 // Check children first. | 978 // We need to hit test both our inline children (InlineBoxes) and culled inl
ines |
| 979 // 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. | 979 // (LayoutObjects). We check our inlines in the same order as line layout bu
t |
| 980 LayoutObject* culledParent = 0; | 980 // for each inline we additionally need to hit test its culled inline parent
s. |
| 981 for (InlineBox* curr = lastChild(); curr; curr = curr->prevOnLine()) { | 981 // While hit testing culled inline parents, we can stop once we reach |
| 982 if (curr->layoutObject().isText() || !curr->boxModelObject()->hasSelfPai
ntingLayer()) { | 982 // a non-inline parent or a culled inline associated with a different inline
box. |
| 983 LayoutObject* newParent = 0; | 983 InlineBox* prev; |
| 984 // Culled parents are only relevant for area-based hit-tests, so ign
ore it in point-based ones. | 984 for (InlineBox* curr = lastChild(); curr; curr = prev) { |
| 985 if (locationInContainer.isRectBasedTest()) { | 985 prev = curr->prevOnLine(); |
| 986 newParent = curr->layoutObject().parent(); | 986 |
| 987 if (newParent == layoutObject()) | 987 // Layers will handle hit testing themselves. |
| 988 newParent = 0; | 988 if (curr->boxModelObject() && curr->boxModelObject()->hasSelfPaintingLay
er()) |
| 989 } | 989 continue; |
| 990 // Check the culled parent after all its children have been checked,
to do this we wait until | 990 |
| 991 // we are about to test an element with a different parent. | 991 if (curr->nodeAtPoint(result, locationInContainer, accumulatedOffset, li
neTop, lineBottom)) { |
| 992 if (newParent != culledParent) { | 992 layoutObject().updateHitTestResult(result, locationInContainer.point
() - toLayoutSize(accumulatedOffset)); |
| 993 if (!newParent || !newParent->isDescendantOf(culledParent)) { | 993 return true; |
| 994 while (culledParent && culledParent != layoutObject() && cul
ledParent != newParent) { | 994 } |
| 995 if (culledParent->isLayoutInline() && toLayoutInline(cul
ledParent)->hitTestCulledInline(result, locationInContainer, accumulatedOffset)) | 995 |
| 996 return true; | 996 // If the current inlinebox's layout object and the previous inlinebox's
layout object are same, |
| 997 culledParent = culledParent->parent(); | 997 // we should yield the hit-test to the previous inlinebox. |
| 998 } | 998 if (prev && curr->layoutObject() == prev->layoutObject()) |
| 999 } | 999 continue; |
| 1000 culledParent = newParent; | 1000 |
| 1001 } | 1001 LayoutObject* culledParent = &curr->layoutObject(); |
| 1002 if (curr->nodeAtPoint(result, locationInContainer, accumulatedOffset
, lineTop, lineBottom)) { | 1002 while (true) { |
| 1003 layoutObject().updateHitTestResult(result, locationInContainer.p
oint() - toLayoutSize(accumulatedOffset)); | 1003 LayoutObject* sibling = culledParent->style()->isLeftToRightDirectio
n() ? culledParent->previousSibling() : culledParent->nextSibling(); |
| 1004 culledParent = culledParent->parent(); |
| 1005 ASSERT(culledParent); |
| 1006 |
| 1007 if (culledParent == layoutObject() || (sibling && prev && prev->layo
utObject().isDescendantOf(culledParent))) |
| 1008 break; |
| 1009 |
| 1010 if (culledParent->isLayoutInline() && toLayoutInline(culledParent)->
hitTestCulledInline(result, locationInContainer, accumulatedOffset)) |
| 1004 return true; | 1011 return true; |
| 1005 } | |
| 1006 } | 1012 } |
| 1007 } | 1013 } |
| 1008 // Check any culled ancestor of the final children tested. | |
| 1009 while (culledParent && culledParent != layoutObject()) { | |
| 1010 if (culledParent->isLayoutInline() && toLayoutInline(culledParent)->hitT
estCulledInline(result, locationInContainer, accumulatedOffset)) | |
| 1011 return true; | |
| 1012 culledParent = culledParent->parent(); | |
| 1013 } | |
| 1014 | 1014 |
| 1015 if (layoutObject().style()->hasBorderRadius()) { | 1015 if (layoutObject().style()->hasBorderRadius()) { |
| 1016 LayoutRect borderRect = logicalFrameRect(); | 1016 LayoutRect borderRect = logicalFrameRect(); |
| 1017 borderRect.moveBy(accumulatedOffset); | 1017 borderRect.moveBy(accumulatedOffset); |
| 1018 FloatRoundedRect border = layoutObject().style()->getRoundedBorderFor(bo
rderRect, includeLogicalLeftEdge(), includeLogicalRightEdge()); | 1018 FloatRoundedRect border = layoutObject().style()->getRoundedBorderFor(bo
rderRect, includeLogicalLeftEdge(), includeLogicalRightEdge()); |
| 1019 if (!locationInContainer.intersects(border)) | 1019 if (!locationInContainer.intersects(border)) |
| 1020 return false; | 1020 return false; |
| 1021 } | 1021 } |
| 1022 | 1022 |
| 1023 // Now check ourselves. Pixel snap hit testing. | 1023 // Now check ourselves. Pixel snap hit testing. |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1307 ASSERT(child->prevOnLine() == prev); | 1307 ASSERT(child->prevOnLine() == prev); |
| 1308 prev = child; | 1308 prev = child; |
| 1309 } | 1309 } |
| 1310 ASSERT(prev == m_lastChild); | 1310 ASSERT(prev == m_lastChild); |
| 1311 #endif | 1311 #endif |
| 1312 } | 1312 } |
| 1313 | 1313 |
| 1314 #endif | 1314 #endif |
| 1315 | 1315 |
| 1316 } // namespace blink | 1316 } // namespace blink |
| OLD | NEW |