Changeset 278343 in webkit
- Timestamp:
- Jun 2, 2021, 1:28:32 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 5 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/css3/masking/clip-path-hit-test-iframe-expected.txt (added)
-
LayoutTests/css3/masking/clip-path-hit-test-iframe.html (added)
-
LayoutTests/css3/masking/clip-path-hit-test-img-expected.txt (added)
-
LayoutTests/css3/masking/clip-path-hit-test-img.html (added)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/rendering/RenderBlock.cpp (modified) (4 diffs)
-
Source/WebCore/rendering/RenderBox.cpp (modified) (5 diffs)
-
Source/WebCore/rendering/RenderBox.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r278337 r278343 1 2021-05-28 Antoine Quint <graouts@webkit.org> 2 3 Hit-testing does not account for clip-path on <iframe> 4 https://bugs.webkit.org/show_bug.cgi?id=226380 5 <rdar://problem/78621486> 6 7 Reviewed by Antti Koivisto. 8 9 Add a new test which checks that we hit-test correctly in part of an 10 <iframe> or <img> clipped by the clip-path property. 11 12 * css3/masking/clip-path-hit-test-iframe-expected.txt: Added. 13 * css3/masking/clip-path-hit-test-iframe.html: Added. 14 * css3/masking/clip-path-hit-test-img-expected.txt: Added. 15 * css3/masking/clip-path-hit-test-img.html: Added. 16 1 17 2021-06-01 Lauro Moura <lmoura@igalia.com> 2 18 -
trunk/Source/WebCore/ChangeLog
r278341 r278343 1 2021-05-28 Antoine Quint <graouts@webkit.org> 2 3 Hit-testing does not account for clip-path on <iframe> 4 https://bugs.webkit.org/show_bug.cgi?id=226380 5 <rdar://problem/78621486> 6 7 Reviewed by Antti Koivisto. 8 9 The logic to account for the clip-path property during hit-testing was only found in RenderBlock::nodeAtPoint() 10 although other types of RenderBox objects may need this, such as RenderIFrame. So we move some of the logic 11 from RenderBlock::nodeAtPoint() to dedicated methods on RenderBox such that RenderBox::nodeAtPoint() may call them 12 but also allow for RenderBlock::nodeAtPoint() to call them. 13 14 Test: css3/masking/clip-path-hit-test-iframe.html 15 css3/masking/clip-path-hit-test-img.html 16 17 * rendering/RenderBlock.cpp: 18 (WebCore::RenderBlock::nodeAtPoint): 19 * rendering/RenderBox.cpp: 20 (WebCore::RenderBox::hitTestVisualOverflow const): 21 (WebCore::RenderBox::hitTestClipPath const): 22 (WebCore::RenderBox::hitTestBorderRadius const): 23 (WebCore::RenderBox::nodeAtPoint): 24 * rendering/RenderBox.h: 25 1 26 2021-06-02 Youenn Fablet <youenn@apple.com> 2 27 -
trunk/Source/WebCore/rendering/RenderBlock.cpp
r278340 r278343 64 64 #include "RenderListMarker.h" 65 65 #include "RenderMenuList.h" 66 #include "RenderSVGResourceClipper.h"67 66 #include "RenderSVGRoot.h" 68 67 #include "RenderTableCell.h" … … 2063 2062 const LayoutSize localOffset = toLayoutSize(adjustedLocation); 2064 2063 2065 if (!isRenderView()) { 2066 // Check if we need to do anything at all. 2067 LayoutRect overflowBox = visualOverflowRect(); 2068 flipForWritingMode(overflowBox); 2069 overflowBox.moveBy(adjustedLocation); 2070 if (!locationInContainer.intersects(overflowBox)) 2071 return false; 2072 } 2064 // Check if we need to do anything at all. 2065 if (!hitTestVisualOverflow(locationInContainer, accumulatedOffset)) 2066 return false; 2073 2067 2074 2068 if ((hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) && isPointInOverflowControl(result, locationInContainer.point(), adjustedLocation)) { … … 2079 2073 } 2080 2074 2081 if (style().clipPath()) { 2082 switch (style().clipPath()->type()) { 2083 case ClipPathOperation::Shape: { 2084 auto& clipPath = downcast<ShapeClipPathOperation>(*style().clipPath()); 2085 auto referenceBoxRect = referenceBox(clipPath.referenceBox()); 2086 if (!clipPath.pathForReferenceRect(referenceBoxRect).contains(locationInContainer.point() - localOffset, clipPath.windRule())) 2087 return false; 2088 break; 2089 } 2090 case ClipPathOperation::Reference: { 2091 const auto& referenceClipPathOperation = downcast<ReferenceClipPathOperation>(*style().clipPath()); 2092 auto* element = document().getElementById(referenceClipPathOperation.fragment()); 2093 if (!element || !element->renderer()) 2094 break; 2095 if (!is<SVGClipPathElement>(*element)) 2096 break; 2097 auto& clipper = downcast<RenderSVGResourceClipper>(*element->renderer()); 2098 if (!clipper.hitTestClipContent(FloatRect(borderBoxRect()), FloatPoint(locationInContainer.point() - localOffset))) 2099 return false; 2100 break; 2101 } 2102 case ClipPathOperation::Box: 2103 break; 2104 } 2105 } 2075 if (!hitTestClipPath(locationInContainer, accumulatedOffset)) 2076 return false; 2106 2077 2107 2078 // If we have clipping, then we can't have any spillout. … … 2114 2085 return true; 2115 2086 2116 // Check if the point is outside radii. 2117 if (!isRenderView() && style().hasBorderRadius()) { 2118 LayoutRect borderRect = borderBoxRect(); 2119 borderRect.moveBy(adjustedLocation); 2120 RoundedRect border = style().getRoundedBorderFor(borderRect); 2121 if (!locationInContainer.intersects(border)) 2122 return false; 2123 } 2087 if (!hitTestBorderRadius(locationInContainer, accumulatedOffset)) 2088 return false; 2124 2089 2125 2090 // Now hit test our background -
trunk/Source/WebCore/rendering/RenderBox.cpp
r278253 r278343 27 27 28 28 #include "CSSFontSelector.h" 29 #include "ClipPathOperation.h" 29 30 #include "ControlStates.h" 30 31 #include "Document.h" … … 67 68 #include "RenderLayoutState.h" 68 69 #include "RenderMultiColumnFlow.h" 70 #include "RenderSVGResourceClipper.h" 69 71 #include "RenderTableCell.h" 70 72 #include "RenderTheme.h" 71 73 #include "RenderView.h" 72 74 #include "RuntimeApplicationChecks.h" 75 #include "SVGClipPathElement.h" 73 76 #include "ScrollAnimator.h" 74 77 #include "ScrollbarTheme.h" … … 1340 1343 1341 1344 // Hit Testing 1345 bool RenderBox::hitTestVisualOverflow(const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) const 1346 { 1347 if (isRenderView()) 1348 return true; 1349 1350 LayoutPoint adjustedLocation = accumulatedOffset + location(); 1351 LayoutRect overflowBox = visualOverflowRect(); 1352 flipForWritingMode(overflowBox); 1353 overflowBox.moveBy(adjustedLocation); 1354 return locationInContainer.intersects(overflowBox); 1355 } 1356 1357 bool RenderBox::hitTestClipPath(const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) const 1358 { 1359 if (!style().clipPath()) 1360 return true; 1361 1362 LayoutPoint adjustedLocation = accumulatedOffset + location(); 1363 const LayoutSize localOffset = toLayoutSize(adjustedLocation); 1364 1365 switch (style().clipPath()->type()) { 1366 case ClipPathOperation::Shape: { 1367 auto& clipPath = downcast<ShapeClipPathOperation>(*style().clipPath()); 1368 auto referenceBoxRect = referenceBox(clipPath.referenceBox()); 1369 if (!clipPath.pathForReferenceRect(referenceBoxRect).contains(locationInContainer.point() - localOffset, clipPath.windRule())) 1370 return false; 1371 break; 1372 } 1373 case ClipPathOperation::Reference: { 1374 const auto& referenceClipPathOperation = downcast<ReferenceClipPathOperation>(*style().clipPath()); 1375 auto* element = document().getElementById(referenceClipPathOperation.fragment()); 1376 if (!element || !element->renderer()) 1377 break; 1378 if (!is<SVGClipPathElement>(*element)) 1379 break; 1380 auto& clipper = downcast<RenderSVGResourceClipper>(*element->renderer()); 1381 if (!clipper.hitTestClipContent(FloatRect(borderBoxRect()), FloatPoint(locationInContainer.point() - localOffset))) 1382 return false; 1383 break; 1384 } 1385 case ClipPathOperation::Box: 1386 break; 1387 } 1388 1389 return true; 1390 } 1391 1392 bool RenderBox::hitTestBorderRadius(const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) const 1393 { 1394 if (isRenderView() || !style().hasBorderRadius()) 1395 return true; 1396 1397 LayoutPoint adjustedLocation = accumulatedOffset + location(); 1398 LayoutRect borderRect = borderBoxRect(); 1399 borderRect.moveBy(adjustedLocation); 1400 RoundedRect border = style().getRoundedBorderFor(borderRect); 1401 return locationInContainer.intersects(border); 1402 } 1403 1342 1404 bool RenderBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action) 1343 1405 { … … 1357 1419 boundsRect.moveBy(adjustedLocation); 1358 1420 if (visibleToHitTesting(request) && action == HitTestForeground && locationInContainer.intersects(boundsRect)) { 1421 if (!hitTestVisualOverflow(locationInContainer, accumulatedOffset)) 1422 return false; 1423 1424 if (!hitTestClipPath(locationInContainer, accumulatedOffset)) 1425 return false; 1426 1427 if (!hitTestBorderRadius(locationInContainer, accumulatedOffset)) 1428 return false; 1429 1359 1430 updateHitTestResult(result, locationInContainer.point() - toLayoutSize(adjustedLocation)); 1360 1431 if (result.addNodeToListBasedTestResult(nodeForHitTest(), request, locationInContainer, boundsRect) == HitTestProgress::Stop) … … 1362 1433 } 1363 1434 1364 return false;1435 return RenderBoxModelObject::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, action); 1365 1436 } 1366 1437 -
trunk/Source/WebCore/rendering/RenderBox.h
r278253 r278343 307 307 void layout() override; 308 308 bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) override; 309 bool hitTestVisualOverflow(const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) const; 310 bool hitTestClipPath(const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) const; 311 bool hitTestBorderRadius(const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) const; 309 312 310 313 LayoutUnit minPreferredLogicalWidth() const override;
Note:
See TracChangeset
for help on using the changeset viewer.