Implemented support for additional JS

This commit is contained in:
Michal Budzynski 2017-06-06 20:34:57 +02:00
parent 6c279453d9
commit f96e7e5cba
6 changed files with 82 additions and 5 deletions

View File

@ -487,6 +487,22 @@ impl MDBook {
None None
} }
pub fn has_additional_js(&self) -> bool {
if let Some(htmlconfig) = self.config.get_html_config() {
return htmlconfig.has_additional_js();
}
false
}
pub fn get_additional_js(&self) -> &[PathBuf] {
if let Some(htmlconfig) = self.config.get_html_config() {
return htmlconfig.get_additional_js();
}
&[]
}
pub fn has_additional_css(&self) -> bool { pub fn has_additional_css(&self) -> bool {
if let Some(htmlconfig) = self.config.get_html_config() { if let Some(htmlconfig) = self.config.get_html_config() {
return htmlconfig.has_additional_css(); return htmlconfig.has_additional_css();

View File

@ -8,6 +8,7 @@ pub struct HtmlConfig {
theme: Option<PathBuf>, theme: Option<PathBuf>,
google_analytics: Option<String>, google_analytics: Option<String>,
additional_css: Vec<PathBuf>, additional_css: Vec<PathBuf>,
additional_js: Vec<PathBuf>,
} }
impl HtmlConfig { impl HtmlConfig {
@ -28,6 +29,7 @@ impl HtmlConfig {
theme: None, theme: None,
google_analytics: None, google_analytics: None,
additional_css: Vec::new(), additional_css: Vec::new(),
additional_js: Vec::new(),
} }
} }
@ -64,6 +66,16 @@ impl HtmlConfig {
} }
} }
if let Some(scriptpaths) = tomlconfig.additional_js {
for path in scriptpaths {
if path.is_relative() {
self.additional_js.push(root.join(path));
} else {
self.additional_js.push(path);
}
}
}
self self
} }
@ -114,4 +126,12 @@ impl HtmlConfig {
pub fn get_additional_css(&self) -> &[PathBuf] { pub fn get_additional_css(&self) -> &[PathBuf] {
&self.additional_css &self.additional_css
} }
pub fn has_additional_js(&self) -> bool {
!self.additional_js.is_empty()
}
pub fn get_additional_js(&self) -> &[PathBuf] {
&self.additional_js
}
} }

View File

@ -25,6 +25,7 @@ pub struct TomlHtmlConfig {
pub theme: Option<PathBuf>, pub theme: Option<PathBuf>,
pub google_analytics: Option<String>, pub google_analytics: Option<String>,
pub additional_css: Option<Vec<PathBuf>>, pub additional_css: Option<Vec<PathBuf>>,
pub additional_js: Option<Vec<PathBuf>>,
} }
/// Returns a TomlConfig from a TOML string /// Returns a TomlConfig from a TOML string

View File

@ -187,14 +187,22 @@ impl Renderer for HtmlHandlebars {
book.write_file("_FontAwesome/fonts/fontawesome-webfont.woff2", theme::FONT_AWESOME_WOFF2)?; book.write_file("_FontAwesome/fonts/fontawesome-webfont.woff2", theme::FONT_AWESOME_WOFF2)?;
book.write_file("_FontAwesome/fonts/FontAwesome.ttf", theme::FONT_AWESOME_TTF)?; book.write_file("_FontAwesome/fonts/FontAwesome.ttf", theme::FONT_AWESOME_TTF)?;
for style in book.get_additional_css() { for custom_file in book.get_additional_css()
.iter()
.chain(book.get_additional_js().iter()) {
let mut data = Vec::new(); let mut data = Vec::new();
let mut f = File::open(style)?; let mut f = File::open(custom_file)?;
f.read_to_end(&mut data)?; f.read_to_end(&mut data)?;
let name = match style.strip_prefix(book.get_root()) { let name = match custom_file.strip_prefix(book.get_root()) {
Ok(p) => p.to_str().expect("Could not convert to str"), Ok(p) => p.to_str().expect("Could not convert to str"),
Err(_) => style.file_name().expect("File has a file name").to_str().expect("Could not convert to str"), Err(_) => {
custom_file
.file_name()
.expect("File has a file name")
.to_str()
.expect("Could not convert to str")
}
}; };
book.write_file(name, &data)?; book.write_file(name, &data)?;
@ -240,6 +248,18 @@ fn make_data(book: &MDBook) -> Result<serde_json::Map<String, serde_json::Value>
data.insert("additional_css".to_owned(), json!(css)); data.insert("additional_css".to_owned(), json!(css));
} }
// Add check to see if there is an additional script
if book.has_additional_js() {
let mut js = Vec::new();
for script in book.get_additional_js() {
match script.strip_prefix(book.get_root()) {
Ok(p) => js.push(p.to_str().expect("Could not convert to str")),
Err(_) => js.push(script.file_name().expect("File has a file name").to_str().expect("Could not convert to str")),
}
}
data.insert("additional_js".to_owned(), json!(js));
}
let mut chapters = vec![]; let mut chapters = vec![];
for item in book.iter() { for item in book.iter() {

View File

@ -44,6 +44,12 @@
document.write(unescape("%3Cscript src='jquery.js'%3E%3C/script%3E")); document.write(unescape("%3Cscript src='jquery.js'%3E%3C/script%3E"));
} }
</script> </script>
<!-- Custom JS script -->
{{#each additional_js}}
<script type="text/javascript" src="{{this}}"></script>
{{/each}}
</head> </head>
<body class="light"> <body class="light">
<!-- Set the theme before any content is loaded, prevents flash --> <!-- Set the theme before any content is loaded, prevents flash -->

View File

@ -115,3 +115,17 @@ fn from_toml_output_html_additional_stylesheet() {
assert_eq!(htmlconfig.get_additional_css(), &[PathBuf::from("root/custom.css"), PathBuf::from("root/two/custom.css")]); assert_eq!(htmlconfig.get_additional_css(), &[PathBuf::from("root/custom.css"), PathBuf::from("root/two/custom.css")]);
} }
// Tests that the `output.html.additional-js` key is correcly parsed in the TOML config
#[test]
fn from_toml_output_html_additional_scripts() {
let toml = r#"[output.html]
additional-js = ["custom.js", "two/custom.js"]"#;
let parsed = TomlConfig::from_toml(&toml).expect("This should parse");
let config = BookConfig::from_tomlconfig("root", parsed);
let htmlconfig = config.get_html_config().expect("There should be an HtmlConfig");
assert_eq!(htmlconfig.get_additional_js(), &[PathBuf::from("root/custom.js"), PathBuf::from("root/two/custom.js")]);
}