From 003b2bc1c65251ec2fc80b78ed91c43fb35402ec Mon Sep 17 00:00:00 2001 From: Guillaume Gomez <guillaume1.gomez@gmail.com> Date: Sat, 20 Jan 2018 21:12:00 +0100 Subject: [PATCH 1/6] Add possibility to have multiple themes --- src/librustdoc/html/layout.rs | 8 +- src/librustdoc/html/render.rs | 82 +++- src/librustdoc/html/static/main.js | 12 +- src/librustdoc/html/static/rustdoc.css | 38 +- src/librustdoc/html/static/themes/dark.css | 382 ++++++++++++++++++ .../html/static/{styles => themes}/main.css | 23 ++ 6 files changed, 537 insertions(+), 8 deletions(-) create mode 100644 src/librustdoc/html/static/themes/dark.css rename src/librustdoc/html/static/{styles => themes}/main.css (96%) diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 3a18c6b8a809e..105b5b103a565 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -47,8 +47,8 @@ r##"<!DOCTYPE html> <title>{title}</title> <link rel="stylesheet" type="text/css" href="{root_path}normalize.css"> - <link rel="stylesheet" type="text/css" href="{root_path}rustdoc.css"> - <link rel="stylesheet" type="text/css" href="{root_path}main.css"> + <link rel="stylesheet" type="text/css" href="{root_path}rustdoc.css" id="mainThemeStyle"> + <link rel="stylesheet" type="text/css" href="{root_path}main.css" id="themeStyle"> {css_extension} {favicon} @@ -70,6 +70,10 @@ r##"<!DOCTYPE html> {sidebar} </nav> + <div id="theme-picker">🖌 + <div id="theme-choices"></div> + </div> + <script src="{root_path}theme.js"></script> <nav class="sub"> <form class="search-form js-only"> <div class="search-container"> diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index cfa09ea30a8be..007d663cf949c 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -219,6 +219,17 @@ impl Error { } } +macro_rules! try_none { + ($e:expr, $file:expr) => ({ + use std::io; + match $e { + Some(e) => e, + None => return Err(Error::new(io::Error::new(io::ErrorKind::Other, "not found"), + $file)) + } + }) +} + macro_rules! try_err { ($e:expr, $file:expr) => ({ match $e { @@ -859,12 +870,75 @@ fn write_shared(cx: &Context, // Add all the static files. These may already exist, but we just // overwrite them anyway to make sure that they're fresh and up-to-date. - write(cx.dst.join("main.js"), - include_bytes!("static/main.js"))?; write(cx.dst.join("rustdoc.css"), include_bytes!("static/rustdoc.css"))?; - write(cx.dst.join("main.css"), - include_bytes!("static/styles/main.css"))?; + let path = cx.shared.src_root.join("../librustdoc/html/static/themes"); + let mut themes: Vec<String> = Vec::new(); + for entry in try_err!(fs::read_dir(path.clone()), &path) { + let entry = try_err!(entry, &path); + let mut content = Vec::with_capacity(100000); + + let mut f = try_err!(File::open(entry.path()), &entry.path()); + try_err!(f.read_to_end(&mut content), &entry.path()); + write(cx.dst.join(entry.file_name()), content.as_slice())?; + themes.push(try_none!( + try_none!(entry.path().file_stem(), &entry.path()).to_str(), + &entry.path()).to_owned()); + } + themes.sort(); + // To avoid theme switch latencies as much as possible, we put everything theme related + // at the beginning of the html files into another js file. + write(cx.dst.join("theme.js"), format!( +r#"var themes = document.getElementById("theme-choices"); +var themePicker = document.getElementById("theme-picker"); +themePicker.onclick = function() {{ + if (themes.style.display === "block") {{ + themes.style.display = "none"; + themePicker.style.borderBottomRightRadius = "3px"; + themePicker.style.borderBottomLeftRadius = "3px"; + }} else {{ + themes.style.display = "block"; + themePicker.style.borderBottomRightRadius = "0"; + themePicker.style.borderBottomLeftRadius = "0"; + }} +}}; +var currentTheme = document.getElementById("themeStyle"); +var mainTheme = document.getElementById("mainThemeStyle"); +[{}].forEach(function(item) {{ + var div = document.createElement('div'); + div.innerHTML = item; + div.onclick = function(el) {{ + switchTheme(currentTheme, mainTheme, item); + }}; + themes.appendChild(div); +}}); + +function updateLocalStorage(theme) {{ + if (typeof(Storage) !== "undefined") {{ + localStorage.theme = theme; + }} else {{ + // No Web Storage support so we do nothing + }} +}} +function switchTheme(styleElem, mainStyleElem, newTheme) {{ + styleElem.href = mainStyleElem.href.replace("rustdoc.css", newTheme + ".css"); + updateLocalStorage(newTheme); +}} +function getCurrentTheme() {{ + if (typeof(Storage) !== "undefined" && localStorage.theme !== undefined) {{ + return localStorage.theme; + }} + return "main"; +}} + +switchTheme(currentTheme, mainTheme, getCurrentTheme()); +"#, themes.iter() + .map(|s| format!("\"{}\"", s)) + .collect::<Vec<String>>() + .join(",")).as_bytes())?; + + write(cx.dst.join("main.js"), include_bytes!("static/main.js"))?; + if let Some(ref css) = cx.shared.css_file_extension { let out = cx.dst.join("theme.css"); try_err!(fs::copy(css, out), css); diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index a9a5bd5de0552..659bed18b0031 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -122,6 +122,10 @@ } } document.getElementsByTagName("body")[0].style.marginTop = '45px'; + var themePicker = document.getElementById("theme-picker"); + if (themePicker) { + themePicker.style.position = "fixed"; + } } function hideSidebar() { @@ -136,6 +140,10 @@ filler.remove(); } document.getElementsByTagName("body")[0].style.marginTop = ''; + var themePicker = document.getElementById("theme-picker"); + if (themePicker) { + themePicker.style.position = "absolute"; + } } // used for special search precedence @@ -1532,7 +1540,9 @@ ul.appendChild(li); } div.appendChild(ul); - sidebar.appendChild(div); + if (sidebar) { + sidebar.appendChild(div); + } } block("primitive", "Primitive Types"); diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 34b04de86735e..c1ca86e3292a4 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -360,7 +360,8 @@ ul.item-list > li > .out-of-band { } h4 > code, h3 > code, .invisible > code { - position: inherit; + max-width: calc(100% - 41px); + display: block; } .in-band, code { @@ -376,6 +377,7 @@ h4 > code, h3 > code, .invisible > code { margin: 0px; padding: 0px; display: inline-block; + max-width: calc(100% - 43px); } .in-band > code { @@ -1140,3 +1142,37 @@ kbd { border-radius: 3px; box-shadow: inset 0 -1px 0; } + +#theme-picker { + position: absolute; + left: 211px; + top: 17px; + padding: 4px; + border: 1px solid; + border-radius: 3px; + cursor: pointer; +} + +#theme-choices { + display: none; + position: absolute; + left: -1px; + top: 30px; + border: 1px solid; + border-radius: 3px; + z-index: 1; +} + +#theme-choices > div { + border-top: 1px solid; + padding: 4px; + text-align: center; +} + +@media (max-width: 700px) { + #theme-picker { + left: 109px; + top: 7px; + z-index: 1; + } +} diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css new file mode 100644 index 0000000000000..a8245d808c900 --- /dev/null +++ b/src/librustdoc/html/static/themes/dark.css @@ -0,0 +1,382 @@ +/** + * Copyright 2015 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. + */ + +body { + background-color: #353535; + color: #ddd; +} + +h1, h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) { + color: #ddd; +} +h1.fqn { + border-bottom-color: #d2d2d2; +} +h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) { + border-bottom-color: #d2d2d2; +} + +.in-band { + background-color: #353535; +} + +.invisible { + background: rgba(0, 0, 0, 0); +} + +.docblock code, .docblock-short code { + background-color: #2A2A2A; +} +pre { + background-color: #2A2A2A; +} + +.sidebar { + background-color: #505050; +} + +.sidebar .current { + background-color: #333; +} + +.source .sidebar { + background-color: #353535; +} + +.sidebar .location { + border-color: #fff; + background: #575757; + color: #DDD; +} + +.sidebar .version { + border-bottom-color: #DDD; +} + +.sidebar-title { + border-top-color: #777; + border-bottom-color: #777; +} + +.block a:hover { + background: #444; +} + +.line-numbers span { color: #3B91E2; } +.line-numbers .line-highlighted { + background-color: #0a042f !important; +} + +.docblock h1, .docblock h2, .docblock h3, .docblock h4, .docblock h5 { + border-bottom-color: #DDD; +} + +.docblock table { + border-color: #ddd; +} + +.docblock table td { + border-top-color: #ddd; + border-bottom-color: #ddd; +} + +.docblock table th { + border-top-color: #ddd; + border-bottom-color: #ddd; +} + +:target { background: #494a3d; } + +:target > .in-band { + background: #494a3d; +} + +.content .method .where, +.content .fn .where, +.content .where.fmt-newline { + color: #ddd; +} + +.content .highlighted { + color: #eee !important; + background-color: #333; +} +.content .highlighted a, .content .highlighted span { color: #eee !important; } +.content .highlighted.trait { background-color: #013191; } +.content .highlighted.mod { background-color: #803a1b; } +.content .highlighted.externcrate { background-color: #afc6e4; } +.content .highlighted.enum { background-color: #5b4e68; } +.content .highlighted.struct { background-color: #194e9f; } +.content .highlighted.fn, +.content .highlighted.method, +.content .highlighted.tymethod { background-color: #4950ed; } +.content .highlighted.type { background-color: #38902c; } +.content .highlighted.foreigntype { background-color: #f5c4ff; } +.content .highlighted.macro { background-color: #8ce488; } +.content .highlighted.constant, +.content .highlighted.static { background-color: #c3e0ff; } +.content .highlighted.primitive { background-color: #9aecff; } + +.content span.enum, .content a.enum, .block a.current.enum { color: #508157; } +.content span.struct, .content a.struct, .block a.current.struct { color: #df3600; } +.content span.type, .content a.type, .block a.current.type { color: #ba5d00; } +.content span.foreigntype, .content a.foreigntype, .block a.current.foreigntype { color: #cd00e2; } +.content span.macro, .content a.macro, .block a.current.macro { color: #068000; } +.content span.union, .content a.union, .block a.current.union { color: #767b27; } +.content span.constant, .content a.constant, .block a.current.constant, +.content span.static, .content a.static, .block a.current.static { color: #546e8a; } +.content span.primitive, .content a.primitive, .block a.current.primitive { color: #2c8093; } +.content span.externcrate, +.content span.mod, .content a.mod, .block a.current.mod { color: #967F00; } +.content span.trait, .content a.trait, .block a.current.trait { color: #7c5af3; } +.content span.fn, .content a.fn, .block a.current.fn, +.content span.method, .content a.method, .block a.current.method, +.content span.tymethod, .content a.tymethod, .block a.current.tymethod, +.content .fnname{ color: #2BAB63; } + +pre.rust .comment { color: #4D4D4C; } +pre.rust .doccomment { color: #8E908C; } + +nav { + border-bottom-color: #4e4e4e; +} +nav.main .current { + border-top-color: #eee; + border-bottom-color: #eee; +} +nav.main .separator { + border-color: #eee; +} +a { + color: #ddd; +} + +.docblock a, .docblock-short a, .stability a { + color: #D2991D; +} + +a.test-arrow { + color: #dedede; +} + +.collapse-toggle { + color: #999; +} + +.search-input { + color: #111; + box-shadow: 0 0 0 1px #000, 0 0 0 2px transparent; + background-color: #f0f0f0; +} + +.search-input:focus { + border-color: #008dfd; +} + +.stab.unstable { background: #FFF5D6; border-color: #FFC600; color: #404040; } +.stab.deprecated { background: #F3DFFF; border-color: #7F0087; color: #404040; } +.stab.portability { background: #C4ECFF; border-color: #7BA5DB; color: #404040; } + +.module-item .stab { + color: #ddd; +} + +#help > div { + background: #e9e9e9; + border-color: #bfbfbf; +} + +#help dt { + border-color: #bfbfbf; + background: #fff; +} + +.since { + color: grey; +} + +tr.result span.primitive::after { + color: black; +} + +.line-numbers :target { background-color: transparent; } + +/* Code highlighting */ +pre.rust .kw { color: #8959A8; } +pre.rust .kw-2, pre.rust .prelude-ty { color: #4271AE; } +pre.rust .number, pre.rust .string { color: #718C00; } +pre.rust .self, pre.rust .bool-val, pre.rust .prelude-val, +pre.rust .attribute, pre.rust .attribute .ident { color: #C82829; } +pre.rust .macro, pre.rust .macro-nonterminal { color: #3E999F; } +pre.rust .lifetime { color: #B76514; } +pre.rust .question-mark { + color: #ff9011; +} + +a.test-arrow { + background-color: rgba(78, 139, 202, 0.2); +} + +a.test-arrow:hover{ + background-color: #4e8bca; +} + +.toggle-label { + color: #999; +} + +:target > code { + background: #FDFFD3; +} + +pre.compile_fail { + border-left: 2px solid rgba(255,0,0,.6); +} + +pre.compile_fail:hover, .information:hover + pre.compile_fail { + border-left: 2px solid #f00; +} + +pre.ignore { + border-left: 2px solid rgba(255,142,0,.6); +} + +pre.ignore:hover, .information:hover + pre.ignore { + border-left: 2px solid #ff9200; +} + +.tooltip.compile_fail { + color: rgba(255,0,0,.6); +} + +.information > .compile_fail:hover { + color: #f00; +} + +.tooltip.ignore { + color: rgba(255,142,0,.6); +} + +.information > .ignore:hover { + color: rgba(255,142,0,1); +} + +.search-failed > a { + color: #0089ff; +} + +.tooltip .tooltiptext { + background-color: black; + color: #fff; +} + +.tooltip .tooltiptext::after { + border-color: transparent black transparent transparent; +} + +.important-traits .tooltip .tooltiptext { + background-color: white; + color: black; + border-color: black; +} + +#titles > div { + border-bottom-color: #ccc; +} + +#titles > div.selected { + border-bottom-color: #0078ee; +} + +#titles > div:hover { + border-bottom-color: #0089ff; +} + +#titles > div > div.count { + color: #888; +} + +.modal { + background-color: rgba(0,0,0,0.3); +} + +.modal-content { + background-color: #272727; + border-color: #999; +} + +.modal-content > .close { + background-color: #272727; + border-color: #999; +} + +.modal-content > .close:hover { + background-color: #ff1f1f; + color: white; +} + +.modal-content > .whiter { + background-color: #272727; +} + +.modal-content > .close:hover + .whiter { + background-color: #ff1f1f; +} + +@media (max-width: 700px) { + .sidebar-menu { + background-color: #505050; + border-bottom-color: #e0e0e0; + border-right-color: #e0e0e0; + } + + .sidebar-elems { + background-color: #505050; + border-right-color: #000; + } + + #sidebar-filler { + background-color: #505050; + border-bottom-color: #e0e0e0; + } +} + +kbd { + color: #444d56; + background-color: #fafbfc; + border-color: #d1d5da; + border-bottom-color: #c6cbd1; + box-shadow-color: #c6cbd1; +} + +#theme-picker { + border-color: #e0e0e0; +} + +#theme-choices { + border-color: #e0e0e0; + background-color: #353535; +} + +#theme-choices > div { + border-top: #e0e0e0; +} + +#theme-choices > div:hover { + background-color: #444; +} + +@media (max-width: 700px) { + #theme-picker { + background: #353535; + } +} \ No newline at end of file diff --git a/src/librustdoc/html/static/styles/main.css b/src/librustdoc/html/static/themes/main.css similarity index 96% rename from src/librustdoc/html/static/styles/main.css rename to src/librustdoc/html/static/themes/main.css index bd74056242442..84b21e7239fc1 100644 --- a/src/librustdoc/html/static/styles/main.css +++ b/src/librustdoc/html/static/themes/main.css @@ -351,3 +351,26 @@ kbd { border-bottom-color: #c6cbd1; box-shadow-color: #c6cbd1; } + +#theme-picker { + border-color: #e0e0e0; +} + +#theme-choices { + border-color: #ccc; + background-color: #fff; +} + +#theme-choices > div { + border-top: #e0e0e0; +} + +#theme-choices > div:hover { + background-color: #eee; +} + +@media (max-width: 700px) { + #theme-picker { + background: #fff; + } +} From 9aee164a8eb39aa17fef8e1d433c8474febe61f7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez <guillaume1.gomez@gmail.com> Date: Sat, 20 Jan 2018 22:16:46 +0100 Subject: [PATCH 2/6] Add themes option --- src/librustdoc/externalfiles.rs | 2 +- src/librustdoc/html/render.rs | 35 ++++++++++++++++++++++----------- src/librustdoc/lib.rs | 17 +++++++++++++++- 3 files changed, 41 insertions(+), 13 deletions(-) diff --git a/src/librustdoc/externalfiles.rs b/src/librustdoc/externalfiles.rs index f8320330ad265..420e0b2e80706 100644 --- a/src/librustdoc/externalfiles.rs +++ b/src/librustdoc/externalfiles.rs @@ -14,7 +14,7 @@ use std::str; use html::markdown::{Markdown, RenderType}; #[derive(Clone)] -pub struct ExternalHtml{ +pub struct ExternalHtml { /// Content that will be included inline in the <head> section of a /// rendered Markdown file or generated documentation pub in_header: String, diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 007d663cf949c..95db6a8679e5d 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -132,6 +132,8 @@ pub struct SharedContext { /// 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). pub sort_modules_alphabetically: bool, + /// Additional themes to be added to the generated docs. + pub themes: Vec<PathBuf>, } impl SharedContext { @@ -500,7 +502,8 @@ pub fn run(mut krate: clean::Crate, renderinfo: RenderInfo, render_type: RenderType, sort_modules_alphabetically: bool, - deny_render_differences: bool) -> Result<(), Error> { + deny_render_differences: bool, + themes: Vec<PathBuf>) -> Result<(), Error> { let src_root = match krate.src { FileName::Real(ref p) => match p.parent() { Some(p) => p.to_path_buf(), @@ -524,6 +527,7 @@ pub fn run(mut krate: clean::Crate, markdown_warnings: RefCell::new(vec![]), created_dirs: RefCell::new(FxHashSet()), sort_modules_alphabetically, + themes, }; // If user passed in `--playground-url` arg, we fill in crate name here @@ -872,19 +876,28 @@ fn write_shared(cx: &Context, write(cx.dst.join("rustdoc.css"), include_bytes!("static/rustdoc.css"))?; - let path = cx.shared.src_root.join("../librustdoc/html/static/themes"); - let mut themes: Vec<String> = Vec::new(); - for entry in try_err!(fs::read_dir(path.clone()), &path) { - let entry = try_err!(entry, &path); + + // To avoid "main.css" to be overwritten, we'll first run over the received themes and only + // then we'll run over the "official" styles. + let mut themes: HashSet<String> = HashSet::new(); + + for entry in &cx.shared.themes { let mut content = Vec::with_capacity(100000); - let mut f = try_err!(File::open(entry.path()), &entry.path()); - try_err!(f.read_to_end(&mut content), &entry.path()); - write(cx.dst.join(entry.file_name()), content.as_slice())?; - themes.push(try_none!( - try_none!(entry.path().file_stem(), &entry.path()).to_str(), - &entry.path()).to_owned()); + let mut f = try_err!(File::open(&entry), &entry); + try_err!(f.read_to_end(&mut content), &entry); + write(cx.dst.join(try_none!(entry.file_name(), &entry)), content.as_slice())?; + themes.insert(try_none!(try_none!(entry.file_stem(), &entry).to_str(), &entry).to_owned()); } + + write(cx.dst.join("main.css"), + include_bytes!("static/themes/main.css"))?; + themes.insert("main".to_owned()); + write(cx.dst.join("dark.css"), + include_bytes!("static/themes/dark.css"))?; + themes.insert("dark".to_owned()); + + let mut themes: Vec<&String> = themes.iter().collect(); themes.sort(); // To avoid theme switch latencies as much as possible, we put everything theme related // at the beginning of the html files into another js file. diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 2e2dba7681cc3..bf624c31d3d95 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -264,6 +264,11 @@ pub fn opts() -> Vec<RustcOptGroup> { o.optflag("", "deny-render-differences", "abort doc runs when markdown rendering \ differences are found") }), + unstable("themes", |o| { + o.optmulti("", "themes", + "additional themes which will be added to the generated docs", + "FILES") + }), ] } @@ -365,6 +370,15 @@ pub fn main_args(args: &[String]) -> isize { } } + let mut themes = Vec::new(); + for theme in matches.opt_strs("themes").iter().map(|s| PathBuf::from(&s)) { + if !theme.is_file() { + eprintln!("rustdoc: option --themes arguments must all be files"); + return 1; + } + themes.push(theme); + } + let external_html = match ExternalHtml::load( &matches.opt_strs("html-in-header"), &matches.opt_strs("html-before-content"), @@ -413,7 +427,8 @@ pub fn main_args(args: &[String]) -> isize { renderinfo, render_type, sort_modules_alphabetically, - deny_render_differences) + deny_render_differences, + themes) .expect("failed to generate documentation"); 0 } From aae6dc4f20bd8f542653cbfdd32bb2664b9a91fe Mon Sep 17 00:00:00 2001 From: QuietMisdreavus <grey@quietmisdreavus.net> Date: Mon, 22 Jan 2018 14:27:58 -0600 Subject: [PATCH 3/6] tweak colors on dark theme --- src/librustdoc/html/static/themes/dark.css | 53 +++++++++++----------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index a8245d808c900..43d00486ca228 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -113,38 +113,38 @@ pre { .content .highlighted a, .content .highlighted span { color: #eee !important; } .content .highlighted.trait { background-color: #013191; } .content .highlighted.mod { background-color: #803a1b; } -.content .highlighted.externcrate { background-color: #afc6e4; } +.content .highlighted.externcrate { background-color: #396bac; } .content .highlighted.enum { background-color: #5b4e68; } .content .highlighted.struct { background-color: #194e9f; } .content .highlighted.fn, .content .highlighted.method, .content .highlighted.tymethod { background-color: #4950ed; } .content .highlighted.type { background-color: #38902c; } -.content .highlighted.foreigntype { background-color: #f5c4ff; } -.content .highlighted.macro { background-color: #8ce488; } +.content .highlighted.foreigntype { background-color: #b200d6; } +.content .highlighted.macro { background-color: #217d1c; } .content .highlighted.constant, -.content .highlighted.static { background-color: #c3e0ff; } -.content .highlighted.primitive { background-color: #9aecff; } - -.content span.enum, .content a.enum, .block a.current.enum { color: #508157; } -.content span.struct, .content a.struct, .block a.current.struct { color: #df3600; } -.content span.type, .content a.type, .block a.current.type { color: #ba5d00; } -.content span.foreigntype, .content a.foreigntype, .block a.current.foreigntype { color: #cd00e2; } -.content span.macro, .content a.macro, .block a.current.macro { color: #068000; } -.content span.union, .content a.union, .block a.current.union { color: #767b27; } +.content .highlighted.static { background-color: #0063cc; } +.content .highlighted.primitive { background-color: #00708a; } + +.content span.enum, .content a.enum, .block a.current.enum { color: #82b089; } +.content span.struct, .content a.struct, .block a.current.struct { color: #ff794d; } +.content span.type, .content a.type, .block a.current.type { color: #ff7f00; } +.content span.foreigntype, .content a.foreigntype, .block a.current.foreigntype { color: #dd7de8; } +.content span.macro, .content a.macro, .block a.current.macro { color: #09bd00; } +.content span.union, .content a.union, .block a.current.union { color: #a6ae37; } .content span.constant, .content a.constant, .block a.current.constant, -.content span.static, .content a.static, .block a.current.static { color: #546e8a; } -.content span.primitive, .content a.primitive, .block a.current.primitive { color: #2c8093; } +.content span.static, .content a.static, .block a.current.static { color: #82a5c9; } +.content span.primitive, .content a.primitive, .block a.current.primitive { color: #43aec7; } .content span.externcrate, -.content span.mod, .content a.mod, .block a.current.mod { color: #967F00; } -.content span.trait, .content a.trait, .block a.current.trait { color: #7c5af3; } +.content span.mod, .content a.mod, .block a.current.mod { color: #bda000; } +.content span.trait, .content a.trait, .block a.current.trait { color: #b78cf2; } .content span.fn, .content a.fn, .block a.current.fn, .content span.method, .content a.method, .block a.current.method, .content span.tymethod, .content a.tymethod, .block a.current.tymethod, .content .fnname{ color: #2BAB63; } -pre.rust .comment { color: #4D4D4C; } -pre.rust .doccomment { color: #8E908C; } +pre.rust .comment { color: #8d8d8b; } +pre.rust .doccomment { color: #8ca375; } nav { border-bottom-color: #4e4e4e; @@ -191,13 +191,14 @@ a.test-arrow { } #help > div { - background: #e9e9e9; + background: #4d4d4d; border-color: #bfbfbf; } #help dt { border-color: #bfbfbf; background: #fff; + color: black; } .since { @@ -205,19 +206,19 @@ a.test-arrow { } tr.result span.primitive::after { - color: black; + color: #ddd; } .line-numbers :target { background-color: transparent; } /* Code highlighting */ -pre.rust .kw { color: #8959A8; } -pre.rust .kw-2, pre.rust .prelude-ty { color: #4271AE; } -pre.rust .number, pre.rust .string { color: #718C00; } +pre.rust .kw { color: #ab8ac1; } +pre.rust .kw-2, pre.rust .prelude-ty { color: #769acb; } +pre.rust .number, pre.rust .string { color: #83a300; } pre.rust .self, pre.rust .bool-val, pre.rust .prelude-val, -pre.rust .attribute, pre.rust .attribute .ident { color: #C82829; } +pre.rust .attribute, pre.rust .attribute .ident { color: #ee6868; } pre.rust .macro, pre.rust .macro-nonterminal { color: #3E999F; } -pre.rust .lifetime { color: #B76514; } +pre.rust .lifetime { color: #d97f26; } pre.rust .question-mark { color: #ff9011; } @@ -379,4 +380,4 @@ kbd { #theme-picker { background: #353535; } -} \ No newline at end of file +} From 3c52acd9ca3c231b2cab881a9653135dca17e8aa Mon Sep 17 00:00:00 2001 From: Guillaume Gomez <guillaume1.gomez@gmail.com> Date: Mon, 22 Jan 2018 21:38:56 +0100 Subject: [PATCH 4/6] Change theme icon --- src/librustdoc/html/layout.rs | 3 ++- src/librustdoc/html/render.rs | 2 ++ src/librustdoc/html/static/brush.svg | 1 + src/librustdoc/html/static/themes/dark.css | 1 + 4 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 src/librustdoc/html/static/brush.svg diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 105b5b103a565..753abf4eacf4f 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -70,7 +70,8 @@ r##"<!DOCTYPE html> {sidebar} </nav> - <div id="theme-picker">🖌 + <div id="theme-picker"> + <img src="{root_path}brush.svg" width="18" alt="Pick another theme!"> <div id="theme-choices"></div> </div> <script src="{root_path}theme.js"></script> diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 95db6a8679e5d..ad785fb830a56 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -890,6 +890,8 @@ fn write_shared(cx: &Context, themes.insert(try_none!(try_none!(entry.file_stem(), &entry).to_str(), &entry).to_owned()); } + write(cx.dst.join("brush.svg"), + include_bytes!("static/brush.svg"))?; write(cx.dst.join("main.css"), include_bytes!("static/themes/main.css"))?; themes.insert("main".to_owned()); diff --git a/src/librustdoc/html/static/brush.svg b/src/librustdoc/html/static/brush.svg new file mode 100644 index 0000000000000..072264a640830 --- /dev/null +++ b/src/librustdoc/html/static/brush.svg @@ -0,0 +1 @@ +<?xml version="1.0" ?><svg height="1792" viewBox="0 0 1792 1792" width="1792" xmlns="http://www.w3.org/2000/svg"><path d="M1615 0q70 0 122.5 46.5t52.5 116.5q0 63-45 151-332 629-465 752-97 91-218 91-126 0-216.5-92.5t-90.5-219.5q0-128 92-212l638-579q59-54 130-54zm-909 1034q39 76 106.5 130t150.5 76l1 71q4 213-129.5 347t-348.5 134q-123 0-218-46.5t-152.5-127.5-86.5-183-29-220q7 5 41 30t62 44.5 59 36.5 46 17q41 0 55-37 25-66 57.5-112.5t69.5-76 88-47.5 103-25.5 125-10.5z"/></svg> \ No newline at end of file diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index 43d00486ca228..05ac066039656 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -361,6 +361,7 @@ kbd { #theme-picker { border-color: #e0e0e0; + background: #f0f0f0; } #theme-choices { From 5f93159e9ddc05f479ade72e604a0267b5413be7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez <guillaume1.gomez@gmail.com> Date: Mon, 22 Jan 2018 23:44:08 +0100 Subject: [PATCH 5/6] Fasten up theme loading --- src/librustdoc/html/layout.rs | 7 +++-- src/librustdoc/html/render.rs | 23 +------------- src/librustdoc/html/static/storage.js | 44 +++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 25 deletions(-) create mode 100644 src/librustdoc/html/static/storage.js diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 753abf4eacf4f..7b4781870de66 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -48,7 +48,8 @@ r##"<!DOCTYPE html> <link rel="stylesheet" type="text/css" href="{root_path}normalize.css"> <link rel="stylesheet" type="text/css" href="{root_path}rustdoc.css" id="mainThemeStyle"> - <link rel="stylesheet" type="text/css" href="{root_path}main.css" id="themeStyle"> + <link rel="stylesheet" type="text/css" href="" id="themeStyle"> + <script src="{root_path}storage.js"></script> {css_extension} {favicon} @@ -70,10 +71,10 @@ r##"<!DOCTYPE html> {sidebar} </nav> - <div id="theme-picker"> + <button id="theme-picker"> <img src="{root_path}brush.svg" width="18" alt="Pick another theme!"> <div id="theme-choices"></div> - </div> + </button> <script src="{root_path}theme.js"></script> <nav class="sub"> <form class="search-form js-only"> diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index ad785fb830a56..9993823c5804a 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -917,8 +917,6 @@ themePicker.onclick = function() {{ themePicker.style.borderBottomLeftRadius = "0"; }} }}; -var currentTheme = document.getElementById("themeStyle"); -var mainTheme = document.getElementById("mainThemeStyle"); [{}].forEach(function(item) {{ var div = document.createElement('div'); div.innerHTML = item; @@ -927,32 +925,13 @@ var mainTheme = document.getElementById("mainThemeStyle"); }}; themes.appendChild(div); }}); - -function updateLocalStorage(theme) {{ - if (typeof(Storage) !== "undefined") {{ - localStorage.theme = theme; - }} else {{ - // No Web Storage support so we do nothing - }} -}} -function switchTheme(styleElem, mainStyleElem, newTheme) {{ - styleElem.href = mainStyleElem.href.replace("rustdoc.css", newTheme + ".css"); - updateLocalStorage(newTheme); -}} -function getCurrentTheme() {{ - if (typeof(Storage) !== "undefined" && localStorage.theme !== undefined) {{ - return localStorage.theme; - }} - return "main"; -}} - -switchTheme(currentTheme, mainTheme, getCurrentTheme()); "#, themes.iter() .map(|s| format!("\"{}\"", s)) .collect::<Vec<String>>() .join(",")).as_bytes())?; write(cx.dst.join("main.js"), include_bytes!("static/main.js"))?; + write(cx.dst.join("storage.js"), include_bytes!("static/storage.js"))?; if let Some(ref css) = cx.shared.css_file_extension { let out = cx.dst.join("theme.css"); diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js new file mode 100644 index 0000000000000..7e384a64c0aa5 --- /dev/null +++ b/src/librustdoc/html/static/storage.js @@ -0,0 +1,44 @@ +/*! + * 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. + */ + +var currentTheme = document.getElementById("themeStyle"); +var mainTheme = document.getElementById("mainThemeStyle"); + +function updateLocalStorage(name, value) { + if (typeof(Storage) !== "undefined") { + localStorage[name] = value; + } else { + // No Web Storage support so we do nothing + } +} + +function getCurrentValue(name) { + if (typeof(Storage) !== "undefined" && localStorage[name] !== undefined) { + return localStorage[name]; + } + return null; +} + +function switchTheme(styleElem, mainStyleElem, newTheme) { + styleElem.href = mainStyleElem.href.replace("rustdoc.css", newTheme + ".css"); + updateLocalStorage('theme', newTheme); + /*var elem = document.getElementsByTagName('body')[0]; + if (elem) { + updateLocalStorage('background', getComputedStyle(elem)['background-color']); + }*/ +} + +/*var elem = document.getElementsByTagName('body')[0]; +if (elem) { + var value = +}*/ +switchTheme(currentTheme, mainTheme, getCurrentValue('theme') || 'main'); From 5b8504401c7590130eb01a34155b12c26881b0b1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez <guillaume1.gomez@gmail.com> Date: Tue, 23 Jan 2018 00:45:34 +0100 Subject: [PATCH 6/6] Fasten even more theme switch --- src/librustdoc/html/layout.rs | 13 +++++++++++-- src/librustdoc/html/render.rs | 6 ++++-- src/librustdoc/html/static/storage.js | 8 -------- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 7b4781870de66..8395b0686e1b0 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -10,6 +10,7 @@ use std::fmt; use std::io; +use std::path::PathBuf; use externalfiles::ExternalHtml; @@ -31,7 +32,7 @@ pub struct Page<'a> { pub fn render<T: fmt::Display, S: fmt::Display>( dst: &mut io::Write, layout: &Layout, page: &Page, sidebar: &S, t: &T, - css_file_extension: bool) + css_file_extension: bool, themes: &[PathBuf]) -> io::Result<()> { write!(dst, @@ -48,7 +49,9 @@ r##"<!DOCTYPE html> <link rel="stylesheet" type="text/css" href="{root_path}normalize.css"> <link rel="stylesheet" type="text/css" href="{root_path}rustdoc.css" id="mainThemeStyle"> - <link rel="stylesheet" type="text/css" href="" id="themeStyle"> + {themes} + <link rel="stylesheet" type="text/css" href="{root_path}dark.css"> + <link rel="stylesheet" type="text/css" href="{root_path}main.css" id="themeStyle"> <script src="{root_path}storage.js"></script> {css_extension} @@ -182,6 +185,12 @@ r##"<!DOCTYPE html> after_content = layout.external_html.after_content, sidebar = *sidebar, krate = layout.krate, + themes = themes.iter() + .filter_map(|t| t.file_stem()) + .filter_map(|t| t.to_str()) + .map(|t| format!(r#"<link rel="stylesheet" type="text/css" href="{}{}">"#, + page.root_path, t)) + .collect::<String>(), ) } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 9993823c5804a..4a56dbac50ec3 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1224,7 +1224,8 @@ impl<'a> SourceCollector<'a> { }; layout::render(&mut w, &self.scx.layout, &page, &(""), &Source(contents), - self.scx.css_file_extension.is_some())?; + self.scx.css_file_extension.is_some(), + &self.scx.themes)?; w.flush()?; self.scx.local_sources.insert(p.clone(), href); Ok(()) @@ -1588,7 +1589,8 @@ impl Context { layout::render(writer, &self.shared.layout, &page, &Sidebar{ cx: self, item: it }, &Item{ cx: self, item: it }, - self.shared.css_file_extension.is_some())?; + self.shared.css_file_extension.is_some(), + &self.shared.themes)?; } else { let mut url = self.root_path(); if let Some(&(ref names, ty)) = cache().paths.get(&it.def_id) { diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js index 7e384a64c0aa5..0aa1065b3786a 100644 --- a/src/librustdoc/html/static/storage.js +++ b/src/librustdoc/html/static/storage.js @@ -31,14 +31,6 @@ function getCurrentValue(name) { function switchTheme(styleElem, mainStyleElem, newTheme) { styleElem.href = mainStyleElem.href.replace("rustdoc.css", newTheme + ".css"); updateLocalStorage('theme', newTheme); - /*var elem = document.getElementsByTagName('body')[0]; - if (elem) { - updateLocalStorage('background', getComputedStyle(elem)['background-color']); - }*/ } -/*var elem = document.getElementsByTagName('body')[0]; -if (elem) { - var value = -}*/ switchTheme(currentTheme, mainTheme, getCurrentValue('theme') || 'main');