From bd0aae2e700aee85d8c978d0989c5c220307ed6e Mon Sep 17 00:00:00 2001 From: Teascade Date: Thu, 19 Apr 2018 22:21:49 +0300 Subject: [PATCH] Add default transition javascript --- config.example.toml | 48 +++++++++----- config.toml | 29 ++++---- src/builder.rs | 24 ++++++- src/config_toml.rs | 1 + src/file_writer.rs | 7 +- src/main.rs | 2 + src/template.rs | 1 + src/templates/default-js.js | 81 +++++++++++++++++++++++ src/templates/meta_tags/css_tag.html | 2 +- src/templates/meta_tags/js_tag.html | 2 +- src/templates/page-template.html | 5 +- test_page/about.toml | 2 +- test_page/other.toml | 6 +- test_page/resources/img/global.png | Bin 0 -> 20392 bytes test_page/resources/img/square_trans.png | Bin 0 -> 347 bytes 15 files changed, 167 insertions(+), 43 deletions(-) create mode 100644 src/templates/default-js.js create mode 100644 test_page/resources/img/global.png create mode 100644 test_page/resources/img/square_trans.png diff --git a/config.example.toml b/config.example.toml index 7906670..1451945 100644 --- a/config.example.toml +++ b/config.example.toml @@ -4,25 +4,41 @@ built_pages = ["test_page/about.toml", "test_page/other.toml"] use_default_css = true javascript = [] css = [] -#before_navbar_url = "/navbar.html" -#before_content_url = "/before_content.html" -#after_content_url = "/after_content.html" +#before_navbar_url = "test_page/resources/before_navbar.html" +#before_content_url = "test_page/resources/before_content.html" +#after_content_url = "test_page/resources/after_content.html" #favicon = "favicon.png" -#twitter_author = "@teascade" + +#charset = "utf-8" +#mobile_viewport = true +#meta_description = true +#meta_og = true + +#output = "public" + +#[google] #google_robots = "all" -#google_site_verification = "" +#google_site_verification = "some_verification" -[navbar] -items = ["about", "other", "google"] +#[twitter] +#twitter_site = "@teascade" +#twitter_creator = "@teascade" - [navbar.item.about] - title = "About" - link = "/" +#[navbar] +#items = ["about", "other", "google"] +# +# [navbar.item.about] +# title = "About" +# link = "/" - [navbar.item.other] - title = "Other" - link = "/other" +# [navbar.item.other] +# title = "Other" +# link = "/other" - [navbar.item.google] - title = "Google!" - link = "https://google.com" \ No newline at end of file +# [navbar.item.google] +# title = "Google!" +# link = "https://google.com" + +#[resource.test] +#source = "test_page/resources/copied_resources/" +#destination = "" \ No newline at end of file diff --git a/config.toml b/config.toml index b39fe66..158246d 100644 --- a/config.toml +++ b/config.toml @@ -2,12 +2,13 @@ website_name = "Test Website Name!" built_pages = ["test_page/about.toml", "test_page/other.toml"] use_default_css = true -javascript = [] -css = [] +use_default_js = true +javascript = ["test.js"] +css = ["test.css"] before_navbar_url = "test_page/resources/before_navbar.html" before_content_url = "test_page/resources/before_content.html" after_content_url = "test_page/resources/after_content.html" -favicon = "favicon.png" +favicon = "/img/global.png" charset = "utf-8" mobile_viewport = true @@ -27,18 +28,18 @@ twitter_creator = "@teascade" [navbar] items = ["about", "other", "google"] -[navbar.item.about] -title = "About" -link = "/" + [navbar.item.about] + title = "About" + link = "/" -[navbar.item.other] -title = "Other" -link = "/other" + [navbar.item.other] + title = "Other" + link = "/other" -[navbar.item.google] -title = "Google!" -link = "https://google.com" + [navbar.item.google] + title = "Google!" + link = "https://google.com" [resource.test] -source = "test_page/resources/copied_resources/" -destination = "" \ No newline at end of file +source = "test_page/resources/img" +destination = "img" \ No newline at end of file diff --git a/src/builder.rs b/src/builder.rs index 148557c..65113ed 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -15,6 +15,7 @@ use options::{BuildOpt, Opt}; use file_writer; const DEFAULT_CSS: &'static str = include_str!("templates/default-css.css"); +const DEFAULT_JS: &'static str = include_str!("templates/default-js.js"); const PAGE_TEMPLATE: &'static str = include_str!("templates/page-template.html"); const NAVBAR_ITEM: &'static str = include_str!("templates/navbar/item-template.html"); const NAVBAR_IMAGE_ITEM: &'static str = include_str!("templates/navbar/image-item-template.html"); @@ -46,6 +47,20 @@ pub fn build(logger: &Logger, opt: &Opt, _: &BuildOpt) -> Result<(), Error> { file_writer::write_file(&css_path, DEFAULT_CSS, opt.overwrite)?; } + if config.global_config.website.use_default_js { + let js_path = file_writer::add_to_beginning( + PathBuf::from("js/default.js"), + config + .clone() + .global_config + .website + .output + .unwrap_or("public".to_owned()), + ); + logger.log(LogLevel::DETAIL, format!("Adding {:?}", js_path)); + file_writer::write_file(&js_path, DEFAULT_JS, opt.overwrite)?; + } + logger.log(LogLevel::INFO, "Generating page templates"); let page_template = Template::new(PAGE_TEMPLATE); let css_tag_template = Template::new(CSS_TAG); @@ -207,15 +222,18 @@ fn write_recursive_resource( } else { match File::open(resource_path.clone()) { Ok(mut read_file) => { - let mut contents = String::new(); - read_file.read_to_string(&mut contents)?; + let bytes: Vec = match read_file.bytes().collect() { + Ok(bytes) => bytes, + Err(_) => Vec::new(), + }; + let mut dest_path = destination.clone(); if source.is_dir() { dest_path = dest_path.join(relative.clone()); dest_path.set_file_name(resource_path.file_name().unwrap()); } - file_writer::write_file(&dest_path, contents, true)?; + file_writer::write_bytes(&dest_path, &bytes, true)?; Ok(()) } diff --git a/src/config_toml.rs b/src/config_toml.rs index 433a6fe..afdf4c8 100644 --- a/src/config_toml.rs +++ b/src/config_toml.rs @@ -30,6 +30,7 @@ pub struct WebsiteConfig { pub website_name: String, pub built_pages: Vec, pub use_default_css: bool, + pub use_default_js: bool, pub javascript: Vec, pub css: Vec, diff --git a/src/file_writer.rs b/src/file_writer.rs index c91abdb..12bd976 100644 --- a/src/file_writer.rs +++ b/src/file_writer.rs @@ -42,6 +42,10 @@ pub fn write_file>( content: T, overwrite: bool, ) -> Result<(), Error> { + write_bytes(path, content.into().as_bytes(), overwrite) +} + +pub fn write_bytes(path: &PathBuf, bytes: &[u8], overwrite: bool) -> Result<(), Error> { if let Some(parent) = path.clone().parent() { create_dir_all(parent.clone())?; } else { @@ -51,7 +55,6 @@ pub fn write_file>( )); } - let content = content.into(); if path.exists() && !overwrite { Err(Error::new( LogLevel::SEVERE, @@ -62,7 +65,7 @@ pub fn write_file>( )) } else { match File::create(path) { - Ok(mut file) => Ok(file.write_all(content.as_bytes()).unwrap()), + Ok(mut file) => Ok(file.write_all(bytes).unwrap()), Err(err) => Err(Error::from(err)), } } diff --git a/src/main.rs b/src/main.rs index f2f92c8..a3fc8b5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,6 +30,7 @@ use logger::{LogLevel, Logger}; use options::{Opt, Subcommands}; use config_toml::{GlobalConfigToml, NavbarConfig, NavbarItem, WebsiteConfig}; +//TODO: Custom markdown fn main() { exit(match run() { Ok(()) => 0, @@ -102,6 +103,7 @@ fn run() -> Result<(), ()> { website_name: init_opt.name, built_pages: Vec::new(), use_default_css: true, + use_default_js: true, javascript: Vec::new(), css: Vec::new(), favicon: init_opt.favicon, diff --git a/src/template.rs b/src/template.rs index 8af9d94..bd9c2e4 100644 --- a/src/template.rs +++ b/src/template.rs @@ -125,6 +125,7 @@ impl Template { "javascript_links".to_owned() => js_tags, "use_default_css".to_owned() => config.global_config.website.use_default_css.to_string(), + "use_default_js".to_owned() => config.global_config.website.use_default_js.to_string(), "navbar".to_owned() => config.global_config.navbar.is_some().to_string(), "navbar_content".to_owned() => navbar_content, diff --git a/src/templates/default-js.js b/src/templates/default-js.js new file mode 100644 index 0000000..42b3926 --- /dev/null +++ b/src/templates/default-js.js @@ -0,0 +1,81 @@ + +var _default_js_pageloader = { + begin: (url) => { console.log("Started to load " + url); }, + progress: (url, current, total) => { console.log("Progress of " + url + ": " + current + "/" + current + " (" + ((current / total) * 100) + "%)"); }, + loaded: (url) => { console.log("Loaded " + url); } +} + +function _default_js_main() { + let elements = document.getElementsByTagName("a"); + for (element of elements) { + if (element.hostname == window.location.hostname) { + element.onclick = _default_js_onclick; + } + } + + window.onpopstate = function () { + var page = window.location + _default_js_open_page(page, false); + }; + +} + +function _default_js_onclick(event) { + event.preventDefault(); + let url = event.target.href; + _default_js_open_page(url, true); +} + +function _default_js_open_page(url, no_pop_state) { + let request = new XMLHttpRequest(); + request.addEventListener("loadstart", (progress) => { + _default_js_pageloader.begin(url); + }); + request.addEventListener("progress", (progress) => { + _default_js_pageloader.progress(url, progress.loaded, progress.total); + }); + request.addEventListener("loadend", (progress) => { + _default_js_pageloader.loaded(url); + let parser = new DOMParser(); + let new_document = parser.parseFromString(request.responseText, "text/html"); + change_page(new_document, url, no_pop_state); + }); + request.open("GET", url); + request.send(); +} + +function change_page(new_document, new_url, no_pop_state) { + + // Some meta tags + document.title = new_document.title; + let new_favicon = new_document.querySelector("link[rel*='icon']").href; + + document.querySelector("link[rel*='icon']").href = new_favicon; + + // Replace css/js tags + let list = document.getElementsByClassName("._default_js_meta"); + for (i in list) { + let element = list[0]; + if (element !== undefined) { + element.parentNode.removeChild(element); + } + } + + let new_list = new_document.getElementsByClassName("._default_js_meta"); + for (i in new_list) { + let element = new_list[0]; + if (element !== undefined) { + document.head.appendChild(element); + } + } + + // Actually replace the content + document.body = new_document.body; + _default_js_main(); + + // Do history modifications + if (no_pop_state) { + window.history.pushState(new_url, new_url, new_url); + } + +} \ No newline at end of file diff --git a/src/templates/meta_tags/css_tag.html b/src/templates/meta_tags/css_tag.html index e6699e1..adf1645 100644 --- a/src/templates/meta_tags/css_tag.html +++ b/src/templates/meta_tags/css_tag.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/templates/meta_tags/js_tag.html b/src/templates/meta_tags/js_tag.html index 10d8897..d10193b 100644 --- a/src/templates/meta_tags/js_tag.html +++ b/src/templates/meta_tags/js_tag.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/templates/page-template.html b/src/templates/page-template.html index 27ba9bc..dc07509 100644 --- a/src/templates/page-template.html +++ b/src/templates/page-template.html @@ -22,7 +22,8 @@ - {{endif}} {{if use_default_css}} + {{endif}} {{if use_default_js}} + {{endif}} {{if use_default_css}} {{endif}} {{css_links}}{{javascript_links}} @@ -30,7 +31,7 @@ {{page_title}} - + {{before_navbar}} {{if navbar}}