use crate::ast;
use crate::ast::ElementKind;
use crate::printer::Printer;
impl<'a> Printer<'a> {
pub(crate) fn is_block_element(&self, element: &ast::Element<'_>) -> bool {
if element.kind == ElementKind::Component {
return false;
}
let facts = element.facts;
if facts.is_raw_text() && has_raw_content(element) {
return true;
}
facts.is_block()
}
}
pub(crate) fn has_raw_content(element: &ast::Element<'_>) -> bool {
use crate::ast::FragmentNode;
element
.fragment
.nodes
.iter()
.any(|node| !matches!(node, FragmentNode::Text(t) if t.raw_span.range().is_empty()))
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ast::FragmentNode;
use crate::html;
fn child<'p, 'arena>(
printer: &Printer<'_>,
parent: &'p ast::Element<'arena>,
tag: &str,
) -> &'p ast::Element<'arena> {
parent
.fragment
.nodes
.iter()
.find_map(|n| match n {
FragmentNode::Element(el) if el.name(printer.source) == tag => Some(el),
_ => None,
})
.unwrap_or_else(|| panic!("no <{tag}> child"))
}
#[test]
fn block_adapter_delegates_and_treats_components_as_inline() {
let src = "<div><span>i</span><Comp>c</Comp></div>";
let arena = bumpalo::Bump::new();
let root = crate::__private::parse(src, &arena).expect("template should parse");
let doc_arena = tsv_lang::doc::arena::DocArena::for_source(src);
let printer = Printer::new(&doc_arena, src, &[]);
let div = match &root.fragment.nodes[0] {
FragmentNode::Element(el) => el,
other => panic!("expected a <div>, got: {other:?}"),
};
assert!(printer.is_block_element(div));
assert!(!printer.is_block_element(child(&printer, div, "span")));
assert!(!printer.is_block_element(child(&printer, div, "Comp")));
}
#[test]
fn block_adapter_promotes_nonempty_script_style_to_block() {
assert!(!html::is_block_element("script"));
assert!(!html::is_block_element("style"));
let src = "<div><script>let x = 1;</script><style>a { color: red }</style></div>";
let arena = bumpalo::Bump::new();
let root = crate::__private::parse(src, &arena).expect("template should parse");
let doc_arena = tsv_lang::doc::arena::DocArena::for_source(src);
let printer = Printer::new(&doc_arena, src, &[]);
let div = match &root.fragment.nodes[0] {
FragmentNode::Element(el) => el,
other => panic!("expected a <div>, got: {other:?}"),
};
assert!(printer.is_block_element(child(&printer, div, "script")));
assert!(printer.is_block_element(child(&printer, div, "style")));
}
#[test]
fn block_adapter_treats_empty_script_style_as_inline() {
let src = "<div><script></script><style></style></div>";
let arena = bumpalo::Bump::new();
let root = crate::__private::parse(src, &arena).expect("template should parse");
let doc_arena = tsv_lang::doc::arena::DocArena::for_source(src);
let printer = Printer::new(&doc_arena, src, &[]);
let div = match &root.fragment.nodes[0] {
FragmentNode::Element(el) => el,
other => panic!("expected a <div>, got: {other:?}"),
};
assert!(!printer.is_block_element(child(&printer, div, "script")));
assert!(!printer.is_block_element(child(&printer, div, "style")));
}
}