148 lines
4.1 KiB
Rust
148 lines
4.1 KiB
Rust
use crate::{Lazy, base, concat_string, util};
|
|
use crate::config::SETTINGS;
|
|
use crate::html::{Markup, html};
|
|
use crate::core::theme::*;
|
|
|
|
mod favicon;
|
|
pub use favicon::Favicon;
|
|
|
|
mod javascript;
|
|
pub use javascript::{JavaScript, JSMode};
|
|
|
|
mod stylesheet;
|
|
pub use stylesheet::StyleSheet;
|
|
|
|
static DEFAULT_THEME: Lazy<&dyn ThemeTrait> = Lazy::new(|| {
|
|
match all::theme_by_single_name(&SETTINGS.app.theme) {
|
|
Some(theme) => theme,
|
|
None => &base::theme::bootsier::Bootsier,
|
|
}
|
|
});
|
|
|
|
pub struct InContext {
|
|
theme : &'static dyn ThemeTrait,
|
|
favicon : Option<Favicon>,
|
|
metadata : Vec<(String, String)>,
|
|
stylesheets: Vec<StyleSheet>,
|
|
javascripts: Vec<JavaScript>,
|
|
with_jquery: bool,
|
|
id_counter : usize,
|
|
}
|
|
|
|
impl InContext {
|
|
pub fn new() -> Self {
|
|
InContext {
|
|
theme : *DEFAULT_THEME,
|
|
favicon : None,
|
|
metadata : Vec::new(),
|
|
stylesheets: Vec::new(),
|
|
javascripts: Vec::new(),
|
|
with_jquery: false,
|
|
id_counter : 0,
|
|
}
|
|
}
|
|
|
|
pub fn using_theme(&mut self, theme_name: &str) -> &mut Self {
|
|
self.theme = all::theme_by_single_name(theme_name).unwrap_or(*DEFAULT_THEME);
|
|
self
|
|
}
|
|
|
|
pub fn with_favicon(&mut self, favicon: Favicon) -> &mut Self {
|
|
self.favicon = Some(favicon);
|
|
self
|
|
}
|
|
|
|
pub fn add_metadata(&mut self, name: String, content: String) -> &mut Self {
|
|
self.metadata.push((name, content));
|
|
self
|
|
}
|
|
|
|
pub fn add_stylesheet(&mut self, css: StyleSheet) -> &mut Self {
|
|
match self.stylesheets.iter().position(|x| x.source == css.source) {
|
|
Some(index) => if self.stylesheets[index].weight > css.weight {
|
|
self.stylesheets.remove(index);
|
|
self.stylesheets.push(css);
|
|
},
|
|
_ => self.stylesheets.push(css)
|
|
}
|
|
self
|
|
}
|
|
|
|
pub fn add_javascript(&mut self, js: JavaScript) -> &mut Self {
|
|
match self.javascripts.iter().position(|x| x.source == js.source) {
|
|
Some(index) => if self.javascripts[index].weight > js.weight {
|
|
self.javascripts.remove(index);
|
|
self.javascripts.push(js);
|
|
},
|
|
_ => self.javascripts.push(js)
|
|
}
|
|
self
|
|
}
|
|
|
|
pub fn add_jquery(&mut self) -> &mut Self {
|
|
if !self.with_jquery {
|
|
self.add_javascript(
|
|
JavaScript::source(
|
|
"/theme/js/jquery.min.js?ver=3.6.0"
|
|
)
|
|
.with_weight(isize::MIN)
|
|
.with_mode(JSMode::Normal)
|
|
);
|
|
self.with_jquery = true;
|
|
}
|
|
self
|
|
}
|
|
|
|
/// InContext GETTERS.
|
|
|
|
pub(crate) fn theme(&mut self) -> &'static dyn ThemeTrait {
|
|
self.theme
|
|
}
|
|
|
|
/// InContext RENDER.
|
|
|
|
pub fn render(&mut self) -> Markup {
|
|
let ordered_css = &mut self.stylesheets;
|
|
ordered_css.sort_by_key(|css| css.weight);
|
|
|
|
let ordered_js = &mut self.javascripts;
|
|
ordered_js.sort_by_key(|js| js.weight);
|
|
|
|
html! {
|
|
@match &self.favicon {
|
|
Some(favicon) => (favicon.render()),
|
|
None => "",
|
|
}
|
|
@for (name, content) in &self.metadata {
|
|
meta name=(name) content=(content) {}
|
|
}
|
|
@for css in ordered_css {
|
|
(css.render())
|
|
}
|
|
@for js in ordered_js {
|
|
(js.render())
|
|
}
|
|
}
|
|
}
|
|
|
|
// InContext EXTRAS.
|
|
|
|
pub fn required_id<T>(&mut self, id: &Option<String>) -> String {
|
|
match id {
|
|
Some(id) => id.to_string(),
|
|
None => {
|
|
let prefix = util::single_type_name::<T>()
|
|
.trim()
|
|
.replace(" ", "_")
|
|
.to_lowercase();
|
|
let prefix = if prefix.is_empty() {
|
|
"prefix".to_owned()
|
|
} else {
|
|
prefix
|
|
};
|
|
self.id_counter += 1;
|
|
concat_string!(prefix, "-", self.id_counter.to_string())
|
|
}
|
|
}
|
|
}
|
|
}
|