Skip to content

Commit

Permalink
Adopt dynamicDowncast<> in a number of page classes
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=267512

Reviewed by Darin Adler.

* Source/WebCore/page/LocalFrame.cpp:
(WebCore::LocalFrame::searchForLabelsBeforeElement):
(WebCore::LocalFrame::setPageAndTextZoomFactors):
(WebCore::LocalFrame::contentFrameFromWindowOrFrameElement):
* Source/WebCore/page/LocalFrameView.cpp:
(WebCore::LocalFrameView::init):
(WebCore::LocalFrameView::applyOverflowToViewport):
(WebCore::LocalFrameView::applyPaginationToViewport):
(WebCore::LocalFrameView::addEmbeddedObjectToUpdate):
(WebCore::LocalFrameView::canShowNonOverlayScrollbars const):
(WebCore::LocalFrameView::maintainScrollPositionAtAnchor):
(WebCore::countRenderedCharactersInRenderObjectWithThreshold):
(WebCore::LocalFrameView::updateEmbeddedObject):
(WebCore::LocalFrameView::hasCustomScrollbars const):
(WebCore::LocalFrameView::addChild):
(WebCore::LocalFrameView::removeChild):
* Source/WebCore/page/Page.cpp:
(WebCore::Page::editableElementsInRect const):
* Source/WebCore/page/PageColorSampler.cpp:
(WebCore::isValidSampleLocation):
* Source/WebCore/page/PageConsoleClient.cpp:
(WebCore::PageConsoleClient::screenshot):
* Source/WebCore/page/PageSerializer.cpp:
(WebCore::PageSerializer::SerializerMarkupAccumulator::appendCustomAttributes):
(WebCore::PageSerializer::serializeFrame):
(WebCore::PageSerializer::serializeCSSStyleSheet):
(WebCore::PageSerializer::retrieveResourcesForProperties):
* Source/WebCore/page/Quirks.cpp:
(WebCore::Quirks::shouldDispatchSimulatedMouseEvents const):
(WebCore::Quirks::shouldDispatchedSimulatedMouseEventsAssumeDefaultPrevented const):
(WebCore::Quirks::simulatedMouseEventTypeForTarget const):
(WebCore::Quirks::shouldMakeTouchEventNonCancelableForTarget const):
(WebCore::Quirks::shouldPreventDispatchOfTouchEvent const):
(WebCore::Quirks::shouldBypassBackForwardCache const):
(WebCore::Quirks::shouldMakeEventListenerPassive):
(WebCore::Quirks::triggerOptionalStorageAccessQuirk const):

Canonical link: https://commits.webkit.org/273154@main
  • Loading branch information
annevk committed Jan 18, 2024
1 parent a775f3c commit b0ccbb2
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 106 deletions.
13 changes: 9 additions & 4 deletions Source/WebCore/page/LocalFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,10 @@ String LocalFrame::searchForLabelsBeforeElement(const Vector<String>& labels, El
RefPtr<Node> n;
for (n = NodeTraversal::previous(*element); n && lengthSearched < charsSearchedThreshold; n = NodeTraversal::previous(*n)) {
// We hit another form element or the start of the form - bail out
if (is<HTMLFormElement>(*n) || (is<Element>(*n) && downcast<Element>(*n).isValidatedFormListedElement()))
if (is<HTMLFormElement>(*n))
break;

if (RefPtr element = dynamicDowncast<Element>(*n); element && element->isValidatedFormListedElement())
break;

if (n->hasTagName(tdTag) && !startingTableCell)
Expand Down Expand Up @@ -1023,7 +1026,7 @@ void LocalFrame::setPageAndTextZoomFactors(float pageZoomFactor, float textZoomF

// Respect SVGs zoomAndPan="disabled" property in standalone SVG documents.
// FIXME: How to handle compound documents + zoomAndPan="disabled"? Needs SVG WG clarification.
if (is<SVGDocument>(*document) && !downcast<SVGDocument>(*document).zoomAndPanEnabled())
if (RefPtr svgDocument = dynamicDowncast<SVGDocument>(*document); svgDocument && !svgDocument->zoomAndPanEnabled())
return;

std::optional<ScrollPosition> scrollPositionAfterZoomed;
Expand Down Expand Up @@ -1229,9 +1232,11 @@ LocalFrame* LocalFrame::contentFrameFromWindowOrFrameElement(JSContextRef contex
return window->frame();

auto* jsNode = JSC::jsDynamicCast<JSNode*>(value);
if (!jsNode || !is<HTMLFrameOwnerElement>(jsNode->wrapped()))
if (!jsNode)
return nullptr;
return dynamicDowncast<LocalFrame>(downcast<HTMLFrameOwnerElement>(jsNode->wrapped()).contentFrame());

RefPtr frameOwner = dynamicDowncast<HTMLFrameOwnerElement>(jsNode->wrapped());
return frameOwner ? dynamicDowncast<LocalFrame>(frameOwner->contentFrame()) : nullptr;
}

CheckedRef<EventHandler> LocalFrame::checkedEventHandler()
Expand Down
64 changes: 32 additions & 32 deletions Source/WebCore/page/LocalFrameView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,8 +334,8 @@ void LocalFrameView::init()
m_lastUsedSizeForLayout = { };

// Propagate the scrolling mode to the view.
auto* ownerElement = m_frame->ownerElement();
if (is<HTMLFrameElementBase>(ownerElement) && downcast<HTMLFrameElementBase>(*ownerElement).scrollingMode() == ScrollbarMode::AlwaysOff)
RefPtr ownerElement = dynamicDowncast<HTMLFrameElementBase>(m_frame->ownerElement());
if (ownerElement && ownerElement->scrollingMode() == ScrollbarMode::AlwaysOff)
setCanHaveScrollbars(false);

Page* page = m_frame->page();
Expand Down Expand Up @@ -608,20 +608,20 @@ void LocalFrameView::applyOverflowToViewport(const RenderElement& renderer, Scro
Overflow overflowY = renderer.style().overflowY();

#if ENABLE(LAYER_BASED_SVG_ENGINE)
if (is<RenderSVGRoot>(renderer)) {
if (CheckedPtr renderSVGRoot = dynamicDowncast<RenderSVGRoot>(renderer)) {
// FIXME: evaluate if we can allow overflow for these cases too.
// Overflow is always hidden when stand-alone SVG documents are embedded.
if (downcast<RenderSVGRoot>(renderer).isEmbeddedThroughFrameContainingSVGDocument()) {
if (renderSVGRoot->isEmbeddedThroughFrameContainingSVGDocument()) {
overflowX = Overflow::Hidden;
overflowY = Overflow::Hidden;
}
}
#endif

if (is<LegacyRenderSVGRoot>(renderer)) {
if (CheckedPtr legacyRenderSVGRoot = dynamicDowncast<LegacyRenderSVGRoot>(renderer)) {
// FIXME: evaluate if we can allow overflow for these cases too.
// Overflow is always hidden when stand-alone SVG documents are embedded.
if (downcast<LegacyRenderSVGRoot>(renderer).isEmbeddedThroughFrameContainingSVGDocument()) {
if (legacyRenderSVGRoot->isEmbeddedThroughFrameContainingSVGDocument()) {
overflowX = Overflow::Hidden;
overflowY = Overflow::Hidden;
}
Expand Down Expand Up @@ -691,7 +691,8 @@ void LocalFrameView::applyPaginationToViewport()
GapLength columnGapLength = documentOrBodyRenderer->style().columnGap();
pagination.gap = 0;
if (!columnGapLength.isNormal()) {
if (auto* containerForPaginationGap = is<RenderBox>(documentOrBodyRenderer) ? downcast<RenderBox>(documentOrBodyRenderer) : documentOrBodyRenderer->containingBlock())
auto* renderBox = dynamicDowncast<RenderBox>(documentOrBodyRenderer);
if (auto* containerForPaginationGap = renderBox ? renderBox : documentOrBodyRenderer->containingBlock())
pagination.gap = valueForLength(columnGapLength.length(), containerForPaginationGap->availableLogicalWidth()).toUnsigned();
}
}
Expand Down Expand Up @@ -1365,8 +1366,8 @@ void LocalFrameView::addEmbeddedObjectToUpdate(RenderEmbeddedObject& embeddedObj
m_embeddedObjectsToUpdate = makeUnique<ListHashSet<SingleThreadWeakRef<RenderEmbeddedObject>>>();

auto& element = embeddedObject.frameOwnerElement();
if (is<HTMLPlugInImageElement>(element))
downcast<HTMLPlugInImageElement>(element).setNeedsWidgetUpdate(true);
if (RefPtr embedOrObject = dynamicDowncast<HTMLPlugInImageElement>(element))
embedOrObject->setNeedsWidgetUpdate(true);

m_embeddedObjectsToUpdate->add(embeddedObject);
}
Expand Down Expand Up @@ -1488,11 +1489,14 @@ String LocalFrameView::debugDescription() const
bool LocalFrameView::canShowNonOverlayScrollbars() const
{
auto usesLegacyScrollbarStyle = [&] {
auto element = rootElementForCustomScrollbarPartStyle();
if (!element || !is<RenderBox>(element->renderer()))
RefPtr element = rootElementForCustomScrollbarPartStyle();
if (!element)
return false;

return downcast<RenderBox>(*element->renderer()).style().usesLegacyScrollbarStyle();
if (CheckedPtr renderBox = dynamicDowncast<RenderBox>(element->renderer()))
return renderBox->style().usesLegacyScrollbarStyle();

return false;
}();

return canHaveScrollbars() && (usesLegacyScrollbarStyle || !ScrollbarTheme::theme().usesOverlayScrollbars());
Expand Down Expand Up @@ -2374,8 +2378,8 @@ void LocalFrameView::maintainScrollPositionAtAnchor(ContainerNode* anchorNode)

cancelScheduledScrolls();

if (is<Element>(anchorNode))
m_frame->document()->updateContentRelevancyForScrollIfNeeded(downcast<Element>(*anchorNode));
if (RefPtr element = dynamicDowncast<Element>(anchorNode))
m_frame->document()->updateContentRelevancyForScrollIfNeeded(*element);

// We need to update the layout before scrolling, otherwise we could
// really mess things up if an anchor scroll comes at a bad moment.
Expand Down Expand Up @@ -3106,8 +3110,8 @@ static unsigned countRenderedCharactersInRenderObjectWithThreshold(const RenderE
{
unsigned count = 0;
for (const RenderObject* descendant = &renderer; descendant; descendant = descendant->nextInPreOrder()) {
if (is<RenderText>(*descendant)) {
count += downcast<RenderText>(*descendant).text().length();
if (CheckedPtr renderText = dynamicDowncast<RenderText>(*descendant)) {
count += renderText->text().length();
if (count >= threshold)
break;
}
Expand Down Expand Up @@ -3710,12 +3714,9 @@ void LocalFrameView::updateEmbeddedObject(const SingleThreadWeakPtr<RenderEmbedd
if (embeddedObject->isPluginUnavailable())
return;

auto& element = embeddedObject->frameOwnerElement();

if (is<HTMLPlugInImageElement>(element)) {
auto& pluginElement = downcast<HTMLPlugInImageElement>(element);
if (pluginElement.needsWidgetUpdate())
pluginElement.updateWidget(CreatePlugins::Yes);
if (RefPtr embedOrObject = dynamicDowncast<HTMLPlugInImageElement>(embeddedObject->frameOwnerElement())) {
if (embedOrObject->needsWidgetUpdate())
embedOrObject->updateWidget(CreatePlugins::Yes);
} else
ASSERT_NOT_REACHED();

Expand Down Expand Up @@ -4575,11 +4576,11 @@ Color LocalFrameView::documentBackgroundColor() const
bool LocalFrameView::hasCustomScrollbars() const
{
for (auto& widget : children()) {
if (is<LocalFrameView>(widget)) {
if (downcast<LocalFrameView>(widget.get()).hasCustomScrollbars())
if (RefPtr frame = dynamicDowncast<LocalFrameView>(widget)) {
if (frame->hasCustomScrollbars())
return true;
} else if (is<Scrollbar>(widget)) {
if (downcast<Scrollbar>(widget.get()).isCustomScrollbar())
} else if (RefPtr scrollbar = dynamicDowncast<Scrollbar>(widget)) {
if (scrollbar->isCustomScrollbar())
return true;
}
}
Expand Down Expand Up @@ -5432,19 +5433,18 @@ void LocalFrameView::scheduleScrollEvent()

void LocalFrameView::addChild(Widget& widget)
{
if (is<LocalFrameView>(widget)) {
auto& childFrameView = downcast<LocalFrameView>(widget);
if (childFrameView.isScrollable())
addScrollableArea(&childFrameView);
if (auto* childFrameView = dynamicDowncast<LocalFrameView>(widget)) {
if (childFrameView->isScrollable())
addScrollableArea(childFrameView);
}

ScrollView::addChild(widget);
}

void LocalFrameView::removeChild(Widget& widget)
{
if (is<LocalFrameView>(widget))
removeScrollableArea(&downcast<LocalFrameView>(widget));
if (auto* childFrameView = dynamicDowncast<LocalFrameView>(widget))
removeScrollableArea(childFrameView);

ScrollView::removeChild(widget);
}
Expand Down
6 changes: 3 additions & 3 deletions Source/WebCore/page/Page.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1184,9 +1184,9 @@ Vector<Ref<Element>> Page::editableElementsInRect(const FloatRect& searchRectInR
return { };

auto rootEditableElement = [](Node& node) -> Element* {
if (is<HTMLTextFormControlElement>(node)) {
if (downcast<HTMLTextFormControlElement>(node).isInnerTextElementEditable())
return &downcast<Element>(node);
if (RefPtr element = dynamicDowncast<HTMLTextFormControlElement>(node)) {
if (element->isInnerTextElementEditable())
return &uncheckedDowncast<Element>(node);
} else if (is<Element>(node) && node.hasEditableStyle())
return node.rootEditableElement();
return nullptr;
Expand Down
10 changes: 5 additions & 5 deletions Source/WebCore/page/PageColorSampler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,11 @@ static bool isValidSampleLocation(Document& document, const IntPoint& location)
if (is<RenderImage>(renderer) || renderer->style().hasBackgroundImage())
return false;

if (!is<Element>(node))
RefPtr element = dynamicDowncast<Element>(node);
if (!element)
continue;

auto& element = downcast<Element>(node);
auto styleable = Styleable::fromElement(element);
auto styleable = Styleable::fromElement(*element);

// Skip nodes with animations as the sample may get an odd color if the animation is in-progress.
if (styleable.hasRunningTransitions())
Expand All @@ -96,11 +96,11 @@ static bool isValidSampleLocation(Document& document, const IntPoint& location)

// Skip `<canvas>` but only if they've been drawn into. Guess this by seeing if there's already
// a `CanvasRenderingContext`, which is only created by JavaScript.
if (is<HTMLCanvasElement>(element) && downcast<HTMLCanvasElement>(element).renderingContext())
if (RefPtr canvas = dynamicDowncast<HTMLCanvasElement>(*element); canvas && canvas->renderingContext())
return false;

// Skip 3rd-party `<iframe>` as the content likely won't match the rest of the page.
if (is<HTMLIFrameElement>(element))
if (is<HTMLIFrameElement>(*element))
return false;
}

Expand Down
22 changes: 10 additions & 12 deletions Source/WebCore/page/PageConsoleClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -340,24 +340,22 @@ void PageConsoleClient::screenshot(JSC::JSGlobalObject* lexicalGlobalObject, Ref
}
};

if (is<HTMLImageElement>(node))
snapshotImageElement(downcast<HTMLImageElement>(*node));
else if (is<HTMLPictureElement>(node)) {
if (auto* firstImage = childrenOfType<HTMLImageElement>(downcast<HTMLPictureElement>(*node)).first())
if (RefPtr imgElement = dynamicDowncast<HTMLImageElement>(node))
snapshotImageElement(*imgElement);
else if (RefPtr pictureElement = dynamicDowncast<HTMLPictureElement>(node)) {
if (RefPtr firstImage = childrenOfType<HTMLImageElement>(*pictureElement).first())
snapshotImageElement(*firstImage);
}
#if ENABLE(VIDEO)
else if (is<HTMLVideoElement>(node)) {
auto& videoElement = downcast<HTMLVideoElement>(*node);
unsigned videoWidth = videoElement.videoWidth();
unsigned videoHeight = videoElement.videoHeight();
else if (RefPtr videoElement = dynamicDowncast<HTMLVideoElement>(node)) {
unsigned videoWidth = videoElement->videoWidth();
unsigned videoHeight = videoElement->videoHeight();
snapshot = ImageBuffer::create(FloatSize(videoWidth, videoHeight), RenderingPurpose::Unspecified, 1, DestinationColorSpace::SRGB(), PixelFormat::BGRA8);
videoElement.paintCurrentFrameInContext(snapshot->context(), FloatRect(0, 0, videoWidth, videoHeight));
videoElement->paintCurrentFrameInContext(snapshot->context(), FloatRect(0, 0, videoWidth, videoHeight));
}
#endif
else if (is<HTMLCanvasElement>(node)) {
auto& canvasElement = downcast<HTMLCanvasElement>(*node);
if (auto* canvasRenderingContext = canvasElement.renderingContext()) {
else if (RefPtr canvasElement = dynamicDowncast<HTMLCanvasElement>(node)) {
if (auto* canvasRenderingContext = canvasElement->renderingContext()) {
if (auto result = InspectorCanvas::getContentAsDataURL(*canvasRenderingContext))
dataURL = result.value();
}
Expand Down
47 changes: 22 additions & 25 deletions Source/WebCore/page/PageSerializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,21 +142,21 @@ void PageSerializer::SerializerMarkupAccumulator::appendStartTag(StringBuilder&

void PageSerializer::SerializerMarkupAccumulator::appendCustomAttributes(StringBuilder& out, const Element& element, Namespaces* namespaces)
{
if (!is<HTMLFrameOwnerElement>(element))
RefPtr frameOwner = dynamicDowncast<HTMLFrameOwnerElement>(element);
if (!frameOwner)
return;

const HTMLFrameOwnerElement& frameOwner = downcast<HTMLFrameOwnerElement>(element);
auto* frame = dynamicDowncast<LocalFrame>(frameOwner.contentFrame());
auto* frame = dynamicDowncast<LocalFrame>(frameOwner->contentFrame());
if (!frame)
return;

URL url = frame->document()->url();
auto url = frame->document()->url();
if (url.isValid() && !url.protocolIsAbout())
return;

// We need to give a fake location to blank frames so they can be referenced by the serialized frame.
url = m_serializer.urlForBlankFrame(frame);
appendAttribute(out, element, Attribute(frameOwnerURLAttributeName(frameOwner), AtomString { url.string() }), namespaces);
appendAttribute(out, element, Attribute(frameOwnerURLAttributeName(*frameOwner), AtomString { url.string() }), namespaces);
}

void PageSerializer::SerializerMarkupAccumulator::appendEndTag(StringBuilder& out, const Element& element)
Expand Down Expand Up @@ -209,23 +209,21 @@ void PageSerializer::serializeFrame(LocalFrame* frame)
if (!element)
continue;
// We have to process in-line style as it might contain some resources (typically background images).
if (is<StyledElement>(*element))
retrieveResourcesForProperties(downcast<StyledElement>(*element).inlineStyle(), document);
if (RefPtr styledElement = dynamicDowncast<StyledElement>(*element))
retrieveResourcesForProperties(styledElement->inlineStyle(), document);

if (is<HTMLImageElement>(*element)) {
Ref imageElement = downcast<HTMLImageElement>(element.releaseNonNull());
URL url = document->completeURL(imageElement->attributeWithoutSynchronization(HTMLNames::srcAttr));
CachedImage* cachedImage = imageElement->cachedImage();
if (RefPtr imageElement = dynamicDowncast<HTMLImageElement>(*element)) {
auto url = document->completeURL(imageElement->attributeWithoutSynchronization(HTMLNames::srcAttr));
auto* cachedImage = imageElement->cachedImage();
addImageToResources(cachedImage, imageElement->renderer(), url);
} else if (is<HTMLLinkElement>(element)) {
Ref linkElement = downcast<HTMLLinkElement>(element.releaseNonNull());
} else if (RefPtr linkElement = dynamicDowncast<HTMLLinkElement>(*element)) {
if (RefPtr sheet = linkElement->sheet()) {
URL url = document->completeURL(linkElement->attributeWithoutSynchronization(HTMLNames::hrefAttr));
auto url = document->completeURL(linkElement->attributeWithoutSynchronization(HTMLNames::hrefAttr));
serializeCSSStyleSheet(sheet.get(), url);
ASSERT(m_resourceURLs.contains(url));
}
} else if (is<HTMLStyleElement>(element)) {
if (RefPtr sheet = downcast<HTMLStyleElement>(*element).sheet())
} else if (RefPtr styleElement = dynamicDowncast<HTMLStyleElement>(*element)) {
if (RefPtr sheet = styleElement->sheet())
serializeCSSStyleSheet(sheet.get(), URL());
}
}
Expand All @@ -251,17 +249,16 @@ void PageSerializer::serializeCSSStyleSheet(CSSStyleSheet* styleSheet, const URL
}
Document* document = styleSheet->ownerDocument();
// Some rules have resources associated with them that we need to retrieve.
if (is<CSSImportRule>(*rule)) {
CSSImportRule& importRule = downcast<CSSImportRule>(*rule);
URL importURL = document->completeURL(importRule.href());
if (RefPtr importRule = dynamicDowncast<CSSImportRule>(*rule)) {
auto importURL = document->completeURL(importRule->href());
if (m_resourceURLs.contains(importURL))
continue;
serializeCSSStyleSheet(importRule.styleSheet(), importURL);
serializeCSSStyleSheet(importRule->styleSheet(), importURL);
} else if (is<CSSFontFaceRule>(*rule)) {
// FIXME: Add support for font face rule. It is not clear to me at this point if the actual otf/eot file can
// be retrieved from the CSSFontFaceRule object.
} else if (is<CSSStyleRule>(*rule))
retrieveResourcesForRule(downcast<CSSStyleRule>(*rule).styleRule(), document);
} else if (RefPtr styleRule = dynamicDowncast<CSSStyleRule>(*rule))
retrieveResourcesForRule(styleRule->styleRule(), document);
}

if (url.isValid() && !m_resourceURLs.contains(url)) {
Expand Down Expand Up @@ -308,11 +305,11 @@ void PageSerializer::retrieveResourcesForProperties(const StyleProperties* style
// that make use of images. We iterate to make sure we include any other
// image properties there might be.
for (auto property : *styleDeclaration) {
auto cssValue = property.value();
if (!is<CSSImageValue>(*cssValue))
RefPtr cssValue = dynamicDowncast<CSSImageValue>(property.value());
if (!cssValue)
continue;

auto* image = downcast<CSSImageValue>(*cssValue).cachedImage();
auto* image = cssValue->cachedImage();
if (!image)
continue;

Expand Down
Loading

0 comments on commit b0ccbb2

Please sign in to comment.