diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/rendering/RenderElement.h | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/rendering/RenderElement.h')
-rw-r--r-- | Source/WebCore/rendering/RenderElement.h | 303 |
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()) |