This fixes a warning of `cargo publish`:
```
warning: manifest has no description, documentation, homepage or repository
```
Testing: Compiling. Manual testing of `cargo publish --dry-run` (with
some additional patches, and until the next error, shows this warning
has been fixed)
Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
This is a preparation for publishing to crates.io. Changes include:
- Add `servo-` prefixes to avoid name collisions on crates.io
- Use `-` instead of `_` in package names.
- Rename the crates to their original names in Cargo.toml,
to keep the diff minimal
- Rename `media` to `servo-media-thread` to avoid name collision with
`servo-media` (originally from the media repository).
This is an outcome of the previous discussion at [#general > Switch
remaining git dependencies to
crates.io](https://servo.zulipchat.com/#narrow/channel/263398-general/topic/Switch.20remaining.20git.20dependencies.20to.20crates.2Eio/with/576336288)
Testing: This should be mostly covered by our CI, but some amount of
breakage is to be expected, since some package names could still be
referenced from scripts which are not tested or run in CI. [mach try
run](https://github.com/jschwe/servo/actions/runs/22502945949)
---------
Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
When a NodeSet is passed to the `id` function then we want to act as if
we were computing the union of individual `id` calls for each node in
the set. We weren't doing that before.
Depends on https://github.com/servo/servo/pull/40592
Testing: A new test starts to pass
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
The result of a predicate can depend on the position of the node in its
set, and this position is dependent on the axis that the node set came
from. This is specified in
https://www.w3.org/TR/1999/REC-xpath-19991116/#predicates.
Additionally, this change fixes a small bug in the implementation of
`preceding::` (https://github.com/servo/servo/pull/40588) where the root
of a subtree would be included twice. That wasn't discovered earlier
because nodes are deduplicated at the end of the evaluation.
Testing: New tests start to pass, this change adds more tests
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
`preceding::` needs to yield all preceding nodes, excluding ancestors.
`following::` needs to yield all following nodes, excluding descendants.
Both `Node::preceding_nodes` and `Node::following_nodes` (which we're
currently using) don't quite match these requirements, so we have to
engineer some xpath-specific iterators.
Testing: New tests start to pass
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
`translate` was incorrect in numerous ways before, so this change
completely replaces it.
Testing: This change adds a couple unit tests, a new xpathmark-ft test
starts to pass
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This change adds `NodeSet`, which is more or less a `Vec<Node>` that
knows whether it is sorted, and can sort itself if it isn't. This allows
us to efficiently enforce tree order in intermediary node sets that
occur during evaluation.
Notably, in many cases it is not necessary to sort at all, because all
location step expressions yield node sets that are either already sorted
(`Axis::DescendantOrSelf` for example), or that are in inverse tree
order (`Axis::PrecedingSiblings` for example).
There's still optimization work left to be done. When merging two node
sets that are already sorted then we could use merge sort instead of
appending one to the other and naively sorting. But I suspect that the
sorting algorithm used by the standard library is already well tuned to
handle such cases...
Testing: This change adds a web platform test
Fixes https://github.com/servo/servo/issues/40435
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This change fixes two panics and cleans up a bunch of the surrounding
code.
Testing: I've added new unit tests
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
I always thought that exceptions thrown in namespace resolver callbacks
should be propagated to the call site of `document.evaluate`.
That is not the case - the exception is silently swallowed and you get a
namespace error, the same as if the callback had returned any other
invalid value.
Testing: New web platform tests start to pass
Fixes https://github.com/servo/servo/issues/39931
Part of #34527
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
JS exceptions can't happen while evaluating an xpath expressions since
the namespace resolver callback is invoked during parsing.
Part of #34527
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
We don't need to care about namespace prefixes in name tests because
they are already resolved to namespaces at this point.
The old implementation was also masking a few other small bugs which
I've fixed here. When the namespace resolver doesn't give us any results
then we should not lookup the namespace on the node itself. In XPath,
namespaces on html elements in html documents are compared a in a
relaxed way, and we were previously also using the relaxed comparison
mode on non-html elements in html documents (like svg).
Testing: Existing tests continue to pass (and the web platform tests
contain numerous namespace tests which cover this behaviour)
Fixes https://github.com/servo/servo/issues/39939
Part of #34527
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
The current XPath AST is tightly tied to the parser grammar. To address
issues like https://github.com/servo/servo/issues/39739, we'll want to
do optimization passes on the AST in the future, which requires relaxing
it's structure first.
This PR moves the AST structure into a separate module and flattens it
into a shape where most expressions are variants of the core
`Expression` enum.
This also has the nice side effect of being a net reduction in LoC and
making the AST *significantly* easier to read.
I think the difference between the old and new structure is best
explained by example.
One of our unit tests parses `concat('hello', ' ', 'world')`, and the
current AST looks like this:
```rust
Expr::Path(PathExpr {
is_absolute: false,
is_descendant: false,
steps: vec![StepExpr::Filter(FilterExpr {
primary: PrimaryExpr::Function(CoreFunction::Concat(vec![
Expr::Path(PathExpr {
is_absolute: false,
is_descendant: false,
steps: vec![StepExpr::Filter(FilterExpr {
primary: PrimaryExpr::Literal(Literal::String(
"hello".to_string(),
)),
predicates: PredicateListExpr { predicates: vec![] },
})],
}),
Expr::Path(PathExpr {
is_absolute: false,
is_descendant: false,
steps: vec![StepExpr::Filter(FilterExpr {
primary: PrimaryExpr::Literal(Literal::String(" ".to_string())),
predicates: PredicateListExpr { predicates: vec![] },
})],
}),
Expr::Path(PathExpr {
is_absolute: false,
is_descendant: false,
steps: vec![StepExpr::Filter(FilterExpr {
primary: PrimaryExpr::Literal(Literal::String(
"world".to_string(),
)),
predicates: PredicateListExpr { predicates: vec![] },
})],
}),
])),
predicates: PredicateListExpr { predicates: vec![] },
})],
}),
```
After this change, the AST looks like this:
```rust
Expression::Function(CoreFunction::Concat(vec![
Expression::Literal(Literal::String("hello".to_string())),
Expression::Literal(Literal::String(" ".to_string())),
Expression::Literal(Literal::String("world".to_string())),
])),
```
Testing: No behaviour change intended, covered by existing tests.
Part of #34527
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
The current AST has different nodes for additive, multiplicative,
relational (etc) expressions. That is not a useful distinction, as they
are all treated more or less the same. Instead, I've unified these as
`Expression::Binary(lhs, binary_operator, rhs)`.
There are also some silly things that can be removed, like
```rust
enum UnaryOp {
Minus
}
```
This change is in preparation for an upcoming PR which will address
#39602 .
Testing: Covered by existing tests
Part of #34527
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
A NodeSet and a String are equal iff the text content of any node in the
set is equal to the string. Instead of creating a hashmap of text
contents and then calling `contains` on that, just iterate over the
nodeset and see if the string is in there.
Testing: This should not change behaviour and is thus covered by
existing tests
Part of #34527
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
The `number` function converts from arbitrary values to numbers. String
values are parsed as you would expect, and whitespace around them is
trimmed. We used to allow arbitrary whitespace, firefox allows only
ASCII. I've taken this opportunity to also implement a dummy DOM that we
can use for testing these kinds of things.
Testing: This change adds new tests
Part of #34527
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
A predicate expression is just a regular expressions. We can remove it
and make the AST a bit smaller (and easier to read).
Testing: Covered by existing tests
Part of #34527
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
The `Evaluatable` trait is used for enforcing a common interface for
expressions. Removing it allows us to pass additional parameters to some
functions that need them, which proves that a few errors are impossible
to reach.
Testing: Covered by existing tests
Part of #34527
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
*Most* of the properties that were verified here were already verified
by the xpath parser before. I have not found any evidence that other
browsers do the remaining checks. There are web platform tests that
expect contradicting behavior (which pass in other browsers).
Additionally, this change switches `xpath` to use `markup5ever` instead
of `html5ever` - this is a drop-in replacement. I thought I did this as
part of https://github.com/servo/servo/pull/39546 but apparently the
change got lost in the rebasing.
Testing: A new web platform test starts to pass.
Fixes https://github.com/servo/servo/issues/39442
Part of #34527
cc @minghuaw
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
XPath (and, in the future, XSLT) is only loosely coupled to `script`. As
`script` is already very large, I'd like to move the xpath parser and
evaluator into a seperate crate. Doing so allows us to iterate on it
more easily, without having to recompile `script`. Abstracting over the
concrete DOM implementation could also allow us to write some more
comprehensive unit tests.
Testing: Covered by existing web platform tests
Part of https://github.com/servo/servo/issues/34527
Fixes https://github.com/servo/servo/issues/39551
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>