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

Keep all theme-updating logic together #107177

Merged
merged 3 commits into from
Jan 30, 2023

Conversation

thanatos
Copy link
Contributor

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 #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".)

The comment says that it is called from main.js, but there don't seem to
be any references to it in main.js.

A quick ripgrep says there are no references in all of librustdoc.
@rustbot
Copy link
Collaborator

rustbot commented Jan 22, 2023

r? @GuillaumeGomez

(rustbot has picked a reviewer for you, use r? to override)

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels Jan 22, 2023
@rustbot
Copy link
Collaborator

rustbot commented Jan 22, 2023

Some changes occurred in HTML/CSS/JS.

cc @GuillaumeGomez, @Folyd, @jsha

@GuillaumeGomez
Copy link
Member

Thanks for working on this! The changes look good to me but I need to run tests locally too, to be sure I didn't miss something. In the meantime, cc @notriddle

@thanatos thanatos changed the title Keep all theme-updating logic together] Keep all theme-updating logic together Jan 22, 2023
@notriddle
Copy link
Contributor

I've run tests locally: I've managed to reproduce the bug in Safari and Chromium. This fixes it in both, apparently.

I haven't managed to reproduce the problem in Firefox. I think rustdoc trips over some compat heuristic and isn't getting bfcached, so the whole point is moot.

isDarkMode = () => mql.matches;

if (mql.addEventListener) {
mql.addEventListener('change', updateTheme);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the eslint to pass, you'll need to use double-quotes

Suggested change
mql.addEventListener('change', updateTheme);
mql.addEventListener("change", updateTheme);

There's a few other spots that need it, too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I'll probably not get back to this until the weekend, but when that rolls around, I'll fix this up.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@notriddle Thanks again, I think I've fixed this & the other errors causing es-lint failures.

Copy link
Contributor

@notriddle notriddle Jan 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool. Can you squash the fixup commits with the one before it?

https://rustc-dev-guide.rust-lang.org/git.html?highlight=Git#advanced-rebasing gives some information on how to do that.

@rust-log-analyzer

This comment has been minimized.

@thanatos
Copy link
Contributor Author

thanatos commented Jan 24, 2023

I've run tests locally: I've managed to reproduce the bug in Safari and Chromium. This fixes it in both, apparently.

I haven't managed to reproduce the problem in Firefox. I think rustdoc trips over some compat heuristic and isn't getting bfcached, so the whole point is moot.

Interesting. Firefox is my current browser, so that's where I see it. My rough understanding though is that entering/leaving bfcache isn't guaranteed to happen, so I suppose it's not out of spec to not see it, too, but it seems to happen pretty reliably for me, so that is still a bit surprising.

(Though, if FF does have a heuristic that it uses … and it happens to be something like "tab pressure", I'm also one of those people with hundreds of tabs open at a time. Although most of them are "snoozed 💤" due to an extension…)

@notriddle
Copy link
Contributor

Huh. Weird.

In any case, we've covered all the major engines between us two, so r=me with the eslint stuff fixed.

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".)
@notriddle
Copy link
Contributor

@bors r+ rollup

@bors
Copy link
Contributor

bors commented Jan 30, 2023

📌 Commit 727a1fd has been approved by notriddle

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jan 30, 2023
bors added a commit to rust-lang-ci/rust that referenced this pull request Jan 30, 2023
…iaskrgr

Rollup of 7 pull requests

Successful merges:

 - rust-lang#107125 (Add and use expect methods to hir.)
 - rust-lang#107172 (Reimplement NormalizeArrayLen based on SsaLocals)
 - rust-lang#107177 (Keep all theme-updating logic together)
 - rust-lang#107424 (Make Vec::clone_from and slice::clone_into share the same code)
 - rust-lang#107455 (use a more descriptive name)
 - rust-lang#107465 (`has_allow_dead_code_or_lang_attr` micro refactor)
 - rust-lang#107469 (Change turbofish context link to an archive link)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit d1320a5 into rust-lang:master Jan 30, 2023
@rustbot rustbot added this to the 1.69.0 milestone Jan 30, 2023
@thanatos thanatos deleted the fix-doc-errant-light-theme branch January 31, 2023 04:52
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request Jan 31, 2023
…ddle

Clean up eslint annotations and remove unused JS function

Thanks to rust-lang#107177 I realized that some eslint annotations might be unneeded so I cleaned them up. I also removed the unused function while we wait for rust-lang#107177 to be updated.

r? `@notriddle`
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request Jan 31, 2023
…ddle

Clean up eslint annotations and remove unused JS function

Thanks to rust-lang#107177 I realized that some eslint annotations might be unneeded so I cleaned them up. I also removed the unused function while we wait for rust-lang#107177 to be updated.

r? ``@notriddle``
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Navigating back/forward in rustdocs causes theme change if page is restored from bfcache
6 participants