From f95c614b56af58423dd1770b413224aaece6b710 Mon Sep 17 00:00:00 2001 From: Chris Dumez Date: Fri, 12 Jan 2024 16:07:44 -0800 Subject: [PATCH] Further reduce use of downcast<>() in rendering code https://bugs.webkit.org/show_bug.cgi?id=267471 Reviewed by Geoffrey Garen. * Source/WebCore/rendering/RenderBlock.cpp: (WebCore::RenderBlock::removePositionedObjectsIfNeeded): (WebCore::RenderBlock::simplifiedLayout): (WebCore::RenderBlock::layoutPositionedObject): (WebCore::RenderBlock::blockSelectionGaps): (WebCore::RenderBlock::clearPercentHeightDescendantsFrom): (WebCore::isChildHitTestCandidate): (WebCore::RenderBlock::positionForPoint): (WebCore::RenderBlock::computeBlockPreferredLogicalWidths const): (WebCore::RenderBlock::computeChildPreferredLogicalWidths const): (WebCore::RenderBlock::hasMarginBeforeQuirk const): (WebCore::RenderBlock::hasMarginAfterQuirk const): * Source/WebCore/rendering/RenderBlockFlow.cpp: (WebCore::RenderBlockFlow::previousSiblingWithOverhangingFloats const): (WebCore::RenderBlockFlow::rebuildFloatingObjectSetFromIntrudingFloats): (WebCore::RenderBlockFlow::computeIntrinsicLogicalWidths const): (WebCore::RenderBlockFlow::layoutBlock): (WebCore::firstInlineFormattingContextRoot): (WebCore::lastInlineFormattingContextRoot): (WebCore::RenderBlockFlow::layoutBlockChildren): (WebCore::RenderBlockFlow::selfCollapsingMarginBeforeWithClear): (WebCore::RenderBlockFlow::collapseMarginsWithChildInfo): (WebCore::RenderBlockFlow::marginBeforeEstimateForChild const): (WebCore::RenderBlockFlow::estimateLogicalTopPosition): (WebCore::RenderBlockFlow::adjustForUnsplittableChild): (WebCore::RenderBlockFlow::subtreeContainsFloat const): (WebCore::RenderBlockFlow::subtreeContainsFloats const): (WebCore::RenderBlockFlow::markAllDescendantsWithFloatsForLayout): (WebCore::RenderBlockFlow::markSiblingsWithFloatsForLayout): (WebCore::RenderBlockFlow::hitTestFloats): (WebCore::RenderBlockFlow::adjustEnclosingTopForPrecedingBlock const): (WebCore::positionForRun): (WebCore::RenderBlockFlow::findClosestTextAtAbsolutePoint): (WebCore::RenderBlockFlow::layoutModernLines): (WebCore::isVisibleRenderText): (WebCore::resizeTextPermitted): (WebCore::RenderBlockFlow::checkForPaginationLogicalHeightChange): (WebCore::stripTrailingSpace): (WebCore::RenderBlockFlow::computeInlinePreferredLogicalWidths const): * Source/WebCore/rendering/RenderBox.cpp: (WebCore::RenderBox::updateGridPositionAfterStyleChange): (WebCore::RenderBox::resetLogicalHeightBeforeLayoutIfNeeded): (WebCore::RenderBox::findAutoscrollable): (WebCore::RenderBox::hitTestClipPath const): (WebCore::RenderBox::repaintLayerRectsForImage): (WebCore::RenderBox::computeVisibleRectsInContainer const): (WebCore::RenderBox::hasStretchedLogicalHeight const): (WebCore::RenderBox::hasStretchedLogicalWidth const): (WebCore::RenderBox::cacheIntrinsicContentLogicalHeightForFlexItem const): (WebCore::RenderBox::computeReplacedLogicalHeightUsing const): (WebCore::RenderBox::availableLogicalHeightUsing const): (WebCore::RenderBox::containingBlockLogicalWidthForPositioned const): (WebCore::RenderBox::containingBlockLogicalHeightForPositioned const): (WebCore::computeInlineStaticDistance): (WebCore::RenderBox::computePositionedLogicalWidth const): (WebCore::positionWithRTLInlineBoxContainingBlock): (WebCore::computeBlockStaticDistance): (WebCore::RenderBox::computePositionedLogicalHeight const): (WebCore::RenderBox::positionForPoint): * Source/WebCore/rendering/RenderBox.h: (WebCore::RenderBox::parentBox const): (WebCore::RenderBox::firstChildBox const): (WebCore::RenderBox::lastChildBox const): (WebCore::RenderBox::previousSiblingBox const): (WebCore::RenderBox::nextSiblingBox const): * Source/WebCore/rendering/RenderBoxModelObject.cpp: (WebCore::accumulateInFlowPositionOffsets): (WebCore::RenderBoxModelObject::computeStickyPositionConstraints const): * Source/WebCore/rendering/RenderButton.cpp: (WebCore::RenderButton::updateFromElement): * Source/WebCore/rendering/RenderCounter.cpp: (WebCore::ancestorStyleContainmentObject): (WebCore::previousSiblingOrParentElement): (WebCore::listItemCounterDirectives): (showCounterRendererTree): * Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp: (WebCore::getHeightForLineCount): (WebCore::RenderDeprecatedFlexibleBox::applyModernLineClamp): (WebCore::RenderDeprecatedFlexibleBox::applyLineClamp): (WebCore::RenderDeprecatedFlexibleBox::clearLineClamp): * Source/WebCore/rendering/RenderDetailsMarker.cpp: (WebCore::RenderDetailsMarker::isOpen const): * Source/WebCore/rendering/RenderElement.cpp: (WebCore::RenderElement::adjustStyleDifference const): (WebCore::RenderElement::repaintBeforeStyleChange): (WebCore::RenderElement::didAttachChild): (WebCore::findNextLayer): (WebCore::layerNextSiblingRespectingTopLayer): (WebCore::RenderElement::repaintAfterLayoutIfNeeded): (WebCore::RenderElement::repaintForPausedImageAnimationsIfNeeded): (WebCore::RenderElement::getLeadingCorner const): (WebCore::RenderElement::getTrailingCorner const): (WebCore::RenderElement::updateOutlineAutoAncestor): (WebCore::RenderElement::adjustFragmentedFlowStateOnContainingBlockChangeIfNeeded): (WebCore::RenderElement::removeFromRenderFragmentedFlowIncludingDescendants): (WebCore::includeNonFixedHeight): (WebCore::RenderElement::adjustComputedFontSizesOnBlocks): (WebCore::RenderElement::resetTextAutosizing): (WebCore::RenderElement::referenceBoxRect const): Canonical link: https://commits.webkit.org/272997@main --- Source/WebCore/rendering/RenderBlock.cpp | 93 ++++--- Source/WebCore/rendering/RenderBlockFlow.cpp | 246 +++++++++--------- Source/WebCore/rendering/RenderBox.cpp | 241 +++++++++-------- Source/WebCore/rendering/RenderBox.h | 20 +- .../rendering/RenderBoxModelObject.cpp | 11 +- Source/WebCore/rendering/RenderButton.cpp | 5 +- Source/WebCore/rendering/RenderCounter.cpp | 24 +- .../rendering/RenderDeprecatedFlexibleBox.cpp | 41 +-- .../WebCore/rendering/RenderDetailsMarker.cpp | 4 +- Source/WebCore/rendering/RenderElement.cpp | 102 ++++---- 10 files changed, 414 insertions(+), 373 deletions(-) diff --git a/Source/WebCore/rendering/RenderBlock.cpp b/Source/WebCore/rendering/RenderBlock.cpp index 0ec2cb0708503..37da8e03393a4 100644 --- a/Source/WebCore/rendering/RenderBlock.cpp +++ b/Source/WebCore/rendering/RenderBlock.cpp @@ -404,8 +404,8 @@ void RenderBlock::removePositionedObjectsIfNeeded(const RenderStyle& oldStyle, c } containingBlock = containingBlock->parent(); } - if (containingBlock && is(*containingBlock)) - downcast(*containingBlock).removePositionedObjects(this, NewContainingBlock); + if (CheckedPtr renderBlock = dynamicDowncast(containingBlock)) + renderBlock->removePositionedObjects(this, NewContainingBlock); } } @@ -876,8 +876,8 @@ bool RenderBlock::simplifiedLayout() // Make sure a forced break is applied after the content if we are a flow thread in a simplified layout. // This ensures the size information is correctly computed for the last auto-height fragment receiving content. - if (is(*this)) - downcast(*this).applyBreakAfterContent(clientLogicalBottom()); + if (CheckedPtr fragmentedFlow = dynamicDowncast(*this)) + fragmentedFlow->applyBreakAfterContent(clientLogicalBottom()); // Lay out our positioned objects if our positioned child bit is set. // Also, if an absolute position element inside a relative positioned container moves, and the absolute element has a fixed position @@ -1005,7 +1005,7 @@ void RenderBlock::layoutPositionedObject(RenderBox& r, bool relayoutChildren, bo auto* parent = r.parent(); bool layoutChanged = false; - if (is(*parent) && downcast(parent)->setStaticPositionForPositionedLayout(r)) { + if (auto* flexibleBox = dynamicDowncast(*parent); flexibleBox && flexibleBox->setStaticPositionForPositionedLayout(r)) { // The static position of an abspos child of a flexbox depends on its size // (for example, they can be centered). So we may have to reposition the // item after layout. @@ -1024,8 +1024,10 @@ void RenderBlock::layoutPositionedObject(RenderBox& r, bool relayoutChildren, bo r.layoutIfNeeded(); } - if (layoutState && layoutState->isPaginated() && is(*this)) - downcast(*this).adjustSizeContainmentChildForPagination(r, r.logicalTop()); + if (layoutState && layoutState->isPaginated()) { + if (CheckedPtr blockFlow = dynamicDowncast(*this)) + blockFlow->adjustSizeContainmentChildForPagination(r, r.logicalTop()); + } } void RenderBlock::layoutPositionedObjects(bool relayoutChildren, bool fixedPositionObjectsOnly) @@ -1620,10 +1622,12 @@ GapRects RenderBlock::blockSelectionGaps(RenderBlock& rootBlock, const LayoutPoi lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + curr->logicalBottom(); lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, curr->logicalBottom(), cache); lastLogicalRight = logicalRightSelectionOffset(rootBlock, curr->logicalBottom(), cache); - } else if (childState != HighlightState::None && is(*curr)) { - // We must be a block that has some selected object inside it, so recur. - result.unite(downcast(*curr).selectionGaps(rootBlock, rootBlockPhysicalPosition, LayoutSize(offsetFromRootBlock.width() + curr->x(), offsetFromRootBlock.height() + curr->y()), - lastLogicalTop, lastLogicalLeft, lastLogicalRight, childCache, paintInfo)); + } else if (childState != HighlightState::None) { + if (auto* renderBlock = dynamicDowncast(*curr)) { + // We must be a block that has some selected object inside it, so recur. + result.unite(renderBlock->selectionGaps(rootBlock, rootBlockPhysicalPosition, LayoutSize(offsetFromRootBlock.width() + curr->x(), offsetFromRootBlock.height() + curr->y()), + lastLogicalTop, lastLogicalLeft, lastLogicalRight, childCache, paintInfo)); + } } } return result; @@ -1851,14 +1855,14 @@ void RenderBlock::clearPercentHeightDescendantsFrom(RenderBox& parent) { ASSERT(percentHeightContainerMap); for (RenderObject* child = parent.firstChild(); child; child = child->nextInPreOrder(&parent)) { - if (!is(*child)) + CheckedPtr box = dynamicDowncast(*child); + if (!box) continue; - auto& box = downcast(*child); - if (!hasPercentHeightDescendant(box)) + if (!hasPercentHeightDescendant(*box)) continue; - removePercentHeightDescendant(box); + removePercentHeightDescendant(*box); } } @@ -2151,7 +2155,11 @@ static inline bool isChildHitTestCandidate(const RenderBox& box, const RenderFra return false; if (!fragment) return true; - const RenderBlock& block = is(box) ? downcast(box) : *box.containingBlock(); + auto& block = [&]() -> const RenderBlock& { + if (auto* block = dynamicDowncast(box)) + return *block; + return *box.containingBlock(); + }(); return block.fragmentAtBlockOffset(point.y()) == fragment; } @@ -2204,8 +2212,8 @@ VisiblePosition RenderBlock::positionForPoint(const LayoutPoint& point, const Re if (!isChildHitTestCandidate(*childBox, fragment, pointInLogicalContents)) continue; auto childLogicalBottom = logicalTopForChild(*childBox) + logicalHeightForChild(*childBox); - if (is(childBox)) - childLogicalBottom = std::max(childLogicalBottom, downcast(*childBox).lowestFloatLogicalBottom()); + if (auto* blockFlow = dynamicDowncast(childBox)) + childLogicalBottom = std::max(childLogicalBottom, blockFlow->lowestFloatLogicalBottom()); // We hit child if our click is above the bottom of its padding box (like IE6/7 and FF3). if (pointInLogicalContents.y() < childLogicalBottom || (blocksAreFlipped && pointInLogicalContents.y() == childLogicalBottom)) return positionForPointRespectingEditingBoundaries(*this, *childBox, pointInContents); @@ -2334,7 +2342,7 @@ void RenderBlock::computeBlockPreferredLogicalWidths(LayoutUnit& minLogicalWidth w = childMaxPreferredLogicalWidth + margin; if (!child->isFloating()) { - if (is(*child) && downcast(*child).avoidsFloats()) { + if (auto* box = dynamicDowncast(*child); box && box->avoidsFloats()) { // Determine a left and right max value based off whether or not the floats can fit in the // margins of the object. For negative margins, we will attempt to overlap the float if the negative margin // is smaller than the float width. @@ -2377,21 +2385,20 @@ void RenderBlock::computeChildIntrinsicLogicalWidths(RenderObject& child, Layout void RenderBlock::computeChildPreferredLogicalWidths(RenderObject& child, LayoutUnit& minPreferredLogicalWidth, LayoutUnit& maxPreferredLogicalWidth) const { - if (child.isRenderBox() && child.isHorizontalWritingMode() != isHorizontalWritingMode()) { + if (CheckedPtr box = dynamicDowncast(child); box && box->isHorizontalWritingMode() != isHorizontalWritingMode()) { // If the child is an orthogonal flow, child's height determines the width, // but the height is not available until layout. // http://dev.w3.org/csswg/css-writing-modes-3/#orthogonal-shrink-to-fit - if (!child.needsLayout()) { - minPreferredLogicalWidth = maxPreferredLogicalWidth = downcast(child).logicalHeight(); + if (!box->needsLayout()) { + minPreferredLogicalWidth = maxPreferredLogicalWidth = box->logicalHeight(); return; } - auto& box = downcast(child); - if (box.shouldComputeLogicalHeightFromAspectRatio() && box.style().logicalWidth().isFixed()) { - LayoutUnit logicalWidth = LayoutUnit(box.style().logicalWidth().value()); - minPreferredLogicalWidth = maxPreferredLogicalWidth = blockSizeFromAspectRatio(box.horizontalBorderAndPaddingExtent(), box.verticalBorderAndPaddingExtent(), LayoutUnit(box.style().logicalAspectRatio()), box.style().boxSizingForAspectRatio(), logicalWidth, style().aspectRatioType(), isRenderReplaced()); + if (box->shouldComputeLogicalHeightFromAspectRatio() && box->style().logicalWidth().isFixed()) { + LayoutUnit logicalWidth = LayoutUnit(box->style().logicalWidth().value()); + minPreferredLogicalWidth = maxPreferredLogicalWidth = blockSizeFromAspectRatio(box->horizontalBorderAndPaddingExtent(), box->verticalBorderAndPaddingExtent(), LayoutUnit(box->style().logicalAspectRatio()), box->style().boxSizingForAspectRatio(), logicalWidth, style().aspectRatioType(), isRenderReplaced()); return; } - minPreferredLogicalWidth = maxPreferredLogicalWidth = box.computeLogicalHeightWithoutLayout(); + minPreferredLogicalWidth = maxPreferredLogicalWidth = box->computeLogicalHeightWithoutLayout(); return; } @@ -3038,14 +3045,18 @@ bool RenderBlock::hasMarginBeforeQuirk(const RenderBox& child) const { // If the child has the same directionality as we do, then we can just return its // margin quirk. - if (!child.isWritingModeRoot()) - return is(child) ? downcast(child).hasMarginBeforeQuirk() : child.style().marginBefore().hasQuirk(); - + if (!child.isWritingModeRoot()) { + auto* childBlock = dynamicDowncast(child); + return childBlock ? childBlock->hasMarginBeforeQuirk() : child.style().marginBefore().hasQuirk(); + } + // The child has a different directionality. If the child is parallel, then it's just // flipped relative to us. We can use the opposite edge. - if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) - return is(child) ? downcast(child).hasMarginAfterQuirk() : child.style().marginAfter().hasQuirk(); - + if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) { + auto* childBlock = dynamicDowncast(child); + return childBlock ? childBlock->hasMarginAfterQuirk() : child.style().marginAfter().hasQuirk(); + } + // The child is perpendicular to us and box sides are never quirky in html.css, and we don't really care about // whether or not authors specified quirky ems, since they're an implementation detail. return false; @@ -3055,14 +3066,18 @@ bool RenderBlock::hasMarginAfterQuirk(const RenderBox& child) const { // If the child has the same directionality as we do, then we can just return its // margin quirk. - if (!child.isWritingModeRoot()) - return is(child) ? downcast(child).hasMarginAfterQuirk() : child.style().marginAfter().hasQuirk(); - + if (!child.isWritingModeRoot()) { + auto* childBlock = dynamicDowncast(child); + return childBlock ? childBlock->hasMarginAfterQuirk() : child.style().marginAfter().hasQuirk(); + } + // The child has a different directionality. If the child is parallel, then it's just // flipped relative to us. We can use the opposite edge. - if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) - return is(child) ? downcast(child).hasMarginBeforeQuirk() : child.style().marginBefore().hasQuirk(); - + if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) { + auto* childBlock = dynamicDowncast(child); + return childBlock ? childBlock->hasMarginBeforeQuirk() : child.style().marginBefore().hasQuirk(); + } + // The child is perpendicular to us and box sides are never quirky in html.css, and we don't really care about // whether or not authors specified quirky ems, since they're an implementation detail. return false; diff --git a/Source/WebCore/rendering/RenderBlockFlow.cpp b/Source/WebCore/rendering/RenderBlockFlow.cpp index 40c97c9bcdfca..2259d31b356b8 100644 --- a/Source/WebCore/rendering/RenderBlockFlow.cpp +++ b/Source/WebCore/rendering/RenderBlockFlow.cpp @@ -185,10 +185,9 @@ RenderBlockFlow* RenderBlockFlow::previousSiblingWithOverhangingFloats(bool& par // to avoid floats. parentHasFloats = false; for (RenderObject* sibling = previousSibling(); sibling; sibling = sibling->previousSibling()) { - if (is(*sibling)) { - auto& siblingBlock = downcast(*sibling); - if (!siblingBlock.avoidsFloats()) - return &siblingBlock; + if (auto* siblingBlock = dynamicDowncast(*sibling)) { + if (!siblingBlock->avoidsFloats()) + return siblingBlock; } if (sibling->isFloating()) parentHasFloats = true; @@ -233,29 +232,29 @@ void RenderBlockFlow::rebuildFloatingObjectSetFromIntrudingFloats() // We should not process floats if the parent node is not a RenderBlock. Otherwise, we will add // floats in an invalid context. This will cause a crash arising from a bad cast on the parent. // See , where float property is applied on a text node in a SVG. - if (!is(parent())) + CheckedPtr parentBlock = dynamicDowncast(parent()); + if (!parentBlock) return; // First add in floats from the parent. Self-collapsing blocks let their parent track any floats that intrude into // them (as opposed to floats they contain themselves) so check for those here too. - auto& parentBlock = downcast(*parent()); bool parentHasFloats = false; RenderBlockFlow* previousBlock = previousSiblingWithOverhangingFloats(parentHasFloats); LayoutUnit logicalTopOffset = logicalTop(); - if (parentHasFloats || (parentBlock.lowestFloatLogicalBottom() > logicalTopOffset && previousBlock && previousBlock->isSelfCollapsingBlock())) - addIntrudingFloats(&parentBlock, &parentBlock, parentBlock.logicalLeftOffsetForContent(), logicalTopOffset); + if (parentHasFloats || (parentBlock->lowestFloatLogicalBottom() > logicalTopOffset && previousBlock && previousBlock->isSelfCollapsingBlock())) + addIntrudingFloats(parentBlock.get(), parentBlock.get(), parentBlock->logicalLeftOffsetForContent(), logicalTopOffset); LayoutUnit logicalLeftOffset; if (previousBlock) logicalTopOffset -= previousBlock->logicalTop(); else { - previousBlock = &parentBlock; - logicalLeftOffset += parentBlock.logicalLeftOffsetForContent(); + previousBlock = parentBlock.get(); + logicalLeftOffset += parentBlock->logicalLeftOffsetForContent(); } // Add overhanging floats from the previous RenderBlock, but only if it has a float that intrudes into our space. if (previousBlock->m_floatingObjects && previousBlock->lowestFloatLogicalBottom() > logicalTopOffset) - addIntrudingFloats(previousBlock, &parentBlock, logicalLeftOffset, logicalTopOffset); + addIntrudingFloats(previousBlock, parentBlock.get(), logicalLeftOffset, logicalTopOffset); if (childrenInline()) { LayoutUnit changeLogicalTop = LayoutUnit::max(); @@ -373,8 +372,8 @@ void RenderBlockFlow::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, minLogicalWidth = 0; } - if (is(*this)) { - Length tableCellWidth = downcast(*this).styleOrColLogicalWidth(); + if (auto* cell = dynamicDowncast(*this)) { + Length tableCellWidth = cell->styleOrColLogicalWidth(); if (tableCellWidth.isFixed() && tableCellWidth.value() > 0) maxLogicalWidth = std::max(minLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(tableCellWidth)); } @@ -572,8 +571,8 @@ void RenderBlockFlow::layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalH // Before updating the final size of the flow thread make sure a forced break is applied after the content. // This ensures the size information is correctly computed for the last auto-height fragment receiving content. - if (is(*this)) - downcast(*this).applyBreakAfterContent(oldClientAfterEdge); + if (CheckedPtr fragmentedFlow = dynamicDowncast(*this)) + fragmentedFlow->applyBreakAfterContent(oldClientAfterEdge); updateLogicalHeight(); LayoutUnit newHeight = logicalHeight(); @@ -714,12 +713,12 @@ static RenderBlockFlow* firstInlineFormattingContextRoot(const RenderBlockFlow& { // FIXME: Remove this after implementing "last line damage". for (auto* child = enclosingBlockContainer.firstChild(); child; child = child->previousSibling()) { - if (!is(child) || downcast(*child).createsNewFormattingContext()) + CheckedPtr blockContainer = dynamicDowncast(*child); + if (!blockContainer || blockContainer->createsNewFormattingContext()) continue; - auto& blockContainer = downcast(*child); - if (blockContainer.hasLines()) - return &blockContainer; - if (auto* descendantRoot = firstInlineFormattingContextRoot(blockContainer)) + if (blockContainer->hasLines()) + return blockContainer.get(); + if (auto* descendantRoot = firstInlineFormattingContextRoot(*blockContainer)) return descendantRoot; } return nullptr; @@ -728,12 +727,12 @@ static RenderBlockFlow* firstInlineFormattingContextRoot(const RenderBlockFlow& static RenderBlockFlow* lastInlineFormattingContextRoot(const RenderBlockFlow& enclosingBlockContainer) { for (auto* child = enclosingBlockContainer.lastChild(); child; child = child->previousSibling()) { - if (!is(child) || downcast(*child).createsNewFormattingContext()) + CheckedPtr blockContainer = dynamicDowncast(*child); + if (!blockContainer || blockContainer->createsNewFormattingContext()) continue; - auto& blockContainer = downcast(*child); - if (blockContainer.hasLines()) - return &blockContainer; - if (auto* descendantRoot = lastInlineFormattingContextRoot(blockContainer)) + if (blockContainer->hasLines()) + return blockContainer.get(); + if (auto* descendantRoot = lastInlineFormattingContextRoot(*blockContainer)) return descendantRoot; } return nullptr; @@ -916,13 +915,13 @@ void RenderBlockFlow::layoutBlockChildren(bool relayoutChildren, LayoutUnit& max return; } for (auto* nextSibling = child.nextSibling(); nextSibling; nextSibling = nextSibling->nextSibling()) { - if (!is(*nextSibling)) + CheckedPtr block = dynamicDowncast(*nextSibling); + if (!block) continue; - auto& block = downcast(*nextSibling); - if (block.avoidsFloats() && !block.shrinkToAvoidFloats()) + if (block->avoidsFloats() && !block->shrinkToAvoidFloats()) continue; - if (block.containsFloat(child)) - block.markAllDescendantsWithFloatsForLayout(); + if (block->containsFloat(child)) + block->markAllDescendantsWithFloatsForLayout(); } }; markSiblingsIfIntrudingForLayout(); @@ -1407,22 +1406,22 @@ LayoutUnit RenderBlockFlow::collapseMargins(RenderBox& child, MarginInfo& margin std::optional RenderBlockFlow::selfCollapsingMarginBeforeWithClear(RenderObject* candidate) { - if (!is(candidate)) + CheckedPtr candidateBlockFlow = dynamicDowncast(candidate); + if (!candidateBlockFlow) return { }; - auto& candidateBlockFlow = downcast(*candidate); - if (!candidateBlockFlow.isSelfCollapsingBlock()) + if (!candidateBlockFlow->isSelfCollapsingBlock()) return { }; - if (RenderStyle::usedClear(candidateBlockFlow) == UsedClear::None || !containsFloats()) + if (RenderStyle::usedClear(*candidateBlockFlow) == UsedClear::None || !containsFloats()) return { }; - auto clear = getClearDelta(candidateBlockFlow, candidateBlockFlow.logicalHeight()); + auto clear = getClearDelta(*candidateBlockFlow, candidateBlockFlow->logicalHeight()); // Just because a block box has the clear property set, it does not mean we always get clearance (e.g. when the box is below the cleared floats) - if (clear < candidateBlockFlow.logicalBottom()) + if (clear < candidateBlockFlow->logicalBottom()) return { }; - return marginValuesForChild(candidateBlockFlow).positiveMarginBefore(); + return marginValuesForChild(*candidateBlockFlow).positiveMarginBefore(); } LayoutUnit RenderBlockFlow::collapseMarginsWithChildInfo(RenderBox* child, RenderObject* prevSibling, MarginInfo& marginInfo) @@ -1547,14 +1546,13 @@ LayoutUnit RenderBlockFlow::collapseMarginsWithChildInfo(RenderBox* child, Rende setLogicalHeight(logicalHeight() + (logicalTop - oldLogicalTop)); } - if (is(prevSibling) && !prevSibling->isFloatingOrOutOfFlowPositioned()) { + if (CheckedPtr block = dynamicDowncast(prevSibling); block && !prevSibling->isFloatingOrOutOfFlowPositioned()) { // If |child| is a self-collapsing block it may have collapsed into a previous sibling and although it hasn't reduced the height of the parent yet // any floats from the parent will now overhang. - RenderBlockFlow& block = downcast(*prevSibling); LayoutUnit oldLogicalHeight = logicalHeight(); setLogicalHeight(logicalTop); - if (block.containsFloats() && !block.avoidsFloats() && (block.logicalTop() + block.lowestFloatLogicalBottom()) > logicalTop) - addOverhangingFloats(block, false); + if (block->containsFloats() && !block->avoidsFloats() && (block->logicalTop() + block->lowestFloatLogicalBottom()) > logicalTop) + addOverhangingFloats(*block, false); setLogicalHeight(oldLogicalHeight); // If |child|'s previous sibling is or contains a self-collapsing block that cleared a float and margin collapsing resulted in |child| moving up @@ -1640,18 +1638,18 @@ void RenderBlockFlow::marginBeforeEstimateForChild(RenderBox& child, LayoutUnit& positiveMarginBefore = std::max(positiveMarginBefore, beforeChildMargin); negativeMarginBefore = std::max(negativeMarginBefore, -beforeChildMargin); - if (!is(child)) + CheckedPtr childBlock = dynamicDowncast(child); + if (!childBlock) return; - RenderBlockFlow& childBlock = downcast(child); - if (childBlock.childrenInline() || childBlock.isWritingModeRoot()) + if (childBlock->childrenInline() || childBlock->isWritingModeRoot()) return; - MarginInfo childMarginInfo(childBlock, childBlock.borderAndPaddingBefore(), childBlock.borderAndPaddingAfter()); + MarginInfo childMarginInfo(*childBlock, childBlock->borderAndPaddingBefore(), childBlock->borderAndPaddingAfter()); if (!childMarginInfo.canCollapseMarginBeforeWithChildren()) return; - RenderBox* grandchildBox = childBlock.firstChildBox(); + RenderBox* grandchildBox = childBlock->firstChildBox(); for (; grandchildBox; grandchildBox = grandchildBox->nextSiblingBox()) { if (!grandchildBox->isFloatingOrOutOfFlowPositioned()) break; @@ -1663,21 +1661,20 @@ void RenderBlockFlow::marginBeforeEstimateForChild(RenderBox& child, LayoutUnit& // Make sure to update the block margins now for the grandchild box so that we're looking at current values. if (grandchildBox->needsLayout()) { grandchildBox->computeAndSetBlockDirectionMargins(*this); - if (is(*grandchildBox)) { - RenderBlock& grandchildBlock = downcast(*grandchildBox); - grandchildBlock.setHasMarginBeforeQuirk(grandchildBox->style().marginBefore().hasQuirk()); - grandchildBlock.setHasMarginAfterQuirk(grandchildBox->style().marginAfter().hasQuirk()); + if (CheckedPtr grandchildBlock = dynamicDowncast(*grandchildBox)) { + grandchildBlock->setHasMarginBeforeQuirk(grandchildBox->style().marginBefore().hasQuirk()); + grandchildBlock->setHasMarginAfterQuirk(grandchildBox->style().marginAfter().hasQuirk()); } } // If we have a 'clear' value but also have a margin we may not actually require clearance to move past any floats. // If that's the case we want to be sure we estimate the correct position including margins after any floats rather // than use 'clearance' later which could give us the wrong position. - if (RenderStyle::usedClear(*grandchildBox) != UsedClear::None && !childBlock.marginBeforeForChild(*grandchildBox)) + if (RenderStyle::usedClear(*grandchildBox) != UsedClear::None && !childBlock->marginBeforeForChild(*grandchildBox)) return; // Collapse the margin of the grandchild box with our own to produce an estimate. - childBlock.marginBeforeEstimateForChild(*grandchildBox, positiveMarginBefore, negativeMarginBefore); + childBlock->marginBeforeEstimateForChild(*grandchildBox, positiveMarginBefore, negativeMarginBefore); } LayoutUnit RenderBlockFlow::estimateLogicalTopPosition(RenderBox& child, const MarginInfo& marginInfo, LayoutUnit& estimateWithoutPagination) @@ -1721,8 +1718,10 @@ LayoutUnit RenderBlockFlow::estimateLogicalTopPosition(RenderBox& child, const M // For replaced elements and scrolled elements, we want to shift them to the next page if they don't fit on the current one. logicalTopEstimate = adjustForUnsplittableChild(child, logicalTopEstimate); - if (!child.selfNeedsLayout() && is(child)) - logicalTopEstimate += downcast(child).paginationStrut(); + if (!child.selfNeedsLayout()) { + if (auto* block = dynamicDowncast(child)) + logicalTopEstimate += block->paginationStrut(); + } } return logicalTopEstimate; @@ -2195,8 +2194,11 @@ LayoutUnit RenderBlockFlow::adjustForUnsplittableChild(RenderBox& child, LayoutU // children. We'll treat flexboxes themselves as unsplittable just to get them to paginate properly inside // a block flow. bool isUnsplittable = childBoxIsUnsplittableForFragmentation(child); - if (!isUnsplittable && !(is(child) && !downcast(child).isFlexibleBoxImpl())) + if (!isUnsplittable) { + auto* flexibleBox = dynamicDowncast(child); + if (!(flexibleBox && !flexibleBox->isFlexibleBoxImpl())) return logicalOffset; + } RenderFragmentedFlow* fragmentedFlow = enclosingFragmentedFlow(); LayoutUnit childLogicalHeight = logicalHeightForChild(child) + childBeforeMargin + childAfterMargin; @@ -2360,10 +2362,8 @@ bool RenderBlockFlow::subtreeContainsFloat(RenderBox& renderer) const return true; for (auto& block : descendantsOfType(const_cast(*this))) { - if (!is(block)) - continue; - auto& blockFlow = downcast(block); - if (blockFlow.containsFloat(renderer)) + auto* blockFlow = dynamicDowncast(block); + if (blockFlow && blockFlow->containsFloat(renderer)) return true; } @@ -2376,10 +2376,8 @@ bool RenderBlockFlow::subtreeContainsFloats() const return true; for (auto& block : descendantsOfType(const_cast(*this))) { - if (!is(block)) - continue; - auto& blockFlow = downcast(block); - if (blockFlow.containsFloats()) + auto* blockFlow = dynamicDowncast(block); + if (blockFlow && blockFlow->containsFloats()) return true; } @@ -3165,14 +3163,14 @@ void RenderBlockFlow::markAllDescendantsWithFloatsForLayout(RenderBox* floatToRe for (auto& block : childrenOfType(*this)) { if (!floatToRemove && block.isFloatingOrOutOfFlowPositioned()) continue; - if (!is(block)) { + CheckedPtr blockFlow = dynamicDowncast(block); + if (!blockFlow) { if (block.shrinkToAvoidFloats() && block.everHadLayout()) block.setChildNeedsLayout(markParents); continue; } - auto& blockFlow = downcast(block); - if ((floatToRemove ? blockFlow.subtreeContainsFloat(*floatToRemove) : blockFlow.subtreeContainsFloats()) || blockFlow.shrinkToAvoidFloats()) - blockFlow.markAllDescendantsWithFloatsForLayout(floatToRemove, inLayout); + if ((floatToRemove ? blockFlow->subtreeContainsFloat(*floatToRemove) : blockFlow->subtreeContainsFloats()) || blockFlow->shrinkToAvoidFloats()) + blockFlow->markAllDescendantsWithFloatsForLayout(floatToRemove, inLayout); } } @@ -3185,16 +3183,16 @@ void RenderBlockFlow::markSiblingsWithFloatsForLayout(RenderBox* floatToRemove) auto end = floatingObjectSet.end(); for (RenderObject* next = nextSibling(); next; next = next->nextSibling()) { - if (!is(*next) || (!floatToRemove && (next->isFloatingOrOutOfFlowPositioned() || downcast(*next).avoidsFloats()))) + CheckedPtr nextBlock = dynamicDowncast(*next); + if (!nextBlock || (!floatToRemove && (next->isFloatingOrOutOfFlowPositioned() || nextBlock->avoidsFloats()))) continue; - RenderBlockFlow& nextBlock = downcast(*next); for (auto it = floatingObjectSet.begin(); it != end; ++it) { RenderBox& floatingBox = (*it)->renderer(); if (floatToRemove && &floatingBox != floatToRemove) continue; - if (nextBlock.containsFloat(floatingBox)) - nextBlock.markAllDescendantsWithFloatsForLayout(&floatingBox); + if (nextBlock->containsFloat(floatingBox)) + nextBlock->markAllDescendantsWithFloatsForLayout(&floatingBox); } } } @@ -3291,8 +3289,8 @@ bool RenderBlockFlow::hitTestFloats(const HitTestRequest& request, HitTestResult return false; LayoutPoint adjustedLocation = accumulatedOffset; - if (is(*this)) - adjustedLocation += toLayoutSize(downcast(*this).frameView().scrollPosition()); + if (auto* renderView = dynamicDowncast(*this)) + adjustedLocation += toLayoutSize(renderView->frameView().scrollPosition()); const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); auto begin = floatingObjectSet.begin(); @@ -3469,10 +3467,15 @@ LayoutUnit RenderBlockFlow::adjustEnclosingTopForPrecedingBlock(LayoutUnit top) const RenderObject* sibling = nullptr; do { sibling = object->previousSibling(); - while (sibling && (!is(*sibling) || downcast(*sibling).isSelectionRoot())) + while (sibling) { + auto* siblingBlock = dynamicDowncast(*sibling); + if (siblingBlock && !siblingBlock->isSelectionRoot()) + break; sibling = sibling->previousSibling(); + } - offsetToBlockBefore -= LayoutSize(downcast(*object).logicalLeft(), downcast(*object).logicalTop()); + auto& objectBlock = downcast(*object); + offsetToBlockBefore -= LayoutSize(objectBlock.logicalLeft(), objectBlock.logicalTop()); object = object->parent(); } while (!sibling && is(object) && !downcast(*object).isSelectionRoot()); @@ -3484,12 +3487,12 @@ LayoutUnit RenderBlockFlow::adjustEnclosingTopForPrecedingBlock(LayoutUnit top) offsetToBlockBefore += LayoutSize(beforeBlock->logicalLeft(), beforeBlock->logicalTop()); auto* child = beforeBlock->lastChild(); - while (is(child)) { - beforeBlock = downcast(child); + while (auto* childBlock = dynamicDowncast(child)) { + beforeBlock = childBlock; offsetToBlockBefore += LayoutSize(beforeBlock->logicalLeft(), beforeBlock->logicalTop()); child = beforeBlock->lastChild(); } - return is(beforeBlock) ? downcast(beforeBlock) : nullptr; + return dynamicDowncast(beforeBlock); }; auto* blockBefore = blockBeforeWithinSelectionRoot(); @@ -3694,11 +3697,11 @@ static Position positionForRun(const RenderBlockFlow& flow, InlineIterator::BoxI if (!box->renderer().nonPseudoNode()) return makeDeprecatedLegacyPosition(flow.nonPseudoElement(), start ? flow.caretMinOffset() : flow.caretMaxOffset()); - if (!is(box)) + auto* textBox = dynamicDowncast(box); + if (!textBox) return makeDeprecatedLegacyPosition(box->renderer().nonPseudoNode(), start ? box->renderer().caretMinOffset() : box->renderer().caretMaxOffset()); - auto& textBox = downcast(box); - return makeDeprecatedLegacyPosition(textBox->renderer().nonPseudoNode(), start ? textBox->start() : textBox->end()); + return makeDeprecatedLegacyPosition((*textBox)->renderer().nonPseudoNode(), start ? (*textBox)->start() : (*textBox)->end()); } RenderText* RenderBlockFlow::findClosestTextAtAbsolutePoint(const FloatPoint& point) @@ -3733,9 +3736,11 @@ RenderText* RenderBlockFlow::findClosestTextAtAbsolutePoint(const FloatPoint& po float bottom = nextChild->y(); - if (localPoint.y() >= top && localPoint.y() < bottom && is(*child)) { - block = downcast(child); - break; + if (localPoint.y() >= top && localPoint.y() < bottom) { + if (auto* childAsBlock = dynamicDowncast(*child)) { + block = childAsBlock; + break; + } } } @@ -3757,9 +3762,10 @@ RenderText* RenderBlockFlow::findClosestTextAtAbsolutePoint(const FloatPoint& po return nullptr; if (localPoint.y() > *previousRootInlineBoxBottom && localPoint.y() < box->logicalTop()) { - auto closestBox = closestBoxForHorizontalPosition(*box->lineBox(), localPoint.x()); - if (closestBox && is(closestBox->renderer())) - return const_cast(&downcast(closestBox->renderer())); + if (auto closestBox = closestBoxForHorizontalPosition(*box->lineBox(), localPoint.x())) { + if (auto* textRenderer = dynamicDowncast(closestBox->renderer())) + return const_cast(textRenderer); + } } } previousRootInlineBoxBottom = box->logicalBottom(); @@ -4006,15 +4012,16 @@ void RenderBlockFlow::layoutModernLines(bool relayoutChildren, LayoutUnit& repai for (auto walker = InlineWalker(*this); !walker.atEnd(); walker.advance()) { auto& renderer = *walker.current(); - auto childNeedsLayout = relayoutChildren || (is(renderer) && downcast(renderer).hasRelativeDimensions()); - auto childNeedsPreferredWidthComputation = relayoutChildren && is(renderer) && downcast(renderer).needsPreferredWidthsRecalculation(); + auto* box = dynamicDowncast(renderer); + auto childNeedsLayout = relayoutChildren || (box && box->hasRelativeDimensions()); + auto childNeedsPreferredWidthComputation = relayoutChildren && box && box->needsPreferredWidthsRecalculation(); if (childNeedsLayout) renderer.setNeedsLayout(MarkOnlyThis); if (childNeedsPreferredWidthComputation) renderer.setPreferredLogicalWidthsDirty(true, MarkOnlyThis); if (renderer.isOutOfFlowPositioned()) - renderer.containingBlock()->insertPositionedObject(downcast(renderer)); + renderer.containingBlock()->insertPositionedObject(*box); else hasSimpleOutOfFlowContentOnly = false; @@ -4027,8 +4034,8 @@ void RenderBlockFlow::layoutModernLines(bool relayoutChildren, LayoutUnit& repai else if (!renderer.isOutOfFlowPositioned()) renderer.clearNeedsLayout(); - if (is(renderer)) { - downcast(renderer).combineTextIfNeeded(); + if (CheckedPtr renderCombineText = dynamicDowncast(renderer)) { + renderCombineText->combineTextIfNeeded(); continue; } } @@ -4218,11 +4225,11 @@ void RenderBlockFlow::materializeRareBlockFlowData() static inline bool isVisibleRenderText(const RenderObject& renderer) { - if (!is(renderer)) + auto* renderText = dynamicDowncast(renderer); + if (!renderText) return false; - auto& renderText = downcast(renderer); - return !renderText.linesBoundingBox().isEmpty() && !renderText.text().containsOnly(); + return !renderText->linesBoundingBox().isEmpty() && !renderText->text().containsOnly(); } static inline bool resizeTextPermitted(const RenderObject& renderer) @@ -4230,10 +4237,8 @@ static inline bool resizeTextPermitted(const RenderObject& renderer) // We disallow resizing for text input fields and textarea to address and for (auto* ancestor = renderer.parent(); ancestor; ancestor = ancestor->parent()) { // Get the first non-shadow HTMLElement and see if it's an input. - if (is(ancestor->element()) && !ancestor->element()->isInShadowTree()) { - auto& element = downcast(*ancestor->element()); - return !is(element) && !is(element); - } + if (auto* element = dynamicDowncast(ancestor->element()); element && !element->isInShadowTree()) + return !is(*element) && !is(*element); } return true; } @@ -4386,9 +4391,7 @@ void RenderBlockFlow::checkForPaginationLogicalHeightChange(bool& relayoutChildr relayoutChildren = true; } fragmentedFlow->setColumnHeightAvailable(newColumnHeight); - } else if (is(*this)) { - RenderFragmentedFlow& fragmentedFlow = downcast(*this); - + } else if (CheckedPtr fragmentedFlow = dynamicDowncast(*this)) { // FIXME: This is a hack to always make sure we have a page logical height, if said height // is known. The page logical height thing in RenderLayoutState is meaningless for flow // thread-based pagination (page height isn't necessarily uniform throughout the flow @@ -4398,9 +4401,9 @@ void RenderBlockFlow::checkForPaginationLogicalHeightChange(bool& relayoutChildr // it's unknown, we need to prevent the pagination code from assuming page breaks everywhere // and thereby eating every top margin. It should be trivial to clean up and get rid of this // hack once the old multicol implementation is gone (see also RenderView::pushLayoutStateForPagination). - pageLogicalHeight = fragmentedFlow.isPageLogicalHeightKnown() ? 1_lu : 0_lu; + pageLogicalHeight = fragmentedFlow->isPageLogicalHeightKnown() ? 1_lu : 0_lu; - pageLogicalHeightChanged = fragmentedFlow.pageLogicalSizeChanged(); + pageLogicalHeightChanged = fragmentedFlow->pageLogicalSizeChanged(); } } @@ -4576,12 +4579,11 @@ static LayoutUnit getBorderPaddingMargin(const RenderBoxModelObject& child, bool static inline void stripTrailingSpace(float& inlineMax, float& inlineMin, RenderObject* trailingSpaceChild) { - if (is(trailingSpaceChild)) { + if (auto* renderText = dynamicDowncast(trailingSpaceChild)) { // Collapse away the trailing space at the end of a block. - RenderText& renderText = downcast(*trailingSpaceChild); const UChar space = ' '; - const FontCascade& font = renderText.style().fontCascade(); // FIXME: This ignores first-line. - float spaceWidth = font.width(RenderBlock::constructTextRun(&space, 1, renderText.style())); + const FontCascade& font = renderText->style().fontCascade(); // FIXME: This ignores first-line. + float spaceWidth = font.width(RenderBlock::constructTextRun(&space, 1, renderText->style())); inlineMax -= spaceWidth + font.wordSpacing(); if (inlineMin > inlineMax) inlineMin = inlineMax; @@ -4705,10 +4707,10 @@ void RenderBlockFlow::computeInlinePreferredLogicalWidths(LayoutUnit& minLogical continue; } // Case (1) and (2). Inline replaced and inline flow elements. - if (is(*child)) { + if (CheckedPtr renderInline = dynamicDowncast(*child)) { // Add in padding/border/margin from the appropriate side of // the element. - float bpm = getBorderPaddingMargin(downcast(*child), childIterator.endOfInline); + float bpm = getBorderPaddingMargin(*renderInline, childIterator.endOfInline); childMin += bpm; childMax += bpm; @@ -4747,9 +4749,8 @@ void RenderBlockFlow::computeInlinePreferredLogicalWidths(LayoutUnit& minLogical // Case (2). Inline replaced elements and floats. // Terminate the current line as far as minwidth is concerned. LayoutUnit childMinPreferredLogicalWidth, childMaxPreferredLogicalWidth; - if (is(*child) && child->isHorizontalWritingMode() != isHorizontalWritingMode()) { - auto& box = downcast(*child); - auto extent = box.computeLogicalHeight(box.borderAndPaddingLogicalHeight(), 0).m_extent; + if (CheckedPtr box = dynamicDowncast(*child); box && child->isHorizontalWritingMode() != isHorizontalWritingMode()) { + auto extent = box->computeLogicalHeight(box->borderAndPaddingLogicalHeight(), 0).m_extent; childMinPreferredLogicalWidth = extent; childMaxPreferredLogicalWidth = extent; } else @@ -4824,12 +4825,11 @@ void RenderBlockFlow::computeInlinePreferredLogicalWidths(LayoutUnit& minLogical trailingSpaceChild = nullptr; lastText = nullptr; } - } else if (is(*child)) { - // Case (3). Text. - RenderText& renderText = downcast(*child); - - if (renderText.style().hasTextCombine() && renderText.isRenderCombineText()) - downcast(renderText).combineTextIfNeeded(); + } else if (CheckedPtr renderText = dynamicDowncast(*child)) { + if (renderText->style().hasTextCombine()) { + if (CheckedPtr renderCombineText = dynamicDowncast(*renderText)) + renderCombineText->combineTextIfNeeded(); + } // Determine if we have a breakable character. Pass in // whether or not we should ignore any spaces at the front @@ -4837,7 +4837,7 @@ void RenderBlockFlow::computeInlinePreferredLogicalWidths(LayoutUnit& minLogical // then they shouldn't be considered in the breakable char // check. bool strippingBeginWS = stripFrontSpaces; - auto widths = renderText.trimmedPreferredWidths(inlineMax, stripFrontSpaces); + auto widths = renderText->trimmedPreferredWidths(inlineMax, stripFrontSpaces); childMin = widths.min; childMax = widths.max; @@ -4851,7 +4851,7 @@ void RenderBlockFlow::computeInlinePreferredLogicalWidths(LayoutUnit& minLogical continue; } - lastText = &renderText; + lastText = renderText.get(); if (stripFrontSpaces) trailingSpaceChild = child; @@ -4882,8 +4882,8 @@ void RenderBlockFlow::computeInlinePreferredLogicalWidths(LayoutUnit& minLogical // See if we have a hanging punctuation situation at the start. if (canHangPunctuationAtStart && !addedStartPunctuationHang) { - unsigned startIndex = strippingBeginWS ? renderText.firstCharacterIndexStrippingSpaces() : 0; - float hangStartWidth = renderText.hangablePunctuationStartWidth(startIndex); + unsigned startIndex = strippingBeginWS ? renderText->firstCharacterIndexStrippingSpaces() : 0; + float hangStartWidth = renderText->hangablePunctuationStartWidth(startIndex); childMin -= hangStartWidth; widths.beginMin -= hangStartWidth; childMax -= hangStartWidth; diff --git a/Source/WebCore/rendering/RenderBox.cpp b/Source/WebCore/rendering/RenderBox.cpp index 200443ea15c6e..f5cb3446e3dda 100644 --- a/Source/WebCore/rendering/RenderBox.cpp +++ b/Source/WebCore/rendering/RenderBox.cpp @@ -390,7 +390,10 @@ void RenderBox::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle void RenderBox::updateGridPositionAfterStyleChange(const RenderStyle& style, const RenderStyle* oldStyle) { - if (!oldStyle || !is(parent())) + if (!oldStyle) + return; + CheckedPtr parentGrid = dynamicDowncast(parent()); + if (!parentGrid) return; if (oldStyle->gridItemColumnStart() == style.gridItemColumnStart() @@ -409,7 +412,7 @@ void RenderBox::updateGridPositionAfterStyleChange(const RenderStyle& style, con // It should be possible to not dirty the grid in some cases (like moving an // explicitly placed grid item). // For now, it's more simple to just always recompute the grid. - downcast(*parent()).dirtyGrid(); + parentGrid->dirtyGrid(); } void RenderBox::updateShapeOutsideInfoAfterStyleChange(const RenderStyle& style, const RenderStyle* oldStyle) @@ -582,7 +585,14 @@ int RenderBox::scrollTop() const void RenderBox::resetLogicalHeightBeforeLayoutIfNeeded() { - if (shouldResetLogicalHeightBeforeLayout() || (is(parent()) && downcast(*parent()).shouldResetChildLogicalHeightBeforeLayout(*this))) + bool shouldSetLogicalHeight = [&] { + if (shouldResetLogicalHeightBeforeLayout()) + return true; + auto* parentBlock = dynamicDowncast(parent()); + return parentBlock && parentBlock->shouldResetChildLogicalHeightBeforeLayout(*this); + }(); + + if (shouldSetLogicalHeight) setLogicalHeight(0_lu); } @@ -1103,7 +1113,9 @@ IntSize RenderBox::calculateAutoscrollDirection(const IntPoint& windowPoint) con RenderBox* RenderBox::findAutoscrollable(RenderObject* renderer) { - while (renderer && !(is(*renderer) && downcast(*renderer).canAutoscroll())) { + while (renderer) { + if (auto* box = dynamicDowncast(*renderer); box && box->canAutoscroll()) + break; if (is(*renderer) && renderer->document().ownerElement()) renderer = renderer->document().ownerElement()->renderer(); else @@ -1531,10 +1543,8 @@ bool RenderBox::hitTestClipPath(const HitTestLocation& hitTestLocation, const La auto hitsClipContent = [&](Element& element) -> bool { #if ENABLE(LAYER_BASED_SVG_ENGINE) - if (is(element.renderer())) { - CheckedRef clipper = downcast(*element.renderer()); + if (CheckedPtr clipper = dynamicDowncast(element.renderer())) return clipper->hitTestClipContent( FloatRect { borderBoxRect() }, hitTestLocationInLocalCoordinates); - } #endif CheckedRef clipper = downcast(*element.renderer()); return clipper->hitTestClipContent( FloatRect { borderBoxRect() }, FloatPoint { hitTestLocationInLocalCoordinates }); @@ -1542,14 +1552,14 @@ bool RenderBox::hitTestClipPath(const HitTestLocation& hitTestLocation, const La switch (style().clipPath()->type()) { case PathOperation::Shape: { - auto& clipPath = downcast(*style().clipPath()); + auto& clipPath = uncheckedDowncast(*style().clipPath()); auto referenceBoxRect = this->referenceBoxRect(clipPath.referenceBox()); if (!clipPath.pathForReferenceRect(referenceBoxRect).contains(hitTestLocationInLocalCoordinates, clipPath.windRule())) return false; break; } case PathOperation::Reference: { - const auto& referencePathOperation = downcast(*style().clipPath()); + const auto& referencePathOperation = uncheckedDowncast(*style().clipPath()); RefPtr element = document().getElementById(referencePathOperation.fragment()); if (!element || !element->renderer()) break; @@ -2073,8 +2083,9 @@ bool RenderBox::repaintLayerRectsForImage(WrappedImagePtr image, const FillLayer if (drawingRootBackground) { layerRenderer = &view(); - LayoutUnit rw = downcast(*layerRenderer).frameView().contentsWidth(); - LayoutUnit rh = downcast(*layerRenderer).frameView().contentsHeight(); + auto& renderView = downcast(*layerRenderer); + LayoutUnit rw = renderView.frameView().contentsWidth(); + LayoutUnit rh = renderView.frameView().contentsHeight(); rendererRect = LayoutRect(-layerRenderer->marginLeft(), -layerRenderer->marginTop(), @@ -2599,14 +2610,14 @@ auto RenderBox::computeVisibleRectsInContainer(const RepaintRects& rects, const adjustedRects.expand(locationOffset - flooredLocationOffset); locationOffset = flooredLocationOffset; context.descendantNeedsEnclosingIntRect = true; - } else if (is(this)) { + } else if (auto* columnFlow = dynamicDowncast(*this)) { // We won't normally run this code. Only when the container is null (i.e., we're trying // to get the rect in view coordinates) will we come in here, since normally container // will be set and we'll stop at the flow thread. This case is mainly hit by the check for whether // or not images should animate. // FIXME: Just as with offsetFromContainer, we aren't really handling objects that span multiple columns properly. LayoutPoint physicalPoint(flipForWritingMode(adjustedRects.clippedOverflowRect.location())); - if (auto* fragment = downcast(*this).physicalTranslationFromFlowToFragment((physicalPoint))) { + if (auto* fragment = columnFlow->physicalTranslationFromFlowToFragment((physicalPoint))) { adjustedRects.clippedOverflowRect.setLocation(fragment->flipForWritingMode(physicalPoint)); return fragment->computeVisibleRectsInContainer(adjustedRects, container, context); } @@ -2916,11 +2927,11 @@ bool RenderBox::hasStretchedLogicalHeight() const return false; } if (containingBlock->isHorizontalWritingMode() != isHorizontalWritingMode()) { - if (is(this) && downcast(this)->isSubgridInParentDirection(GridTrackSizingDirection::ForColumns)) + if (auto* grid = dynamicDowncast(*this); grid && grid->isSubgridInParentDirection(GridTrackSizingDirection::ForColumns)) return true; return style.resolvedJustifySelf(&containingBlock->style(), containingBlock->selfAlignmentNormalBehavior(this)).position() == ItemPosition::Stretch; } - if (is(this) && downcast(this)->isSubgridInParentDirection(GridTrackSizingDirection::ForRows)) + if (auto* grid = dynamicDowncast(*this); grid && grid->isSubgridInParentDirection(GridTrackSizingDirection::ForRows)) return true; return style.resolvedAlignSelf(&containingBlock->style(), containingBlock->selfAlignmentNormalBehavior(this)).position() == ItemPosition::Stretch; } @@ -2939,11 +2950,11 @@ bool RenderBox::hasStretchedLogicalWidth(StretchingMode stretchingMode) const } auto normalItemPosition = stretchingMode == StretchingMode::Any ? containingBlock->selfAlignmentNormalBehavior(this) : ItemPosition::Normal; if (containingBlock->isHorizontalWritingMode() != isHorizontalWritingMode()) { - if (is(this) && downcast(this)->isSubgridInParentDirection(GridTrackSizingDirection::ForRows)) + if (auto* grid = dynamicDowncast(*this); grid && grid->isSubgridInParentDirection(GridTrackSizingDirection::ForRows)) return true; return style.resolvedAlignSelf(&containingBlock->style(), normalItemPosition).position() == ItemPosition::Stretch; } - if (is(this) && downcast(this)->isSubgridInParentDirection(GridTrackSizingDirection::ForColumns)) + if (auto* grid = dynamicDowncast(*this); grid && grid->isSubgridInParentDirection(GridTrackSizingDirection::ForColumns)) return true; return style.resolvedJustifySelf(&containingBlock->style(), normalItemPosition).position() == ItemPosition::Stretch; } @@ -3155,9 +3166,14 @@ void RenderBox::cacheIntrinsicContentLogicalHeightForFlexItem(LayoutUnit height) // FIXME: it should be enough with checking hasOverridingLogicalHeight() as this logic could be shared // by any layout system using overrides like grid or flex. However this causes a never ending sequence of calls // between layoutBlock() <-> relayoutToAvoidWidows(). - if (isFloatingOrOutOfFlowPositioned() || !is(parent()) || hasOverridingLogicalHeight() || shouldComputeLogicalHeightFromAspectRatio()) + if (isFloatingOrOutOfFlowPositioned()) + return; + CheckedPtr flexibleBox = dynamicDowncast(parent()); + if (!flexibleBox) + return; + if (hasOverridingLogicalHeight() || shouldComputeLogicalHeightFromAspectRatio()) return; - downcast(parent())->setCachedChildIntrinsicContentLogicalHeight(*this, height); + flexibleBox->setCachedChildIntrinsicContentLogicalHeight(*this, height); } void RenderBox::overrideLogicalHeightForSizeContainment() @@ -3677,8 +3693,7 @@ LayoutUnit RenderBox::computeReplacedLogicalHeightUsing(SizeType heightType, Len } bool hasPerpendicularContainingBlock = container->isHorizontalWritingMode() != isHorizontalWritingMode(); std::optional stretchedHeight; - if (is(container)) { - auto* block = downcast(container); + if (auto* block = dynamicDowncast(container)) { block->addPercentHeightDescendant(*const_cast(this)); if (block->isFlexItem() && downcast(block->parent())->useChildOverridingLogicalHeightForPercentageResolution(*block)) stretchedHeight = block->overridingContentLogicalHeight(); @@ -3691,8 +3706,7 @@ LayoutUnit RenderBox::computeReplacedLogicalHeightUsing(SizeType heightType, Len if (container->isOutOfFlowPositioned() && container->style().height().isAuto() && !(container->style().top().isAuto() || container->style().bottom().isAuto())) { - RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(container->isRenderBlock()); - auto& block = downcast(*container); + auto& block = checkedDowncast(*container); auto computedValues = block.computeLogicalHeight(block.logicalHeight(), 0); LayoutUnit newContentHeight = computedValues.m_extent - block.borderAndPaddingLogicalHeight() - block.scrollbarLogicalHeight(); return adjustContentBoxLogicalHeightForBoxSizing(valueForLength(logicalHeight, newContentHeight)); @@ -3772,10 +3786,9 @@ LayoutUnit RenderBox::availableLogicalHeightUsing(const Length& h, AvailableLogi // Height of absolutely positioned, non-replaced elements section 5.3 rule 5 // https://www.w3.org/TR/css-position-3/#abs-non-replaced-height - if (is(*this) && isOutOfFlowPositioned() && style().logicalHeight().isAuto() && !(style().logicalTop().isAuto() || style().logicalBottom().isAuto())) { - RenderBlock& block = const_cast(downcast(*this)); - auto computedValues = block.computeLogicalHeight(block.logicalHeight(), 0); - return computedValues.m_extent - block.borderAndPaddingLogicalHeight() - block.scrollbarLogicalHeight(); + if (CheckedPtr block = dynamicDowncast(*this); block && isOutOfFlowPositioned() && style().logicalHeight().isAuto() && !(style().logicalTop().isAuto() || style().logicalBottom().isAuto())) { + auto computedValues = block->computeLogicalHeight(block->logicalHeight(), 0); + return computedValues.m_extent - block->borderAndPaddingLogicalHeight() - block->scrollbarLogicalHeight(); } LayoutUnit availableHeight = isOrthogonal(*this, *containingBlock()) ? containingBlockLogicalWidthForContent() : containingBlockLogicalHeightForContent(heightType); @@ -3838,36 +3851,37 @@ LayoutUnit RenderBox::containingBlockLogicalWidthForPositioned(const RenderBoxMo return width.value(); } - if (is(containingBlock)) { + if (auto* box = dynamicDowncast(containingBlock)) { bool isFixedPosition = isFixedPositioned(); RenderFragmentedFlow* fragmentedFlow = enclosingFragmentedFlow(); if (!fragmentedFlow) { - if (isFixedPosition && is(containingBlock)) - return downcast(containingBlock).clientLogicalWidthForFixedPosition(); - + if (isFixedPosition) { + if (auto* renderView = dynamicDowncast(containingBlock)) + return renderView->clientLogicalWidthForFixedPosition(); + } return downcast(containingBlock).clientLogicalWidth(); } - if (!is(containingBlock)) - return downcast(containingBlock).clientLogicalWidth(); + CheckedPtr cb = dynamicDowncast(containingBlock); + if (!cb) + return box->clientLogicalWidth(); - const RenderBlock& cb = downcast(containingBlock); RenderBoxFragmentInfo* boxInfo = nullptr; if (!fragment) { - if (is(containingBlock) && !checkForPerpendicularWritingMode) - return downcast(containingBlock).contentLogicalWidthOfFirstFragment(); + if (auto* fragmentedFlow = dynamicDowncast(containingBlock); fragmentedFlow && !checkForPerpendicularWritingMode) + return fragmentedFlow->contentLogicalWidthOfFirstFragment(); if (isWritingModeRoot()) { - LayoutUnit cbPageOffset = cb.offsetFromLogicalTopOfFirstPage(); - RenderFragmentContainer* cbFragment = cb.fragmentAtBlockOffset(cbPageOffset); + LayoutUnit cbPageOffset = cb->offsetFromLogicalTopOfFirstPage(); + RenderFragmentContainer* cbFragment = cb->fragmentAtBlockOffset(cbPageOffset); if (cbFragment) - boxInfo = cb.renderBoxFragmentInfo(cbFragment); + boxInfo = cb->renderBoxFragmentInfo(cbFragment); } } else if (fragmentedFlow->isHorizontalWritingMode() == containingBlock.isHorizontalWritingMode()) { - RenderFragmentContainer* containingBlockFragment = cb.clampToStartAndEndFragments(fragment); - boxInfo = cb.renderBoxFragmentInfo(containingBlockFragment); + RenderFragmentContainer* containingBlockFragment = cb->clampToStartAndEndFragments(fragment); + boxInfo = cb->renderBoxFragmentInfo(containingBlockFragment); } - return (boxInfo) ? std::max(0, cb.clientLogicalWidth() - (cb.logicalWidth() - boxInfo->logicalWidth())) : cb.clientLogicalWidth(); + return (boxInfo) ? std::max(0, cb->clientLogicalWidth() - (cb->logicalWidth() - boxInfo->logicalWidth())) : cb->clientLogicalWidth(); } ASSERT(containingBlock.isInFlowPositioned()); @@ -3888,14 +3902,19 @@ LayoutUnit RenderBox::containingBlockLogicalHeightForPositioned(const RenderBoxM if (containingBlock.isRenderBox()) { bool isFixedPosition = isFixedPositioned(); - if (isFixedPosition && is(containingBlock)) - return downcast(containingBlock).clientLogicalHeightForFixedPosition(); + if (isFixedPosition) { + if (auto* renderView = dynamicDowncast(containingBlock)) + return renderView->clientLogicalHeightForFixedPosition(); + } - const RenderBlock& cb = is(containingBlock) ? downcast(containingBlock) : *containingBlock.containingBlock(); + auto* containingBlockAsRenderBlock = dynamicDowncast(containingBlock); + const RenderBlock& cb = containingBlockAsRenderBlock ? *containingBlockAsRenderBlock : *containingBlock.containingBlock(); LayoutUnit result = cb.clientLogicalHeight(); RenderFragmentedFlow* fragmentedFlow = enclosingFragmentedFlow(); - if (fragmentedFlow && is(containingBlock) && fragmentedFlow->isHorizontalWritingMode() == containingBlock.isHorizontalWritingMode()) - return downcast(containingBlock).contentLogicalHeightOfFirstFragment(); + if (fragmentedFlow && fragmentedFlow->isHorizontalWritingMode() == containingBlock.isHorizontalWritingMode()) { + if (auto* containingBlockFragmentedFlow = dynamicDowncast(containingBlock)) + return containingBlockFragmentedFlow->contentLogicalHeightOfFirstFragment(); + } return result; } @@ -3927,18 +3946,18 @@ static void computeInlineStaticDistance(Length& logicalLeft, Length& logicalRigh if (parentDirection == TextDirection::LTR || isOrthogonal(*child, *parent)) { LayoutUnit staticPosition = isOrthogonal(*child, *parent) ? child->layer()->staticBlockPosition() - containerBlock.borderBefore() : child->layer()->staticInlinePosition() - containerBlock.borderLogicalLeft(); for (auto* current = parent; current && current != &containerBlock; current = current->container()) { - if (!is(*current)) + CheckedPtr renderBox = dynamicDowncast(*current); + if (!renderBox) continue; - const auto& renderBox = downcast(*current); - staticPosition += isOrthogonal(*child, *parent) ? renderBox.logicalTop() : renderBox.logicalLeft(); - if (renderBox.isInFlowPositioned()) - staticPosition += renderBox.isHorizontalWritingMode() ? renderBox.offsetForInFlowPosition().width() : renderBox.offsetForInFlowPosition().height(); - if (fragment && is(*current)) { - const RenderBlock& currentBlock = downcast(*current); - fragment = currentBlock.clampToStartAndEndFragments(fragment); - RenderBoxFragmentInfo* boxInfo = currentBlock.renderBoxFragmentInfo(fragment); - if (boxInfo) - staticPosition += boxInfo->logicalLeft(); + staticPosition += isOrthogonal(*child, *parent) ? renderBox->logicalTop() : renderBox->logicalLeft(); + if (renderBox->isInFlowPositioned()) + staticPosition += renderBox->isHorizontalWritingMode() ? renderBox->offsetForInFlowPosition().width() : renderBox->offsetForInFlowPosition().height(); + if (fragment) { + if (CheckedPtr currentBlock = dynamicDowncast(*current)) { + fragment = currentBlock->clampToStartAndEndFragments(fragment); + if (auto* boxInfo = currentBlock->renderBoxFragmentInfo(fragment)) + staticPosition += boxInfo->logicalLeft(); + } } } logicalLeft.setValue(LengthType::Fixed, staticPosition); @@ -3952,24 +3971,25 @@ static void computeInlineStaticDistance(Length& logicalLeft, Length& logicalRigh } staticPosition -= enclosingBox.logicalWidth(); for (const RenderElement* current = &enclosingBox; current; current = current->container()) { - if (!is(*current)) + CheckedPtr renderBox = dynamicDowncast(*current); + if (!renderBox) continue; if (current != &containerBlock) { - auto& renderBox = downcast(*current); - staticPosition -= renderBox.logicalLeft(); - if (renderBox.isInFlowPositioned()) - staticPosition -= renderBox.isHorizontalWritingMode() ? renderBox.offsetForInFlowPosition().width() : renderBox.offsetForInFlowPosition().height(); + staticPosition -= renderBox->logicalLeft(); + if (renderBox->isInFlowPositioned()) + staticPosition -= renderBox->isHorizontalWritingMode() ? renderBox->offsetForInFlowPosition().width() : renderBox->offsetForInFlowPosition().height(); } - if (fragment && is(*current)) { - auto& currentBlock = downcast(*current); - fragment = currentBlock.clampToStartAndEndFragments(fragment); - RenderBoxFragmentInfo* boxInfo = currentBlock.renderBoxFragmentInfo(fragment); - if (boxInfo) { - if (current != &containerBlock) - staticPosition -= currentBlock.logicalWidth() - (boxInfo->logicalLeft() + boxInfo->logicalWidth()); - if (current == &enclosingBox) - staticPosition += enclosingBox.logicalWidth() - boxInfo->logicalWidth(); + if (fragment) { + if (CheckedPtr currentBlock = dynamicDowncast(*current)) { + fragment = currentBlock->clampToStartAndEndFragments(fragment); + RenderBoxFragmentInfo* boxInfo = currentBlock->renderBoxFragmentInfo(fragment); + if (boxInfo) { + if (current != &containerBlock) + staticPosition -= currentBlock->logicalWidth() - (boxInfo->logicalLeft() + boxInfo->logicalWidth()); + if (current == &enclosingBox) + staticPosition += enclosingBox.logicalWidth() - boxInfo->logicalWidth(); + } } } if (current == &containerBlock) @@ -4107,26 +4127,26 @@ void RenderBox::computePositionedLogicalWidth(LogicalExtentComputedValues& compu } computedValues.m_extent += bordersPlusPadding; - if (is(containerBlock)) { - auto& containingBox = downcast(containerBlock); - if (containingBox.shouldPlaceVerticalScrollbarOnLeft() && isHorizontalWritingMode()) - computedValues.m_position += containingBox.verticalScrollbarWidth(); + if (auto* containingBox = dynamicDowncast(containerBlock)) { + if (containingBox->shouldPlaceVerticalScrollbarOnLeft() && isHorizontalWritingMode()) + computedValues.m_position += containingBox->verticalScrollbarWidth(); } // Adjust logicalLeft if we need to for the flipped version of our writing mode in fragments. // FIXME: Add support for other types of objects as containerBlock, not only RenderBlock. RenderFragmentedFlow* fragmentedFlow = enclosingFragmentedFlow(); - if (fragmentedFlow && !fragment && isWritingModeRoot() && isHorizontalWritingMode() == containerBlock.isHorizontalWritingMode() && is(containerBlock)) { - ASSERT(containerBlock.canHaveBoxInfoInFragment()); - LayoutUnit logicalLeftPos = computedValues.m_position; - const RenderBlock& renderBlock = downcast(containerBlock); - LayoutUnit cbPageOffset = renderBlock.offsetFromLogicalTopOfFirstPage(); - RenderFragmentContainer* cbFragment = renderBlock.fragmentAtBlockOffset(cbPageOffset); - if (cbFragment) { - RenderBoxFragmentInfo* boxInfo = renderBlock.renderBoxFragmentInfo(cbFragment); - if (boxInfo) { - logicalLeftPos += boxInfo->logicalLeft(); - computedValues.m_position = logicalLeftPos; + if (fragmentedFlow && !fragment && isWritingModeRoot() && isHorizontalWritingMode() == containerBlock.isHorizontalWritingMode()) { + if (CheckedPtr renderBlock = dynamicDowncast(containerBlock)) { + ASSERT(containerBlock.canHaveBoxInfoInFragment()); + LayoutUnit logicalLeftPos = computedValues.m_position; + LayoutUnit cbPageOffset = renderBlock->offsetFromLogicalTopOfFirstPage(); + RenderFragmentContainer* cbFragment = renderBlock->fragmentAtBlockOffset(cbPageOffset); + if (cbFragment) { + RenderBoxFragmentInfo* boxInfo = renderBlock->renderBoxFragmentInfo(cbFragment); + if (boxInfo) { + logicalLeftPos += boxInfo->logicalLeft(); + computedValues.m_position = logicalLeftPos; + } } } } @@ -4148,11 +4168,11 @@ static void computeLogicalLeftPositionedOffset(LayoutUnit& logicalLeftPos, const static std::optional positionWithRTLInlineBoxContainingBlock(const RenderElement& containingBlock, LayoutUnit logicalLeftValue, LayoutUnit marginLogicalLeftValue) { - if (!is(containingBlock) || containingBlock.style().isLeftToRightDirection()) + CheckedPtr renderInline = dynamicDowncast(containingBlock); + if (!renderInline || containingBlock.style().isLeftToRightDirection()) return { }; - auto& renderInline = downcast(containingBlock); - auto firstInlineBox = InlineIterator::firstInlineBoxFor(renderInline); + auto firstInlineBox = InlineIterator::firstInlineBoxFor(*renderInline); if (!firstInlineBox) return { }; @@ -4164,7 +4184,7 @@ static std::optional positionWithRTLInlineBoxContainingBlock(const Render if (firstInlineBox == lastInlineBox) return { }; - auto lastInlineBoxPaddingBoxVisualRight = lastInlineBox->logicalLeftIgnoringInlineDirection() + renderInline.borderLogicalLeft(); + auto lastInlineBoxPaddingBoxVisualRight = lastInlineBox->logicalLeftIgnoringInlineDirection() + renderInline->borderLogicalLeft(); // FIXME: This does not work with decoration break clone. auto firstInlineBoxPaddingBoxVisualRight = firstInlineBox->logicalLeftIgnoringInlineDirection(); auto distance = lastInlineBoxPaddingBoxVisualRight - firstInlineBoxPaddingBoxVisualRight; @@ -4372,13 +4392,13 @@ static void computeBlockStaticDistance(Length& logicalTop, Length& logicalBottom // the child's writing mode) is retrieved from the static inline position instead of the static block position. LayoutUnit staticLogicalTop = isOrthogonal(*child, *parent) ? child->layer()->staticInlinePosition() - containerBlock.borderLogicalLeft() : child->layer()->staticBlockPosition() - containerBlock.borderBefore(); for (RenderElement* container = child->parent(); container && container != &containerBlock; container = container->container()) { - if (!is(*container)) + auto* renderBox = dynamicDowncast(*container); + if (!renderBox) continue; - const auto& renderBox = downcast(*container); - if (!is(renderBox)) - staticLogicalTop += isOrthogonal(*child, *parent) ? renderBox.logicalLeft() : renderBox.logicalTop(); - if (renderBox.isInFlowPositioned()) - staticLogicalTop += renderBox.isHorizontalWritingMode() ? renderBox.offsetForInFlowPosition().height() : renderBox.offsetForInFlowPosition().width(); + if (!is(*renderBox)) + staticLogicalTop += isOrthogonal(*child, *parent) ? renderBox->logicalLeft() : renderBox->logicalTop(); + if (renderBox->isInFlowPositioned()) + staticLogicalTop += renderBox->isHorizontalWritingMode() ? renderBox->offsetForInFlowPosition().height() : renderBox->offsetForInFlowPosition().width(); } // If the parent is RTL then we need to flip the coordinate by setting the logical bottom instead of the logical top. That only needs @@ -4484,17 +4504,18 @@ void RenderBox::computePositionedLogicalHeight(LogicalExtentComputedValues& comp // Adjust logicalTop if we need to for perpendicular writing modes in fragments. // FIXME: Add support for other types of objects as containerBlock, not only RenderBlock. RenderFragmentedFlow* fragmentedFlow = enclosingFragmentedFlow(); - if (fragmentedFlow && isHorizontalWritingMode() != containerBlock.isHorizontalWritingMode() && is(containerBlock)) { - ASSERT(containerBlock.canHaveBoxInfoInFragment()); - LayoutUnit logicalTopPos = computedValues.m_position; - const RenderBlock& renderBox = downcast(containerBlock); - LayoutUnit cbPageOffset = renderBox.offsetFromLogicalTopOfFirstPage() - logicalLeft(); - RenderFragmentContainer* cbFragment = renderBox.fragmentAtBlockOffset(cbPageOffset); - if (cbFragment) { - RenderBoxFragmentInfo* boxInfo = renderBox.renderBoxFragmentInfo(cbFragment); - if (boxInfo) { - logicalTopPos += boxInfo->logicalLeft(); - computedValues.m_position = logicalTopPos; + if (fragmentedFlow && isHorizontalWritingMode() != containerBlock.isHorizontalWritingMode()) { + if (CheckedPtr renderBox = dynamicDowncast(containerBlock)) { + ASSERT(containerBlock.canHaveBoxInfoInFragment()); + LayoutUnit logicalTopPos = computedValues.m_position; + LayoutUnit cbPageOffset = renderBox->offsetFromLogicalTopOfFirstPage() - logicalLeft(); + RenderFragmentContainer* cbFragment = renderBox->fragmentAtBlockOffset(cbPageOffset); + if (cbFragment) { + RenderBoxFragmentInfo* boxInfo = renderBox->renderBoxFragmentInfo(cbFragment); + if (boxInfo) { + logicalTopPos += boxInfo->logicalLeft(); + computedValues.m_position = logicalTopPos; + } } } } @@ -5004,9 +5025,9 @@ VisiblePosition RenderBox::positionForPoint(const LayoutPoint& point, const Rend adjustedPoint.moveBy(location()); for (auto& renderer : childrenOfType(*this)) { - if (is(*this)) { + if (CheckedPtr fragmentedFlow = dynamicDowncast(*this)) { ASSERT(fragment); - if (!downcast(*this).objectShouldFragmentInFlowFragment(&renderer, fragment)) + if (!fragmentedFlow->objectShouldFragmentInFlowFragment(&renderer, fragment)) continue; } diff --git a/Source/WebCore/rendering/RenderBox.h b/Source/WebCore/rendering/RenderBox.h index 1564dd6861ec9..ed4310d25032b 100644 --- a/Source/WebCore/rendering/RenderBox.h +++ b/Source/WebCore/rendering/RenderBox.h @@ -813,8 +813,8 @@ class RenderBox : public RenderBoxModelObject { inline RenderBox* RenderBox::parentBox() const { - if (is(parent())) - return downcast(parent()); + if (auto* box = dynamicDowncast(parent())) + return box; ASSERT(!parent()); return nullptr; @@ -822,8 +822,8 @@ inline RenderBox* RenderBox::parentBox() const inline RenderBox* RenderBox::firstChildBox() const { - if (is(firstChild())) - return downcast(firstChild()); + if (auto* box = dynamicDowncast(firstChild())) + return box; ASSERT(!firstChild()); return nullptr; @@ -836,8 +836,8 @@ inline RenderBox* RenderBox::firstInFlowChildBox() const inline RenderBox* RenderBox::lastChildBox() const { - if (is(lastChild())) - return downcast(lastChild()); + if (auto* box = dynamicDowncast(lastChild())) + return box; ASSERT(!lastChild()); return nullptr; @@ -850,8 +850,8 @@ inline RenderBox* RenderBox::lastInFlowChildBox() const inline RenderBox* RenderBox::previousSiblingBox() const { - if (is(previousSibling())) - return downcast(previousSibling()); + if (auto* box = dynamicDowncast(previousSibling())) + return box; ASSERT(!previousSibling()); return nullptr; @@ -868,8 +868,8 @@ inline RenderBox* RenderBox::previousInFlowSiblingBox() const inline RenderBox* RenderBox::nextSiblingBox() const { - if (is(nextSibling())) - return downcast(nextSibling()); + if (auto* box = dynamicDowncast(nextSibling())) + return box; ASSERT(!nextSibling()); return nullptr; diff --git a/Source/WebCore/rendering/RenderBoxModelObject.cpp b/Source/WebCore/rendering/RenderBoxModelObject.cpp index 578b38d3d2a38..6edf90453482f 100644 --- a/Source/WebCore/rendering/RenderBoxModelObject.cpp +++ b/Source/WebCore/rendering/RenderBoxModelObject.cpp @@ -225,9 +225,12 @@ static LayoutSize accumulateInFlowPositionOffsets(const RenderObject* child) if (!child->isAnonymousBlock() || !child->isInFlowPositioned()) return LayoutSize(); LayoutSize offset; - for (RenderElement* parent = downcast(*child).inlineContinuation(); is(parent); parent = parent->parent()) { + for (RenderElement* parent = downcast(*child).inlineContinuation(); parent; parent = parent->parent()) { + auto* parentRenderInline = dynamicDowncast(*parent); + if (!parentRenderInline) + break; if (parent->isInFlowPositioned()) - offset += downcast(*parent).offsetForInFlowPosition(); + offset += parentRenderInline->offsetForInFlowPosition(); } return offset; } @@ -547,8 +550,8 @@ void RenderBoxModelObject::computeStickyPositionConstraints(StickyPositionViewpo // have already done a similar call to move from the containing block to the scrolling // ancestor above, but localToContainerQuad takes care of a lot of complex situations // involving inlines, tables, and transformations. - if (parent()->isRenderBox()) - downcast(parent())->flipForWritingMode(stickyBoxRect); + if (CheckedPtr parentBox = dynamicDowncast(*parent())) + parentBox->flipForWritingMode(stickyBoxRect); auto stickyBoxRelativeToScrollingAncestor = parent()->localToContainerQuad(FloatRect(stickyBoxRect), &enclosingClippingBox, { } /* ignore transforms */).boundingBox(); if (enclosingClippingLayer) { diff --git a/Source/WebCore/rendering/RenderButton.cpp b/Source/WebCore/rendering/RenderButton.cpp index 406d4cd25c471..4d9492b74168e 100644 --- a/Source/WebCore/rendering/RenderButton.cpp +++ b/Source/WebCore/rendering/RenderButton.cpp @@ -101,9 +101,8 @@ void RenderButton::updateAnonymousChildStyle(RenderStyle& childStyle) const void RenderButton::updateFromElement() { // If we're an input element, we may need to change our button text. - if (is(formControlElement())) { - HTMLInputElement& input = downcast(formControlElement()); - String value = input.valueWithDefault(); + if (RefPtr input = dynamicDowncast(formControlElement())) { + String value = input->valueWithDefault(); setText(value); } } diff --git a/Source/WebCore/rendering/RenderCounter.cpp b/Source/WebCore/rendering/RenderCounter.cpp index 9e09963da9381..3f108d110dee4 100644 --- a/Source/WebCore/rendering/RenderCounter.cpp +++ b/Source/WebCore/rendering/RenderCounter.cpp @@ -61,7 +61,8 @@ static CounterMaps& counterMaps() static Element* ancestorStyleContainmentObject(const Element& element) { - Element* ancestor = is(element) ? downcast(element).hostElement() : element.parentElement(); + auto* pseudoElement = dynamicDowncast(element); + Element* ancestor = pseudoElement ? pseudoElement->hostElement() : element.parentElement(); while (ancestor) { if (auto* style = ancestor->existingComputedStyle()) { if (style->containsStyle()) @@ -118,8 +119,8 @@ static Element* previousSiblingOrParentElement(const Element& element) return previous; } - if (is(element)) { - auto* hostElement = downcast(element).hostElement(); + if (auto* pseudoElement = dynamicDowncast(element)) { + auto* hostElement = pseudoElement->hostElement(); ASSERT(hostElement); if (hostElement->renderer()) return hostElement; @@ -163,20 +164,18 @@ static RenderElement* nextInPreOrder(const RenderElement& renderer, const Elemen static CounterDirectives listItemCounterDirectives(RenderElement& renderer) { - if (is(renderer)) { - auto& item = downcast(renderer); + if (auto* item = dynamicDowncast(renderer)) { return { .resetValue = std::nullopt, - .incrementValue = item.isInReversedOrderedList() ? -1 : 1, + .incrementValue = item->isInReversedOrderedList() ? -1 : 1, .setValue = std::nullopt }; } if (auto element = renderer.element()) { - if (is(*element)) { - auto& list = downcast(*element); + if (auto* list = dynamicDowncast(*element)) { return { - .resetValue = list.start(), - .incrementValue = list.isReversed() ? 1 : -1, + .resetValue = list->start(), + .incrementValue = list->isReversed() ? 1 : -1, .setValue = std::nullopt }; } @@ -617,14 +616,15 @@ void showCounterRendererTree(const WebCore::RenderObject* renderer, const char* auto identifier = AtomString::fromLatin1(counterName); for (auto* current = root; current; current = current->nextInPreOrder()) { - if (!is(*current)) + auto* element = dynamicDowncast(*current); + if (!element) continue; fprintf(stderr, "%c", (current == renderer) ? '*' : ' '); for (auto* ancestor = current; ancestor && ancestor != root; ancestor = ancestor->parent()) fprintf(stderr, " "); fprintf(stderr, "%p N:%p P:%p PS:%p NS:%p C:%p\n", current, current->node(), current->parent(), current->previousSibling(), - current->nextSibling(), downcast(*current).hasCounterNodeMap() ? + current->nextSibling(), element->hasCounterNodeMap() ? counterName ? WebCore::counterMaps().find(*downcast(current))->value->get(identifier) : (WebCore::CounterNode*)1 : (WebCore::CounterNode*)0); } fflush(stderr); diff --git a/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp b/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp index 0eb548851f4d0..738874b04ffb2 100644 --- a/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp +++ b/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp @@ -1014,8 +1014,8 @@ static std::optional getHeightForLineCount(const RenderBlockFlow& bl RenderBox* normalFlowChildWithoutLines = nullptr; for (auto* obj = block.firstChildBox(); obj; obj = obj->nextSiblingBox()) { - if (is(*obj) && shouldIncludeLinesForParentLineCount(downcast(*obj))) { - if (auto height = getHeightForLineCount(downcast(*obj), lineCount, false, count)) + if (auto* blockFlow = dynamicDowncast(*obj); blockFlow && shouldIncludeLinesForParentLineCount(*blockFlow)) { + if (auto height = getHeightForLineCount(*blockFlow, lineCount, false, count)) return *height + obj->y() + (includeBottom ? (block.borderBottom() + block.paddingBottom()) : 0_lu); } else if (!obj->isFloatingOrOutOfFlowPositioned()) normalFlowChildWithoutLines = obj; @@ -1080,8 +1080,8 @@ std::optional RenderDeprecatedFlexi continue; child->layoutIfNeeded(); - if (is(*child)) - numberOfLines += lineCountFor(downcast(*child)); + if (auto* blockFlow = dynamicDowncast(*child)) + numberOfLines += lineCountFor(*blockFlow); // FIXME: This should be turned into a partial damange. child->setChildNeedsLayout(MarkOnlyThis); } @@ -1116,9 +1116,9 @@ std::optional RenderDeprecatedFlexi child->setChildNeedsLayout(MarkOnlyThis); // Dirty all the positioned objects. - if (is(*child)) { - downcast(*child).markPositionedObjectsForLayout(); - clearTruncation(downcast(*child)); + if (CheckedPtr blockFlow = dynamicDowncast(*child)) { + blockFlow->markPositionedObjectsForLayout(); + clearTruncation(*blockFlow); } } } @@ -1132,8 +1132,10 @@ std::optional RenderDeprecatedFlexi continue; child->layoutIfNeeded(); - if (child->style().height().isAuto() && is(*child)) - maxLineCount = std::max(maxLineCount, lineCountFor(downcast(*child))); + if (child->style().height().isAuto()) { + if (auto* blockFlow = dynamicDowncast(*child)) + maxLineCount = std::max(maxLineCount, lineCountFor(*blockFlow)); + } } // Get the number of lines and then alter all block flow children with auto height to use the @@ -1150,15 +1152,18 @@ std::optional RenderDeprecatedFlexi return { }; for (RenderBox* child = iterator.first(); child; child = iterator.next()) { - if (childDoesNotAffectWidthOrFlexing(child) || !child->style().height().isAuto() || !is(*child)) + if (childDoesNotAffectWidthOrFlexing(child) || !child->style().height().isAuto()) + continue; + + CheckedPtr blockChild = dynamicDowncast(*child); + if (!blockChild) continue; - RenderBlockFlow& blockChild = downcast(*child); - auto lineCount = lineCountFor(blockChild); + auto lineCount = lineCountFor(*blockChild); if (lineCount <= numVisibleLines) continue; - auto newHeight = heightForLineCount(blockChild, numVisibleLines).value_or(0); + auto newHeight = heightForLineCount(*blockChild, numVisibleLines).value_or(0); if (newHeight == child->height()) continue; @@ -1171,11 +1176,11 @@ std::optional RenderDeprecatedFlexi continue; // Get the last line - LegacyRootInlineBox* lastLine = lineAtIndex(blockChild, lineCount - 1); + LegacyRootInlineBox* lastLine = lineAtIndex(*blockChild, lineCount - 1); if (!lastLine) continue; - LegacyRootInlineBox* lastVisibleLine = lineAtIndex(blockChild, numVisibleLines - 1); + LegacyRootInlineBox* lastVisibleLine = lineAtIndex(*blockChild, numVisibleLines - 1); if (!lastVisibleLine || !lastVisibleLine->firstChild()) continue; @@ -1237,9 +1242,9 @@ void RenderDeprecatedFlexibleBox::clearLineClamp() || (child->style().height().isAuto() && is(*child))) { child->setChildNeedsLayout(); - if (is(*child)) { - downcast(*child).markPositionedObjectsForLayout(); - clearTruncation(downcast(*child)); + if (CheckedPtr blockFlow = dynamicDowncast(*child)) { + blockFlow->markPositionedObjectsForLayout(); + clearTruncation(*blockFlow); } } } diff --git a/Source/WebCore/rendering/RenderDetailsMarker.cpp b/Source/WebCore/rendering/RenderDetailsMarker.cpp index d05f461053537..fe4aeee1eb0e3 100644 --- a/Source/WebCore/rendering/RenderDetailsMarker.cpp +++ b/Source/WebCore/rendering/RenderDetailsMarker.cpp @@ -148,8 +148,8 @@ bool RenderDetailsMarker::isOpen() const for (RenderObject* renderer = parent(); renderer; renderer = renderer->parent()) { if (!renderer->node()) continue; - if (is(*renderer->node())) - return !downcast(*renderer->node()).attributeWithoutSynchronization(openAttr).isNull(); + if (auto* details = dynamicDowncast(*renderer->node())) + return !details->attributeWithoutSynchronization(openAttr).isNull(); if (is(*renderer->node())) return true; } diff --git a/Source/WebCore/rendering/RenderElement.cpp b/Source/WebCore/rendering/RenderElement.cpp index cceafbeaf8d28..bc2eee9d19181 100644 --- a/Source/WebCore/rendering/RenderElement.cpp +++ b/Source/WebCore/rendering/RenderElement.cpp @@ -317,9 +317,11 @@ StyleDifference RenderElement::adjustStyleDifference(StyleDifference diff, Optio // The answer to requiresLayer() for plugins, iframes, and canvas can change without the actual // style changing, since it depends on whether we decide to composite these elements. When the // layer status of one of these elements changes, we need to force a layout. - if (diff < StyleDifference::Layout && isRenderLayerModelObject()) { - if (hasLayer() != downcast(*this).requiresLayer()) - diff = StyleDifference::Layout; + if (diff < StyleDifference::Layout) { + if (auto* modelObject = dynamicDowncast(*this)) { + if (hasLayer() != modelObject->requiresLayer()) + diff = StyleDifference::Layout; + } } // If we have no layer(), just treat a RepaintLayer hint as a normal Repaint. @@ -440,9 +442,9 @@ bool RenderElement::repaintBeforeStyleChange(StyleDifference diff, const RenderS if (newStyle.outlineSize() < oldStyle.outlineSize()) return RequiredRepaint::RendererOnly; - if (is(*this)) { + if (auto* modelObject = dynamicDowncast(*this)) { // 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. - bool hasLayer = downcast(*this).hasLayer(); + bool hasLayer = modelObject->hasLayer(); bool willHaveLayer = newStyle.affectsTransform() || newStyle.hasOpacity() || newStyle.hasFilter() || newStyle.hasBackdropFilter(); if (!hasLayer && willHaveLayer) return RequiredRepaint::RendererOnly; @@ -556,8 +558,8 @@ void RenderElement::setStyle(RenderStyle&& style, StyleDifference minimalStyleDi void RenderElement::didAttachChild(RenderObject& child, RenderObject*) { - if (is(child)) - downcast(child).styleDidChange(StyleDifference::Equal, nullptr); + if (CheckedPtr textRenderer = dynamicDowncast(child)) + textRenderer->styleDidChange(StyleDifference::Equal, nullptr); // The following only applies to the legacy SVG engine -- LBSE always creates layers // independant of the position in the render tree, see comment in layerCreationAllowedForSubtree(). @@ -633,9 +635,10 @@ static RenderLayer* findNextLayer(const RenderElement& currRenderer, const Rende // into our siblings trying to find the next layer whose parent is the desired parent. if (!ourLayer || ourLayer == &parentLayer) { for (auto* child = siblingToTraverseFrom ? siblingToTraverseFrom->nextSibling() : currRenderer.firstChild(); child; child = child->nextSibling()) { - if (!is(*child)) + auto* element = dynamicDowncast(*child); + if (!element) continue; - if (auto* nextLayer = findNextLayer(downcast(*child), parentLayer, nullptr, false)) + if (auto* nextLayer = findNextLayer(*element, parentLayer, nullptr, false)) return nextLayer; } } @@ -657,11 +660,10 @@ static RenderLayer* layerNextSiblingRespectingTopLayer(const RenderElement& rend { ASSERT_IMPLIES(isInTopLayerOrBackdrop(renderer.style(), renderer.element()), renderer.hasLayer()); - if (is(renderer) && isInTopLayerOrBackdrop(renderer.style(), renderer.element())) { - auto& layerModelObject = downcast(renderer); - ASSERT(layerModelObject.hasLayer()); + if (auto* layerModelObject = dynamicDowncast(renderer); layerModelObject && isInTopLayerOrBackdrop(renderer.style(), renderer.element())) { + ASSERT(layerModelObject->hasLayer()); auto topLayerLayers = RenderLayer::topLayerRenderLayers(renderer.view()); - auto layerIndex = topLayerLayers.find(layerModelObject.layer()); + auto layerIndex = topLayerLayers.find(layerModelObject->layer()); if (layerIndex != notFound && layerIndex < topLayerLayers.size() - 1) return topLayerLayers[layerIndex + 1]; @@ -1373,11 +1375,11 @@ bool RenderElement::repaintAfterLayoutIfNeeded(const RenderLayerModelObject* rep auto insetExtent = [&] { // Inset "content" is inside the border box (e.g. border, negative outline and box shadow). auto borderRightExtent = [&]() -> LayoutUnit { - if (!is(*this)) + auto* renderBox = dynamicDowncast(*this); + if (!renderBox) return { }; - auto& renderBox = downcast(*this); - auto borderBoxWidth = renderBox.width(); - return std::max(renderBox.borderRight(), std::max(valueForLength(style.borderTopRightRadius().width, borderBoxWidth), valueForLength(style.borderBottomRightRadius().width, borderBoxWidth))); + auto borderBoxWidth = renderBox->width(); + return std::max(renderBox->borderRight(), std::max(valueForLength(style.borderTopRightRadius().width, borderBoxWidth), valueForLength(style.borderBottomRightRadius().width, borderBoxWidth))); }; auto outlineRightInsetExtent = [&]() -> LayoutUnit { auto offset = LayoutUnit { outlineStyle.outlineOffset() }; @@ -1415,11 +1417,11 @@ bool RenderElement::repaintAfterLayoutIfNeeded(const RenderLayerModelObject* rep auto insetExtent = [&] { // Inset "content" is inside the border box (e.g. border, negative outline and box shadow). auto borderBottomExtent = [&]() -> LayoutUnit { - if (!is(*this)) + auto* renderBox = dynamicDowncast(*this); + if (!renderBox) return { }; - auto& renderBox = downcast(*this); - auto borderBoxHeight = renderBox.height(); - return std::max(renderBox.borderBottom(), std::max(valueForLength(style.borderBottomLeftRadius().height, borderBoxHeight), valueForLength(style.borderBottomRightRadius().height, borderBoxHeight))); + auto borderBoxHeight = renderBox->height(); + return std::max(renderBox->borderBottom(), std::max(valueForLength(style.borderBottomLeftRadius().height, borderBoxHeight), valueForLength(style.borderBottomRightRadius().height, borderBoxHeight))); }; auto outlineBottomInsetExtent = [&]() -> LayoutUnit { auto offset = LayoutUnit { outlineStyle.outlineOffset() }; @@ -1621,8 +1623,8 @@ bool RenderElement::repaintForPausedImageAnimationsIfNeeded(const IntRect& visib } // For directly-composited animated GIFs it does not suffice to call repaint() to resume animation. We need to mark the image as changed. - if (is(*this)) - downcast(*this).contentChanged(ImageChanged); + if (CheckedPtr modelObject = dynamicDowncast(*this)) + modelObject->contentChanged(ImageChanged); return true; } @@ -1820,12 +1822,11 @@ bool RenderElement::getLeadingCorner(FloatPoint& point, bool& insideFixed) const // do nothing - skip unrendered whitespace that is a child or next sibling of the anchor } else if (is(*o) || o->isReplacedOrInlineBlock()) { point = FloatPoint(); - if (is(*o)) { - auto& textRenderer = downcast(*o); - if (auto run = InlineIterator::firstTextBoxFor(textRenderer)) - point.move(textRenderer.linesBoundingBox().x(), run->lineBox()->contentLogicalTop()); - } else if (is(*o)) - point.moveBy(downcast(*o).location()); + if (CheckedPtr textRenderer = dynamicDowncast(*o)) { + if (auto run = InlineIterator::firstTextBoxFor(*textRenderer)) + point.move(textRenderer->linesBoundingBox().x(), run->lineBox()->contentLogicalTop()); + } else if (auto* box = dynamicDowncast(*o)) + point.moveBy(box->location()); point = o->container()->localToAbsolute(point, UseTransforms, &insideFixed); return true; } @@ -1867,8 +1868,8 @@ bool RenderElement::getTrailingCorner(FloatPoint& point, bool& insideFixed) cons ASSERT(o); if (is(*o) || o->isReplacedOrInlineBlock()) { point = FloatPoint(); - if (is(*o)) { - LayoutRect linesBox = downcast(*o).linesBoundingBox(); + if (auto* textRenderer = dynamicDowncast(*o)) { + LayoutRect linesBox = textRenderer->linesBoundingBox(); if (!linesBox.maxX() && !linesBox.maxY()) continue; point.moveBy(linesBox.maxXMaxYCorner()); @@ -2010,8 +2011,8 @@ void RenderElement::issueRepaintForOutlineAuto(float outlineSize) void RenderElement::updateOutlineAutoAncestor(bool hasOutlineAuto) { - if (is(*this)) { - CheckedPtr spanner = downcast(*this).spanner(); + if (auto* placeholder = dynamicDowncast(*this)) { + CheckedPtr spanner = placeholder->spanner(); spanner->setHasOutlineAutoAncestor(hasOutlineAuto); spanner->updateOutlineAutoAncestor(hasOutlineAuto); } @@ -2023,12 +2024,11 @@ void RenderElement::updateOutlineAutoAncestor(bool hasOutlineAuto) bool childHasOutlineAuto = child->outlineStyleForRepaint().outlineStyleIsAuto() == OutlineIsAuto::On; if (childHasOutlineAuto) continue; - if (!is(child.get())) - continue; - downcast(child.get()).updateOutlineAutoAncestor(hasOutlineAuto); + if (auto* element = dynamicDowncast(child.get())) + element->updateOutlineAutoAncestor(hasOutlineAuto); } - if (is(*this)) { - if (CheckedPtr continuation = downcast(*this).continuation()) + if (auto* modelObject = dynamicDowncast(*this)) { + if (CheckedPtr continuation = modelObject->continuation()) continuation->updateOutlineAutoAncestor(hasOutlineAuto); } } @@ -2075,8 +2075,8 @@ void RenderElement::adjustFragmentedFlowStateOnContainingBlockChangeIfNeeded(con return; // Invalidate the containing block caches. - if (is(*this)) - downcast(*this).resetEnclosingFragmentedFlowAndChildInfoIncludingDescendants(); + if (CheckedPtr block = dynamicDowncast(*this)) + block->resetEnclosingFragmentedFlowAndChildInfoIncludingDescendants(); else { // Relatively positioned inline boxes can have absolutely positioned block descendants. We need to reset them as well. for (CheckedRef descendant : descendantsOfType(*this)) @@ -2107,8 +2107,8 @@ void RenderElement::removeFromRenderFragmentedFlowIncludingDescendants(bool shou shouldUpdateState = false; for (CheckedRef child : childrenOfType(*this)) { - if (is(child.get())) { - downcast(child.get()).removeFromRenderFragmentedFlowIncludingDescendants(shouldUpdateState); + if (auto* element = dynamicDowncast(child.get())) { + element->removeFromRenderFragmentedFlowIncludingDescendants(shouldUpdateState); continue; } if (shouldUpdateState) @@ -2127,8 +2127,8 @@ void RenderElement::removeFromRenderFragmentedFlowIncludingDescendants(bool shou break; enclosingFragmentedFlow = parent->enclosingFragmentedFlow(); } - if (is(*this)) - downcast(*this).setCachedEnclosingFragmentedFlowNeedsUpdate(); + if (CheckedPtr block = dynamicDowncast(*this)) + block->setCachedEnclosingFragmentedFlowNeedsUpdate(); if (shouldUpdateState) setFragmentedFlowState(FragmentedFlowState::NotInsideFlow); @@ -2198,11 +2198,10 @@ static RenderObject::BlockContentHeightType includeNonFixedHeight(const RenderOb { const RenderStyle& style = renderer.style(); if (style.height().isFixed()) { - if (is(renderer)) { + if (CheckedPtr block = dynamicDowncast(renderer)) { // For fixed height styles, if the overflow size of the element spills out of the specified // height, assume we can apply text auto-sizing. - if (downcast(renderer).effectiveOverflowY() == Overflow::Visible - && style.height().value() < downcast(renderer).layoutOverflowRect().maxY()) + if (block->effectiveOverflowY() == Overflow::Visible && style.height().value() < block->layoutOverflowRect().maxY()) return RenderObject::OverflowHeight; } return RenderObject::FixedHeight; @@ -2231,8 +2230,8 @@ void RenderElement::adjustComputedFontSizesOnBlocks(float size, float visibleWid depthStack.append(newFixedDepth); int stackSize = depthStack.size(); - if (is(*descendant) && !descendant->isRenderListItem() && (!stackSize || currentDepth - depthStack[stackSize - 1] > TextAutoSizingFixedHeightDepth)) - downcast(*descendant).adjustComputedFontSizes(size, visibleWidth); + if (CheckedPtr blockFlow = dynamicDowncast(*descendant); blockFlow && !blockFlow->isRenderListItem() && (!stackSize || currentDepth - depthStack[stackSize - 1] > TextAutoSizingFixedHeightDepth)) + blockFlow->adjustComputedFontSizes(size, visibleWidth); newFixedDepth = 0; } @@ -2261,8 +2260,8 @@ void RenderElement::resetTextAutosizing() depthStack.append(newFixedDepth); int stackSize = depthStack.size(); - if (is(*descendant) && !descendant->isRenderListItem() && (!stackSize || currentDepth - depthStack[stackSize - 1] > TextAutoSizingFixedHeightDepth)) - downcast(*descendant).resetComputedFontSize(); + if (CheckedPtr blockFlow = dynamicDowncast(*descendant); blockFlow && !blockFlow->isRenderListItem() && (!stackSize || currentDepth - depthStack[stackSize - 1] > TextAutoSizingFixedHeightDepth)) + blockFlow->resetComputedFontSize(); newFixedDepth = 0; } } @@ -2367,7 +2366,6 @@ FloatRect RenderElement::referenceBoxRect(CSSBoxType boxType) const #if ENABLE(LAYER_BASED_SVG_ENGINE) // RenderSVGViewportContainer is the only possible anonymous renderer in the SVG tree. if (!viewportElement && document().settings().layerBasedSVGEngineEnabled()) { - ASSERT(is(this)); ASSERT(isAnonymous()); viewportElement = &downcast(*this).svgSVGElement(); }