Skip to content

Commit

Permalink
Reduce use of downcast<>() in WebCore
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=266679

Reviewed by Simon Fraser.

* Source/WebCore/rendering/updating/RenderTreeBuilderMultiColumn.cpp:
(WebCore::isValidColumnSpanner):
(WebCore::RenderTreeBuilder::MultiColumn::createFragmentedFlow):
(WebCore::RenderTreeBuilder::MultiColumn::resolveMovedChild):
(WebCore::RenderTreeBuilder::MultiColumn::multiColumnDescendantInserted):
(WebCore::RenderTreeBuilder::MultiColumn::processPossibleSpannerDescendant):
(WebCore::RenderTreeBuilder::MultiColumn::multiColumnRelativeWillBeRemoved):
(WebCore::RenderTreeBuilder::MultiColumn::adjustBeforeChildForMultiColumnSpannerIfNeeded):
* Source/WebCore/rendering/updating/RenderTreeBuilderRuby.cpp:
(WebCore::RenderTreeBuilder::Ruby::detach):
* Source/WebCore/rendering/updating/RenderTreeBuilderTable.cpp:
(WebCore::RenderTreeBuilder::Table::findOrCreateParentForChild):
(WebCore::RenderTreeBuilder::Table::attach):
(WebCore::RenderTreeBuilder::Table::childRequiresTable):
* Source/WebCore/rendering/updating/RenderTreePosition.cpp:
(WebCore::RenderTreePosition::nextSiblingRenderer const):
* Source/WebCore/rendering/updating/RenderTreeUpdater.cpp:
(WebCore::RenderTreeUpdater::updateRebuildRoots):
(WebCore::RenderTreeUpdater::updateRenderTree):
(WebCore::RenderTreeUpdater::tearDownRenderers):
(WebCore::RenderTreeUpdater::tearDownLeftoverChildrenOfComposedTree):
* Source/WebCore/rendering/updating/RenderTreeUpdaterGeneratedContent.cpp:
(WebCore::elementIsTargetedByKeyframeEffectRequiringPseudoElement):
* Source/WebCore/style/ElementRuleCollector.cpp:
(WebCore::Style::ElementRuleCollector::matchAllRules):
(WebCore::Style::ElementRuleCollector::addElementInlineStyleProperties):
* Source/WebCore/style/FilterOperationsBuilder.cpp:
(WebCore::Style::createFilterOperations):
* Source/WebCore/style/InlineTextBoxStyle.cpp:
(WebCore::minLogicalTopForTextDecorationLineUnder):
(WebCore::maxLogicalBottomForTextDecorationLineUnder):
* Source/WebCore/style/InspectorCSSOMWrappers.cpp:
(WebCore::Style::InspectorCSSOMWrappers::collect):
* Source/WebCore/style/RuleSetBuilder.cpp:
(WebCore::Style::RuleSetBuilder::addChildRule):
(WebCore::Style::RuleSetBuilder::addMutatingRulesToResolver):
* Source/WebCore/style/StyleAdjuster.cpp:
(WebCore::Style::Adjuster::computeEventListenerRegionTypes):
* Source/WebCore/style/StyleInvalidator.cpp:
(WebCore::Style::invalidateAssignedElements):
* Source/WebCore/style/StyleSharingResolver.cpp:
(WebCore::Style::SharingResolver::findSibling const):

Canonical link: https://commits.webkit.org/272366@main
  • Loading branch information
cdumez committed Dec 20, 2023
1 parent bdc9ba2 commit b541bbc
Show file tree
Hide file tree
Showing 14 changed files with 173 additions and 176 deletions.
62 changes: 31 additions & 31 deletions Source/WebCore/rendering/updating/RenderTreeBuilderMultiColumn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,29 +77,29 @@ static bool isValidColumnSpanner(const RenderMultiColumnFlow& fragmentedFlow, co
// We assume that we're inside the flow thread. This function is not to be called otherwise.
ASSERT(descendant.isDescendantOf(&fragmentedFlow));
// First make sure that the renderer itself has the right properties for becoming a spanner.
if (!is<RenderBox>(descendant))
auto* descendantBox = dynamicDowncast<RenderBox>(descendant);
if (!descendantBox)
return false;

auto& descendantBox = downcast<RenderBox>(descendant);
if (descendantBox.isFloatingOrOutOfFlowPositioned())
if (descendantBox->isFloatingOrOutOfFlowPositioned())
return false;

if (descendantBox.style().columnSpan() != ColumnSpan::All)
if (descendantBox->style().columnSpan() != ColumnSpan::All)
return false;

auto* parent = descendantBox.parent();
auto* parent = descendantBox->parent();
if (!is<RenderBlockFlow>(*parent) || parent->childrenInline()) {
// Needs to be block-level.
return false;
}

// We need to have the flow thread as the containing block. A spanner cannot break out of the flow thread.
auto* enclosingFragmentedFlow = descendantBox.enclosingFragmentedFlow();
auto* enclosingFragmentedFlow = descendantBox->enclosingFragmentedFlow();
if (enclosingFragmentedFlow != &fragmentedFlow)
return false;

// This looks like a spanner, but if we're inside something unbreakable, it's not to be treated as one.
for (auto* ancestor = descendantBox.containingBlock(); ancestor; ancestor = ancestor->containingBlock()) {
for (auto* ancestor = descendantBox->containingBlock(); ancestor; ancestor = ancestor->containingBlock()) {
if (is<RenderView>(*ancestor))
return false;
if (ancestor->isLegend())
Expand All @@ -112,13 +112,12 @@ static bool isValidColumnSpanner(const RenderMultiColumnFlow& fragmentedFlow, co
// implement (not to mention specify behavior).
return ancestor == &fragmentedFlow;
}
if (is<RenderBlockFlow>(*ancestor)) {
auto& blockFlowAncestor = downcast<RenderBlockFlow>(*ancestor);
if (blockFlowAncestor.willCreateColumns()) {
if (auto* blockFlowAncestor = dynamicDowncast<RenderBlockFlow>(*ancestor)) {
if (blockFlowAncestor->willCreateColumns()) {
// This ancestor (descendent of the fragmentedFlow) will create columns later. The spanner belongs to it.
return false;
}
if (blockFlowAncestor.multiColumnFlow()) {
if (blockFlowAncestor->multiColumnFlow()) {
// While this ancestor (descendent of the fragmentedFlow) has a fragmented flow context, this context is being destroyed.
// However the spanner still belongs to it (will most likely be moved to the parent fragmented context as the next step).
return false;
Expand Down Expand Up @@ -158,8 +157,8 @@ void RenderTreeBuilder::MultiColumn::createFragmentedFlow(RenderBlockFlow& flow)
flow.deleteLines();
// If this soon-to-be multicolumn flow is already part of a multicolumn context, we need to move back the descendant spanners
// to their original position before moving subtrees around.
if (auto* enclosingflow = flow.enclosingFragmentedFlow(); is<RenderMultiColumnFlow>(enclosingflow))
restoreColumnSpannersForContainer(flow, downcast<RenderMultiColumnFlow>(*enclosingflow));
if (auto* enclosingflow = dynamicDowncast<RenderMultiColumnFlow>(flow.enclosingFragmentedFlow()))
restoreColumnSpannersForContainer(flow, *enclosingflow);

auto newFragmentedFlow = WebCore::createRenderer<RenderMultiColumnFlow>(flow.document(), RenderStyle::createAnonymousStyleWithDisplay(flow.style(), DisplayType::Block));
newFragmentedFlow->initializeStyle();
Expand Down Expand Up @@ -256,7 +255,8 @@ RenderObject* RenderTreeBuilder::MultiColumn::resolveMovedChild(RenderFragmented
if (!is<RenderBox>(*beforeChild))
return beforeChild;

if (!is<RenderMultiColumnFlow>(enclosingFragmentedFlow))
auto* renderMultiColumnFlow = dynamicDowncast<RenderMultiColumnFlow>(enclosingFragmentedFlow);
if (!renderMultiColumnFlow)
return beforeChild;

// We only need to resolve for column spanners.
Expand All @@ -269,7 +269,7 @@ RenderObject* RenderTreeBuilder::MultiColumn::resolveMovedChild(RenderFragmented
// create and insert a renderer for the sibling node immediately preceding the spanner, we need
// to map that spanner renderer to the spanner's placeholder, which is where the new inserted
// renderer belongs.
if (auto* placeholder = downcast<RenderMultiColumnFlow>(enclosingFragmentedFlow).findColumnSpannerPlaceholder(downcast<RenderBox>(beforeChild)))
if (auto* placeholder = renderMultiColumnFlow->findColumnSpannerPlaceholder(downcast<RenderBox>(beforeChild)))
return placeholder;

// This is an invalid spanner, or its placeholder hasn't been created yet. This happens when
Expand All @@ -294,14 +294,13 @@ void RenderTreeBuilder::MultiColumn::multiColumnDescendantInserted(RenderMultiCo
descendant = descendant->nextSibling();
continue;
}
if (is<RenderMultiColumnSpannerPlaceholder>(*descendant)) {
if (auto* placeholder = dynamicDowncast<RenderMultiColumnSpannerPlaceholder>(*descendant)) {
// A spanner's placeholder has been inserted. The actual spanner renderer is moved from
// where it would otherwise occur (if it weren't a spanner) to becoming a sibling of the
// column sets.
RenderMultiColumnSpannerPlaceholder& placeholder = downcast<RenderMultiColumnSpannerPlaceholder>(*descendant);
ASSERT(!flow.spannerMap().get(placeholder.spanner()));
flow.spannerMap().add(placeholder.spanner(), downcast<RenderMultiColumnSpannerPlaceholder>(descendant));
ASSERT(!placeholder.firstChild()); // There should be no children here, but if there are, we ought to skip them.
ASSERT(!flow.spannerMap().get(placeholder->spanner()));
flow.spannerMap().add(placeholder->spanner(), placeholder);
ASSERT(!placeholder->firstChild()); // There should be no children here, but if there are, we ought to skip them.
} else
descendant = processPossibleSpannerDescendant(flow, subtreeRoot, *descendant);
if (descendant)
Expand Down Expand Up @@ -358,14 +357,13 @@ RenderObject* RenderTreeBuilder::MultiColumn::processPossibleSpannerDescendant(R
nextDescendant = &placeholder;
} else {
// This is regular multicol content, i.e. not part of a spanner.
if (is<RenderMultiColumnSpannerPlaceholder>(nextRendererInFragmentedFlow)) {
if (auto* placeholder = dynamicDowncast<RenderMultiColumnSpannerPlaceholder>(nextRendererInFragmentedFlow)) {
// Inserted right before a spanner. Is there a set for us there?
RenderMultiColumnSpannerPlaceholder& placeholder = downcast<RenderMultiColumnSpannerPlaceholder>(*nextRendererInFragmentedFlow);
if (RenderObject* previous = placeholder.spanner()->previousSibling()) {
if (RenderObject* previous = placeholder->spanner()->previousSibling()) {
if (is<RenderMultiColumnSet>(*previous))
return nextDescendant; // There's already a set there. Nothing to do.
}
insertBeforeMulticolChild = placeholder.spanner();
insertBeforeMulticolChild = placeholder->spanner();
} else if (RenderMultiColumnSet* lastSet = flow.lastMultiColumnSet()) {
// This child is not an immediate predecessor of a spanner, which means that if this
// child precedes a spanner at all, there has to be a column set created for us there
Expand Down Expand Up @@ -419,12 +417,12 @@ void RenderTreeBuilder::MultiColumn::handleSpannerRemoval(RenderMultiColumnFlow&
void RenderTreeBuilder::MultiColumn::multiColumnRelativeWillBeRemoved(RenderMultiColumnFlow& flow, RenderObject& relative, RenderTreeBuilder::CanCollapseAnonymousBlock canCollapseAnonymousBlock)
{
flow.invalidateFragments();
if (is<RenderMultiColumnSpannerPlaceholder>(relative)) {
if (auto* placeholder = dynamicDowncast<RenderMultiColumnSpannerPlaceholder>(relative)) {
// Remove the map entry for this spanner, but leave the actual spanner renderer alone. Also
// keep the reference to the spanner, since the placeholder may be about to be re-inserted
// in the tree.
ASSERT(relative.isDescendantOf(&flow));
flow.spannerMap().remove(downcast<RenderMultiColumnSpannerPlaceholder>(relative).spanner());
flow.spannerMap().remove(placeholder->spanner());
return;
}
if (relative.style().columnSpan() == ColumnSpan::All) {
Expand All @@ -440,21 +438,23 @@ void RenderTreeBuilder::MultiColumn::multiColumnRelativeWillBeRemoved(RenderMult

RenderObject* RenderTreeBuilder::MultiColumn::adjustBeforeChildForMultiColumnSpannerIfNeeded(RenderObject& beforeChild)
{
if (!is<RenderBox>(beforeChild))
auto* beforeChildBox = dynamicDowncast<RenderBox>(beforeChild);
if (!beforeChildBox)
return &beforeChild;

auto* nextSibling = beforeChild.nextSibling();
auto* nextSibling = beforeChildBox->nextSibling();
if (!nextSibling)
return &beforeChild;

if (!is<RenderMultiColumnSet>(*nextSibling))
auto* renderMultiColumnSet = dynamicDowncast<RenderMultiColumnSet>(*nextSibling);
if (!renderMultiColumnSet)
return &beforeChild;

auto* multiColumnFlow = downcast<RenderMultiColumnSet>(*nextSibling).multiColumnFlow();
auto* multiColumnFlow = renderMultiColumnSet->multiColumnFlow();
if (!multiColumnFlow)
return &beforeChild;

return multiColumnFlow->findColumnSpannerPlaceholder(downcast<RenderBox>(&beforeChild));
return multiColumnFlow->findColumnSpannerPlaceholder(beforeChildBox);
}

}
25 changes: 12 additions & 13 deletions Source/WebCore/rendering/updating/RenderTreeBuilderRuby.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,19 +369,18 @@ RenderPtr<RenderObject> RenderTreeBuilder::Ruby::detach(RenderRubyRun& parent, R
// If the child is a ruby text, then merge the ruby base with the base of
// the right sibling run, if possible.
if (!parent.beingDestroyed() && !parent.renderTreeBeingDestroyed() && child.isRenderRubyText()) {
RenderRubyBase* base = parent.rubyBase();
RenderObject* rightNeighbour = parent.nextSibling();
if (base && is<RenderRubyRun>(rightNeighbour)) {
// Ruby run without a base can happen only at the first run.
RenderRubyRun& rightRun = downcast<RenderRubyRun>(*rightNeighbour);
if (rightRun.hasRubyBase()) {
RenderRubyBase* rightBase = rightRun.rubyBase();
// Collect all children in a single base, then swap the bases.
moveChildren(*rightBase, *base);
m_builder.move(parent, rightRun, *base, RenderTreeBuilder::NormalizeAfterInsertion::No);
m_builder.move(rightRun, parent, *rightBase, RenderTreeBuilder::NormalizeAfterInsertion::No);
// The now empty ruby base will be removed below.
ASSERT(!parent.rubyBase()->firstChild());
if (auto* base = parent.rubyBase()) {
if (auto* rightRun = dynamicDowncast<RenderRubyRun>(parent.nextSibling())) {
// Ruby run without a base can happen only at the first run.
if (rightRun->hasRubyBase()) {
RenderRubyBase* rightBase = rightRun->rubyBase();
// Collect all children in a single base, then swap the bases.
moveChildren(*rightBase, *base);
m_builder.move(parent, *rightRun, *base, RenderTreeBuilder::NormalizeAfterInsertion::No);
m_builder.move(*rightRun, parent, *rightBase, RenderTreeBuilder::NormalizeAfterInsertion::No);
// The now empty ruby base will be removed below.
ASSERT(!parent.rubyBase()->firstChild());
}
}
}
}
Expand Down
Loading

0 comments on commit b541bbc

Please sign in to comment.