diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index 551bb56685c..bbd427bbdd2 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -26,8 +26,11 @@ pub(crate) fn render(cx: &mut Context<'_>, krate: &clean::Crate) -> Result<(), E let dst = cx.dst.join("src").join(krate.name(cx.tcx()).as_str()); cx.shared.ensure_dir(&dst)?; + let crate_name = krate.name(cx.tcx()); + let crate_name = crate_name.as_str(); - let mut collector = SourceCollector { dst, cx, emitted_local_sources: FxHashSet::default() }; + let mut collector = + SourceCollector { dst, cx, emitted_local_sources: FxHashSet::default(), crate_name }; collector.visit_crate(krate); Ok(()) } @@ -115,6 +118,8 @@ struct SourceCollector<'a, 'tcx> { /// Root destination to place all HTML output into dst: PathBuf, emitted_local_sources: FxHashSet, + + crate_name: &'a str, } impl DocVisitor for SourceCollector<'_, '_> { @@ -210,6 +215,9 @@ fn emit_source( }, ); + let src_fname = p.file_name().expect("source has no filename").to_os_string(); + let mut fname = src_fname.clone(); + let root_path = PathBuf::from("../../").join(root_path.into_inner()); let mut root_path = root_path.to_string_lossy(); if let Some(c) = root_path.as_bytes().last() @@ -217,12 +225,12 @@ fn emit_source( { root_path += "/"; } + let mut file_path = Path::new(&self.crate_name).join(&*cur.borrow()); + file_path.push(&fname); + fname.push(".html"); let mut cur = self.dst.join(cur.into_inner()); shared.ensure_dir(&cur)?; - let src_fname = p.file_name().expect("source has no filename").to_os_string(); - let mut fname = src_fname.clone(); - fname.push(".html"); cur.push(&fname); let title = format!("{} - source", src_fname.to_string_lossy()); @@ -250,7 +258,7 @@ fn emit_source( cx, &root_path, highlight::DecorationInfo::default(), - SourceContext::Standalone, + SourceContext::Standalone { file_path }, ) }, &shared.style_files, @@ -313,10 +321,11 @@ struct ScrapedSource<'a, Code: std::fmt::Display> { struct Source { lines: RangeInclusive, code_html: Code, + file_path: Option<(String, String)>, } pub(crate) enum SourceContext<'a> { - Standalone, + Standalone { file_path: PathBuf }, Embedded(ScrapedInfo<'a>), } @@ -345,9 +354,19 @@ pub(crate) fn print_src( }); let lines = s.lines().count(); match source_context { - SourceContext::Standalone => { - Source { lines: (1..=lines), code_html: code }.render_into(&mut writer).unwrap() + SourceContext::Standalone { file_path } => Source { + lines: (1..=lines), + code_html: code, + file_path: if let Some(file_name) = file_path.file_name() + && let Some(file_path) = file_path.parent() + { + Some((file_path.display().to_string(), file_name.display().to_string())) + } else { + None + }, } + .render_into(&mut writer) + .unwrap(), SourceContext::Embedded(info) => { let lines = (1 + info.offset)..=(lines + info.offset); ScrapedSource { info, lines, code_html: code }.render_into(&mut writer).unwrap(); diff --git a/src/librustdoc/html/static/css/noscript.css b/src/librustdoc/html/static/css/noscript.css index e62b16267f1..477a79d63e9 100644 --- a/src/librustdoc/html/static/css/noscript.css +++ b/src/librustdoc/html/static/css/noscript.css @@ -61,6 +61,8 @@ nav.sub { --copy-path-img-hover-filter: invert(35%); --code-example-button-color: #7f7f7f; --code-example-button-hover-color: #595959; + --settings-menu-filter: invert(50%); + --settings-menu-hover-filter: invert(35%); --codeblock-error-hover-color: rgb(255, 0, 0); --codeblock-error-color: rgba(255, 0, 0, .5); --codeblock-ignore-hover-color: rgb(255, 142, 0); @@ -87,7 +89,6 @@ nav.sub { --search-tab-button-not-selected-background: #e6e6e6; --search-tab-button-selected-border-top-color: #0089ff; --search-tab-button-selected-background: #fff; - --settings-menu-filter: none; --stab-background-color: #fff5d6; --stab-code-color: #000; --code-highlight-kw-color: #8959a8; @@ -192,6 +193,8 @@ nav.sub { --search-tab-button-not-selected-background: #252525; --search-tab-button-selected-border-top-color: #0089ff; --search-tab-button-selected-background: #353535; + --settings-menu-filter: invert(50%); + --settings-menu-hover-filter: invert(65%); --stab-background-color: #314559; --stab-code-color: #e6e1cf; --code-highlight-kw-color: #ab8ac1; diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 38154dee3e2..2a9b4c95883 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -165,7 +165,7 @@ h1, h2, h3, h4 { .main-heading h1 { margin: 0; padding: 0; - flex-grow: 1; + grid-area: main-heading-h1; /* We use overflow-wrap: break-word for Safari, which doesn't recognize `anywhere`: https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-wrap */ overflow-wrap: break-word; @@ -174,8 +174,12 @@ h1, h2, h3, h4 { overflow-wrap: anywhere; } .main-heading { - display: flex; - flex-wrap: wrap; + position: relative; + display: grid; + grid-template-areas: + "main-heading-h1 main-heading-toolbar" + "main-heading-sub-heading main-heading-toolbar"; + grid-template-columns: 1fr max-content; padding-bottom: 6px; margin-bottom: 15px; } @@ -218,9 +222,10 @@ h1, h2, h3, h4, h5, h6, .search-results .result-name, .item-name > a, .out-of-band, +.sub-heading, span.since, a.src, -#help-button > a, +rustdoc-toolbar, summary.hideme, .scraped-example-list, /* This selector is for the items listed in the "all items" page. */ @@ -884,9 +889,19 @@ both the code example and the line numbers, so we need to remove the radius in t overflow-x: auto; } -.out-of-band { +.sub-heading { flex-grow: 0; font-size: 1.125rem; + grid-area: main-heading-sub-heading; +} + +.main-heading rustdoc-toolbar, .main-heading .out-of-band { + grid-area: main-heading-toolbar; +} +rustdoc-toolbar { + display: flex; + flex-direction: row; + flex-wrap: nowrap; } .docblock code, .docblock-short code, @@ -1282,10 +1297,16 @@ so that we can apply CSS-filters to change the arrow color in themes */ border-color: var(--settings-input-color) !important; } +#settings.popover { + --popover-arrow-offset: 118px; + top: 26px; +} + /* use larger max-width for help popover, but not for help.html */ #help.popover { max-width: 600px; - --popover-arrow-offset: 48px; + --popover-arrow-offset: 36px; + top: 26px; } #help dt { @@ -1293,10 +1314,15 @@ so that we can apply CSS-filters to change the arrow color in themes */ clear: left; margin-right: 0.5rem; } +#help dd { + margin-bottom: 0.5rem; +} #help span.top, #help span.bottom { text-align: center; display: block; font-size: 1.125rem; + padding: 0 0.5rem; + text-wrap-style: balance; } #help span.top { margin: 10px 0; @@ -1308,10 +1334,13 @@ so that we can apply CSS-filters to change the arrow color in themes */ clear: both; border-top: 1px solid var(--border-color); } +.side-by-side { + display: flex; + margin-bottom: 20px; +} .side-by-side > div { width: 50%; - float: left; - padding: 0 20px 20px 17px; + padding: 0 20px 0 17px; } .item-info .stab { @@ -1374,7 +1403,9 @@ so that we can apply CSS-filters to change the arrow color in themes */ } .rightside:not(a), -.out-of-band { +.out-of-band, +.sub-heading, +rustdoc-toolbar { color: var(--right-side-color); } @@ -1588,8 +1619,8 @@ instead, we check that it's not a "finger" cursor. display: block; } -.out-of-band > span.since { - font-size: 1.25rem; +.main-heading span.since::before { + content: "Since "; } .sub-variant h4 { @@ -1691,6 +1722,8 @@ a.tooltip:hover::after { } #search-tabs { + grid-area: main-heading-sub-heading; + margin-top: 0.25rem; display: flex; flex-direction: row; gap: 1px; @@ -1752,9 +1785,10 @@ a.tooltip:hover::after { border-bottom: 1px solid var(--border-color); } -#settings-menu, #help-button { +#settings-menu, #help-button, button#toggle-all-docs { margin-left: var(--button-left-margin); display: flex; + line-height: initial; } #sidebar-button { display: none; @@ -1778,33 +1812,35 @@ a.tooltip:hover::after { .hide-sidebar .src #sidebar-button { position: static; } -#settings-menu > a, #help-button > a, #sidebar-button > a { +#settings-menu > a, #help-button > a, #sidebar-button > a, button#toggle-all-docs { display: flex; align-items: center; justify-content: center; - background-color: var(--button-background-color); - border: 1px solid var(--border-color); + flex-direction: column; + border: 1px solid transparent; border-radius: var(--button-border-radius); - color: var(--settings-button-color); - /* Rare exception to specifying font sizes in rem. Since this is acting - as an icon, it's okay to specify their sizes in pixels. */ - font-size: 20px; + color: var(--main-color); +} +#settings-menu > a, #help-button > a, button#toggle-all-docs { + width: 80px; +} +#sidebar-button > a { + background-color: var(--button-background-color); + border-color: var(--border-color); width: 33px; } -#settings-menu > a:hover, #settings-menu > a:focus, -#help-button > a:hover, #help-button > a:focus, -#sidebar-button > a:hover, #sidebar-button > a:focus { +#settings-menu > a:hover, #settings-menu > a:focus-visible, +#help-button > a:hover, #help-button > a:focus-visible, +#sidebar-button > a:hover, #sidebar-button > a:focus-visible, +button#toggle-all-docs:hover, button#toggle-all-docs:focus-visible { border-color: var(--settings-button-border-focus); + text-decoration: none; } -#settings-menu > a { - line-height: 0; - font-size: 0; -} #settings-menu > a:before { /* Wheel */ - content: url('data:image/svg+xml,\ '); - width: 22px; - height: 22px; + width: 18px; + height: 18px; filter: var(--settings-menu-filter); } +button#toggle-all-docs:before { + /* Custom arrow icon */ + content: url('data:image/svg+xml,\ + '); + width: 18px; + height: 18px; + filter: var(--settings-menu-filter); +} + +#help-button > a:before { + /* Question mark with circle */ + content: url('data:image/svg+xml,\ + \ + ?'); + width: 18px; + height: 18px; + filter: var(--settings-menu-filter); +} + +button#toggle-all-docs:before, +#help-button > a:before, +#settings-menu > a:before { + filter: var(--settings-menu-filter); + margin: 8px; +} + +@media not (pointer: coarse) { + button#toggle-all-docs:hover:before, + #help-button > a:hover:before, + #settings-menu > a:hover:before { + filter: var(--settings-menu-hover-filter); + } +} + +rustdoc-toolbar span.label { + font-size: initial; + font-variant-caps: small-caps; + text-transform: lowercase; + flex-grow: 1; +} + #sidebar-button > a:before { /* sidebar resizer image */ content: url('data:image/svg+xml,\ - \ + \ \ '); width: 22px; @@ -1941,10 +2020,10 @@ details.toggle > summary.hideme > span { } details.toggle > summary::before { - /* toggle plus */ - background: url('data:image/svg+xml,') no-repeat top left; + /* arrow pointing left */ + background: url('data:image/svg+xml,\ + '); content: ""; cursor: pointer; width: 16px; @@ -2027,10 +2106,10 @@ details.toggle[open] > summary.hideme > span { } details.toggle[open] > summary::before { - /* toggle minus */ - background: url('data:image/svg+xml,') no-repeat top left; + /* arrow pointing down */ + background: url('data:image/svg+xml,\ + '); } details.toggle[open] > summary::after { @@ -2076,6 +2155,15 @@ However, it's not needed with smaller screen width because the doc/code block is opacity: 0.75; } +/* help button is mostly for search */ +#help-button:not(.help-open), +#alternative-display #toggle-all-docs { + display: none; +} +#alternative-display #help-button { + display: flex; +} + /* Media Queries */ /* Make sure all the buttons line wrap at the same time */ @@ -2083,6 +2171,12 @@ However, it's not needed with smaller screen width because the doc/code block is #search-tabs .count { display: block; } + .side-by-side { + flex-direction: column-reverse; + } + .side-by-side > div { + width: auto; + } } /* @@ -2099,6 +2193,27 @@ in src-script.js and main.js scroll-margin-top: 45px; } + /* We don't display this button on mobile devices. */ + #copy-path { + display: none; + } + + /* Text label takes up too much space at this size. */ + rustdoc-toolbar span.label { + display: none; + } + #settings-menu > a, #help-button > a, button#toggle-all-docs { + width: 33px; + } + #settings.popover { + --popover-arrow-offset: 48px; + top: calc(100% - 8px); + } + #help.popover { + --popover-arrow-offset: 12px; + top: calc(100% - 8px); + } + .rustdoc { /* Sidebar should overlay main content, rather than pushing main content to the right. Turn off `display: flex` on the body element. */ @@ -2110,20 +2225,6 @@ in src-script.js and main.js padding-top: 0px; } - .main-heading { - flex-direction: column; - } - - .out-of-band { - text-align: left; - margin-left: initial; - padding: initial; - } - - .out-of-band .since::before { - content: "Since "; - } - /* Hide the logo and item name from the sidebar. Those are displayed in the mobile-topbar instead. */ .sidebar .logo-container, @@ -2227,16 +2328,11 @@ in src-script.js and main.js left: -11px; } - /* We don't display these buttons on mobile devices. */ - #copy-path, #help-button { - display: none; - } - /* sidebar button becomes topbar button */ #sidebar-button > a:before { content: url('data:image/svg+xml,\ - \ + \ \ '); width: 22px; @@ -2536,6 +2632,8 @@ by default. --copy-path-img-hover-filter: invert(35%); --code-example-button-color: #7f7f7f; --code-example-button-hover-color: #595959; + --settings-menu-filter: invert(50%); + --settings-menu-hover-filter: invert(35%); --codeblock-error-hover-color: rgb(255, 0, 0); --codeblock-error-color: rgba(255, 0, 0, .5); --codeblock-ignore-hover-color: rgb(255, 142, 0); @@ -2562,7 +2660,6 @@ by default. --search-tab-button-not-selected-background: #e6e6e6; --search-tab-button-selected-border-top-color: #0089ff; --search-tab-button-selected-background: #fff; - --settings-menu-filter: none; --stab-background-color: #fff5d6; --stab-code-color: #000; --code-highlight-kw-color: #8959a8; @@ -2666,7 +2763,8 @@ by default. --search-tab-button-not-selected-background: #252525; --search-tab-button-selected-border-top-color: #0089ff; --search-tab-button-selected-background: #353535; - --settings-menu-filter: none; + --settings-menu-filter: invert(50%); + --settings-menu-hover-filter: invert(65%); --stab-background-color: #314559; --stab-code-color: #e6e1cf; --code-highlight-kw-color: #ab8ac1; @@ -2777,7 +2875,8 @@ Original by Dempfi (https://github.com/dempfi/ayu) --search-tab-button-not-selected-background: transparent !important; --search-tab-button-selected-border-top-color: none; --search-tab-button-selected-background: #141920 !important; - --settings-menu-filter: invert(100%); + --settings-menu-filter: invert(70%); + --settings-menu-hover-filter: invert(100%); --stab-background-color: #314559; --stab-code-color: #e6e1cf; --code-highlight-kw-color: #ff7733; diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 858753a1917..53326f0fcad 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -22,14 +22,14 @@ function hideMain() { } function showMain() { - removeClass(document.getElementById(MAIN_ID), "hidden"); -} - -function blurHandler(event, parentElem, hideCallback) { - if (!parentElem.contains(document.activeElement) && - !parentElem.contains(event.relatedTarget) - ) { - hideCallback(); + const main = document.getElementById(MAIN_ID); + removeClass(main, "hidden"); + const mainHeading = main.querySelector(".main-heading"); + if (mainHeading && searchState.rustdocToolbar) { + if (searchState.rustdocToolbar.parentElement) { + searchState.rustdocToolbar.parentElement.removeChild(searchState.rustdocToolbar); + } + mainHeading.appendChild(searchState.rustdocToolbar); } } @@ -167,6 +167,14 @@ function switchDisplayedElement(elemToDisplay) { el.appendChild(elemToDisplay); hideMain(); removeClass(el, "hidden"); + + const mainHeading = elemToDisplay.querySelector(".main-heading"); + if (mainHeading && searchState.rustdocToolbar) { + if (searchState.rustdocToolbar.parentElement) { + searchState.rustdocToolbar.parentElement.removeChild(searchState.rustdocToolbar); + } + mainHeading.appendChild(searchState.rustdocToolbar); + } } function browserSupportsHistoryApi() { @@ -194,33 +202,36 @@ function preLoadCss(cssUrl) { document.head.append(script); } - getSettingsButton().onclick = event => { - if (event.ctrlKey || event.altKey || event.metaKey) { - return; - } - window.hideAllModals(false); - addClass(getSettingsButton(), "rotate"); - event.preventDefault(); - // Sending request for the CSS and the JS files at the same time so it will - // hopefully be loaded when the JS will generate the settings content. - loadScript(getVar("static-root-path") + getVar("settings-js")); - // Pre-load all theme CSS files, so that switching feels seamless. - // - // When loading settings.html as a standalone page, the equivalent HTML is - // generated in context.rs. - setTimeout(() => { - const themes = getVar("themes").split(","); - for (const theme of themes) { - // if there are no themes, do nothing - // "".split(",") == [""] - if (theme !== "") { - preLoadCss(getVar("root-path") + theme + ".css"); - } + if (getSettingsButton()) { + getSettingsButton().onclick = event => { + if (event.ctrlKey || event.altKey || event.metaKey) { + return; } - }, 0); - }; + window.hideAllModals(false); + addClass(getSettingsButton(), "rotate"); + event.preventDefault(); + // Sending request for the CSS and the JS files at the same time so it will + // hopefully be loaded when the JS will generate the settings content. + loadScript(getVar("static-root-path") + getVar("settings-js")); + // Pre-load all theme CSS files, so that switching feels seamless. + // + // When loading settings.html as a standalone page, the equivalent HTML is + // generated in context.rs. + setTimeout(() => { + const themes = getVar("themes").split(","); + for (const theme of themes) { + // if there are no themes, do nothing + // "".split(",") == [""] + if (theme !== "") { + preLoadCss(getVar("root-path") + theme + ".css"); + } + } + }, 0); + }; + } window.searchState = { + rustdocToolbar: document.querySelector("rustdoc-toolbar"), loadingText: "Loading search results...", input: document.getElementsByClassName("search-input")[0], outputElement: () => { @@ -919,8 +930,7 @@ function preLoadCss(cssUrl) { e.open = true; } }); - innerToggle.title = "collapse all docs"; - innerToggle.children[0].innerText = "\u2212"; // "\u2212" is "−" minus sign + innerToggle.children[0].innerText = "Summary"; } function collapseAllDocs() { @@ -934,8 +944,7 @@ function preLoadCss(cssUrl) { e.open = false; } }); - innerToggle.title = "expand all docs"; - innerToggle.children[0].innerText = "+"; + innerToggle.children[0].innerText = "Show all"; } function toggleAllDocs() { @@ -1328,7 +1337,13 @@ function preLoadCss(cssUrl) { } function helpBlurHandler(event) { - blurHandler(event, getHelpButton(), window.hidePopoverMenus); + if (!getHelpButton().contains(document.activeElement) && + !getHelpButton().contains(event.relatedTarget) && + !getSettingsButton().contains(document.activeElement) && + !getSettingsButton().contains(event.relatedTarget) + ) { + window.hidePopoverMenus(); + } } function buildHelpMenu() { @@ -1431,9 +1446,13 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm * Hide all the popover menus. */ window.hidePopoverMenus = () => { - onEachLazy(document.querySelectorAll(".search-form .popover"), elem => { + onEachLazy(document.querySelectorAll("rustdoc-toolbar .popover"), elem => { elem.style.display = "none"; }); + const button = getHelpButton(); + if (button) { + removeClass(button, "help-open"); + } }; /** @@ -1458,7 +1477,9 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm function showHelp() { // Prevent `blur` events from being dispatched as a result of closing // other modals. - getHelpButton().querySelector("a").focus(); + const button = getHelpButton(); + addClass(button, "help-open"); + button.querySelector("a").focus(); const menu = getHelpMenu(true); if (menu.style.display === "none") { window.hideAllModals(); @@ -1466,28 +1487,15 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm } } + const helpLink = document.querySelector(`#${HELP_BUTTON_ID} > a`); if (isHelpPage) { - showHelp(); - document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click", event => { - // Already on the help page, make help button a no-op. - const target = event.target; - if (target.tagName !== "A" || - target.parentElement.id !== HELP_BUTTON_ID || - event.ctrlKey || - event.altKey || - event.metaKey) { - return; - } - event.preventDefault(); - }); - } else { - document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click", event => { + buildHelpMenu(); + } else if (helpLink) { + helpLink.addEventListener("click", event => { // By default, have help button open docs in a popover. // If user clicks with a moderator, though, use default browser behavior, // probably opening in a new window or tab. - const target = event.target; - if (target.tagName !== "A" || - target.parentElement.id !== HELP_BUTTON_ID || + if (!helpLink.contains(helpLink) || event.ctrlKey || event.altKey || event.metaKey) { diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 4da0bbc787d..15b1046a27c 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -3605,7 +3605,8 @@ async function showResults(results, go_to_first, filterCrates) { crates += ""; } - let output = `

Results${crates}

`; + let output = `
\ +

Results${crates}

`; if (results.query.error !== null) { const error = results.query.error; error.forEach((value, index) => { @@ -3662,6 +3663,9 @@ async function showResults(results, go_to_first, filterCrates) { resultsElem.appendChild(ret_returned[0]); search.innerHTML = output; + if (searchState.rustdocToolbar) { + search.querySelector(".main-heading").appendChild(searchState.rustdocToolbar); + } const crateSearch = document.getElementById("crate-search"); if (crateSearch) { crateSearch.addEventListener("input", updateCrate); diff --git a/src/librustdoc/html/static/js/settings.js b/src/librustdoc/html/static/js/settings.js index c52a19ef987..183663b94fc 100644 --- a/src/librustdoc/html/static/js/settings.js +++ b/src/librustdoc/html/static/js/settings.js @@ -1,7 +1,7 @@ // Local js definitions: /* global getSettingValue, updateLocalStorage, updateTheme */ -/* global addClass, removeClass, onEach, onEachLazy, blurHandler */ -/* global MAIN_ID, getVar, getSettingsButton */ +/* global addClass, removeClass, onEach, onEachLazy */ +/* global MAIN_ID, getVar, getSettingsButton, getHelpButton */ "use strict"; @@ -267,15 +267,16 @@ } function settingsBlurHandler(event) { - blurHandler(event, getSettingsButton(), window.hidePopoverMenus); + if (!getHelpButton().contains(document.activeElement) && + !getHelpButton().contains(event.relatedTarget) && + !getSettingsButton().contains(document.activeElement) && + !getSettingsButton().contains(event.relatedTarget) + ) { + window.hidePopoverMenus(); + } } - if (isSettingsPage) { - // We replace the existing "onclick" callback to do nothing if clicked. - getSettingsButton().onclick = event => { - event.preventDefault(); - }; - } else { + if (!isSettingsPage) { // We replace the existing "onclick" callback. const settingsButton = getSettingsButton(); const settingsMenu = document.getElementById("settings"); diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js index d75fb7a7fb5..344743c87ed 100644 --- a/src/librustdoc/html/static/js/storage.js +++ b/src/librustdoc/html/static/js/storage.js @@ -274,16 +274,29 @@ class RustdocSearchElement extends HTMLElement { spellcheck="false" placeholder="Type ‘S’ or ‘/’ to search, ‘?’ for more options…" type="search"> -
- ? -
- `; } } window.customElements.define("rustdoc-search", RustdocSearchElement); +class RustdocToolbarElement extends HTMLElement { + constructor() { + super(); + } + connectedCallback() { + // Avoid replacing the children after they're already here. + if (this.firstElementChild) { + return; + } + const rootPath = getVar("root-path"); + this.innerHTML = ` +
+ Settings +
+ +
+ Help +
`; + } +} +window.customElements.define("rustdoc-toolbar", RustdocToolbarElement); diff --git a/src/librustdoc/html/templates/print_item.html b/src/librustdoc/html/templates/print_item.html index 76e770453b6..1b8c8293088 100644 --- a/src/librustdoc/html/templates/print_item.html +++ b/src/librustdoc/html/templates/print_item.html @@ -10,17 +10,16 @@ Copy item path {# #} {# #} {# #} - + + {% if !stability_since_raw.is_empty() %} - {{ stability_since_raw|safe +}} · {#+ #} + {{ stability_since_raw|safe +}} {% endif %} {% match src_href %} {% when Some with (href) %} - source · {#+ #} + {% if !stability_since_raw.is_empty() +%} · {%+ endif %} + source {#+ #} {% else %} {% endmatch %} - {# #} - {# #} + {# #} diff --git a/src/librustdoc/html/templates/source.html b/src/librustdoc/html/templates/source.html index 60a47f1b5de..9daa0cf8ff6 100644 --- a/src/librustdoc/html/templates/source.html +++ b/src/librustdoc/html/templates/source.html @@ -1,4 +1,15 @@ -
+{% match file_path %} +{% when Some with ((path, name)) %} +
{# #} +

{# #} +
{{path}}/
+ {{name}} +

{# #} + {# #} +
+{% else %} +{% endmatch %} +
{# #} {# https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag#data-nosnippet-attr Do not show "1 2 3 4 5 ..." in web search results. #}
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 6649e1721a4..5f303d96c40 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -10,6 +10,7 @@
 #![feature(iter_intersperse)]
 #![feature(let_chains)]
 #![feature(never_type)]
+#![feature(os_str_display)]
 #![feature(round_char_boundary)]
 #![feature(test)]
 #![feature(type_alias_impl_trait)]
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index c18f569e528..d24dd334a34 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -2739,7 +2739,7 @@ fn compare_to_default_rustdoc(&mut self, out_dir: &Path) {
 
         #[rustfmt::skip]
         let tidy_args = [
-            "--new-blocklevel-tags", "rustdoc-search",
+            "--new-blocklevel-tags", "rustdoc-search,rustdoc-toolbar",
             "--indent", "yes",
             "--indent-spaces", "2",
             "--wrap", "0",
diff --git a/src/tools/html-checker/main.rs b/src/tools/html-checker/main.rs
index ecfbb1955e7..5cdc4d53ab5 100644
--- a/src/tools/html-checker/main.rs
+++ b/src/tools/html-checker/main.rs
@@ -31,7 +31,7 @@ fn check_html_file(file: &Path) -> usize {
         .arg("--mute-id") // this option is useful in case we want to mute more warnings
         .arg("yes")
         .arg("--new-blocklevel-tags")
-        .arg("rustdoc-search") // custom elements
+        .arg("rustdoc-search,rustdoc-toolbar") // custom elements
         .arg("--mute")
         .arg(&to_mute_s)
         .arg(file);
diff --git a/tests/rustdoc-gui/help-page.goml b/tests/rustdoc-gui/help-page.goml
index f1a2675128c..6d6e353ae36 100644
--- a/tests/rustdoc-gui/help-page.goml
+++ b/tests/rustdoc-gui/help-page.goml
@@ -4,7 +4,7 @@ set-window-size: (1000, 1000) // Try desktop size first.
 wait-for: "#help"
 assert-css: ("#help", {"display": "block"})
 assert-css: ("#help dd", {"font-size": "16px"})
-click: "#help-button > a"
+assert-false: "#help-button > a"
 assert-css: ("#help", {"display": "block"})
 compare-elements-property: (".sub", "#help", ["offsetWidth"])
 compare-elements-position: (".sub", "#help", ["x"])
@@ -50,7 +50,8 @@ call-function: ("check-colors", {
 })
 
 // This test ensures that opening the help popover without switching pages works.
-go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
+go-to: "file://" + |DOC_PATH| + "/test_docs/index.html?search=a"
+wait-for: "#search-tabs" // Waiting for the search.js to load.
 set-window-size: (1000, 1000) // Only supported on desktop.
 assert-false: "#help"
 click: "#help-button > a"
@@ -62,7 +63,8 @@ compare-elements-property-false: (".sub", "#help", ["offsetWidth"])
 compare-elements-position-false: (".sub", "#help", ["x"])
 
 // This test ensures that the "the rustdoc book" anchor link within the help popover works.
-go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
+go-to: "file://" + |DOC_PATH| + "/test_docs/index.html?search=a"
+wait-for: "#search-tabs" // Waiting for the search.js to load.
 set-window-size: (1000, 1000) // Popover only appears when the screen width is >700px.
 assert-false: "#help"
 click: "#help-button > a"
diff --git a/tests/rustdoc-gui/item-info.goml b/tests/rustdoc-gui/item-info.goml
index 7a0194c6cc1..debda8d06c2 100644
--- a/tests/rustdoc-gui/item-info.goml
+++ b/tests/rustdoc-gui/item-info.goml
@@ -20,7 +20,7 @@ store-position: (
     {"x": second_line_x, "y": second_line_y},
 )
 assert: |first_line_x| != |second_line_x| && |first_line_x| == 516 && |second_line_x| == 272
-assert: |first_line_y| != |second_line_y| && |first_line_y| == 688 && |second_line_y| == 711
+assert: |first_line_y| != |second_line_y| && |first_line_y| == 715 && |second_line_y| == 738
 
 // Now we ensure that they're not rendered on the same line.
 set-window-size: (1100, 800)
diff --git a/tests/rustdoc-gui/mobile.goml b/tests/rustdoc-gui/mobile.goml
index e576385cd53..a9eee53dd1d 100644
--- a/tests/rustdoc-gui/mobile.goml
+++ b/tests/rustdoc-gui/mobile.goml
@@ -5,23 +5,8 @@ set-window-size: (400, 600)
 set-font-size: 18
 wait-for: 100 // wait a bit for the resize and the font-size change to be fully taken into account.
 
-// The out-of-band info (source, stable version, collapse) should be below the
-// h1 when the screen gets narrow enough.
-assert-css: (".main-heading", {
-  "display": "flex",
-  "flex-direction": "column"
-})
-
 assert-property: (".mobile-topbar h2", {"offsetHeight": 33})
 
-// Note: We can't use assert-text here because the 'Since' is set by CSS and
-// is therefore not part of the DOM.
-assert-css: (".content .out-of-band .since::before", { "content": "\"Since \"" })
-
-set-window-size: (1000, 1000)
-wait-for: 100 // wait a bit for the resize to be fully taken into account.
-assert-css-false: (".content .out-of-band .since::before", { "content": "\"Since \"" })
-
 // On the settings page, the theme buttons should not line-wrap. Instead, they should
 // all be placed as a group on a line below the setting name "Theme."
 go-to: "file://" + |DOC_PATH| + "/settings.html"
diff --git a/tests/rustdoc-gui/notable-trait.goml b/tests/rustdoc-gui/notable-trait.goml
index e2a8a43007e..b8fa26b17f6 100644
--- a/tests/rustdoc-gui/notable-trait.goml
+++ b/tests/rustdoc-gui/notable-trait.goml
@@ -248,12 +248,13 @@ click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']"
 assert-count: ("//*[@class='tooltip popover']", 1)
 assert-false: "//*[@class='sidebar shown']"
 
-// Also check the focus handling for the help button.
+// Also check the focus handling for the settings button.
 set-window-size: (1100, 600)
 reload:
 assert-count: ("//*[@class='tooltip popover']", 0)
 click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']"
 assert-count: ("//*[@class='tooltip popover']", 1)
-click: "#help-button a"
+click: "#settings-menu a"
+wait-for: "#settings"
 assert-count: ("//*[@class='tooltip popover']", 0)
 assert-false: "#method\.create_an_iterator_from_read .tooltip:focus"
diff --git a/tests/rustdoc-gui/pocket-menu.goml b/tests/rustdoc-gui/pocket-menu.goml
index ec31f492abe..4a062fec751 100644
--- a/tests/rustdoc-gui/pocket-menu.goml
+++ b/tests/rustdoc-gui/pocket-menu.goml
@@ -1,6 +1,7 @@
 // This test ensures that the "pocket menus" are working as expected.
 include: "utils.goml"
-go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
+go-to: "file://" + |DOC_PATH| + "/test_docs/index.html?search=test"
+wait-for: "#crate-search"
 // First we check that the help menu doesn't exist yet.
 assert-false: "#help-button .popover"
 // Then we display the help menu.
diff --git a/tests/rustdoc-gui/scrape-examples-layout.goml b/tests/rustdoc-gui/scrape-examples-layout.goml
index 6bea352bce4..55187a3e596 100644
--- a/tests/rustdoc-gui/scrape-examples-layout.goml
+++ b/tests/rustdoc-gui/scrape-examples-layout.goml
@@ -72,8 +72,8 @@ click: ".scraped-example .button-holder .expand"
 store-value: (offset_y, 4)
 
 // First with desktop
-assert-position: (".scraped-example", {"y": 226})
-assert-position: (".scraped-example .prev", {"y": 226 + |offset_y|})
+assert-position: (".scraped-example", {"y": 253})
+assert-position: (".scraped-example .prev", {"y": 253 + |offset_y|})
 
 // Gradient background should be at the top of the code block.
 assert-css: (".scraped-example .example-wrap::before", {"top": "0px"})
diff --git a/tests/rustdoc-gui/search-form-elements.goml b/tests/rustdoc-gui/search-form-elements.goml
index 63d2ceb3e7c..efe39f7a9d1 100644
--- a/tests/rustdoc-gui/search-form-elements.goml
+++ b/tests/rustdoc-gui/search-form-elements.goml
@@ -1,13 +1,14 @@
 // This test ensures that the elements in ".search-form" have the expected display.
 include: "utils.goml"
-go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
+go-to: "file://" + |DOC_PATH| + "/test_docs/index.html?search=test"
+wait-for: "#search-tabs" // Waiting for the search.js to load.
 show-text: true
 
 define-function: (
     "check-search-colors",
     [
         theme, border, background, search_input_color, search_input_border_focus,
-        menu_button_border, menu_button_a_color, menu_button_a_border_hover, menu_a_color,
+        menu_button_a_color, menu_button_a_border_hover, menu_a_color,
     ],
     block {
         call-function: ("switch-theme", {"theme": |theme|})
@@ -29,30 +30,22 @@ define-function: (
                 "color": |search_input_color|,
             },
         )
-        assert-css: (
-            "#help-button",
-            {"border-color": |menu_button_border|},
-        )
         assert-css: (
             "#help-button > a",
             {
                 "color": |menu_button_a_color|,
-                "border-color": |border|,
-                "background-color": |background|,
+                "border-color": "transparent",
+                "background-color": "transparent",
             },
         )
         // Hover help button.
         move-cursor-to: "#help-button"
-        assert-css: (
-            "#help-button:hover",
-            {"border-color": |menu_button_border|},
-        )
         assert-css: (
             "#help-button > a",
             {
                 "color": |menu_button_a_color|,
                 "border-color": |menu_button_a_border_hover|,
-                "background-color": |background|,
+                "background-color": "transparent",
             },
         )
         // Link color inside
@@ -63,30 +56,22 @@ define-function: (
                 "color": |menu_a_color|,
             },
         )
-        assert-css: (
-            "#settings-menu",
-            {"border-color": |menu_button_border|},
-        )
         assert-css: (
             "#settings-menu > a",
             {
                 "color": |menu_button_a_color|,
-                "border-color": |border|,
-                "background-color": |background|,
+                "border-color": "transparent",
+                "background-color": "transparent",
             },
         )
         // Hover settings menu.
         move-cursor-to: "#settings-menu"
-        assert-css: (
-            "#settings-menu:hover",
-            {"border-color": |menu_button_border|},
-        )
         assert-css: (
             "#settings-menu:hover > a",
             {
                 "color": |menu_button_a_color|,
                 "border-color": |menu_button_a_border_hover|,
-                "background-color": |background|,
+                "background-color": "transparent",
             },
         )
     },
@@ -100,8 +85,7 @@ call-function: (
         "background": "#141920",
         "search_input_color": "#fff",
         "search_input_border_focus": "#5c6773",
-        "menu_button_border": "#c5c5c5",
-        "menu_button_a_color": "#fff",
+        "menu_button_a_color": "#c5c5c5",
         "menu_button_a_border_hover": "#e0e0e0",
         "menu_a_color": "#39afd7",
     }
@@ -114,8 +98,7 @@ call-function: (
         "background": "#f0f0f0",
         "search_input_color": "#111",
         "search_input_border_focus": "#008dfd",
-        "menu_button_border": "#ddd",
-        "menu_button_a_color": "#000",
+        "menu_button_a_color": "#ddd",
         "menu_button_a_border_hover": "#ffb900",
         "menu_a_color": "#d2991d",
     }
@@ -128,7 +111,6 @@ call-function: (
         "background": "#fff",
         "search_input_color": "#000",
         "search_input_border_focus": "#66afe9",
-        "menu_button_border": "#000",
         "menu_button_a_color": "#000",
         "menu_button_a_border_hover": "#717171",
         "menu_a_color": "#3873ad",
diff --git a/tests/rustdoc-gui/search-result-display.goml b/tests/rustdoc-gui/search-result-display.goml
index 3ca46f3c569..c69ca59d44a 100644
--- a/tests/rustdoc-gui/search-result-display.goml
+++ b/tests/rustdoc-gui/search-result-display.goml
@@ -51,7 +51,10 @@ set-window-size: (900, 900)
 
 // First we check the current width, height and position.
 assert-css: ("#crate-search", {"width": "223px"})
-assert-css: (".search-results-title", {"height": "50px", "width": "640px"})
+store-size: (".search-results-title", {
+    "height": search_results_title_height,
+    "width": search_results_title_width,
+})
 assert-css: ("#search", {"width": "640px"})
 
 // Then we update the text of one of the `