bool LayoutPart::nodeAtPoint(HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action) { if (!widget() || !widget()->isFrameView() || !result.hitTestRequest().allowsChildFrameContent()) return nodeAtPointOverWidget(result, locationInContainer, accumulatedOffset, action); FrameView* childFrameView = toFrameView(widget()); LayoutView* childRoot = childFrameView->layoutView(); if (visibleToHitTestRequest(result.hitTestRequest()) && childRoot) { LayoutPoint adjustedLocation = accumulatedOffset + location(); LayoutPoint contentOffset = LayoutPoint(borderLeft() + paddingLeft(), borderTop() + paddingTop()) - LayoutSize(childFrameView->scrollOffset()); HitTestLocation newHitTestLocation(locationInContainer, -adjustedLocation - contentOffset); HitTestRequest newHitTestRequest(result.hitTestRequest().type() | HitTestRequest::ChildFrameHitTest); HitTestResult childFrameResult(newHitTestRequest, newHitTestLocation); bool isInsideChildFrame = childRoot->hitTest(newHitTestRequest, newHitTestLocation, childFrameResult); if (result.hitTestRequest().listBased()) result.append(childFrameResult); else if (isInsideChildFrame) result = childFrameResult; if (isInsideChildFrame) return true; } return nodeAtPointOverWidget(result, locationInContainer, accumulatedOffset, action); }
bool RenderWidget::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action) { if (request.allowsChildFrameContent() && widget() && widget()->isFrameView() && toFrameView(widget())->renderView()) { FrameView* childFrameView = toFrameView(widget()); RenderView* childRoot = childFrameView->renderView(); LayoutPoint adjustedLocation = accumulatedOffset + location(); LayoutPoint contentOffset = LayoutPoint(borderLeft() + paddingLeft(), borderTop() + paddingTop()) - childFrameView->scrollOffset(); HitTestLocation newHitTestLocation(locationInContainer, -adjustedLocation - contentOffset); HitTestRequest newHitTestRequest(request.type() | HitTestRequest::ChildFrameHitTest); HitTestResult childFrameResult(newHitTestLocation); bool isInsideChildFrame = childRoot->hitTest(newHitTestRequest, newHitTestLocation, childFrameResult); if (newHitTestLocation.isRectBasedTest()) result.append(childFrameResult); else if (isInsideChildFrame) result = childFrameResult; if (isInsideChildFrame) return true; } bool hadResult = result.innerNode(); bool inside = RenderReplaced::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, action); // Check to see if we are really over the widget itself (and not just in the border/padding area). if ((inside || result.isRectBasedTest()) && !hadResult && result.innerNode() == &frameOwnerElement()) result.setIsOverWidget(contentBoxRect().contains(result.localPoint())); return inside; }
bool LayoutPart::nodeAtPoint(HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action) { if (!widget() || !widget()->isFrameView() || !result.hitTestRequest().allowsChildFrameContent()) return nodeAtPointOverWidget(result, locationInContainer, accumulatedOffset, action); // A hit test can never hit an off-screen element; only off-screen iframes are throttled; // therefore, hit tests can skip descending into throttled iframes. if (toFrameView(widget())->shouldThrottleRendering()) return nodeAtPointOverWidget(result, locationInContainer, accumulatedOffset, action); ASSERT(document().lifecycle().state() >= DocumentLifecycle::CompositingClean); if (action == HitTestForeground) { FrameView* childFrameView = toFrameView(widget()); LayoutView* childRoot = childFrameView->layoutView(); if (visibleToHitTestRequest(result.hitTestRequest()) && childRoot) { LayoutPoint adjustedLocation = accumulatedOffset + location(); LayoutPoint contentOffset = LayoutPoint(borderLeft() + paddingLeft(), borderTop() + paddingTop()) - LayoutSize(childFrameView->scrollOffset()); HitTestLocation newHitTestLocation(locationInContainer, -adjustedLocation - contentOffset); HitTestRequest newHitTestRequest(result.hitTestRequest().type() | HitTestRequest::ChildFrameHitTest); HitTestResult childFrameResult(newHitTestRequest, newHitTestLocation); // The frame's layout and style must be up-to-date if we reach here. bool isInsideChildFrame = childRoot->hitTestNoLifecycleUpdate(childFrameResult); if (result.hitTestRequest().listBased()) { result.append(childFrameResult); } else if (isInsideChildFrame) { // Force the result not to be cacheable because the parent // frame should not cache this result; as it won't be notified of // changes in the child. childFrameResult.setCacheable(false); result = childFrameResult; } // Don't trust |isInsideChildFrame|. For rect-based hit-test, returns // true only when the hit test rect is totally within the iframe, // i.e. nodeAtPointOverWidget() also returns true. // Use a temporary HitTestResult because we don't want to collect the // iframe element itself if the hit-test rect is totally within the iframe. if (isInsideChildFrame) { if (!locationInContainer.isRectBasedTest()) return true; HitTestResult pointOverWidgetResult = result; bool pointOverWidget = nodeAtPointOverWidget(pointOverWidgetResult, locationInContainer, accumulatedOffset, action); if (pointOverWidget) return true; result = pointOverWidgetResult; return false; } } } return nodeAtPointOverWidget(result, locationInContainer, accumulatedOffset, action); }
bool LayoutImage::nodeAtPoint(HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction) { HitTestResult tempResult(result.hitTestRequest(), result.hitTestLocation()); bool inside = LayoutReplaced::nodeAtPoint(tempResult, locationInContainer, accumulatedOffset, hitTestAction); if (!inside && result.hitTestRequest().listBased()) result.append(tempResult); if (inside) result = tempResult; return inside; }
bool RenderImage::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) { HitTestResult tempResult(result.hitTestLocation()); bool inside = RenderReplaced::nodeAtPoint(request, tempResult, locationInContainer, accumulatedOffset); if (!inside && result.isRectBasedTest()) result.append(tempResult); if (inside) result = tempResult; return inside; }
bool RenderImage::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction) { HitTestResult tempResult(result.point(), result.topPadding(), result.rightPadding(), result.bottomPadding(), result.leftPadding()); bool inside = RenderReplaced::nodeAtPoint(request, tempResult, x, y, tx, ty, hitTestAction); if (tempResult.innerNode() && node()) { if (HTMLMapElement* map = imageMap()) { IntRect contentBox = contentBoxRect(); float zoom = style()->effectiveZoom(); int mapX = lroundf((x - tx - this->x() - contentBox.x()) / zoom); int mapY = lroundf((y - ty - this->y() - contentBox.y()) / zoom); if (map->mapMouseEvent(mapX, mapY, contentBox.size(), tempResult)) tempResult.setInnerNonSharedNode(node()); } } if (!inside && result.isRectBasedTest()) result.append(tempResult); if (inside) result = tempResult; return inside; }
bool RenderImage::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction) { HitTestResult tempResult(result.point(), result.topPadding(), result.rightPadding(), result.bottomPadding(), result.leftPadding()); bool inside = RenderReplaced::nodeAtPoint(request, tempResult, pointInContainer, accumulatedOffset, hitTestAction); if (tempResult.innerNode() && node()) { if (HTMLMapElement* map = imageMap()) { IntRect contentBox = contentBoxRect(); float scaleFactor = 1 / style()->effectiveZoom(); LayoutPoint mapLocation(pointInContainer.x() - accumulatedOffset.x() - this->x() - contentBox.x(), pointInContainer.y() - accumulatedOffset.y() - this->y() - contentBox.y()); mapLocation.scale(scaleFactor, scaleFactor); if (map->mapMouseEvent(mapLocation, contentBox.size(), tempResult)) tempResult.setInnerNonSharedNode(node()); } } if (!inside && result.isRectBasedTest()) result.append(tempResult); if (inside) result = tempResult; return inside; }
bool RenderImage::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction) { HitTestResult tempResult(result.hitTestLocation()); bool inside = RenderReplaced::nodeAtPoint(request, tempResult, locationInContainer, accumulatedOffset, hitTestAction); if (tempResult.innerNode() && node()) { if (HTMLMapElement* map = imageMap()) { LayoutRect contentBox = contentBoxRect(); float scaleFactor = 1 / style()->effectiveZoom(); LayoutPoint mapLocation = locationInContainer.point() - toLayoutSize(accumulatedOffset) - locationOffset() - toLayoutSize(contentBox.location()); mapLocation.scale(scaleFactor, scaleFactor); if (map->mapMouseEvent(mapLocation, contentBox.size(), tempResult)) tempResult.setInnerNonSharedNode(node()); } } if (!inside && result.isRectBasedTest()) result.append(tempResult); if (inside) result = tempResult; return inside; }
bool RenderPart::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action) { if (!widget() || !widget()->isFrameView() || !request.allowsChildFrameContent()) return RenderWidget::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, action); FrameView* childFrameView = toFrameView(widget()); RenderView* childRoot = childFrameView->renderView(); if (childRoot) { LayoutPoint adjustedLocation = accumulatedOffset + location(); LayoutPoint contentOffset = LayoutPoint(borderLeft() + paddingLeft(), borderTop() + paddingTop()) - childFrameView->scrollOffset(); HitTestLocation newHitTestLocation(locationInContainer, -adjustedLocation - contentOffset); HitTestRequest newHitTestRequest(request.type() | HitTestRequest::ChildFrameHitTest); HitTestResult childFrameResult(newHitTestLocation); bool isInsideChildFrame = childRoot->hitTest(newHitTestRequest, newHitTestLocation, childFrameResult); if (newHitTestLocation.isRectBasedTest()) result.append(childFrameResult); else if (isInsideChildFrame) result = childFrameResult; if (isInsideChildFrame) return true; if (request.allowsFrameScrollbars()) { // ScrollView scrollbars are not the same as RenderLayer scrollbars tested by RenderLayer::hitTestOverflowControls, // so we need to test ScrollView scrollbars separately here. // FIXME: Consider if this test could be done unconditionally. Scrollbar* frameScrollbar = childFrameView->scrollbarAtPoint(newHitTestLocation.roundedPoint()); if (frameScrollbar) result.setScrollbar(frameScrollbar); } } return RenderWidget::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, action); }