Auto merge of #91356 - GuillaumeGomez:improve-rustdoc-layout, r=jsha

Improve rustdoc layout

This is an overtake of https://github.com/rust-lang/rust/pull/89385 originally written by `@cynecx.`

I kept the original commit and simply added the missing fixes into a new one. You can test it online [here](https://rustdoc.crud.net/imperio/improve-rustdoc-layout/std/index.html).

r? `@jsha`
This commit is contained in:
bors 2021-12-05 18:35:43 +00:00
commit e2116acae5
29 changed files with 343 additions and 237 deletions

View file

@ -1447,7 +1447,7 @@ fn init_id_map() -> FxHashMap<String, usize> {
map.insert("theme-choices".to_owned(), 1);
map.insert("settings-menu".to_owned(), 1);
map.insert("help-button".to_owned(), 1);
map.insert("main".to_owned(), 1);
map.insert("main-content".to_owned(), 1);
map.insert("search".to_owned(), 1);
map.insert("crate-search".to_owned(), 1);
map.insert("render-detail".to_owned(), 1);

View file

@ -12,7 +12,7 @@ fn test_unique_id() {
"examples",
"method.into_iter",
"foo",
"main",
"main-content",
"search",
"methods",
"examples",
@ -28,7 +28,7 @@ fn test_unique_id() {
"examples-2",
"method.into_iter-1",
"foo-1",
"main-1",
"main-content-1",
"search-1",
"methods",
"examples-3",
@ -219,8 +219,8 @@ fn test_header_ids_multiple_blocks() {
);
t(
&mut map,
"# Main",
"<h2 id=\"main-1\" class=\"section-header\"><a href=\"#main-1\">Main</a></h2>",
"# Search",
"<h2 id=\"search-1\" class=\"section-header\"><a href=\"#search-1\">Search</a></h2>",
);
t(
&mut map,

View file

@ -4,7 +4,7 @@ of content is hidden by default (depending on the settings too), we have to over
rules.
*/
#main .attributes {
#main-content .attributes {
/* Since there is no toggle (the "[-]") when JS is disabled, no need for this margin either. */
margin-left: 0 !important;
}

View file

@ -111,7 +111,6 @@ body {
font: 16px/1.4 "Source Serif 4", NanumBarunGothic, serif;
margin: 0;
position: relative;
padding: 10px 15px 20px 15px;
-webkit-font-feature-settings: "kern", "liga";
-moz-font-feature-settings: "kern", "liga";
@ -202,7 +201,7 @@ details.rustdoc-toggle > summary::before,
div.impl-items > div:not(.docblock):not(.item-info),
.content ul.crate a.crate, a.srclink,
/* This selector is for the items listed in the "all items" page. */
#main > ul.docblock > li > a {
#main-content > ul.docblock > li > a {
font-family: "Fira Sans", Arial, NanumBarunGothic, sans-serif;
}
@ -248,6 +247,32 @@ textarea {
/* end tweaks for normalize.css 8 */
.rustdoc {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
}
main {
position: relative;
flex-grow: 1;
padding: 10px 15px 40px 45px;
min-width: 0;
}
.source main {
padding: 15px;
}
.width-limiter {
max-width: 960px;
margin-right: auto;
}
.source .width-limiter {
max-width: unset;
}
details:not(.rustdoc-toggle) summary {
margin-bottom: .6em;
}
@ -285,28 +310,75 @@ li {
}
.source .content {
margin-top: 50px;
max-width: none;
overflow: visible;
margin-left: 0px;
}
nav.sub {
position: relative;
font-size: 16px;
text-transform: uppercase;
}
.sub-container {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
}
.sub-logo-container {
display: none;
margin-right: 20px;
}
.source .sub-logo-container {
display: block;
}
.source .sub-logo-container > img {
height: 60px;
width: 60px;
object-fit: contain;
}
.sidebar {
width: 200px;
position: fixed;
left: 0;
top: 0;
bottom: 0;
overflow-y: scroll;
position: sticky;
min-width: 200px;
height: 100vh;
top: 0;
left: 0;
}
.rustdoc.source .sidebar {
width: 50px;
min-width: 0px;
max-width: 300px;
flex-grow: 0;
flex-shrink: 0;
flex-basis: auto;
border-right: 1px solid;
overflow-x: hidden;
/* The sidebar is by default hidden */
overflow-y: hidden;
}
.source .sidebar > *:not(:first-child) {
transition: opacity 0.5s, visibility 0.2s;
opacity: 0;
visibility: hidden;
}
.source .sidebar.expanded {
overflow-y: auto;
width: 300px;
}
.source .sidebar.expanded > * {
opacity: 1;
visibility: visible;
}
/* Improve the scrollbar display on firefox */
@ -332,10 +404,6 @@ nav.sub {
margin-right: -10px;
}
.content, nav {
max-width: 960px;
}
/* Everything else */
.hidden {
@ -343,23 +411,15 @@ nav.sub {
}
.logo-container {
height: 100px;
width: 100px;
position: relative;
margin: 20px auto;
display: block;
display: flex;
margin-top: 10px;
margin-bottom: 10px;
justify-content: center;
}
.logo-container > img {
max-width: 100px;
max-height: 100px;
height: 100%;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
display: block;
height: 100px;
width: 100px;
}
.sidebar .location {
@ -439,10 +499,6 @@ nav.sub {
display: none;
}
.content {
padding: 15px 0;
}
.source .content pre.rust {
white-space: pre;
overflow: auto;
@ -487,7 +543,6 @@ nav.sub {
}
#search {
margin-left: 230px;
position: relative;
}
@ -578,10 +633,10 @@ nav.sub {
display: inline-block;
}
#main {
#main-content {
position: relative;
}
#main > .since {
#main-content > .since {
top: inherit;
font-family: "Fira Sans", Arial, sans-serif;
}
@ -700,14 +755,18 @@ nav.sub {
flex-basis: 100%;
}
#main > .item-info {
#main-content > .item-info {
margin-top: 0;
}
nav:not(.sidebar) {
flex-grow: 1;
border-bottom: 1px solid;
padding-bottom: 10px;
margin-bottom: 10px;
margin-bottom: 25px;
}
.source nav:not(.sidebar).sub {
margin-left: 32px;
}
nav.main {
padding: 20px 0;
@ -726,10 +785,6 @@ nav.main .separator {
nav.sum { text-align: right; }
nav.sub form { display: inline; }
nav.sub, .content {
margin-left: 230px;
}
a {
text-decoration: none;
background: transparent;
@ -802,6 +857,7 @@ h2.small-section-header > .anchor {
.search-container {
position: relative;
max-width: 960px;
}
.search-container > div {
display: inline-flex;
@ -1320,30 +1376,23 @@ pre.rust {
}
#sidebar-toggle {
position: fixed;
top: 30px;
left: 300px;
z-index: 10;
padding: 3px;
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
position: sticky;
top: 0;
left: 0;
cursor: pointer;
font-weight: bold;
transition: left .5s;
font-size: 1.2em;
border: 1px solid;
border-left: 0;
border-bottom: 1px solid;
display: flex;
height: 40px;
justify-content: center;
align-items: center;
z-index: 10;
}
#source-sidebar {
position: fixed;
top: 0;
bottom: 0;
left: 0;
width: 300px;
z-index: 1;
overflow: auto;
transition: left .5s;
border-right: 1px solid;
}
#source-sidebar > .title {
font-size: 1.5em;
@ -1354,8 +1403,8 @@ pre.rust {
.theme-picker {
position: absolute;
left: 211px;
top: 19px;
left: -34px;
top: 9px;
}
.theme-picker button {
@ -1472,10 +1521,10 @@ kbd {
left: -5px;
}
#main > ul {
#main-content > ul {
padding-left: 10px;
}
#main > ul > li {
#main-content > ul > li {
list-style: none;
}
@ -1646,6 +1695,18 @@ details.rustdoc-toggle[open] > summary.hideme::after {
.docblock > .information:first-child > .tooltip {
margin-top: 16px;
}
/* When we expand the sidebar on the source code page, we hide the logo on the left of the
search bar to have more space. */
.sidebar.expanded + main .width-limiter .sub-logo-container.rust-logo {
display: none;
}
/* It doesn't render well on mobile because of the layout, so better only have the transition
on desktop. */
.rustdoc.source .sidebar {
transition: width .5s;
}
}
@media (max-width: 700px) {
@ -1653,14 +1714,43 @@ details.rustdoc-toggle[open] > summary.hideme::after {
padding-top: 0px;
}
.rustdoc > .sidebar {
main {
padding-left: 15px;
padding-top: 0px;
}
.rustdoc {
flex-direction: column;
}
.rustdoc:not(.source) > .sidebar {
width: 100%;
height: 45px;
min-height: 40px;
max-height: 45px;
margin: 0;
margin-left: -15px;
padding: 0 15px;
position: static;
z-index: 11;
overflow-y: hidden;
}
.rustdoc.source > .sidebar {
position: fixed;
top: 0;
left: 0;
margin: 0;
z-index: 11;
width: 0;
}
.sidebar.mobile {
position: sticky !important;
top: 0;
left: 0;
width: 100%;
margin-left: 0;
background-color: rgba(0,0,0,0);
}
.sidebar > .location {
@ -1678,7 +1768,7 @@ details.rustdoc-toggle[open] > summary.hideme::after {
padding: 0;
}
.sidebar .logo-container {
.rustdoc:not(.source) .sidebar .logo-container {
width: 35px;
height: 35px;
margin-top: 5px;
@ -1699,6 +1789,7 @@ details.rustdoc-toggle[open] > summary.hideme::after {
cursor: pointer;
width: 45px;
left: 0;
top: 0;
text-align: center;
display: block;
border-bottom: 1px solid;
@ -1748,20 +1839,25 @@ details.rustdoc-toggle[open] > summary.hideme::after {
nav.sub {
width: calc(100% - 32px);
float: right;
margin-left: 32px;
margin-bottom: 10px;
}
.source nav:not(.sidebar).sub {
margin-left: 32px;
}
.content {
margin-left: 0px;
}
#main, #search {
margin-top: 45px;
padding: 0;
.source .content {
margin-top: 10px;
}
#search {
margin-left: 0;
padding: 0;
}
.anchor {
@ -1769,8 +1865,6 @@ details.rustdoc-toggle[open] > summary.hideme::after {
}
.theme-picker {
left: 10px;
top: 54px;
z-index: 1;
}
@ -1789,25 +1883,6 @@ details.rustdoc-toggle[open] > summary.hideme::after {
height: 50px;
}
.sidebar.mobile {
position: fixed;
width: 100%;
margin-left: 0;
background-color: rgba(0,0,0,0);
height: 100%;
}
/*
This allows to prevent the version text to overflow the sidebar title on mobile mode when the
sidebar is displayed (after clicking on the "hamburger" button).
*/
.sidebar.mobile > div.version {
overflow: hidden;
max-height: 33px;
}
.sidebar {
width: calc(100% + 30px);
}
.show-it, .sidebar-elems:focus-within {
z-index: 2;
left: 0;
@ -1845,8 +1920,8 @@ details.rustdoc-toggle[open] > summary.hideme::after {
border-bottom: 1px solid;
}
#main > details.rustdoc-toggle > summary::before,
#main > div > details.rustdoc-toggle > summary::before {
#main-content > details.rustdoc-toggle > summary::before,
#main-content > div > details.rustdoc-toggle > summary::before {
left: -11px;
}
@ -1854,19 +1929,32 @@ details.rustdoc-toggle[open] > summary.hideme::after {
margin: 10px;
}
#sidebar-toggle {
.sidebar.expanded #sidebar-toggle {
font-size: 1.5rem;
}
.sidebar:not(.expanded) #sidebar-toggle {
position: fixed;
left: 1px;
top: 100px;
width: 30px;
font-size: 1.5rem;
text-align: center;
padding: 0;
z-index: 10;
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
cursor: pointer;
font-weight: bold;
border: 1px solid;
border-left: 0;
}
#source-sidebar {
z-index: 11;
}
#main > .line-numbers {
#main-content > .line-numbers {
margin-top: 0;
}
@ -1920,14 +2008,7 @@ details.rustdoc-toggle[open] > summary.hideme::after {
height: 73px;
}
/* This is to prevent the search bar from being underneath the <section>
* element following it.
*/
#main, #search {
margin-top: 100px;
}
#main > table:not(.table-display) td {
#main-content > table:not(.table-display) td {
word-break: break-word;
width: 50%;
}
@ -1969,6 +2050,23 @@ details.rustdoc-toggle[open] > summary.hideme::after {
.docblock code {
overflow-wrap: anywhere;
}
.sub-container {
flex-direction: column;
}
.sub-logo-container {
align-self: center;
}
.source .sub-logo-container > img {
height: 35px;
width: 35px;
}
.sidebar:not(.expanded) #sidebar-toggle {
top: 10px;
}
}

View file

@ -61,7 +61,7 @@ pre, .rustdoc.source .example-wrap {
background-color: #14191f;
}
.logo-container.rust-logo > img {
.rust-logo > img {
filter: drop-shadow(1px 0 0px #fff)
drop-shadow(0 1px 0 #fff)
drop-shadow(-1px 0 0 #fff)
@ -97,7 +97,7 @@ pre, .rustdoc.source .example-wrap {
}
.source .sidebar {
background-color: #0f1419;
background-color: #14191f;
}
.sidebar .location {

View file

@ -32,7 +32,7 @@ pre, .rustdoc.source .example-wrap {
background-color: #505050;
}
.logo-container.rust-logo > img {
.rust-logo > img {
filter: drop-shadow(1px 0 0px #fff)
drop-shadow(0 1px 0 #fff)
drop-shadow(-1px 0 0 #fff)
@ -66,7 +66,7 @@ pre, .rustdoc.source .example-wrap {
}
.source .sidebar {
background-color: #353535;
background-color: #565656;
}
.sidebar .location {

View file

@ -43,7 +43,7 @@ pre, .rustdoc.source .example-wrap {
scrollbar-color: rgba(36, 37, 39, 0.6) #d9d9d9;
}
.logo-container.rust-logo > img {
.rust-logo > img {
/* No need for a border in here! */
}
@ -66,7 +66,7 @@ pre, .rustdoc.source .example-wrap {
}
.source .sidebar {
background-color: #fff;
background-color: #f1f1f1;
}
.sidebar .location {

View file

@ -94,6 +94,7 @@ function getVirtualKey(ev) {
var THEME_PICKER_ELEMENT_ID = "theme-picker";
var THEMES_ELEMENT_ID = "theme-choices";
var MAIN_ID = "main-content";
function getThemesElement() {
return document.getElementById(THEMES_ELEMENT_ID);
@ -362,7 +363,7 @@ function hideThemeButtonState() {
}
var toggleAllDocsId = "toggle-all-docs";
var main = document.getElementById("main");
var main = document.getElementById(MAIN_ID);
var savedHash = "";
function handleHashes(ev) {
@ -787,7 +788,7 @@ function hideThemeButtonState() {
} else {
addClass(innerToggle, "will-expand");
onEachLazy(document.getElementsByClassName("rustdoc-toggle"), function(e) {
if (e.parentNode.id !== "main" ||
if (e.parentNode.id !== MAIN_ID ||
(!hasClass(e, "implementors-toggle") &&
!hasClass(e, "type-contents-toggle")))
{
@ -1001,7 +1002,7 @@ function hideThemeButtonState() {
container.appendChild(rustdoc_version);
popup.appendChild(container);
insertAfter(popup, searchState.outputElement());
insertAfter(popup, document.querySelector("main"));
// So that it's only built once and then it'll do nothing when called!
buildHelperPopup = function() {};
};

View file

@ -77,16 +77,14 @@ function createDirEntry(elem, parent, fullPath, currentFile, hasFoundFile) {
}
function toggleSidebar() {
var sidebar = document.getElementById("source-sidebar");
var child = this.children[0].children[0];
var sidebar = document.querySelector("nav.sidebar");
var child = this.children[0];
if (child.innerText === ">") {
sidebar.style.left = "";
this.style.left = "";
sidebar.classList.add("expanded");
child.innerText = "<";
updateLocalStorage("rustdoc-source-sidebar-show", "true");
} else {
sidebar.style.left = "-300px";
this.style.left = "0";
sidebar.classList.remove("expanded");
child.innerText = ">";
updateLocalStorage("rustdoc-source-sidebar-show", "false");
}
@ -97,20 +95,15 @@ function createSidebarToggle() {
sidebarToggle.id = "sidebar-toggle";
sidebarToggle.onclick = toggleSidebar;
var inner1 = document.createElement("div");
inner1.style.position = "relative";
var inner = document.createElement("div");
var inner2 = document.createElement("div");
inner2.style.paddingTop = "3px";
if (getCurrentValue("rustdoc-source-sidebar-show") === "true") {
inner2.innerText = "<";
inner.innerText = "<";
} else {
inner2.innerText = ">";
sidebarToggle.style.left = "0";
inner.innerText = ">";
}
inner1.appendChild(inner2);
sidebarToggle.appendChild(inner1);
sidebarToggle.appendChild(inner);
return sidebarToggle;
}
@ -120,15 +113,17 @@ function createSourceSidebar() {
if (!window.rootPath.endsWith("/")) {
window.rootPath += "/";
}
var main = document.getElementById("main");
var container = document.querySelector("nav.sidebar");
var sidebarToggle = createSidebarToggle();
main.insertBefore(sidebarToggle, main.firstChild);
container.insertBefore(sidebarToggle, container.firstChild);
var sidebar = document.createElement("div");
sidebar.id = "source-sidebar";
if (getCurrentValue("rustdoc-source-sidebar-show") !== "true") {
sidebar.style.left = "-300px";
container.classList.remove("expanded");
} else {
container.classList.add("expanded");
}
var currentFile = getCurrentFilePath();
@ -144,7 +139,7 @@ function createSourceSidebar() {
currentFile, hasFoundFile);
});
main.insertBefore(sidebar, main.firstChild);
container.insertBefore(sidebar, document.querySelector(".sidebar-logo").nextSibling);
// Focus on the current file in the source files sidebar.
var selected_elem = sidebar.getElementsByClassName("selected")[0];
if (typeof selected_elem !== "undefined") {

View file

@ -74,52 +74,67 @@
{{- layout.external_html.before_content | safe -}}
<nav class="sidebar"> {#- -#}
<div class="sidebar-menu" role="button">&#9776;</div> {#- -#}
<a href='{{page.root_path | safe}}{{krate_with_trailing_slash | safe}}index.html'> {#- -#}
<a class="sidebar-logo" href='{{page.root_path | safe}}{{krate_with_trailing_slash | safe}}index.html'> {#- -#}
<div class='logo-container rust-logo'> {#- -#}
<img src='
{%- if layout.logo -%}
{{layout.logo}}
{%- else -%}
{{static_root_path | safe}}rust-logo{{page.resource_suffix}}.png
{%- endif -%}
' alt='logo'> {#- -#}
<img src='
{%- if layout.logo -%}
{{layout.logo}}
{%- else -%}
{{static_root_path | safe}}rust-logo{{page.resource_suffix}}.png
{%- endif -%}
' alt='logo'> {#- -#}
</div> {#- -#}
</a> {#- -#}
{{- sidebar | safe -}}
</nav> {#- -#}
<div class="theme-picker"> {#- -#}
<button id="theme-picker" aria-label="Pick another theme!" aria-haspopup="menu" title="themes"> {#- -#}
<img width="18" height="18" alt="Pick another theme!" {# -#}
src="{{static_root_path | safe}}brush{{page.resource_suffix}}.svg"> {#- -#}
</button> {#- -#}
<div id="theme-choices" role="menu"></div> {#- -#}
</div> {#- -#}
<nav class="sub"> {#- -#}
<form class="search-form"> {#- -#}
<div class="search-container"> {#- -#}
<div>{%- if layout.generate_search_filter -%}
<select id="crate-search"> {#- -#}
<option value="All crates">All crates</option> {#- -#}
</select> {#- -#}
{%- endif -%}
<input {# -#}
class="search-input" {# -#}
name="search" {# -#}
autocomplete="off" {# -#}
spellcheck="false" {# -#}
placeholder="Click or press S to search, ? for more options…" {# -#}
type="search"> {#- -#}
</div> {#- -#}
<button type="button" id="help-button" title="help">?</button> {#- -#}
<a id="settings-menu" href="{{page.root_path | safe}}settings.html" title="settings"> {#- -#}
<img width="18" height="18" alt="Change settings" {# -#}
src="{{static_root_path | safe}}wheel{{page.resource_suffix}}.svg"> {#- -#}
<main> {#- -#}
<div class="width-limiter"> {#- -#}
<div class="sub-container"> {#- -#}
<a class="sub-logo-container rust-logo" href='{{page.root_path | safe}}{{krate_with_trailing_slash | safe}}index.html'> {#- -#}
<img src='
{%- if layout.logo -%}
{{layout.logo}}
{%- else -%}
{{static_root_path | safe}}rust-logo{{page.resource_suffix}}.png
{%- endif -%}
' alt='logo'> {#- -#}
</a> {#- -#}
<nav class="sub"> {#- -#}
<div class="theme-picker"> {#- -#}
<button id="theme-picker" aria-label="Pick another theme!" aria-haspopup="menu" title="themes"> {#- -#}
<img width="18" height="18" alt="Pick another theme!" {# -#}
src="{{static_root_path | safe}}brush{{page.resource_suffix}}.svg"> {#- -#}
</button> {#- -#}
<div id="theme-choices" role="menu"></div> {#- -#}
</div> {#- -#}
<form class="search-form"> {#- -#}
<div class="search-container"> {#- -#}
<div>{%- if layout.generate_search_filter -%}
<select id="crate-search"> {#- -#}
<option value="All crates">All crates</option> {#- -#}
</select> {#- -#}
{%- endif -%}
<input {# -#}
class="search-input" {# -#}
name="search" {# -#}
autocomplete="off" {# -#}
spellcheck="false" {# -#}
placeholder="Click or press S to search, ? for more options…" {# -#}
type="search"> {#- -#}
</div> {#- -#}
<button type="button" id="help-button" title="help">?</button> {#- -#}
<a id="settings-menu" href="{{page.root_path | safe}}settings.html" title="settings"> {#- -#}
<img width="18" height="18" alt="Change settings" {# -#}
src="{{static_root_path | safe}}wheel{{page.resource_suffix}}.svg"> {#- -#}
</a> {#- -#}
</div> {#- -#}
</form> {#- -#}
</nav> {#- -#}
</div> {#- -#}
</form> {#- -#}
</nav> {#- -#}
<section id="main" class="content">{{- content | safe -}}</section> {#- -#}
<section id="search" class="content hidden"></section> {#- -#}
<section id="main-content" class="content">{{- content | safe -}}</section> {#- -#}
<section id="search" class="content hidden"></section> {#- -#}
</div> {#- -#}
</main> {#- -#}
{{- layout.external_html.after_content | safe -}}
<div id="rustdoc-vars" {# -#}
data-root-path="{{page.root_path | safe}}" {# -#}