Skip to content

Commit

Permalink
Adopt more dynamicDowncast<> in XML code
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=268460

Reviewed by Chris Dumez.

* Source/WebCore/xml/XPathFunctions.cpp:
(WebCore::XPath::expandedNameLocalPart):
(WebCore::XPath::expandedName):
(WebCore::XPath::FunLocalName::evaluate const):
(WebCore::XPath::FunName::evaluate const):
(WebCore::XPath::FunLang::evaluate const):
* Source/WebCore/xml/XPathStep.cpp:
(WebCore::XPath::nodeMatchesBasicTest):
(WebCore::XPath::Step::nodesInAxis const):
* Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp:
(WebCore::XMLDocumentParser::startElementNs):

Canonical link: https://commits.webkit.org/273878@main
  • Loading branch information
annevk committed Feb 1, 2024
1 parent 0d37807 commit 0150236
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 31 deletions.
31 changes: 15 additions & 16 deletions Source/WebCore/xml/XPathFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -353,16 +353,16 @@ Value FunId::evaluate() const
return Value(WTFMove(result));
}

static inline String expandedNameLocalPart(Node* node)
static inline String expandedNameLocalPart(Node& node)
{
if (is<ProcessingInstruction>(*node))
return downcast<ProcessingInstruction>(*node).target();
return node->localName().string();
if (auto* pi = dynamicDowncast<ProcessingInstruction>(node))
return pi->target();
return node.localName().string();
}

static inline String expandedName(Node* node)
static inline String expandedName(Node& node)
{
const AtomString& prefix = node->prefix();
auto& prefix = node.prefix();
return prefix.isEmpty() ? expandedNameLocalPart(node) : prefix + ":" + expandedNameLocalPart(node);
}

Expand All @@ -373,11 +373,11 @@ Value FunLocalName::evaluate() const
if (!a.isNodeSet())
return emptyString();

Node* node = a.toNodeSet().firstNode();
return node ? expandedNameLocalPart(node) : emptyString();
auto* node = a.toNodeSet().firstNode();
return node ? expandedNameLocalPart(*node) : emptyString();
}

return expandedNameLocalPart(evaluationContext().node.get());
return expandedNameLocalPart(*evaluationContext().node);
}

Value FunNamespaceURI::evaluate() const
Expand All @@ -401,11 +401,11 @@ Value FunName::evaluate() const
if (!a.isNodeSet())
return emptyString();

Node* node = a.toNodeSet().firstNode();
return node ? expandedName(node) : emptyString();
auto* node = a.toNodeSet().firstNode();
return node ? expandedName(*node) : emptyString();
}

return expandedName(evaluationContext().node.get());
return expandedName(*evaluationContext().node);
}

Value FunCount::evaluate() const
Expand Down Expand Up @@ -627,10 +627,9 @@ Value FunLang::evaluate() const
const Attribute* languageAttribute = nullptr;
Node* node = evaluationContext().node.get();
while (node) {
if (is<Element>(*node)) {
Element& element = downcast<Element>(*node);
if (element.hasAttributes())
languageAttribute = element.findAttributeByName(XMLNames::langAttr);
if (RefPtr element = dynamicDowncast<Element>(*node)) {
if (element->hasAttributes())
languageAttribute = element->findAttributeByName(XMLNames::langAttr);
}
if (languageAttribute)
break;
Expand Down
26 changes: 13 additions & 13 deletions Source/WebCore/xml/XPathStep.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,21 +200,22 @@ inline bool nodeMatchesBasicTest(Node& node, Step::Axis axis, const Step::NodeTe

// For other axes, the principal node type is element.
ASSERT(primaryNodeType(axis) == Node::ELEMENT_NODE);
if (!is<Element>(node))
auto* element = dynamicDowncast<Element>(node);
if (!element)
return false;

if (name == starAtom())
return namespaceURI.isEmpty() || namespaceURI == node.namespaceURI();

if (node.document().isHTMLDocument()) {
if (is<HTMLElement>(node)) {
if (is<HTMLElement>(*element)) {
// Paths without namespaces should match HTML elements in HTML documents despite those having an XHTML namespace. Names are compared case-insensitively.
return equalIgnoringASCIICase(downcast<HTMLElement>(node).localName(), name) && (namespaceURI.isNull() || namespaceURI == node.namespaceURI());
return equalIgnoringASCIICase(element->localName(), name) && (namespaceURI.isNull() || namespaceURI == node.namespaceURI());
}
// An expression without any prefix shouldn't match no-namespace nodes (because HTML5 says so).
return downcast<Element>(node).hasLocalName(name) && namespaceURI == node.namespaceURI() && !namespaceURI.isNull();
return element->hasLocalName(name) && namespaceURI == node.namespaceURI() && !namespaceURI.isNull();
}
return downcast<Element>(node).hasLocalName(name) && namespaceURI == node.namespaceURI();
return element->hasLocalName(name) && namespaceURI == node.namespaceURI();
}
}
ASSERT_NOT_REACHED();
Expand Down Expand Up @@ -347,32 +348,31 @@ void Step::nodesInAxis(Node& context, NodeSet& nodes) const
return;
}
case AttributeAxis: {
if (!is<Element>(context))
RefPtr contextElement = dynamicDowncast<Element>(context);
if (!contextElement)
return;

Element& contextElement = downcast<Element>(context);

// Avoid lazily creating attribute nodes for attributes that we do not need anyway.
if (m_nodeTest.m_kind == NodeTest::NameTest && m_nodeTest.m_data != starAtom()) {
RefPtr<Attr> attr;
// We need this branch because getAttributeNodeNS() doesn't do
// ignore-case matching even for an HTML element in an HTML document.
if (m_nodeTest.m_namespaceURI.isNull())
attr = contextElement.getAttributeNode(m_nodeTest.m_data);
attr = contextElement->getAttributeNode(m_nodeTest.m_data);
else
attr = contextElement.getAttributeNodeNS(m_nodeTest.m_namespaceURI, m_nodeTest.m_data);
attr = contextElement->getAttributeNodeNS(m_nodeTest.m_namespaceURI, m_nodeTest.m_data);
if (attr && attr->namespaceURI() != XMLNSNames::xmlnsNamespaceURI) { // In XPath land, namespace nodes are not accessible on the attribute axis.
if (nodeMatches(*attr, AttributeAxis, m_nodeTest)) // Still need to check merged predicates.
nodes.append(WTFMove(attr));
}
return;
}

if (!contextElement.hasAttributes())
if (!contextElement->hasAttributes())
return;

for (const Attribute& attribute : contextElement.attributesIterator()) {
auto attr = contextElement.ensureAttr(attribute.name());
for (const Attribute& attribute : contextElement->attributesIterator()) {
auto attr = contextElement->ensureAttr(attribute.name());
if (nodeMatches(attr.get(), AttributeAxis, m_nodeTest))
nodes.append(WTFMove(attr));
}
Expand Down
4 changes: 2 additions & 2 deletions Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -837,8 +837,8 @@ void XMLDocumentParser::startElementNs(const xmlChar* xmlLocalName, const xmlCha
if (!m_currentNode) // Synchronous DOM events may have removed the current node.
return;

if (is<HTMLTemplateElement>(newElement))
pushCurrentNode(&downcast<HTMLTemplateElement>(newElement.get()).content());
if (RefPtr templateElement = dynamicDowncast<HTMLTemplateElement>(newElement))
pushCurrentNode(&templateElement->content());
else
pushCurrentNode(newElement.ptr());

Expand Down

0 comments on commit 0150236

Please sign in to comment.