Nuevos activos para el contexto

This commit is contained in:
Manuel Cillero 2023-07-06 18:24:35 +02:00
parent cb8078f79f
commit 4673b82a93
7 changed files with 187 additions and 44 deletions

View file

@ -1,6 +1,6 @@
use crate::core::theme::all::{theme_by_single_name, THEME}; use crate::core::theme::all::{theme_by_single_name, THEME};
use crate::core::theme::ThemeStaticRef; use crate::core::theme::ThemeStaticRef;
use crate::html::{html, Assets, JavaScript, Markup, StyleSheet}; use crate::html::{html, Assets, HeadScript, HeadStyles, JavaScript, Markup, StyleSheet};
use crate::locale::{LanguageIdentifier, LANGID}; use crate::locale::{LanguageIdentifier, LANGID};
use crate::service::HttpRequest; use crate::service::HttpRequest;
use crate::{concat_string, util}; use crate::{concat_string, util};
@ -11,21 +11,31 @@ use std::str::FromStr;
pub enum ContextOp { pub enum ContextOp {
LangId(&'static LanguageIdentifier), LangId(&'static LanguageIdentifier),
Theme(&'static str), Theme(&'static str),
// Stylesheets.
AddStyleSheet(StyleSheet), AddStyleSheet(StyleSheet),
RemoveStyleSheet(&'static str), RemoveStyleSheet(&'static str),
// Styles in head.
AddHeadStyles(HeadStyles),
RemoveHeadStyles(&'static str),
// JavaScripts.
AddJavaScript(JavaScript), AddJavaScript(JavaScript),
RemoveJavaScript(&'static str), RemoveJavaScript(&'static str),
// Scripts in head.
AddHeadScript(HeadScript),
RemoveHeadScript(&'static str),
} }
#[rustfmt::skip] #[rustfmt::skip]
pub struct Context { pub struct Context {
request : HttpRequest, request : HttpRequest,
langid : &'static LanguageIdentifier, langid : &'static LanguageIdentifier,
theme : ThemeStaticRef, theme : ThemeStaticRef,
stylesheets: Assets<StyleSheet>, stylesheet: Assets<StyleSheet>, // Stylesheets.
javascripts: Assets<JavaScript>, headstyles: Assets<HeadStyles>, // Styles in head.
params : HashMap<&'static str, String>, javascript: Assets<JavaScript>, // JavaScripts.
id_counter : usize, headscript: Assets<HeadScript>, // Scripts in head.
params : HashMap<&'static str, String>,
id_counter: usize,
} }
impl Context { impl Context {
@ -33,15 +43,18 @@ impl Context {
pub(crate) fn new(request: HttpRequest) -> Self { pub(crate) fn new(request: HttpRequest) -> Self {
Context { Context {
request, request,
langid : &LANGID, langid : &LANGID,
theme : *THEME, theme : *THEME,
stylesheets: Assets::<StyleSheet>::new(), stylesheet: Assets::<StyleSheet>::new(), // Stylesheets.
javascripts: Assets::<JavaScript>::new(), headstyles: Assets::<HeadStyles>::new(), // Styles in head.
params : HashMap::<&str, String>::new(), javascript: Assets::<JavaScript>::new(), // JavaScripts.
id_counter : 0, headscript: Assets::<HeadScript>::new(), // Scripts in head.
params : HashMap::<&str, String>::new(),
id_counter: 0,
} }
} }
#[rustfmt::skip]
pub fn alter(&mut self, op: ContextOp) -> &mut Self { pub fn alter(&mut self, op: ContextOp) -> &mut Self {
match op { match op {
ContextOp::LangId(langid) => { ContextOp::LangId(langid) => {
@ -50,18 +63,18 @@ impl Context {
ContextOp::Theme(theme_name) => { ContextOp::Theme(theme_name) => {
self.theme = theme_by_single_name(theme_name).unwrap_or(*THEME); self.theme = theme_by_single_name(theme_name).unwrap_or(*THEME);
} }
ContextOp::AddStyleSheet(css) => { // Stylesheets.
self.stylesheets.add(css); ContextOp::AddStyleSheet(css) => { self.stylesheet.add(css); }
} ContextOp::RemoveStyleSheet(path) => { self.stylesheet.remove(path); }
ContextOp::RemoveStyleSheet(source) => { // Styles in head.
self.stylesheets.remove(source); ContextOp::AddHeadStyles(styles) => { self.headstyles.add(styles); }
} ContextOp::RemoveHeadStyles(path) => { self.headstyles.remove(path); }
ContextOp::AddJavaScript(js) => { // JavaScripts.
self.javascripts.add(js); ContextOp::AddJavaScript(js) => { self.javascript.add(js); }
} ContextOp::RemoveJavaScript(path) => { self.javascript.remove(path); }
ContextOp::RemoveJavaScript(source) => { // Scripts in head.
self.javascripts.remove(source); ContextOp::AddHeadScript(script) => { self.headscript.add(script); }
} ContextOp::RemoveHeadScript(path) => { self.headscript.remove(path); }
} }
self self
} }
@ -71,6 +84,11 @@ impl Context {
self self
} }
pub fn remove_param(&mut self, key: &'static str) -> &mut Self {
self.params.remove(key);
self
}
/// Context GETTERS. /// Context GETTERS.
pub fn request(&self) -> &HttpRequest { pub fn request(&self) -> &HttpRequest {
@ -98,8 +116,10 @@ impl Context {
pub fn prepare(&mut self) -> Markup { pub fn prepare(&mut self) -> Markup {
html! { html! {
(self.stylesheets.prepare()) (self.stylesheet.prepare()) // Stylesheets.
(self.javascripts.prepare()) (self.headstyles.prepare()) // Styles in head.
(self.javascript.prepare()) // JavaScripts.
(self.headscript.prepare()) // Scripts in head.
} }
} }

View file

@ -4,6 +4,8 @@ mod maud;
pub use maud::{html, html_private, Markup, PreEscaped, DOCTYPE}; pub use maud::{html, html_private, Markup, PreEscaped, DOCTYPE};
mod assets; mod assets;
pub use assets::headscript::HeadScript;
pub use assets::headstyles::HeadStyles;
pub use assets::javascript::{JavaScript, ModeJS}; pub use assets::javascript::{JavaScript, ModeJS};
pub use assets::stylesheet::{StyleSheet, TargetMedia}; pub use assets::stylesheet::{StyleSheet, TargetMedia};
pub use assets::Assets; pub use assets::Assets;

View file

@ -1,10 +1,12 @@
pub mod headscript;
pub mod headstyles;
pub mod javascript; pub mod javascript;
pub mod stylesheet; pub mod stylesheet;
use crate::html::{html, Markup}; use crate::html::{html, Markup};
pub trait AssetsTrait { pub trait AssetsTrait {
fn source(&self) -> &str; fn path(&self) -> &str;
fn weight(&self) -> isize; fn weight(&self) -> isize;
@ -20,7 +22,7 @@ impl<T: AssetsTrait> Assets<T> {
} }
pub fn add(&mut self, asset: T) -> &mut Self { pub fn add(&mut self, asset: T) -> &mut Self {
match self.0.iter().position(|x| x.source() == asset.source()) { match self.0.iter().position(|x| x.path() == asset.path()) {
Some(index) => { Some(index) => {
if self.0[index].weight() > asset.weight() { if self.0[index].weight() > asset.weight() {
self.0.remove(index); self.0.remove(index);
@ -32,8 +34,8 @@ impl<T: AssetsTrait> Assets<T> {
self self
} }
pub fn remove(&mut self, source: &'static str) -> &mut Self { pub fn remove(&mut self, path: &'static str) -> &mut Self {
if let Some(index) = self.0.iter().position(|x| x.source() == source) { if let Some(index) = self.0.iter().position(|x| x.path() == path) {
self.0.remove(index); self.0.remove(index);
}; };
self self

View file

@ -0,0 +1,46 @@
use super::AssetsTrait;
use crate::html::{html, Markup};
#[rustfmt::skip]
#[derive(Default)]
pub struct HeadScript {
path : String,
code : String,
weight: isize,
}
impl AssetsTrait for HeadScript {
fn path(&self) -> &str {
self.path.as_str()
}
fn weight(&self) -> isize {
self.weight
}
fn prepare(&self) -> Markup {
html! { script { (self.code) }; }
}
}
impl HeadScript {
pub fn named<S>(path: S) -> Self
where
S: Into<String>,
{
HeadScript {
path: path.into(),
..Default::default()
}
}
pub fn with_code(mut self, code: &str) -> Self {
self.code = code.trim().to_owned();
self
}
pub fn with_weight(mut self, weight: isize) -> Self {
self.weight = weight;
self
}
}

View file

@ -0,0 +1,46 @@
use super::AssetsTrait;
use crate::html::{html, Markup};
#[rustfmt::skip]
#[derive(Default)]
pub struct HeadStyles {
path : String,
styles: String,
weight: isize,
}
impl AssetsTrait for HeadStyles {
fn path(&self) -> &str {
self.path.as_str()
}
fn weight(&self) -> isize {
self.weight
}
fn prepare(&self) -> Markup {
html! { styles { (self.styles) }; }
}
}
impl HeadStyles {
pub fn named<S>(path: S) -> Self
where
S: Into<String>,
{
HeadStyles {
path: path.into(),
..Default::default()
}
}
pub fn with_styles(mut self, styles: &str) -> Self {
self.styles = styles.trim().to_owned();
self
}
pub fn with_weight(mut self, weight: isize) -> Self {
self.weight = weight;
self
}
}

View file

@ -12,14 +12,16 @@ pub enum ModeJS {
#[rustfmt::skip] #[rustfmt::skip]
#[derive(Default)] #[derive(Default)]
pub struct JavaScript { pub struct JavaScript {
source : String, path : String,
prefix : &'static str,
version: &'static str,
weight : isize, weight : isize,
mode : ModeJS, mode : ModeJS,
} }
impl AssetsTrait for JavaScript { impl AssetsTrait for JavaScript {
fn source(&self) -> &str { fn path(&self) -> &str {
self.source.as_str() self.path.as_str()
} }
fn weight(&self) -> isize { fn weight(&self) -> isize {
@ -29,7 +31,7 @@ impl AssetsTrait for JavaScript {
fn prepare(&self) -> Markup { fn prepare(&self) -> Markup {
html! { html! {
script type="text/javascript" script type="text/javascript"
src=(self.source) src=(crate::concat_string!(self.path, self.prefix, self.version))
async[self.mode == ModeJS::Async] async[self.mode == ModeJS::Async]
defer[self.mode == ModeJS::Defer] defer[self.mode == ModeJS::Defer]
{}; {};
@ -38,16 +40,25 @@ impl AssetsTrait for JavaScript {
} }
impl JavaScript { impl JavaScript {
pub fn located<S>(source: S) -> Self pub fn located<S>(path: S) -> Self
where where
S: Into<String>, S: Into<String>,
{ {
JavaScript { JavaScript {
source: source.into(), path: path.into(),
..Default::default() ..Default::default()
} }
} }
pub fn with_version(mut self, version: &'static str) -> Self {
(self.prefix, self.version) = if version.is_empty() {
("", "")
} else {
("?v=", version)
};
self
}
pub fn with_weight(mut self, weight: isize) -> Self { pub fn with_weight(mut self, weight: isize) -> Self {
self.weight = weight; self.weight = weight;
self self

View file

@ -11,14 +11,16 @@ pub enum TargetMedia {
#[rustfmt::skip] #[rustfmt::skip]
#[derive(Default)] #[derive(Default)]
pub struct StyleSheet { pub struct StyleSheet {
source : String, path : String,
prefix : &'static str,
version: &'static str,
media : Option<&'static str>, media : Option<&'static str>,
weight : isize, weight : isize,
} }
impl AssetsTrait for StyleSheet { impl AssetsTrait for StyleSheet {
fn source(&self) -> &str { fn path(&self) -> &str {
self.source.as_str() self.path.as_str()
} }
fn weight(&self) -> isize { fn weight(&self) -> isize {
@ -26,21 +28,35 @@ impl AssetsTrait for StyleSheet {
} }
fn prepare(&self) -> Markup { fn prepare(&self) -> Markup {
html! { link rel="stylesheet" href=(self.source) media=[self.media]; } html! {
link
rel="stylesheet"
href=(crate::concat_string!(self.path, self.prefix, self.version))
media=[self.media];
}
} }
} }
impl StyleSheet { impl StyleSheet {
pub fn located<S>(source: S) -> Self pub fn located<S>(path: S) -> Self
where where
S: Into<String>, S: Into<String>,
{ {
StyleSheet { StyleSheet {
source: source.into(), path: path.into(),
..Default::default() ..Default::default()
} }
} }
pub fn with_version(mut self, version: &'static str) -> Self {
(self.prefix, self.version) = if version.is_empty() {
("", "")
} else {
("?v=", version)
};
self
}
pub fn with_weight(mut self, weight: isize) -> Self { pub fn with_weight(mut self, weight: isize) -> Self {
self.weight = weight; self.weight = weight;
self self