diff options
Diffstat (limited to 'Source/WebCore/rendering/RenderLayerModelObject.cpp')
-rw-r--r-- | Source/WebCore/rendering/RenderLayerModelObject.cpp | 107 |
1 files changed, 83 insertions, 24 deletions
diff --git a/Source/WebCore/rendering/RenderLayerModelObject.cpp b/Source/WebCore/rendering/RenderLayerModelObject.cpp index ba528c67e..343d14119 100644 --- a/Source/WebCore/rendering/RenderLayerModelObject.cpp +++ b/Source/WebCore/rendering/RenderLayerModelObject.cpp @@ -26,7 +26,10 @@ #include "RenderLayerModelObject.h" #include "RenderLayer.h" +#include "RenderLayerCompositor.h" #include "RenderView.h" +#include "Settings.h" +#include "StyleScrollSnapPoints.h" namespace WebCore { @@ -35,18 +38,30 @@ bool RenderLayerModelObject::s_hadLayer = false; bool RenderLayerModelObject::s_hadTransform = false; bool RenderLayerModelObject::s_layerWasSelfPainting = false; -RenderLayerModelObject::RenderLayerModelObject(Element& element, PassRef<RenderStyle> style, unsigned baseTypeFlags) - : RenderElement(element, std::move(style), baseTypeFlags | RenderLayerModelObjectFlag) +RenderLayerModelObject::RenderLayerModelObject(Element& element, RenderStyle&& style, BaseTypeFlags baseTypeFlags) + : RenderElement(element, WTFMove(style), baseTypeFlags | RenderLayerModelObjectFlag) { } -RenderLayerModelObject::RenderLayerModelObject(Document& document, PassRef<RenderStyle> style, unsigned baseTypeFlags) - : RenderElement(document, std::move(style), baseTypeFlags | RenderLayerModelObjectFlag) +RenderLayerModelObject::RenderLayerModelObject(Document& document, RenderStyle&& style, BaseTypeFlags baseTypeFlags) + : RenderElement(document, WTFMove(style), baseTypeFlags | RenderLayerModelObjectFlag) { } RenderLayerModelObject::~RenderLayerModelObject() { + // Do not add any code here. Add it to willBeDestroyed() instead. +} + +void RenderLayerModelObject::willBeDestroyed() +{ + if (isPositioned()) { + if (style().hasViewportConstrainedPosition()) + view().frameView().removeViewportConstrainedObject(this); + } + + RenderElement::willBeDestroyed(); + // Our layer should have been destroyed and cleared by now ASSERT(!hasLayer()); ASSERT(!m_layer); @@ -72,17 +87,6 @@ bool RenderLayerModelObject::hasSelfPaintingLayer() const return m_layer && m_layer->isSelfPaintingLayer(); } -void RenderLayerModelObject::willBeDestroyed() -{ - if (isPositioned()) { - if (style().hasViewportConstrainedPosition()) - view().frameView().removeViewportConstrainedObject(this); - } - - // RenderObject::willBeDestroyed calls back to destroyLayer() for layer destruction - RenderElement::willBeDestroyed(); -} - void RenderLayerModelObject::styleWillChange(StyleDifference diff, const RenderStyle& newStyle) { s_wasFloating = isFloating(); @@ -107,8 +111,7 @@ void RenderLayerModelObject::styleWillChange(StyleDifference diff, const RenderS } if (diff == StyleDifferenceLayout || diff == StyleDifferenceSimplifiedLayout) { - // When a layout hint happens, we go ahead and do a repaint of the layer, since the layer could - // end up being destroyed. + // When a layout hint happens, we do a repaint of the layer, since the layer could end up being destroyed. if (hasLayer()) { if (oldStyle->position() != newStyle.position() || oldStyle->zIndex() != newStyle.zIndex() @@ -117,12 +120,10 @@ void RenderLayerModelObject::styleWillChange(StyleDifference diff, const RenderS || oldStyle->hasClip() != newStyle.hasClip() || oldStyle->opacity() != newStyle.opacity() || oldStyle->transform() != newStyle.transform() -#if ENABLE(CSS_FILTERS) || oldStyle->filter() != newStyle.filter() -#endif ) layer()->repaintIncludingDescendants(); - } else if (newStyle.hasTransform() || newStyle.opacity() < 1 || newStyle.hasFilter()) { + } else if (newStyle.hasTransform() || newStyle.opacity() < 1 || newStyle.hasFilter() || newStyle.hasBackdropFilter()) { // If we don't have a layer yet, but we are going to get one because of transform or opacity, // then we need to repaint the old position of the object. repaint(); @@ -133,6 +134,13 @@ void RenderLayerModelObject::styleWillChange(StyleDifference diff, const RenderS RenderElement::styleWillChange(diff, newStyle); } +#if ENABLE(CSS_SCROLL_SNAP) +static bool scrollSnapContainerRequiresUpdateForStyleUpdate(const RenderStyle& oldStyle, const RenderStyle& newStyle) +{ + return oldStyle.scrollSnapPort() != newStyle.scrollSnapPort(); +} +#endif + void RenderLayerModelObject::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) { RenderElement::styleDidChange(diff, oldStyle); @@ -151,8 +159,15 @@ void RenderLayerModelObject::styleDidChange(StyleDifference diff, const RenderSt } } } 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. +#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 && layer()->hasComputedRepaintRect()) + repaintUsingContainer(containerForRepaint(), layer()->repaintRect()); layer()->removeOnlyThisLayer(); // calls destroyLayer() which clears m_layer if (s_wasFloating && isFloating()) setChildNeedsLayout(); @@ -166,14 +181,58 @@ void RenderLayerModelObject::styleDidChange(StyleDifference diff, const RenderSt setChildNeedsLayout(); } - bool newStyleIsViewportConstained = style().hasViewportConstrainedPosition(); + bool newStyleIsViewportConstrained = style().hasViewportConstrainedPosition(); bool oldStyleIsViewportConstrained = oldStyle && oldStyle->hasViewportConstrainedPosition(); - if (newStyleIsViewportConstained != oldStyleIsViewportConstrained) { - if (newStyleIsViewportConstained && layer()) + 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->scrollSnapArea() != newStyle.scrollSnapArea()) { + const RenderBox* scrollSnapBox = enclosingBox().findEnclosingScrollableContainer(); + if (scrollSnapBox && scrollSnapBox->layer()) { + const RenderStyle& style = scrollSnapBox->style(); + if (style.scrollSnapType().strictness != ScrollSnapStrictness::None) { + scrollSnapBox->layer()->updateSnapOffsets(); + scrollSnapBox->layer()->updateScrollSnapState(); + if (scrollSnapBox->isBody() || scrollSnapBox->isDocumentElementRenderer()) + scrollSnapBox->view().frameView().updateScrollingCoordinatorScrollSnapProperties(); + } + } + } +#endif +} + +bool RenderLayerModelObject::shouldPlaceBlockDirectionScrollbarOnLeft() const +{ +// RTL Scrollbars require some system support, and this system support does not exist on certain versions of OS X. iOS uses a separate mechanism. +#if PLATFORM(IOS) || (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101200) + return false; +#else + switch (settings().userInterfaceDirectionPolicy()) { + case UserInterfaceDirectionPolicy::Content: + return style().shouldPlaceBlockDirectionScrollbarOnLeft(); + case UserInterfaceDirectionPolicy::System: + return settings().systemLayoutDirection() == RTL; + } + ASSERT_NOT_REACHED(); + return style().shouldPlaceBlockDirectionScrollbarOnLeft(); +#endif } } // namespace WebCore |