1use std::iter::Enumerate;
6use std::vec::IntoIter;
7
8use script_bindings::str::DOMString;
9
10use super::Node;
11use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
12use crate::dom::bindings::root::DomRoot;
13
14#[derive(Debug)]
16pub(crate) struct EvaluationCtx {
17 pub(crate) starting_node: DomRoot<Node>,
19 pub(crate) context_node: DomRoot<Node>,
21 pub(crate) predicate_ctx: Option<PredicateCtx>,
23 pub(crate) predicate_nodes: Option<Vec<DomRoot<Node>>>,
25}
26
27#[derive(Clone, Copy, Debug)]
28pub(crate) struct PredicateCtx {
29 pub(crate) index: usize,
30 pub(crate) size: usize,
31}
32
33impl EvaluationCtx {
34 pub(crate) fn new(context_node: &Node) -> EvaluationCtx {
36 EvaluationCtx {
37 starting_node: DomRoot::from_ref(context_node),
38 context_node: DomRoot::from_ref(context_node),
39 predicate_ctx: None,
40 predicate_nodes: None,
41 }
42 }
43
44 pub(crate) fn subcontext_for_node(&self, node: &Node) -> EvaluationCtx {
46 EvaluationCtx {
47 starting_node: self.starting_node.clone(),
48 context_node: DomRoot::from_ref(node),
49 predicate_ctx: self.predicate_ctx,
50 predicate_nodes: self.predicate_nodes.clone(),
51 }
52 }
53
54 pub(crate) fn update_predicate_nodes(&self, nodes: Vec<&Node>) -> EvaluationCtx {
55 EvaluationCtx {
56 starting_node: self.starting_node.clone(),
57 context_node: self.context_node.clone(),
58 predicate_ctx: None,
59 predicate_nodes: Some(nodes.into_iter().map(DomRoot::from_ref).collect()),
60 }
61 }
62
63 pub(crate) fn subcontext_iter_for_nodes(&self) -> EvalNodesetIter<'_> {
64 let size = self.predicate_nodes.as_ref().map_or(0, |v| v.len());
65 EvalNodesetIter {
66 ctx: self,
67 nodes_iter: self
68 .predicate_nodes
69 .as_ref()
70 .map_or_else(|| Vec::new().into_iter(), |v| v.clone().into_iter())
71 .enumerate(),
72 size,
73 }
74 }
75
76 pub(crate) fn resolve_namespace(&self, prefix: Option<&str>) -> Option<DOMString> {
78 self.context_node
79 .LookupNamespaceURI(prefix.map(DOMString::from))
80 }
81}
82
83pub(crate) struct EvalNodesetIter<'a> {
86 ctx: &'a EvaluationCtx,
87 nodes_iter: Enumerate<IntoIter<DomRoot<Node>>>,
88 size: usize,
89}
90
91impl Iterator for EvalNodesetIter<'_> {
92 type Item = EvaluationCtx;
93
94 fn next(&mut self) -> Option<EvaluationCtx> {
95 self.nodes_iter.next().map(|(idx, node)| EvaluationCtx {
96 starting_node: self.ctx.starting_node.clone(),
97 context_node: node.clone(),
98 predicate_nodes: self.ctx.predicate_nodes.clone(),
99 predicate_ctx: Some(PredicateCtx {
100 index: idx + 1,
101 size: self.size,
102 }),
103 })
104 }
105}