initial commit
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
use indoc::indoc;
|
||||
|
||||
use crate::css::scope_css;
|
||||
|
||||
use crate::compiler::models::{PageRoute, Project, Template};
|
||||
use crate::js::minify_javascript;
|
||||
|
||||
impl Project {
|
||||
pub fn compile_script(&self) -> String {
|
||||
let template = indoc! { r#"
|
||||
(function() {
|
||||
if (typeof Handlebars === 'undefined') {
|
||||
const script = document.createElement('script');
|
||||
script.src = 'https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.js';
|
||||
document.head.appendChild(script);
|
||||
}
|
||||
|
||||
const tempDefine = window.define;
|
||||
window.define = undefined;
|
||||
|
||||
const script = document.createElement('script');
|
||||
script.src = 'https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.js';
|
||||
|
||||
script.onload = function() {
|
||||
window.define = tempDefine;
|
||||
|
||||
{pages_script}
|
||||
};
|
||||
|
||||
document.head.appendChild(script);
|
||||
|
||||
})()
|
||||
"# };
|
||||
let mut script = String::new();
|
||||
|
||||
for page in &self.pages {
|
||||
let template_script = indoc! { r#"
|
||||
if (eval({page_route})) {
|
||||
{content_script}
|
||||
}
|
||||
"# };
|
||||
|
||||
let route_script = page.route.as_script();
|
||||
let content_script = page
|
||||
.content
|
||||
.iter()
|
||||
.map(|template| template.as_script())
|
||||
.collect::<Vec<String>>()
|
||||
.join("\n");
|
||||
|
||||
script.push_str(
|
||||
&template_script
|
||||
.replace("{page_route}", &format!("{:?}", minify_javascript(&route_script)))
|
||||
.replace("{content_script}", &content_script),
|
||||
);
|
||||
}
|
||||
|
||||
minify_javascript(&template.replace("{pages_script}", &script))
|
||||
}
|
||||
}
|
||||
|
||||
impl PageRoute {
|
||||
fn as_script(&self) -> String {
|
||||
match self {
|
||||
PageRoute::Regexpr(expr) => {
|
||||
let template = indoc! { r#"
|
||||
(function() {
|
||||
const regex = new RegExp({expr});
|
||||
return regex.test(window.location.pathname);
|
||||
})()
|
||||
"# };
|
||||
|
||||
template.replace("{expr}", &format!("{:?}", expr.trim()))
|
||||
}
|
||||
PageRoute::Static(route) => {
|
||||
let template = indoc! { r#"
|
||||
(function() {
|
||||
return window.location.pathname === {route};
|
||||
})()
|
||||
"# };
|
||||
|
||||
template.replace("{route}", &format!("{:?}", route))
|
||||
}
|
||||
PageRoute::CustomScript(script) => script.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Template {
|
||||
pub fn as_script(&self) -> String {
|
||||
match self {
|
||||
Template::CustomScript { script, style } => {
|
||||
if style.is_none() || style.as_ref().unwrap().trim().is_empty() {
|
||||
return script.clone();
|
||||
}
|
||||
|
||||
let style_script = style.as_ref().map_or(String::new(), |s| {
|
||||
format!(
|
||||
r#"
|
||||
const styleElement = document.createElement('style');
|
||||
styleElement.textContent = {style};
|
||||
document.head.appendChild(styleElement);
|
||||
"#,
|
||||
style = format!("{:?}", s)
|
||||
)
|
||||
});
|
||||
|
||||
format!("{}\n{}", style_script, script)
|
||||
}
|
||||
Template::TemplateInjector {
|
||||
template,
|
||||
replace_selector,
|
||||
scraper,
|
||||
style,
|
||||
} => {
|
||||
let scope_class = format!("template-style-{}", rand::random::<u32>());
|
||||
|
||||
let style_script = if let Some(style) = style {
|
||||
if style.trim().is_empty() {
|
||||
String::new()
|
||||
} else {
|
||||
format!(
|
||||
indoc! {r#"
|
||||
const styleElement = document.createElement('style');
|
||||
styleElement.textContent = {style};
|
||||
document.head.appendChild(styleElement);
|
||||
"# },
|
||||
style = &scope_css(&style, &scope_class)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
|
||||
let script_template = indoc! { r#"
|
||||
(function() {
|
||||
{style_script}
|
||||
|
||||
const parsedData = eval({scraper} || "(() => ({}))");
|
||||
const template = Handlebars.compile({template});
|
||||
const rendered = template(parsedData);
|
||||
console.log("Rendered template:", rendered);
|
||||
const targetElement = document.querySelector({replace_selector});
|
||||
|
||||
const temp = document.createElement('template');
|
||||
temp.innerHTML = rendered;
|
||||
|
||||
const newElement = temp.content.firstElementChild;
|
||||
|
||||
targetElement.replaceWith(newElement);
|
||||
|
||||
newElement.classList.add({scope_class});
|
||||
})();
|
||||
"# };
|
||||
|
||||
script_template
|
||||
.replace("{style_script}", &style_script)
|
||||
.replace("{template}", &format!("{:?}", template.trim()))
|
||||
.replace("{replace_selector}", &format!("{:?}", replace_selector))
|
||||
.replace("{scope_class}", &format!("{:?}", scope_class))
|
||||
.replace(
|
||||
"{scraper}",
|
||||
&format!("{:?}", minify_javascript(scraper.as_deref().unwrap_or(""))),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user