Skip to content

Commit

Permalink
rustdoc: use a button instead of a bar for search
Browse files Browse the repository at this point in the history
This is a response to complaints that the header area takes up
too much vertical space, forcing the user to scroll more than
they ought to need. It also adds a reasonable way to pick the
crate name before actually searching, which was also a feature
that people ask for.
  • Loading branch information
notriddle committed Nov 21, 2024
1 parent bfe809d commit cf1e854
Show file tree
Hide file tree
Showing 5 changed files with 222 additions and 120 deletions.
90 changes: 54 additions & 36 deletions src/librustdoc/html/static/css/rustdoc.css
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@ h1, h2, h3, h4 {
more aggressively when we want them to. */
overflow-wrap: anywhere;
}
.search-results-main-heading nav.sub {
grid-area: main-heading-h1;
}
.main-heading {
position: relative;
display: grid;
Expand All @@ -195,6 +198,16 @@ h1, h2, h3, h4 {
align-items: end;
padding-top: 5px;
}
.search-switcher {
grid-area: main-heading-breadcrumbs;
line-height: 1.25;
display: flex;
flex-wrap: wrap;
color: var(--main-color);
align-items: baseline;
white-space: nowrap;
margin-top: -1px;
}
.rustdoc-breadcrumbs a {
padding: 4px 0;
margin: -4px 0;
Expand Down Expand Up @@ -249,6 +262,7 @@ rustdoc-toolbar,
summary.hideme,
.scraped-example-list,
.rustdoc-breadcrumbs,
.search-switcher,
/* This selector is for the items listed in the "all items" page. */
ul.all-items {
font-family: "Fira Sans", Arial, NanumBarunGothic, sans-serif;
Expand Down Expand Up @@ -996,16 +1010,15 @@ div.where {
nav.sub {
flex-grow: 1;
flex-flow: row nowrap;
margin: 4px 0 0 0;
display: flex;
align-items: center;
align-items: start;
margin-top: 4px;
}
.search-form {
position: relative;
display: flex;
height: 34px;
flex-grow: 1;
margin-bottom: 4px;
}
.src nav.sub {
margin: 0 0 -10px 0;
Expand Down Expand Up @@ -1109,21 +1122,6 @@ table,
padding-right: 1.25rem;
}

.search-results-title {
margin-top: 0;
white-space: nowrap;
/* flex layout allows shrinking the <select> appropriately if it becomes too large */
display: flex;
/* make things look like in a line, despite the fact that we're using a layout
with boxes (i.e. from the flex layout) */
align-items: baseline;
}
.search-results-title + .sub-heading {
color: var(--main-color);
display: flex;
align-items: baseline;
white-space: nowrap;
}
#crate-search-div {
/* ensures that 100% in properties of #crate-search-div:after
are relative to the size of this div */
Expand Down Expand Up @@ -1848,7 +1846,7 @@ a.tooltip:hover::after {
border-bottom: 1px solid var(--border-color);
}

#settings-menu, #help-button, button#toggle-all-docs {
#search-button, #settings-menu, #help-button, button#toggle-all-docs {
margin-left: var(--button-left-margin);
display: flex;
line-height: 1.25;
Expand Down Expand Up @@ -1876,7 +1874,11 @@ a.tooltip:hover::after {
.hide-sidebar .src #sidebar-button {
position: static;
}
#settings-menu > a, #help-button > a, #sidebar-button > a, button#toggle-all-docs {
#search-button > a,
#settings-menu > a,
#help-button > a,
#sidebar-button > a,
button#toggle-all-docs {
display: flex;
align-items: center;
justify-content: center;
Expand All @@ -1885,11 +1887,11 @@ a.tooltip:hover::after {
border-radius: var(--button-border-radius);
color: var(--main-color);
}
#settings-menu > a, #help-button > a, button#toggle-all-docs {
#search-button > a, #settings-menu > a, #help-button > a, button#toggle-all-docs {
width: 80px;
border-radius: var(--toolbar-button-border-radius);
}
#settings-menu > a, #help-button > a {
#search-button > a, #settings-menu > a, #help-button > a {
min-width: 0;
}
#sidebar-button > a {
Expand All @@ -1898,6 +1900,7 @@ a.tooltip:hover::after {
width: 33px;
}

#search-button > a:hover, #search-button > a:focus-visible,
#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,
Expand All @@ -1906,6 +1909,19 @@ button#toggle-all-docs:hover, button#toggle-all-docs:focus-visible {
text-decoration: none;
}

#search-button > a:before {
/* Magnifying glass */
content: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" \
width="18" height="18" viewBox="0 0 16 16">\
<circle r="5" cy="7" cx="6" style="fill:none;stroke:currentColor;stroke-width:3"></circle>\
<path d="M 16,15 10,10" style="fill:none;stroke:currentColor;stroke-width:4"></path>\
<desc>Search</desc>\
</svg>');
width: 18px;
height: 18px;
filter: var(--settings-menu-filter);
}

#settings-menu > a:before {
/* Wheel <https://www.svgrepo.com/svg/384069/settings-cog-gear> */
content: url('data:image/svg+xml,<svg width="18" height="18" viewBox="0 0 12 12" \
Expand Down Expand Up @@ -1948,6 +1964,7 @@ button#toggle-all-docs:before {
filter: var(--settings-menu-filter);
}

#search-button > a:before,
button#toggle-all-docs:before,
#help-button > a:before,
#settings-menu > a:before {
Expand All @@ -1956,6 +1973,7 @@ button#toggle-all-docs:before,
}

@media not (pointer: coarse) {
#search-button > a:hover:before,
button#toggle-all-docs:hover:before,
#help-button > a:hover:before,
#settings-menu > a:hover:before {
Expand Down Expand Up @@ -2247,6 +2265,20 @@ However, it's not needed with smaller screen width because the doc/code block is
.side-by-side > div {
width: auto;
}

/* Text label takes up too much space at this size. */
rustdoc-toolbar span.label {
display: none;
}
#search-button > a, #settings-menu > a, #help-button > a, button#toggle-all-docs {
width: 33px;
}
#settings.popover {
--popover-arrow-offset: 86px;
}
#help.popover {
--popover-arrow-offset: 48px;
}
}

/*
Expand All @@ -2273,20 +2305,6 @@ in src-script.js and main.js
visibility: hidden;
}

/* 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: 86px;
}
#help.popover {
--popover-arrow-offset: 48px;
}

.rustdoc {
/* Sidebar should overlay main content, rather than pushing main content to the right.
Turn off `display: flex` on the body element. */
Expand Down
91 changes: 75 additions & 16 deletions src/librustdoc/html/static/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,36 @@ function preLoadCss(cssUrl) {
window.searchState = {
rustdocToolbar: document.querySelector("rustdoc-toolbar"),
loadingText: "Loading search results...",
input: document.getElementsByClassName("search-input")[0],
outputElement: () => {
inputElement: () => {
let el = document.getElementsByClassName("search-input")[0];
if (!el) {
const out = searchState.outputElement().parentElement;
const hdr = document.createElement("div");
hdr.className = "main-heading search-results-main-heading";
const rootPath = getVar("root-path");
const currentCrate = getVar("current-crate");
hdr.innerHTML = `<nav class="sub">
<form class="search-form">
<span></span> <!-- This empty span is a hacky fix for Safari: see #93184 -->
<div id="sidebar-button" tabindex="-1">
<a href="${rootPath}${currentCrate}/all.html" title="show sidebar"></a>
</div>
<input
class="search-input"
name="search"
aria-label="Run search in the documentation"
autocomplete="off"
spellcheck="false"
placeholder="Type ‘S’ or ‘/’ to search, ‘?’ for more options…"
type="search">
</form>
</nav><div class="search-switcher"></div>`;
out.insertBefore(hdr, searchState.outputElement());
el = document.getElementsByClassName("search-input")[0];
}
return el;
},
containerElement: () => {
let el = document.getElementById("search");
if (!el) {
el = document.createElement("section");
Expand All @@ -251,6 +279,16 @@ function preLoadCss(cssUrl) {
}
return el;
},
outputElement: () => {
const container = searchState.containerElement();
let el = container.querySelector(".search-out");
if (!el) {
el = document.createElement("div");
el.className = "search-out";
container.appendChild(el);
}
return el;
},
title: document.title,
titleBeforeSearch: document.title,
timeout: null,
Expand All @@ -268,22 +306,38 @@ function preLoadCss(cssUrl) {
searchState.timeout = null;
}
},
isDisplayed: () => searchState.outputElement().parentElement.id === ALTERNATIVE_DISPLAY_ID,
isDisplayed: () => searchState.containerElement().parentElement.id ===
ALTERNATIVE_DISPLAY_ID,
// Sets the focus on the search bar at the top of the page
focus: () => {
searchState.input.focus();
searchState.showResults();
searchState.inputElement().focus();
},
// Removes the focus from the search bar.
defocus: () => {
searchState.input.blur();
searchState.inputElement().blur();
},
toggle: () => {
if (searchState.isDisplayed()) {
searchState.defocus();
searchState.hideResults();
} else {
searchState.focus();
}
},
showResults: search => {
if (search === null || typeof search === "undefined") {
search = searchState.outputElement();
showResults: () => {
document.title = searchState.title;
if (searchState.isDisplayed()) {
return;
}
const search = searchState.containerElement();
switchDisplayedElement(search);
searchState.mouseMovedAfterSearch = false;
document.title = searchState.title;
const btn = document.querySelector("#search-button a");
if (browserSupportsHistoryApi() && btn &&
searchState.getQueryStringParams().search === undefined) {
history.pushState(null, "", btn.href);
}
},
removeQueryParameters: () => {
// We change the document title.
Expand All @@ -309,11 +363,8 @@ function preLoadCss(cssUrl) {
return params;
},
setup: () => {
const search_input = searchState.input;
if (!searchState.input) {
return;
}
let searchLoaded = false;
const search_input = searchState.inputElement();
// If you're browsing the nightly docs, the page might need to be refreshed for the
// search to work because the hash of the JS scripts might have changed.
function sendSearchForm() {
Expand All @@ -333,8 +384,16 @@ function preLoadCss(cssUrl) {
loadSearch();
});

if (search_input.value !== "") {
loadSearch();
const btn = document.getElementById("search-button");
if (btn) {
btn.onclick = event => {
if (event.ctrlKey || event.altKey || event.metaKey) {
return;
}
event.preventDefault();
searchState.toggle();
loadSearch();
};
}

const params = searchState.getQueryStringParams();
Expand All @@ -346,7 +405,7 @@ function preLoadCss(cssUrl) {
setLoadingSearch: () => {
const search = searchState.outputElement();
search.innerHTML = "<h3 class=\"search-loading\">" + searchState.loadingText + "</h3>";
searchState.showResults(search);
searchState.showResults();
},
descShards: new Map(),
loadDesc: async function({descShard, descIndex}) {
Expand Down
Loading

0 comments on commit cf1e854

Please sign in to comment.