mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
rustdoc: enforce BODY_MIN constraint on sidebar resize
This commit is contained in:
parent
210c88fc7a
commit
273a302ac8
@ -9,6 +9,11 @@
|
||||
:root {
|
||||
--nav-sub-mobile-padding: 8px;
|
||||
--search-typename-width: 6.75rem;
|
||||
/* DEFAULT_SIDEBAR_WIDTH
|
||||
see main.js for information on these values
|
||||
and on the RUSTDOC_MOBILE_BREAKPOINT */
|
||||
--desktop-sidebar-width: 200px;
|
||||
--src-sidebar-width: 300px;
|
||||
}
|
||||
|
||||
/* See FiraSans-LICENSE.txt for the Fira Sans license. */
|
||||
@ -383,7 +388,7 @@ img {
|
||||
|
||||
.sidebar {
|
||||
font-size: 0.875rem;
|
||||
flex: 0 0 var(--desktop-sidebar-width, 200px);
|
||||
flex: 0 0 var(--desktop-sidebar-width);
|
||||
overflow-y: scroll;
|
||||
overscroll-behavior: contain;
|
||||
position: sticky;
|
||||
@ -414,7 +419,7 @@ img {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
/* make sure there's a 1px gap between the scrollbar and resize handle */
|
||||
left: calc(var(--desktop-sidebar-width, 200px) + 1px);
|
||||
left: calc(var(--desktop-sidebar-width) + 1px);
|
||||
}
|
||||
|
||||
.rustdoc.src .sidebar-resizer {
|
||||
@ -426,7 +431,7 @@ img {
|
||||
.src-sidebar-expanded .rustdoc.src .sidebar-resizer {
|
||||
/* for src sidebar, gap is already provided by 1px border on sidebar itself, so place resizer
|
||||
to right of it */
|
||||
left: var(--src-sidebar-width, 300px);
|
||||
left: var(--src-sidebar-width);
|
||||
}
|
||||
|
||||
.sidebar-resizing {
|
||||
@ -448,7 +453,7 @@ img {
|
||||
margin: 0;
|
||||
/* when active or hovered, place resizer glow on top of the sidebar (right next to, or even
|
||||
on top of, the scrollbar) */
|
||||
left: var(--desktop-sidebar-width, 200px);
|
||||
left: var(--desktop-sidebar-width);
|
||||
border-left: solid 1px var(--sidebar-resizer-hover);
|
||||
}
|
||||
|
||||
@ -457,7 +462,7 @@ img {
|
||||
.src-sidebar-expanded .rustdoc.src .sidebar-resizer:focus,
|
||||
.src-sidebar-expanded .rustdoc.src .sidebar-resizer.active {
|
||||
/* when active or hovered, place resizer glow on top of the normal src sidebar border */
|
||||
left: calc(var(--src-sidebar-width, 300px) - 1px);
|
||||
left: calc(var(--src-sidebar-width) - 1px);
|
||||
}
|
||||
|
||||
@media (pointer: coarse) {
|
||||
@ -497,7 +502,7 @@ img {
|
||||
|
||||
.src-sidebar-expanded .src .sidebar {
|
||||
overflow-y: auto;
|
||||
flex-basis: var(--src-sidebar-width, 300px);
|
||||
flex-basis: var(--src-sidebar-width);
|
||||
}
|
||||
|
||||
.src-sidebar-expanded .src .sidebar > *:not(#src-sidebar-toggle) {
|
||||
@ -1806,7 +1811,7 @@ However, it's not needed with smaller screen width because the doc/code block is
|
||||
/*
|
||||
WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY
|
||||
If you update this line, then you also need to update the line with the same warning
|
||||
in src-script.js
|
||||
in src-script.js and main.js
|
||||
*/
|
||||
@media (max-width: 700px) {
|
||||
/* When linking to an item with an `id` (for instance, by clicking a link in the sidebar,
|
||||
|
@ -1273,8 +1273,49 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/how-to-read-rustdoc.html\
|
||||
searchState.setup();
|
||||
}());
|
||||
|
||||
// This section handles sidebar resizing
|
||||
// Hide, show, and resize the sidebar
|
||||
//
|
||||
// The body class and CSS variable are initially set up in storage.js,
|
||||
// but in this file, we implement:
|
||||
//
|
||||
// * the show sidebar button, which appears if the sidebar is hidden
|
||||
// and, by clicking on it, will bring it back
|
||||
// * the sidebar resize handle, which appears only on large viewports
|
||||
// with a [fine precision pointer] to allow the user to change
|
||||
// the size of the sidebar
|
||||
//
|
||||
// [fine precision pointer]: https://developer.mozilla.org/en-US/docs/Web/CSS/@media/pointer
|
||||
(function() {
|
||||
// 100 is the size of the logo
|
||||
// don't let the sidebar get smaller than that, or it'll get squished
|
||||
const SIDEBAR_MIN = 100;
|
||||
// Don't let the sidebar get bigger than this
|
||||
const SIDEBAR_MAX = 500;
|
||||
// Don't let the body (including the gutter) get smaller than this
|
||||
//
|
||||
// WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY
|
||||
// Acceptable values for BODY_MIN are constrained by the mobile breakpoint
|
||||
// (which is the minimum size of the whole page where the sidebar exists)
|
||||
// and the default sidebar width:
|
||||
//
|
||||
// BODY_MIN <= RUSTDOC_MOBILE_BREAKPOINT - DEFAULT_SIDEBAR_WIDTH
|
||||
//
|
||||
// At the time of this writing, the DEFAULT_SIDEBAR_WIDTH on src pages is
|
||||
// 300px, and the RUSTDOC_MOBILE_BREAKPOINT is 700px, so BODY_MIN must be
|
||||
// at most 400px. Otherwise, it would start out at the default size, then
|
||||
// grabbing the resize handle would suddenly cause it to jank to
|
||||
// its contraint-generated maximum.
|
||||
const BODY_MIN = 400;
|
||||
// At half-way past the minimum size, vanish the sidebar entirely
|
||||
const SIDEBAR_VANISH_THRESHOLD = SIDEBAR_MIN / 2;
|
||||
|
||||
// Toolbar button to show the sidebar.
|
||||
//
|
||||
// On small, "mobile-sized" viewports, it's not persistent and it
|
||||
// can only be activated by going into Settings and hiding the nav bar.
|
||||
// On larger, "desktop-sized" viewports (though that includes many
|
||||
// tablets), it's fixed-position, appears in the left side margin,
|
||||
// and it can be activated by resizing the sidebar into nothing.
|
||||
const sidebarButton = document.getElementById("sidebar-button");
|
||||
if (sidebarButton) {
|
||||
sidebarButton.addEventListener("click", e => {
|
||||
@ -1283,13 +1324,38 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/how-to-read-rustdoc.html\
|
||||
e.preventDefault();
|
||||
});
|
||||
}
|
||||
|
||||
// Pointer capture.
|
||||
//
|
||||
// Resizing is a single-pointer gesture. Any secondary pointer is ignored
|
||||
let currentPointerId = null;
|
||||
|
||||
// "Desired" sidebar size.
|
||||
//
|
||||
// This is stashed here for window resizing. If the sidebar gets
|
||||
// shrunk to maintain BODY_MIN, and then the user grows the window again,
|
||||
// it gets the sidebar to restore its size.
|
||||
let desiredSidebarSize = null;
|
||||
|
||||
// If this page has no sidebar at all, bail out.
|
||||
const resizer = document.querySelector(".sidebar-resizer");
|
||||
const sidebar = document.querySelector(".sidebar");
|
||||
if (!resizer || !sidebar) {
|
||||
return;
|
||||
}
|
||||
|
||||
// src page and docs page use different variables, because the contents of
|
||||
// the sidebar are so different that it's reasonable to thing the user
|
||||
// would want them to have different sizes
|
||||
const isSrcPage = hasClass(document.body, "src");
|
||||
|
||||
// Call this function to hide the sidebar when using the resize handle
|
||||
//
|
||||
// This function also nulls out the sidebar width CSS variable and setting,
|
||||
// causing it to return to its default. This does not happen if you do it
|
||||
// from settings.js, which uses a separate function. It's done here because
|
||||
// the minimum sidebar size is rather uncomfortable, and it must pass
|
||||
// through that size when using the shrink-to-nothing gesture.
|
||||
function hideSidebar() {
|
||||
if (isSrcPage) {
|
||||
window.rustdocCloseSourceSidebar();
|
||||
@ -1302,6 +1368,13 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/how-to-read-rustdoc.html\
|
||||
document.documentElement.style.removeProperty("--desktop-sidebar-width");
|
||||
}
|
||||
}
|
||||
|
||||
// Call this function to show the sidebar from the resize handle.
|
||||
// On docs pages, this can only happen if the user has grabbed the resize
|
||||
// handle, shrunk the sidebar down to nothing, and then pulls back into
|
||||
// the visible range without releasing it. You can, however, grab the
|
||||
// resize handle on a source page with the sidebar closed, because it
|
||||
// remains visible all the time on there.
|
||||
function showSidebar() {
|
||||
if (isSrcPage) {
|
||||
window.rustdocShowSourceSidebar();
|
||||
@ -1310,6 +1383,9 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/how-to-read-rustdoc.html\
|
||||
updateLocalStorage("hide-sidebar", "false");
|
||||
}
|
||||
}
|
||||
|
||||
// Call this to set the correct CSS variable and setting.
|
||||
// This function doesn't enforce size constraints. Do that before calling it!
|
||||
function changeSidebarSize(size) {
|
||||
if (isSrcPage) {
|
||||
updateLocalStorage("src-sidebar-width", size);
|
||||
@ -1319,34 +1395,54 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/how-to-read-rustdoc.html\
|
||||
document.documentElement.style.setProperty("--desktop-sidebar-width", size + "px");
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the sidebar is hidden. Since src pages and doc pages have
|
||||
// different settings, this function has to check that.
|
||||
function isSidebarHidden() {
|
||||
return isSrcPage ?
|
||||
!hasClass(document.documentElement, "src-sidebar-expanded") :
|
||||
hasClass(document.documentElement, "hide-sidebar");
|
||||
}
|
||||
|
||||
// Respond to the resize handle event.
|
||||
// This function enforces size constraints, and implements the
|
||||
// shrink-to-nothing gesture based on thresholds defined above.
|
||||
function resize(e) {
|
||||
if (currentPointerId === null || currentPointerId !== e.pointerId) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
const pos = e.clientX - sidebar.offsetLeft - 3;
|
||||
if (pos < 50) {
|
||||
if (pos < SIDEBAR_VANISH_THRESHOLD) {
|
||||
hideSidebar();
|
||||
} else if (pos >= 100) {
|
||||
// 100 is the size of the logo
|
||||
// don't let the sidebar get smaller than that, or it'll get squished
|
||||
} else if (pos >= SIDEBAR_MIN) {
|
||||
if (isSidebarHidden()) {
|
||||
showSidebar();
|
||||
}
|
||||
// don't let the sidebar get wider than 500
|
||||
changeSidebarSize(Math.min(pos, window.innerWidth - 100, 500));
|
||||
// don't let the sidebar get wider than SIDEBAR_MAX, or the body narrower
|
||||
// than BODY_MIN
|
||||
const constrainedPos = Math.min(pos, window.innerWidth - BODY_MIN, SIDEBAR_MAX);
|
||||
changeSidebarSize(constrainedPos);
|
||||
desiredSidebarSize = constrainedPos;
|
||||
}
|
||||
}
|
||||
// Respond to the window resize event.
|
||||
window.addEventListener("resize", () => {
|
||||
stopResize();
|
||||
if (desiredSidebarSize >= (window.innerWidth - BODY_MIN)) {
|
||||
changeSidebarSize(window.innerWidth - BODY_MIN);
|
||||
} else if (desiredSidebarSize !== null && desiredSidebarSize > SIDEBAR_MIN) {
|
||||
changeSidebarSize(desiredSidebarSize);
|
||||
}
|
||||
});
|
||||
function stopResize(e) {
|
||||
if (currentPointerId === null) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
desiredSidebarSize = sidebar.getBoundingClientRect().width;
|
||||
removeClass(resizer, "active");
|
||||
window.removeEventListener("pointermove", resize, false);
|
||||
window.removeEventListener("pointerup", stopResize, false);
|
||||
@ -1376,6 +1472,7 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/how-to-read-rustdoc.html\
|
||||
window.addEventListener("pointerup", stopResize, false);
|
||||
addClass(resizer, "active");
|
||||
addClass(document.documentElement, "sidebar-resizing");
|
||||
desiredSidebarSize = null;
|
||||
}
|
||||
resizer.addEventListener("pointerdown", initResize, false);
|
||||
}());
|
||||
|
@ -196,18 +196,21 @@ if (getSettingValue("use-system-theme") !== "false" && window.matchMedia) {
|
||||
|
||||
updateTheme();
|
||||
|
||||
// Hide, show, and resize the sidebar at page load time
|
||||
//
|
||||
// This needs to be done here because this JS is render-blocking,
|
||||
// so that the sidebar doesn't "jump" after appearing on screen.
|
||||
// The user interaction to change this is set up in main.js.
|
||||
if (getSettingValue("source-sidebar-show") === "true") {
|
||||
// At this point in page load, `document.body` is not available yet.
|
||||
// Set a class on the `<html>` element instead.
|
||||
addClass(document.documentElement, "src-sidebar-expanded");
|
||||
}
|
||||
|
||||
if (getSettingValue("hide-sidebar") === "true") {
|
||||
// At this point in page load, `document.body` is not available yet.
|
||||
// Set a class on the `<html>` element instead.
|
||||
addClass(document.documentElement, "hide-sidebar");
|
||||
}
|
||||
|
||||
function updateSidebarWidth() {
|
||||
const desktopSidebarWidth = getSettingValue("desktop-sidebar-width");
|
||||
if (desktopSidebarWidth && desktopSidebarWidth !== "null") {
|
||||
|
33
tests/rustdoc-gui/sidebar-resize-window.goml
Normal file
33
tests/rustdoc-gui/sidebar-resize-window.goml
Normal file
@ -0,0 +1,33 @@
|
||||
// Checks sidebar resizing
|
||||
go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
|
||||
set-window-size: (1280, 600)
|
||||
wait-for-property: (".sidebar", {"clientWidth": 200}, [NEAR])
|
||||
|
||||
// resize past maximum (don't grow past 500)
|
||||
drag-and-drop: ((205, 100), (600, 100))
|
||||
wait-for-property: (".sidebar", {"clientWidth": 500}, [NEAR])
|
||||
|
||||
// make the window small enough that the sidebar has to shrink
|
||||
set-window-size: (750, 600)
|
||||
wait-for-property: (".sidebar", {"clientWidth": 350}, [NEAR])
|
||||
|
||||
// grow the window again to make the sidebar bigger
|
||||
set-window-size: (1280, 600)
|
||||
wait-for-property: (".sidebar", {"clientWidth": 500}, [NEAR])
|
||||
|
||||
// make the window small enough that the sidebar has to shrink
|
||||
set-window-size: (750, 600)
|
||||
wait-for-property: (".sidebar", {"clientWidth": 350}, [NEAR])
|
||||
|
||||
// grow the window again to make the sidebar bigger
|
||||
set-window-size: (1280, 600)
|
||||
wait-for-property: (".sidebar", {"clientWidth": 500}, [NEAR])
|
||||
|
||||
// shrink back down again, then reload the page
|
||||
// the "desired size" is a bit of remembered implicit state,
|
||||
// and rustdoc tries to minimize things like this
|
||||
set-window-size: (800, 600)
|
||||
wait-for-property: (".sidebar", {"clientWidth": 400}, [NEAR])
|
||||
reload:
|
||||
set-window-size: (1280, 600)
|
||||
wait-for-property: (".sidebar", {"clientWidth": 400}, [NEAR])
|
Loading…
Reference in New Issue
Block a user