Rollup merge of #115660 - notriddle:notriddle/sidebar-resize, r=GuillaumeGomez
rustdoc: allow resizing the sidebar / hiding the top bar
Fixes #97306
Preview: http://notriddle.com/rustdoc-html-demo-4/sidebar-resize/std/index.html

## Summary
This feature adds:
1. A checkbox to the Settings popover to hide the persistent navigation bar (the sidebar on large viewports and the top bar on small ones).
2. On large viewports, it adds a resize handle to the persistent sidebar. Resizing it into nothing is equivalent to turning off the persistent navigation bar checkbox in Settings.
3. If the navigation bar is hidden, a toolbar button to the left of the search appears. Clicking it brings the navigation bar back.
## Motivation
While "mobile mode" is definitely a good default, it's not the only reason people have wanted to hide the sidebar:
* Some people use tiling window managers, and don't like rustdoc's current breakpoints. Changing the breakpoints might help with that, but there's no perfect solution, because there's a gap between "huge screen" and "smartphone" where reasonable people can disagree about whether it makes sense for the sidebar to be on-screen. https://github.com/rust-lang/rust/issues/97306
* Some people ask for ways to reduce on-screen clutter because it makes it easier to focus. There's not a media query for that (and if there was, privacy-conscious users would turn it off). https://github.com/rust-lang/rust/issues/59829
This feature is designed to avoid these problems. Resizing the sidebar especially helps, because it provides a way to hide the sidebar without adding a new top-level button (which would add clutter), and it provides a way to make rustdoc play nicer in complex, custom screen layouts.
## Guide and Reference-level explanation
On a desktop or laptop with a mouse, resize the sidebar by dragging its right edge.
On any browser, including mobile phones, the sticky top bar or side bar can be hidden from the Settings area (the button with the cog wheel, next to the search bar). When it's hidden, a convenient button will appear on the search bar's left.
## Drawbacks
This adds more JavaScript code to the render blocking area.
## Rationale and alternatives
The most obvious way to allow people to hide the sidebar would have been to let them "manually enter mobile mode." The upside is that it's a feature we already have. The downside is that it's actually really hard to come up with a terse description. Is it:
* A Setting that forces desktop viewers to always have the mobile-style top bar? If so, how do we label it? Should it be visible on mobile, and, if so, does it just not do anything?
* A persistent hide/show sidebar button, present on desktop, just like on mobile? That's clutter that I'd like to avoid.
## Prior art
* The new file browser in GitHub uses a similar divider with a mouse-over indicator
* mdBook and macOS Finder both allow you to resize the sidebar to nothing as a gesture to hide it
* https://www.nngroup.com/articles/drag-drop/
## Future possibilities
https://rust-lang.zulipchat.com/#narrow/stream/266220-rustdoc/topic/Table.20of.20contents proposes a new, second sidebar (a table of contents). How should it fit in with this feature? Should it be resizeable? Hideable? Can it be accessed on mobile?
This commit is contained in:
commit
f8b92697a1
17 changed files with 625 additions and 30 deletions
20
tests/rustdoc-gui/hide-mobile-topbar.goml
Normal file
20
tests/rustdoc-gui/hide-mobile-topbar.goml
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Checks sidebar resizing stays synced with the setting
|
||||
go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
|
||||
set-window-size: (400, 600)
|
||||
|
||||
// Verify that the "hide" option is unchecked
|
||||
click: "#settings-menu"
|
||||
wait-for: "#settings"
|
||||
assert-css: ("#settings", {"display": "block"})
|
||||
assert-property: ("#hide-sidebar", {"checked": "false"})
|
||||
assert-css: (".mobile-topbar", {"display": "flex"})
|
||||
|
||||
// Toggle it
|
||||
click: "#hide-sidebar"
|
||||
assert-property: ("#hide-sidebar", {"checked": "true"})
|
||||
assert-css: (".mobile-topbar", {"display": "none"})
|
||||
|
||||
// Toggle it again
|
||||
click: "#hide-sidebar"
|
||||
assert-property: ("#hide-sidebar", {"checked": "false"})
|
||||
assert-css: (".mobile-topbar", {"display": "flex"})
|
|
@ -26,12 +26,12 @@ define-function: (
|
|||
assert-css: (".item-table .keyword", {"color": |keyword|}, ALL)
|
||||
// Checking sidebar elements.
|
||||
assert-css: (
|
||||
".sidebar-elems a:not(.current)",
|
||||
".sidebar-elems li:not(.current) a",
|
||||
{"color": |sidebar|, "background-color": "rgba(0, 0, 0, 0)", "font-weight": "400"},
|
||||
ALL,
|
||||
)
|
||||
assert-css: (
|
||||
".sidebar-elems a.current",
|
||||
".sidebar-elems li.current a",
|
||||
{
|
||||
"color": |sidebar_current|,
|
||||
"background-color": |sidebar_current_background|,
|
||||
|
|
|
@ -17,10 +17,10 @@ define-function: (
|
|||
reload:
|
||||
// Struct
|
||||
assert-css: (
|
||||
".sidebar .block.struct a:not(.current)",
|
||||
".sidebar .block.struct li:not(.current) a",
|
||||
{"color": |struct|, "background-color": "rgba(0, 0, 0, 0)"},
|
||||
)
|
||||
move-cursor-to: ".sidebar .block.struct a:not(.current)"
|
||||
move-cursor-to: ".sidebar .block.struct li:not(.current) a"
|
||||
assert-css: (
|
||||
".sidebar .block.struct a:hover",
|
||||
{"color": |struct_hover|, "background-color": |struct_hover_background|},
|
||||
|
|
23
tests/rustdoc-gui/sidebar-resize-setting.goml
Normal file
23
tests/rustdoc-gui/sidebar-resize-setting.goml
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Checks sidebar resizing stays synced with the setting
|
||||
go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
|
||||
assert-property: (".sidebar", {"clientWidth": "200"})
|
||||
show-text: true
|
||||
|
||||
// Verify that the "hide" option is unchecked
|
||||
click: "#settings-menu"
|
||||
wait-for: "#settings"
|
||||
assert-css: ("#settings", {"display": "block"})
|
||||
assert-property: ("#hide-sidebar", {"checked": "false"})
|
||||
press-key: "Escape"
|
||||
wait-for-css: ("#settings", {"display": "none"})
|
||||
|
||||
drag-and-drop: ((205, 100), (5, 100))
|
||||
assert-css: (".sidebar", {"display": "none"})
|
||||
|
||||
// Verify that the "hide" option is checked
|
||||
focus: "#settings-menu a"
|
||||
press-key: "Enter"
|
||||
wait-for-css: ("#settings", {"display": "block"})
|
||||
assert-property: ("#hide-sidebar", {"checked": "true"})
|
||||
click: "#hide-sidebar"
|
||||
wait-for-css: (".sidebar", {"display": "block"})
|
37
tests/rustdoc-gui/sidebar-resize-window.goml
Normal file
37
tests/rustdoc-gui/sidebar-resize-window.goml
Normal file
|
@ -0,0 +1,37 @@
|
|||
// 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])
|
||||
assert-local-storage: {"rustdoc-desktop-sidebar-width": "350"}
|
||||
set-window-size: (400, 600)
|
||||
wait-for-css: (".sidebar", {"display": "block", "left": "-1000px"})
|
||||
assert-local-storage: {"rustdoc-desktop-sidebar-width": "350"}
|
||||
|
||||
// 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])
|
28
tests/rustdoc-gui/sidebar-resize.goml
Normal file
28
tests/rustdoc-gui/sidebar-resize.goml
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Checks sidebar resizing
|
||||
go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
|
||||
assert-property: (".sidebar", {"clientWidth": "200"})
|
||||
show-text: true
|
||||
// normal resizing
|
||||
drag-and-drop: ((205, 100), (185, 100))
|
||||
assert-property: (".sidebar", {"clientWidth": "182"})
|
||||
// resize past maximum (don't grow past 500)
|
||||
drag-and-drop: ((185, 100), (600, 100))
|
||||
assert-property: (".sidebar", {"clientWidth": "500"})
|
||||
// resize past minimum (hide sidebar)
|
||||
drag-and-drop: ((501, 100), (5, 100))
|
||||
assert-property: (".sidebar", {"clientWidth": "0"})
|
||||
assert-css: (".sidebar", {"display": "none"})
|
||||
assert-local-storage: {"rustdoc-hide-sidebar": "true"}
|
||||
set-local-storage: {"rustdoc-hide-sidebar": "false"}
|
||||
|
||||
// Now same thing, but for source code
|
||||
go-to: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html"
|
||||
assert-property: (".sidebar", {"clientWidth": "49"})
|
||||
drag-and-drop: ((52, 100), (185, 100))
|
||||
assert-property: (".sidebar", {"clientWidth": "181"})
|
||||
drag-and-drop: ((185, 100), (600, 100))
|
||||
assert-property: (".sidebar", {"clientWidth": "499"})
|
||||
drag-and-drop: ((500, 100), (5, 100))
|
||||
// instead of hiding the sidebar entirely, this
|
||||
// will switch to the toggle mode
|
||||
assert-property: (".sidebar", {"clientWidth": "49"})
|
|
@ -48,6 +48,7 @@ call-function: (
|
|||
|
||||
// Next, desktop mode layout.
|
||||
set-window-size: (1100, 800)
|
||||
wait-for: "#src-sidebar-toggle"
|
||||
// We check that the sidebar isn't expanded and has the expected width.
|
||||
assert-css: ("nav.sidebar", {"width": "50px"})
|
||||
// We now click on the button to expand the sidebar.
|
||||
|
@ -58,7 +59,7 @@ assert-css: (".src-sidebar-expanded nav.sidebar a", {"font-size": "14px"})
|
|||
// We collapse the sidebar.
|
||||
click: (10, 10)
|
||||
// We ensure that the class has been removed.
|
||||
wait-for: "html:not(.expanded)"
|
||||
wait-for: "html:not(.src-sidebar-expanded)"
|
||||
assert: "nav.sidebar"
|
||||
|
||||
// Checking that only the path to the current file is "open".
|
||||
|
|
|
@ -57,7 +57,7 @@ assert-count: (".sidebar h2", 1)
|
|||
assert-text: ("#all-types", "All Items")
|
||||
assert-css: ("#all-types", {"color": "#356da4"})
|
||||
// We check that we have the crates list and that the "current" on is "test_docs".
|
||||
assert-text: (".sidebar-elems ul.crate > li > a.current", "test_docs")
|
||||
assert-text: (".sidebar-elems ul.crate > li.current > a", "test_docs")
|
||||
// And we're also supposed to have the list of items in the current module.
|
||||
assert-text: (".sidebar-elems section ul > li:nth-child(1)", "Re-exports")
|
||||
assert-text: (".sidebar-elems section ul > li:nth-child(2)", "Modules")
|
||||
|
@ -98,7 +98,7 @@ assert-property: (".sidebar", {"clientWidth": "200"})
|
|||
assert-text: (".sidebar > .sidebar-crate > h2 > a", "lib2")
|
||||
assert-count: (".sidebar .location", 0)
|
||||
// We check that we have the crates list and that the "current" on is now "lib2".
|
||||
assert-text: (".sidebar-elems ul.crate > li > a.current", "lib2")
|
||||
assert-text: (".sidebar-elems ul.crate > li.current > a", "lib2")
|
||||
// We now go to the "foobar" function page.
|
||||
assert-text: (".sidebar-elems > section ul.block > li:nth-child(1)", "Modules")
|
||||
assert-text: (".sidebar-elems > section ul.block > li:nth-child(2)", "Structs")
|
||||
|
|
|
@ -96,4 +96,6 @@
|
|||
--scrape-example-help-hover-color: #000;
|
||||
--scrape-example-code-wrapper-background-start: rgba(255, 255, 255, 1);
|
||||
--scrape-example-code-wrapper-background-end: rgba(255, 255, 255, 0);
|
||||
--sidebar-resizer-hover: hsl(207, 90%, 66%);
|
||||
--sidebar-resizer-active: hsl(207, 90%, 54%);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue