void updateSnapOffsetsForScrollableArea(ScrollableArea& scrollableArea, HTMLElement& scrollingElement, const RenderBox& scrollingElementBox, const RenderStyle& scrollingElementStyle) { if (scrollingElementStyle.scrollSnapType() == ScrollSnapType::None) { scrollableArea.clearHorizontalSnapOffsets(); scrollableArea.clearVerticalSnapOffsets(); return; } LayoutUnit viewWidth = scrollingElementBox.width(); LayoutUnit viewHeight = scrollingElementBox.height(); LayoutUnit scrollWidth = scrollingElementBox.scrollWidth(); LayoutUnit scrollHeight = scrollingElementBox.scrollHeight(); bool canComputeHorizontalOffsets = scrollWidth > 0 && viewWidth > 0 && viewWidth < scrollWidth; bool canComputeVerticalOffsets = scrollHeight > 0 && viewHeight > 0 && viewHeight < scrollHeight; if (!canComputeHorizontalOffsets) scrollableArea.clearHorizontalSnapOffsets(); if (!canComputeVerticalOffsets) scrollableArea.clearVerticalSnapOffsets(); if (!canComputeHorizontalOffsets && !canComputeVerticalOffsets) return; Vector<LayoutUnit> horizontalSnapOffsetSubsequence; Vector<LayoutUnit> verticalSnapOffsetSubsequence; bool scrollSnapPointsXUsesElements = styleUsesElements(ScrollEventAxis::Horizontal, scrollingElementStyle); bool scrollSnapPointsYUsesElements = styleUsesElements(ScrollEventAxis::Vertical , scrollingElementStyle); if (scrollSnapPointsXUsesElements || scrollSnapPointsYUsesElements) { bool shouldAddHorizontalChildOffsets = scrollSnapPointsXUsesElements && canComputeHorizontalOffsets; bool shouldAddVerticalChildOffsets = scrollSnapPointsYUsesElements && canComputeVerticalOffsets; appendChildSnapOffsets(scrollingElement, shouldAddHorizontalChildOffsets, horizontalSnapOffsetSubsequence, shouldAddVerticalChildOffsets, verticalSnapOffsetSubsequence); } if (scrollingElementStyle.scrollSnapPointsX() && !scrollSnapPointsXUsesElements && canComputeHorizontalOffsets) { for (auto& snapLength : scrollingElementStyle.scrollSnapPointsX()->offsets) horizontalSnapOffsetSubsequence.append(valueForLength(snapLength, viewWidth)); } if (scrollingElementStyle.scrollSnapPointsY() && !scrollSnapPointsYUsesElements && canComputeVerticalOffsets) { for (auto& snapLength : scrollingElementStyle.scrollSnapPointsY()->offsets) verticalSnapOffsetSubsequence.append(valueForLength(snapLength, viewHeight)); } if (canComputeHorizontalOffsets) { auto horizontalSnapOffsets = std::make_unique<Vector<LayoutUnit>>(); updateFromStyle(*horizontalSnapOffsets, scrollingElementStyle, ScrollEventAxis::Horizontal, viewWidth, scrollWidth, horizontalSnapOffsetSubsequence); scrollableArea.setHorizontalSnapOffsets(WTF::move(horizontalSnapOffsets)); } if (canComputeVerticalOffsets) { auto verticalSnapOffsets = std::make_unique<Vector<LayoutUnit>>(); updateFromStyle(*verticalSnapOffsets, scrollingElementStyle, ScrollEventAxis::Vertical, viewHeight, scrollHeight, verticalSnapOffsetSubsequence); scrollableArea.setVerticalSnapOffsets(WTF::move(verticalSnapOffsets)); } }
void RenderLayerModelObject::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) { bool hadTransform = hasTransform(); RenderObject::styleDidChange(diff, oldStyle); updateFromStyle(); LayerType type = layerTypeRequired(); if (type != NoLayer) { if (!layer()) { createLayer(type); if (parent() && !needsLayout()) { // FIXME: This invalidation is overly broad. We should update to // do the correct invalidation at RenderStyle::diff time. crbug.com/349061 layer()->renderer()->setShouldDoFullPaintInvalidation(true); // FIXME: We should call a specialized version of this function. layer()->updateLayerPositionsAfterLayout(); } } } else if (layer() && layer()->parent()) { setHasTransform(false); // Either a transform wasn't specified or the object doesn't support transforms, so just null out the bit. layer()->removeOnlyThisLayer(); // calls destroyLayer() which clears m_layer if (hadTransform) setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(); } if (layer()) { // FIXME: Ideally we shouldn't need this setter but we can't easily infer an overflow-only layer // from the style. layer()->setLayerType(type); layer()->styleChanged(diff, oldStyle); } }
void RenderLayerModelObject::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) { bool hadTransform = hasTransform(); RenderObject::styleDidChange(diff, oldStyle); updateFromStyle(); LayerType type = layerTypeRequired(); if (type != NoLayer) { if (!layer() && layerCreationAllowedForSubtree()) { if (s_wasFloating && isFloating()) setChildNeedsLayout(); createLayer(type); if (parent() && !needsLayout() && containingBlock()) { // FIXME: This invalidation is overly broad. We should update to // do the correct invalidation at RenderStyle::diff time. crbug.com/349061 if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) layer()->renderer()->setShouldDoFullPaintInvalidationAfterLayout(true); else layer()->repainter().setRepaintStatus(NeedsFullRepaint); // Hit in animations/interpolation/perspective-interpolation.html // FIXME: I suspect we can remove this assert disabler now. DisableCompositingQueryAsserts disabler; layer()->updateLayerPositionRecursive(); } } } else if (layer() && layer()->parent()) { setHasTransform(false); // Either a transform wasn't specified or the object doesn't support transforms, so just null out the bit. setHasReflection(false); layer()->removeOnlyThisLayer(); // calls destroyLayer() which clears m_layer if (s_wasFloating && isFloating()) setChildNeedsLayout(); if (hadTransform) setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(); } if (layer()) { // FIXME: Ideally we shouldn't need this setter but we can't easily infer an overflow-only layer // from the style. layer()->setLayerType(type); layer()->styleChanged(diff, oldStyle); } if (FrameView *frameView = view()->frameView()) { bool newStyleIsViewportConstained = style()->hasViewportConstrainedPosition(); bool oldStyleIsViewportConstrained = oldStyle && oldStyle->hasViewportConstrainedPosition(); if (newStyleIsViewportConstained != oldStyleIsViewportConstrained) { if (newStyleIsViewportConstained && layer()) frameView->addViewportConstrainedObject(this); else frameView->removeViewportConstrainedObject(this); } } }
void RenderLayerModelObject::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) { bool hadTransform = hasTransform(); bool hadLayer = hasLayer(); bool layerWasSelfPainting = hadLayer && layer()->isSelfPaintingLayer(); RenderObject::styleDidChange(diff, oldStyle); updateFromStyle(); LayerType type = layerTypeRequired(); if (type != NoLayer) { if (!layer() && layerCreationAllowedForSubtree()) { if (s_wasFloating && isFloating()) setChildNeedsLayout(); createLayer(type); if (parent() && !needsLayout()) { // FIXME: We should call a specialized version of this function. layer()->updateLayerPositionsAfterLayout(); } } } else if (layer() && layer()->parent()) { setHasTransform(false); // Either a transform wasn't specified or the object doesn't support transforms, so just null out the bit. setHasReflection(false); layer()->removeOnlyThisLayer(); // calls destroyLayer() which clears m_layer if (s_wasFloating && isFloating()) setChildNeedsLayout(); if (hadTransform) setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(); } if (layer()) { // FIXME: Ideally we shouldn't need this setter but we can't easily infer an overflow-only layer // from the style. layer()->setLayerType(type); layer()->styleChanged(diff, oldStyle); if (hadLayer && layer()->isSelfPaintingLayer() != layerWasSelfPainting) setChildNeedsLayout(); } if (FrameView *frameView = view()->frameView()) { bool newStyleIsViewportConstained = style()->hasViewportConstrainedPosition(); bool oldStyleIsViewportConstrained = oldStyle && oldStyle->hasViewportConstrainedPosition(); if (newStyleIsViewportConstained != oldStyleIsViewportConstrained) { if (newStyleIsViewportConstained && layer()) frameView->addViewportConstrainedObject(this); else frameView->removeViewportConstrainedObject(this); } } }
void RenderLayerModelObject::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) { bool hadTransform = hasTransform(); bool hadLayer = hasLayer(); bool layerWasSelfPainting = hadLayer && layer()->isSelfPaintingLayer(); RenderObject::styleDidChange(diff, oldStyle); updateFromStyle(); if (requiresLayer()) { if (!layer() && layerCreationAllowedForSubtree()) { if (s_wasFloating && isFloating()) setChildNeedsLayout(); createLayer(); if (parent() && !needsLayout() && containingBlock()) { layer()->repainter().setRepaintStatus(NeedsFullRepaint); // There is only one layer to update, it is not worth using |cachedOffset| since // we are not sure the value will be used. layer()->updateLayerPositions(0); } } } else if (layer() && layer()->parent()) { setHasTransform(false); // Either a transform wasn't specified or the object doesn't support transforms, so just null out the bit. setHasReflection(false); layer()->removeOnlyThisLayer(); // calls destroyLayer() which clears m_layer if (s_wasFloating && isFloating()) setChildNeedsLayout(); if (hadTransform) setNeedsLayoutAndPrefWidthsRecalc(); } if (layer()) { layer()->styleChanged(diff, oldStyle); if (hadLayer && layer()->isSelfPaintingLayer() != layerWasSelfPainting) setChildNeedsLayout(); } if (FrameView *frameView = view()->frameView()) { bool newStyleIsViewportConstained = style()->hasViewportConstrainedPosition(); bool oldStyleIsViewportConstrained = oldStyle && oldStyle->hasViewportConstrainedPosition(); if (newStyleIsViewportConstained != oldStyleIsViewportConstrained) { if (newStyleIsViewportConstained && layer()) frameView->addViewportConstrainedObject(this); else frameView->removeViewportConstrainedObject(this); } } }
void RenderLayerModelObject::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) { RenderElement::styleDidChange(diff, oldStyle); updateFromStyle(); if (requiresLayer()) { if (!layer() && layerCreationAllowedForSubtree()) { if (s_wasFloating && isFloating()) setChildNeedsLayout(); createLayer(); if (parent() && !needsLayout() && containingBlock()) { layer()->setRepaintStatus(NeedsFullRepaint); // There is only one layer to update, it is not worth using |cachedOffset| since // we are not sure the value will be used. layer()->updateLayerPositions(0); } } } else if (layer() && layer()->parent()) { #if ENABLE(CSS_COMPOSITING) if (oldStyle->hasBlendMode()) layer()->parent()->dirtyAncestorChainHasBlendingDescendants(); #endif setHasTransformRelatedProperty(false); // All transform-related propeties force layers, so we know we don't have one or the object doesn't support them. setHasReflection(false); // Repaint the about to be destroyed self-painting layer when style change also triggers repaint. if (layer()->isSelfPaintingLayer() && layer()->repaintStatus() == NeedsFullRepaint) repaintUsingContainer(containerForRepaint(), layer()->repaintRect()); layer()->removeOnlyThisLayer(); // calls destroyLayer() which clears m_layer if (s_wasFloating && isFloating()) setChildNeedsLayout(); if (s_hadTransform) setNeedsLayoutAndPrefWidthsRecalc(); } if (layer()) { layer()->styleChanged(diff, oldStyle); if (s_hadLayer && layer()->isSelfPaintingLayer() != s_layerWasSelfPainting) setChildNeedsLayout(); } bool newStyleIsViewportConstrained = style().hasViewportConstrainedPosition(); bool oldStyleIsViewportConstrained = oldStyle && oldStyle->hasViewportConstrainedPosition(); if (newStyleIsViewportConstrained != oldStyleIsViewportConstrained) { if (newStyleIsViewportConstrained && layer()) view().frameView().addViewportConstrainedObject(this); else view().frameView().removeViewportConstrainedObject(this); } #if ENABLE(CSS_SCROLL_SNAP) const RenderStyle& newStyle = style(); if (oldStyle && scrollSnapContainerRequiresUpdateForStyleUpdate(*oldStyle, newStyle)) { if (RenderLayer* renderLayer = layer()) { renderLayer->updateSnapOffsets(); renderLayer->updateScrollSnapState(); } else if (isBody() || isDocumentElementRenderer()) { FrameView& frameView = view().frameView(); frameView.updateSnapOffsets(); frameView.updateScrollSnapState(); frameView.updateScrollingCoordinatorScrollSnapProperties(); } } if (oldStyle && oldStyle->scrollSnapCoordinates() != newStyle.scrollSnapCoordinates()) { const RenderBox* scrollSnapBox = enclosingBox().findEnclosingScrollableContainer(); if (scrollSnapBox && scrollSnapBox->layer()) { const RenderStyle& style = scrollSnapBox->style(); if (style.scrollSnapType() != ScrollSnapType::None) { scrollSnapBox->layer()->updateSnapOffsets(); scrollSnapBox->layer()->updateScrollSnapState(); if (scrollSnapBox->isBody() || scrollSnapBox->isDocumentElementRenderer()) scrollSnapBox->view().frameView().updateScrollingCoordinatorScrollSnapProperties(); } } } #endif }