bool RenderSVGResourceClipper::hitTestClipContent(const FloatRect& objectBoundingBox, const FloatPoint& nodeAtPoint) { FloatPoint point = nodeAtPoint; if (!SVGRenderSupport::pointInClippingArea(*this, point)) return false; if (clipPathElement().clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { AffineTransform transform; transform.translate(objectBoundingBox.x(), objectBoundingBox.y()); transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height()); point = transform.inverse().valueOr(AffineTransform()).mapPoint(point); } point = clipPathElement().animatedLocalTransform().inverse().valueOr(AffineTransform()).mapPoint(point); for (Node* childNode = clipPathElement().firstChild(); childNode; childNode = childNode->nextSibling()) { RenderObject* renderer = childNode->renderer(); if (!childNode->isSVGElement() || !renderer) continue; if (!renderer->isSVGShape() && !renderer->isSVGText() && !childNode->hasTagName(SVGNames::useTag)) continue; IntPoint hitPoint; HitTestResult result(hitPoint); if (renderer->nodeAtFloatPoint(HitTestRequest(HitTestRequest::SVGClipContent | HitTestRequest::DisallowUserAgentShadowContent), result, point, HitTestForeground)) return true; } return false; }
bool RenderSVGResourceClipper::hitTestClipContent(const FloatRect& objectBoundingBox, const FloatPoint& nodeAtPoint) { FloatPoint point = nodeAtPoint; if (!SVGRenderSupport::pointInClippingArea(this, point)) return false; if (static_cast<SVGClipPathElement*>(node())->clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { AffineTransform transform; transform.translate(objectBoundingBox.x(), objectBoundingBox.y()); transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height()); point = transform.inverse().mapPoint(point); } for (Node* childNode = node()->firstChild(); childNode; childNode = childNode->nextSibling()) { RenderObject* renderer = childNode->renderer(); if (!childNode->isSVGElement() || !static_cast<SVGElement*>(childNode)->isStyled() || !renderer) continue; if (!renderer->isSVGPath() && !renderer->isSVGText() && !renderer->isSVGShadowTreeRootContainer()) continue; IntPoint hitPoint; HitTestResult result(hitPoint); if (renderer->nodeAtFloatPoint(HitTestRequest(HitTestRequest::SVGClipContent), result, point, HitTestForeground)) return true; } return false; }
TEST_F(ChromeClientTest, SetToolTipFlood) { ChromeClientToolTipLogger logger; ChromeClient* client = &logger; HitTestResult result(HitTestRequest(HitTestRequest::Move), LayoutPoint(10, 20)); Document* doc = Document::create(); Element* element = HTMLElement::create(HTMLNames::divTag, *doc); element->setAttribute(HTMLNames::titleAttr, "tooltip"); result.setInnerNode(element); client->setToolTip(*doc->frame(), result); EXPECT_EQ("tooltip", logger.toolTipForLastSetToolTip()); // seToolTip(HitTestResult) again in the same condition. logger.clearToolTipForLastSetToolTip(); client->setToolTip(*doc->frame(), result); // setToolTip(String,TextDirection) should not be called. EXPECT_EQ(String(), logger.toolTipForLastSetToolTip()); // Cancel the tooltip, and setToolTip(HitTestResult) again. client->clearToolTip(*doc->frame()); logger.clearToolTipForLastSetToolTip(); client->setToolTip(*doc->frame(), result); // setToolTip(String,TextDirection) should not be called. EXPECT_EQ(String(), logger.toolTipForLastSetToolTip()); logger.clearToolTipForLastSetToolTip(); element->setAttribute(HTMLNames::titleAttr, "updated"); client->setToolTip(*doc->frame(), result); // setToolTip(String,TextDirection) should be called because tooltip string // is different from the last one. EXPECT_EQ("updated", logger.toolTipForLastSetToolTip()); }
bool RenderSVGResourceClipper::hitTestClipContent(const FloatRect& objectBoundingBox, const FloatPoint& nodeAtPoint) { FloatPoint point = nodeAtPoint; if (!SVGRenderSupport::pointInClippingArea(this, point)) return false; if (clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { AffineTransform transform; transform.translate(objectBoundingBox.x(), objectBoundingBox.y()); transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height()); point = transform.inverse().mapPoint(point); } AffineTransform animatedLocalTransform = toSVGClipPathElement(element())->animatedLocalTransform(); if (!animatedLocalTransform.isInvertible()) return false; point = animatedLocalTransform.inverse().mapPoint(point); for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element()); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement)) { RenderObject* renderer = childElement->renderer(); if (!renderer) continue; if (!renderer->isSVGShape() && !renderer->isSVGText() && !isSVGUseElement(*childElement)) continue; IntPoint hitPoint; HitTestResult result(hitPoint); if (renderer->nodeAtFloatPoint(HitTestRequest(HitTestRequest::SVGClipContent), result, point, HitTestForeground)) return true; } return false; }
HitTestResult NewEventHandler::performHitTest(const LayoutPoint& point) { HitTestResult result(point); if (!m_frame.contentRenderer()) return result; m_frame.contentRenderer()->hitTest(HitTestRequest(HitTestRequest::ReadOnly), result); return result; }