Skip to content

Commit

Permalink
More dynamicDowncast<> adoption in editing and OffscreenCanvas
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=268256

Reviewed by Chris Dumez.

And increase RefPtr usage while there.

* Source/WebCore/editing/InsertLineBreakCommand.cpp:
(WebCore::InsertLineBreakCommand::doApply):
* Source/WebCore/editing/InsertParagraphSeparatorCommand.cpp:
(WebCore::isPhrasingContent):
(WebCore::InsertParagraphSeparatorCommand::doApply):
* Source/WebCore/editing/VisiblePosition.cpp:
(WebCore::midpoint):
* Source/WebCore/editing/cocoa/DataDetection.mm:
(WebCore::DataDetection::isDataDetectorLink):
(WebCore::searchForLinkRemovingExistingDDLinks):
(WebCore::DataDetection::detectContentInRange):
* Source/WebCore/html/OffscreenCanvas.cpp:
(WebCore::OffscreenCanvas::getContext):

Canonical link: https://commits.webkit.org/273709@main
  • Loading branch information
annevk committed Jan 30, 2024
1 parent 1b72851 commit 4146bc8
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 45 deletions.
13 changes: 6 additions & 7 deletions Source/WebCore/editing/InsertLineBreakCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,23 +117,22 @@ void InsertLineBreakCommand::doApply()
} else if (position.deprecatedEditingOffset() >= caretMaxOffset(*position.deprecatedNode()) || !is<Text>(*position.deprecatedNode())) {
insertNodeAt(*nodeToInsert, position);
setEndingSelection(VisibleSelection(positionInParentAfterNode(nodeToInsert.get()), Affinity::Downstream, endingSelection().isDirectional()));
} else if (is<Text>(*position.deprecatedNode())) {
} else if (RefPtr textNode = dynamicDowncast<Text>(*position.deprecatedNode())) {
// Split a text node
auto textNode = downcast<Text>(position.protectedDeprecatedNode().releaseNonNull());
splitTextNode(textNode, position.deprecatedEditingOffset());
insertNodeBefore(*nodeToInsert, textNode);
Position endingPosition = firstPositionInNode(textNode.ptr());
splitTextNode(*textNode, position.deprecatedEditingOffset());
insertNodeBefore(*nodeToInsert, *textNode);
Position endingPosition = firstPositionInNode(textNode.get());

// Handle whitespace that occurs after the split
document->updateLayoutIgnorePendingStylesheets();
if (!endingPosition.isRenderedCharacter()) {
Position positionBeforeTextNode(positionInParentBeforeNode(textNode.ptr()));
Position positionBeforeTextNode(positionInParentBeforeNode(textNode.get()));
// Clear out all whitespace and insert one non-breaking space
deleteInsignificantTextDownstream(endingPosition);
ASSERT(!textNode->renderer() || textNode->renderer()->style().collapseWhiteSpace());
// Deleting insignificant whitespace will remove textNode if it contains nothing but insignificant whitespace.
if (textNode->isConnected())
insertTextIntoNode(textNode, 0, nonBreakingSpaceString());
insertTextIntoNode(*textNode, 0, nonBreakingSpaceString());
else {
auto nbspNode = document->createTextNode(String { nonBreakingSpaceString() });
insertNodeAt(nbspNode.copyRef(), positionBeforeTextNode);
Expand Down
17 changes: 8 additions & 9 deletions Source/WebCore/editing/InsertParagraphSeparatorCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,11 @@ Ref<Element> InsertParagraphSeparatorCommand::cloneHierarchyUnderNewBlock(const

static bool isPhrasingContent(const Node& node)
{
if (!is<Element>(node))
RefPtr element = dynamicDowncast<Element>(node);
if (!element)
return false;

switch (downcast<Element>(node).elementName()) {
switch (element->elementName()) {
case ElementNames::HTML::a:
case ElementNames::HTML::abbr:
case ElementNames::HTML::area:
Expand Down Expand Up @@ -429,20 +430,18 @@ void InsertParagraphSeparatorCommand::doApply()
Position leadingWhitespace = insertionPosition.leadingWhitespacePosition(VisiblePosition::defaultAffinity);
// FIXME: leadingWhitespacePosition is returning the position before preserved newlines for positions
// after the preserved newline, causing the newline to be turned into a nbsp.
if (is<Text>(leadingWhitespace.deprecatedNode())) {
auto textNode = downcast<Text>(leadingWhitespace.protectedDeprecatedNode().releaseNonNull());
if (RefPtr textNode = dynamicDowncast<Text>(leadingWhitespace.deprecatedNode())) {
ASSERT(!textNode->renderer() || textNode->renderer()->style().collapseWhiteSpace());
replaceTextInNodePreservingMarkers(textNode.get(), leadingWhitespace.deprecatedEditingOffset(), 1, nonBreakingSpaceString());
replaceTextInNodePreservingMarkers(*textNode, leadingWhitespace.deprecatedEditingOffset(), 1, nonBreakingSpaceString());
}

// Split at pos if in the middle of a text node.
Position positionAfterSplit;
if (insertionPosition.anchorType() == Position::PositionIsOffsetInAnchor && is<Text>(*insertionPosition.containerNode())) {
Ref<Text> textNode = downcast<Text>(*insertionPosition.containerNode());
if (RefPtr textNode = dynamicDowncast<Text>(*insertionPosition.containerNode()); textNode && insertionPosition.anchorType() == Position::PositionIsOffsetInAnchor) {
bool atEnd = static_cast<unsigned>(insertionPosition.offsetInContainerNode()) >= textNode->length();
if (insertionPosition.deprecatedEditingOffset() > 0 && !atEnd) {
splitTextNode(textNode, insertionPosition.offsetInContainerNode());
positionAfterSplit = firstPositionInNode(textNode.ptr());
splitTextNode(*textNode, insertionPosition.offsetInContainerNode());
positionAfterSplit = firstPositionInNode(textNode.get());
if (!textNode->previousSibling())
return; // Bail out if mutation events detachd the split text node.
insertionPosition.moveToPosition(textNode->previousSibling(), insertionPosition.offsetInContainerNode());
Expand Down
4 changes: 3 additions & 1 deletion Source/WebCore/editing/VisiblePosition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -837,7 +837,9 @@ VisiblePosition midpoint(const VisiblePositionRange& range)
RefPtr rootNode = commonInclusiveAncestor(range);
if (!rootNode)
return { };
RefPtr rootContainerNode = rootNode->isContainerNode() ? downcast<ContainerNode>(WTFMove(rootNode)) : RefPtr { rootNode->parentNode() };
RefPtr rootContainerNode = dynamicDowncast<ContainerNode>(rootNode);
if (!rootContainerNode)
rootContainerNode = rootNode->parentNode();
if (!rootContainerNode)
return { };
auto scope = makeRangeSelectingNodeContents(*rootContainerNode);
Expand Down
39 changes: 18 additions & 21 deletions Source/WebCore/editing/cocoa/DataDetection.mm
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,8 @@

bool DataDetection::isDataDetectorLink(Element& element)
{
if (!is<HTMLAnchorElement>(element))
return false;

return canBePresentedByDataDetectors(downcast<HTMLAnchorElement>(element).href());
RefPtr anchor = dynamicDowncast<HTMLAnchorElement>(element);
return anchor && canBePresentedByDataDetectors(anchor->href());
}

bool DataDetection::requiresExtendedContext(Element& element)
Expand Down Expand Up @@ -292,12 +290,11 @@ static void removeResultLinksFromAnchor(Element& element)

static bool searchForLinkRemovingExistingDDLinks(Node& startNode, Node& endNode)
{
for (Node* node = &startNode; node; node = NodeTraversal::next(*node)) {
if (is<HTMLAnchorElement>(*node)) {
auto& anchor = downcast<HTMLAnchorElement>(*node);
if (!equalLettersIgnoringASCIICase(anchor.attributeWithoutSynchronization(x_apple_data_detectorsAttr), "true"_s))
for (auto* node = &startNode; node; node = NodeTraversal::next(*node)) {
if (RefPtr anchor = dynamicDowncast<HTMLAnchorElement>(*node)) {
if (!equalLettersIgnoringASCIICase(anchor->attributeWithoutSynchronization(x_apple_data_detectorsAttr), "true"_s))
return true;
removeResultLinksFromAnchor(anchor);
removeResultLinksFromAnchor(*anchor);
}

if (node == &endNode) {
Expand Down Expand Up @@ -586,28 +583,28 @@ static inline CFComparisonResult queryOffsetCompare(DDQueryOffset o1, DDQueryOff
if (!parentNode)
continue;

if (!is<Text>(range.start.container))
RefPtr currentTextNode = dynamicDowncast<Text>(range.start.container);
if (!currentTextNode)
continue;

auto& currentTextNode = downcast<Text>(range.start.container.get());
Document& document = currentTextNode.document();
auto& document = currentTextNode->document();
String textNodeData;

if (lastTextNodeToUpdate != &currentTextNode) {
if (lastTextNodeToUpdate != currentTextNode.get()) {
if (lastTextNodeToUpdate)
lastTextNodeToUpdate->setData(lastNodeContent);
if (range.start.offset > 0)
textNodeData = currentTextNode.data().left(range.start.offset);
textNodeData = currentTextNode->data().left(range.start.offset);
} else
textNodeData = currentTextNode.data().substring(contentOffset, range.start.offset - contentOffset);
textNodeData = currentTextNode->data().substring(contentOffset, range.start.offset - contentOffset);

if (!textNodeData.isEmpty())
parentNode->insertBefore(Text::create(document, WTFMove(textNodeData)), &currentTextNode);
parentNode->insertBefore(Text::create(document, WTFMove(textNodeData)), currentTextNode.get());

// Create the actual anchor node and insert it before the current node.
textNodeData = currentTextNode.data().substring(range.start.offset, range.end.offset - range.start.offset);
textNodeData = currentTextNode->data().substring(range.start.offset, range.end.offset - range.start.offset);
auto newTextNode = Text::create(document, WTFMove(textNodeData));
parentNode->insertBefore(newTextNode.copyRef(), &currentTextNode);
parentNode->insertBefore(newTextNode.copyRef(), currentTextNode.get());

Ref<HTMLAnchorElement> anchorElement = HTMLAnchorElement::create(document);
anchorElement->setHref(correspondingURL);
Expand Down Expand Up @@ -644,12 +641,12 @@ static inline CFComparisonResult queryOffsetCompare(DDQueryOffset o1, DDQueryOff
anchorElement->setAttributeWithoutSynchronization(x_apple_data_detectors_typeAttr, dataDetectorTypeForCategory(PAL::softLink_DataDetectorsCore_DDResultGetCategory(coreResult)));
anchorElement->setAttributeWithoutSynchronization(x_apple_data_detectors_resultAttr, identifier);

parentNode->insertBefore(WTFMove(anchorElement), &currentTextNode);
parentNode->insertBefore(WTFMove(anchorElement), currentTextNode.get());

contentOffset = range.end.offset;

lastNodeContent = currentTextNode.data().substring(range.end.offset, currentTextNode.length() - range.end.offset);
lastTextNodeToUpdate = &currentTextNode;
lastNodeContent = currentTextNode->data().substring(range.end.offset, currentTextNode->length() - range.end.offset);
lastTextNodeToUpdate = WTFMove(currentTextNode);
}
}

Expand Down
12 changes: 5 additions & 7 deletions Source/WebCore/html/OffscreenCanvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,14 +252,12 @@ ExceptionOr<std::optional<OffscreenRenderingContext>> OffscreenCanvas::getContex
if (!m_context) {
auto scope = DECLARE_THROW_SCOPE(state.vm());
RETURN_IF_EXCEPTION(scope, Exception { ExceptionCode::ExistingExceptionError });
auto* scriptExecutionContext = this->scriptExecutionContext();
if (scriptExecutionContext->isWorkerGlobalScope()) {
auto& globalScope = downcast<WorkerGlobalScope>(*scriptExecutionContext);
if (auto* gpu = globalScope.navigator().gpu())
Ref scriptExecutionContext = *this->scriptExecutionContext();
if (RefPtr globalScope = dynamicDowncast<WorkerGlobalScope>(scriptExecutionContext)) {
if (auto* gpu = globalScope->navigator().gpu())
m_context = GPUCanvasContext::create(*this, *gpu);
} else if (scriptExecutionContext->isDocument()) {
auto& document = downcast<Document>(*scriptExecutionContext);
if (auto* domWindow = document.domWindow()) {
} else if (RefPtr document = dynamicDowncast<Document>(scriptExecutionContext)) {
if (RefPtr domWindow = document->domWindow()) {
if (auto* gpu = domWindow->navigator().gpu())
m_context = GPUCanvasContext::create(*this, *gpu);
}
Expand Down

0 comments on commit 4146bc8

Please sign in to comment.