From 5fb0a1332e57a545f12d02b72fd0cff5eca6cddd Mon Sep 17 00:00:00 2001 From: Manuel Cillero Date: Sun, 4 Aug 2024 18:00:34 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=A7=91=E2=80=8D=F0=9F=92=BB=20Improve=20u?= =?UTF-8?q?sage=20of=20stylesheets=20and=20JavaScript?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/base/component.rs | 14 +++--- src/base/package/welcome.rs | 2 +- src/base/theme/basic.rs | 4 +- src/base/theme/chassis.rs | 4 +- src/base/theme/inception.rs | 4 +- src/core/component/context.rs | 32 +++---------- src/html.rs | 6 +-- src/html/assets.rs | 12 ++--- src/html/assets/headscript.rs | 44 ------------------ src/html/assets/headstyles.rs | 44 ------------------ src/html/assets/javascript.rs | 88 ++++++++++++++++++++++++++--------- src/html/assets/stylesheet.rs | 44 +++++++++++++----- 12 files changed, 126 insertions(+), 172 deletions(-) delete mode 100644 src/html/assets/headscript.rs delete mode 100644 src/html/assets/headstyles.rs diff --git a/src/base/component.rs b/src/base/component.rs index 6c3b9a3f..9a6d1e85 100644 --- a/src/base/component.rs +++ b/src/base/component.rs @@ -14,24 +14,24 @@ pub(crate) fn add_base_assets(cx: &mut Context) { let weight = cx.get_param::(PARAM_BASE_WEIGHT).unwrap_or(-90); cx.set_assets(AssetsOp::AddStyleSheet( - StyleSheet::at("/base/css/root.css") + StyleSheet::from("/base/css/root.css") .with_version("0.0.1") .with_weight(weight), )) .set_assets(AssetsOp::AddStyleSheet( - StyleSheet::at("/base/css/looks.css") + StyleSheet::from("/base/css/looks.css") .with_version("0.0.1") .with_weight(weight), )) .set_assets(AssetsOp::AddStyleSheet( - StyleSheet::at("/base/css/buttons.css") + StyleSheet::from("/base/css/buttons.css") .with_version("0.0.2") .with_weight(weight), )); if let Ok(true) = cx.get_param::(PARAM_BASE_INCLUDE_ICONS) { cx.set_assets(AssetsOp::AddStyleSheet( - StyleSheet::at("/base/css/icons.min.css") + StyleSheet::from("/base/css/icons.min.css") .with_version("1.11.1") .with_weight(weight), )); @@ -39,7 +39,7 @@ pub(crate) fn add_base_assets(cx: &mut Context) { if let Ok(true) = cx.get_param::(PARAM_BASE_INCLUDE_FLEX_ASSETS) { cx.set_assets(AssetsOp::AddStyleSheet( - StyleSheet::at("/base/css/flex.css") + StyleSheet::from("/base/css/flex.css") .with_version("0.0.1") .with_weight(weight), )); @@ -47,12 +47,12 @@ pub(crate) fn add_base_assets(cx: &mut Context) { if let Ok(true) = cx.get_param::(PARAM_BASE_INCLUDE_MENU_ASSETS) { cx.set_assets(AssetsOp::AddStyleSheet( - StyleSheet::at("/base/css/menu.css") + StyleSheet::from("/base/css/menu.css") .with_version("0.0.1") .with_weight(weight), )) .set_assets(AssetsOp::AddJavaScript( - JavaScript::at("/base/js/menu.js") + JavaScript::defer("/base/js/menu.js") .with_version("0.0.1") .with_weight(weight), )); diff --git a/src/base/package/welcome.rs b/src/base/package/welcome.rs index 609591a8..77d2180b 100644 --- a/src/base/package/welcome.rs +++ b/src/base/package/welcome.rs @@ -35,7 +35,7 @@ fn home(request: HttpRequest, lang: &'static LanguageIdentifier) -> ResultPage, // Stylesheets. - headstyles: Assets, // Styles in head. - javascript: Assets, // JavaScripts. - headscript: Assets, // Scripts in head. + stylesheet: Assets, + javascript: Assets, regions : ComponentsInRegions, params : HashMap<&'static str, String>, id_counter: usize, @@ -75,10 +67,8 @@ impl Context { langid : &LANGID_DEFAULT, theme : *THEME_DEFAULT, layout : "default", - stylesheet: Assets::::new(), // Stylesheets. - headstyles: Assets::::new(), // Styles in head. - javascript: Assets::::new(), // JavaScripts. - headscript: Assets::::new(), // Scripts in head. + stylesheet: Assets::::new(), + javascript: Assets::::new(), regions : ComponentsInRegions::default(), params : HashMap::<&str, String>::new(), id_counter: 0, @@ -101,15 +91,9 @@ impl Context { // Stylesheets. AssetsOp::AddStyleSheet(css) => { self.stylesheet.add(css); } AssetsOp::RemoveStyleSheet(path) => { self.stylesheet.remove(path); } - // Styles in head. - AssetsOp::AddHeadStyles(styles) => { self.headstyles.add(styles); } - AssetsOp::RemoveHeadStyles(path) => { self.headstyles.remove(path); } // JavaScripts. AssetsOp::AddJavaScript(js) => { self.javascript.add(js); } AssetsOp::RemoveJavaScript(path) => { self.javascript.remove(path); } - // Scripts in head. - AssetsOp::AddHeadScript(script) => { self.headscript.add(script); } - AssetsOp::RemoveHeadScript(path) => { self.headscript.remove(path); } // Add assets to properly use base components. AssetsOp::AddBaseAssets => { add_base_assets(self); } @@ -160,10 +144,8 @@ impl Context { pub(crate) fn prepare_assets(&mut self) -> Markup { html! { - (self.stylesheet.prepare()) // Stylesheets. - (self.headstyles.prepare()) // Styles in head. - (self.javascript.prepare()) // JavaScripts. - (self.headscript.prepare()) // Scripts in head. + (self.stylesheet.prepare()) + (self.javascript.prepare()) } } diff --git a/src/html.rs b/src/html.rs index 83de200d..163ebf4f 100644 --- a/src/html.rs +++ b/src/html.rs @@ -4,11 +4,9 @@ mod maud; pub use maud::{html, html_private, Markup, PreEscaped, DOCTYPE}; mod assets; -pub use assets::headscript::HeadScript; -pub use assets::headstyles::HeadStyles; -pub use assets::javascript::{JavaScript, ModeJS}; +pub use assets::javascript::JavaScript; pub use assets::stylesheet::{StyleSheet, TargetMedia}; -pub use assets::Assets; +pub(crate) use assets::Assets; mod favicon; pub use favicon::Favicon; diff --git a/src/html/assets.rs b/src/html/assets.rs index 4f5f529a..7a89937f 100644 --- a/src/html/assets.rs +++ b/src/html/assets.rs @@ -1,5 +1,3 @@ -pub mod headscript; -pub mod headstyles; pub mod javascript; pub mod stylesheet; @@ -7,7 +5,7 @@ use crate::html::{html, Markup}; use crate::{AutoDefault, Weight}; pub trait AssetsTrait { - fn path(&self) -> &str; + fn name(&self) -> &String; fn weight(&self) -> Weight; @@ -15,7 +13,7 @@ pub trait AssetsTrait { } #[derive(AutoDefault)] -pub struct Assets(Vec); +pub(crate) struct Assets(Vec); impl Assets { pub fn new() -> Self { @@ -23,7 +21,7 @@ impl Assets { } pub fn add(&mut self, asset: T) -> &mut Self { - match self.0.iter().position(|x| x.path() == asset.path()) { + match self.0.iter().position(|x| x.name() == asset.name()) { Some(index) => { if self.0[index].weight() > asset.weight() { self.0.remove(index); @@ -35,8 +33,8 @@ impl Assets { self } - pub fn remove(&mut self, path: &'static str) -> &mut Self { - if let Some(index) = self.0.iter().position(|x| x.path() == path) { + pub fn remove(&mut self, name: &'static str) -> &mut Self { + if let Some(index) = self.0.iter().position(|x| x.name() == name) { self.0.remove(index); }; self diff --git a/src/html/assets/headscript.rs b/src/html/assets/headscript.rs deleted file mode 100644 index 708ab3eb..00000000 --- a/src/html/assets/headscript.rs +++ /dev/null @@ -1,44 +0,0 @@ -use crate::html::assets::AssetsTrait; -use crate::html::{html, Markup}; -use crate::{AutoDefault, Weight}; - -#[rustfmt::skip] -#[derive(AutoDefault)] -pub struct HeadScript { - path : String, - code : String, - weight: Weight, -} - -impl AssetsTrait for HeadScript { - fn path(&self) -> &str { - self.path.as_str() - } - - fn weight(&self) -> Weight { - self.weight - } - - fn prepare(&self) -> Markup { - html! { script { (self.code) }; } - } -} - -impl HeadScript { - pub fn named(path: impl Into) -> Self { - HeadScript { - path: path.into(), - ..Default::default() - } - } - - pub fn with_code(mut self, code: impl Into) -> Self { - self.code = code.into().trim().to_owned(); - self - } - - pub fn with_weight(mut self, value: Weight) -> Self { - self.weight = value; - self - } -} diff --git a/src/html/assets/headstyles.rs b/src/html/assets/headstyles.rs deleted file mode 100644 index dcc36ba4..00000000 --- a/src/html/assets/headstyles.rs +++ /dev/null @@ -1,44 +0,0 @@ -use crate::html::assets::AssetsTrait; -use crate::html::{html, Markup}; -use crate::{AutoDefault, Weight}; - -#[rustfmt::skip] -#[derive(AutoDefault)] -pub struct HeadStyles { - path : String, - styles: String, - weight: Weight, -} - -impl AssetsTrait for HeadStyles { - fn path(&self) -> &str { - self.path.as_str() - } - - fn weight(&self) -> Weight { - self.weight - } - - fn prepare(&self) -> Markup { - html! { styles { (self.styles) }; } - } -} - -impl HeadStyles { - pub fn named(path: impl Into) -> Self { - HeadStyles { - path: path.into(), - ..Default::default() - } - } - - pub fn with_styles(mut self, styles: impl Into) -> Self { - self.styles = styles.into().trim().to_owned(); - self - } - - pub fn with_weight(mut self, value: Weight) -> Self { - self.weight = value; - self - } -} diff --git a/src/html/assets/javascript.rs b/src/html/assets/javascript.rs index 3f78681a..672ab3e0 100644 --- a/src/html/assets/javascript.rs +++ b/src/html/assets/javascript.rs @@ -1,28 +1,35 @@ use crate::html::assets::AssetsTrait; use crate::html::{html, Markup}; -use crate::{AutoDefault, Weight}; +use crate::{concat_string, AutoDefault, Weight}; -#[derive(Default, Eq, PartialEq)] -pub enum ModeJS { - Async, +#[derive(AutoDefault)] +enum Source { #[default] - Defer, - Normal, + From(String), + Defer(String), + Async(String), + Inline(String, String), + OnLoad(String, String), } #[rustfmt::skip] #[derive(AutoDefault)] pub struct JavaScript { - path : String, + source : Source, prefix : &'static str, version: &'static str, weight : Weight, - mode : ModeJS, } impl AssetsTrait for JavaScript { - fn path(&self) -> &str { - self.path.as_str() + fn name(&self) -> &String { + 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 { @@ -30,20 +37,60 @@ impl AssetsTrait for JavaScript { } fn prepare(&self) -> Markup { - html! { - script type="text/javascript" - src=(crate::concat_string!(self.path, self.prefix, self.version)) - async[self.mode == ModeJS::Async] - defer[self.mode == ModeJS::Defer] - {}; + match &self.source { + Source::From(path) => html! { + script src=(concat_string!(path, self.prefix, self.version)) {}; + }, + Source::Defer(path) => html! { + script src=(concat_string!(path, self.prefix, self.version)) defer {}; + }, + Source::Async(path) => html! { + script src=(concat_string!(path, self.prefix, self.version)) async {}; + }, + Source::Inline(_, code) => html! { + script { (code) }; + }, + Source::OnLoad(_, code) => html! { (concat_string!( + "document.addEventListener('DOMContentLoaded',function(){", + code, + "});" + )) }, } } } impl JavaScript { - pub fn at(path: impl Into) -> Self { + pub fn from(path: impl Into) -> Self { JavaScript { - path: path.into(), + source: Source::From(path.into()), + ..Default::default() + } + } + + pub fn defer(path: impl Into) -> Self { + JavaScript { + source: Source::Defer(path.into()), + ..Default::default() + } + } + + pub fn asynchronous(path: impl Into) -> Self { + JavaScript { + source: Source::Async(path.into()), + ..Default::default() + } + } + + pub fn inline(name: impl Into, script: impl Into) -> Self { + JavaScript { + source: Source::Inline(name.into(), script.into()), + ..Default::default() + } + } + + pub fn on_load(name: impl Into, script: impl Into) -> Self { + JavaScript { + source: Source::OnLoad(name.into(), script.into()), ..Default::default() } } @@ -61,9 +108,4 @@ impl JavaScript { self.weight = value; self } - - pub fn with_mode(mut self, mode: ModeJS) -> Self { - self.mode = mode; - self - } } diff --git a/src/html/assets/stylesheet.rs b/src/html/assets/stylesheet.rs index e53d9b9e..9fd5e191 100644 --- a/src/html/assets/stylesheet.rs +++ b/src/html/assets/stylesheet.rs @@ -1,6 +1,13 @@ use crate::html::assets::AssetsTrait; use crate::html::{html, Markup}; -use crate::{AutoDefault, Weight}; +use crate::{concat_string, AutoDefault, Weight}; + +#[derive(AutoDefault)] +enum Source { + #[default] + From(String), + Inline(String, String), +} pub enum TargetMedia { Default, @@ -12,7 +19,7 @@ pub enum TargetMedia { #[rustfmt::skip] #[derive(AutoDefault)] pub struct StyleSheet { - path : String, + source : Source, prefix : &'static str, version: &'static str, media : Option<&'static str>, @@ -20,8 +27,11 @@ pub struct StyleSheet { } impl AssetsTrait for StyleSheet { - fn path(&self) -> &str { - self.path.as_str() + fn name(&self) -> &String { + match &self.source { + Source::From(path) => path, + Source::Inline(name, _) => name, + } } fn weight(&self) -> Weight { @@ -29,19 +39,31 @@ impl AssetsTrait for StyleSheet { } fn prepare(&self) -> Markup { - html! { - link - rel="stylesheet" - href=(crate::concat_string!(self.path, self.prefix, self.version)) - media=[self.media]; + match &self.source { + Source::From(path) => html! { + link + rel="stylesheet" + href=(concat_string!(path, self.prefix, self.version)) + media=[self.media]; + }, + Source::Inline(_, code) => html! { + styles { (code) }; + }, } } } impl StyleSheet { - pub fn at(path: impl Into) -> Self { + pub fn from(path: impl Into) -> Self { StyleSheet { - path: path.into(), + source: Source::From(path.into()), + ..Default::default() + } + } + + pub fn inline(name: impl Into, styles: impl Into) -> Self { + StyleSheet { + source: Source::Inline(name.into(), styles.into()), ..Default::default() } }