1
Fork 0

new --static-root-path flag for controlling static file locations

This commit is contained in:
QuietMisdreavus 2018-12-20 10:18:45 -06:00
parent 0a4a4ffc69
commit 0b0a00cc05
6 changed files with 80 additions and 14 deletions

View file

@ -402,3 +402,18 @@ Using `index-page` option enables `enable-index-page` option as well.
### `--enable-index-page`: generate a default index page for docs ### `--enable-index-page`: generate a default index page for docs
This feature allows the generation of a default index-page which lists the generated crates. This feature allows the generation of a default index-page which lists the generated crates.
### `--static-root-path`: control how static files are loaded in HTML output
Using this flag looks like this:
```bash
$ rustdoc src/lib.rs -Z unstable-options --static-root-path '/cache/'
```
This flag controls how rustdoc links to its static files on HTML pages. If you're hosting a lot of
crates' docs generated by the same version of rustdoc, you can use this flag to cache rustdoc's CSS,
JavaScript, and font files in a single location, rather than duplicating it once per "doc root"
(grouping of crate docs generated into the same output directory, like with `cargo doc`). Per-crate
files like the search index will still load from the documentation root, but anything that gets
renamed with `--resource-suffix` will load from the given path.

View file

@ -181,6 +181,9 @@ pub struct RenderOptions {
/// A file to use as the index page at the root of the output directory. Overrides /// A file to use as the index page at the root of the output directory. Overrides
/// `enable_index_page` to be true if set. /// `enable_index_page` to be true if set.
pub index_page: Option<PathBuf>, pub index_page: Option<PathBuf>,
/// An optional path to use as the location of static files. If not set, uses combinations of
/// `../` to reach the documentation root.
pub static_root_path: Option<String>,
// Options specific to reading standalone Markdown files // Options specific to reading standalone Markdown files
@ -433,6 +436,7 @@ impl Options {
let markdown_playground_url = matches.opt_str("markdown-playground-url"); let markdown_playground_url = matches.opt_str("markdown-playground-url");
let crate_version = matches.opt_str("crate-version"); let crate_version = matches.opt_str("crate-version");
let enable_index_page = matches.opt_present("enable-index-page") || index_page.is_some(); let enable_index_page = matches.opt_present("enable-index-page") || index_page.is_some();
let static_root_path = matches.opt_str("static-root-path");
let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format); let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);
@ -471,6 +475,7 @@ impl Options {
enable_minification, enable_minification,
enable_index_page, enable_index_page,
index_page, index_page,
static_root_path,
markdown_no_toc, markdown_no_toc,
markdown_css, markdown_css,
markdown_playground_url, markdown_playground_url,

View file

@ -26,6 +26,7 @@ pub struct Page<'a> {
pub title: &'a str, pub title: &'a str,
pub css_class: &'a str, pub css_class: &'a str,
pub root_path: &'a str, pub root_path: &'a str,
pub static_root_path: Option<&'a str>,
pub description: &'a str, pub description: &'a str,
pub keywords: &'a str, pub keywords: &'a str,
pub resource_suffix: &'a str, pub resource_suffix: &'a str,
@ -36,6 +37,7 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
css_file_extension: bool, themes: &[PathBuf], extra_scripts: &[&str]) css_file_extension: bool, themes: &[PathBuf], extra_scripts: &[&str])
-> io::Result<()> -> io::Result<()>
{ {
let static_root_path = page.static_root_path.unwrap_or(page.root_path);
write!(dst, write!(dst,
"<!DOCTYPE html>\ "<!DOCTYPE html>\
<html lang=\"en\">\ <html lang=\"en\">\
@ -46,20 +48,20 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
<meta name=\"description\" content=\"{description}\">\ <meta name=\"description\" content=\"{description}\">\
<meta name=\"keywords\" content=\"{keywords}\">\ <meta name=\"keywords\" content=\"{keywords}\">\
<title>{title}</title>\ <title>{title}</title>\
<link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}normalize{suffix}.css\">\ <link rel=\"stylesheet\" type=\"text/css\" href=\"{static_root_path}normalize{suffix}.css\">\
<link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}rustdoc{suffix}.css\" \ <link rel=\"stylesheet\" type=\"text/css\" href=\"{static_root_path}rustdoc{suffix}.css\" \
id=\"mainThemeStyle\">\ id=\"mainThemeStyle\">\
{themes}\ {themes}\
<link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}dark{suffix}.css\">\ <link rel=\"stylesheet\" type=\"text/css\" href=\"{static_root_path}dark{suffix}.css\">\
<link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}light{suffix}.css\" \ <link rel=\"stylesheet\" type=\"text/css\" href=\"{static_root_path}light{suffix}.css\" \
id=\"themeStyle\">\ id=\"themeStyle\">\
<script src=\"{root_path}storage{suffix}.js\"></script>\ <script src=\"{static_root_path}storage{suffix}.js\"></script>\
<noscript><link rel=\"stylesheet\" href=\"{root_path}noscript{suffix}.css\"></noscript>\ <noscript><link rel=\"stylesheet\" href=\"{static_root_path}noscript{suffix}.css\"></noscript>\
{css_extension}\ {css_extension}\
{favicon}\ {favicon}\
{in_header}\ {in_header}\
<style type=\"text/css\">\ <style type=\"text/css\">\
#crate-search{{background-image:url(\"{root_path}down-arrow{suffix}.svg\");}}\ #crate-search{{background-image:url(\"{static_root_path}down-arrow{suffix}.svg\");}}\
</style>\ </style>\
</head>\ </head>\
<body class=\"rustdoc {css_class}\">\ <body class=\"rustdoc {css_class}\">\
@ -77,11 +79,13 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
</nav>\ </nav>\
<div class=\"theme-picker\">\ <div class=\"theme-picker\">\
<button id=\"theme-picker\" aria-label=\"Pick another theme!\">\ <button id=\"theme-picker\" aria-label=\"Pick another theme!\">\
<img src=\"{root_path}brush{suffix}.svg\" width=\"18\" alt=\"Pick another theme!\">\ <img src=\"{static_root_path}brush{suffix}.svg\" \
width=\"18\" \
alt=\"Pick another theme!\">\
</button>\ </button>\
<div id=\"theme-choices\"></div>\ <div id=\"theme-choices\"></div>\
</div>\ </div>\
<script src=\"{root_path}theme{suffix}.js\"></script>\ <script src=\"{static_root_path}theme{suffix}.js\"></script>\
<nav class=\"sub\">\ <nav class=\"sub\">\
<form class=\"search-form js-only\">\ <form class=\"search-form js-only\">\
<div class=\"search-container\">\ <div class=\"search-container\">\
@ -96,7 +100,9 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
type=\"search\">\ type=\"search\">\
</div>\ </div>\
<a id=\"settings-menu\" href=\"{root_path}settings.html\">\ <a id=\"settings-menu\" href=\"{root_path}settings.html\">\
<img src=\"{root_path}wheel{suffix}.svg\" width=\"18\" alt=\"Change settings\">\ <img src=\"{static_root_path}wheel{suffix}.svg\" \
width=\"18\" \
alt=\"Change settings\">\
</a>\ </a>\
</div>\ </div>\
</form>\ </form>\
@ -157,19 +163,22 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
window.currentCrate = \"{krate}\";\ window.currentCrate = \"{krate}\";\
</script>\ </script>\
<script src=\"{root_path}aliases.js\"></script>\ <script src=\"{root_path}aliases.js\"></script>\
<script src=\"{root_path}main{suffix}.js\"></script>\ <script src=\"{static_root_path}main{suffix}.js\"></script>\
{extra_scripts}\ {extra_scripts}\
<script defer src=\"{root_path}search-index.js\"></script>\ <script defer src=\"{root_path}search-index.js\"></script>\
</body>\ </body>\
</html>", </html>",
css_extension = if css_file_extension { css_extension = if css_file_extension {
format!("<link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}theme{suffix}.css\">", format!("<link rel=\"stylesheet\" \
root_path = page.root_path, type=\"text/css\" \
href=\"{static_root_path}theme{suffix}.css\">",
static_root_path = static_root_path,
suffix=page.resource_suffix) suffix=page.resource_suffix)
} else { } else {
String::new() String::new()
}, },
content = *t, content = *t,
static_root_path = static_root_path,
root_path = page.root_path, root_path = page.root_path,
css_class = page.css_class, css_class = page.css_class,
logo = if layout.logo.is_empty() { logo = if layout.logo.is_empty() {
@ -197,11 +206,13 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
.filter_map(|t| t.file_stem()) .filter_map(|t| t.file_stem())
.filter_map(|t| t.to_str()) .filter_map(|t| t.to_str())
.map(|t| format!(r#"<link rel="stylesheet" type="text/css" href="{}{}{}.css">"#, .map(|t| format!(r#"<link rel="stylesheet" type="text/css" href="{}{}{}.css">"#,
page.root_path, static_root_path,
t, t,
page.resource_suffix)) page.resource_suffix))
.collect::<String>(), .collect::<String>(),
suffix=page.resource_suffix, suffix=page.resource_suffix,
// TODO: break out a separate `static_extra_scripts` that uses `static_root_path` instead,
// then leave `source-files.js` here and move `source-script.js` to the static version
extra_scripts=extra_scripts.iter().map(|e| { extra_scripts=extra_scripts.iter().map(|e| {
format!("<script src=\"{root_path}{extra_script}.js\"></script>", format!("<script src=\"{root_path}{extra_script}.js\"></script>",
root_path=page.root_path, root_path=page.root_path,

View file

@ -140,6 +140,9 @@ struct SharedContext {
/// Suffix to be added on resource files (if suffix is "-v2" then "light.css" becomes /// Suffix to be added on resource files (if suffix is "-v2" then "light.css" becomes
/// "light-v2.css"). /// "light-v2.css").
pub resource_suffix: String, pub resource_suffix: String,
/// Optional path string to be used to load static files on output pages. If not set, uses
/// combinations of `../` to reach the documentation root.
pub static_root_path: Option<String>,
} }
impl SharedContext { impl SharedContext {
@ -506,6 +509,7 @@ pub fn run(mut krate: clean::Crate,
extension_css, extension_css,
extern_html_root_urls, extern_html_root_urls,
resource_suffix, resource_suffix,
static_root_path,
.. ..
} = options; } = options;
@ -533,6 +537,7 @@ pub fn run(mut krate: clean::Crate,
sort_modules_alphabetically, sort_modules_alphabetically,
themes, themes,
resource_suffix, resource_suffix,
static_root_path,
}; };
// If user passed in `--playground-url` arg, we fill in crate name here // If user passed in `--playground-url` arg, we fill in crate name here
@ -1080,6 +1085,7 @@ themePicker.onblur = handleThemeButtonsBlur;
title: "Index of crates", title: "Index of crates",
css_class: "mod", css_class: "mod",
root_path: "./", root_path: "./",
static_root_path: cx.shared.static_root_path.deref(),
description: "List of crates", description: "List of crates",
keywords: BASIC_KEYWORDS, keywords: BASIC_KEYWORDS,
resource_suffix: &cx.shared.resource_suffix, resource_suffix: &cx.shared.resource_suffix,
@ -1366,6 +1372,7 @@ impl<'a> SourceCollector<'a> {
title: &title, title: &title,
css_class: "source", css_class: "source",
root_path: &root_path, root_path: &root_path,
static_root_path: self.scx.static_root_path.deref(),
description: &desc, description: &desc,
keywords: BASIC_KEYWORDS, keywords: BASIC_KEYWORDS,
resource_suffix: &self.scx.resource_suffix, resource_suffix: &self.scx.resource_suffix,
@ -1956,6 +1963,7 @@ impl Context {
title: "List of all items in this crate", title: "List of all items in this crate",
css_class: "mod", css_class: "mod",
root_path: "../", root_path: "../",
static_root_path: self.shared.static_root_path.deref(),
description: "List of all items in this crate", description: "List of all items in this crate",
keywords: BASIC_KEYWORDS, keywords: BASIC_KEYWORDS,
resource_suffix: &self.shared.resource_suffix, resource_suffix: &self.shared.resource_suffix,
@ -2035,6 +2043,7 @@ impl Context {
let page = layout::Page { let page = layout::Page {
css_class: tyname, css_class: tyname,
root_path: &self.root_path(), root_path: &self.root_path(),
static_root_path: self.shared.static_root_path.deref(),
title: &title, title: &title,
description: &desc, description: &desc,
keywords: &keywords, keywords: &keywords,

View file

@ -25,6 +25,7 @@
#![feature(crate_visibility_modifier)] #![feature(crate_visibility_modifier)]
#![feature(const_fn)] #![feature(const_fn)]
#![feature(drain_filter)] #![feature(drain_filter)]
#![feature(inner_deref)]
#![recursion_limit="256"] #![recursion_limit="256"]
@ -338,6 +339,13 @@ fn opts() -> Vec<RustcOptGroup> {
"enable-index-page", "enable-index-page",
"To enable generation of the index page") "To enable generation of the index page")
}), }),
unstable("static-root-path", |o| {
o.optopt("",
"static-root-path",
"Path string to force loading static files from in output pages. \
If not set, uses combinations of '../' to reach the documentation root.",
"PATH")
}),
] ]
} }

View file

@ -0,0 +1,18 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-flags:-Z unstable-options --static-root-path /cache/
// @has static_root_path/struct.SomeStruct.html
// @matches - '"/cache/main\.js"'
// @!matches - '"\.\./main\.js"'
// @matches - '"\.\./search-index\.js"'
// @!matches - '"/cache/search-index\.js"'
pub struct SomeStruct;