Añade nuevas posibilidades para manipular contexto

This commit is contained in:
Manuel Cillero 2022-07-29 22:41:00 +02:00
parent 33c3262426
commit de0785c29f
13 changed files with 129 additions and 108 deletions

View file

@ -32,9 +32,9 @@ impl ComponentTrait for Icon {
}
fn before_render(&mut self, context: &mut InContext) {
context.alter(InContextOp::StyleSheet(AssetsOp::Add(
context.alter(InContextOp::AddStyleSheet(
StyleSheet::located("/theme/icons/bootstrap-icons.css").with_version("1.8.2"),
)));
));
}
fn default_render(&self, _: &mut InContext) -> Markup {

View file

@ -206,15 +206,15 @@ impl ComponentTrait for Menu {
fn default_render(&self, context: &mut InContext) -> Markup {
context
.alter(InContextOp::StyleSheet(AssetsOp::Add(
.alter(InContextOp::AddStyleSheet(
StyleSheet::located("/theme/menu/css/menu.css").with_version("1.1.1"),
)))
.alter(InContextOp::StyleSheet(AssetsOp::Add(
))
.alter(InContextOp::AddStyleSheet(
StyleSheet::located("/theme/menu/css/menu-clean.css").with_version("1.1.1"),
)))
.alter(InContextOp::JavaScript(AssetsOp::Add(
))
.alter(InContextOp::AddJavaScript(
JavaScript::located("/theme/menu/js/menu.min.js").with_version("1.1.1"),
)))
))
.alter(InContextOp::AddJQuery);
let id = context.required_id::<Menu>(self.id());

View file

@ -27,9 +27,9 @@ impl ModuleTrait for DefaultHomePage {
async fn demo() -> ResultPage<Markup, FatalError> {
Page::new()
.with_title(l("page_title").as_str())
.with_context(InContextOp::StyleSheet(AssetsOp::Add(StyleSheet::located(
"/theme/module/homepage/styles.css",
))))
.with_context(InContextOp::AddStyleSheet(
StyleSheet::located("/theme/module/homepage/styles.css"
)))
.add_to("region-content", hello_world())
.add_to("region-content", welcome())
.add_to("region-content", about_pagetop())

View file

@ -16,11 +16,12 @@ impl ThemeTrait for Aliner {
}
fn before_render_page(&self, page: &mut Page) {
page.alter_context(InContextOp::Favicon(Some(
Favicon::new().with_icon("/theme/favicon.png"),
)))
.alter_context(InContextOp::StyleSheet(AssetsOp::Add(
StyleSheet::located("/aliner/css/styles.css").with_weight(-99),
)));
page
.alter_context(InContextOp::AddFavicon(
Favicon::new().with_icon("/theme/favicon.png"),
))
.alter_context(InContextOp::AddStyleSheet(
StyleSheet::located("/aliner/css/styles.css").with_weight(-99),
));
}
}

View file

@ -18,20 +18,21 @@ impl ThemeTrait for Bootsier {
}
fn before_render_page(&self, page: &mut Page) {
page.alter_context(InContextOp::Favicon(Some(
Favicon::new().with_icon("/theme/favicon.png"),
)))
.alter_context(InContextOp::StyleSheet(AssetsOp::Add(
StyleSheet::located("/bootsier/css/bootstrap.min.css")
.with_version("5.1.3")
.with_weight(-99),
)))
.alter_context(InContextOp::JavaScript(AssetsOp::Add(
JavaScript::located("/bootsier/js/bootstrap.bundle.min.js")
.with_version("5.1.3")
.with_weight(-99),
)))
.alter_context(InContextOp::AddJQuery);
page
.alter_context(InContextOp::AddFavicon(
Favicon::new().with_icon("/theme/favicon.png"),
))
.alter_context(InContextOp::AddStyleSheet(
StyleSheet::located("/bootsier/css/bootstrap.min.css")
.with_version("5.1.3")
.with_weight(-99),
))
.alter_context(InContextOp::AddJavaScript(
JavaScript::located("/bootsier/js/bootstrap.bundle.min.js")
.with_version("5.1.3")
.with_weight(-99),
))
.alter_context(InContextOp::AddJQuery);
}
fn error_404_not_found(&self) -> Container {

View file

@ -16,15 +16,16 @@ impl ThemeTrait for Bulmix {
}
fn before_render_page(&self, page: &mut Page) {
page.alter_context(InContextOp::Favicon(Some(
Favicon::new().with_icon("/theme/favicon.png"),
)))
.alter_context(InContextOp::StyleSheet(AssetsOp::Add(
StyleSheet::located("/bulmix/css/bulma.min.css")
.with_version("0.9.4")
.with_weight(-99),
)))
.alter_context(InContextOp::AddJQuery);
page
.alter_context(InContextOp::AddFavicon(
Favicon::new().with_icon("/theme/favicon.png"),
))
.alter_context(InContextOp::AddStyleSheet(
StyleSheet::located("/bulmix/css/bulma.min.css")
.with_version("0.9.4")
.with_weight(-99),
))
.alter_context(InContextOp::AddJQuery);
}
fn before_render_component(

View file

@ -13,17 +13,26 @@ static DEFAULT_THEME: LazyStatic<&dyn ThemeTrait> = LazyStatic::new(||
pub enum InContextOp {
SetTheme(&'static str),
AddFavicon(Favicon),
RemoveFavicon,
AddMetadata(&'static str, &'static str),
Favicon(Option<Favicon>),
StyleSheet(AssetsOp<StyleSheet>),
JavaScript(AssetsOp<JavaScript>),
AddProperty(&'static str, &'static str),
AddStyleSheet(StyleSheet),
RemoveStyleSheet(&'static str),
AddJavaScript(JavaScript),
RemoveJavaScript(&'static str),
AddJQuery,
}
pub struct InContext {
theme : &'static dyn ThemeTrait,
favicon : Option<Favicon>,
metadata : Vec<(String, String)>,
metadata : Vec<(&'static str, &'static str)>,
properties : Vec<(&'static str, &'static str)>,
stylesheets: Assets<StyleSheet>,
javascripts: Assets<JavaScript>,
with_jquery: bool,
@ -36,6 +45,7 @@ impl InContext {
theme : *DEFAULT_THEME,
favicon : None,
metadata : Vec::new(),
properties : Vec::new(),
stylesheets: Assets::<StyleSheet>::new(),
javascripts: Assets::<JavaScript>::new(),
with_jquery: false,
@ -48,26 +58,42 @@ impl InContext {
InContextOp::SetTheme(theme_name) => {
self.theme = theme_by_single_name(theme_name).unwrap_or(*DEFAULT_THEME);
}
InContextOp::AddFavicon(favicon) => {
self.favicon = Some(favicon);
}
InContextOp::RemoveFavicon => {
self.favicon = None;
}
InContextOp::AddMetadata(name, content) => {
self.metadata.push((name.to_owned(), content.to_owned()));
self.metadata.push((name, content));
}
InContextOp::Favicon(favicon) => {
self.favicon = favicon;
InContextOp::AddProperty(property, content) => {
self.properties.push((property, content));
}
InContextOp::StyleSheet(css) => {
self.stylesheets.alter(css);
InContextOp::AddStyleSheet(css) => {
self.stylesheets.add(css);
}
InContextOp::JavaScript(js) => {
self.javascripts.alter(js);
InContextOp::RemoveStyleSheet(source) => {
self.stylesheets.remove(source);
}
InContextOp::AddJavaScript(js) => {
self.javascripts.add(js);
}
InContextOp::RemoveJavaScript(source) => {
self.javascripts.remove(source);
}
InContextOp::AddJQuery => {
if !self.with_jquery {
self.javascripts.alter(AssetsOp::Add(
self.javascripts.add(
JavaScript::located("/theme/js/jquery.min.js")
.with_version("3.6.0")
.with_weight(isize::MIN)
.with_mode(JSMode::Normal),
));
);
self.with_jquery = true;
}
}
@ -92,6 +118,9 @@ impl InContext {
@for (name, content) in &self.metadata {
meta name=(name) content=(content) {}
}
@for (property, content) in &self.properties {
meta property=(property) content=(content) {}
}
(self.stylesheets.render())
(self.javascripts.render())
}

View file

@ -28,9 +28,9 @@ pub trait ThemeTrait: BaseTheme + Send + Sync {
#[allow(unused_variables)]
fn before_render_page(&self, page: &mut Page) {
page.alter_context(InContextOp::Favicon(Some(
page.alter_context(InContextOp::AddFavicon(
Favicon::new().with_icon("/theme/favicon.png"),
)));
));
}
fn render_page_head(&self, page: &mut Page) -> Markup {

View file

@ -3,7 +3,7 @@ pub use maud::{html, Markup, PreEscaped, DOCTYPE};
mod assets;
pub use assets::javascript::{JSMode, JavaScript};
pub use assets::stylesheet::{StyleSheet, TargetMedia};
pub use assets::{Assets, AssetsOp, SourceValue};
pub use assets::Assets;
mod favicon;
pub use favicon::Favicon;

View file

@ -3,21 +3,14 @@ pub mod stylesheet;
use crate::html::{html, Markup};
pub type SourceValue = &'static str;
pub trait AssetsTrait {
fn source(&self) -> SourceValue;
fn source(&self) -> &'static str;
fn weight(&self) -> isize;
fn render(&self) -> Markup;
}
pub enum AssetsOp<T: AssetsTrait> {
Add(T),
Remove(SourceValue),
}
#[derive(Default)]
pub struct Assets<T>(Vec<T>);
@ -26,25 +19,23 @@ impl<T: AssetsTrait> Assets<T> {
Assets::<T>(Vec::<T>::new())
}
pub fn alter(&mut self, op: AssetsOp<T>) -> &mut Self {
match op {
AssetsOp::Add(asset) => {
match self.0.iter().position(|x| x.source() == asset.source()) {
Some(index) => {
if self.0[index].weight() > asset.weight() {
self.0.remove(index);
self.0.push(asset);
}
}
_ => self.0.push(asset),
}
}
AssetsOp::Remove(source) => {
if let Some(index) = self.0.iter().position(|x| x.source() == source) {
pub fn add(&mut self, asset: T) -> &mut Self {
match self.0.iter().position(|x| x.source() == asset.source()) {
Some(index) => {
if self.0[index].weight() > asset.weight() {
self.0.remove(index);
self.0.push(asset);
}
}
}
_ => self.0.push(asset),
};
self
}
pub fn remove(&mut self, source: &'static str) -> &mut Self {
if let Some(index) = self.0.iter().position(|x| x.source() == source) {
self.0.remove(index);
};
self
}

View file

@ -1,4 +1,4 @@
use super::{AssetsTrait, SourceValue};
use super::AssetsTrait;
use crate::html::{html, Markup};
#[derive(PartialEq)]
@ -9,7 +9,7 @@ pub enum JSMode {
}
pub struct JavaScript {
source : SourceValue,
source : &'static str,
prefix : &'static str,
version: &'static str,
weight : isize,
@ -17,7 +17,7 @@ pub struct JavaScript {
}
impl AssetsTrait for JavaScript {
fn source(&self) -> SourceValue {
fn source(&self) -> &'static str {
self.source
}
@ -37,7 +37,7 @@ impl AssetsTrait for JavaScript {
}
impl JavaScript {
pub fn located(source: SourceValue) -> Self {
pub fn located(source: &'static str) -> Self {
JavaScript {
source,
prefix : "",

View file

@ -1,10 +1,10 @@
use super::{AssetsTrait, SourceValue};
use super::AssetsTrait;
use crate::html::{html, Markup};
pub enum TargetMedia {Default, Print, Screen, Speech}
pub struct StyleSheet {
source : SourceValue,
source : &'static str,
prefix : &'static str,
version: &'static str,
media : Option<&'static str>,
@ -12,7 +12,7 @@ pub struct StyleSheet {
}
impl AssetsTrait for StyleSheet {
fn source(&self) -> SourceValue {
fn source(&self) -> &'static str {
self.source
}
@ -31,7 +31,7 @@ impl AssetsTrait for StyleSheet {
}
impl StyleSheet {
pub fn located(source: SourceValue) -> Self {
pub fn located(source: &'static str) -> Self {
StyleSheet {
source,
prefix : "",

View file

@ -60,34 +60,32 @@ async fn mdbook_page(request: app::HttpRequest) -> ResultPage<Markup, FatalError
Page::new()
.with_title(title)
.with_context(InContextOp::AddMetadata("theme-color", "#ffffff"))
.with_context(InContextOp::StyleSheet(
AssetsOp::<StyleSheet>::Add(StyleSheet::located("/doc/css/variables.css"))
.with_context(InContextOp::AddStyleSheet(
StyleSheet::located("/doc/css/variables.css")
))
.with_context(InContextOp::StyleSheet(
AssetsOp::<StyleSheet>::Add(StyleSheet::located("/doc/css/general.css"))
.with_context(InContextOp::AddStyleSheet(
StyleSheet::located("/doc/css/general.css")
))
.with_context(InContextOp::StyleSheet(
AssetsOp::<StyleSheet>::Add(StyleSheet::located("/doc/css/chrome.css"))
.with_context(InContextOp::AddStyleSheet(
StyleSheet::located("/doc/css/chrome.css")
))
.with_context(InContextOp::StyleSheet(
AssetsOp::<StyleSheet>::Add(
StyleSheet::located("/doc/css/print.css").for_media(TargetMedia::Print)
)
.with_context(InContextOp::AddStyleSheet(
StyleSheet::located("/doc/css/print.css").for_media(TargetMedia::Print)
))
.with_context(InContextOp::StyleSheet(
AssetsOp::<StyleSheet>::Add(StyleSheet::located("/doc/FontAwesome/css/font-awesome.css"))
.with_context(InContextOp::AddStyleSheet(
StyleSheet::located("/doc/FontAwesome/css/font-awesome.css")
))
.with_context(InContextOp::StyleSheet(
AssetsOp::<StyleSheet>::Add(StyleSheet::located("/doc/fonts/fonts.css"))
.with_context(InContextOp::AddStyleSheet(
StyleSheet::located("/doc/fonts/fonts.css")
))
.with_context(InContextOp::StyleSheet(
AssetsOp::<StyleSheet>::Add(StyleSheet::located("/doc/highlight.css"))
.with_context(InContextOp::AddStyleSheet(
StyleSheet::located("/doc/highlight.css")
))
.with_context(InContextOp::StyleSheet(
AssetsOp::<StyleSheet>::Add(StyleSheet::located("/doc/tomorrow-night.css"))
.with_context(InContextOp::AddStyleSheet(
StyleSheet::located("/doc/tomorrow-night.css")
))
.with_context(InContextOp::StyleSheet(
AssetsOp::<StyleSheet>::Add(StyleSheet::located("/doc/ayu-highlight.css"))
.with_context(InContextOp::AddStyleSheet(
StyleSheet::located("/doc/ayu-highlight.css")
))
.add_to(
"region-content",