blitz_dom/
query_selector.rs1use selectors::SelectorList;
2use smallvec::SmallVec;
3use style::dom_apis::{MayUseInvalidation, QueryAll, QueryFirst, query_selector};
4use style::selector_parser::{SelectorImpl, SelectorParser};
5use style::stylesheets::UrlExtraData;
6use style_traits::ParseError;
7use url::Url;
8
9use crate::{BaseDocument, Node};
10
11impl BaseDocument {
12 pub fn query_selector<'input>(
18 &self,
19 selector: &'input str,
20 ) -> Result<Option<usize>, ParseError<'input>> {
21 let selector_list = self.try_parse_selector_list(selector)?;
22 Ok(self.query_selector_raw(&selector_list))
23 }
24
25 pub fn query_selector_raw(&self, selector_list: &SelectorList<SelectorImpl>) -> Option<usize> {
27 let root_node = self.root_node();
28 let mut result = None;
29 query_selector::<&Node, QueryFirst>(
30 root_node,
31 selector_list,
32 &mut result,
33 MayUseInvalidation::Yes,
34 );
35
36 result.map(|node| node.id)
37 }
38
39 pub fn query_selector_all<'input>(
44 &self,
45 selector: &'input str,
46 ) -> Result<SmallVec<[usize; 32]>, ParseError<'input>> {
47 let selector_list = self.try_parse_selector_list(selector)?;
48 Ok(self.query_selector_all_raw(&selector_list))
49 }
50
51 pub fn query_selector_all_raw(
53 &self,
54 selector_list: &SelectorList<SelectorImpl>,
55 ) -> SmallVec<[usize; 32]> {
56 let root_node = self.root_node();
57 let mut results = SmallVec::new();
58 query_selector::<&Node, QueryAll>(
59 root_node,
60 selector_list,
61 &mut results,
62 MayUseInvalidation::Yes,
63 );
64
65 results.iter().map(|node| node.id).collect()
66 }
67
68 pub fn try_parse_selector_list<'input>(
69 &self,
70 input: &'input str,
71 ) -> Result<SelectorList<SelectorImpl>, ParseError<'input>> {
72 let url_extra_data = UrlExtraData::from(self.base_url.clone().unwrap_or_else(|| {
73 "data:text/css;charset=utf-8;base64,"
74 .parse::<Url>()
75 .unwrap()
76 }));
77 SelectorParser::parse_author_origin_no_namespace(input, &url_extra_data)
78 }
79}