Skip to content

Commit 2008d1b

Browse files
authored
Rollup merge of #77213 - ijackson:wip-rustdoc-settings, r=jyn514,GuillaumeGomez
rustdoc options to set default theme (and other settings) Hi. This is the MR I promised in #77024 It is a little more general than I envisaged there. Once I had found the settings-handling machinery it seemed foolish to add this feature just for the theme. Closes #77024
2 parents 31ee872 + 776e204 commit 2008d1b

File tree

8 files changed

+109
-25
lines changed

8 files changed

+109
-25
lines changed

src/librustdoc/config.rs

+31-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::collections::BTreeMap;
1+
use std::collections::{BTreeMap, HashMap};
22
use std::convert::TryFrom;
33
use std::ffi::OsStr;
44
use std::fmt;
@@ -216,6 +216,9 @@ pub struct RenderOptions {
216216
pub extension_css: Option<PathBuf>,
217217
/// A map of crate names to the URL to use instead of querying the crate's `html_root_url`.
218218
pub extern_html_root_urls: BTreeMap<String, String>,
219+
/// A map of the default settings (values are as for DOM storage API). Keys should lack the
220+
/// `rustdoc-` prefix.
221+
pub default_settings: HashMap<String, String>,
219222
/// If present, suffix added to CSS/JavaScript files when referencing them in generated pages.
220223
pub resource_suffix: String,
221224
/// Whether to run the static CSS/JavaScript through a minifier when outputting them. `true` by
@@ -374,6 +377,32 @@ impl Options {
374377
}
375378
};
376379

380+
let default_settings: Vec<Vec<(String, String)>> = vec![
381+
matches
382+
.opt_str("default-theme")
383+
.iter()
384+
.map(|theme| {
385+
vec![
386+
("use-system-theme".to_string(), "false".to_string()),
387+
("theme".to_string(), theme.to_string()),
388+
]
389+
})
390+
.flatten()
391+
.collect(),
392+
matches
393+
.opt_strs("default-setting")
394+
.iter()
395+
.map(|s| {
396+
let mut kv = s.splitn(2, '=');
397+
// never panics because `splitn` always returns at least one element
398+
let k = kv.next().unwrap().to_string();
399+
let v = kv.next().unwrap_or("true").to_string();
400+
(k, v)
401+
})
402+
.collect(),
403+
];
404+
let default_settings = default_settings.into_iter().flatten().collect();
405+
377406
let test_args = matches.opt_strs("test-args");
378407
let test_args: Vec<String> =
379408
test_args.iter().flat_map(|s| s.split_whitespace()).map(|s| s.to_string()).collect();
@@ -596,6 +625,7 @@ impl Options {
596625
themes,
597626
extension_css,
598627
extern_html_root_urls,
628+
default_settings,
599629
resource_suffix,
600630
enable_minification,
601631
enable_index_page,

src/librustdoc/html/layout.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::collections::HashMap;
12
use std::path::PathBuf;
23

34
use crate::externalfiles::ExternalHtml;
@@ -10,6 +11,7 @@ pub struct Layout {
1011
pub logo: String,
1112
pub favicon: String,
1213
pub external_html: ExternalHtml,
14+
pub default_settings: HashMap<String, String>,
1315
pub krate: String,
1416
/// The given user css file which allow to customize the generated
1517
/// documentation theme.
@@ -53,6 +55,7 @@ pub fn render<T: Print, S: Print>(
5355
<link rel=\"stylesheet\" type=\"text/css\" href=\"{static_root_path}rustdoc{suffix}.css\" \
5456
id=\"mainThemeStyle\">\
5557
{style_files}\
58+
<script id=\"default-settings\"{default_settings}></script>\
5659
<script src=\"{static_root_path}storage{suffix}.js\"></script>\
5760
<noscript><link rel=\"stylesheet\" href=\"{static_root_path}noscript{suffix}.css\"></noscript>\
5861
{css_extension}\
@@ -172,6 +175,11 @@ pub fn render<T: Print, S: Print>(
172175
after_content = layout.external_html.after_content,
173176
sidebar = Buffer::html().to_display(sidebar),
174177
krate = layout.krate,
178+
default_settings = layout
179+
.default_settings
180+
.iter()
181+
.map(|(k, v)| format!(r#" data-{}="{}""#, k.replace('-', "_"), Escape(v)))
182+
.collect::<String>(),
175183
style_files = style_files
176184
.iter()
177185
.filter_map(|t| {

src/librustdoc/html/markdown.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1228,6 +1228,7 @@ fn init_id_map() -> FxHashMap<String, usize> {
12281228
map.insert("render-detail".to_owned(), 1);
12291229
map.insert("toggle-all-docs".to_owned(), 1);
12301230
map.insert("all-types".to_owned(), 1);
1231+
map.insert("default-settings".to_owned(), 1);
12311232
// This is the list of IDs used by rustdoc sections.
12321233
map.insert("fields".to_owned(), 1);
12331234
map.insert("variants".to_owned(), 1);

src/librustdoc/html/render/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,7 @@ impl FormatRenderer for Context {
392392
playground_url,
393393
sort_modules_alphabetically,
394394
themes: style_files,
395+
default_settings,
395396
extension_css,
396397
resource_suffix,
397398
static_root_path,
@@ -415,6 +416,7 @@ impl FormatRenderer for Context {
415416
logo: String::new(),
416417
favicon: String::new(),
417418
external_html,
419+
default_settings,
418420
krate: krate.name.clone(),
419421
css_file_extension: extension_css,
420422
generate_search_filter,

src/librustdoc/html/static/main.js

+11-11
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ function defocusSearchBar() {
8989
"derive",
9090
"traitalias"];
9191

92-
var disableShortcuts = getCurrentValue("rustdoc-disable-shortcuts") === "true";
92+
var disableShortcuts = getSettingValue("disable-shortcuts") === "true";
9393
var search_input = getSearchInput();
9494
var searchTimeout = null;
9595
var toggleAllDocsId = "toggle-all-docs";
@@ -1580,7 +1580,7 @@ function defocusSearchBar() {
15801580
function showResults(results) {
15811581
var search = getSearchElement();
15821582
if (results.others.length === 1
1583-
&& getCurrentValue("rustdoc-go-to-only-result") === "true"
1583+
&& getSettingValue("go-to-only-result") === "true"
15841584
// By default, the search DOM element is "empty" (meaning it has no children not
15851585
// text content). Once a search has been run, it won't be empty, even if you press
15861586
// ESC or empty the search input (which also "cancels" the search).
@@ -2296,7 +2296,7 @@ function defocusSearchBar() {
22962296
function autoCollapse(pageId, collapse) {
22972297
if (collapse) {
22982298
toggleAllDocs(pageId, true);
2299-
} else if (getCurrentValue("rustdoc-auto-hide-trait-implementations") !== "false") {
2299+
} else if (getSettingValue("auto-hide-trait-implementations") !== "false") {
23002300
var impl_list = document.getElementById("trait-implementations-list");
23012301

23022302
if (impl_list !== null) {
@@ -2370,8 +2370,8 @@ function defocusSearchBar() {
23702370
}
23712371

23722372
var toggle = createSimpleToggle(false);
2373-
var hideMethodDocs = getCurrentValue("rustdoc-auto-hide-method-docs") === "true";
2374-
var hideImplementors = getCurrentValue("rustdoc-auto-collapse-implementors") !== "false";
2373+
var hideMethodDocs = getSettingValue("auto-hide-method-docs") === "true";
2374+
var hideImplementors = getSettingValue("auto-collapse-implementors") !== "false";
23752375
var pageId = getPageId();
23762376

23772377
var func = function(e) {
@@ -2487,15 +2487,15 @@ function defocusSearchBar() {
24872487
});
24882488
}
24892489
}
2490-
var showItemDeclarations = getCurrentValue("rustdoc-auto-hide-" + className);
2490+
var showItemDeclarations = getSettingValue("auto-hide-" + className);
24912491
if (showItemDeclarations === null) {
24922492
if (className === "enum" || className === "macro") {
24932493
showItemDeclarations = "false";
24942494
} else if (className === "struct" || className === "union" || className === "trait") {
24952495
showItemDeclarations = "true";
24962496
} else {
24972497
// In case we found an unknown type, we just use the "parent" value.
2498-
showItemDeclarations = getCurrentValue("rustdoc-auto-hide-declarations");
2498+
showItemDeclarations = getSettingValue("auto-hide-declarations");
24992499
}
25002500
}
25012501
showItemDeclarations = showItemDeclarations === "false";
@@ -2569,7 +2569,7 @@ function defocusSearchBar() {
25692569
onEachLazy(document.getElementsByClassName("sub-variant"), buildToggleWrapper);
25702570
var pageId = getPageId();
25712571

2572-
autoCollapse(pageId, getCurrentValue("rustdoc-collapse") === "true");
2572+
autoCollapse(pageId, getSettingValue("collapse") === "true");
25732573

25742574
if (pageId !== null) {
25752575
expandSection(pageId);
@@ -2592,7 +2592,7 @@ function defocusSearchBar() {
25922592
(function() {
25932593
// To avoid checking on "rustdoc-item-attributes" value on every loop...
25942594
var itemAttributesFunc = function() {};
2595-
if (getCurrentValue("rustdoc-auto-hide-attributes") !== "false") {
2595+
if (getSettingValue("auto-hide-attributes") !== "false") {
25962596
itemAttributesFunc = function(x) {
25972597
collapseDocs(x.previousSibling.childNodes[0], "toggle");
25982598
};
@@ -2611,7 +2611,7 @@ function defocusSearchBar() {
26112611
(function() {
26122612
// To avoid checking on "rustdoc-line-numbers" value on every loop...
26132613
var lineNumbersFunc = function() {};
2614-
if (getCurrentValue("rustdoc-line-numbers") === "true") {
2614+
if (getSettingValue("line-numbers") === "true") {
26152615
lineNumbersFunc = function(x) {
26162616
var count = x.textContent.split("\n").length;
26172617
var elems = [];
@@ -2768,7 +2768,7 @@ function defocusSearchBar() {
27682768
}
27692769
return 0;
27702770
});
2771-
var savedCrate = getCurrentValue("rustdoc-saved-filter-crate");
2771+
var savedCrate = getSettingValue("saved-filter-crate");
27722772
for (var i = 0; i < crates_text.length; ++i) {
27732773
var option = document.createElement("option");
27742774
option.value = crates_text[i];

src/librustdoc/html/static/settings.js

-4
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@
1414
}
1515
}
1616

17-
function getSettingValue(settingName) {
18-
return getCurrentValue("rustdoc-" + settingName);
19-
}
20-
2117
function setEvents() {
2218
var elems = {
2319
toggles: document.getElementsByClassName("slider"),

src/librustdoc/html/static/storage.js

+36-9
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,37 @@
11
// From rust:
2-
/* global resourcesSuffix */
2+
/* global resourcesSuffix, getSettingValue */
33

44
var darkThemes = ["dark", "ayu"];
55
var currentTheme = document.getElementById("themeStyle");
66
var mainTheme = document.getElementById("mainThemeStyle");
7-
var localStoredTheme = getCurrentValue("rustdoc-theme");
7+
8+
var settingsDataset = (function () {
9+
var settingsElement = document.getElementById("default-settings");
10+
if (settingsElement === null) {
11+
return null;
12+
}
13+
var dataset = settingsElement.dataset;
14+
if (dataset === undefined) {
15+
return null;
16+
}
17+
return dataset;
18+
})();
19+
20+
function getSettingValue(settingName) {
21+
var current = getCurrentValue('rustdoc-' + settingName);
22+
if (current !== null) {
23+
return current;
24+
}
25+
if (settingsDataset !== null) {
26+
var def = settingsDataset[settingName.replace(/-/g,'_')];
27+
if (def !== undefined) {
28+
return def;
29+
}
30+
}
31+
return null;
32+
}
33+
34+
var localStoredTheme = getSettingValue("theme");
835

936
var savedHref = [];
1037

@@ -156,9 +183,9 @@ var updateSystemTheme = (function() {
156183

157184
function handlePreferenceChange(mql) {
158185
// maybe the user has disabled the setting in the meantime!
159-
if (getCurrentValue("rustdoc-use-system-theme") !== "false") {
160-
var lightTheme = getCurrentValue("rustdoc-preferred-light-theme") || "light";
161-
var darkTheme = getCurrentValue("rustdoc-preferred-dark-theme") || "dark";
186+
if (getSettingValue("use-system-theme") !== "false") {
187+
var lightTheme = getSettingValue("preferred-light-theme") || "light";
188+
var darkTheme = getSettingValue("preferred-dark-theme") || "dark";
162189

163190
if (mql.matches) {
164191
// prefers a dark theme
@@ -181,11 +208,11 @@ var updateSystemTheme = (function() {
181208
};
182209
})();
183210

184-
if (getCurrentValue("rustdoc-use-system-theme") !== "false" && window.matchMedia) {
211+
if (getSettingValue("use-system-theme") !== "false" && window.matchMedia) {
185212
// update the preferred dark theme if the user is already using a dark theme
186213
// See https://github.com/rust-lang/rust/pull/77809#issuecomment-707875732
187-
if (getCurrentValue("rustdoc-use-system-theme") === null
188-
&& getCurrentValue("rustdoc-preferred-dark-theme") === null
214+
if (getSettingValue("use-system-theme") === null
215+
&& getSettingValue("preferred-dark-theme") === null
189216
&& darkThemes.indexOf(localStoredTheme) >= 0) {
190217
updateLocalStorage("rustdoc-preferred-dark-theme", localStoredTheme);
191218
}
@@ -196,7 +223,7 @@ if (getCurrentValue("rustdoc-use-system-theme") !== "false" && window.matchMedia
196223
switchTheme(
197224
currentTheme,
198225
mainTheme,
199-
getCurrentValue("rustdoc-theme") || "light",
226+
getSettingValue("theme") || "light",
200227
false
201228
);
202229
}

src/librustdoc/lib.rs

+20
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,26 @@ fn opts() -> Vec<RustcOptGroup> {
269269
"sort modules by where they appear in the program, rather than alphabetically",
270270
)
271271
}),
272+
unstable("default-theme", |o| {
273+
o.optopt(
274+
"",
275+
"default-theme",
276+
"Set the default theme. THEME should be the theme name, generally lowercase. \
277+
If an unknown default theme is specified, the builtin default is used. \
278+
The set of themes, and the rustdoc built-in default is not stable.",
279+
"THEME",
280+
)
281+
}),
282+
unstable("default-setting", |o| {
283+
o.optmulti(
284+
"",
285+
"default-setting",
286+
"Default value for a rustdoc setting (used when \"rustdoc-SETTING\" is absent \
287+
from web browser Local Storage). If VALUE is not supplied, \"true\" is used. \
288+
Supported SETTINGs and VALUEs are not documented and not stable.",
289+
"SETTING[=VALUE]",
290+
)
291+
}),
272292
stable("theme", |o| {
273293
o.optmulti(
274294
"",

0 commit comments

Comments
 (0)