From d891849b8d27f7fb1e4f004d98097cf723e74135 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 9 Dec 2021 15:10:15 -0700 Subject: [PATCH 1/2] Inline some SVG icons into rustdoc.css This reduces the number of requests made when loading rustdoc off the web, without any significant bloat (they aren't base64-ed, and they aren't inlined into every single HTML file, either). This is currently three icons, but if we switch to font-awesome, it will probably be more. --- Cargo.lock | 1 + src/librustdoc/Cargo.toml | 1 + src/librustdoc/html/render/write_shared.rs | 55 +++++++++++++++------- src/librustdoc/html/static_files.rs | 4 +- 4 files changed, 41 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 92e13881f8de4..fbf720d453965 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4602,6 +4602,7 @@ dependencies = [ "expect-test", "itertools 0.9.0", "minifier", + "percent-encoding 2.1.0", "pulldown-cmark", "rayon", "regex", diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 268905bcb5339..0f1f437ddd693 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -21,6 +21,7 @@ rustdoc-json-types = { path = "../rustdoc-json-types" } tracing = "0.1" tracing-tree = "0.1.9" tera = { version = "1.10.0", default-features = false } +percent-encoding = "2.1" [dependencies.tracing-subscriber] version = "0.2.13" diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 0d5ba8e80d242..7c0768fa4132d 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -181,18 +181,26 @@ pub(super) fn write_shared( cx.write_shared(SharedResource::InvocationSpecific { basename: p }, content, &options.emit) }; - // Given "foo.svg", return e.g. "url(\"foo1.58.0.svg\")" - fn ver_url(cx: &Context<'_>, basename: &'static str) -> String { - format!( - "url(\"{}\")", - SharedResource::ToolchainSpecific { basename } - .path(cx) - .file_name() - .unwrap() - .to_str() - .unwrap() - ) - } + // Given "foo.svg", either include it directly in the CSS as a data URL, + // or link to it, depending on the options. + let css_icon_url = |basename: &'static str, icon: &[u8]| -> String { + if basename.ends_with(".svg") && options.enable_minification { + use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS}; + const DATA_URI: &AsciiSet = &CONTROLS.add(b'\'').add(b'#').add(b'?'); + let icn = utf8_percent_encode(std::str::from_utf8(icon).unwrap(), DATA_URI); + format!("url('data:image/svg+xml,{}')", icn,) + } else { + format!( + "url(\"{}\")", + SharedResource::ToolchainSpecific { basename } + .path(cx) + .file_name() + .unwrap() + .to_str() + .unwrap() + ) + } + }; // We use the AUTOREPLACE mechanism to inject into our static JS and CSS certain // values that are only known at doc build time. Since this mechanism is somewhat @@ -202,10 +210,16 @@ pub(super) fn write_shared( static_files::RUSTDOC_CSS .replace( "/* AUTOREPLACE: */url(\"toggle-minus.svg\")", - &ver_url(cx, "toggle-minus.svg"), + &css_icon_url("toggle-minus.svg", static_files::TOGGLE_MINUS_SVG), + ) + .replace( + "/* AUTOREPLACE: */url(\"toggle-plus.svg\")", + &css_icon_url("toggle-plus.svg", static_files::TOGGLE_PLUS_SVG), ) - .replace("/* AUTOREPLACE: */url(\"toggle-plus.svg\")", &ver_url(cx, "toggle-plus.svg")) - .replace("/* AUTOREPLACE: */url(\"down-arrow.svg\")", &ver_url(cx, "down-arrow.svg")), + .replace( + "/* AUTOREPLACE: */url(\"down-arrow.svg\")", + &css_icon_url("down-arrow.svg", static_files::DOWN_ARROW_SVG), + ), cx, options, )?; @@ -250,9 +264,14 @@ pub(super) fn write_shared( write_toolchain("brush.svg", static_files::BRUSH_SVG)?; write_toolchain("wheel.svg", static_files::WHEEL_SVG)?; write_toolchain("clipboard.svg", static_files::CLIPBOARD_SVG)?; - write_toolchain("down-arrow.svg", static_files::DOWN_ARROW_SVG)?; - write_toolchain("toggle-minus.svg", static_files::TOGGLE_MINUS_PNG)?; - write_toolchain("toggle-plus.svg", static_files::TOGGLE_PLUS_PNG)?; + + // The following icons are embeded in the CSS file, + // unless we're in tweak-the-theme-mode. + if !options.enable_minification { + write_toolchain("down-arrow.svg", static_files::DOWN_ARROW_SVG)?; + write_toolchain("toggle-minus.svg", static_files::TOGGLE_MINUS_SVG)?; + write_toolchain("toggle-plus.svg", static_files::TOGGLE_PLUS_SVG)?; + } let mut themes: Vec<&String> = themes.iter().collect(); themes.sort(); diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs index 56c5399d074b6..079c5e337ac7f 100644 --- a/src/librustdoc/html/static_files.rs +++ b/src/librustdoc/html/static_files.rs @@ -52,10 +52,10 @@ crate static CLIPBOARD_SVG: &[u8] = include_bytes!("static/images/clipboard.svg" crate static DOWN_ARROW_SVG: &[u8] = include_bytes!("static/images/down-arrow.svg"); /// The file contents of `toggle-minus.svg`, the icon used for opened toggles. -crate static TOGGLE_MINUS_PNG: &[u8] = include_bytes!("static/images/toggle-minus.svg"); +crate static TOGGLE_MINUS_SVG: &[u8] = include_bytes!("static/images/toggle-minus.svg"); /// The file contents of `toggle-plus.svg`, the icon used for closed toggles. -crate static TOGGLE_PLUS_PNG: &[u8] = include_bytes!("static/images/toggle-plus.svg"); +crate static TOGGLE_PLUS_SVG: &[u8] = include_bytes!("static/images/toggle-plus.svg"); /// The contents of `COPYRIGHT.txt`, the license listing for files distributed with documentation /// output. From 04b96ac607a29ca96734fe27d169420d48615606 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 9 Dec 2021 15:31:29 -0700 Subject: [PATCH 2/2] Make down-arrow.svg smaller --- src/librustdoc/html/static/images/down-arrow.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/images/down-arrow.svg b/src/librustdoc/html/static/images/down-arrow.svg index 35437e77a710c..6f0558d51b18f 100644 --- a/src/librustdoc/html/static/images/down-arrow.svg +++ b/src/librustdoc/html/static/images/down-arrow.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file