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 | #pragma once |
24 | |
25 | #include "LengthFunctions.h" |
26 | #include "RenderObject.h" |
27 | |
28 | namespace WebCore { |
29 | |
30 | class ControlStates; |
31 | class KeyframeList; |
32 | class RenderBlock; |
33 | class RenderTreeBuilder; |
34 | |
35 | class RenderElement : public RenderObject { |
36 | WTF_MAKE_ISO_ALLOCATED(RenderElement); |
37 | public: |
38 | virtual ~RenderElement(); |
39 | |
40 | enum RendererCreationType { CreateAllRenderers, OnlyCreateBlockAndFlexboxRenderers }; |
41 | static RenderPtr<RenderElement> createFor(Element&, RenderStyle&&, RendererCreationType = CreateAllRenderers); |
42 | |
43 | bool hasInitializedStyle() const { return m_hasInitializedStyle; } |
44 | |
45 | const RenderStyle& style() const { return m_style; } |
46 | const RenderStyle& firstLineStyle() const; |
47 | |
48 | // FIXME: Style shouldn't be mutated. |
49 | RenderStyle& mutableStyle() { return m_style; } |
50 | |
51 | void initializeStyle(); |
52 | |
53 | // Calling with minimalStyleDifference > StyleDifference::Equal indicates that |
54 | // out-of-band state (e.g. animations) requires that styleDidChange processing |
55 | // continue even if the style isn't different from the current style. |
56 | void setStyle(RenderStyle&&, StyleDifference minimalStyleDifference = StyleDifference::Equal); |
57 | |
58 | // The pseudo element style can be cached or uncached. Use the cached method if the pseudo element doesn't respect |
59 | // any pseudo classes (and therefore has no concept of changing state). |
60 | const RenderStyle* getCachedPseudoStyle(PseudoId, const RenderStyle* parentStyle = nullptr) const; |
61 | std::unique_ptr<RenderStyle> getUncachedPseudoStyle(const PseudoStyleRequest&, const RenderStyle* parentStyle = nullptr, const RenderStyle* ownStyle = nullptr) const; |
62 | |
63 | // This is null for anonymous renderers. |
64 | Element* element() const { return downcast<Element>(RenderObject::node()); } |
65 | Element* nonPseudoElement() const { return downcast<Element>(RenderObject::nonPseudoNode()); } |
66 | Element* generatingElement() const; |
67 | |
68 | RenderObject* firstChild() const { return m_firstChild; } |
69 | RenderObject* lastChild() const { return m_lastChild; } |
70 | |
71 | bool canContainFixedPositionObjects() const; |
72 | bool canContainAbsolutelyPositionedObjects() const; |
73 | |
74 | Color selectionColor(CSSPropertyID) const; |
75 | std::unique_ptr<RenderStyle> selectionPseudoStyle() const; |
76 | |
77 | // Obtains the selection colors that should be used when painting a selection. |
78 | Color selectionBackgroundColor() const; |
79 | Color selectionForegroundColor() const; |
80 | Color selectionEmphasisMarkColor() const; |
81 | |
82 | // FIXME: Make these standalone and move to relevant files. |
83 | bool isRenderLayerModelObject() const; |
84 | bool isBoxModelObject() const; |
85 | bool isRenderBlock() const; |
86 | bool isRenderBlockFlow() const; |
87 | bool isRenderReplaced() const; |
88 | bool isRenderInline() const; |
89 | |
90 | virtual bool isChildAllowed(const RenderObject&, const RenderStyle&) const { return true; } |
91 | void didAttachChild(RenderObject& child, RenderObject* beforeChild); |
92 | |
93 | // The following functions are used when the render tree hierarchy changes to make sure layers get |
94 | // properly added and removed. Since containership can be implemented by any subclass, and since a hierarchy |
95 | // can contain a mixture of boxes and other object types, these functions need to be in the base class. |
96 | void addLayers(RenderLayer* parentLayer); |
97 | void removeLayers(RenderLayer* parentLayer); |
98 | void moveLayers(RenderLayer* oldParent, RenderLayer* newParent); |
99 | RenderLayer* findNextLayer(RenderLayer* parentLayer, RenderObject* startPoint, bool checkParent = true); |
100 | |
101 | virtual void dirtyLinesFromChangedChild(RenderObject&) { } |
102 | |
103 | bool ancestorLineBoxDirty() const { return m_ancestorLineBoxDirty; } |
104 | void setAncestorLineBoxDirty(bool f = true); |
105 | |
106 | void setChildNeedsLayout(MarkingBehavior = MarkContainingBlockChain); |
107 | void clearChildNeedsLayout(); |
108 | void setNeedsPositionedMovementLayout(const RenderStyle* oldStyle); |
109 | void setNeedsSimplifiedNormalFlowLayout(); |
110 | |
111 | virtual void paint(PaintInfo&, const LayoutPoint&) = 0; |
112 | |
113 | // inline-block elements paint all phases atomically. This function ensures that. Certain other elements |
114 | // (grid items, flex items) require this behavior as well, and this function exists as a helper for them. |
115 | // It is expected that the caller will call this function independent of the value of paintInfo.phase. |
116 | void paintAsInlineBlock(PaintInfo&, const LayoutPoint&); |
117 | |
118 | // Recursive function that computes the size and position of this object and all its descendants. |
119 | virtual void layout(); |
120 | |
121 | /* This function performs a layout only if one is needed. */ |
122 | void layoutIfNeeded() { if (needsLayout()) layout(); } |
123 | |
124 | // Updates only the local style ptr of the object. Does not update the state of the object, |
125 | // and so only should be called when the style is known not to have changed (or from setStyle). |
126 | void setStyleInternal(RenderStyle&& style) { m_style = WTFMove(style); } |
127 | |
128 | // Repaint only if our old bounds and new bounds are different. The caller may pass in newBounds and newOutlineBox if they are known. |
129 | bool repaintAfterLayoutIfNeeded(const RenderLayerModelObject* repaintContainer, const LayoutRect& oldBounds, const LayoutRect& oldOutlineBox, const LayoutRect* newBoundsPtr = nullptr, const LayoutRect* newOutlineBoxPtr = nullptr); |
130 | |
131 | bool borderImageIsLoadedAndCanBeRendered() const; |
132 | bool mayCauseRepaintInsideViewport(const IntRect* visibleRect = nullptr) const; |
133 | bool isVisibleInDocumentRect(const IntRect& documentRect) const; |
134 | |
135 | // Returns true if this renderer requires a new stacking context. |
136 | static bool createsGroupForStyle(const RenderStyle&); |
137 | bool createsGroup() const { return createsGroupForStyle(style()); } |
138 | |
139 | bool isTransparent() const { return style().opacity() < 1.0f; } |
140 | float opacity() const { return style().opacity(); } |
141 | |
142 | bool visibleToHitTesting() const { return style().visibility() == Visibility::Visible && style().pointerEvents() != PointerEvents::None; } |
143 | |
144 | bool hasBackground() const { return style().hasBackground(); } |
145 | bool hasMask() const { return style().hasMask(); } |
146 | bool hasClip() const { return isOutOfFlowPositioned() && style().hasClip(); } |
147 | bool hasClipOrOverflowClip() const { return hasClip() || hasOverflowClip(); } |
148 | bool hasClipPath() const { return style().clipPath(); } |
149 | bool hasHiddenBackface() const { return style().backfaceVisibility() == BackfaceVisibility::Hidden; } |
150 | bool hasOutlineAnnotation() const; |
151 | bool hasOutline() const { return style().hasOutline() || hasOutlineAnnotation(); } |
152 | bool hasSelfPaintingLayer() const; |
153 | |
154 | bool checkForRepaintDuringLayout() const; |
155 | |
156 | // anchorRect() is conceptually similar to absoluteBoundingBoxRect(), but is intended for scrolling to an anchor. |
157 | // For inline renderers, this gets the logical top left of the first leaf child and the logical bottom right of the |
158 | // last leaf child, converts them to absolute coordinates, and makes a box out of them. |
159 | LayoutRect absoluteAnchorRect(bool* insideFixed = nullptr) const; |
160 | |
161 | bool hasFilter() const { return style().hasFilter(); } |
162 | bool hasBackdropFilter() const |
163 | { |
164 | #if ENABLE(FILTERS_LEVEL_2) |
165 | return style().hasBackdropFilter(); |
166 | #else |
167 | return false; |
168 | #endif |
169 | } |
170 | |
171 | |
172 | #if ENABLE(CSS_COMPOSITING) |
173 | bool hasBlendMode() const { return style().hasBlendMode(); } |
174 | #else |
175 | bool hasBlendMode() const { return false; } |
176 | #endif |
177 | |
178 | bool hasShapeOutside() const { return style().shapeOutside(); } |
179 | |
180 | void registerForVisibleInViewportCallback(); |
181 | void unregisterForVisibleInViewportCallback(); |
182 | |
183 | VisibleInViewportState visibleInViewportState() const { return static_cast<VisibleInViewportState>(m_visibleInViewportState); } |
184 | void setVisibleInViewportState(VisibleInViewportState); |
185 | virtual void visibleInViewportStateChanged(); |
186 | |
187 | bool repaintForPausedImageAnimationsIfNeeded(const IntRect& visibleRect, CachedImage&); |
188 | bool hasPausedImageAnimations() const { return m_hasPausedImageAnimations; } |
189 | void setHasPausedImageAnimations(bool b) { m_hasPausedImageAnimations = b; } |
190 | |
191 | void setRenderBoxNeedsLazyRepaint(bool b) { m_renderBoxNeedsLazyRepaint = b; } |
192 | bool renderBoxNeedsLazyRepaint() const { return m_renderBoxNeedsLazyRepaint; } |
193 | |
194 | bool hasCounterNodeMap() const { return m_hasCounterNodeMap; } |
195 | void setHasCounterNodeMap(bool f) { m_hasCounterNodeMap = f; } |
196 | |
197 | const RenderElement* enclosingRendererWithTextDecoration(OptionSet<TextDecoration>, bool firstLine) const; |
198 | void drawLineForBoxSide(GraphicsContext&, const FloatRect&, BoxSide, Color, BorderStyle, float adjacentWidth1, float adjacentWidth2, bool antialias = false) const; |
199 | |
200 | #if ENABLE(TEXT_AUTOSIZING) |
201 | void adjustComputedFontSizesOnBlocks(float size, float visibleWidth); |
202 | WEBCORE_EXPORT void resetTextAutosizing(); |
203 | #endif |
204 | RenderBlock* containingBlockForFixedPosition() const; |
205 | RenderBlock* containingBlockForAbsolutePosition() const; |
206 | |
207 | RespectImageOrientationEnum shouldRespectImageOrientation() const; |
208 | |
209 | void removeFromRenderFragmentedFlow(); |
210 | virtual void resetEnclosingFragmentedFlowAndChildInfoIncludingDescendants(RenderFragmentedFlow*); |
211 | |
212 | // Called before anonymousChild.setStyle(). Override to set custom styles for |
213 | // the child. |
214 | virtual void updateAnonymousChildStyle(RenderStyle&) const { }; |
215 | |
216 | bool hasContinuationChainNode() const { return m_hasContinuationChainNode; } |
217 | bool isContinuation() const { return m_isContinuation; } |
218 | void setIsContinuation() { m_isContinuation = true; } |
219 | bool isFirstLetter() const { return m_isFirstLetter; } |
220 | void setIsFirstLetter() { m_isFirstLetter = true; } |
221 | |
222 | RenderObject* attachRendererInternal(RenderPtr<RenderObject> child, RenderObject* beforeChild); |
223 | RenderPtr<RenderObject> detachRendererInternal(RenderObject&); |
224 | |
225 | virtual bool startTransition(double /* timeOffset */, CSSPropertyID, const RenderStyle* /* fromStyle */, const RenderStyle* /* toStyle */) { return false; } |
226 | virtual void transitionPaused(double /* timeOffset */, CSSPropertyID) { } |
227 | virtual void transitionFinished(CSSPropertyID) { } |
228 | |
229 | virtual bool startAnimation(double /* timeOffset */, const Animation&, const KeyframeList&) { return false; } |
230 | virtual void animationPaused(double /* timeOffset */, const String& /* name */) { } |
231 | virtual void animationSeeked(double /* timeOffset */, const String& /* name */) { } |
232 | virtual void animationFinished(const String& /* name */) { } |
233 | |
234 | virtual void suspendAnimations(MonotonicTime = MonotonicTime()) { } |
235 | |
236 | protected: |
237 | enum BaseTypeFlag { |
238 | RenderLayerModelObjectFlag = 1 << 0, |
239 | RenderBoxModelObjectFlag = 1 << 1, |
240 | RenderInlineFlag = 1 << 2, |
241 | RenderReplacedFlag = 1 << 3, |
242 | RenderBlockFlag = 1 << 4, |
243 | RenderBlockFlowFlag = 1 << 5, |
244 | }; |
245 | |
246 | typedef unsigned BaseTypeFlags; |
247 | |
248 | RenderElement(Element&, RenderStyle&&, BaseTypeFlags); |
249 | RenderElement(Document&, RenderStyle&&, BaseTypeFlags); |
250 | |
251 | bool layerCreationAllowedForSubtree() const; |
252 | |
253 | enum StylePropagationType { PropagateToAllChildren, PropagateToBlockChildrenOnly }; |
254 | void propagateStyleToAnonymousChildren(StylePropagationType); |
255 | |
256 | LayoutUnit valueForLength(const Length&, LayoutUnit maximumValue) const; |
257 | LayoutUnit minimumValueForLength(const Length&, LayoutUnit maximumValue) const; |
258 | |
259 | void setFirstChild(RenderObject* child) { m_firstChild = child; } |
260 | void setLastChild(RenderObject* child) { m_lastChild = child; } |
261 | |
262 | virtual void styleWillChange(StyleDifference, const RenderStyle& newStyle); |
263 | virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); |
264 | |
265 | void insertedIntoTree() override; |
266 | void willBeRemovedFromTree() override; |
267 | void willBeDestroyed() override; |
268 | |
269 | void setRenderInlineAlwaysCreatesLineBoxes(bool b) { m_renderInlineAlwaysCreatesLineBoxes = b; } |
270 | bool renderInlineAlwaysCreatesLineBoxes() const { return m_renderInlineAlwaysCreatesLineBoxes; } |
271 | |
272 | void setHasContinuationChainNode(bool b) { m_hasContinuationChainNode = b; } |
273 | |
274 | void setRenderBlockHasMarginBeforeQuirk(bool b) { m_renderBlockHasMarginBeforeQuirk = b; } |
275 | void setRenderBlockHasMarginAfterQuirk(bool b) { m_renderBlockHasMarginAfterQuirk = b; } |
276 | void setRenderBlockShouldForceRelayoutChildren(bool b) { m_renderBlockShouldForceRelayoutChildren = b; } |
277 | bool renderBlockHasMarginBeforeQuirk() const { return m_renderBlockHasMarginBeforeQuirk; } |
278 | bool renderBlockHasMarginAfterQuirk() const { return m_renderBlockHasMarginAfterQuirk; } |
279 | bool renderBlockShouldForceRelayoutChildren() const { return m_renderBlockShouldForceRelayoutChildren; } |
280 | |
281 | void setRenderBlockFlowLineLayoutPath(unsigned u) { m_renderBlockFlowLineLayoutPath = u; } |
282 | void setRenderBlockFlowHasMarkupTruncation(bool b) { m_renderBlockFlowHasMarkupTruncation = b; } |
283 | unsigned renderBlockFlowLineLayoutPath() const { return m_renderBlockFlowLineLayoutPath; } |
284 | bool renderBlockFlowHasMarkupTruncation() const { return m_renderBlockFlowHasMarkupTruncation; } |
285 | |
286 | void paintFocusRing(PaintInfo&, const RenderStyle&, const Vector<LayoutRect>& focusRingRects); |
287 | void paintOutline(PaintInfo&, const LayoutRect&); |
288 | void updateOutlineAutoAncestor(bool hasOutlineAuto); |
289 | |
290 | void removeFromRenderFragmentedFlowIncludingDescendants(bool shouldUpdateState); |
291 | void adjustFragmentedFlowStateOnContainingBlockChangeIfNeeded(); |
292 | |
293 | bool isVisibleInViewport() const; |
294 | |
295 | private: |
296 | RenderElement(ContainerNode&, RenderStyle&&, BaseTypeFlags); |
297 | void node() const = delete; |
298 | void nonPseudoNode() const = delete; |
299 | void generatingNode() const = delete; |
300 | void isText() const = delete; |
301 | void isRenderElement() const = delete; |
302 | |
303 | RenderObject* firstChildSlow() const final { return firstChild(); } |
304 | RenderObject* lastChildSlow() const final { return lastChild(); } |
305 | |
306 | // Called when an object that was floating or positioned becomes a normal flow object |
307 | // again. We have to make sure the render tree updates as needed to accommodate the new |
308 | // normal flow object. |
309 | void handleDynamicFloatPositionChange(); |
310 | |
311 | bool shouldRepaintForStyleDifference(StyleDifference) const; |
312 | bool hasImmediateNonWhitespaceTextChildOrBorderOrOutline() const; |
313 | |
314 | void updateFillImages(const FillLayer*, const FillLayer&); |
315 | void updateImage(StyleImage*, StyleImage*); |
316 | void updateShapeImage(const ShapeValue*, const ShapeValue*); |
317 | |
318 | StyleDifference adjustStyleDifference(StyleDifference, OptionSet<StyleDifferenceContextSensitiveProperty>) const; |
319 | std::unique_ptr<RenderStyle> computeFirstLineStyle() const; |
320 | void invalidateCachedFirstLineStyle(); |
321 | |
322 | bool canDestroyDecodedData() final { return !isVisibleInViewport(); } |
323 | VisibleInViewportState imageFrameAvailable(CachedImage&, ImageAnimatingState, const IntRect* changeRect) final; |
324 | void didRemoveCachedImageClient(CachedImage&) final; |
325 | |
326 | bool getLeadingCorner(FloatPoint& output, bool& insideFixed) const; |
327 | bool getTrailingCorner(FloatPoint& output, bool& insideFixed) const; |
328 | |
329 | void clearSubtreeLayoutRootIfNeeded() const; |
330 | |
331 | bool shouldWillChangeCreateStackingContext() const; |
332 | void issueRepaintForOutlineAuto(float outlineSize); |
333 | |
334 | unsigned m_baseTypeFlags : 6; |
335 | unsigned m_ancestorLineBoxDirty : 1; |
336 | unsigned m_hasInitializedStyle : 1; |
337 | |
338 | unsigned m_renderInlineAlwaysCreatesLineBoxes : 1; |
339 | unsigned m_renderBoxNeedsLazyRepaint : 1; |
340 | unsigned m_hasPausedImageAnimations : 1; |
341 | unsigned m_hasCounterNodeMap : 1; |
342 | unsigned m_hasContinuationChainNode : 1; |
343 | unsigned m_isContinuation : 1; |
344 | unsigned m_isFirstLetter : 1; |
345 | mutable unsigned m_hasValidCachedFirstLineStyle : 1; |
346 | |
347 | unsigned m_renderBlockHasMarginBeforeQuirk : 1; |
348 | unsigned m_renderBlockHasMarginAfterQuirk : 1; |
349 | unsigned m_renderBlockShouldForceRelayoutChildren : 1; |
350 | unsigned m_renderBlockFlowHasMarkupTruncation : 1; |
351 | unsigned m_renderBlockFlowLineLayoutPath : 2; |
352 | |
353 | unsigned m_isRegisteredForVisibleInViewportCallback : 1; |
354 | unsigned m_visibleInViewportState : 2; |
355 | |
356 | RenderObject* m_firstChild; |
357 | RenderObject* m_lastChild; |
358 | |
359 | RenderStyle m_style; |
360 | }; |
361 | |
362 | inline void RenderElement::setAncestorLineBoxDirty(bool f) |
363 | { |
364 | m_ancestorLineBoxDirty = f; |
365 | if (m_ancestorLineBoxDirty) |
366 | setNeedsLayout(); |
367 | } |
368 | |
369 | inline void RenderElement::setChildNeedsLayout(MarkingBehavior markParents) |
370 | { |
371 | ASSERT(!isSetNeedsLayoutForbidden()); |
372 | if (normalChildNeedsLayout()) |
373 | return; |
374 | setNormalChildNeedsLayoutBit(true); |
375 | if (markParents == MarkContainingBlockChain) |
376 | markContainingBlocksForLayout(); |
377 | } |
378 | |
379 | inline LayoutUnit RenderElement::valueForLength(const Length& length, LayoutUnit maximumValue) const |
380 | { |
381 | return WebCore::valueForLength(length, maximumValue); |
382 | } |
383 | |
384 | inline LayoutUnit RenderElement::minimumValueForLength(const Length& length, LayoutUnit maximumValue) const |
385 | { |
386 | return WebCore::minimumValueForLength(length, maximumValue); |
387 | } |
388 | |
389 | inline bool RenderElement::isRenderLayerModelObject() const |
390 | { |
391 | return m_baseTypeFlags & RenderLayerModelObjectFlag; |
392 | } |
393 | |
394 | inline bool RenderElement::isBoxModelObject() const |
395 | { |
396 | return m_baseTypeFlags & RenderBoxModelObjectFlag; |
397 | } |
398 | |
399 | inline bool RenderElement::isRenderBlock() const |
400 | { |
401 | return m_baseTypeFlags & RenderBlockFlag; |
402 | } |
403 | |
404 | inline bool RenderElement::isRenderBlockFlow() const |
405 | { |
406 | return m_baseTypeFlags & RenderBlockFlowFlag; |
407 | } |
408 | |
409 | inline bool RenderElement::isRenderReplaced() const |
410 | { |
411 | return m_baseTypeFlags & RenderReplacedFlag; |
412 | } |
413 | |
414 | inline bool RenderElement::isRenderInline() const |
415 | { |
416 | return m_baseTypeFlags & RenderInlineFlag; |
417 | } |
418 | |
419 | inline Element* RenderElement::generatingElement() const |
420 | { |
421 | return downcast<Element>(RenderObject::generatingNode()); |
422 | } |
423 | |
424 | inline bool RenderElement::canContainFixedPositionObjects() const |
425 | { |
426 | return isRenderView() |
427 | || (hasTransform() && isRenderBlock()) |
428 | || isSVGForeignObject() |
429 | || isOutOfFlowRenderFragmentedFlow(); |
430 | } |
431 | |
432 | inline bool RenderElement::canContainAbsolutelyPositionedObjects() const |
433 | { |
434 | return style().position() != PositionType::Static |
435 | || (isRenderBlock() && hasTransformRelatedProperty()) |
436 | || isSVGForeignObject() |
437 | || isRenderView(); |
438 | } |
439 | |
440 | inline bool RenderElement::createsGroupForStyle(const RenderStyle& style) |
441 | { |
442 | return style.opacity() < 1.0f || style.hasMask() || style.clipPath() || style.hasFilter() || style.hasBackdropFilter() || style.hasBlendMode(); |
443 | } |
444 | |
445 | inline bool RenderObject::isRenderLayerModelObject() const |
446 | { |
447 | return is<RenderElement>(*this) && downcast<RenderElement>(*this).isRenderLayerModelObject(); |
448 | } |
449 | |
450 | inline bool RenderObject::isBoxModelObject() const |
451 | { |
452 | return is<RenderElement>(*this) && downcast<RenderElement>(*this).isBoxModelObject(); |
453 | } |
454 | |
455 | inline bool RenderObject::isRenderBlock() const |
456 | { |
457 | return is<RenderElement>(*this) && downcast<RenderElement>(*this).isRenderBlock(); |
458 | } |
459 | |
460 | inline bool RenderObject::isRenderBlockFlow() const |
461 | { |
462 | return is<RenderElement>(*this) && downcast<RenderElement>(*this).isRenderBlockFlow(); |
463 | } |
464 | |
465 | inline bool RenderObject::isRenderReplaced() const |
466 | { |
467 | return is<RenderElement>(*this) && downcast<RenderElement>(*this).isRenderReplaced(); |
468 | } |
469 | |
470 | inline bool RenderObject::isRenderInline() const |
471 | { |
472 | return is<RenderElement>(*this) && downcast<RenderElement>(*this).isRenderInline(); |
473 | } |
474 | |
475 | inline const RenderStyle& RenderObject::style() const |
476 | { |
477 | if (isText()) |
478 | return m_parent->style(); |
479 | return downcast<RenderElement>(*this).style(); |
480 | } |
481 | |
482 | inline const RenderStyle& RenderObject::firstLineStyle() const |
483 | { |
484 | if (isText()) |
485 | return m_parent->firstLineStyle(); |
486 | return downcast<RenderElement>(*this).firstLineStyle(); |
487 | } |
488 | |
489 | inline RenderElement* ContainerNode::renderer() const |
490 | { |
491 | return downcast<RenderElement>(Node::renderer()); |
492 | } |
493 | |
494 | inline int adjustForAbsoluteZoom(int value, const RenderElement& renderer) |
495 | { |
496 | return adjustForAbsoluteZoom(value, renderer.style()); |
497 | } |
498 | |
499 | inline LayoutUnit adjustLayoutUnitForAbsoluteZoom(LayoutUnit value, const RenderElement& renderer) |
500 | { |
501 | return adjustLayoutUnitForAbsoluteZoom(value, renderer.style()); |
502 | } |
503 | |
504 | } // namespace WebCore |
505 | |
506 | SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderElement, isRenderElement()) |
507 | |