use crate::ast::{
DirectiveNode, ElementNode, ElementType, ExpressionNode, PropNode, TemplateChildNode,
};
use vize_carton::is_builtin_directive;
use super::super::{
context::CodegenContext, node::generate_node, props::is_supported_directive,
v_for::generate_for, v_if::generate_if,
};
pub fn has_v_once(el: &ElementNode<'_>) -> bool {
el.props.iter().any(|prop| {
if let PropNode::Directive(dir) = prop {
dir.name.as_str() == "once"
} else {
false
}
})
}
pub(crate) fn is_whitespace_or_comment(child: &TemplateChildNode<'_>) -> bool {
match child {
TemplateChildNode::Text(t) => t.content.trim().is_empty(),
TemplateChildNode::Comment(_) => true,
_ => false,
}
}
pub fn has_vshow_directive(el: &ElementNode<'_>) -> bool {
el.props.iter().any(|prop| {
if let PropNode::Directive(dir) = prop {
dir.name.as_str() == "show" && dir.exp.is_some()
} else {
false
}
})
}
pub fn has_custom_directives(el: &ElementNode<'_>) -> bool {
el.props.iter().any(|prop| {
if let PropNode::Directive(dir) = prop {
!is_builtin_directive(&dir.name)
} else {
false
}
})
}
pub fn get_custom_directives<'a, 'b>(el: &'b ElementNode<'a>) -> Vec<&'b DirectiveNode<'a>> {
el.props
.iter()
.filter_map(|prop| {
if let PropNode::Directive(dir) = prop
&& !is_builtin_directive(&dir.name)
{
return Some(dir.as_ref());
}
None
})
.collect()
}
pub fn has_vmodel_directive(el: &ElementNode<'_>) -> bool {
if el.tag_type != ElementType::Element {
return false;
}
if !matches!(el.tag.as_str(), "input" | "textarea" | "select") {
return false;
}
el.props.iter().any(|prop| {
if let PropNode::Directive(dir) = prop {
dir.name.as_str() == "model"
} else {
false
}
})
}
pub(crate) fn get_vmodel_directive<'a, 'b>(
el: &'b ElementNode<'a>,
) -> Option<&'b DirectiveNode<'a>> {
el.props.iter().find_map(|prop| {
if let PropNode::Directive(dir) = prop
&& dir.name.as_str() == "model"
{
return Some(dir.as_ref());
}
None
})
}
pub(crate) fn is_is_prop(p: &PropNode<'_>) -> bool {
match p {
PropNode::Attribute(attr) => attr.name == "is",
PropNode::Directive(dir) => {
if dir.name == "bind"
&& let Some(ExpressionNode::Simple(arg)) = &dir.arg
{
return arg.content == "is";
}
false
}
}
}
pub(crate) fn is_dynamic_component_tag(tag: &str) -> bool {
tag == "component"
}
pub(crate) fn is_dynamic_component(el: &ElementNode<'_>) -> bool {
is_dynamic_component_tag(&el.tag) || (el.tag == "Component" && el.props.iter().any(is_is_prop))
}
pub(crate) fn is_renderable_prop(prop: &PropNode<'_>) -> bool {
match prop {
PropNode::Attribute(_) => true,
PropNode::Directive(dir) => is_supported_directive(dir),
}
}
pub fn has_renderable_props(el: &ElementNode<'_>) -> bool {
el.props.iter().any(|prop| is_renderable_prop(prop))
}
pub fn generate_root_node(ctx: &mut CodegenContext, node: &TemplateChildNode<'_>) {
match node {
TemplateChildNode::Element(el) => super::block::generate_element_block(ctx, el),
TemplateChildNode::If(if_node) => generate_if(ctx, if_node),
TemplateChildNode::For(for_node) => generate_for(ctx, for_node),
_ => generate_node(ctx, node),
}
}