Move continuation teardown from subclasses to RenderBoxModelObject.
[WebKit-https.git] / Source / WebCore / rendering / RenderElement.h
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  * Copyright (C) 2003, 2006, 2007, 2009, 2013 Apple Inc. All rights reserved.
5  * Copyright (C) 2010, 2012 Google Inc. All rights reserved.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 #ifndef RenderElement_h
24 #define RenderElement_h
25
26 #include "AnimationController.h"
27 #include "RenderObject.h"
28
29 namespace WebCore {
30
31 class ControlStates;
32
33 class RenderElement : public RenderObject {
34 public:
35     virtual ~RenderElement();
36
37     static RenderPtr<RenderElement> createFor(Element&, PassRef<RenderStyle>);
38
39     bool hasInitializedStyle() const { return m_hasInitializedStyle; }
40
41     RenderStyle& style() const { return const_cast<RenderStyle&>(m_style.get()); }
42     RenderStyle& firstLineStyle() const;
43
44     void initializeStyle();
45
46     void setStyle(PassRef<RenderStyle>);
47     // Called to update a style that is allowed to trigger animations.
48     void setAnimatableStyle(PassRef<RenderStyle>);
49
50     // This is null for anonymous renderers.
51     Element* element() const { return downcast<Element>(RenderObject::node()); }
52     Element* nonPseudoElement() const { return downcast<Element>(RenderObject::nonPseudoNode()); }
53     Element* generatingElement() const;
54
55     RenderObject* firstChild() const { return m_firstChild; }
56     RenderObject* lastChild() const { return m_lastChild; }
57
58     virtual bool isEmpty() const override { return !firstChild(); }
59
60     // FIXME: Make these standalone and move to relevant files.
61     bool isRenderLayerModelObject() const;
62     bool isBoxModelObject() const;
63     bool isRenderBlock() const;
64     bool isRenderBlockFlow() const;
65     bool isRenderReplaced() const;
66     bool isRenderInline() const;
67     bool isRenderNamedFlowFragmentContainer() const;
68
69     virtual bool isChildAllowed(const RenderObject&, const RenderStyle&) const { return true; }
70     virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0);
71     virtual void addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild = 0) { return addChild(newChild, beforeChild); }
72     virtual RenderObject* removeChild(RenderObject&);
73
74     // The following functions are used when the render tree hierarchy changes to make sure layers get
75     // properly added and removed. Since containership can be implemented by any subclass, and since a hierarchy
76     // can contain a mixture of boxes and other object types, these functions need to be in the base class.
77     void addLayers(RenderLayer* parentLayer);
78     void removeLayers(RenderLayer* parentLayer);
79     void moveLayers(RenderLayer* oldParent, RenderLayer* newParent);
80     RenderLayer* findNextLayer(RenderLayer* parentLayer, RenderObject* startPoint, bool checkParent = true);
81
82     enum NotifyChildrenType { NotifyChildren, DontNotifyChildren };
83     void insertChildInternal(RenderObject*, RenderObject* beforeChild, NotifyChildrenType);
84     RenderObject* removeChildInternal(RenderObject&, NotifyChildrenType);
85
86     virtual RenderElement* hoverAncestor() const;
87
88     virtual void dirtyLinesFromChangedChild(RenderObject&) { }
89
90     bool ancestorLineBoxDirty() const { return m_ancestorLineBoxDirty; }
91     void setAncestorLineBoxDirty(bool f = true);
92
93     void setChildNeedsLayout(MarkingBehavior = MarkContainingBlockChain);
94     void clearChildNeedsLayout();
95     void setNeedsPositionedMovementLayout(const RenderStyle* oldStyle);
96     void setNeedsSimplifiedNormalFlowLayout();
97
98     virtual void paint(PaintInfo&, const LayoutPoint&) = 0;
99
100     // Recursive function that computes the size and position of this object and all its descendants.
101     virtual void layout();
102
103     /* This function performs a layout only if one is needed. */
104     void layoutIfNeeded() { if (needsLayout()) layout(); }
105
106     // 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.
107     RenderElement& rendererForRootBackground();
108
109     // Used only by Element::pseudoStyleCacheIsInvalid to get a first line style based off of a
110     // given new style, without accessing the cache.
111     PassRefPtr<RenderStyle> uncachedFirstLineStyle(RenderStyle*) const;
112
113     // Updates only the local style ptr of the object. Does not update the state of the object,
114     // and so only should be called when the style is known not to have changed (or from setStyle).
115     void setStyleInternal(PassRef<RenderStyle> style) { m_style = WTF::move(style); }
116
117     // Repaint only if our old bounds and new bounds are different. The caller may pass in newBounds and newOutlineBox if they are known.
118     bool repaintAfterLayoutIfNeeded(const RenderLayerModelObject* repaintContainer, const LayoutRect& oldBounds, const LayoutRect& oldOutlineBox, const LayoutRect* newBoundsPtr = nullptr, const LayoutRect* newOutlineBoxPtr = nullptr);
119
120     bool borderImageIsLoadedAndCanBeRendered() const;
121
122     // Returns true if this renderer requires a new stacking context.
123     bool createsGroup() const { return isTransparent() || hasMask() || hasFilter() || hasBlendMode(); }
124
125     bool isTransparent() const { return style().opacity() < 1.0f; }
126     float opacity() const { return style().opacity(); }
127
128     bool visibleToHitTesting() const { return style().visibility() == VISIBLE && style().pointerEvents() != PE_NONE; }
129
130     bool hasBackground() const { return style().hasBackground(); }
131     bool hasMask() const { return style().hasMask(); }
132     bool hasClip() const { return isOutOfFlowPositioned() && style().hasClip(); }
133     bool hasClipOrOverflowClip() const { return hasClip() || hasOverflowClip(); }
134     bool hasClipPath() const { return style().clipPath(); }
135     bool hasHiddenBackface() const { return style().backfaceVisibility() == BackfaceVisibilityHidden; }
136
137     bool hasFilter() const { return style().hasFilter(); }
138
139 #if ENABLE(CSS_COMPOSITING)
140     bool hasBlendMode() const { return style().hasBlendMode(); }
141 #else
142     bool hasBlendMode() const { return false; }
143 #endif
144
145 #if ENABLE(CSS_SHAPES)
146     bool hasShapeOutside() const { return style().shapeOutside(); }
147 #else
148     bool hasShapeOutside() const { return false; }
149 #endif
150
151     bool repaintForPausedImageAnimationsIfNeeded(const IntRect& visibleRect);
152     bool hasPausedImageAnimations() const { return m_hasPausedImageAnimations; }
153     void setHasPausedImageAnimations(bool b) { m_hasPausedImageAnimations = b; }
154
155     RenderNamedFlowThread* renderNamedFlowThreadWrapper();
156
157     void setRenderBoxNeedsLazyRepaint(bool b) { m_renderBoxNeedsLazyRepaint = b; }
158     bool renderBoxNeedsLazyRepaint() const { return m_renderBoxNeedsLazyRepaint; }
159
160     bool hasCounterNodeMap() const { return m_hasCounterNodeMap; }
161     void setHasCounterNodeMap(bool f) { m_hasCounterNodeMap = f; }
162
163     bool isCSSAnimating() const { return m_isCSSAnimating; }
164     void setIsCSSAnimating(bool b) { m_isCSSAnimating = b; }
165
166 protected:
167     enum BaseTypeFlags {
168         RenderLayerModelObjectFlag = 1 << 0,
169         RenderBoxModelObjectFlag = 1 << 1,
170         RenderInlineFlag = 1 << 2,
171         RenderReplacedFlag = 1 << 3,
172         RenderBlockFlag = 1 << 4,
173         RenderBlockFlowFlag = 1 << 5,
174     };
175
176     RenderElement(Element&, PassRef<RenderStyle>, unsigned baseTypeFlags);
177     RenderElement(Document&, PassRef<RenderStyle>, unsigned baseTypeFlags);
178
179     bool layerCreationAllowedForSubtree() const;
180
181     enum StylePropagationType { PropagateToAllChildren, PropagateToBlockChildrenOnly };
182     void propagateStyleToAnonymousChildren(StylePropagationType);
183
184     LayoutUnit valueForLength(const Length&, LayoutUnit maximumValue) const;
185     LayoutUnit minimumValueForLength(const Length&, LayoutUnit maximumValue, bool roundPercentages = false) const;
186
187     void setFirstChild(RenderObject* child) { m_firstChild = child; }
188     void setLastChild(RenderObject* child) { m_lastChild = child; }
189     void destroyLeftoverChildren();
190
191     virtual void styleWillChange(StyleDifference, const RenderStyle& newStyle);
192     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
193
194     virtual void insertedIntoTree() override;
195     virtual void willBeRemovedFromTree() override;
196     virtual void willBeDestroyed() override;
197
198     void setRenderInlineAlwaysCreatesLineBoxes(bool b) { m_renderInlineAlwaysCreatesLineBoxes = b; }
199     bool renderInlineAlwaysCreatesLineBoxes() const { return m_renderInlineAlwaysCreatesLineBoxes; }
200
201     void setHasContinuation(bool b) { m_hasContinuation = b; }
202     bool hasContinuation() const { return m_hasContinuation; }
203
204     static bool hasControlStatesForRenderer(const RenderObject*);
205     static ControlStates* controlStatesForRenderer(const RenderObject*);
206     static void removeControlStatesForRenderer(const RenderObject*);
207     static void addControlStatesForRenderer(const RenderObject*, ControlStates*);
208
209 private:
210     RenderElement(ContainerNode&, PassRef<RenderStyle>, unsigned baseTypeFlags);
211     void node() const = delete;
212     void nonPseudoNode() const = delete;
213     void generatingNode() const = delete;
214     void isText() const = delete;
215     void isRenderElement() const = delete;
216
217     virtual RenderObject* firstChildSlow() const override final { return firstChild(); }
218     virtual RenderObject* lastChildSlow() const override final { return lastChild(); }
219
220     bool shouldRepaintForStyleDifference(StyleDifference) const;
221     bool hasImmediateNonWhitespaceTextChildOrBorderOrOutline() const;
222
223     void updateFillImages(const FillLayer*, const FillLayer*);
224     void updateImage(StyleImage*, StyleImage*);
225 #if ENABLE(CSS_SHAPES)
226     void updateShapeImage(const ShapeValue*, const ShapeValue*);
227 #endif
228
229     StyleDifference adjustStyleDifference(StyleDifference, unsigned contextSensitiveProperties) const;
230     RenderStyle* cachedFirstLineStyle() const;
231
232     virtual void newImageAnimationFrameAvailable(CachedImage&) final override;
233
234     unsigned m_baseTypeFlags : 6;
235     unsigned m_ancestorLineBoxDirty : 1;
236     unsigned m_hasInitializedStyle : 1;
237
238     unsigned m_renderInlineAlwaysCreatesLineBoxes : 1;
239     unsigned m_renderBoxNeedsLazyRepaint : 1;
240     unsigned m_hasPausedImageAnimations : 1;
241     unsigned m_hasCounterNodeMap : 1;
242     unsigned m_isCSSAnimating : 1;
243     unsigned m_hasContinuation : 1;
244
245     RenderObject* m_firstChild;
246     RenderObject* m_lastChild;
247
248     Ref<RenderStyle> m_style;
249
250     // FIXME: Get rid of this hack.
251     // Store state between styleWillChange and styleDidChange
252     static bool s_affectsParentBlock;
253     static bool s_noLongerAffectsParentBlock;
254 };
255
256 inline void RenderElement::setAnimatableStyle(PassRef<RenderStyle> style)
257 {
258     setStyle(animation().updateAnimations(*this, WTF::move(style)));
259 }
260
261 inline RenderStyle& RenderElement::firstLineStyle() const
262 {
263     return document().styleSheetCollection().usesFirstLineRules() ? *cachedFirstLineStyle() : style();
264 }
265
266 inline void RenderElement::setAncestorLineBoxDirty(bool f)
267 {
268     m_ancestorLineBoxDirty = f;
269     if (m_ancestorLineBoxDirty)
270         setNeedsLayout();
271 }
272
273 inline void RenderElement::setChildNeedsLayout(MarkingBehavior markParents)
274 {
275     ASSERT(!isSetNeedsLayoutForbidden());
276     if (normalChildNeedsLayout())
277         return;
278     setNormalChildNeedsLayoutBit(true);
279     if (markParents == MarkContainingBlockChain)
280         markContainingBlocksForLayout();
281 }
282
283 inline LayoutUnit RenderElement::valueForLength(const Length& length, LayoutUnit maximumValue) const
284 {
285     return WebCore::valueForLength(length, maximumValue);
286 }
287
288 inline LayoutUnit RenderElement::minimumValueForLength(const Length& length, LayoutUnit maximumValue, bool roundPercentages) const
289 {
290     return WebCore::minimumValueForLength(length, maximumValue, roundPercentages);
291 }
292
293 inline bool RenderElement::isRenderLayerModelObject() const
294 {
295     return m_baseTypeFlags & RenderLayerModelObjectFlag;
296 }
297
298 inline bool RenderElement::isBoxModelObject() const
299 {
300     return m_baseTypeFlags & RenderBoxModelObjectFlag;
301 }
302
303 inline bool RenderElement::isRenderBlock() const
304 {
305     return m_baseTypeFlags & RenderBlockFlag;
306 }
307
308 inline bool RenderElement::isRenderBlockFlow() const
309 {
310     return m_baseTypeFlags & RenderBlockFlowFlag;
311 }
312
313 inline bool RenderElement::isRenderReplaced() const
314 {
315     return m_baseTypeFlags & RenderReplacedFlag;
316 }
317
318 inline bool RenderElement::isRenderInline() const
319 {
320     return m_baseTypeFlags & RenderInlineFlag;
321 }
322
323 inline Element* RenderElement::generatingElement() const
324 {
325     if (parent() && isRenderNamedFlowFragment())
326         return parent()->generatingElement();
327     return downcast<Element>(RenderObject::generatingNode());
328 }
329
330 inline bool RenderObject::isRenderLayerModelObject() const
331 {
332     return is<RenderElement>(*this) && downcast<RenderElement>(*this).isRenderLayerModelObject();
333 }
334
335 inline bool RenderObject::isBoxModelObject() const
336 {
337     return is<RenderElement>(*this) && downcast<RenderElement>(*this).isBoxModelObject();
338 }
339
340 inline bool RenderObject::isRenderBlock() const
341 {
342     return is<RenderElement>(*this) && downcast<RenderElement>(*this).isRenderBlock();
343 }
344
345 inline bool RenderObject::isRenderBlockFlow() const
346 {
347     return is<RenderElement>(*this) && downcast<RenderElement>(*this).isRenderBlockFlow();
348 }
349
350 inline bool RenderObject::isRenderReplaced() const
351 {
352     return is<RenderElement>(*this) && downcast<RenderElement>(*this).isRenderReplaced();
353 }
354
355 inline bool RenderObject::isRenderInline() const
356 {
357     return is<RenderElement>(*this) && downcast<RenderElement>(*this).isRenderInline();
358 }
359
360 inline RenderStyle& RenderObject::style() const
361 {
362     if (isText())
363         return m_parent->style();
364     return downcast<RenderElement>(*this).style();
365 }
366
367 inline RenderStyle& RenderObject::firstLineStyle() const
368 {
369     if (isText())
370         return m_parent->firstLineStyle();
371     return downcast<RenderElement>(*this).firstLineStyle();
372 }
373
374 inline RenderElement* ContainerNode::renderer() const
375 {
376     return downcast<RenderElement>(Node::renderer());
377 }
378
379 inline int adjustForAbsoluteZoom(int value, const RenderElement& renderer)
380 {
381     return adjustForAbsoluteZoom(value, renderer.style());
382 }
383
384 inline LayoutUnit adjustLayoutUnitForAbsoluteZoom(LayoutUnit value, const RenderElement& renderer)
385 {
386     return adjustLayoutUnitForAbsoluteZoom(value, renderer.style());
387 }
388
389 } // namespace WebCore
390
391 SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderElement, isRenderElement())
392
393 #endif // RenderElement_h