Skip to content

Extract vendored css from style.css into a separate file vendored.css… #993

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 33 additions & 8 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ fn main() {
);

// Don't rerun anytime a single change is made
println!("cargo:rerun-if-changed=templates/style/vendored.scss");
println!("cargo:rerun-if-changed=templates/style/base.scss");
println!("cargo:rerun-if-changed=templates/style/_rustdoc.scss");
println!("cargo:rerun-if-changed=templates/style/_vars.scss");
Expand Down Expand Up @@ -57,30 +58,54 @@ fn get_git_hash() -> Option<String> {
})
}

fn compile_sass() -> Result<(), Box<dyn Error>> {
fn compile_sass_file(
name: &str,
target: &str,
include_paths: &[String],
) -> Result<(), Box<dyn Error>> {
use sass_rs::{Context, Options, OutputStyle};

const STYLE_DIR: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/templates/style");

let mut context = Context::new_file(format!("{}/base.scss", STYLE_DIR))?;
let include_paths = {
let mut paths = vec![STYLE_DIR.to_owned()];
paths.extend_from_slice(include_paths);
paths
};

// Compile base.scss
let mut context = Context::new_file(format!("{}/{}.scss", STYLE_DIR, name))?;
context.set_options(Options {
output_style: OutputStyle::Compressed,
include_paths: vec![
STYLE_DIR.to_owned(),
concat!(env!("CARGO_MANIFEST_DIR"), "/vendor/fontawesome/scss").to_owned(),
concat!(env!("CARGO_MANIFEST_DIR"), "/vendor/pure-css/css").to_owned(),
],
include_paths,
..Default::default()
});

let css = context.compile()?;
let dest_path = Path::new(&env::var("OUT_DIR")?).join("style.css");
let dest_path = Path::new(&env::var("OUT_DIR")?).join(format!("{}.css", target));
let mut file = File::create(&dest_path)?;
file.write_all(css.as_bytes())?;

Ok(())
}

fn compile_sass() -> Result<(), Box<dyn Error>> {
// Compile base.scss -> style.css
compile_sass_file("base", "style", &[])?;

// Compile vendored.scss -> vendored.css
compile_sass_file(
"vendored",
"vendored",
&[
concat!(env!("CARGO_MANIFEST_DIR"), "/vendor/fontawesome/scss").to_owned(),
concat!(env!("CARGO_MANIFEST_DIR"), "/vendor/pure-css/css").to_owned(),
],
)?;

Ok(())
}

fn copy_js() {
["menu.js", "index.js"].iter().for_each(|path| {
let source_path =
Expand Down
37 changes: 28 additions & 9 deletions src/utils/html.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ pub(crate) fn rewrite_lol(

let templates = templates.templates.load();
let tera_head = templates.render("rustdoc/head.html", &ctx).unwrap();
let tera_vendored_css = templates.render("rustdoc/vendored.html", &ctx).unwrap();
let tera_body = templates.render("rustdoc/body.html", &ctx).unwrap();
let tera_rustdoc_header = templates.render("rustdoc/header.html", &ctx).unwrap();

// Append `style.css` stylesheet after all head elements.
let head_handler = |head: &mut Element| {
head.append(&tera_head, ContentType::Html);

Expand Down Expand Up @@ -62,17 +64,34 @@ pub(crate) fn rewrite_lol(
Ok(())
};

let (head_selector, body_selector) = ("head".parse().unwrap(), "body".parse().unwrap());
let head = (
&head_selector,
ElementContentHandlers::default().element(head_handler),
);
let body = (
&body_selector,
ElementContentHandlers::default().element(body_handler),
// Append `vendored.css` before the first stylesheet (rustdoc's first stylesheet is `normalize.css`).
let first_stylesheet_handler = |head: &mut Element| {
head.before(&tera_vendored_css, ContentType::Html);

Ok(())
};

let (head_selector, body_selector, first_stylesheet_selector) = (
"head".parse().unwrap(),
"body".parse().unwrap(),
"link[type='text/css'][href*='normalize']".parse().unwrap(),
Copy link
Contributor Author

@cynecx cynecx Aug 22, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I consider this a hack because we are assuming that the first stylesheet included by rustdoc is normalize.css which might not be the case in the future (But I gotta say, having css style selectors is pretty nice :)).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't depend on it being first, though, does it? The reason it needs to come before normalize is because pure-css bundles its own whole separate copy, but I don't think pure-css duplicates any other of the rustdoc styles.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't depend on it being first, though, does it?

Well, it just needs to be positioned before rustdoc.css. By just inserting the vendored.css link before or after all head elements doesn't seem to be a good idea either.

);
let element_content_handlers = vec![
(
&head_selector,
ElementContentHandlers::default().element(head_handler),
),
(
&body_selector,
ElementContentHandlers::default().element(body_handler),
),
(
&first_stylesheet_selector,
ElementContentHandlers::default().element(first_stylesheet_handler),
),
];
let settings = Settings {
element_content_handlers: vec![head, body],
element_content_handlers,
memory_settings: MemorySettings {
max_allowed_memory_usage,
..MemorySettings::default()
Expand Down
1 change: 1 addition & 0 deletions src/web/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ mod tests {
("/robots.txt", "static resource"),
("/sitemap.xml", "static resource"),
("/-/static/style.css", "static resource"),
("/-/static/vendored.css", "static resource"),
];

wrapper(|env| {
Expand Down
22 changes: 21 additions & 1 deletion src/web/statics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use mime_guess::MimeGuess;
use router::Router;
use std::{ffi::OsStr, fs, path::Path};

const VENDORED_CSS: &str = include_str!(concat!(env!("OUT_DIR"), "/vendored.css"));
const STYLE_CSS: &str = include_str!(concat!(env!("OUT_DIR"), "/style.css"));
const MENU_JS: &str = include_str!(concat!(env!("OUT_DIR"), "/menu.js"));
const INDEX_JS: &str = include_str!(concat!(env!("OUT_DIR"), "/index.js"));
Expand All @@ -20,6 +21,7 @@ pub(crate) fn static_handler(req: &mut Request) -> IronResult<Response> {
let file = cexpect!(req, router.find("file"));

match file {
"vendored.css" => serve_resource(VENDORED_CSS, ContentType("text/css".parse().unwrap())),
"style.css" => serve_resource(STYLE_CSS, ContentType("text/css".parse().unwrap())),
"index.js" => serve_resource(
INDEX_JS,
Expand Down Expand Up @@ -119,7 +121,7 @@ pub(super) fn ico_handler(req: &mut Request) -> IronResult<Response> {

#[cfg(test)]
mod tests {
use super::{INDEX_JS, MENU_JS, STATIC_SEARCH_PATHS, STYLE_CSS};
use super::{INDEX_JS, MENU_JS, STATIC_SEARCH_PATHS, STYLE_CSS, VENDORED_CSS};
use crate::test::wrapper;
use std::fs;

Expand All @@ -141,6 +143,24 @@ mod tests {
});
}

#[test]
fn vendored_css() {
wrapper(|env| {
let web = env.frontend();

let resp = web.get("/-/static/vendored.css").send()?;
assert!(resp.status().is_success());
assert_eq!(
resp.headers().get("Content-Type"),
Some(&"text/css".parse().unwrap()),
);
assert_eq!(resp.content_length().unwrap(), VENDORED_CSS.len() as u64);
assert_eq!(resp.text()?, VENDORED_CSS);

Ok(())
});
}

#[test]
fn index_js() {
wrapper(|env| {
Expand Down
1 change: 1 addition & 0 deletions templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
{%- block meta -%}{%- endblock meta -%}

{# Docs.rs styles #}
<link rel="stylesheet" href="/-/static/vendored.css?{{ docsrs_version() | slugify }}" type="text/css" media="all" />
<link rel="stylesheet" href="/normalize-{{ rustc_resource_suffix() }}.css" type="text/css" media="all" />
<link rel="stylesheet" href="/rustdoc-{{ rustc_resource_suffix() }}.css" type="text/css" media="all" />
<link rel="stylesheet" href="/light-{{ rustc_resource_suffix() }}.css" type="text/css" media="all" />
Expand Down
2 changes: 2 additions & 0 deletions templates/rustdoc/vendored.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<link rel="stylesheet" href="/-/static/vendored.css?{{ docsrs_version() | slugify }}" type="text/css" media="all" />

3 changes: 1 addition & 2 deletions templates/style/base.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// FIXME: Use modules
@import "vars", "rustdoc", "utils", "navbar", "fontawesome", "regular", "solid", "brands", "pure-min",
"grids-responsive-min";
@import "vars", "rustdoc", "utils", "navbar";

html,
input,
Expand Down
3 changes: 3 additions & 0 deletions templates/style/vendored.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@import "fontawesome", "regular", "solid", "brands", "pure-min",
"grids-responsive-min";