From b541bbcbd32a399a33f3a54b22e18f88ea307289 Mon Sep 17 00:00:00 2001 From: Chris Dumez Date: Wed, 20 Dec 2023 12:10:09 -0800 Subject: [PATCH] Reduce use of downcast<>() in WebCore 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 --- .../updating/RenderTreeBuilderMultiColumn.cpp | 62 ++++++++--------- .../updating/RenderTreeBuilderRuby.cpp | 25 ++++--- .../updating/RenderTreeBuilderTable.cpp | 67 +++++++++---------- .../rendering/updating/RenderTreePosition.cpp | 11 ++- .../rendering/updating/RenderTreeUpdater.cpp | 31 +++++---- .../RenderTreeUpdaterGeneratedContent.cpp | 4 +- Source/WebCore/style/ElementRuleCollector.cpp | 22 +++--- .../WebCore/style/FilterOperationsBuilder.cpp | 54 +++++++-------- Source/WebCore/style/InlineTextBoxStyle.cpp | 4 +- .../WebCore/style/InspectorCSSOMWrappers.cpp | 14 ++-- Source/WebCore/style/RuleSetBuilder.cpp | 40 +++++------ Source/WebCore/style/StyleAdjuster.cpp | 9 +-- Source/WebCore/style/StyleInvalidator.cpp | 2 +- Source/WebCore/style/StyleSharingResolver.cpp | 4 +- 14 files changed, 173 insertions(+), 176 deletions(-) diff --git a/Source/WebCore/rendering/updating/RenderTreeBuilderMultiColumn.cpp b/Source/WebCore/rendering/updating/RenderTreeBuilderMultiColumn.cpp index 07b16eead1df3..31e05f201040b 100644 --- a/Source/WebCore/rendering/updating/RenderTreeBuilderMultiColumn.cpp +++ b/Source/WebCore/rendering/updating/RenderTreeBuilderMultiColumn.cpp @@ -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(descendant)) + auto* descendantBox = dynamicDowncast(descendant); + if (!descendantBox) return false; - auto& descendantBox = downcast(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(*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(*ancestor)) return false; if (ancestor->isLegend()) @@ -112,13 +112,12 @@ static bool isValidColumnSpanner(const RenderMultiColumnFlow& fragmentedFlow, co // implement (not to mention specify behavior). return ancestor == &fragmentedFlow; } - if (is(*ancestor)) { - auto& blockFlowAncestor = downcast(*ancestor); - if (blockFlowAncestor.willCreateColumns()) { + if (auto* blockFlowAncestor = dynamicDowncast(*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; @@ -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(enclosingflow)) - restoreColumnSpannersForContainer(flow, downcast(*enclosingflow)); + if (auto* enclosingflow = dynamicDowncast(flow.enclosingFragmentedFlow())) + restoreColumnSpannersForContainer(flow, *enclosingflow); auto newFragmentedFlow = WebCore::createRenderer(flow.document(), RenderStyle::createAnonymousStyleWithDisplay(flow.style(), DisplayType::Block)); newFragmentedFlow->initializeStyle(); @@ -256,7 +255,8 @@ RenderObject* RenderTreeBuilder::MultiColumn::resolveMovedChild(RenderFragmented if (!is(*beforeChild)) return beforeChild; - if (!is(enclosingFragmentedFlow)) + auto* renderMultiColumnFlow = dynamicDowncast(enclosingFragmentedFlow); + if (!renderMultiColumnFlow) return beforeChild; // We only need to resolve for column spanners. @@ -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(enclosingFragmentedFlow).findColumnSpannerPlaceholder(downcast(beforeChild))) + if (auto* placeholder = renderMultiColumnFlow->findColumnSpannerPlaceholder(downcast(beforeChild))) return placeholder; // This is an invalid spanner, or its placeholder hasn't been created yet. This happens when @@ -294,14 +294,13 @@ void RenderTreeBuilder::MultiColumn::multiColumnDescendantInserted(RenderMultiCo descendant = descendant->nextSibling(); continue; } - if (is(*descendant)) { + if (auto* placeholder = dynamicDowncast(*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(*descendant); - ASSERT(!flow.spannerMap().get(placeholder.spanner())); - flow.spannerMap().add(placeholder.spanner(), downcast(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) @@ -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(nextRendererInFragmentedFlow)) { + if (auto* placeholder = dynamicDowncast(nextRendererInFragmentedFlow)) { // Inserted right before a spanner. Is there a set for us there? - RenderMultiColumnSpannerPlaceholder& placeholder = downcast(*nextRendererInFragmentedFlow); - if (RenderObject* previous = placeholder.spanner()->previousSibling()) { + if (RenderObject* previous = placeholder->spanner()->previousSibling()) { if (is(*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 @@ -419,12 +417,12 @@ void RenderTreeBuilder::MultiColumn::handleSpannerRemoval(RenderMultiColumnFlow& void RenderTreeBuilder::MultiColumn::multiColumnRelativeWillBeRemoved(RenderMultiColumnFlow& flow, RenderObject& relative, RenderTreeBuilder::CanCollapseAnonymousBlock canCollapseAnonymousBlock) { flow.invalidateFragments(); - if (is(relative)) { + if (auto* placeholder = dynamicDowncast(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(relative).spanner()); + flow.spannerMap().remove(placeholder->spanner()); return; } if (relative.style().columnSpan() == ColumnSpan::All) { @@ -440,21 +438,23 @@ void RenderTreeBuilder::MultiColumn::multiColumnRelativeWillBeRemoved(RenderMult RenderObject* RenderTreeBuilder::MultiColumn::adjustBeforeChildForMultiColumnSpannerIfNeeded(RenderObject& beforeChild) { - if (!is(beforeChild)) + auto* beforeChildBox = dynamicDowncast(beforeChild); + if (!beforeChildBox) return &beforeChild; - auto* nextSibling = beforeChild.nextSibling(); + auto* nextSibling = beforeChildBox->nextSibling(); if (!nextSibling) return &beforeChild; - if (!is(*nextSibling)) + auto* renderMultiColumnSet = dynamicDowncast(*nextSibling); + if (!renderMultiColumnSet) return &beforeChild; - auto* multiColumnFlow = downcast(*nextSibling).multiColumnFlow(); + auto* multiColumnFlow = renderMultiColumnSet->multiColumnFlow(); if (!multiColumnFlow) return &beforeChild; - return multiColumnFlow->findColumnSpannerPlaceholder(downcast(&beforeChild)); + return multiColumnFlow->findColumnSpannerPlaceholder(beforeChildBox); } } diff --git a/Source/WebCore/rendering/updating/RenderTreeBuilderRuby.cpp b/Source/WebCore/rendering/updating/RenderTreeBuilderRuby.cpp index 164da772c5a3c..62d8b68033239 100644 --- a/Source/WebCore/rendering/updating/RenderTreeBuilderRuby.cpp +++ b/Source/WebCore/rendering/updating/RenderTreeBuilderRuby.cpp @@ -369,19 +369,18 @@ RenderPtr 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(rightNeighbour)) { - // Ruby run without a base can happen only at the first run. - RenderRubyRun& rightRun = downcast(*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(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()); + } } } } diff --git a/Source/WebCore/rendering/updating/RenderTreeBuilderTable.cpp b/Source/WebCore/rendering/updating/RenderTreeBuilderTable.cpp index d93acce24acee..9f3bf5b059eab 100644 --- a/Source/WebCore/rendering/updating/RenderTreeBuilderTable.cpp +++ b/Source/WebCore/rendering/updating/RenderTreeBuilderTable.cpp @@ -46,9 +46,9 @@ RenderElement& RenderTreeBuilder::Table::findOrCreateParentForChild(RenderTableR if (beforeChild && !beforeChild->isAnonymous() && beforeChild->parent() == &parent) { auto* previousSibling = beforeChild->previousSibling(); - if (is(previousSibling) && previousSibling->isAnonymous()) { + if (auto* tableCell = dynamicDowncast(previousSibling); tableCell && tableCell->isAnonymous()) { beforeChild = nullptr; - return downcast(*previousSibling); + return *tableCell; } } @@ -62,10 +62,10 @@ RenderElement& RenderTreeBuilder::Table::findOrCreateParentForChild(RenderTableR auto* lastChild = beforeChild ? beforeChild : parent.lastCell(); if (lastChild) { - if (is(*lastChild) && lastChild->isAnonymous() && !lastChild->isBeforeOrAfterContent()) { + if (auto* tableCell = dynamicDowncast(*lastChild); tableCell && tableCell->isAnonymous() && !tableCell->isBeforeOrAfterContent()) { if (beforeChild == lastChild) - beforeChild = downcast(*lastChild).firstChild(); - return downcast(*lastChild); + beforeChild = tableCell->firstChild(); + return *tableCell; } // Try to find an anonymous container for the child. @@ -78,8 +78,8 @@ RenderElement& RenderTreeBuilder::Table::findOrCreateParentForChild(RenderTableR if (!is(*lastChild)) return *lastChildParent; // If beforeChild is inside an anonymous row, insert into the row. - if (is(*lastChildParent)) - return createAnonymousTableCell(downcast(*lastChildParent)); + if (auto* tableRow = dynamicDowncast(*lastChildParent)) + return createAnonymousTableCell(*tableRow); } } } @@ -92,17 +92,17 @@ RenderElement& RenderTreeBuilder::Table::findOrCreateParentForChild(RenderTableS return parent; auto* lastChild = beforeChild ? beforeChild : parent.lastRow(); - if (is(lastChild) && lastChild->isAnonymous() && !lastChild->isBeforeOrAfterContent()) { + if (auto* tableRow = dynamicDowncast(lastChild); tableRow && tableRow->isAnonymous() && !tableRow->isBeforeOrAfterContent()) { if (beforeChild == lastChild) - beforeChild = downcast(*lastChild).firstCell(); - return downcast(*lastChild); + beforeChild = tableRow->firstCell(); + return *tableRow; } if (beforeChild && !beforeChild->isAnonymous() && beforeChild->parent() == &parent) { auto* row = beforeChild->previousSibling(); - if (is(row) && row->isAnonymous()) { + if (auto* tableRow = dynamicDowncast(row); tableRow && tableRow->isAnonymous()) { beforeChild = nullptr; - return downcast(*row); + return *tableRow; } } @@ -111,8 +111,8 @@ RenderElement& RenderTreeBuilder::Table::findOrCreateParentForChild(RenderTableS auto* parentCandidate = lastChild; while (parentCandidate && parentCandidate->parent() && parentCandidate->parent()->isAnonymous() && !is(*parentCandidate)) parentCandidate = parentCandidate->parent(); - if (is(parentCandidate) && parentCandidate->isAnonymous() && !parentCandidate->isBeforeOrAfterContent()) - return downcast(*parentCandidate); + if (auto* tableRow = dynamicDowncast(parentCandidate); tableRow && tableRow->isAnonymous() && !tableRow->isBeforeOrAfterContent()) + return *tableRow; auto newRow = RenderTableRow::createAnonymousWithParentRenderer(parent); auto& row = *newRow; @@ -140,14 +140,14 @@ RenderElement& RenderTreeBuilder::Table::findOrCreateParentForChild(RenderTable& } auto* lastChild = parent.lastChild(); - if (!beforeChild && is(lastChild) && lastChild->isAnonymous() && !lastChild->isBeforeContent()) - return downcast(*lastChild); + if (auto* tableSection = dynamicDowncast(lastChild); !beforeChild && tableSection && tableSection->isAnonymous() && !tableSection->isBeforeContent()) + return *tableSection; if (beforeChild && !beforeChild->isAnonymous() && beforeChild->parent() == &parent) { auto* section = beforeChild->previousSibling(); - if (is(section) && section->isAnonymous()) { + if (auto* tableSection = dynamicDowncast(section); tableSection && tableSection->isAnonymous()) { beforeChild = nullptr; - return downcast(*section); + return *tableSection; } } @@ -161,16 +161,16 @@ RenderElement& RenderTreeBuilder::Table::findOrCreateParentForChild(RenderTable& if (parentCandidate) { if (beforeChild && !beforeChild->isAnonymous() && parentCandidate->parent() == &parent) { auto* section = parentCandidate->previousSibling(); - if (is(section) && section->isAnonymous()) { + if (auto* tableSection = dynamicDowncast(section); tableSection && tableSection->isAnonymous()) { beforeChild = nullptr; - return downcast(*section); + return *tableSection; } } - if (is(*parentCandidate) && parentCandidate->isAnonymous() && !parent.isAfterContent(parentCandidate)) { + if (auto* parentTableSection = dynamicDowncast(*parentCandidate); parentTableSection && parentTableSection->isAnonymous() && !parent.isAfterContent(parentTableSection)) { if (beforeChild == parentCandidate) - beforeChild = downcast(*parentCandidate).firstRow(); - return downcast(*parentCandidate); + beforeChild = parentTableSection->firstRow(); + return *parentTableSection; } } @@ -195,8 +195,8 @@ void RenderTreeBuilder::Table::attach(RenderTableRow& parent, RenderPtr(*beforeChild)); m_builder.attachToRenderElement(parent, WTFMove(child), beforeChild); // FIXME: child should always be a RenderTableCell at this point. - if (is(newChild)) - parent.didInsertTableCell(downcast(newChild), beforeChild); + if (auto* renderTableCell = dynamicDowncast(newChild)) + parent.didInsertTableCell(*renderTableCell, beforeChild); } void RenderTreeBuilder::Table::attach(RenderTableSection& parent, RenderPtr child, RenderObject* beforeChild) @@ -205,8 +205,8 @@ void RenderTreeBuilder::Table::attach(RenderTableSection& parent, RenderPtr(child)) - parent.willInsertTableRow(downcast(*child.get()), beforeChild); + if (auto* renderTableRow = dynamicDowncast(child.get())) + parent.willInsertTableRow(*renderTableRow, beforeChild); ASSERT(!beforeChild || is(*beforeChild)); m_builder.attachToRenderElement(parent, WTFMove(child), beforeChild); } @@ -217,19 +217,18 @@ void RenderTreeBuilder::Table::attach(RenderTable& parent, RenderPtr(newChild)) - parent.willInsertTableSection(downcast(newChild), beforeChild); - else if (is(newChild)) - parent.willInsertTableColumn(downcast(newChild), beforeChild); + if (auto* renderTableSection = dynamicDowncast(newChild)) + parent.willInsertTableSection(*renderTableSection, beforeChild); + else if (auto* renderTableCol = dynamicDowncast(newChild)) + parent.willInsertTableColumn(*renderTableCol, beforeChild); m_builder.attachToRenderElement(parent, WTFMove(child), beforeChild); } bool RenderTreeBuilder::Table::childRequiresTable(const RenderElement& parent, const RenderObject& child) { - if (is(child)) { - const RenderTableCol& newTableColumn = downcast(child); - bool isColumnInColumnGroup = newTableColumn.isTableColumn() && is(parent); + if (auto* newTableColumn = dynamicDowncast(child)) { + bool isColumnInColumnGroup = newTableColumn->isTableColumn() && is(parent); return !is(parent) && !isColumnInColumnGroup; } if (is(child)) diff --git a/Source/WebCore/rendering/updating/RenderTreePosition.cpp b/Source/WebCore/rendering/updating/RenderTreePosition.cpp index 769266980d6a5..c004723e0684c 100644 --- a/Source/WebCore/rendering/updating/RenderTreePosition.cpp +++ b/Source/WebCore/rendering/updating/RenderTreePosition.cpp @@ -84,8 +84,8 @@ RenderObject* RenderTreePosition::nextSiblingRenderer(const Node& node) const auto composedDescendants = composedTreeDescendants(*parentElement); auto initializeIteratorConsideringPseudoElements = [&] { - if (is(node)) { - auto* host = downcast(node).hostElement(); + if (auto* pseudoElement = dynamicDowncast(node)) { + auto* host = pseudoElement->hostElement(); if (node.isBeforePseudoElement()) { if (host != parentElement) return composedDescendants.at(*host).traverseNext(); @@ -131,10 +131,9 @@ RenderObject* RenderTreePosition::nextSiblingRenderer(const Node& node) const if (auto* renderer = it->renderer()) return renderer; - if (is(*it)) { - auto& element = downcast(*it); - if (element.hasDisplayContents()) { - if (auto* renderer = pushCheckingForAfterPseudoElementRenderer(element)) + if (auto* element = dynamicDowncast(*it)) { + if (element->hasDisplayContents()) { + if (auto* renderer = pushCheckingForAfterPseudoElementRenderer(*element)) return renderer; it.traverseNext(); continue; diff --git a/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp b/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp index acb628ee0fd89..e8850360eb88f 100644 --- a/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp +++ b/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp @@ -171,12 +171,12 @@ void RenderTreeUpdater::updateRebuildRoots() auto it = descendants.begin(); auto end = descendants.end(); while (it != end) { - auto& descendant = *it; - if (!is(descendant)) { + auto* descendant = dynamicDowncast(*it); + if (!descendant) { it.traverseNext(); continue; } - if (!addForRebuild(downcast(descendant))) { + if (!addForRebuild(*descendant)) { it.traverseNextSkippingChildren(); continue; } @@ -225,18 +225,17 @@ void RenderTreeUpdater::updateRenderTree(ContainerNode& root) if (auto* renderer = node.renderer()) renderTreePosition().invalidateNextSibling(*renderer); - else if (is(node) && downcast(node).hasDisplayContents()) + else if (auto* element = dynamicDowncast(node); element && element->hasDisplayContents()) renderTreePosition().invalidateNextSibling(); - if (is(node)) { - auto& text = downcast(node); - auto* textUpdate = m_styleUpdate->textUpdate(text); + if (auto* text = dynamicDowncast(node)) { + auto* textUpdate = m_styleUpdate->textUpdate(*text); bool didCreateParent = parent().update && parent().update->change == Style::Change::Renderer; - bool mayNeedUpdateWhitespaceOnlyRenderer = renderingParent().didCreateOrDestroyChildRenderer && text.data().containsOnly(); + bool mayNeedUpdateWhitespaceOnlyRenderer = renderingParent().didCreateOrDestroyChildRenderer && text->data().containsOnly(); if (didCreateParent || textUpdate || mayNeedUpdateWhitespaceOnlyRenderer) - updateTextRenderer(text, textUpdate); + updateTextRenderer(*text, textUpdate); - storePreviousRenderer(text); + storePreviousRenderer(*text); it.traverseNextSkippingChildren(); continue; } @@ -751,8 +750,8 @@ void RenderTreeUpdater::tearDownRenderers(Element& root, TeardownType teardownTy for (auto it = descendants.begin(), end = descendants.end(); it != end; ++it) { pop(it.depth()); - if (is(*it)) { - tearDownTextRenderer(downcast(*it), builder); + if (auto* text = dynamicDowncast(*it)) { + tearDownTextRenderer(*text, builder); continue; } @@ -790,12 +789,12 @@ void RenderTreeUpdater::tearDownLeftoverChildrenOfComposedTree(Element& element, for (auto* child = element.firstChild(); child; child = child->nextSibling()) { if (!child->renderer()) continue; - if (is(*child)) { - tearDownTextRenderer(downcast(*child), builder); + if (auto* text = dynamicDowncast(*child)) { + tearDownTextRenderer(*text, builder); continue; } - if (is(*child)) - tearDownRenderers(downcast(*child), TeardownType::Full, builder); + if (auto* element = dynamicDowncast(*child)) + tearDownRenderers(*element, TeardownType::Full, builder); } } diff --git a/Source/WebCore/rendering/updating/RenderTreeUpdaterGeneratedContent.cpp b/Source/WebCore/rendering/updating/RenderTreeUpdaterGeneratedContent.cpp index 2632a99863a58..2887b091e28f9 100644 --- a/Source/WebCore/rendering/updating/RenderTreeUpdaterGeneratedContent.cpp +++ b/Source/WebCore/rendering/updating/RenderTreeUpdaterGeneratedContent.cpp @@ -85,8 +85,8 @@ void RenderTreeUpdater::GeneratedContent::updateCounters() static bool elementIsTargetedByKeyframeEffectRequiringPseudoElement(const Element* element, PseudoId pseudoId) { - if (is(element)) - return elementIsTargetedByKeyframeEffectRequiringPseudoElement(downcast(*element).hostElement(), pseudoId); + if (auto* pseudoElement = dynamicDowncast(element)) + return elementIsTargetedByKeyframeEffectRequiringPseudoElement(pseudoElement->hostElement(), pseudoId); if (element) { if (auto* stack = element->keyframeEffectStack(pseudoId)) diff --git a/Source/WebCore/style/ElementRuleCollector.cpp b/Source/WebCore/style/ElementRuleCollector.cpp index d14f00dbb63e8..5fcf2c6034f98 100644 --- a/Source/WebCore/style/ElementRuleCollector.cpp +++ b/Source/WebCore/style/ElementRuleCollector.cpp @@ -733,17 +733,16 @@ void ElementRuleCollector::matchAllRules(bool matchAuthorAndUserStyles, bool inc if (matchAuthorAndUserStyles) matchUserRules(); - if (is(element())) { - auto& styledElement = downcast(element()); + if (auto* styledElement = dynamicDowncast(element())) { // https://html.spec.whatwg.org/#presentational-hints - addElementStyleProperties(styledElement.presentationalHintStyle(), RuleSet::cascadeLayerPriorityForPresentationalHints); + addElementStyleProperties(styledElement->presentationalHintStyle(), RuleSet::cascadeLayerPriorityForPresentationalHints); // Tables and table cells share an additional presentation style that must be applied // after all attributes, since their style depends on the values of multiple attributes. - addElementStyleProperties(styledElement.additionalPresentationalHintStyle(), RuleSet::cascadeLayerPriorityForPresentationalHints); + addElementStyleProperties(styledElement->additionalPresentationalHintStyle(), RuleSet::cascadeLayerPriorityForPresentationalHints); - if (is(styledElement)) { - auto result = downcast(styledElement).directionalityIfDirIsAuto(); + if (auto* htmlElement = dynamicDowncast(*styledElement)) { + auto result = htmlElement->directionalityIfDirIsAuto(); auto& properties = result.value_or(TextDirection::LTR) == TextDirection::LTR ? leftToRightDeclaration() : rightToLeftDeclaration(); if (result) addMatchedProperties({ properties }, DeclarationOrigin::Author); @@ -768,16 +767,19 @@ void ElementRuleCollector::matchAllRules(bool matchAuthorAndUserStyles, bool inc void ElementRuleCollector::addElementInlineStyleProperties(bool includeSMILProperties) { - if (!is(element())) + auto* styledElement = dynamicDowncast(element()); + if (!styledElement) return; - if (auto* inlineStyle = downcast(element()).inlineStyle()) { + if (auto* inlineStyle = styledElement->inlineStyle()) { bool isInlineStyleCacheable = !inlineStyle->isMutable(); addElementStyleProperties(inlineStyle, RuleSet::cascadeLayerPriorityForUnlayered, isInlineStyleCacheable, FromStyleAttribute::Yes); } - if (includeSMILProperties && is(element())) - addElementStyleProperties(downcast(element()).animatedSMILStyleProperties(), RuleSet::cascadeLayerPriorityForUnlayered, false /* isCacheable */); + if (includeSMILProperties) { + if (auto* svgElement = dynamicDowncast(element())) + addElementStyleProperties(svgElement->animatedSMILStyleProperties(), RuleSet::cascadeLayerPriorityForUnlayered, false /* isCacheable */); + } } bool ElementRuleCollector::hasAnyMatchingRules(const RuleSet& ruleSet) diff --git a/Source/WebCore/style/FilterOperationsBuilder.cpp b/Source/WebCore/style/FilterOperationsBuilder.cpp index 82f1bd536eee2..f8cc8ad2b5ede 100644 --- a/Source/WebCore/style/FilterOperationsBuilder.cpp +++ b/Source/WebCore/style/FilterOperationsBuilder.cpp @@ -76,48 +76,47 @@ std::optional createFilterOperations(const Document& document, { FilterOperations operations; - if (is(inValue)) { - auto& primitiveValue = downcast(inValue); - if (primitiveValue.valueID() == CSSValueNone) + if (auto* primitiveValue = dynamicDowncast(inValue)) { + if (primitiveValue->valueID() == CSSValueNone) return operations; } - if (!is(inValue)) + auto* list = dynamicDowncast(inValue); + if (!list) return std::nullopt; - for (auto& currentValue : downcast(inValue)) { - if (is(currentValue)) { - auto& primitiveValue = downcast(currentValue); - if (!primitiveValue.isURI()) + for (auto& currentValue : *list) { + if (auto* primitiveValue = dynamicDowncast(currentValue)) { + if (!primitiveValue->isURI()) continue; - auto filterURL = primitiveValue.stringValue(); + auto filterURL = primitiveValue->stringValue(); auto fragment = document.completeURL(filterURL).fragmentIdentifier().toAtomString(); operations.operations().append(ReferenceFilterOperation::create(filterURL, WTFMove(fragment))); continue; } - if (!is(currentValue)) + auto* filterValue = dynamicDowncast(currentValue); + if (!filterValue) continue; - auto& filterValue = downcast(currentValue); - auto operationType = filterOperationForType(filterValue.name()); + auto operationType = filterOperationForType(filterValue->name()); // Check that all parameters are primitive values, with the // exception of drop shadow which has a CSSShadowValue parameter. const CSSPrimitiveValue* firstValue = nullptr; if (operationType != FilterOperation::Type::DropShadow) { bool haveNonPrimitiveValue = false; - for (unsigned j = 0; j < filterValue.length(); ++j) { - if (!is(*filterValue.itemWithoutBoundsCheck(j))) { + for (unsigned j = 0; j < filterValue->length(); ++j) { + if (!is(*filterValue->itemWithoutBoundsCheck(j))) { haveNonPrimitiveValue = true; break; } } if (haveNonPrimitiveValue) continue; - if (filterValue.length()) - firstValue = downcast(filterValue.itemWithoutBoundsCheck(0)); + if (filterValue->length()) + firstValue = downcast(filterValue->itemWithoutBoundsCheck(0)); } switch (operationType) { @@ -125,7 +124,7 @@ std::optional createFilterOperations(const Document& document, case FilterOperation::Type::Sepia: case FilterOperation::Type::Saturate: { double amount = 1; - if (filterValue.length() == 1) { + if (filterValue->length() == 1) { amount = firstValue->doubleValue(); if (firstValue->isPercentage()) amount /= 100; @@ -136,7 +135,7 @@ std::optional createFilterOperations(const Document& document, } case FilterOperation::Type::HueRotate: { double angle = 0; - if (filterValue.length() == 1) + if (filterValue->length() == 1) angle = firstValue->computeDegrees(); operations.operations().append(BasicColorMatrixFilterOperation::create(angle, operationType)); @@ -147,7 +146,7 @@ std::optional createFilterOperations(const Document& document, case FilterOperation::Type::Contrast: case FilterOperation::Type::Opacity: { double amount = 1; - if (filterValue.length() == 1) { + if (filterValue->length() == 1) { amount = firstValue->doubleValue(); if (firstValue->isPercentage()) amount /= 100; @@ -162,7 +161,7 @@ std::optional createFilterOperations(const Document& document, } case FilterOperation::Type::Blur: { Length stdDeviation = Length(0, LengthType::Fixed); - if (filterValue.length() >= 1) + if (filterValue->length() >= 1) stdDeviation = convertToFloatLength(firstValue, cssToLengthConversionData); if (stdDeviation.isUndefined()) return std::nullopt; @@ -171,19 +170,18 @@ std::optional createFilterOperations(const Document& document, break; } case FilterOperation::Type::DropShadow: { - if (filterValue.length() != 1) + if (filterValue->length() != 1) return std::nullopt; - const auto* cssValue = filterValue.itemWithoutBoundsCheck(0); - if (!is(cssValue)) + const auto* item = dynamicDowncast(filterValue->itemWithoutBoundsCheck(0)); + if (!item) continue; - const auto& item = downcast(*cssValue); - int x = item.x->computeLength(cssToLengthConversionData); - int y = item.y->computeLength(cssToLengthConversionData); + int x = item->x->computeLength(cssToLengthConversionData); + int y = item->y->computeLength(cssToLengthConversionData); IntPoint location(x, y); - int blur = item.blur ? item.blur->computeLength(cssToLengthConversionData) : 0; - auto color = item.color ? colorFromPrimitiveValueWithResolvedCurrentColor(document, style, *item.color) : style.color(); + int blur = item->blur ? item->blur->computeLength(cssToLengthConversionData) : 0; + auto color = item->color ? colorFromPrimitiveValueWithResolvedCurrentColor(document, style, *item->color) : style.color(); operations.operations().append(DropShadowFilterOperation::create(location, blur, color.isValid() ? color : Color::transparentBlack)); break; diff --git a/Source/WebCore/style/InlineTextBoxStyle.cpp b/Source/WebCore/style/InlineTextBoxStyle.cpp index c815f6c6efb79..54d5b7d989c8b 100644 --- a/Source/WebCore/style/InlineTextBoxStyle.cpp +++ b/Source/WebCore/style/InlineTextBoxStyle.cpp @@ -65,7 +65,7 @@ static float minLogicalTopForTextDecorationLineUnder(const InlineIterator::LineB if (!run->style().textDecorationsInEffect().contains(TextDecorationLine::Underline)) continue; // If the text decoration isn't in effect on the child, then it must be outside of |decoratingBoxRendererForUnderline|'s hierarchy. - if (decoratingBoxRendererForUnderline.isRenderInline() && !isAncestorAndWithinBlock(downcast(decoratingBoxRendererForUnderline), &run->renderer())) + if (auto* renderInline = dynamicDowncast(decoratingBoxRendererForUnderline); renderInline && !isAncestorAndWithinBlock(*renderInline, &run->renderer())) continue; if (run->isText() || run->style().textDecorationSkipInk() == TextDecorationSkipInk::None) @@ -84,7 +84,7 @@ static float maxLogicalBottomForTextDecorationLineUnder(const InlineIterator::Li if (!run->style().textDecorationsInEffect().contains(TextDecorationLine::Underline)) continue; // If the text decoration isn't in effect on the child, then it must be outside of |decoratingBoxRendererForUnderline|'s hierarchy. - if (decoratingBoxRendererForUnderline.isRenderInline() && !isAncestorAndWithinBlock(downcast(decoratingBoxRendererForUnderline), &run->renderer())) + if (auto* renderInline = dynamicDowncast(decoratingBoxRendererForUnderline); renderInline && !isAncestorAndWithinBlock(*renderInline, &run->renderer())) continue; if (run->isText() || run->style().textDecorationSkipInk() == TextDecorationSkipInk::None) diff --git a/Source/WebCore/style/InspectorCSSOMWrappers.cpp b/Source/WebCore/style/InspectorCSSOMWrappers.cpp index 0e43b4eebc224..2107008d61111 100644 --- a/Source/WebCore/style/InspectorCSSOMWrappers.cpp +++ b/Source/WebCore/style/InspectorCSSOMWrappers.cpp @@ -65,25 +65,25 @@ void InspectorCSSOMWrappers::collect(ListType* listType) switch (cssRule->styleRuleType()) { case StyleRuleType::Container: - collect(downcast(cssRule)); + collect(uncheckedDowncast(cssRule)); break; case StyleRuleType::Import: - collect(downcast(*cssRule).styleSheet()); + collect(uncheckedDowncast(*cssRule).styleSheet()); break; case StyleRuleType::LayerBlock: - collect(downcast(cssRule)); + collect(uncheckedDowncast(cssRule)); break; case StyleRuleType::Media: - collect(downcast(cssRule)); + collect(uncheckedDowncast(cssRule)); break; case StyleRuleType::Supports: - collect(downcast(cssRule)); + collect(uncheckedDowncast(cssRule)); break; case StyleRuleType::Style: - m_styleRuleToCSSOMWrapperMap.add(&downcast(*cssRule).styleRule(), downcast(cssRule)); + m_styleRuleToCSSOMWrapperMap.add(&uncheckedDowncast(*cssRule).styleRule(), uncheckedDowncast(cssRule)); // Eagerly collect rules nested in this style rule. - collect(downcast(cssRule)); + collect(uncheckedDowncast(cssRule)); break; default: break; diff --git a/Source/WebCore/style/RuleSetBuilder.cpp b/Source/WebCore/style/RuleSetBuilder.cpp index 9daf50dbdcdf3..a17a7b01c5e18 100644 --- a/Source/WebCore/style/RuleSetBuilder.cpp +++ b/Source/WebCore/style/RuleSetBuilder.cpp @@ -110,16 +110,16 @@ void RuleSetBuilder::addChildRule(Ref rule) switch (rule->type()) { case StyleRuleType::StyleWithNesting: if (m_ruleSet) - addStyleRule(downcast(rule)); + addStyleRule(uncheckedDowncast(rule)); return; case StyleRuleType::Style: if (m_ruleSet) - addStyleRule(downcast(rule)); + addStyleRule(uncheckedDowncast(rule)); return; case StyleRuleType::Scope: { - auto scopeRule = downcast(WTFMove(rule)); + auto scopeRule = uncheckedDowncast(WTFMove(rule)); auto previousScopeIdentifier = m_currentScopeIdentifier; if (m_ruleSet) { m_ruleSet->m_scopeRules.append({ scopeRule.copyRef(), previousScopeIdentifier }); @@ -149,11 +149,11 @@ void RuleSetBuilder::addChildRule(Ref rule) case StyleRuleType::Page: if (m_ruleSet) - m_ruleSet->addPageRule(downcast(rule)); + m_ruleSet->addPageRule(uncheckedDowncast(rule)); return; case StyleRuleType::Media: { - auto mediaRule = downcast(WTFMove(rule)); + auto mediaRule = uncheckedDowncast(WTFMove(rule)); if (m_mediaQueryCollector.pushAndEvaluate(mediaRule->mediaQueries())) addChildRules(mediaRule->childRules()); m_mediaQueryCollector.pop(mediaRule->mediaQueries()); @@ -161,7 +161,7 @@ void RuleSetBuilder::addChildRule(Ref rule) } case StyleRuleType::Container: { - auto containerRule = downcast(WTFMove(rule)); + auto containerRule = uncheckedDowncast(WTFMove(rule)); auto previousContainerQueryIdentifier = m_currentContainerQueryIdentifier; if (m_ruleSet) { m_ruleSet->m_containerQueries.append({ containerRule.copyRef(), previousContainerQueryIdentifier }); @@ -177,7 +177,7 @@ void RuleSetBuilder::addChildRule(Ref rule) case StyleRuleType::LayerStatement: { disallowDynamicMediaQueryEvaluationIfNeeded(); - auto layerRule = downcast(WTFMove(rule)); + auto layerRule = uncheckedDowncast(WTFMove(rule)); if (layerRule->isStatement()) { // Statement syntax just registers the layers. registerLayers(layerRule->nameList()); @@ -201,7 +201,7 @@ void RuleSetBuilder::addChildRule(Ref rule) return; case StyleRuleType::Supports: { - auto supportsRule = downcast(WTFMove(rule)); + auto supportsRule = uncheckedDowncast(WTFMove(rule)); if (supportsRule->conditionIsSupported()) addChildRules(supportsRule->childRules()); return; @@ -423,39 +423,39 @@ void RuleSetBuilder::addMutatingRulesToResolver() m_ruleSet->m_resolverMutatingRulesInLayers.append(collectedRule); auto& rule = collectedRule.rule; - if (is(rule)) { - m_resolver->document().fontSelector().addFontFaceRule(downcast(rule.get()), false); + if (auto* styleRuleFontFace = dynamicDowncast(rule.get())) { + m_resolver->document().fontSelector().addFontFaceRule(*styleRuleFontFace, false); m_resolver->invalidateMatchedDeclarationsCache(); continue; } - if (is(rule)) { - m_resolver->document().fontSelector().addFontPaletteValuesRule(downcast(rule.get())); + if (auto* styleRuleFontPaletteValues = dynamicDowncast(rule.get())) { + m_resolver->document().fontSelector().addFontPaletteValuesRule(*styleRuleFontPaletteValues); m_resolver->invalidateMatchedDeclarationsCache(); continue; } - if (is(rule)) { - m_resolver->document().fontSelector().addFontFeatureValuesRule(downcast(rule.get())); + if (auto* styleRuleFontFeatureValues = dynamicDowncast(rule.get())) { + m_resolver->document().fontSelector().addFontFeatureValuesRule(*styleRuleFontFeatureValues); m_resolver->invalidateMatchedDeclarationsCache(); continue; } - if (is(rule)) { - m_resolver->addKeyframeStyle(downcast(rule.get())); + if (auto* styleRuleKeyframes = dynamicDowncast(rule.get())) { + m_resolver->addKeyframeStyle(*styleRuleKeyframes); continue; } - if (is(rule)) { + if (auto* styleRuleCounterStyle = dynamicDowncast(rule.get())) { if (m_resolver->scopeType() == Resolver::ScopeType::ShadowTree) continue; auto& registry = m_resolver->document().styleScope().counterStyleRegistry(); - registry.addCounterStyle(downcast(rule.get()).descriptors()); + registry.addCounterStyle(styleRuleCounterStyle->descriptors()); continue; } - if (is(rule)) { + if (auto* styleRuleProperty = dynamicDowncast(rule.get())) { // "A @property is invalid if it occurs in a stylesheet inside of a shadow tree, and must be ignored." // https://drafts.css-houdini.org/css-properties-values-api/#at-property-rule if (m_resolver->scopeType() == Resolver::ScopeType::ShadowTree) continue; auto& registry = m_resolver->document().styleScope().customPropertyRegistry(); - registry.registerFromStylesheet(downcast(rule.get()).descriptor()); + registry.registerFromStylesheet(styleRuleProperty->descriptor()); continue; } } diff --git a/Source/WebCore/style/StyleAdjuster.cpp b/Source/WebCore/style/StyleAdjuster.cpp index 4cc22a836bec6..f0000ae63f111 100644 --- a/Source/WebCore/style/StyleAdjuster.cpp +++ b/Source/WebCore/style/StyleAdjuster.cpp @@ -337,10 +337,11 @@ OptionSet Adjuster::computeEventListenerRegionTypes(con #endif #if ENABLE(INTERACTION_REGIONS_IN_EVENT_REGION) - if (document.page() && document.page()->shouldBuildInteractionRegions() && eventTarget.isNode()) { - const auto& node = downcast(eventTarget); - if (node.willRespondToMouseClickEventsWithEditability(node.computeEditabilityForMouseClickEvents(&style))) - types.add(EventListenerRegionType::MouseClick); + if (document.page() && document.page()->shouldBuildInteractionRegions()) { + if (const auto* node = dynamicDowncast(eventTarget)) { + if (node->willRespondToMouseClickEventsWithEditability(node->computeEditabilityForMouseClickEvents(&style))) + types.add(EventListenerRegionType::MouseClick); + } } #else UNUSED_PARAM(document); diff --git a/Source/WebCore/style/StyleInvalidator.cpp b/Source/WebCore/style/StyleInvalidator.cpp index cf8261d48ea52..19ff536ae0108 100644 --- a/Source/WebCore/style/StyleInvalidator.cpp +++ b/Source/WebCore/style/StyleInvalidator.cpp @@ -148,7 +148,7 @@ static void invalidateAssignedElements(HTMLSlotElement& slot) invalidateAssignedElements(*slotElement); continue; } - downcast(*node).invalidateStyleInternal(); + element->invalidateStyleInternal(); } } diff --git a/Source/WebCore/style/StyleSharingResolver.cpp b/Source/WebCore/style/StyleSharingResolver.cpp index ad456f51bf9c7..c0bb0854019dc 100644 --- a/Source/WebCore/style/StyleSharingResolver.cpp +++ b/Source/WebCore/style/StyleSharingResolver.cpp @@ -161,11 +161,11 @@ StyledElement* SharingResolver::findSibling(const Context& context, Node* node, if (!styledElement) continue; if (canShareStyleWithElement(context, *styledElement)) - break; + return styledElement; if (count++ >= cStyleSearchThreshold) return nullptr; } - return downcast(node); + return nullptr; } Node* SharingResolver::locateCousinList(const Element* parent) const