Skip to content

Commit a1c1c10

Browse files
committed
Add configuration options to hide TOC or module navigation
1 parent 0d4df6c commit a1c1c10

File tree

11 files changed

+140
-44
lines changed

11 files changed

+140
-44
lines changed

src/librustdoc/html/markdown.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1661,7 +1661,10 @@ pub(crate) fn plain_text_summary(md: &str, link_names: &[RenderedLink]) -> Strin
16611661
s
16621662
}
16631663

1664-
pub(crate) fn plain_text_from_events<'a>(events: impl Iterator<Item=pulldown_cmark::Event<'a>>, s: &mut String) {
1664+
pub(crate) fn plain_text_from_events<'a>(
1665+
events: impl Iterator<Item = pulldown_cmark::Event<'a>>,
1666+
s: &mut String,
1667+
) {
16651668
for event in events {
16661669
match &event {
16671670
Event::Text(text) => s.push_str(text),

src/librustdoc/html/render/context.rs

+1
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
631631
title: "",
632632
is_crate: false,
633633
is_mod: false,
634+
parent_is_crate: false,
634635
blocks: vec![blocks],
635636
path: String::new(),
636637
};

src/librustdoc/html/render/sidebar.rs

+35-24
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub(super) struct Sidebar<'a> {
1919
pub(super) title_prefix: &'static str,
2020
pub(super) title: &'a str,
2121
pub(super) is_crate: bool,
22+
pub(super) parent_is_crate: bool,
2223
pub(super) is_mod: bool,
2324
pub(super) blocks: Vec<LinkBlock<'a>>,
2425
pub(super) path: String,
@@ -126,8 +127,15 @@ pub(super) fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buf
126127
} else {
127128
"".into()
128129
};
129-
let sidebar =
130-
Sidebar { title_prefix, title, is_mod: it.is_mod(), is_crate: it.is_crate(), blocks, path };
130+
let sidebar = Sidebar {
131+
title_prefix,
132+
title,
133+
is_mod: it.is_mod(),
134+
is_crate: it.is_crate(),
135+
parent_is_crate: sidebar_path.len() == 1,
136+
blocks,
137+
path,
138+
};
131139
sidebar.render_into(buffer).unwrap();
132140
}
133141

@@ -156,26 +164,32 @@ fn docblock_toc<'a>(
156164
edition: cx.shared.edition(),
157165
playground: &cx.shared.playground,
158166
custom_code_classes_in_docs: cx.tcx().features().custom_code_classes_in_docs,
159-
}.into_parts();
160-
let links: Vec<Link<'_>> = toc.entries.into_iter().map(|entry| {
161-
Link {
162-
name: entry.name.into(),
163-
href: entry.id.into(),
164-
children: entry.children.entries.into_iter().map(|entry| Link {
167+
}
168+
.into_parts();
169+
let links: Vec<Link<'_>> = toc
170+
.entries
171+
.into_iter()
172+
.map(|entry| {
173+
Link {
165174
name: entry.name.into(),
166175
href: entry.id.into(),
167-
// Only a single level of nesting is shown here.
168-
// Going the full six could break the layout,
169-
// so we have to cut it off somewhere.
170-
children: vec![],
171-
}).collect()
172-
}
173-
}).collect();
174-
if links.is_empty() {
175-
None
176-
} else {
177-
Some(LinkBlock::new(Link::new("#", "Sections"), "top-toc", links))
178-
}
176+
children: entry
177+
.children
178+
.entries
179+
.into_iter()
180+
.map(|entry| Link {
181+
name: entry.name.into(),
182+
href: entry.id.into(),
183+
// Only a single level of nesting is shown here.
184+
// Going the full six could break the layout,
185+
// so we have to cut it off somewhere.
186+
children: vec![],
187+
})
188+
.collect(),
189+
}
190+
})
191+
.collect();
192+
if links.is_empty() { None } else { Some(LinkBlock::new(Link::new("", ""), "top-toc", links)) }
179193
}
180194

181195
fn sidebar_struct<'a>(
@@ -505,10 +519,7 @@ pub(crate) fn sidebar_module_like(
505519
LinkBlock::new(Link::empty(), "", item_sections)
506520
}
507521

508-
fn sidebar_module(
509-
items: &[clean::Item],
510-
ids: &mut IdMap,
511-
) -> LinkBlock<'static> {
522+
fn sidebar_module(items: &[clean::Item], ids: &mut IdMap) -> LinkBlock<'static> {
512523
let item_sections_in_use: FxHashSet<_> = items
513524
.iter()
514525
.filter(|it| {

src/librustdoc/html/static/css/rustdoc.css

+8
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,14 @@ ul.block, .block li, .block ul {
567567
margin-right: 0.25rem;
568568
}
569569

570+
.hide-toc #TOC, .hide-toc .in-crate {
571+
display: none;
572+
}
573+
574+
.hide-modnav #ModNav {
575+
display: none;
576+
}
577+
570578
.sidebar h2 {
571579
overflow-wrap: anywhere;
572580
padding: 0;

src/librustdoc/html/static/js/main.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ function preLoadCss(cssUrl) {
460460
if (!window.SIDEBAR_ITEMS) {
461461
return;
462462
}
463-
const sidebar = document.getElementsByClassName("sidebar-elems")[0];
463+
const sidebar = document.getElementById("ModNav");
464464

465465
/**
466466
* Append to the sidebar a "block" of links - a heading along with a list (`<ul>`) of items.
@@ -845,7 +845,7 @@ function preLoadCss(cssUrl) {
845845
if (!window.ALL_CRATES) {
846846
return;
847847
}
848-
const sidebarElems = document.getElementsByClassName("sidebar-elems")[0];
848+
const sidebarElems = document.getElementById("ModNav");
849849
if (!sidebarElems) {
850850
return;
851851
}

src/librustdoc/html/static/js/settings.js

+29
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,20 @@
3636
removeClass(document.documentElement, "hide-sidebar");
3737
}
3838
break;
39+
case "hide-toc":
40+
if (value === true) {
41+
addClass(document.documentElement, "hide-toc");
42+
} else {
43+
removeClass(document.documentElement, "hide-toc");
44+
}
45+
break;
46+
case "hide-modnav":
47+
if (value === true) {
48+
addClass(document.documentElement, "hide-modnav");
49+
} else {
50+
removeClass(document.documentElement, "hide-modnav");
51+
}
52+
break;
3953
}
4054
}
4155

@@ -102,6 +116,11 @@
102116
let output = "";
103117

104118
for (const setting of settings) {
119+
if (setting === "hr") {
120+
output += "<hr>";
121+
continue;
122+
}
123+
105124
const js_data_name = setting["js_name"];
106125
const setting_name = setting["name"];
107126

@@ -198,6 +217,16 @@
198217
"js_name": "hide-sidebar",
199218
"default": false,
200219
},
220+
{
221+
"name": "Hide table of contents",
222+
"js_name": "hide-toc",
223+
"default": false,
224+
},
225+
{
226+
"name": "Hide module navigation",
227+
"js_name": "hide-modnav",
228+
"default": false,
229+
},
201230
{
202231
"name": "Disable keyboard shortcuts",
203232
"js_name": "disable-shortcuts",

src/librustdoc/html/static/js/storage.js

+9-4
Original file line numberDiff line numberDiff line change
@@ -196,16 +196,21 @@ updateTheme();
196196
// This needs to be done here because this JS is render-blocking,
197197
// so that the sidebar doesn't "jump" after appearing on screen.
198198
// The user interaction to change this is set up in main.js.
199+
//
200+
// At this point in page load, `document.body` is not available yet.
201+
// Set a class on the `<html>` element instead.
199202
if (getSettingValue("source-sidebar-show") === "true") {
200-
// At this point in page load, `document.body` is not available yet.
201-
// Set a class on the `<html>` element instead.
202203
addClass(document.documentElement, "src-sidebar-expanded");
203204
}
204205
if (getSettingValue("hide-sidebar") === "true") {
205-
// At this point in page load, `document.body` is not available yet.
206-
// Set a class on the `<html>` element instead.
207206
addClass(document.documentElement, "hide-sidebar");
208207
}
208+
if (getSettingValue("hide-toc") === "true") {
209+
addClass(document.documentElement, "hide-toc");
210+
}
211+
if (getSettingValue("hide-modnav") === "true") {
212+
addClass(document.documentElement, "hide-modnav");
213+
}
209214
function updateSidebarWidth() {
210215
const desktopSidebarWidth = getSettingValue("desktop-sidebar-width");
211216
if (desktopSidebarWidth && desktopSidebarWidth !== "null") {

src/librustdoc/html/templates/sidebar.html

+12-8
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
{% if !title.is_empty() %}
2-
<h2 class="location"> {# #}
3-
<a href="#">{{title_prefix}}{{title}}</a> {# #}
4-
</h2>
5-
{% endif %}
61
<div class="sidebar-elems">
72
{% if is_crate %}
83
<ul class="block">
@@ -11,11 +6,16 @@ <h2 class="location"> {# #}
116
{% endif %}
127

138
{% if self.should_render_blocks() %}
14-
<section>
9+
<section id="TOC">
10+
{% if !title.is_empty() %}
11+
<h2 class="location"> {# #}
12+
<a href="#">{{title_prefix}}{{title}}</a> {# #}
13+
</h2>
14+
{% endif %}
1515
{% for block in blocks %}
1616
{% if block.should_render() %}
1717
{% if !block.heading.name.is_empty() %}
18-
<h3{% if !block.class.is_empty() +%} class="{{block.class}}"{% endif %}> {# #}
18+
<h3> {# #}
1919
<a href="#{{block.heading.href|safe}}">{{block.heading.name}}</a> {# #}
2020
</h3> {# #}
2121
{% endif %}
@@ -39,7 +39,11 @@ <h2 class="location"> {# #}
3939
{% endfor %}
4040
</section>
4141
{% endif %}
42+
<div id="ModNav">
4243
{% if !path.is_empty() %}
43-
<h2><a href="{% if is_mod %}../{% endif %}index.html">In {{+ path}}</a></h2>
44+
<h2{% if parent_is_crate +%} class="in-crate"{% endif %}> {# #}
45+
<a href="{% if is_mod %}../{% endif %}index.html">In {{+ path}}</a> {# #}
46+
</h2> {# #}
4447
{% endif %}
48+
</div> {# #}
4549
</div>

tests/rustdoc-gui/sidebar.goml

+37-4
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,8 @@ assert-count: (".sidebar .location", 1)
128128
// - Module name, followed by TOC for module headings
129129
// - "In crate [name]" parent pointer, followed by sibling navigation
130130
assert-count: (".sidebar h2", 3)
131-
assert-text: (".sidebar > .sidebar-elems > h2", "In crate lib2")
132-
assert-property: (".sidebar > .sidebar-elems > h2 > a", {
131+
assert-text: (".sidebar > .sidebar-elems > #ModNav > h2", "In crate lib2")
132+
assert-property: (".sidebar > .sidebar-elems > #ModNav > h2 > a", {
133133
"href": "/lib2/index.html",
134134
}, ENDS_WITH)
135135
// We check that we don't have the crate list.
@@ -139,8 +139,8 @@ go-to: "./sub_module/sub_sub_module/index.html"
139139
assert-property: (".sidebar", {"clientWidth": "200"})
140140
assert-text: (".sidebar > .sidebar-crate > h2 > a", "lib2")
141141
assert-text: (".sidebar .location", "Module sub_sub_module")
142-
assert-text: (".sidebar > .sidebar-elems > h2", "In lib2::module::sub_module")
143-
assert-property: (".sidebar > .sidebar-elems > h2 > a", {
142+
assert-text: (".sidebar > .sidebar-elems > #ModNav > h2", "In lib2::module::sub_module")
143+
assert-property: (".sidebar > .sidebar-elems > #ModNav > h2 > a", {
144144
"href": "/module/sub_module/index.html",
145145
}, ENDS_WITH)
146146
// We check that we don't have the crate list.
@@ -184,3 +184,36 @@ assert-property: (".sidebar .sidebar-crate h2 a", {
184184
"offsetTop": |index_sidebar_y|,
185185
"offsetLeft": |index_sidebar_x|,
186186
})
187+
188+
// Configuration option to show TOC in sidebar.
189+
set-local-storage: {"rustdoc-hide-toc": "true"}
190+
go-to: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html"
191+
assert-css: ("#TOC", {"display": "none"})
192+
assert-css: (".sidebar .in-crate", {"display": "none"})
193+
set-local-storage: {"rustdoc-hide-toc": "false"}
194+
go-to: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html"
195+
assert-css: ("#TOC", {"display": "block"})
196+
assert-css: (".sidebar .in-crate", {"display": "block"})
197+
198+
set-local-storage: {"rustdoc-hide-modnav": "true"}
199+
go-to: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html"
200+
assert-css: ("#ModNav", {"display": "none"})
201+
set-local-storage: {"rustdoc-hide-modnav": "false"}
202+
go-to: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html"
203+
assert-css: ("#ModNav", {"display": "block"})
204+
205+
set-local-storage: {"rustdoc-hide-toc": "true"}
206+
go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
207+
assert-css: ("#TOC", {"display": "none"})
208+
assert-false: ".sidebar .in-crate"
209+
set-local-storage: {"rustdoc-hide-toc": "false"}
210+
go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
211+
assert-css: ("#TOC", {"display": "block"})
212+
assert-false: ".sidebar .in-crate"
213+
214+
set-local-storage: {"rustdoc-hide-modnav": "true"}
215+
go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
216+
assert-css: ("#ModNav", {"display": "none"})
217+
set-local-storage: {"rustdoc-hide-modnav": "false"}
218+
go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
219+
assert-css: ("#ModNav", {"display": "block"})

tests/rustdoc/sidebar/top-toc-html.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// ignore-tidy-linelength
2+
13
#![crate_name = "foo"]
24
#![feature(lazy_type_alias)]
35
#![allow(incomplete_features)]

tests/rustdoc/sidebar/top-toc-idmap.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#![allow(incomplete_features)]
44

55
//! # Structs
6-
//!
6+
//!
77
//! This header has the same name as a built-in header,
88
//! and we need to make sure they're disambiguated with
99
//! suffixes.

0 commit comments

Comments
 (0)