script/dom/
xpathexpression.rs1use std::rc::Rc;
6
7use dom_struct::dom_struct;
8use js::rust::HandleObject;
9
10use crate::dom::bindings::codegen::Bindings::XPathExpressionBinding::XPathExpressionMethods;
11use crate::dom::bindings::codegen::Bindings::XPathNSResolverBinding::XPathNSResolver;
12use crate::dom::bindings::error::{Error, Fallible};
13use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object_with_proto};
14use crate::dom::bindings::root::{Dom, DomRoot};
15use crate::dom::node::Node;
16use crate::dom::window::Window;
17use crate::dom::xpathresult::{XPathResult, XPathResultType};
18use crate::script_runtime::CanGc;
19use crate::xpath::{Expr, evaluate_parsed_xpath};
20
21#[dom_struct]
22pub(crate) struct XPathExpression {
23 reflector_: Reflector,
24 window: Dom<Window>,
25 #[no_trace]
26 parsed_expression: Expr,
27}
28
29impl XPathExpression {
30 fn new_inherited(window: &Window, parsed_expression: Expr) -> XPathExpression {
31 XPathExpression {
32 reflector_: Reflector::new(),
33 window: Dom::from_ref(window),
34 parsed_expression,
35 }
36 }
37
38 pub(crate) fn new(
39 window: &Window,
40 proto: Option<HandleObject>,
41 can_gc: CanGc,
42 parsed_expression: Expr,
43 ) -> DomRoot<XPathExpression> {
44 reflect_dom_object_with_proto(
45 Box::new(XPathExpression::new_inherited(window, parsed_expression)),
46 window,
47 proto,
48 can_gc,
49 )
50 }
51
52 pub(crate) fn evaluate_internal(
53 &self,
54 context_node: &Node,
55 result_type_num: u16,
56 result: Option<&XPathResult>,
57 resolver: Option<Rc<XPathNSResolver>>,
58 can_gc: CanGc,
59 ) -> Fallible<DomRoot<XPathResult>> {
60 let result_type = XPathResultType::try_from(result_type_num)
61 .map_err(|()| Error::Type("Invalid XPath result type".to_string()))?;
62
63 let global = self.global();
64 let window = global.as_window();
65
66 let result_value =
67 evaluate_parsed_xpath(&self.parsed_expression, context_node, resolver)?.into();
68
69 if let Some(result) = result {
70 result.reinitialize_with(result_type, result_value);
73 Ok(DomRoot::from_ref(result))
74 } else {
75 Ok(XPathResult::new(
76 window,
77 None,
78 can_gc,
79 result_type,
80 result_value,
81 ))
82 }
83 }
84}
85
86impl XPathExpressionMethods<crate::DomTypeHolder> for XPathExpression {
87 fn Evaluate(
89 &self,
90 context_node: &Node,
91 result_type_num: u16,
92 result: Option<&XPathResult>,
93 can_gc: CanGc,
94 ) -> Fallible<DomRoot<XPathResult>> {
95 self.evaluate_internal(context_node, result_type_num, result, None, can_gc)
96 }
97}