diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 532b98d9bb9f6..04492da82265d 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -1683,6 +1683,11 @@ details.rustdoc-toggle[open] > summary.hideme::after {
/* Media Queries */
+/*
+WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY;
+If you update this line, then you also need to update the line with the same warning
+in storage.js plus the media query with (max-width: 700px)
+*/
@media (min-width: 701px) {
/* In case there is no documentation before a code block, we need to add some margin at the top
to prevent an overlay between the "collapse toggle" and the information tooltip.
@@ -1703,6 +1708,11 @@ details.rustdoc-toggle[open] > summary.hideme::after {
}
}
+/*
+WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY
+If you update this line, then you also need to update the line with the same warning
+in storage.js plus the media query with (min-width: 701px)
+*/
@media (max-width: 700px) {
/* When linking to an item with an `id` (for instance, by clicking a link in the sidebar,
or visiting a URL with a fragment like `#method.new`, we don't want the item to be obscured
diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js
index acb1d8d7b5c8d..586c14c33a3ba 100644
--- a/src/librustdoc/html/static/js/source-script.js
+++ b/src/librustdoc/html/static/js/source-script.js
@@ -12,6 +12,12 @@
const rootPath = document.getElementById("rustdoc-vars").attributes["data-root-path"].value;
let oldScrollPosition = 0;
+function closeSidebarIfMobile() {
+ if (window.innerWidth < window.RUSTDOC_MOBILE_BREAKPOINT) {
+ updateLocalStorage("source-sidebar-show", "false");
+ }
+}
+
function createDirEntry(elem, parent, fullPath, hasFoundFile) {
const name = document.createElement("div");
name.className = "name";
@@ -48,6 +54,7 @@ function createDirEntry(elem, parent, fullPath, hasFoundFile) {
const file = document.createElement("a");
file.innerText = file_text;
file.href = rootPath + "src/" + fullPath + file_text + ".html";
+ file.addEventListener("click", closeSidebarIfMobile);
const w = window.location.href.split("#")[0];
if (!hasFoundFile && w === file.href) {
file.className = "selected";
@@ -66,7 +73,7 @@ function createDirEntry(elem, parent, fullPath, hasFoundFile) {
function toggleSidebar() {
const child = this.children[0];
if (child.innerText === ">") {
- if (window.innerWidth < 701) {
+ if (window.innerWidth < window.RUSTDOC_MOBILE_BREAKPOINT) {
// This is to keep the scroll position on mobile.
oldScrollPosition = window.scrollY;
document.body.style.position = "fixed";
@@ -76,7 +83,7 @@ function toggleSidebar() {
child.innerText = "<";
updateLocalStorage("source-sidebar-show", "true");
} else {
- if (window.innerWidth < 701) {
+ if (window.innerWidth < window.RUSTDOC_MOBILE_BREAKPOINT) {
// This is to keep the scroll position on mobile.
document.body.style.position = "";
document.body.style.top = "";
diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js
index 1c4c88344888c..0c5389d45e5b7 100644
--- a/src/librustdoc/html/static/js/storage.js
+++ b/src/librustdoc/html/static/js/storage.js
@@ -9,6 +9,11 @@ const darkThemes = ["dark", "ayu"];
window.currentTheme = document.getElementById("themeStyle");
window.mainTheme = document.getElementById("mainThemeStyle");
+// WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY
+// If you update this line, then you also need to update the two media queries with the same
+// warning in rustdoc.css
+window.RUSTDOC_MOBILE_BREAKPOINT = 701;
+
const settingsDataset = (function() {
const settingsElement = document.getElementById("default-settings");
if (settingsElement === null) {
diff --git a/src/test/rustdoc-gui/sidebar-source-code-display.goml b/src/test/rustdoc-gui/sidebar-source-code-display.goml
index c441f84a82135..8d13246a63f80 100644
--- a/src/test/rustdoc-gui/sidebar-source-code-display.goml
+++ b/src/test/rustdoc-gui/sidebar-source-code-display.goml
@@ -18,6 +18,17 @@ click: "#sidebar-toggle"
// Because of the transition CSS, we check by using `wait-for-css` instead of `assert-css`.
wait-for-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1})
+// We now check that opening the sidebar and clicking a link will leave it open.
+// The behavior here on desktop is different than the behavior on mobile,
+// but since the sidebar doesn't fill the entire screen here, it makes sense to have the
+// sidebar stay resident.
+wait-for-css: (".sidebar", {"width": "300px"})
+assert-local-storage: {"rustdoc-source-sidebar-show": "true"}
+click: ".sidebar a.selected"
+goto: file://|DOC_PATH|/src/test_docs/lib.rs.html
+wait-for-css: (".sidebar", {"width": "300px"})
+assert-local-storage: {"rustdoc-source-sidebar-show": "true"}
+
// Now we check the display of the sidebar items.
show-text: true
@@ -152,3 +163,23 @@ click: "#sidebar-toggle"
wait-for-css: (".sidebar", {"width": "0px"})
// The "scrollTop" property should be the same.
assert-window-property: {"pageYOffset": "2519"}
+
+// We now check that opening the sidebar and clicking a link will close it.
+// The behavior here on mobile is different than the behavior on desktop,
+// but common sense dictates that if you have a list of files that fills the entire screen, and
+// you click one of them, you probably want to actually see the file's contents, and not just
+// make it the current selection.
+click: "#sidebar-toggle"
+wait-for-css: ("#source-sidebar", {"visibility": "visible"})
+assert-local-storage: {"rustdoc-source-sidebar-show": "true"}
+click: ".sidebar a.selected"
+goto: file://|DOC_PATH|/src/test_docs/lib.rs.html
+wait-for-css: ("#source-sidebar", {"visibility": "hidden"})
+assert-local-storage: {"rustdoc-source-sidebar-show": "false"}
+// Resize back to desktop size, to check that the sidebar doesn't spontaneously open.
+size: (1000, 1000)
+wait-for-css: ("#source-sidebar", {"visibility": "hidden"})
+assert-local-storage: {"rustdoc-source-sidebar-show": "false"}
+click: "#sidebar-toggle"
+wait-for-css: ("#source-sidebar", {"visibility": "visible"})
+assert-local-storage: {"rustdoc-source-sidebar-show": "true"}