script: Fix two issues in the XPath parser to pass all xml_xpath_tests.xml tests (#37279)

1. Better handling of namespaces for element and attribute names in XML
mode (read: non-HTML mode)
2. While parsing, pass along context on whether we are in an absolute
(`/`) or descendant (`//`) part of the query, and use it to correctly
enumerate descendants according to where we are in the evaluation of the
AST.

Testing: All 1024 tests in `xml_xpath_tests.xml` (actually
`xml_xpath_runner.html`) pass, as well as some random tests in
`text-html-attributes.html`.
Fixes: #37278

---------

Signed-off-by: Ville Lindholm <ville@lindholm.dev>
This commit is contained in:
Ville Lindholm 2025-06-06 10:16:42 +03:00 committed by GitHub
parent c7eba2dbba
commit 475a3dfa38
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 104 additions and 3140 deletions

View file

@ -5,10 +5,14 @@
use std::iter::Enumerate;
use std::vec::IntoIter;
use script_bindings::str::DOMString;
use super::Node;
use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use crate::dom::bindings::root::DomRoot;
/// The context during evaluation of an XPath expression.
#[derive(Debug)]
pub(crate) struct EvaluationCtx {
/// Where we started at
pub(crate) starting_node: DomRoot<Node>,
@ -20,7 +24,7 @@ pub(crate) struct EvaluationCtx {
pub(crate) predicate_nodes: Option<Vec<DomRoot<Node>>>,
}
#[derive(Clone, Copy)]
#[derive(Clone, Copy, Debug)]
pub(crate) struct PredicateCtx {
pub(crate) index: usize,
pub(crate) size: usize,
@ -68,6 +72,12 @@ impl EvaluationCtx {
size,
}
}
/// Resolve a namespace prefix using the context node's document
pub(crate) fn resolve_namespace(&self, prefix: Option<&str>) -> Option<DOMString> {
self.context_node
.LookupNamespaceURI(prefix.map(DOMString::from))
}
}
/// When evaluating predicates, we need to keep track of the current node being evaluated and