use crate::html::assets::AssetsTrait;
use crate::html::{html, Markup, Render};
use crate::{join, join_pair, AutoDefault, Weight};
// Define el origen del recurso JavaScript y cómo debe cargarse en el navegador.
//
// Los distintos modos de carga permiten optimizar el rendimiento y controlar el comportamiento del
// script.
//
// - [`From`] – Carga el script de forma estándar con la etiqueta ``. El parámetro `name` se usa como identificador interno del
/// *script*.
pub fn inline(name: impl Into, script: impl Into) -> Self {
JavaScript {
source: Source::Inline(name.into(), script.into()),
..Default::default()
}
}
/// Crea un **script embebido** que se ejecuta automáticamente al terminar de cargarse el
/// documento HTML.
///
/// El código se envuelve automáticamente en un `addEventListener('DOMContentLoaded', ...)`. El
/// parámetro `name` se usa como identificador interno del *script*.
pub fn on_load(name: impl Into, script: impl Into) -> Self {
JavaScript {
source: Source::OnLoad(name.into(), script.into()),
..Default::default()
}
}
// JavaScript BUILDER **************************************************************************
/// Asocia una versión al recurso (usada para control de la caché del navegador).
///
/// Si `version` está vacío, no se añade ningún parámetro a la URL.
pub fn with_version(mut self, version: impl Into) -> Self {
self.version = version.into();
self
}
/// Modifica el peso del recurso.
///
/// Los recursos se renderizan de menor a mayor peso. Por defecto es `0`, que respeta el orden
/// de creación.
pub fn with_weight(mut self, value: Weight) -> Self {
self.weight = value;
self
}
}
impl AssetsTrait for JavaScript {
// Para *scripts* externos es la ruta; para *scripts* embebidos, un identificador.
fn name(&self) -> &str {
match &self.source {
Source::From(path) => path,
Source::Defer(path) => path,
Source::Async(path) => path,
Source::Inline(name, _) => name,
Source::OnLoad(name, _) => name,
}
}
fn weight(&self) -> Weight {
self.weight
}
}
impl Render for JavaScript {
fn render(&self) -> Markup {
match &self.source {
Source::From(path) => html! {
script src=(join_pair!(path, "?v=", self.version.as_str())) {};
},
Source::Defer(path) => html! {
script src=(join_pair!(path, "?v=", self.version.as_str())) defer {};
},
Source::Async(path) => html! {
script src=(join_pair!(path, "?v=", self.version.as_str())) async {};
},
Source::Inline(_, code) => html! {
script { (code) };
},
Source::OnLoad(_, code) => html! { (join!(
"document.addEventListener('DOMContentLoaded',function(){", code, "});"
)) },
}
}
}