From b30725eab7cbc898dbdb851d5977a352d1dd2187 Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Sun, 23 Jan 2022 13:04:17 -0800 Subject: [PATCH] Update theme on pageshow event When a user goes forward or back, the page may be rendered from the back/forward cache (https://web.dev/bfcache/) rather than from scratch. If they have changed theme in the meantime, that means seeing an incorrect theme on the page they went forward or back to. The `pageshow` event fires on such navigations, so we can update the theme based on that event. --- src/librustdoc/html/static/js/storage.js | 31 +++++++++++++++++++----- 1 file changed, 25 insertions(+), 6 deletions(-) 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); + } +});