Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Navigating back/forward in rustdocs causes theme change if page is restored from bfcache #94250

Closed
thanatos opened this issue Feb 22, 2022 · 2 comments · Fixed by #107177
Closed
Labels
C-bug Category: This is a bug.

Comments

@thanatos
Copy link
Contributor

I normally use the "dark" theme for docs.rs ; however, lately, if I hit "back" to go backwards, the previous page is now in light mode, not dark mode. Refreshing the page fixes it, but is annoying, of course.

@thanatos thanatos added the C-bug Category: This is a bug. label Feb 22, 2022
@jyn514
Copy link
Member

jyn514 commented Feb 24, 2022

Please file this under rust-lang/docs.rs.

@thanatos thanatos changed the title Navigating back/forward in docs.rs causes theme changes Navigating back/forward in rustdocs causes theme changes Jan 18, 2023
@thanatos thanatos changed the title Navigating back/forward in rustdocs causes theme changes Navigating back/forward in rustdocs causes theme change if page is restored from bfcache Jan 18, 2023
@thanatos
Copy link
Contributor Author

thanatos commented Jan 18, 2023

I did some digging: this happens locally as well as in docs.rs. Since rustdoc is in this repo, I think this is the right place for it. (These sorts of things get encountered on docs.rs first … as that gets updated far before my local toolchain.)

The bug is around here:

function switchToSavedTheme() {
switchTheme(
window.currentTheme,
window.mainTheme,
getSettingValue("theme") || "light",
false
);
}

Essentially, there are two paths through this file:

  1. On initial page load, we run the top-level JavaScript: in particular, we call updateSystemTheme() which detects the system theme (dark, on my system) and sets the page theme appropriately.
  2. Possibly (it's up to the UA) on navigation, such as back/forward — if the page is restored from bfcache , the top level JS isn't run. (As the page is stlil, in essence, "alive".) Instead, a pageshow event fires, and that calls the highlighted method above, switchToSavedTheme. That method unilaterally sets a theme — but never obeys the system theme, and thus, we end up with buggy theme switch. (On my system, the getSettingValue("theme") will return null, and so it goes with the default of 'light', despite the prefers-dark-theme pref.)

What I'm not getting is why that event handler is even there. (Edit: ugh, see the next paragraph. The committer of the commit that introduced the bug wrote a good commit message!) bfcache persists the state of the page … including, AFAICT, the adjustments that switchTheme makes to set the theme. I.e., if I comment out the event handler, I get the correct behavior on pageshow events. (I.e., if it's a persisted === true pageshow event, why are we setting the theme? It's persisted.)

So what's the event handler event there for? The commit tells us:

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.

That's true: the theme from the settings might have changed while the page was cached. But we only want to update the theme if that's the case. (In my case, it isn't.) (And the earlier remark about "completely recompute the desired theme" holds, here.)

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jan 30, 2023
…e, r=notriddle

Keep all theme-updating logic together

Prior to this PR, if the page is restored from the browser bfcache¹, we call `switchToSavedTheme`. But `switchToSavedTheme` never looks at the `use-system-theme` preference. Further, if it can't find a saved theme, it will fall back to the default of "light".

For a user with cookies disabled² whose preferred color scheme is dark, this means the theme will wobble back and forth between dark and light. The sequence that occurs is,

1. The page is loaded. During a page load, we consult `use-system-theme`: as cookies are disabled, this preference is unset. The default is true.

   Because the default is true, we look at the preferred color scheme: for our example user, that's "dark". **The page theme is set to dark.** We'll attempt to store these preferences in localStorage, but fail due to cookies being disabled.

2. The user navigates through the docs. Subsequent page loads happen, and the same process in step 1 recurs. Previous pages are (potentially) put into the bfcache.

3. The user navigates backwards/forwards, causing a page in bfcache to be pulled out of cache. The `pageShow` event handler is triggered. However, this calls `switchToSavedTheme`: this doesn't consider the system theme, as noted above. Instead, it only looks for a saved theme. However, with cookies disabled, there is none. It defaults to light. **The page theme is set to light!** The user wonders why the dark theme is lost.

There are effectively two functions trying to determine and apply the correct theme: `updateSystemTheme` and `switchToSavedTheme`. Thus, we merge them into just one: `updateTheme`. This function contains all the logic for determining the correct theme, and is called in all circumstances where we need to set the theme:

* The initial page load
* If the browser preferred color scheme (i.e., light/dark mode) is changed
* If the page is restored from bfcache
* If the user updates the theme preferences (i.e., in `settings.js`)

Fixes rust-lang#94250.

¹bfcache: https://web.dev/bfcache/ The bfcache is used to sleep a page, if the user navigates away from it, and to restore it from cache if the user returns to it.

²Note that the browser preference that enables/disables cookies really controls many forms of storage. The same preference thus also affects localStorage. (This is so a normal browser user doesn't need to understand the distinction between "cookies" and "localStorage".)
@bors bors closed this as completed in 727a1fd Jan 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants