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 1010 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1021 } | 1021 } |
1022 | 1022 |
1023 bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re sult, const HitTestLocation& locationInContainer, const LayoutPoint& accumulated Offset, LayoutUnit lineTop, LayoutUnit lineBottom) | 1023 bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re sult, const HitTestLocation& locationInContainer, const LayoutPoint& accumulated Offset, LayoutUnit lineTop, LayoutUnit lineBottom) |
1024 { | 1024 { |
1025 LayoutRect overflowRect(visualOverflowRect(lineTop, lineBottom)); | 1025 LayoutRect overflowRect(visualOverflowRect(lineTop, lineBottom)); |
1026 flipForWritingMode(overflowRect); | 1026 flipForWritingMode(overflowRect); |
1027 overflowRect.moveBy(accumulatedOffset); | 1027 overflowRect.moveBy(accumulatedOffset); |
1028 if (!locationInContainer.intersects(overflowRect)) | 1028 if (!locationInContainer.intersects(overflowRect)) |
1029 return false; | 1029 return false; |
1030 | 1030 |
1031 // Check children first. | 1031 // We need to hit test both our inline children (InlineBoxes) and culled inl ines |
1032 // 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. | 1032 // (RenderObjects). We check our inlines in the same order as line layout bu t |
1033 RenderObject* culledParent = 0; | 1033 // for each inline we additionally need to hit test its culled inline parent s. |
1034 for (InlineBox* curr = lastChild(); curr; curr = curr->prevOnLine()) { | 1034 // While hit testing culled inline parents, we can stop once we reach |
1035 if (curr->renderer().isText() || !curr->boxModelObject()->hasSelfPaintin gLayer()) { | 1035 // a non-inline parent or a culled inline associated with a different inline box. |
1036 RenderObject* newParent = 0; | 1036 InlineBox* prev; |
1037 // Culled parents are only relevant for area-based hit-tests, so ign ore it in point-based ones. | 1037 for (InlineBox* curr = lastChild(); curr; curr = prev) { |
pdr.
2014/12/14 22:06:48
This code is so much easier to understand than the
| |
1038 if (locationInContainer.isRectBasedTest()) { | 1038 prev = curr->prevOnLine(); |
1039 newParent = curr->renderer().parent(); | 1039 // Layers will handle hit testing themselves. |
1040 if (newParent == renderer()) | 1040 if (curr->boxModelObject() && curr->boxModelObject()->hasSelfPaintingLay er()) |
1041 newParent = 0; | 1041 continue; |
1042 | |
1043 if (curr->nodeAtPoint(request, result, locationInContainer, accumulatedO ffset, lineTop, lineBottom)) { | |
1044 renderer().updateHitTestResult(result, locationInContainer.point() - toLayoutSize(accumulatedOffset)); | |
1045 return true; | |
1046 } | |
1047 | |
1048 RenderObject* culledParent = &curr->renderer(); | |
1049 // If current inlinebox's renderer and previous inlinebox's renderer is same, | |
pdr.
2014/12/14 22:06:48
Minor nit:
"// If [the] current inlinebox's render
Miyoung Shin(g)
2014/12/15 13:01:15
Thanks.
| |
1050 // we should yield the hit-test to previous inlinebox. | |
1051 if (prev && curr->renderer() == prev->renderer()) | |
1052 continue; | |
1053 | |
1054 while (true) { | |
1055 if (culledParent->style()->isLeftToRightDirection()) { | |
pdr.
2014/12/14 22:06:48
I still don't understand the direction part here.
pdr.
2014/12/14 22:06:48
I still don't understand the direction part here.
Miyoung Shin(g)
2014/12/15 13:01:15
OK. I will add nodesFromRect-culled-inlines-betwee
| |
1056 if (culledParent->previousSibling()) | |
pdr.
2014/12/14 22:06:48
This essentially checks if we can early-out becaus
Miyoung Shin(g)
2014/12/15 13:01:15
I'm sorry. I think I get it now.
I thought that ev
| |
1057 break; | |
1058 } else if (culledParent->nextSibling()) { | |
1059 break; | |
1042 } | 1060 } |
1043 // Check the culled parent after all its children have been checked, to do this we wait until | 1061 |
1044 // we are about to test an element with a different parent. | 1062 culledParent = culledParent->parent(); |
1045 if (newParent != culledParent) { | 1063 ASSERT(culledParent); |
1046 if (!newParent || !newParent->isDescendantOf(culledParent)) { | 1064 if (culledParent == renderer()) |
1047 while (culledParent && culledParent != renderer() && culledP arent != newParent) { | 1065 break; |
1048 if (culledParent->isRenderInline() && toRenderInline(cul ledParent)->hitTestCulledInline(request, result, locationInContainer, accumulate dOffset)) | 1066 |
1049 return true; | 1067 if (culledParent->isRenderInline() && toRenderInline(culledParent)-> hitTestCulledInline(request, result, locationInContainer, accumulatedOffset)) |
1050 culledParent = culledParent->parent(); | |
1051 } | |
1052 } | |
1053 culledParent = newParent; | |
1054 } | |
1055 if (curr->nodeAtPoint(request, result, locationInContainer, accumula tedOffset, lineTop, lineBottom)) { | |
1056 renderer().updateHitTestResult(result, locationInContainer.point () - toLayoutSize(accumulatedOffset)); | |
1057 return true; | 1068 return true; |
1058 } | |
1059 } | 1069 } |
1060 } | 1070 } |
1061 // Check any culled ancestor of the final children tested. | |
1062 while (culledParent && culledParent != renderer()) { | |
1063 if (culledParent->isRenderInline() && toRenderInline(culledParent)->hitT estCulledInline(request, result, locationInContainer, accumulatedOffset)) | |
1064 return true; | |
1065 culledParent = culledParent->parent(); | |
1066 } | |
1067 | 1071 |
1068 // Now check ourselves. Pixel snap hit testing. | 1072 // Now check ourselves. Pixel snap hit testing. |
1069 LayoutRect frameRect = roundedFrameRect(); | 1073 LayoutRect frameRect = roundedFrameRect(); |
1070 LayoutUnit minX = frameRect.x(); | 1074 LayoutUnit minX = frameRect.x(); |
1071 LayoutUnit minY = frameRect.y(); | 1075 LayoutUnit minY = frameRect.y(); |
1072 LayoutUnit width = frameRect.width(); | 1076 LayoutUnit width = frameRect.width(); |
1073 LayoutUnit height = frameRect.height(); | 1077 LayoutUnit height = frameRect.height(); |
1074 | 1078 |
1075 // Constrain our hit testing to the line top and bottom if necessary. | 1079 // Constrain our hit testing to the line top and bottom if necessary. |
1076 bool noQuirksMode = renderer().document().inNoQuirksMode(); | 1080 bool noQuirksMode = renderer().document().inNoQuirksMode(); |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1352 ASSERT(child->prevOnLine() == prev); | 1356 ASSERT(child->prevOnLine() == prev); |
1353 prev = child; | 1357 prev = child; |
1354 } | 1358 } |
1355 ASSERT(prev == m_lastChild); | 1359 ASSERT(prev == m_lastChild); |
1356 #endif | 1360 #endif |
1357 } | 1361 } |
1358 | 1362 |
1359 #endif | 1363 #endif |
1360 | 1364 |
1361 } // namespace blink | 1365 } // namespace blink |
OLD | NEW |