1
Fork 0

Clean up handling of style files in rustdoc

Disable all themes other than `light.css` to prevent rule conflicts
This commit is contained in:
Jarek Samic 2020-07-12 14:37:22 -04:00
parent 9d09331e00
commit 0e89f50f6e
4 changed files with 76 additions and 43 deletions

View file

@ -20,6 +20,7 @@ use crate::core::new_handler;
use crate::externalfiles::ExternalHtml; use crate::externalfiles::ExternalHtml;
use crate::html; use crate::html;
use crate::html::markdown::IdMap; use crate::html::markdown::IdMap;
use crate::html::render::StylePath;
use crate::html::static_files; use crate::html::static_files;
use crate::opts; use crate::opts;
use crate::passes::{self, Condition, DefaultPassOption}; use crate::passes::{self, Condition, DefaultPassOption};
@ -207,7 +208,7 @@ pub struct RenderOptions {
pub sort_modules_alphabetically: bool, pub sort_modules_alphabetically: bool,
/// List of themes to extend the docs with. Original argument name is included to assist in /// List of themes to extend the docs with. Original argument name is included to assist in
/// displaying errors if it fails a theme check. /// displaying errors if it fails a theme check.
pub themes: Vec<PathBuf>, pub themes: Vec<StylePath>,
/// If present, CSS file that contains rules to add to the default CSS. /// If present, CSS file that contains rules to add to the default CSS.
pub extension_css: Option<PathBuf>, pub extension_css: Option<PathBuf>,
/// A map of crate names to the URL to use instead of querying the crate's `html_root_url`. /// A map of crate names to the URL to use instead of querying the crate's `html_root_url`.
@ -410,7 +411,7 @@ impl Options {
)) ))
.emit(); .emit();
} }
themes.push(theme_file); themes.push(StylePath { path: theme_file, disabled: true });
} }
} }

View file

@ -3,7 +3,7 @@ use std::path::PathBuf;
use crate::externalfiles::ExternalHtml; use crate::externalfiles::ExternalHtml;
use crate::html::escape::Escape; use crate::html::escape::Escape;
use crate::html::format::{Buffer, Print}; use crate::html::format::{Buffer, Print};
use crate::html::render::ensure_trailing_slash; use crate::html::render::{ensure_trailing_slash, StylePath};
#[derive(Clone)] #[derive(Clone)]
pub struct Layout { pub struct Layout {
@ -36,7 +36,7 @@ pub fn render<T: Print, S: Print>(
page: &Page<'_>, page: &Page<'_>,
sidebar: S, sidebar: S,
t: T, t: T,
themes: &[PathBuf], style_files: &[StylePath],
) -> String { ) -> String {
let static_root_path = page.static_root_path.unwrap_or(page.root_path); let static_root_path = page.static_root_path.unwrap_or(page.root_path);
format!( format!(
@ -52,10 +52,7 @@ pub fn render<T: Print, S: Print>(
<link rel=\"stylesheet\" type=\"text/css\" href=\"{static_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=\"{static_root_path}rustdoc{suffix}.css\" \ <link rel=\"stylesheet\" type=\"text/css\" href=\"{static_root_path}rustdoc{suffix}.css\" \
id=\"mainThemeStyle\">\ id=\"mainThemeStyle\">\
{themes}\ {style_files}\
<link rel=\"stylesheet\" type=\"text/css\" href=\"{static_root_path}dark{suffix}.css\">\
<link rel=\"stylesheet\" type=\"text/css\" href=\"{static_root_path}light{suffix}.css\" \
id=\"themeStyle\">\
<script src=\"{static_root_path}storage{suffix}.js\"></script>\ <script src=\"{static_root_path}storage{suffix}.js\"></script>\
<noscript><link rel=\"stylesheet\" href=\"{static_root_path}noscript{suffix}.css\"></noscript>\ <noscript><link rel=\"stylesheet\" href=\"{static_root_path}noscript{suffix}.css\"></noscript>\
{css_extension}\ {css_extension}\
@ -172,13 +169,19 @@ pub fn render<T: Print, S: Print>(
after_content = layout.external_html.after_content, after_content = layout.external_html.after_content,
sidebar = Buffer::html().to_display(sidebar), sidebar = Buffer::html().to_display(sidebar),
krate = layout.krate, krate = layout.krate,
themes = themes style_files = style_files
.iter() .iter()
.filter_map(|t| t.file_stem()) .filter_map(|t| {
.filter_map(|t| t.to_str()) if let Some(stem) = t.path.file_stem() { Some((stem, t.disabled)) } else { None }
})
.filter_map(|t| {
if let Some(path) = t.0.to_str() { Some((path, t.1)) } else { None }
})
.map(|t| format!( .map(|t| format!(
r#"<link rel="stylesheet" type="text/css" href="{}.css">"#, r#"<link rel="stylesheet" type="text/css" href="{}.css" {} {}>"#,
Escape(&format!("{}{}{}", static_root_path, t, page.resource_suffix)) Escape(&format!("{}{}{}", static_root_path, t.0, page.resource_suffix)),
if t.1 { "disabled" } else { "" },
if t.0 == "light" { "id=\"themeStyle\"" } else { "" }
)) ))
.collect::<String>(), .collect::<String>(),
suffix = page.resource_suffix, suffix = page.resource_suffix,

View file

@ -187,8 +187,8 @@ crate struct SharedContext {
/// This flag indicates whether listings of modules (in the side bar and documentation itself) /// This flag indicates whether listings of modules (in the side bar and documentation itself)
/// should be ordered alphabetically or in order of appearance (in the source code). /// should be ordered alphabetically or in order of appearance (in the source code).
pub sort_modules_alphabetically: bool, pub sort_modules_alphabetically: bool,
/// Additional themes to be added to the generated docs. /// Additional CSS files to be added to the generated docs.
pub themes: Vec<PathBuf>, pub style_files: Vec<StylePath>,
/// 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,
@ -417,6 +417,14 @@ impl Serialize for TypeWithKind {
} }
} }
#[derive(Debug, Clone)]
pub struct StylePath {
/// The path to the theme
pub path: PathBuf,
/// What the `disabled` attribute should be set to in the HTML tag
pub disabled: bool,
}
thread_local!(static CACHE_KEY: RefCell<Arc<Cache>> = Default::default()); thread_local!(static CACHE_KEY: RefCell<Arc<Cache>> = Default::default());
thread_local!(pub static CURRENT_DEPTH: Cell<usize> = Cell::new(0)); thread_local!(pub static CURRENT_DEPTH: Cell<usize> = Cell::new(0));
@ -460,7 +468,7 @@ pub fn run(
id_map, id_map,
playground_url, playground_url,
sort_modules_alphabetically, sort_modules_alphabetically,
themes, themes: style_files,
extension_css, extension_css,
extern_html_root_urls, extern_html_root_urls,
resource_suffix, resource_suffix,
@ -530,7 +538,7 @@ pub fn run(
layout, layout,
created_dirs: Default::default(), created_dirs: Default::default(),
sort_modules_alphabetically, sort_modules_alphabetically,
themes, style_files,
resource_suffix, resource_suffix,
static_root_path, static_root_path,
fs: DocFS::new(&errors), fs: DocFS::new(&errors),
@ -539,6 +547,18 @@ pub fn run(
playground, playground,
}; };
// Add the default themes to the `Vec` of stylepaths
//
// Note that these must be added before `sources::render` is called
// so that the resulting source pages are styled
//
// `light.css` is not disabled because it is the stylesheet that stays loaded
// by the browser as the theme stylesheet. The theme system (hackily) works by
// changing the href to this stylesheet. All other themes are disabled to
// prevent rule conflicts
scx.style_files.push(StylePath { path: PathBuf::from("light.css"), disabled: false });
scx.style_files.push(StylePath { path: PathBuf::from("dark.css"), disabled: true });
let dst = output; let dst = output;
scx.ensure_dir(&dst)?; scx.ensure_dir(&dst)?;
krate = sources::render(&dst, &mut scx, krate)?; krate = sources::render(&dst, &mut scx, krate)?;
@ -615,11 +635,34 @@ fn write_shared(
// then we'll run over the "official" styles. // then we'll run over the "official" styles.
let mut themes: FxHashSet<String> = FxHashSet::default(); let mut themes: FxHashSet<String> = FxHashSet::default();
for entry in &cx.shared.themes { for entry in &cx.shared.style_files {
let content = try_err!(fs::read(&entry), &entry); let theme = try_none!(try_none!(entry.path.file_stem(), &entry.path).to_str(), &entry.path);
let theme = try_none!(try_none!(entry.file_stem(), &entry).to_str(), &entry); let extension =
let extension = try_none!(try_none!(entry.extension(), &entry).to_str(), &entry); try_none!(try_none!(entry.path.extension(), &entry.path).to_str(), &entry.path);
cx.shared.fs.write(cx.path(&format!("{}.{}", theme, extension)), content.as_slice())?;
// Handle the official themes
match theme {
"light" => write_minify(
&cx.shared.fs,
cx.path("light.css"),
static_files::themes::LIGHT,
options.enable_minification,
)?,
"dark" => write_minify(
&cx.shared.fs,
cx.path("dark.css"),
static_files::themes::DARK,
options.enable_minification,
)?,
_ => {
// Handle added third-party themes
let content = try_err!(fs::read(&entry.path), &entry.path);
cx.shared
.fs
.write(cx.path(&format!("{}.{}", theme, extension)), content.as_slice())?;
}
};
themes.insert(theme.to_owned()); themes.insert(theme.to_owned());
} }
@ -633,20 +676,6 @@ fn write_shared(
write(cx.path("brush.svg"), static_files::BRUSH_SVG)?; write(cx.path("brush.svg"), static_files::BRUSH_SVG)?;
write(cx.path("wheel.svg"), static_files::WHEEL_SVG)?; write(cx.path("wheel.svg"), static_files::WHEEL_SVG)?;
write(cx.path("down-arrow.svg"), static_files::DOWN_ARROW_SVG)?; write(cx.path("down-arrow.svg"), static_files::DOWN_ARROW_SVG)?;
write_minify(
&cx.shared.fs,
cx.path("light.css"),
static_files::themes::LIGHT,
options.enable_minification,
)?;
themes.insert("light".to_owned());
write_minify(
&cx.shared.fs,
cx.path("dark.css"),
static_files::themes::DARK,
options.enable_minification,
)?;
themes.insert("dark".to_owned());
let mut themes: Vec<&String> = themes.iter().collect(); let mut themes: Vec<&String> = themes.iter().collect();
themes.sort(); themes.sort();
@ -957,7 +986,7 @@ themePicker.onblur = handleThemeButtonsBlur;
}) })
.collect::<String>() .collect::<String>()
); );
let v = layout::render(&cx.shared.layout, &page, "", content, &cx.shared.themes); let v = layout::render(&cx.shared.layout, &page, "", content, &cx.shared.style_files);
cx.shared.fs.write(&dst, v.as_bytes())?; cx.shared.fs.write(&dst, v.as_bytes())?;
} }
} }
@ -1375,7 +1404,7 @@ impl Context {
&page, &page,
sidebar, sidebar,
|buf: &mut Buffer| all.print(buf), |buf: &mut Buffer| all.print(buf),
&self.shared.themes, &self.shared.style_files,
); );
self.shared.fs.write(&final_file, v.as_bytes())?; self.shared.fs.write(&final_file, v.as_bytes())?;
@ -1384,9 +1413,9 @@ impl Context {
page.description = "Settings of Rustdoc"; page.description = "Settings of Rustdoc";
page.root_path = "./"; page.root_path = "./";
let mut themes = self.shared.themes.clone(); let mut style_files = self.shared.style_files.clone();
let sidebar = "<p class='location'>Settings</p><div class='sidebar-elems'></div>"; let sidebar = "<p class='location'>Settings</p><div class='sidebar-elems'></div>";
themes.push(PathBuf::from("settings.css")); style_files.push(StylePath { path: PathBuf::from("settings.css"), disabled: false });
let v = layout::render( let v = layout::render(
&self.shared.layout, &self.shared.layout,
&page, &page,
@ -1395,7 +1424,7 @@ impl Context {
self.shared.static_root_path.as_deref().unwrap_or("./"), self.shared.static_root_path.as_deref().unwrap_or("./"),
&self.shared.resource_suffix, &self.shared.resource_suffix,
), ),
&themes, &style_files,
); );
self.shared.fs.write(&settings_file, v.as_bytes())?; self.shared.fs.write(&settings_file, v.as_bytes())?;
@ -1457,7 +1486,7 @@ impl Context {
&page, &page,
|buf: &mut _| print_sidebar(self, it, buf), |buf: &mut _| print_sidebar(self, it, buf),
|buf: &mut _| print_item(self, it, buf), |buf: &mut _| print_item(self, it, buf),
&self.shared.themes, &self.shared.style_files,
) )
} else { } else {
let mut url = self.root_path(); let mut url = self.root_path();

View file

@ -123,7 +123,7 @@ impl<'a> SourceCollector<'a> {
&page, &page,
"", "",
|buf: &mut _| print_src(buf, &contents), |buf: &mut _| print_src(buf, &contents),
&self.scx.themes, &self.scx.style_files,
); );
self.scx.fs.write(&cur, v.as_bytes())?; self.scx.fs.write(&cur, v.as_bytes())?;
self.scx.local_sources.insert(p, href); self.scx.local_sources.insert(p, href);