Skip to content

Commit c330963

Browse files
committed
Simplify rendering of stylesheet links into HTML
We carry around a list of stylesheets that can carry two different types of thing: 1. Internal stylesheets specific to a page type (only for settings) 2. Themes In this change I move the link generation for settings.css into settings(), so Context.style_files is reserved just for themes. We had two places where we extracted a base theme name from a list of StylePaths. I consolidated that code to be a method on StylePath. I moved generation of link tags for stylesheets into the page.html template. With that change, I made the template responsible for special handling of light.css (making it the default theme) and of the other themes (marking them disabled). That allowed getting rid of the `disabled` field on StylePath.
1 parent ce3f3a5 commit c330963

File tree

7 files changed

+49
-50
lines changed

7 files changed

+49
-50
lines changed

src/librustdoc/config.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@ impl Options {
556556
))
557557
.emit();
558558
}
559-
themes.push(StylePath { path: theme_file, disabled: true });
559+
themes.push(StylePath { path: theme_file });
560560
}
561561
}
562562

src/librustdoc/error.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ macro_rules! try_none {
3939
match $e {
4040
Some(e) => e,
4141
None => {
42-
return Err(Error::new(io::Error::new(io::ErrorKind::Other, "not found"), $file));
42+
return Err(<crate::error::Error as crate::docfs::PathError>::new(
43+
io::Error::new(io::ErrorKind::Other, "not found"),
44+
$file,
45+
));
4346
}
4447
}
4548
}};

src/librustdoc/html/layout.rs

+7-15
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use std::path::PathBuf;
22

33
use rustc_data_structures::fx::FxHashMap;
44

5+
use crate::error::Error;
56
use crate::externalfiles::ExternalHtml;
6-
use crate::html::escape::Escape;
77
use crate::html::format::{Buffer, Print};
88
use crate::html::render::{ensure_trailing_slash, StylePath};
99

@@ -50,7 +50,7 @@ struct PageLayout<'a> {
5050
static_root_path: &'a str,
5151
page: &'a Page<'a>,
5252
layout: &'a Layout,
53-
style_files: String,
53+
themes: Vec<String>,
5454
sidebar: String,
5555
content: String,
5656
krate_with_trailing_slash: String,
@@ -66,26 +66,18 @@ crate fn render<T: Print, S: Print>(
6666
) -> String {
6767
let static_root_path = page.get_static_root_path();
6868
let krate_with_trailing_slash = ensure_trailing_slash(&layout.krate).to_string();
69-
let style_files = style_files
69+
let themes = style_files
7070
.iter()
71-
.filter_map(|t| t.path.file_stem().map(|stem| (stem, t.disabled)))
72-
.filter_map(|t| t.0.to_str().map(|path| (path, t.1)))
73-
.map(|t| {
74-
format!(
75-
r#"<link rel="stylesheet" type="text/css" href="{}.css" {} {}>"#,
76-
Escape(&format!("{}{}{}", static_root_path, t.0, page.resource_suffix)),
77-
if t.1 { "disabled" } else { "" },
78-
if t.0 == "light" { "id=\"themeStyle\"" } else { "" }
79-
)
80-
})
81-
.collect::<String>();
71+
.map(StylePath::basename)
72+
.collect::<Result<_, Error>>()
73+
.unwrap_or_default();
8274
let content = Buffer::html().to_display(t); // Note: This must happen before making the sidebar.
8375
let sidebar = Buffer::html().to_display(sidebar);
8476
let teractx = tera::Context::from_serialize(PageLayout {
8577
static_root_path,
8678
page,
8779
layout,
88-
style_files,
80+
themes,
8981
sidebar,
9082
content,
9183
krate_with_trailing_slash,

src/librustdoc/html/render/context.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -504,9 +504,9 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
504504
// by the browser as the theme stylesheet. The theme system (hackily) works by
505505
// changing the href to this stylesheet. All other themes are disabled to
506506
// prevent rule conflicts
507-
scx.style_files.push(StylePath { path: PathBuf::from("light.css"), disabled: false });
508-
scx.style_files.push(StylePath { path: PathBuf::from("dark.css"), disabled: true });
509-
scx.style_files.push(StylePath { path: PathBuf::from("ayu.css"), disabled: true });
507+
scx.style_files.push(StylePath { path: PathBuf::from("light.css") });
508+
scx.style_files.push(StylePath { path: PathBuf::from("dark.css") });
509+
scx.style_files.push(StylePath { path: PathBuf::from("ayu.css") });
510510

511511
let dst = output;
512512
scx.ensure_dir(&dst)?;
@@ -596,9 +596,13 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
596596
page.description = "Settings of Rustdoc";
597597
page.root_path = "./";
598598

599-
let mut style_files = self.shared.style_files.clone();
600599
let sidebar = "<h2 class=\"location\">Settings</h2><div class=\"sidebar-elems\"></div>";
601-
style_files.push(StylePath { path: PathBuf::from("settings.css"), disabled: false });
600+
let theme_names: Vec<String> = self
601+
.shared
602+
.style_files
603+
.iter()
604+
.map(StylePath::basename)
605+
.collect::<Result<_, Error>>()?;
602606
let v = layout::render(
603607
&self.shared.templates,
604608
&self.shared.layout,
@@ -607,9 +611,9 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
607611
settings(
608612
self.shared.static_root_path.as_deref().unwrap_or("./"),
609613
&self.shared.resource_suffix,
610-
&self.shared.style_files,
614+
theme_names,
611615
)?,
612-
&style_files,
616+
&self.shared.style_files,
613617
);
614618
self.shared.fs.write(settings_file, v)?;
615619
if let Some(ref redirections) = self.shared.redirections {

src/librustdoc/html/render/mod.rs

+15-23
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ use serde::ser::SerializeSeq;
6464
use serde::{Serialize, Serializer};
6565

6666
use crate::clean::{self, ItemId, RenderedLink, SelfTy};
67-
use crate::docfs::PathError;
6867
use crate::error::Error;
6968
use crate::formats::cache::Cache;
7069
use crate::formats::item_type::ItemType;
@@ -173,8 +172,12 @@ impl Serialize for TypeWithKind {
173172
crate struct StylePath {
174173
/// The path to the theme
175174
crate path: PathBuf,
176-
/// What the `disabled` attribute should be set to in the HTML tag
177-
crate disabled: bool,
175+
}
176+
177+
impl StylePath {
178+
pub fn basename(&self) -> Result<String, Error> {
179+
Ok(try_none!(try_none!(self.path.file_stem(), &self.path).to_str(), &self.path).to_string())
180+
}
178181
}
179182

180183
fn write_srclink(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer) {
@@ -353,7 +356,7 @@ enum Setting {
353356
js_data_name: &'static str,
354357
description: &'static str,
355358
default_value: &'static str,
356-
options: Vec<(String, String)>,
359+
options: Vec<String>,
357360
},
358361
}
359362

@@ -393,10 +396,9 @@ impl Setting {
393396
options
394397
.iter()
395398
.map(|opt| format!(
396-
"<option value=\"{}\" {}>{}</option>",
397-
opt.0,
398-
if opt.0 == default_value { "selected" } else { "" },
399-
opt.1,
399+
"<option value=\"{name}\" {}>{name}</option>",
400+
if opt == default_value { "selected" } else { "" },
401+
name = opt,
400402
))
401403
.collect::<String>(),
402404
root_path,
@@ -421,18 +423,7 @@ impl<T: Into<Setting>> From<(&'static str, Vec<T>)> for Setting {
421423
}
422424
}
423425

424-
fn settings(root_path: &str, suffix: &str, themes: &[StylePath]) -> Result<String, Error> {
425-
let theme_names: Vec<(String, String)> = themes
426-
.iter()
427-
.map(|entry| {
428-
let theme =
429-
try_none!(try_none!(entry.path.file_stem(), &entry.path).to_str(), &entry.path)
430-
.to_string();
431-
432-
Ok((theme.clone(), theme))
433-
})
434-
.collect::<Result<_, Error>>()?;
435-
426+
fn settings(root_path: &str, suffix: &str, theme_names: Vec<String>) -> Result<String, Error> {
436427
// (id, explanation, default value)
437428
let settings: &[Setting] = &[
438429
(
@@ -469,10 +460,11 @@ fn settings(root_path: &str, suffix: &str, themes: &[StylePath]) -> Result<Strin
469460
<span class=\"in-band\">Rustdoc settings</span>\
470461
</h1>\
471462
<div class=\"settings\">{}</div>\
472-
<script src=\"{}settings{}.js\"></script>",
463+
<link rel=\"stylesheet\" href=\"{root_path}settings{suffix}.css\">\
464+
<script src=\"{root_path}settings{suffix}.js\"></script>",
473465
settings.iter().map(|s| s.display(root_path, suffix)).collect::<String>(),
474-
root_path,
475-
suffix
466+
root_path = root_path,
467+
suffix = suffix
476468
))
477469
}
478470

src/librustdoc/html/render/write_shared.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -228,12 +228,12 @@ pub(super) fn write_shared(
228228
let mut themes: FxHashSet<String> = FxHashSet::default();
229229

230230
for entry in &cx.shared.style_files {
231-
let theme = try_none!(try_none!(entry.path.file_stem(), &entry.path).to_str(), &entry.path);
231+
let theme = entry.basename()?;
232232
let extension =
233233
try_none!(try_none!(entry.path.extension(), &entry.path).to_str(), &entry.path);
234234

235235
// Handle the official themes
236-
match theme {
236+
match theme.as_str() {
237237
"light" => write_minify("light.css", static_files::themes::LIGHT, cx, options)?,
238238
"dark" => write_minify("dark.css", static_files::themes::DARK, cx, options)?,
239239
"ayu" => write_minify("ayu.css", static_files::themes::AYU, cx, options)?,

src/librustdoc/html/templates/page.html

+9-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,15 @@
1212
<link rel="stylesheet" type="text/css" {# -#}
1313
href="{{static_root_path | safe}}rustdoc{{page.resource_suffix}}.css" {# -#}
1414
id="mainThemeStyle"> {#- -#}
15-
{{- style_files | safe -}}
15+
{%- for theme in themes -%}
16+
<link rel="stylesheet" type="text/css" {# -#}
17+
{%- if theme == "light" -%}
18+
id="themeStyle"
19+
{%- else -%}
20+
disabled
21+
{%- endif -%}
22+
href="{{static_root_path | safe}}{{theme}}{{page.resource_suffix}}.css"> {#- -#}
23+
{%- endfor -%}
1624
<script id="default-settings" {# -#}
1725
{% for k, v in layout.default_settings %}
1826
data-{{k}}="{{v}}"

0 commit comments

Comments
 (0)