diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js
index 2394df4c715d4..06bb34eb11573 100644
--- a/src/librustdoc/html/static/js/storage.js
+++ b/src/librustdoc/html/static/js/storage.js
@@ -216,6 +216,15 @@ var updateSystemTheme = (function() {
};
})();
+function switchToSavedTheme() {
+ switchTheme(
+ window.currentTheme,
+ window.mainTheme,
+ getSettingValue("theme") || "light",
+ false
+ );
+}
+
if (getSettingValue("use-system-theme") !== "false" && window.matchMedia) {
// update the preferred dark theme if the user is already using a dark theme
// See https://github.com/rust-lang/rust/pull/77809#issuecomment-707875732
@@ -228,10 +237,20 @@ if (getSettingValue("use-system-theme") !== "false" && window.matchMedia) {
// call the function to initialize the theme at least once!
updateSystemTheme();
} else {
- switchTheme(
- window.currentTheme,
- window.mainTheme,
- getSettingValue("theme") || "light",
- false
- );
+ switchToSavedTheme();
}
+
+// If we navigate away (for example to a settings page), and then use the back or
+// forward button to get back to a page, the theme may have changed in the meantime.
+// But scripts may not be re-loaded in such a case due to the bfcache
+// (https://web.dev/bfcache/). The "pageshow" event triggers on such navigations.
+// Use that opportunity to update the theme.
+// We use a setTimeout with a 0 timeout here to put the change on the event queue.
+// For some reason, if we try to change the theme while the `pageshow` event is
+// running, it sometimes fails to take effect. The problem manifests on Chrome,
+// specifically when talking to a remote website with no caching.
+window.addEventListener("pageshow", function(ev) {
+ if (ev.persisted) {
+ setTimeout(switchToSavedTheme, 0);
+ }
+});