use serde::{Deserialize, Serialize};
use vize_atelier_core::options::{BindingMetadata, CodegenMode};
use vize_carton::String;
use vize_carton::config::VueVersion;
use vize_croquis::Croquis;
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DomCompilerOptions {
#[serde(default)]
pub mode: CodegenMode,
#[serde(default)]
pub prefix_identifiers: bool,
#[serde(default)]
pub hoist_static: bool,
#[serde(default)]
pub cache_handlers: bool,
#[serde(default)]
pub scope_id: Option<String>,
#[serde(default)]
pub ssr: bool,
#[serde(default)]
pub source_map: bool,
#[serde(default)]
pub comments: bool,
#[serde(default)]
pub component_name: Option<String>,
#[serde(default)]
pub inline: bool,
#[serde(default)]
pub custom_renderer: bool,
#[serde(skip)]
pub binding_metadata: Option<BindingMetadata>,
#[serde(default)]
pub is_ts: bool,
#[serde(skip)]
pub dialect: VueVersion,
#[serde(skip)]
pub croquis: Option<Box<Croquis>>,
}
impl Clone for DomCompilerOptions {
fn clone(&self) -> Self {
Self {
mode: self.mode,
prefix_identifiers: self.prefix_identifiers,
hoist_static: self.hoist_static,
cache_handlers: self.cache_handlers,
scope_id: self.scope_id.clone(),
ssr: self.ssr,
source_map: self.source_map,
comments: self.comments,
component_name: self.component_name.clone(),
inline: self.inline,
custom_renderer: self.custom_renderer,
binding_metadata: self.binding_metadata.clone(),
is_ts: self.is_ts,
dialect: self.dialect,
croquis: None,
}
}
}
impl Default for DomCompilerOptions {
fn default() -> Self {
Self {
mode: CodegenMode::Function,
prefix_identifiers: false,
hoist_static: true,
cache_handlers: false,
scope_id: None,
ssr: false,
source_map: false,
comments: false,
component_name: None,
inline: false,
custom_renderer: false,
binding_metadata: None,
is_ts: false,
dialect: VueVersion::V3,
croquis: None,
}
}
}
pub mod element_checks {
use phf::phf_set;
pub static VOID_ELEMENTS: phf::Set<&'static str> = phf_set! {
"area", "base", "br", "col", "embed", "hr", "img", "input",
"link", "meta", "param", "source", "track", "wbr"
};
pub static V_MODEL_ELEMENTS: phf::Set<&'static str> = phf_set! {
"input", "textarea", "select"
};
pub static CHECKBOX_OR_RADIO: phf::Set<&'static str> = phf_set! {
"checkbox", "radio"
};
#[inline]
pub fn is_v_model_element(tag: &str) -> bool {
V_MODEL_ELEMENTS.contains(tag)
}
#[inline]
pub fn is_void_element(tag: &str) -> bool {
VOID_ELEMENTS.contains(tag)
}
#[inline]
pub fn is_checkbox_or_radio(input_type: &str) -> bool {
CHECKBOX_OR_RADIO.contains(input_type)
}
}
pub mod event_modifiers {
use phf::phf_set;
pub static EVENT_OPTION_MODIFIERS: phf::Set<&'static str> = phf_set! {
"passive", "once", "capture"
};
pub static KEY_MODIFIERS: phf::Set<&'static str> = phf_set! {
"stop", "prevent", "self", "ctrl", "shift", "alt", "meta", "exact",
"left", "middle", "right"
};
pub static KEY_ALIASES: phf::Set<&'static str> = phf_set! {
"esc", "space", "up", "down", "left", "right", "delete", "backspace",
"tab", "enter"
};
pub static SYSTEM_MODIFIERS: phf::Set<&'static str> = phf_set! {
"ctrl", "shift", "alt", "meta"
};
#[inline]
pub fn is_event_option_modifier(modifier: &str) -> bool {
EVENT_OPTION_MODIFIERS.contains(modifier)
}
#[inline]
pub fn is_key_modifier(modifier: &str) -> bool {
KEY_MODIFIERS.contains(modifier)
}
#[inline]
pub fn is_system_modifier(modifier: &str) -> bool {
SYSTEM_MODIFIERS.contains(modifier)
}
#[inline]
pub fn is_key_alias(modifier: &str) -> bool {
KEY_ALIASES.contains(modifier)
}
pub fn get_key_code(alias: &str) -> Option<&'static str> {
match alias {
"esc" => Some("Escape"),
"space" => Some(" "),
"up" => Some("ArrowUp"),
"down" => Some("ArrowDown"),
"left" => Some("ArrowLeft"),
"right" => Some("ArrowRight"),
"delete" => Some("Delete"),
"backspace" => Some("Backspace"),
"tab" => Some("Tab"),
"enter" => Some("Enter"),
_ => None,
}
}
}
#[cfg(test)]
mod tests {
use super::{DomCompilerOptions, element_checks, event_modifiers};
#[test]
fn test_default_options() {
let opts = DomCompilerOptions::default();
assert!(!opts.prefix_identifiers);
assert!(opts.hoist_static);
assert!(!opts.ssr);
}
#[test]
fn test_v_model_elements() {
assert!(element_checks::is_v_model_element("input"));
assert!(element_checks::is_v_model_element("textarea"));
assert!(element_checks::is_v_model_element("select"));
assert!(!element_checks::is_v_model_element("div"));
}
#[test]
fn test_event_modifiers() {
assert!(event_modifiers::is_event_option_modifier("passive"));
assert!(event_modifiers::is_key_modifier("stop"));
assert!(event_modifiers::is_system_modifier("ctrl"));
assert!(event_modifiers::is_key_alias("enter"));
}
#[test]
fn test_key_codes() {
assert_eq!(event_modifiers::get_key_code("enter"), Some("Enter"));
assert_eq!(event_modifiers::get_key_code("esc"), Some("Escape"));
assert_eq!(event_modifiers::get_key_code("unknown"), None);
}
#[test]
fn test_void_elements_all() {
let void_tags = [
"area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param",
"source", "track", "wbr",
];
for tag in &void_tags {
assert!(
element_checks::is_void_element(tag),
"{} should be void",
tag
);
}
assert!(!element_checks::is_void_element("div"));
assert!(!element_checks::is_void_element("span"));
}
#[test]
fn test_key_aliases_all() {
let aliases = [
"esc",
"space",
"up",
"down",
"left",
"right",
"delete",
"backspace",
"tab",
"enter",
];
for alias in &aliases {
assert!(
event_modifiers::is_key_alias(alias),
"{} should be a key alias",
alias
);
assert!(
event_modifiers::get_key_code(alias).is_some(),
"{} should have a key code",
alias
);
}
}
#[test]
fn test_checkbox_or_radio() {
assert!(element_checks::is_checkbox_or_radio("checkbox"));
assert!(element_checks::is_checkbox_or_radio("radio"));
assert!(!element_checks::is_checkbox_or_radio("text"));
assert!(!element_checks::is_checkbox_or_radio("number"));
}
}