tablo_test/protocol/
page_filters.rs1use super::dom::{attr_value, elements, is_selected, open_tags, tags_where};
5
6#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct PageFilterBar {
9 pub submits: Vec<(String, String)>,
13 pub reset: Option<String>,
15}
16
17pub fn page_filter_bar(html: &str) -> Option<PageFilterBar> {
19 let (_, _, form) = tags_where(html, |tag, attrs| {
20 tag == "form" && attr_value(attrs, "data-page-filters").is_some()
21 })
22 .into_iter()
23 .next()?;
24 let mut submits: Vec<(usize, String, String)> = open_tags(&form)
25 .into_iter()
26 .filter(|(tag, _, _)| tag == "input")
27 .filter_map(|(_, attrs, at)| {
28 Some((
29 at,
30 attr_value(&attrs, "name")?,
31 attr_value(&attrs, "value").unwrap_or_default(),
32 ))
33 })
34 .collect();
35 let selects = open_tags(&form)
36 .into_iter()
37 .filter(|(tag, _, _)| tag == "select")
38 .map(|(_, attrs, at)| (at, attr_value(&attrs, "name")));
39 for ((at, name), (_, _, inner)) in selects.zip(elements(&form, "select")) {
40 let Some(name) = name else { continue };
41 let options = elements(&inner, "option");
42 let chosen = options
43 .iter()
44 .find(|(_, attrs, _)| is_selected(attrs))
45 .or(options.first())
46 .and_then(|(_, attrs, _)| attr_value(attrs, "value"))
47 .unwrap_or_default();
48 submits.push((at, name, chosen));
49 }
50 submits.sort_by_key(|(at, _, _)| *at);
51 let reset = tags_where(&form, |tag, attrs| {
52 tag == "a" && attr_value(attrs, "data-page-filters-reset").is_some()
53 })
54 .into_iter()
55 .next()
56 .and_then(|(_, attrs, _)| attr_value(&attrs, "href"));
57 Some(PageFilterBar {
58 submits: submits
59 .into_iter()
60 .map(|(_, name, value)| (name, value))
61 .collect(),
62 reset,
63 })
64}