rustdoc: make the help button a link to a page

This allows you to open the help section in a new browser tab, which is a
pretty reasonable thing to want for a documentation page.
This commit is contained in:
Michael Howell 2022-10-14 09:48:19 -07:00
parent ee1c3b385b
commit ae4ad9adb6
10 changed files with 127 additions and 46 deletions

View File

@ -1433,6 +1433,7 @@ static DEFAULT_ID_MAP: Lazy<FxHashMap<Cow<'static, str>, usize>> = Lazy::new(||
fn init_id_map() -> FxHashMap<Cow<'static, str>, usize> { fn init_id_map() -> FxHashMap<Cow<'static, str>, usize> {
let mut map = FxHashMap::default(); let mut map = FxHashMap::default();
// This is the list of IDs used in Javascript. // This is the list of IDs used in Javascript.
map.insert("help".into(), 1);
map.insert("settings".into(), 1); map.insert("settings".into(), 1);
map.insert("not-displayed".into(), 1); map.insert("not-displayed".into(), 1);
map.insert("alternative-display".into(), 1); map.insert("alternative-display".into(), 1);

View File

@ -581,6 +581,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
let crate_name = self.tcx().crate_name(LOCAL_CRATE); let crate_name = self.tcx().crate_name(LOCAL_CRATE);
let final_file = self.dst.join(crate_name.as_str()).join("all.html"); let final_file = self.dst.join(crate_name.as_str()).join("all.html");
let settings_file = self.dst.join("settings.html"); let settings_file = self.dst.join("settings.html");
let help_file = self.dst.join("help.html");
let scrape_examples_help_file = self.dst.join("scrape-examples-help.html"); let scrape_examples_help_file = self.dst.join("scrape-examples-help.html");
let mut root_path = self.dst.to_str().expect("invalid path").to_owned(); let mut root_path = self.dst.to_str().expect("invalid path").to_owned();
@ -657,6 +658,39 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
); );
shared.fs.write(settings_file, v)?; shared.fs.write(settings_file, v)?;
// Generating help page.
page.title = "Rustdoc help";
page.description = "Documentation for Rustdoc";
page.root_path = "./";
let sidebar = "<h2 class=\"location\">Help</h2><div class=\"sidebar-elems\"></div>";
let v = layout::render(
&shared.layout,
&page,
sidebar,
|buf: &mut Buffer| {
write!(
buf,
"<div class=\"main-heading\">\
<h1 class=\"fqn\">Rustdoc help</h1>\
<span class=\"out-of-band\">\
<a id=\"back\" href=\"javascript:void(0)\" onclick=\"history.back();\">\
Back\
</a>\
</span>\
</div>\
<noscript>\
<section>\
<p>You need to enable Javascript to use keyboard commands or search.</p>\
<p>For more information, browse the <a href=\"https://doc.rust-lang.org/rustdoc/\">rustdoc handbook</a>.</p>\
</section>\
</noscript>",
)
},
&shared.style_files,
);
shared.fs.write(help_file, v)?;
if shared.layout.scrape_examples_extension { if shared.layout.scrape_examples_extension {
page.title = "About scraped examples"; page.title = "About scraped examples";
page.description = "How the scraped examples feature works in Rustdoc"; page.description = "How the scraped examples feature works in Rustdoc";

View File

@ -199,7 +199,7 @@ h1, h2, h3, h4, h5, h6,
.out-of-band, .out-of-band,
span.since, span.since,
a.srclink, a.srclink,
#help-button > button, #help-button > a,
details.rustdoc-toggle.top-doc > summary, details.rustdoc-toggle.top-doc > summary,
details.rustdoc-toggle.non-exhaustive > summary, details.rustdoc-toggle.non-exhaustive > summary,
.scraped-example-title, .scraped-example-title,
@ -974,32 +974,33 @@ so that we can apply CSS-filters to change the arrow color in themes */
color: var(--main-color); color: var(--main-color);
} }
#help-button .popover { /* use larger max-width for help popover, but not for help.html */
#help.popover {
max-width: 600px; max-width: 600px;
} }
#help-button .popover::before { #help.popover::before {
right: 48px; right: 48px;
} }
#help-button dt { #help dt {
float: left; float: left;
clear: left; clear: left;
display: block; display: block;
margin-right: 0.5rem; margin-right: 0.5rem;
} }
#help-button span.top, #help-button span.bottom { #help span.top, #help span.bottom {
text-align: center; text-align: center;
display: block; display: block;
font-size: 1.125rem; font-size: 1.125rem;
} }
#help-button span.top { #help span.top {
margin: 10px 0; margin: 10px 0;
border-bottom: 1px solid var(--border-color); border-bottom: 1px solid var(--border-color);
padding-bottom: 4px; padding-bottom: 4px;
margin-bottom: 6px; margin-bottom: 6px;
} }
#help-button span.bottom { #help span.bottom {
clear: both; clear: both;
border-top: 1px solid var(--border-color); border-top: 1px solid var(--border-color);
} }
@ -1433,7 +1434,7 @@ h3.variant {
outline: none; outline: none;
} }
#settings-menu > a, #help-button > button, #copy-path { #settings-menu > a, #help-button > a, #copy-path {
padding: 5px; padding: 5px;
width: 33px; width: 33px;
border: 1px solid var(--border-color); border: 1px solid var(--border-color);
@ -1442,7 +1443,7 @@ h3.variant {
line-height: 1.5; line-height: 1.5;
} }
#settings-menu > a, #help-button > button { #settings-menu > a, #help-button > a {
padding: 5px; padding: 5px;
height: 100%; height: 100%;
display: block; display: block;
@ -1490,7 +1491,7 @@ input:checked + .slider {
background-color: var(--settings-input-color); background-color: var(--settings-input-color);
} }
#help-button > button { #help-button > a {
text-align: center; text-align: center;
/* Rare exception to specifying font sizes in rem. Since this is acting /* Rare exception to specifying font sizes in rem. Since this is acting
as an icon, it's okay to specify their sizes in pixels. */ as an icon, it's okay to specify their sizes in pixels. */

View File

@ -248,7 +248,7 @@ kbd {
box-shadow: inset 0 -1px 0 #5c6773; box-shadow: inset 0 -1px 0 #5c6773;
} }
#settings-menu > a, #help-button > button { #settings-menu > a, #help-button > a {
color: #fff; color: #fff;
} }
@ -257,7 +257,7 @@ kbd {
} }
#settings-menu > a:hover, #settings-menu > a:focus, #settings-menu > a:hover, #settings-menu > a:focus,
#help-button > button:hover, #help-button > button:focus { #help-button > a:hover, #help-button > a:focus {
border-color: #e0e0e0; border-color: #e0e0e0;
} }

View File

@ -153,12 +153,12 @@ kbd {
box-shadow: inset 0 -1px 0 #c6cbd1; box-shadow: inset 0 -1px 0 #c6cbd1;
} }
#settings-menu > a, #help-button > button { #settings-menu > a, #help-button > a {
color: #000; color: #000;
} }
#settings-menu > a:hover, #settings-menu > a:focus, #settings-menu > a:hover, #settings-menu > a:focus,
#help-button > button:hover, #help-button > button:focus { #help-button > a:hover, #help-button > a:focus {
border-color: #ffb900; border-color: #ffb900;
} }

View File

@ -147,8 +147,12 @@ kbd {
box-shadow: inset 0 -1px 0 #c6cbd1; box-shadow: inset 0 -1px 0 #c6cbd1;
} }
#settings-menu > a, #help-button > a {
color: #000;
}
#settings-menu > a:hover, #settings-menu > a:focus, #settings-menu > a:hover, #settings-menu > a:focus,
#help-button > button:hover, #help-button > button:focus { #help-button > a:hover, #help-button > a:focus {
border-color: #717171; border-color: #717171;
} }

View File

@ -192,6 +192,8 @@ function loadCss(cssFileName) {
} }
(function() { (function() {
const isHelpPage = window.location.pathname.endsWith("/help.html");
function loadScript(url) { function loadScript(url) {
const script = document.createElement("script"); const script = document.createElement("script");
script.src = url; script.src = url;
@ -873,7 +875,10 @@ function loadCss(cssFileName) {
rustdoc_version.appendChild(rustdoc_version_code); rustdoc_version.appendChild(rustdoc_version_code);
const container = document.createElement("div"); const container = document.createElement("div");
if (!isHelpPage) {
container.className = "popover"; container.className = "popover";
}
container.id = "help";
container.style.display = "none"; container.style.display = "none";
const side_by_side = document.createElement("div"); const side_by_side = document.createElement("div");
@ -885,6 +890,12 @@ function loadCss(cssFileName) {
container.appendChild(side_by_side); container.appendChild(side_by_side);
container.appendChild(rustdoc_version); container.appendChild(rustdoc_version);
if (isHelpPage) {
const help_section = document.createElement("section");
help_section.appendChild(container);
document.getElementById("main-content").appendChild(help_section);
container.style.display = "block";
} else {
const help_button = getHelpButton(); const help_button = getHelpButton();
help_button.appendChild(container); help_button.appendChild(container);
@ -894,6 +905,7 @@ function loadCss(cssFileName) {
}; };
help_button.onblur = helpBlurHandler; help_button.onblur = helpBlurHandler;
help_button.children[0].onblur = helpBlurHandler; help_button.children[0].onblur = helpBlurHandler;
}
return container; return container;
} }
@ -934,11 +946,15 @@ function loadCss(cssFileName) {
} }
} }
document.querySelector(`#${HELP_BUTTON_ID} > button`).addEventListener("click", event => { if (isHelpPage) {
showHelp();
} else {
document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click", event => {
const target = event.target; const target = event.target;
if (target.tagName !== "BUTTON" || target.parentElement.id !== HELP_BUTTON_ID) { if (target.tagName !== "A" || target.parentElement.id !== HELP_BUTTON_ID) {
return; return;
} }
event.preventDefault();
const menu = getHelpMenu(true); const menu = getHelpMenu(true);
const shouldShowHelp = menu.style.display === "none"; const shouldShowHelp = menu.style.display === "none";
if (shouldShowHelp) { if (shouldShowHelp) {
@ -947,6 +963,7 @@ function loadCss(cssFileName) {
window.hidePopoverMenus(); window.hidePopoverMenus();
} }
}); });
}
setMobileTopbar(); setMobileTopbar();
addSidebarItems(); addSidebarItems();

View File

@ -122,7 +122,7 @@
placeholder="Click or press S to search, ? for more options…" {# -#} placeholder="Click or press S to search, ? for more options…" {# -#}
type="search"> {#- -#} type="search"> {#- -#}
<div id="help-button" title="help" tabindex="-1"> {#- -#} <div id="help-button" title="help" tabindex="-1"> {#- -#}
<button type="button">?</button> {#- -#} <a href="{{page.root_path|safe}}help.html">?</a> {#- -#}
</div> {#- -#} </div> {#- -#}
<div id="settings-menu" tabindex="-1"> {#- -#} <div id="settings-menu" tabindex="-1"> {#- -#}
<a href="{{page.root_path|safe}}settings.html" title="settings"> {#- -#} <a href="{{page.root_path|safe}}settings.html" title="settings"> {#- -#}

View File

@ -0,0 +1,24 @@
// This test ensures that opening the help page in its own tab works.
goto: "file://" + |DOC_PATH| + "/help.html"
size: (1000, 1000) // Try desktop size first.
wait-for: "#help"
assert-css: ("#help", {"display": "block"})
click: "#help-button > a"
assert-css: ("#help", {"display": "block"})
compare-elements-property: (".sub-container", "#help", ["offsetWidth"])
compare-elements-position: (".sub-container", "#help", ("x"))
size: (500, 1000) // Try mobile next.
assert-css: ("#help", {"display": "block"})
compare-elements-property: (".sub-container", "#help", ["offsetWidth"])
compare-elements-position: (".sub-container", "#help", ("x"))
// This test ensures that opening the help popover without switching pages works.
goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
size: (1000, 1000) // Only supported on desktop.
assert-false: "#help"
click: "#help-button > a"
assert-css: ("#help", {"display": "block"})
click: "#help-button > a"
assert-css: ("#help", {"display": "none"})
compare-elements-property-false: (".sub-container", "#help", ["offsetWidth"])
compare-elements-position-false: (".sub-container", "#help", ("x"))

View File

@ -33,7 +33,7 @@ assert-css: (
{"border-color": "rgb(197, 197, 197)"}, {"border-color": "rgb(197, 197, 197)"},
) )
assert-css: ( assert-css: (
"#help-button > button", "#help-button > a",
{ {
"color": "rgb(255, 255, 255)", "color": "rgb(255, 255, 255)",
"border-color": "rgb(92, 103, 115)", "border-color": "rgb(92, 103, 115)",
@ -47,7 +47,7 @@ assert-css: (
) )
// Only "border-color" should change. // Only "border-color" should change.
assert-css: ( assert-css: (
"#help-button:hover > button", "#help-button:hover > a",
{ {
"color": "rgb(255, 255, 255)", "color": "rgb(255, 255, 255)",
"border-color": "rgb(224, 224, 224)", "border-color": "rgb(224, 224, 224)",
@ -113,7 +113,7 @@ assert-css: (
{"border-color": "rgb(221, 221, 221)"}, {"border-color": "rgb(221, 221, 221)"},
) )
assert-css: ( assert-css: (
"#help-button > button", "#help-button > a",
{ {
"color": "rgb(0, 0, 0)", "color": "rgb(0, 0, 0)",
"border-color": "rgb(224, 224, 224)", "border-color": "rgb(224, 224, 224)",
@ -127,7 +127,7 @@ assert-css: (
) )
// Only "border-color" should change. // Only "border-color" should change.
assert-css: ( assert-css: (
"#help-button:hover > button", "#help-button:hover > a",
{ {
"color": "rgb(0, 0, 0)", "color": "rgb(0, 0, 0)",
"border-color": "rgb(255, 185, 0)", "border-color": "rgb(255, 185, 0)",
@ -193,7 +193,7 @@ assert-css: (
{"border-color": "rgb(0, 0, 0)"}, {"border-color": "rgb(0, 0, 0)"},
) )
assert-css: ( assert-css: (
"#help-button > button", "#help-button > a",
{ {
"color": "rgb(0, 0, 0)", "color": "rgb(0, 0, 0)",
"border-color": "rgb(224, 224, 224)", "border-color": "rgb(224, 224, 224)",
@ -207,7 +207,7 @@ assert-css: (
) )
// Only "border-color" should change. // Only "border-color" should change.
assert-css: ( assert-css: (
"#help-button:hover > button", "#help-button:hover > a",
{ {
"color": "rgb(0, 0, 0)", "color": "rgb(0, 0, 0)",
"border-color": "rgb(113, 113, 113)", "border-color": "rgb(113, 113, 113)",
@ -222,7 +222,7 @@ assert-css: (
assert-css: ( assert-css: (
"#settings-menu > a", "#settings-menu > a",
{ {
"color": "rgb(56, 115, 173)", "color": "rgb(0, 0, 0)",
"border-color": "rgb(224, 224, 224)", "border-color": "rgb(224, 224, 224)",
"background-color": "rgb(255, 255, 255)", "background-color": "rgb(255, 255, 255)",
}, },
@ -236,7 +236,7 @@ assert-css: (
assert-css: ( assert-css: (
"#settings-menu:hover > a", "#settings-menu:hover > a",
{ {
"color": "rgb(56, 115, 173)", "color": "rgb(0, 0, 0)",
"border-color": "rgb(113, 113, 113)", "border-color": "rgb(113, 113, 113)",
"background-color": "rgb(255, 255, 255)", "background-color": "rgb(255, 255, 255)",
}, },