Skip to content

feat(themes): add a "None" theme that leaves YouTube's styling alone - #4330

Open
Mihailchik wants to merge 1 commit into
code-charity:masterfrom
Mihailchik:theme-none
Open

feat(themes): add a "None" theme that leaves YouTube's styling alone#4330
Mihailchik wants to merge 1 commit into
code-charity:masterfrom
Mihailchik:theme-none

Conversation

@Mihailchik

Copy link
Copy Markdown

Closes #4329.

Adds a None theme that leaves YouTube's own styling alone, for people who theme it with Stylus or similar.

Why the extension fights user styles today

Picking "YouTube's Light" does not actually mean "don't restyle".

  • The radio stores light, and every setting is mirrored to an it-* attribute on <html>, so the page gets it-theme="light".
  • The rules in styles.css are written as html[it-theme]:not([it-theme=default]), so they match light and force the page background (ytd-app, #page, #content, …) and the link colours with !important.
  • setTheme('light') also clears YouTube's PREF f6 dark-mode cookie and removes the dark attribute.

So there was no setting under which the extension stays out of theming, and that is what the report runs into.

Changes

  • Menu: a "None" radio after YouTube's Dark, with search tags (off, disable, stylus, userstyle). It reuses the existing none string, which is already translated in 43 of 65 locales, so no new strings were needed.
  • setTheme: 'none' shares the 'default' branch. It drops the custom palette and restores the cinematics glow. It never touches the dark attribute, the masthead or the PREF cookie.
  • styles.css: the ten "any theme but default" selectors now also exclude none. Without that, it-theme="none" would still match them and restyle the page.
  • Menu swatch: .satus-label--none-theme gets the same row height as the other themes and a dashed outline instead of a colour.

The dark/light switch in the header already handles this. It treats none as a light theme and restores it when you toggle back. The load-time heuristic that stores dark only fires when no theme is stored at all, so it leaves none alone.

Deliberately left alone

The light-mode tonal-button rule (html:not([dark]):not([it-theme=black])…, around styles.css:2166) still applies with none. It compensates for an unconditional rule just above it, which makes those buttons translucent white. Excluding none there would leave them nearly invisible in light mode.

More generally, the extension's feature styles that are not tied to a theme still apply. This option switches off the theme layer, not every stylesheet the extension ships.

Tests

New tests/unit/theme-none.test.js, following the style of the existing themes-menu and theme-cookie tests:

  • the menu offers a none radio in the theme group;
  • setTheme with none leaves the dark attribute, the masthead, the PREF cookie and storage untouched;
  • it still drops the custom palette and restores cinematics;
  • a guard over styles.css: every html[it-theme]:not([it-theme=default]) selector must also exclude none, so a rule added later cannot quietly restyle the page again. I checked that the guard fails when one exclusion is removed; the failure names the offending selector.

npx jest: 117 passed (113 before, plus these 4).

Not verified

I did not load the unpacked extension in a browser. The behaviour is covered by the unit tests above, but a quick manual check with Stylus active would be worth doing before merge.

Unrelated, for what it's worth

The CI step npx eslint --config=tests/eslint_rules.config.mjs currently fails before linting anything. ESLint 8 reads the flat .mjs config as a legacy config and throws a YAMLException, and continue-on-error hides it. Running it with ESLINT_USE_FLAT_CONFIG=true works. With that flag, this change adds no new findings.

There was no way to tell the extension to stay out of theming. The first
radio, "YouTube's Light", stores `light`, and because every setting is
mirrored to an `it-*` attribute, `html[it-theme=light]` matches the rules
written as `html[it-theme]:not([it-theme=default])`, which force page
backgrounds and link colours with !important. setTheme('light') also clears
YouTube's PREF f6 cookie and removes the `dark` attribute. Users who theme
YouTube with Stylus ended up fighting the extension.

- Menu: a "None" radio after YouTube's Dark, reusing the existing `none`
  string, which is already translated in 43 of 65 locales.
- setTheme: 'none' shares the 'default' branch. It drops the custom palette
  and restores the cinematics glow, and never touches `dark`, the masthead
  or the PREF cookie.
- styles.css: the ten "any theme but default" selectors also exclude
  `none`, since `it-theme="none"` would otherwise match them.

The light-mode tonal-button rule is left as it is. It compensates for an
unconditional rule above it, and excluding `none` there would leave those
buttons nearly invisible in light mode.

Closes code-charity#4329
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

💡Ability to Disable/Choose No Theme

1 participant