Skip to content

Commit 5cd96d6

Browse files
committed
rustdoc: Provide a way to set the default settings from Rust code
rustdoc has various user-configurable preferences. These are recorded in web Local Storage (where available). But we want to provide a way to configure the default default, including for when web storage is not available. getSettingValue is the function responsible for looking up these settings. Here we make it fall back some in-DOM data, which ultimately comes from RenderOptions.default_settings. Using HTML data atrtributes is fairly convenient here, dsspite the need to transform between snake and kebab case to avoid the DOM converting kebab case to camel case (!) We cache the element and dataset lookup in a global variable, to ensure that getSettingValue remains fast. The DOM representation has to be in an element which precedes the inclusion of storage.js. That means it has to be in the <head> and we should not use an empty <div> as the container (although most browsers will accept that). An empty <script> element provides a convenient and harmless container object. <meta> would be another possibility but runs a greater risk of having unwanted behaviours on weird browsers. We trust the RenderOptions not to contain unhelpful setting names, which don't fit nicely into an HTML attribute. It's awkward to quote dataset keys. Signed-off-by: Ian Jackson <[email protected]>
1 parent 2e10475 commit 5cd96d6

File tree

5 files changed

+39
-2
lines changed

5 files changed

+39
-2
lines changed

src/librustdoc/config.rs

Lines changed: 5 additions & 1 deletion
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
@@ -596,6 +599,7 @@ impl Options {
596599
themes,
597600
extension_css,
598601
extern_html_root_urls,
602+
default_settings: Default::default(),
599603
resource_suffix,
600604
enable_minification,
601605
enable_index_page,

src/librustdoc/html/layout.rs

Lines changed: 8 additions & 0 deletions
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 2 additions & 0 deletions
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/storage.js

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,30 @@ var darkThemes = ["dark", "ayu"];
55
var currentTheme = document.getElementById("themeStyle");
66
var mainTheme = document.getElementById("mainThemeStyle");
77

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+
820
function getSettingValue(settingName) {
9-
return getCurrentValue('rustdoc-' + 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;
1032
}
1133

1234
var localStoredTheme = getSettingValue("theme");

0 commit comments

Comments
 (0)