Changeset 263659 in webkit
- Timestamp:
- Jun 29, 2020 5:15:06 AM (4 years ago)
- Location:
- trunk
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/imported/w3c/ChangeLog
r263647 r263659 1 2020-06-09 Sergio Villar Senin <svillar@igalia.com> 2 3 [css-flexbox] WebKit mistakenly lets pointer events (click/hover/etc) pass through flex items, if they have negative margin 4 https://bugs.webkit.org/show_bug.cgi?id=185771 5 6 Reviewed by Javier Fernandez. 7 8 * web-platform-tests/css/css-flexbox/hittest-overlapping-margin-expected.txt: Replaced FAIL by PASS expectation. 9 * web-platform-tests/css/css-flexbox/hittest-overlapping-order-expected.txt: Ditto. 10 1 11 2020-06-29 Rob Buis <rbuis@igalia.com> 2 12 -
trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-flexbox/hittest-overlapping-margin-expected.txt
r261859 r263659 1 1 foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo 2 2 3 FAIL Flexboxes should perform hit testing in reverse paint order for overlapping elements: negative margin case (crbug.com/844505) assert_equals: expected "DIV" but got "A" 3 PASS Flexboxes should perform hit testing in reverse paint order for overlapping elements: negative margin case (crbug.com/844505) 4 4 -
trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-flexbox/hittest-overlapping-order-expected.txt
r261859 r263659 1 1 foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo 2 2 3 FAIL Flexboxes should perform hit testing in reverse paint order for overlapping elements: flex order case (crbug.com/844505) assert_equals: expected "DIV" but got "A" 3 PASS Flexboxes should perform hit testing in reverse paint order for overlapping elements: flex order case (crbug.com/844505) 4 4 -
trunk/Source/WebCore/ChangeLog
r263658 r263659 1 2020-06-09 Sergio Villar Senin <svillar@igalia.com> 2 3 [css-flexbox] WebKit mistakenly lets pointer events (click/hover/etc) pass through flex items, if they have negative margin 4 https://bugs.webkit.org/show_bug.cgi?id=185771 5 6 Reviewed by Javier Fernandez. 7 8 When multiple child elements of a flexbox overlap (for example, due to negative margins), the element drawn in the 9 foreground may not actually capture the hit if the element underneath it is hit-tested despite being occluded. 10 This is because painting of flexbox children is done in order modified document order instead of raw document order. 11 12 In order to achieve this we should inspect flex items in reverse order modified document order. As the OrderIterator 13 cannot go backwards, we cache the reverse order of items when doing the layout in order to have fast hit testing in 14 flexbox containers. 15 16 As this behaviour is different to the one implemented in RenderBlock a new virtual method to perform hit testing of children 17 was extracted from RenderBlock:nodeAtPoint() to a new method called RenderBlock::hitTestChildren. The RenderBlock 18 implementation is identical to the current one but flexbox containers overwrite it. 19 20 Two WPT flexbox hittests are passing now thanks to this patch. 21 22 * rendering/RenderBlock.cpp: 23 (WebCore::RenderBlock::hitTestChildren): Implementation of the new virtual method extracted from nodeAtPoint. 24 (WebCore::RenderBlock::nodeAtPoint): Moved code to hit test children to hitTestChildren() 25 * rendering/RenderBlock.h: Added hitTestChildren new virtual method. 26 * rendering/RenderFlexibleBox.cpp: 27 (WebCore::RenderFlexibleBox::hitTestChildren): Implemented. 28 (WebCore::RenderFlexibleBox::layoutFlexItems): Cache the reverse of the order iterator to be used by hit testing. 29 * rendering/RenderFlexibleBox.h: Added hitTestChildren. 30 1 31 2020-06-29 Xabier Rodriguez Calvar <calvaris@igalia.com> 2 32 -
trunk/Source/WebCore/rendering/RenderBlock.cpp
r262481 r263659 2004 2004 } 2005 2005 2006 bool RenderBlock::hitTestChildren(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& adjustedLocation, HitTestAction hitTestAction) 2007 { 2008 // Hit test descendants first. 2009 const LayoutSize localOffset = toLayoutSize(adjustedLocation); 2010 const LayoutSize scrolledOffset(localOffset - toLayoutSize(scrollPosition())); 2011 2012 if (hitTestAction == HitTestFloat && hitTestFloats(request, result, locationInContainer, toLayoutPoint(scrolledOffset))) 2013 return true; 2014 if (hitTestContents(request, result, locationInContainer, toLayoutPoint(scrolledOffset), hitTestAction)) { 2015 updateHitTestResult(result, flipForWritingMode(locationInContainer.point() - localOffset)); 2016 return true; 2017 } 2018 return false; 2019 } 2020 2006 2021 bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction) 2007 2022 { 2008 LayoutPoint adjustedLocation(accumulatedOffset + location());2009 LayoutSize localOffset = toLayoutSize(adjustedLocation);2023 const LayoutPoint adjustedLocation(accumulatedOffset + location()); 2024 const LayoutSize localOffset = toLayoutSize(adjustedLocation); 2010 2025 2011 2026 if (!isRenderView()) { … … 2055 2070 bool useClip = (hasControlClip() || useOverflowClip); 2056 2071 bool checkChildren = !useClip || (hasControlClip() ? locationInContainer.intersects(controlClipRect(adjustedLocation)) : locationInContainer.intersects(overflowClipRect(adjustedLocation, nullptr, IncludeOverlayScrollbarSize))); 2057 if (checkChildren) { 2058 // Hit test descendants first. 2059 LayoutSize scrolledOffset(localOffset - toLayoutSize(scrollPosition())); 2060 2061 if (hitTestAction == HitTestFloat && hitTestFloats(request, result, locationInContainer, toLayoutPoint(scrolledOffset))) 2062 return true; 2063 if (hitTestContents(request, result, locationInContainer, toLayoutPoint(scrolledOffset), hitTestAction)) { 2064 updateHitTestResult(result, flipForWritingMode(locationInContainer.point() - localOffset)); 2065 return true; 2066 } 2067 } 2072 if (checkChildren && hitTestChildren(request, result, locationInContainer, adjustedLocation, hitTestAction)) 2073 return true; 2068 2074 2069 2075 if (!checkChildren && hitTestExcludedChildrenInBorder(request, result, locationInContainer, adjustedLocation, hitTestAction)) -
trunk/Source/WebCore/rendering/RenderBlock.h
r260173 r263659 453 453 // FIXME-BLOCKFLOW: Remove virtualization when all callers have moved to RenderBlockFlow 454 454 virtual bool hitTestFloats(const HitTestRequest&, HitTestResult&, const HitTestLocation&, const LayoutPoint&) { return false; } 455 virtual bool hitTestChildren(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& adjustedLocation, HitTestAction); 455 456 virtual bool hitTestInlineChildren(const HitTestRequest&, HitTestResult&, const HitTestLocation&, const LayoutPoint&, HitTestAction) { return false; } 456 457 bool hitTestExcludedChildrenInBorder(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction); -
trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp
r263399 r263659 33 33 34 34 #include "FlexibleBoxAlgorithm.h" 35 #include "HitTestResult.h" 35 36 #include "LayoutRepainter.h" 36 37 #include "RenderChildIterator.h" … … 253 254 } 254 255 } 256 } 257 258 bool RenderFlexibleBox::hitTestChildren(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& adjustedLocation, HitTestAction hitTestAction) 259 { 260 if (hitTestAction != HitTestForeground) 261 return false; 262 263 LayoutPoint scrolledOffset = hasOverflowClip() ? adjustedLocation - toLayoutSize(scrollPosition()) : adjustedLocation; 264 265 for (auto* child : m_reversedOrderIteratorForHitTesting) { 266 if (child->hasSelfPaintingLayer()) 267 continue; 268 auto childPoint = flipForWritingModeForChild(child, scrolledOffset); 269 if (child->hitTest(request, result, locationInContainer, childPoint)) { 270 updateHitTestResult(result, flipForWritingMode(toLayoutPoint(locationInContainer.point() - adjustedLocation))); 271 return true; 272 } 273 } 274 275 return false; 255 276 } 256 277 … … 873 894 // should work off this list of a subset. 874 895 // TODO(cbiesinger): That second part is not yet true. 896 // Also initialize the reversed order iterator that would be eventually used for hit testing. 875 897 Vector<FlexItem> allItems; 898 m_reversedOrderIteratorForHitTesting.clear(); 876 899 m_orderIterator.first(); 877 900 for (RenderBox* child = m_orderIterator.currentChild(); child; child = m_orderIterator.next()) { … … 882 905 continue; 883 906 } 907 m_reversedOrderIteratorForHitTesting.append(child); 884 908 allItems.append(constructFlexItem(*child, relayoutChildren)); 885 909 } 910 m_reversedOrderIteratorForHitTesting.reverse(); 886 911 887 912 const LayoutUnit lineBreakLength = mainAxisContentExtent(LayoutUnit::max()); -
trunk/Source/WebCore/rendering/RenderFlexibleBox.h
r252716 r263659 58 58 59 59 void styleDidChange(StyleDifference, const RenderStyle*) override; 60 bool hitTestChildren(const HitTestRequest&, HitTestResult&, const HitTestLocation&, const LayoutPoint& adjustedLocation, HitTestAction) override; 60 61 void paintChildren(PaintInfo& forSelf, const LayoutPoint&, PaintInfo& forChild, bool usePrintRect) override; 61 62 … … 209 210 210 211 mutable OrderIterator m_orderIterator { *this }; 212 Vector<RenderBox*> m_reversedOrderIteratorForHitTesting; 211 213 int m_numberOfInFlowChildrenOnFirstLine { -1 }; 212 214
Note: See TracChangeset
for help on using the changeset viewer.