use vize_relief::ast::{ElementNode, ElementType, TemplateChildNode};
pub const DEPRECATED_ELEMENTS: &[&str] = &[
"acronym",
"applet",
"basefont",
"bgsound",
"big",
"blink",
"center",
"dir",
"font",
"frame",
"frameset",
"isindex",
"keygen",
"listing",
"marquee",
"menuitem",
"multicol",
"nextid",
"nobr",
"noembed",
"noframes",
"plaintext",
"rb",
"rtc",
"spacer",
"strike",
"tt",
"xmp",
];
pub fn deprecated_attr_suggestion(element: &str, attr: &str) -> Option<&'static str> {
match (element, attr) {
(_, "align") => Some("CSS `text-align` or `margin: auto`"),
(_, "bgcolor") => Some("CSS `background-color`"),
(_, "border") if element != "table" => Some("CSS `border`"),
("body", "background") => Some("CSS `background-image`"),
("body", "text") => Some("CSS `color`"),
("body", "link" | "vlink" | "alink") => Some("CSS `:link`, `:visited`"),
("table", "cellpadding") => Some("CSS `padding` on cells"),
("table", "cellspacing") => Some("CSS `border-spacing`"),
("td" | "th", "width" | "height") => Some("CSS `width`/`height`"),
("td" | "th", "valign") => Some("CSS `vertical-align`"),
("td" | "th", "nowrap") => Some("CSS `white-space: nowrap`"),
("img", "hspace" | "vspace") => Some("CSS `margin`"),
("br", "clear") => Some("CSS `clear`"),
("hr", "noshade" | "size" | "width" | "color") => Some("CSS styling"),
("li", "type") => Some("CSS `list-style-type`"),
("ul", "type") => Some("CSS `list-style-type`"),
("pre", "width") => Some("CSS `width`"),
_ => None,
}
}
pub const BOOLEAN_ATTRIBUTES: &[&str] = &[
"allowfullscreen",
"async",
"autofocus",
"autoplay",
"checked",
"controls",
"default",
"defer",
"disabled",
"formnovalidate",
"hidden",
"inert",
"ismap",
"itemscope",
"loop",
"multiple",
"muted",
"nomodule",
"novalidate",
"open",
"playsinline",
"readonly",
"required",
"reversed",
"selected",
];
pub const PALPABLE_CONTENT_ELEMENTS: &[&str] = &[
"p",
"li",
"dt",
"dd",
"th",
"td",
"figcaption",
"summary",
"legend",
"caption",
"label",
"option",
];
pub fn has_palpable_content(element: &ElementNode) -> bool {
for child in &element.children {
match child {
TemplateChildNode::Text(text) if !text.content.trim().is_empty() => return true,
TemplateChildNode::Interpolation(_) => return true,
TemplateChildNode::Element(el) if el.tag_type != ElementType::Template => return true,
_ => {}
}
}
false
}
pub fn is_valid_datetime(s: &str) -> bool {
let s = s.trim();
if s.is_empty() {
return false;
}
if let Some(rest) = s.strip_prefix('P') {
return rest
.chars()
.all(|c| c.is_ascii_digit() || "YMWDTHS.".contains(c));
}
if !s.chars().any(|c| c.is_ascii_digit()) {
return false;
}
s.chars()
.all(|c| c.is_ascii_digit() || "-:TtZz+. W".contains(c))
}
pub fn walk_elements<'a, F>(children: &[TemplateChildNode<'a>], visitor: &mut F)
where
F: FnMut(&ElementNode<'a>),
{
for child in children {
match child {
TemplateChildNode::Element(el) => {
visitor(el);
walk_elements(&el.children, visitor);
}
TemplateChildNode::If(if_node) => {
for branch in if_node.branches.iter() {
walk_elements(&branch.children, visitor);
}
}
TemplateChildNode::For(for_node) => {
walk_elements(&for_node.children, visitor);
}
_ => {}
}
}
}