use vize_carton::Vec;
use vize_relief::ast::TemplateChildNode;
pub(super) fn condense_whitespace<'a>(children: &mut Vec<'a, TemplateChildNode<'a>>) {
while !children.is_empty() {
if let TemplateChildNode::Text(ref text) = children[0] {
if text.content.chars().all(char::is_whitespace) {
children.remove(0);
continue;
}
}
break;
}
while !children.is_empty() {
let last = children.len() - 1;
if let TemplateChildNode::Text(ref text) = children[last] {
if text.content.chars().all(char::is_whitespace) {
children.remove(last);
continue;
}
}
break;
}
let mut i = 0;
while i < children.len() {
let action = if let TemplateChildNode::Text(ref text) = children[i] {
let content = text.content.as_str();
if content.chars().all(char::is_whitespace) {
let prev_is_text = i > 0
&& matches!(
children[i - 1],
TemplateChildNode::Text(_) | TemplateChildNode::Interpolation(_)
);
let next_is_text = i + 1 < children.len()
&& matches!(
children[i + 1],
TemplateChildNode::Text(_) | TemplateChildNode::Interpolation(_)
);
if !prev_is_text && !next_is_text {
let has_newline = content.contains('\n');
if has_newline {
WhitespaceAction::Remove
} else {
WhitespaceAction::Condense
}
} else {
WhitespaceAction::Keep
}
} else {
WhitespaceAction::Keep
}
} else {
WhitespaceAction::Keep
};
match action {
WhitespaceAction::Remove => {
children.remove(i);
continue;
}
WhitespaceAction::Condense => {
if let TemplateChildNode::Text(ref mut text) = children[i] {
text.content = " ".into();
}
}
WhitespaceAction::Keep => {}
}
if let TemplateChildNode::Element(ref mut el) = children[i] {
condense_whitespace(&mut el.children);
}
i += 1;
}
}
enum WhitespaceAction {
Keep,
Remove,
Condense,
}