summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/RenderElement.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/rendering/RenderElement.h')
-rw-r--r--Source/WebCore/rendering/RenderElement.h303
1 files changed, 225 insertions, 78 deletions
diff --git a/Source/WebCore/rendering/RenderElement.h b/Source/WebCore/rendering/RenderElement.h
index 31dc734b5..91f6af7e0 100644
--- a/Source/WebCore/rendering/RenderElement.h
+++ b/Source/WebCore/rendering/RenderElement.h
@@ -20,38 +20,63 @@
* Boston, MA 02110-1301, USA.
*/
-#ifndef RenderElement_h
-#define RenderElement_h
+#pragma once
+#include "CSSAnimationController.h"
+#include "LengthFunctions.h"
#include "RenderObject.h"
+#include "StyleInheritedData.h"
namespace WebCore {
+class ControlStates;
+class RenderBlock;
+
class RenderElement : public RenderObject {
public:
virtual ~RenderElement();
- static RenderPtr<RenderElement> createFor(Element&, PassRef<RenderStyle>);
+ static RenderPtr<RenderElement> createFor(Element&, RenderStyle&&);
bool hasInitializedStyle() const { return m_hasInitializedStyle; }
- RenderStyle& style() const { return const_cast<RenderStyle&>(m_style.get()); }
- RenderStyle& firstLineStyle() const;
+ const RenderStyle& style() const { return m_style; }
+ const RenderStyle& firstLineStyle() const;
+
+ // FIXME: Style shouldn't be mutated.
+ RenderStyle& mutableStyle() { return m_style; }
void initializeStyle();
- void setStyle(PassRef<RenderStyle>);
- // Called to update a style that is allowed to trigger animations.
- void setAnimatableStyle(PassRef<RenderStyle>);
+ // Calling with minimalStyleDifference > StyleDifferenceEqual indicates that
+ // out-of-band state (e.g. animations) requires that styleDidChange processing
+ // continue even if the style isn't different from the current style.
+ void setStyle(RenderStyle&&, StyleDifference minimalStyleDifference = StyleDifferenceEqual);
+
+ // The pseudo element style can be cached or uncached. Use the cached method if the pseudo element doesn't respect
+ // any pseudo classes (and therefore has no concept of changing state).
+ const RenderStyle* getCachedPseudoStyle(PseudoId, const RenderStyle* parentStyle = nullptr) const;
+ std::unique_ptr<RenderStyle> getUncachedPseudoStyle(const PseudoStyleRequest&, const RenderStyle* parentStyle = nullptr, const RenderStyle* ownStyle = nullptr) const;
// This is null for anonymous renderers.
- Element* element() const { return toElement(RenderObject::node()); }
- Element* nonPseudoElement() const { return toElement(RenderObject::nonPseudoNode()); }
+ Element* element() const { return downcast<Element>(RenderObject::node()); }
+ Element* nonPseudoElement() const { return downcast<Element>(RenderObject::nonPseudoNode()); }
Element* generatingElement() const;
RenderObject* firstChild() const { return m_firstChild; }
RenderObject* lastChild() const { return m_lastChild; }
+ bool canContainFixedPositionObjects() const;
+ bool canContainAbsolutelyPositionedObjects() const;
+
+ Color selectionColor(int colorProperty) const;
+ std::unique_ptr<RenderStyle> selectionPseudoStyle() const;
+
+ // Obtains the selection colors that should be used when painting a selection.
+ Color selectionBackgroundColor() const;
+ Color selectionForegroundColor() const;
+ Color selectionEmphasisMarkColor() const;
+
// FIXME: Make these standalone and move to relevant files.
bool isRenderLayerModelObject() const;
bool isBoxModelObject() const;
@@ -62,8 +87,8 @@ public:
bool isRenderNamedFlowFragmentContainer() const;
virtual bool isChildAllowed(const RenderObject&, const RenderStyle&) const { return true; }
- virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0);
- virtual void addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild = 0) { return addChild(newChild, beforeChild); }
+ virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = nullptr);
+ virtual void addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild = nullptr) { return addChild(newChild, beforeChild); }
virtual void removeChild(RenderObject&);
// The following functions are used when the render tree hierarchy changes to make sure layers get
@@ -80,7 +105,7 @@ public:
virtual RenderElement* hoverAncestor() const;
- virtual void dirtyLinesFromChangedChild(RenderObject*) { }
+ virtual void dirtyLinesFromChangedChild(RenderObject&) { }
bool ancestorLineBoxDirty() const { return m_ancestorLineBoxDirty; }
void setAncestorLineBoxDirty(bool f = true);
@@ -92,30 +117,33 @@ public:
virtual void paint(PaintInfo&, const LayoutPoint&) = 0;
+ // inline-block elements paint all phases atomically. This function ensures that. Certain other elements
+ // (grid items, flex items) require this behavior as well, and this function exists as a helper for them.
+ // It is expected that the caller will call this function independent of the value of paintInfo.phase.
+ void paintAsInlineBlock(PaintInfo&, const LayoutPoint&);
+
// Recursive function that computes the size and position of this object and all its descendants.
virtual void layout();
/* This function performs a layout only if one is needed. */
void layoutIfNeeded() { if (needsLayout()) layout(); }
- // Return the renderer whose background style is used to paint the root background. Should only be called on the renderer for which isRoot() is true.
- RenderElement& rendererForRootBackground();
-
- // Used only by Element::pseudoStyleCacheIsInvalid to get a first line style based off of a
- // given new style, without accessing the cache.
- PassRefPtr<RenderStyle> uncachedFirstLineStyle(RenderStyle*) const;
-
// Updates only the local style ptr of the object. Does not update the state of the object,
// and so only should be called when the style is known not to have changed (or from setStyle).
- void setStyleInternal(PassRef<RenderStyle> style) { m_style = std::move(style); }
+ void setStyleInternal(RenderStyle&& style) { m_style = WTFMove(style); }
+
+ bool hasInitialAnimatedStyle() const { return m_hasInitialAnimatedStyle; }
+ void setHasInitialAnimatedStyle(bool b) { m_hasInitialAnimatedStyle = b; }
// Repaint only if our old bounds and new bounds are different. The caller may pass in newBounds and newOutlineBox if they are known.
bool repaintAfterLayoutIfNeeded(const RenderLayerModelObject* repaintContainer, const LayoutRect& oldBounds, const LayoutRect& oldOutlineBox, const LayoutRect* newBoundsPtr = nullptr, const LayoutRect* newOutlineBoxPtr = nullptr);
bool borderImageIsLoadedAndCanBeRendered() const;
+ bool mayCauseRepaintInsideViewport(const IntRect* visibleRect = nullptr) const;
// Returns true if this renderer requires a new stacking context.
- bool createsGroup() const { return isTransparent() || hasMask() || hasFilter() || hasBlendMode(); }
+ static bool createsGroupForStyle(const RenderStyle&);
+ bool createsGroup() const { return createsGroupForStyle(style()); }
bool isTransparent() const { return style().opacity() < 1.0f; }
float opacity() const { return style().opacity(); }
@@ -128,12 +156,27 @@ public:
bool hasClipOrOverflowClip() const { return hasClip() || hasOverflowClip(); }
bool hasClipPath() const { return style().clipPath(); }
bool hasHiddenBackface() const { return style().backfaceVisibility() == BackfaceVisibilityHidden; }
+ bool hasOutlineAnnotation() const;
+ bool hasOutline() const { return style().hasOutline() || hasOutlineAnnotation(); }
+ bool hasSelfPaintingLayer() const;
+
+ bool checkForRepaintDuringLayout() const;
+
+ // anchorRect() is conceptually similar to absoluteBoundingBoxRect(), but is intended for scrolling to an anchor.
+ // For inline renderers, this gets the logical top left of the first leaf child and the logical bottom right of the
+ // last leaf child, converts them to absolute coordinates, and makes a box out of them.
+ LayoutRect absoluteAnchorRect(bool* insideFixed = nullptr) const;
-#if ENABLE(CSS_FILTERS)
bool hasFilter() const { return style().hasFilter(); }
+ bool hasBackdropFilter() const
+ {
+#if ENABLE(FILTERS_LEVEL_2)
+ return style().hasBackdropFilter();
#else
- bool hasFilter() const { return false; }
+ return false;
#endif
+ }
+
#if ENABLE(CSS_COMPOSITING)
bool hasBlendMode() const { return style().hasBlendMode(); }
@@ -141,26 +184,64 @@ public:
bool hasBlendMode() const { return false; }
#endif
+ bool hasShapeOutside() const { return style().shapeOutside(); }
+
+ void registerForVisibleInViewportCallback();
+ void unregisterForVisibleInViewportCallback();
+ void visibleInViewportStateChanged(VisibleInViewportState);
+
+ bool repaintForPausedImageAnimationsIfNeeded(const IntRect& visibleRect);
+ bool hasPausedImageAnimations() const { return m_hasPausedImageAnimations; }
+ void setHasPausedImageAnimations(bool b) { m_hasPausedImageAnimations = b; }
+
+ void setRenderBoxNeedsLazyRepaint(bool b) { m_renderBoxNeedsLazyRepaint = b; }
+ bool renderBoxNeedsLazyRepaint() const { return m_renderBoxNeedsLazyRepaint; }
+
+ bool hasCounterNodeMap() const { return m_hasCounterNodeMap; }
+ void setHasCounterNodeMap(bool f) { m_hasCounterNodeMap = f; }
+
+ bool isCSSAnimating() const { return m_isCSSAnimating; }
+ void setIsCSSAnimating(bool b) { m_isCSSAnimating = b; }
+
+ const RenderElement* enclosingRendererWithTextDecoration(TextDecoration, bool firstLine) const;
+ void drawLineForBoxSide(GraphicsContext&, const FloatRect&, BoxSide, Color, EBorderStyle, float adjacentWidth1, float adjacentWidth2, bool antialias = false) const;
+
+ bool childRequiresTable(const RenderObject& child) const;
+ bool hasContinuation() const { return m_hasContinuation; }
+
+#if ENABLE(TEXT_AUTOSIZING)
+ void adjustComputedFontSizesOnBlocks(float size, float visibleWidth);
+ WEBCORE_EXPORT void resetTextAutosizing();
+#endif
+ RenderBlock* containingBlockForFixedPosition() const;
+ RenderBlock* containingBlockForAbsolutePosition() const;
+
+ RespectImageOrientationEnum shouldRespectImageOrientation() const;
+
+ void removeFromRenderFlowThread();
+
protected:
- enum BaseTypeFlags {
- RenderLayerModelObjectFlag = 1 << 0,
- RenderBoxModelObjectFlag = 1 << 1,
- RenderInlineFlag = 1 << 2,
- RenderReplacedFlag = 1 << 3,
- RenderBlockFlag = 1 << 4,
- RenderBlockFlowFlag = 1 << 5,
+ enum BaseTypeFlag {
+ RenderLayerModelObjectFlag = 1 << 0,
+ RenderBoxModelObjectFlag = 1 << 1,
+ RenderInlineFlag = 1 << 2,
+ RenderReplacedFlag = 1 << 3,
+ RenderBlockFlag = 1 << 4,
+ RenderBlockFlowFlag = 1 << 5,
};
+
+ typedef unsigned BaseTypeFlags;
- RenderElement(Element&, PassRef<RenderStyle>, unsigned baseTypeFlags);
- RenderElement(Document&, PassRef<RenderStyle>, unsigned baseTypeFlags);
+ RenderElement(Element&, RenderStyle&&, BaseTypeFlags);
+ RenderElement(Document&, RenderStyle&&, BaseTypeFlags);
bool layerCreationAllowedForSubtree() const;
enum StylePropagationType { PropagateToAllChildren, PropagateToBlockChildrenOnly };
void propagateStyleToAnonymousChildren(StylePropagationType);
- LayoutUnit valueForLength(const Length&, LayoutUnit maximumValue, bool roundPercentages = false) const;
- LayoutUnit minimumValueForLength(const Length&, LayoutUnit maximumValue, bool roundPercentages = false) const;
+ LayoutUnit valueForLength(const Length&, LayoutUnit maximumValue) const;
+ LayoutUnit minimumValueForLength(const Length&, LayoutUnit maximumValue) const;
void setFirstChild(RenderObject* child) { m_firstChild = child; }
void setLastChild(RenderObject* child) { m_lastChild = child; }
@@ -169,59 +250,108 @@ protected:
virtual void styleWillChange(StyleDifference, const RenderStyle& newStyle);
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
- virtual void insertedIntoTree() override;
- virtual void willBeRemovedFromTree() override;
- virtual void willBeDestroyed() override;
+ void insertedIntoTree() override;
+ void willBeRemovedFromTree() override;
+ void willBeDestroyed() override;
void setRenderInlineAlwaysCreatesLineBoxes(bool b) { m_renderInlineAlwaysCreatesLineBoxes = b; }
bool renderInlineAlwaysCreatesLineBoxes() const { return m_renderInlineAlwaysCreatesLineBoxes; }
+ void setHasContinuation(bool b) { m_hasContinuation = b; }
+
+ void setRenderBlockHasMarginBeforeQuirk(bool b) { m_renderBlockHasMarginBeforeQuirk = b; }
+ void setRenderBlockHasMarginAfterQuirk(bool b) { m_renderBlockHasMarginAfterQuirk = b; }
+ void setRenderBlockShouldForceRelayoutChildren(bool b) { m_renderBlockShouldForceRelayoutChildren = b; }
+ bool renderBlockHasMarginBeforeQuirk() const { return m_renderBlockHasMarginBeforeQuirk; }
+ bool renderBlockHasMarginAfterQuirk() const { return m_renderBlockHasMarginAfterQuirk; }
+ bool renderBlockShouldForceRelayoutChildren() const { return m_renderBlockShouldForceRelayoutChildren; }
+
+ void setRenderBlockFlowLineLayoutPath(unsigned u) { m_renderBlockFlowLineLayoutPath = u; }
+ void setRenderBlockFlowHasMarkupTruncation(bool b) { m_renderBlockFlowHasMarkupTruncation = b; }
+ unsigned renderBlockFlowLineLayoutPath() const { return m_renderBlockFlowLineLayoutPath; }
+ bool renderBlockFlowHasMarkupTruncation() const { return m_renderBlockFlowHasMarkupTruncation; }
+
+ void paintFocusRing(PaintInfo&, const RenderStyle&, const Vector<LayoutRect>& focusRingRects);
+ void paintOutline(PaintInfo&, const LayoutRect&);
+ void updateOutlineAutoAncestor(bool hasOutlineAuto);
+
+ void removeFromRenderFlowThreadIncludingDescendants(bool shouldUpdateState);
+ void adjustFlowThreadStateOnContainingBlockChangeIfNeeded();
+
+ bool noLongerAffectsParentBlock() const { return s_noLongerAffectsParentBlock; }
+
private:
+ RenderElement(ContainerNode&, RenderStyle&&, BaseTypeFlags);
void node() const = delete;
void nonPseudoNode() const = delete;
void generatingNode() const = delete;
void isText() const = delete;
void isRenderElement() const = delete;
- virtual RenderObject* firstChildSlow() const override final { return firstChild(); }
- virtual RenderObject* lastChildSlow() const override final { return lastChild(); }
+ RenderObject* firstChildSlow() const final { return firstChild(); }
+ RenderObject* lastChildSlow() const final { return lastChild(); }
+
+ // Called when an object that was floating or positioned becomes a normal flow object
+ // again. We have to make sure the render tree updates as needed to accommodate the new
+ // normal flow object.
+ void handleDynamicFloatPositionChange();
+ void removeAnonymousWrappersForInlinesIfNecessary();
bool shouldRepaintForStyleDifference(StyleDifference) const;
bool hasImmediateNonWhitespaceTextChildOrBorderOrOutline() const;
- void updateFillImages(const FillLayer*, const FillLayer*);
+ void updateFillImages(const FillLayer*, const FillLayer&);
void updateImage(StyleImage*, StyleImage*);
-#if ENABLE(CSS_SHAPES)
void updateShapeImage(const ShapeValue*, const ShapeValue*);
-#endif
StyleDifference adjustStyleDifference(StyleDifference, unsigned contextSensitiveProperties) const;
- RenderStyle* cachedFirstLineStyle() const;
+ std::unique_ptr<RenderStyle> computeFirstLineStyle() const;
+ void invalidateCachedFirstLineStyle();
- unsigned m_baseTypeFlags : 6;
- bool m_ancestorLineBoxDirty : 1;
- bool m_hasInitializedStyle : 1;
+ void newImageAnimationFrameAvailable(CachedImage&) final;
+
+ bool getLeadingCorner(FloatPoint& output, bool& insideFixed) const;
+ bool getTrailingCorner(FloatPoint& output, bool& insideFixed) const;
- // Specific to RenderInline.
- bool m_renderInlineAlwaysCreatesLineBoxes : 1;
+ void clearLayoutRootIfNeeded() const;
+
+ bool shouldWillChangeCreateStackingContext() const;
+ void issueRepaintForOutlineAuto(float outlineSize);
+
+ unsigned m_baseTypeFlags : 6;
+ unsigned m_ancestorLineBoxDirty : 1;
+ unsigned m_hasInitializedStyle : 1;
+ unsigned m_hasInitialAnimatedStyle : 1;
+
+ unsigned m_renderInlineAlwaysCreatesLineBoxes : 1;
+ unsigned m_renderBoxNeedsLazyRepaint : 1;
+ unsigned m_hasPausedImageAnimations : 1;
+ unsigned m_hasCounterNodeMap : 1;
+ unsigned m_isCSSAnimating : 1;
+ unsigned m_hasContinuation : 1;
+ mutable unsigned m_hasValidCachedFirstLineStyle : 1;
+
+ unsigned m_renderBlockHasMarginBeforeQuirk : 1;
+ unsigned m_renderBlockHasMarginAfterQuirk : 1;
+ unsigned m_renderBlockShouldForceRelayoutChildren : 1;
+ unsigned m_renderBlockFlowHasMarkupTruncation : 1;
+ unsigned m_renderBlockFlowLineLayoutPath : 2;
RenderObject* m_firstChild;
RenderObject* m_lastChild;
- Ref<RenderStyle> m_style;
+ RenderStyle m_style;
// FIXME: Get rid of this hack.
// Store state between styleWillChange and styleDidChange
static bool s_affectsParentBlock;
static bool s_noLongerAffectsParentBlock;
-};
-
-template <> inline bool isRendererOfType<const RenderElement>(const RenderObject& renderer) { return renderer.isRenderElement(); }
-inline RenderStyle& RenderElement::firstLineStyle() const
-{
- return document().styleSheetCollection().usesFirstLineRules() ? *cachedFirstLineStyle() : style();
-}
+protected:
+#if !ASSERT_DISABLED
+ bool m_reparentingChild { false };
+#endif
+};
inline void RenderElement::setAncestorLineBoxDirty(bool f)
{
@@ -240,14 +370,14 @@ inline void RenderElement::setChildNeedsLayout(MarkingBehavior markParents)
markContainingBlocksForLayout();
}
-inline LayoutUnit RenderElement::valueForLength(const Length& length, LayoutUnit maximumValue, bool roundPercentages) const
+inline LayoutUnit RenderElement::valueForLength(const Length& length, LayoutUnit maximumValue) const
{
- return WebCore::valueForLength(length, maximumValue, &view(), roundPercentages);
+ return WebCore::valueForLength(length, maximumValue);
}
-inline LayoutUnit RenderElement::minimumValueForLength(const Length& length, LayoutUnit maximumValue, bool roundPercentages) const
+inline LayoutUnit RenderElement::minimumValueForLength(const Length& length, LayoutUnit maximumValue) const
{
- return WebCore::minimumValueForLength(length, maximumValue, &view(), roundPercentages);
+ return WebCore::minimumValueForLength(length, maximumValue);
}
inline bool RenderElement::isRenderLayerModelObject() const
@@ -280,62 +410,81 @@ inline bool RenderElement::isRenderInline() const
return m_baseTypeFlags & RenderInlineFlag;
}
-RENDER_OBJECT_TYPE_CASTS(RenderElement, isRenderElement())
-
inline Element* RenderElement::generatingElement() const
{
if (parent() && isRenderNamedFlowFragment())
return parent()->generatingElement();
- return toElement(RenderObject::generatingNode());
+ return downcast<Element>(RenderObject::generatingNode());
+}
+
+inline bool RenderElement::canContainFixedPositionObjects() const
+{
+ return isRenderView()
+ || (hasTransform() && isRenderBlock())
+ || isSVGForeignObject()
+ || isOutOfFlowRenderFlowThread();
+}
+
+inline bool RenderElement::canContainAbsolutelyPositionedObjects() const
+{
+ return style().position() != StaticPosition
+ || (isRenderBlock() && hasTransformRelatedProperty())
+ || isSVGForeignObject()
+ || isRenderView();
+}
+
+inline bool RenderElement::createsGroupForStyle(const RenderStyle& style)
+{
+ return style.opacity() < 1.0f || style.hasMask() || style.clipPath() || style.hasFilter() || style.hasBackdropFilter() || style.hasBlendMode();
}
inline bool RenderObject::isRenderLayerModelObject() const
{
- return isRenderElement() && toRenderElement(this)->isRenderLayerModelObject();
+ return is<RenderElement>(*this) && downcast<RenderElement>(*this).isRenderLayerModelObject();
}
inline bool RenderObject::isBoxModelObject() const
{
- return isRenderElement() && toRenderElement(this)->isBoxModelObject();
+ return is<RenderElement>(*this) && downcast<RenderElement>(*this).isBoxModelObject();
}
inline bool RenderObject::isRenderBlock() const
{
- return isRenderElement() && toRenderElement(this)->isRenderBlock();
+ return is<RenderElement>(*this) && downcast<RenderElement>(*this).isRenderBlock();
}
inline bool RenderObject::isRenderBlockFlow() const
{
- return isRenderElement() && toRenderElement(this)->isRenderBlockFlow();
+ return is<RenderElement>(*this) && downcast<RenderElement>(*this).isRenderBlockFlow();
}
inline bool RenderObject::isRenderReplaced() const
{
- return isRenderElement() && toRenderElement(this)->isRenderReplaced();
+ return is<RenderElement>(*this) && downcast<RenderElement>(*this).isRenderReplaced();
}
inline bool RenderObject::isRenderInline() const
{
- return isRenderElement() && toRenderElement(this)->isRenderInline();
+ return is<RenderElement>(*this) && downcast<RenderElement>(*this).isRenderInline();
}
-inline RenderStyle& RenderObject::style() const
+inline const RenderStyle& RenderObject::style() const
{
if (isText())
return m_parent->style();
- return toRenderElement(this)->style();
+ return downcast<RenderElement>(*this).style();
}
-inline RenderStyle& RenderObject::firstLineStyle() const
+inline const RenderStyle& RenderObject::firstLineStyle() const
{
if (isText())
return m_parent->firstLineStyle();
- return toRenderElement(this)->firstLineStyle();
+ return downcast<RenderElement>(*this).firstLineStyle();
}
inline RenderElement* ContainerNode::renderer() const
{
- return toRenderElement(Node::renderer());
+ return downcast<RenderElement>(Node::renderer());
}
inline int adjustForAbsoluteZoom(int value, const RenderElement& renderer)
@@ -343,13 +492,11 @@ inline int adjustForAbsoluteZoom(int value, const RenderElement& renderer)
return adjustForAbsoluteZoom(value, renderer.style());
}
-#if ENABLE(SUBPIXEL_LAYOUT)
inline LayoutUnit adjustLayoutUnitForAbsoluteZoom(LayoutUnit value, const RenderElement& renderer)
{
return adjustLayoutUnitForAbsoluteZoom(value, renderer.style());
}
-#endif
} // namespace WebCore
-#endif // RenderElement_h
+SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderElement, isRenderElement())