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, "});" )) }, } } }