Changeset 244215 in webkit
- Timestamp:
- Apr 12, 2019 7:54:12 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 12 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r244213 r244215 1 2019-04-11 Simon Fraser <simon.fraser@apple.com> 2 3 [iOS WK2] Wrong scrolling behavior for nested absolute position elements inside overflow scroll 4 https://bugs.webkit.org/show_bug.cgi?id=196146 5 6 Reviewed by Antti Koivisto. 7 8 Dump the scrolling tree for various configurations of positioned, overflow and stacking context 9 elements. 10 11 * fast/scrolling/ios/overflow-scroll-overlap-6-expected.txt: Progressed results. 12 * platform/ios-wk2/scrollingcoordinator/scrolling-tree/nested-absolute-in-absolute-overflow-expected.txt: Added. 13 * platform/ios-wk2/scrollingcoordinator/scrolling-tree/nested-absolute-in-overflow-expected.txt: Added. 14 * platform/ios-wk2/scrollingcoordinator/scrolling-tree/nested-absolute-in-relative-in-overflow-expected.txt: Added. 15 * platform/ios-wk2/scrollingcoordinator/scrolling-tree/nested-absolute-in-sc-overflow-expected.txt: Added. 16 * scrollingcoordinator/scrolling-tree/nested-absolute-in-absolute-overflow-expected.txt: Added. 17 * scrollingcoordinator/scrolling-tree/nested-absolute-in-absolute-overflow.html: Added. 18 * scrollingcoordinator/scrolling-tree/nested-absolute-in-overflow-expected.txt: Added. 19 * scrollingcoordinator/scrolling-tree/nested-absolute-in-overflow.html: Added. 20 * scrollingcoordinator/scrolling-tree/nested-absolute-in-relative-in-overflow-expected.txt: Added. 21 * scrollingcoordinator/scrolling-tree/nested-absolute-in-relative-in-overflow.html: Added. 22 * scrollingcoordinator/scrolling-tree/nested-absolute-in-sc-overflow-expected.txt: Added. 23 * scrollingcoordinator/scrolling-tree/nested-absolute-in-sc-overflow.html: Added. 24 1 25 2019-04-12 Manuel Rego Casasnovas <rego@igalia.com> 2 26 -
trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap-6-expected.txt
r243380 r244215 2 2 3 3 case 1: 4 case 2: Scrollable 25 case 3: Scrollable 34 case 2: 5 case 3: 6 6 -
trunk/Source/WebCore/ChangeLog
r244213 r244215 1 2019-04-11 Simon Fraser <simon.fraser@apple.com> 2 3 [iOS WK2] Wrong scrolling behavior for nested absolute position elements inside overflow scroll 4 https://bugs.webkit.org/show_bug.cgi?id=196146 5 6 Reviewed by Antti Koivisto. 7 8 computeCoordinatedPositioningForLayer() failed to handle nested positions elements 9 inside overflow scroll, because it only walked up to the first containing block of 10 a nested position:absolute. We need to walk all the way up the ancestor layer chain, 11 looking at containing block, scroller and composited ancestor relationships. 12 13 Make this code easier to understand by writing it in terms of "is foo scrolled by bar", rather than 14 trying to collapse all the logic into a single ancestor walk, which was really hard. This is a few 15 more ancestor traversals, but we now only run this code if there's composited scrolling 16 in the ancestor chain. 17 18 Tests: scrollingcoordinator/scrolling-tree/nested-absolute-in-absolute-overflow.html 19 scrollingcoordinator/scrolling-tree/nested-absolute-in-overflow.html 20 scrollingcoordinator/scrolling-tree/nested-absolute-in-relative-in-overflow.html 21 scrollingcoordinator/scrolling-tree/nested-absolute-in-sc-overflow.html 22 23 * rendering/RenderLayerCompositor.cpp: 24 (WebCore::enclosingCompositedScrollingLayer): 25 (WebCore::isScrolledByOverflowScrollLayer): 26 (WebCore::isNonScrolledLayerInsideScrolledCompositedAncestor): 27 (WebCore::RenderLayerCompositor::layerContainingBlockCrossesCoordinatedScrollingBoundary): 28 (WebCore::collectStationaryLayerRelatedOverflowNodes): 29 (WebCore::RenderLayerCompositor::computeCoordinatedPositioningForLayer const): 30 (WebCore::collectRelatedCoordinatedScrollingNodes): 31 (WebCore::layerParentedAcrossCoordinatedScrollingBoundary): Deleted. 32 1 33 2019-04-12 Manuel Rego Casasnovas <rego@igalia.com> 2 34 -
trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp
r244209 r244215 2905 2905 } 2906 2906 2907 // Is this layer's containingBlock an ancestor of scrollable overflow, and is the layer's compositing ancestor inside that overflow? 2907 static RenderLayer* enclosingCompositedScrollingLayer(const RenderLayer& layer, const RenderLayer& intermediateLayer, bool& sawIntermediateLayer) 2908 { 2909 const auto* currLayer = &layer; 2910 while (currLayer) { 2911 if (currLayer == &intermediateLayer) 2912 sawIntermediateLayer = true; 2913 2914 if (currLayer->hasCompositedScrollableOverflow()) 2915 return const_cast<RenderLayer*>(currLayer); 2916 2917 currLayer = currLayer->parent(); 2918 } 2919 2920 return nullptr; 2921 } 2922 2923 // Return true if overflowScrollLayer is in layer's containing block chain. 2924 static bool isScrolledByOverflowScrollLayer(const RenderLayer& layer, const RenderLayer& overflowScrollLayer) 2925 { 2926 bool containingBlockCanSkipLayers = layer.renderer().isAbsolutelyPositioned(); 2927 2928 for (const auto* currLayer = layer.parent(); currLayer; currLayer = currLayer->parent()) { 2929 bool inContainingBlockChain = true; 2930 if (containingBlockCanSkipLayers) { 2931 inContainingBlockChain = currLayer->renderer().canContainAbsolutelyPositionedObjects(); 2932 if (inContainingBlockChain) 2933 containingBlockCanSkipLayers = currLayer->renderer().isAbsolutelyPositioned(); 2934 } 2935 2936 if (currLayer == &overflowScrollLayer) 2937 return inContainingBlockChain; 2938 } 2939 2940 return false; 2941 } 2942 2943 static bool isNonScrolledLayerInsideScrolledCompositedAncestor(const RenderLayer& layer, const RenderLayer& compositedAncestor, const RenderLayer& scrollingAncestor) 2944 { 2945 bool ancestorMovedByScroller = &compositedAncestor == &scrollingAncestor || isScrolledByOverflowScrollLayer(compositedAncestor, scrollingAncestor); 2946 bool layerMovedByScroller = isScrolledByOverflowScrollLayer(layer, scrollingAncestor); 2947 2948 return ancestorMovedByScroller && !layerMovedByScroller; 2949 } 2950 2908 2951 bool RenderLayerCompositor::layerContainingBlockCrossesCoordinatedScrollingBoundary(const RenderLayer& layer, const RenderLayer& compositedAncestor) 2909 2952 { 2953 bool compositedAncestorIsInsideScroller = false; 2954 auto* scrollingAncestor = enclosingCompositedScrollingLayer(layer, compositedAncestor, compositedAncestorIsInsideScroller); 2955 if (!scrollingAncestor) { 2956 ASSERT_NOT_REACHED(); // layer.hasCompositedScrollingAncestor() should guarantee we have one. 2957 return false; 2958 } 2959 2960 if (!compositedAncestorIsInsideScroller) 2961 return false; 2962 2963 return isNonScrolledLayerInsideScrolledCompositedAncestor(layer, compositedAncestor, *scrollingAncestor); 2964 } 2965 2966 static void collectStationaryLayerRelatedOverflowNodes(const RenderLayer& layer, const RenderLayer& /*compositedAncestor*/, Vector<ScrollingNodeID>& scrollingNodes) 2967 { 2968 ASSERT(layer.isComposited()); 2969 2970 auto appendOverflowLayerNodeID = [&scrollingNodes] (const RenderLayer& overflowLayer) { 2971 ASSERT(overflowLayer.isComposited()); 2972 auto scrollingNodeID = overflowLayer.backing()->scrollingNodeIDForRole(ScrollCoordinationRole::Scrolling); 2973 if (scrollingNodeID) 2974 scrollingNodes.append(scrollingNodeID); 2975 else 2976 LOG(Scrolling, "Layer %p doesn't have scrolling node ID yet", &overflowLayer); 2977 }; 2978 2910 2979 ASSERT(layer.renderer().isAbsolutelyPositioned()); 2911 2912 bool sawCompositingAncestor = false; 2980 bool containingBlockCanSkipLayers = true; 2981 2913 2982 for (const auto* currLayer = layer.parent(); currLayer; currLayer = currLayer->parent()) { 2914 if (currLayer->renderer().canContainAbsolutelyPositionedObjects()) 2915 return false; 2916 2917 if (currLayer == &compositedAncestor) 2918 sawCompositingAncestor = true; 2919 2920 if (currLayer->hasCompositedScrollableOverflow()) 2921 return sawCompositingAncestor; 2922 } 2923 2924 return false; 2925 } 2926 2927 // Is there scrollable overflow between this layer and its composited ancestor, and the containing block is the scroller or inside the scroller. 2928 static bool layerParentedAcrossCoordinatedScrollingBoundary(const RenderLayer& layer, const RenderLayer& compositedAncestor, bool checkContainingBlock, bool& containingBlockIsInsideOverflow) 2929 { 2930 ASSERT(layer.isComposited()); 2931 2932 for (const auto* currLayer = layer.parent(); currLayer != &compositedAncestor; currLayer = currLayer->parent()) { 2933 if (checkContainingBlock && currLayer->renderer().canContainAbsolutelyPositionedObjects()) 2934 containingBlockIsInsideOverflow = true; 2935 2936 if (currLayer->hasCompositedScrollableOverflow()) 2937 return true; 2938 } 2939 2940 return false; 2941 } 2983 bool inContainingBlockChain = true; 2984 if (containingBlockCanSkipLayers) { 2985 inContainingBlockChain = currLayer->renderer().canContainAbsolutelyPositionedObjects(); 2986 if (inContainingBlockChain) 2987 containingBlockCanSkipLayers = currLayer->renderer().isAbsolutelyPositioned(); 2988 } 2989 2990 if (currLayer->hasCompositedScrollableOverflow()) { 2991 appendOverflowLayerNodeID(*currLayer); 2992 break; 2993 } 2994 } 2995 } 2996 2942 2997 2943 2998 ScrollPositioningBehavior RenderLayerCompositor::computeCoordinatedPositioningForLayer(const RenderLayer& layer) const … … 2955 3010 if (!scrollingCoordinator) 2956 3011 return ScrollPositioningBehavior::None; 3012 3013 auto* compositedAncestor = layer.ancestorCompositingLayer(); 3014 if (!compositedAncestor) { 3015 ASSERT_NOT_REACHED(); 3016 return ScrollPositioningBehavior::None; 3017 } 3018 3019 bool compositedAncestorIsInsideScroller = false; 3020 auto* scrollingAncestor = enclosingCompositedScrollingLayer(layer, *compositedAncestor, compositedAncestorIsInsideScroller); 3021 if (!scrollingAncestor) { 3022 ASSERT_NOT_REACHED(); // layer.hasCompositedScrollingAncestor() should guarantee we have one. 3023 return ScrollPositioningBehavior::None; 3024 } 2957 3025 2958 3026 // There are two cases we have to deal with here: … … 2960 3028 // composited (z-order) ancestor is inside the scroller or is the scroller. In this case, we have to compensate for scroll position 2961 3029 // changes to make the positioned layer stay in the same place. This only applies to position:absolute (since we handle fixed elsewhere). 2962 auto* compositedAncestor = layer.ancestorCompositingLayer(); 2963 2964 auto& renderer = layer.renderer(); 2965 bool containingBlockCanSkipOverflow = renderer.isOutOfFlowPositioned() && renderer.style().position() == PositionType::Absolute; 2966 if (containingBlockCanSkipOverflow) { 2967 if (layerContainingBlockCrossesCoordinatedScrollingBoundary(layer, *compositedAncestor)) 3030 if (layer.renderer().isAbsolutelyPositioned()) { 3031 if (compositedAncestorIsInsideScroller && isNonScrolledLayerInsideScrolledCompositedAncestor(layer, *compositedAncestor, *scrollingAncestor)) 2968 3032 return ScrollPositioningBehavior::Stationary; 2969 3033 } … … 2972 3036 // outside the overflow:scroll. In that case, we have to move the layer via the scrolling tree to make 2973 3037 // it move along with the overflow scrolling. 2974 bool containingBlockIsInsideOverflow = !containingBlockCanSkipOverflow; 2975 if (layerParentedAcrossCoordinatedScrollingBoundary(layer, *compositedAncestor, containingBlockCanSkipOverflow, containingBlockIsInsideOverflow) && containingBlockIsInsideOverflow) 3038 if (!compositedAncestorIsInsideScroller && isScrolledByOverflowScrollLayer(layer, *scrollingAncestor)) 2976 3039 return ScrollPositioningBehavior::Moves; 2977 3040 … … 2999 3062 } 3000 3063 case ScrollPositioningBehavior::Stationary: { 3001 // Collect all the composited scrollers between this layer and its containing block. 3002 ASSERT(layer.renderer().style().position() == PositionType::Absolute); 3003 for (const auto* currLayer = layer.parent(); currLayer; currLayer = currLayer->parent()) { 3004 if (currLayer->renderer().canContainAbsolutelyPositionedObjects()) 3005 break; 3006 3007 if (currLayer->hasCompositedScrollableOverflow()) { 3008 auto scrollingNodeID = currLayer->backing()->scrollingNodeIDForRole(ScrollCoordinationRole::Scrolling); 3009 if (scrollingNodeID) 3010 overflowNodeData.append(scrollingNodeID); 3011 else 3012 LOG(Scrolling, "Layer %p doesn't have scrolling node ID yet", &layer); 3013 } 3014 } 3015 // Don't need to do anything because the layer is a descendant of the overflow in stacking. 3064 ASSERT(layer.renderer().isAbsolutelyPositioned()); 3065 // Collect all the composited scrollers between this layer and its composited ancestor. 3066 auto* compositedAncestor = layer.ancestorCompositingLayer(); 3067 if (!compositedAncestor) 3068 return overflowNodeData; 3069 collectStationaryLayerRelatedOverflowNodes(layer, *compositedAncestor, overflowNodeData); 3016 3070 break; 3017 3071 }
Note: See TracChangeset
for help on using the changeset viewer.