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 |