mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
XPath: implement lang() and id() core functions (#34594)
XPath's `lang()` and `id()` functions were still unimplemented. Also: * Add WPT tests for `id()`. * Fix uniqueness check in `NodesetHelpers::document_order_unique`. * Tweak the AST a bit to make it clearer to express "no predicates". * Fix a parsing bug where "/" was attempted before "//", leaving the "//" branch as always unused. --- - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #34593 - [x] There are tests for these changes --------- Signed-off-by: Ville Lindholm <ville@lindholm.dev>
This commit is contained in:
parent
1dfc14d2fb
commit
8cfb6e33fe
11 changed files with 276 additions and 61 deletions
|
@ -542,7 +542,7 @@ fn relative_path_expr(input: &str) -> IResult<&str, Expr> {
|
|||
let (input, first) = step_expr(input)?;
|
||||
let (input, steps) = many0(pair(
|
||||
// ("/" | "//")
|
||||
ws(alt((value(false, char('/')), value(true, tag("//"))))),
|
||||
ws(alt((value(true, tag("//")), value(false, char('/'))))),
|
||||
step_expr,
|
||||
))(input)?;
|
||||
|
||||
|
@ -592,12 +592,7 @@ fn axis_step(input: &str) -> IResult<&str, AxisStep> {
|
|||
}
|
||||
|
||||
fn forward_step(input: &str) -> IResult<&str, (Axis, NodeTest)> {
|
||||
alt((
|
||||
// ForwardAxis NodeTest
|
||||
pair(forward_axis, node_test),
|
||||
// AbbrevForwardStep
|
||||
abbrev_forward_step,
|
||||
))(input)
|
||||
alt((pair(forward_axis, node_test), abbrev_forward_step))(input)
|
||||
}
|
||||
|
||||
fn forward_axis(input: &str) -> IResult<&str, Axis> {
|
||||
|
@ -704,6 +699,7 @@ fn filter_expr(input: &str) -> IResult<&str, FilterExpr> {
|
|||
|
||||
fn predicate_list(input: &str) -> IResult<&str, PredicateListExpr> {
|
||||
let (input, predicates) = many0(predicate)(input)?;
|
||||
|
||||
Ok((input, PredicateListExpr { predicates }))
|
||||
}
|
||||
|
||||
|
@ -1195,6 +1191,118 @@ mod tests {
|
|||
],
|
||||
}),
|
||||
),
|
||||
(
|
||||
"//mu[@xml:id=\"id1\"]//rho[@title][@xml:lang=\"en-GB\"]",
|
||||
Expr::Path(PathExpr {
|
||||
is_absolute: true,
|
||||
is_descendant: true,
|
||||
steps: vec![
|
||||
StepExpr::Axis(AxisStep {
|
||||
axis: Axis::Child,
|
||||
node_test: NodeTest::Name(QName {
|
||||
prefix: None,
|
||||
local_part: "mu".to_string(),
|
||||
}),
|
||||
predicates: PredicateListExpr {
|
||||
predicates: vec![PredicateExpr {
|
||||
expr: Expr::Equality(
|
||||
Box::new(Expr::Path(PathExpr {
|
||||
is_absolute: false,
|
||||
is_descendant: false,
|
||||
steps: vec![StepExpr::Axis(AxisStep {
|
||||
axis: Axis::Attribute,
|
||||
node_test: NodeTest::Name(QName {
|
||||
prefix: Some("xml".to_string()),
|
||||
local_part: "id".to_string(),
|
||||
}),
|
||||
predicates: PredicateListExpr {
|
||||
predicates: vec![],
|
||||
},
|
||||
})],
|
||||
})),
|
||||
EqualityOp::Eq,
|
||||
Box::new(Expr::Path(PathExpr {
|
||||
is_absolute: false,
|
||||
is_descendant: false,
|
||||
steps: vec![StepExpr::Filter(FilterExpr {
|
||||
primary: PrimaryExpr::Literal(Literal::String(
|
||||
"id1".to_string(),
|
||||
)),
|
||||
predicates: PredicateListExpr {
|
||||
predicates: vec![],
|
||||
},
|
||||
})],
|
||||
})),
|
||||
),
|
||||
}],
|
||||
},
|
||||
}),
|
||||
StepExpr::Axis(AxisStep {
|
||||
axis: Axis::DescendantOrSelf, // Represents the second '//'
|
||||
node_test: NodeTest::Kind(KindTest::Node),
|
||||
predicates: PredicateListExpr { predicates: vec![] },
|
||||
}),
|
||||
StepExpr::Axis(AxisStep {
|
||||
axis: Axis::Child,
|
||||
node_test: NodeTest::Name(QName {
|
||||
prefix: None,
|
||||
local_part: "rho".to_string(),
|
||||
}),
|
||||
predicates: PredicateListExpr {
|
||||
predicates: vec![
|
||||
PredicateExpr {
|
||||
expr: Expr::Path(PathExpr {
|
||||
is_absolute: false,
|
||||
is_descendant: false,
|
||||
steps: vec![StepExpr::Axis(AxisStep {
|
||||
axis: Axis::Attribute,
|
||||
node_test: NodeTest::Name(QName {
|
||||
prefix: None,
|
||||
local_part: "title".to_string(),
|
||||
}),
|
||||
predicates: PredicateListExpr {
|
||||
predicates: vec![],
|
||||
},
|
||||
})],
|
||||
}),
|
||||
},
|
||||
PredicateExpr {
|
||||
expr: Expr::Equality(
|
||||
Box::new(Expr::Path(PathExpr {
|
||||
is_absolute: false,
|
||||
is_descendant: false,
|
||||
steps: vec![StepExpr::Axis(AxisStep {
|
||||
axis: Axis::Attribute,
|
||||
node_test: NodeTest::Name(QName {
|
||||
prefix: Some("xml".to_string()),
|
||||
local_part: "lang".to_string(),
|
||||
}),
|
||||
predicates: PredicateListExpr {
|
||||
predicates: vec![],
|
||||
},
|
||||
})],
|
||||
})),
|
||||
EqualityOp::Eq,
|
||||
Box::new(Expr::Path(PathExpr {
|
||||
is_absolute: false,
|
||||
is_descendant: false,
|
||||
steps: vec![StepExpr::Filter(FilterExpr {
|
||||
primary: PrimaryExpr::Literal(Literal::String(
|
||||
"en-GB".to_string(),
|
||||
)),
|
||||
predicates: PredicateListExpr {
|
||||
predicates: vec![],
|
||||
},
|
||||
})],
|
||||
})),
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
],
|
||||
}),
|
||||
),
|
||||
];
|
||||
|
||||
for (input, expected) in cases {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue