use super::dom::{Attrs, Element, attr_value, elements, open_tags, strip_text};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DisabledAction {
pub name: String,
pub reason: String,
}
pub fn confirms_first(html: &str, action: &str) -> Option<bool> {
open_tags(html)
.into_iter()
.find(|(tag, attrs, _)| {
tag == "button" && attr_value(attrs, "formaction").as_deref() == Some(action)
})
.map(|(_, attrs, _)| attr_value(&attrs, "type").as_deref() == Some("button"))
}
fn posting_button(html: &str, url: &str) -> Option<Element> {
let posts_to = |attrs: &Attrs, name: &str| {
attr_value(attrs, name).is_some_and(|posted| posted.split('?').next() == Some(url))
};
elements(html, "button")
.into_iter()
.find(|(_, attrs, _)| posts_to(attrs, "formaction"))
.or_else(|| {
elements(html, "form")
.into_iter()
.find(|(_, attrs, _)| posts_to(attrs, "action"))
.and_then(|(_, _, inner)| elements(&inner, "button").into_iter().next())
})
}
pub fn action_label(html: &str, url: &str) -> Option<String> {
posting_button(html, url).map(|(_, _, inner)| strip_text(&inner))
}
pub fn action_tooltip(html: &str, url: &str) -> Option<String> {
posting_button(html, url).and_then(|(_, attrs, _)| attr_value(&attrs, "title"))
}
pub fn action_badge(html: &str, url: &str) -> Option<String> {
let (_, _, inner) = posting_button(html, url)?;
elements(&inner, "span")
.into_iter()
.find(|(_, attrs, _)| attr_value(attrs, "data-action-badge").is_some())
.map(|(_, _, count)| strip_text(&count))
}
pub fn selects_matching(html: &str) -> bool {
open_tags(html).iter().any(|(tag, attrs, _)| {
tag == "button" && attr_value(attrs, "data-select-matching").is_some()
})
}
pub fn disabled_actions(html: &str) -> Vec<DisabledAction> {
open_tags(html)
.into_iter()
.filter_map(|(_, attrs, _)| {
Some(DisabledAction {
name: attr_value(&attrs, "data-disabled-action")?,
reason: attr_value(&attrs, "title").unwrap_or_default(),
})
})
.collect()
}