fix(editor): drop prism.css to unblock dark-mode rendering

Prism's stock theme has

    code[class*=language-] { color:#000; background:transparent; }

at specificity (0,1,1), which beats our .editor-code (0,1,0). Result:
the editor's background was transparent and base text was #000, leaving
black-on-dark text in dark mode (unreadable).

We override every Prism token class we use (.token.comment / .string /
.keyword / .number / .operator / .identifier) via theme-aware
--color-* tokens defined in both :root and the
@media (prefers-color-scheme: dark) block of tokens.css, so prism.css
contributes nothing of value. Drop the <link> from _editor_assets.html.
Flip the form-contract tests to assert prism.css is NOT in the body so
a future accidental re-add is caught.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
mwiegand 2026-05-17 00:03:48 +02:00
parent 9a773093a8
commit bee0f07d2f
No known key found for this signature in database
3 changed files with 18 additions and 6 deletions

View file

@ -1,8 +1,14 @@
{# Editor asset bundle — include on any page that mounts a
<textarea data-editor-language>. Order matters: prism + codejar load
first, then the srccfg grammar registers itself on window.Prism, then
editor.js scans the DOM and mounts. #}
<link rel="stylesheet" href="{{ url_for('static', filename='vendor/prism.css') }}">
editor.js scans the DOM and mounts.
prism.css is intentionally NOT loaded — its base `code[class*=language-]`
rule has specificity (0,1,1) which beats our `.editor-code` (0,1,0)
and forces color:#000 + background:transparent, which renders black
text on the dark-mode page background. We override every Prism token
class we use in editor.css with --color-* tokens that follow
prefers-color-scheme, so the default Prism theme adds nothing useful. #}
<link rel="stylesheet" href="{{ url_for('static', filename='css/editor.css') }}">
<script src="{{ url_for('static', filename='vendor/prism.js') }}" defer nonce="{{ g.csp_nonce }}"></script>
<script src="{{ url_for('static', filename='vendor/codejar.js') }}" defer nonce="{{ g.csp_nonce }}"></script>

View file

@ -266,13 +266,17 @@ def test_blueprint_detail_renders_editor_assets(user_client) -> None:
body = response.get_data(as_text=True)
# Editor opts the textarea in via a data-attribute.
assert 'data-editor-language="srccfg"' in body
# All editor assets are referenced.
# All editor assets are referenced. prism.css intentionally not loaded
# — its default theme's `code[class*=language-]` selector beats our
# `.editor-code` background/color rules at higher specificity and
# breaks dark mode. We override every Prism token class we use in
# editor.css with theme-aware --color-* tokens instead.
assert "static/vendor/prism.js" in body
assert "static/vendor/prism.css" in body
assert "static/vendor/codejar.js" in body
assert "static/js/srccfg-grammar.js" in body
assert "static/js/editor.js" in body
assert "static/css/editor.css" in body
assert "static/vendor/prism.css" not in body
# Scripts are nonce'd (CSP regression guard).
assert 'nonce="' in body

View file

@ -288,12 +288,14 @@ def test_script_overlay_detail_renders_bash_editor(app, alice_id) -> None:
body = response.get_data(as_text=True)
# Editor opts the textarea in via a data-attribute.
assert 'data-editor-language="bash"' in body
# All editor assets are referenced.
# All editor assets are referenced. prism.css intentionally not loaded
# — see _editor_assets.html for the rationale (specificity conflict
# with our dark-mode tokens).
assert "static/vendor/prism.js" in body
assert "static/vendor/prism.css" in body
assert "static/vendor/codejar.js" in body
assert "static/js/srccfg-grammar.js" in body
assert "static/js/editor.js" in body
assert "static/css/editor.css" in body
assert "static/vendor/prism.css" not in body
# Scripts are nonce'd (CSP regression guard).
assert 'nonce="' in body