Skip to content

feat: add visual library settings panel (highlight.js, MathJax, Mermaid, JoyPixels) - #278

Open
itznan wants to merge 10 commits into
ThisIs-Developer:mainfrom
itznan:feat/visual-settings
Open

itznan wants to merge 10 commits into
ThisIs-Developer:mainfrom
itznan:feat/visual-settings

Conversation

@itznan

@itznan itznan commented Oct 10, 2026

Copy link
Copy Markdown

Summary

Implements a configurable visual library settings panel allowing users to customize rendering appearances for highlight.js, MathJax, Mermaid, and JoyPixels emojis. Settings update live without full page reload, persist across reloads via localStorage (mdv.visualSettings.v1), and support light/dark modes and mobile viewports.

Closes #129

Configurable Settings & Options

  • highlight.js theme (hljsTheme): auto (follows app light/dark mode) + 14 themes (github, github-dark, monokai, dracula, atom-one-dark, atom-one-light, solarized-dark, solarized-light, vs, vs2015, nord, tokyo-night-dark, tokyo-night-light, default).
  • MathJax font (mathFont): 10 mathematical fonts (mathjax-modern, mathjax-tex, mathjax-stix2, mathjax-asana, mathjax-bonum, mathjax-dejavu, mathjax-fira, mathjax-pagella, mathjax-schola, mathjax-termes).
  • Mermaid theme (mermaidTheme): auto, default, neutral, dark, forest, base.
  • Mermaid look (mermaidLook): classic, handDrawn.
  • JoyPixels skin tone (emojiSkinTone): default (yellow), tone1 - tone5 (Fitzpatrick modifiers). Preserves explicit tones and leaves unsupported emojis untouched.

Library & Architecture Updates

  • MathJax 4 Upgrade: MathJax upgraded from 3.2.2 to MathJax 4 (4.0.0-beta.7) with SRI verification (sha384-2f5bAKjuFIbbQ+0O9aSu5W1OyLA4q80QrDEvjXDwJexjU9VqoJhMgw19pYVpSJab) to enable dynamic on-demand mathematical font switching.
  • Store & Adapters: Modular architecture separating UI/store (visual-settings-store.js) from library adapters (visual-settings-adapters.js), with schema validation and subscriber events.
  • Accessibility & UI: Modal dialog with Escape key dismissal, focus trapping, header toolbar trigger, workspace menu, and mobile drawer integration.

Local Testing & Validation

Run locally:

npm install && npm start

Validation results:

  • npm run build: Static build smoke check and SEO sitemap check passed.
  • npm run test:unit: 32/32 unit tests passed (including store and adapter tests).
  • PLAYWRIGHT_CHANNEL=chrome npx playwright test tests/e2e/visual-settings.spec.js: 3/3 passed (dialog lifecycle, live preview updates/persistence/reset, dark mode/mobile).

Known Limitations

  • Offline / Desktop MathJax Fonts: MathJax dynamic alternate fonts require initial network fetch from CDN; offline/desktop environments fallback seamlessly to the bundled Modern TeX font.
  • Beta Library: MathJax 4 is currently in 4.0.0-beta.7.

@vercel

vercel Bot commented Oct 10, 2026

Copy link
Copy Markdown

@itznan is attempting to deploy a commit to the Developer Labs Team on Vercel.

A member of the Team first needs to authorize it.

@vercel

vercel Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
markdown-viewer Ready Ready Preview Oct 11, 2026 1:28pm UTC

This comment was marked as outdated.

@ThisIs-Developer ThisIs-Developer left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Hi @itznan,

First of all, this is really great work. I honestly never dared to touch this issue because of how many rendering libraries are involved, so I really appreciate the effort you’ve put into it.

I haven’t done a full review yet. I only tested the PR briefly from a user-experience perspective, but I noticed a few concerns that I want to share before going deeper.

  1. MathJax style changes don’t seem to apply correctly.
    When I select another MathJax style, the rendered math often doesn’t change. I need to refresh, and even then it doesn’t always seem to apply.

  2. LaTeX rendering feels quite slow.
    LaTeX rendering time is noticeably higher.

  3. The Visual Settings panel becomes laggy with large LaTeX documents.
    I imported a Markdown file containing many different LaTeX expressions, then opened the Visual Settings menu. The application became quite unresponsive, and even scrolling inside the settings panel was hanging.

  4. Emoji skin tone didn’t work for me.
    I changed the skin tone and also tried refreshing, but I couldn’t see the expected change.

I also ran an additional code review (Codex) and found a few technical concerns:

Codex Review — 4 P2 Issues Found in PR #278

1. Math font selection does not change rendered math.

Selecting STIX Two updates the configuration, but the real MathJax renderer remains MathJaxModern. Rebuilding the output jax retains the existing font data.

Reference: [visual-settings-adapters.js:209](https://github.com/ThisIs-Developer/Markdown-Viewer/pull/278/files)

2. Dark syntax themes become difficult to read in light mode.

With Monokai selected, both <pre> and <code> have transparent backgrounds, leaving light text (#ddd) on the application's pale background (#f6f8fa). The selected theme's background needs to override the existing preview styles.

Reference: [visual-settings-adapters.js:109](https://github.com/ThisIs-Developer/Markdown-Viewer/pull/278/files)

3. Three syntax themes request nonexistent stylesheets.

Dracula, Solarized Dark, and Solarized Light all return HTTP 404. Their files are under styles/base16/, while the adapter constructs URLs directly under styles/.

Reference: [visual-settings-adapters.js:131](https://github.com/ThisIs-Developer/Markdown-Viewer/pull/278/files)

4. Settings do not refresh the secondary split preview.

With :wave: in both documents, selecting tone3 changes the primary preview to 👋🏽 while the secondary remains 👋. The settings handler only rerenders the primary preview; it also needs to invalidate and refresh the secondary.

Reference: [script.js:24174](https://github.com/ThisIs-Developer/Markdown-Viewer/pull/278/files)

If you would like to continue improving this PR, let me know. I can do a much deeper review, and we can work through these issues together. This is only my initial review.

I also want to ask your opinion about the feature itself. From my perspective, I’m not completely sure how many users actually need things like changing MathJax fonts or switching between many rendering themes. I understand that different users have different preferences, so I’d genuinely like to know your perspective as well. Do you think this level of visual customization is something Markdown Viewer users would actively use?

Thanks again for taking on such a complex feature.

@ThisIs-Developer ThisIs-Developer added accessibility enhancement New feature, improvement, or usability enhancement. ui/ux User interface, layout, interaction, usability, or visual improvements. labels Oct 10, 2026 — with ChatGPT Codex Connector

@ThisIs-Developer ThisIs-Developer left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Codex review

Found five P2 issues that should be addressed before merging: math font changes do not reach the renderer, Mermaid ignores the export theme, Docker omits the new scripts, three highlight.js themes use nonexistent URLs, and the secondary document preview retains the previous settings. Details and reproduction evidence are attached inline.

Reviewed commit 2296a16f4bdb81666d307e3648b44914d0a20a40.

Validation:

  • All 32 unit tests passed.
  • All three new visual-settings Chromium tests passed.
  • The existing dark vector PDF keeps tables and diagrams dark in print media test failed on this PR and passed when using the base commit's application files (9ce2de9).
  • Browser checks with the real libraries reproduced the MathJax font and secondary-preview issues. The Docker asset omission was verified against its COPY list and reproduced by serving the missing scripts as 404s.
  • The build passed after temporarily normalizing Windows line endings in sitemap.xml; its content already matches the base branch. No source changes were retained.

Comment on lines +209 to +213
const newOutputJax = window.MathJax.startup.getOutputJax();
if (newOutputJax) {
window.MathJax.startup.output = newOutputJax;
if (typeof window.MathJax.startup.getDocument === 'function') {
window.MathJax.startup.document = window.MathJax.startup.getDocument();

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

[P2] Activate the selected font data before rebuilding MathJax

After math has rendered, selecting STIX Two or TeX (Classic) updates the setting and downloads the component, but getOutputJax() still uses the existing MathJax.config.chtml.fontData. Browser verification with the real MathJax 4 beta showed both the font constructor and configured font data remaining MathJaxModern, with the same MJX-MM glyph fonts after either selection. Activate the newly loaded font data before recreating the output renderer so the setting changes the rendered math.

Comment on lines +420 to +422
getMermaidConfig: (themeOverride) => ({
theme: resolveMermaidThemeName(_activeMermaidTheme),
look: _activeMermaidLook === 'handDrawn' ? 'handDrawn' : 'classic'

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

[P2] Preserve the export theme when resolving Auto

getMermaidConfig() ignores themeOverride, so with Mermaid set to Auto, exporting a dark PDF from a light workspace produces light Mermaid diagrams. The existing tests/e2e/export.spec.js test dark vector PDF keeps tables and diagrams dark in print media fails on this PR: node/text colors remain the light palette. The same test passes with the base commit's application files. Resolve Auto using the supplied export theme when present, falling back to the workspace theme otherwise.

Comment thread index.html
Comment on lines +2401 to +2402
<script src="visual-settings-adapters.js" defer></script>
<script src="visual-settings-store.js" defer></script>

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

[P2] Include both new scripts in the Docker image

Dockerfile copies an explicit list of files and was not updated to include either of these scripts. Docker deployments therefore return 404 for both URLs, leaving the store and adapters undefined. Reproducing those missing assets produces a Visual Library Settings panel with five empty dropdowns, so the new feature cannot be used in the Docker distribution. Add both files to the Docker build.

Comment thread visual-settings-adapters.js Outdated
Comment on lines +130 to +131
const effectiveName = resolveHljsThemeName(_activeHljsTheme);
const href = `${HLJS_CDN_BASE}${effectiveName}.min.css`;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

[P2] Map the Base16 themes to their actual stylesheet paths

The generated URLs for dracula, solarized-dark, and solarized-light return 404 in the pinned highlight.js 11.9.0 release. These stylesheets are under styles/base16/, where all three URLs return 200. Selecting any of these options saves the preference but does not load the requested palette. Map these options to the correct asset paths instead of treating every theme as a file directly under styles/.

Comment thread script.js Outdated
console.warn('Error applying visual setting via adapter:', err);
}
}
renderMarkdown({ force: true, forceAdvancedPostProcess: true });

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

[P2] Refresh the secondary document preview after settings changes

This rerenders only the primary preview. Open two documents side by side in preview mode, include :wave: in each, and select skin tone tone3: the primary wave changes to the selected tone while the secondary remains yellow. The secondary preview also caches by document content, so merely calling its render function without invalidating that cache will retain the old appearance. Invalidate and refresh the secondary preview when rendering settings change.

@itznan

itznan commented Oct 11, 2026 •

Copy link
Copy Markdown
Author

Hi @ThisIs-Developer,

Thank you for the thorough initial review and feedback! I've addressed all the UX concerns and Codex issues, and pushed the updates to the PR (e5a4a61).

Here is a summary of what was improved and how each issue was resolved:

1. MathJax Font Switching & Live Application (P1)

  • Problem: Changing MathJax styles retained MathJaxModern because MathJax.config.chtml.fontData was not being updated prior to recreating the output jax.
  • Solution: The adapter now loads the font component, extracts the constructor from MathJax._.output.fonts[fontName].chtml_ts, and assigns it to MathJax.config.chtml.fontData before invoking getOutputJax(). startup.output and startup.document are updated and re-typeset. If loading fails or offline, it gracefully falls back to bundled Modern.
  • Verification: Verified live switching and persistence across reload via unit tests and E2E browser tests inspecting the rendered MJX-STX glyphs.

2. Dark Vector PDF Mermaid Regression (P2)

  • Problem: getMermaidConfig() ignored themeOverride, producing light diagrams in dark PDF exports from a light workspace.
  • Solution: resolveMermaidThemeName() now prioritizes themeOverride when resolving auto, ensuring the export theme takes precedence.
  • Verification: export.spec.js ("dark vector PDF keeps tables and diagrams dark in print media") now passes cleanly.

3. Docker & Distribution Asset Completeness (P3)

  • Problem: visual-settings-adapters.js and visual-settings-store.js were missing from the Dockerfile COPY list, resulting in 404s and empty dropdowns.
  • Solution: Added both scripts (and required runtime SEO modules) to Dockerfile and precached them in sw.js.
  • Verification: Verified in an isolated container simulation; all local assets return HTTP 200 and all 5 settings dropdowns populate properly.

4. Highlight.js Base16 Stylesheet 404s (P4)

  • Problem: Dracula, Solarized Dark, and Solarized Light returned 404 because they live under styles/base16/ in highlight.js 11.9.0.
  • Solution: Added explicit mapping in HLJS_THEME_PATHS so Base16 themes resolve to their correct paths.
  • Verification: All 14 syntax themes verified to return HTTP 200.

5. Dark Syntax Theme Contrast in Light Mode (P5)

  • Problem: Monokai and other dark themes had transparent <pre>/<code> backgrounds, leaving light text illegible against the light workspace.
  • Solution: Added dynamic helper styling (#mdv-hljs-style-helper) with a DOM probe to read computed background colors and enforce appropriate backgrounds and contrast across light mode, dark mode, and print/PDF media.
  • Verification: Verified dark themes apply their theme background (e.g. #272822 for Monokai) rather than remaining transparent.

6. Secondary Split Document Preview Synchronization (P6)

  • Problem: Changing visual settings only refreshed the primary preview; the secondary preview cached by content string and remained stale.
  • Solution: In applyVisualSettings(), documentSplitPreviewContent = null is now invalidated and renderDocumentSplitView() is called.
  • Verification: Verified in split preview E2E test with dual documents containing emoji, math, Mermaid diagrams, and code blocks.

7. Emoji Skin Tone Application (P7)

  • Problem: Emoji skin tones didn't visibly update or persist reliably.
  • Solution: Fixed tone candidate resolution, ensured JoyPixels wrapper avoids duplicate suffix appending, and confirmed shortcodes and Unicode resolve accurately.
  • Verification: Verified tone changes (e.g. :wave: -> tone3 => 👋🏽) apply and persist across reload.

8. LaTeX Performance & Settings Panel Responsiveness (P8)

  • Problem: UI lag and hanging when opening settings or scrolling with large LaTeX documents.
  • Solution:
    • Debounced setting changes (50ms) to coalesce rapid updates into a single render pass.
    • Bypassed Markdown re-rendering for stylesheet-only updates like hljsTheme (needsRerender('hljsTheme') === false).
    • Opening the settings modal no longer triggers unnecessary document re-renders.
  • Verification: Benchmarked on an 80+ equation LaTeX document: modal scrolling executes smoothly (14ms for 10 scroll events) and 5 rapid consecutive changes coalesce in 368ms.

9. Build Housekeeping (P9)

  • Handled Windows CRLF line-ending normalization in seo/generate-sitemap.mjs and build check scripts. npm run build and all 32 unit tests pass cleanly.

10. DeepScan Static Analysis

  • Resolved minor unused declarations and redundant condition checks flagged by DeepScan (e5a4a61), keeping all static analysis checks green.

Regarding Your Question on Customization Value

Regarding your point about whether this level of customization is something users actively need:

I think you raise a valid consideration. My perspective:

  1. On-Demand Loading: None of the alternative themes or fonts bloat the initial bundle—they are only loaded on-demand via CDN when a user explicitly chooses them. The default configuration remains lightweight and fast out of the box.
  2. Lightweight vs Heavy Settings: Syntax theme switching and emoji skin tones are practically free in terms of runtime cost and are popular in editor tools. MathJax fonts are heavier, but academic and technical writers often specifically request STIX Two or AMS-compatible fonts for paper and documentation drafting.
  3. If preferred, we could also simplify the panel in the future to expose only the most requested options (e.g. popular syntax themes and emoji tones) while keeping the underlying adapter architecture modular.

Could you please check out the latest changes and let me know if this is what you were looking for? Happy to make any further adjustments!

@ThisIs-Developer

Copy link
Copy Markdown
Owner

Hi @itznan,

First of all, thank you for resolving all the issues. That’s really great, and I appreciate the amount of work you’ve put into this.

Coming to the question of whether we should continue with this feature—yes, I’d like to continue with it.

The perspective you shared also makes sense to me. This does not seem like a heavy feature that would significantly affect the overall performance of the application, especially since the additional themes and fonts are loaded only when needed. Many other editors and applications also provide this kind of customization, so I think it makes sense for Markdown Viewer to support it as well.

From a UX and user perspective, I tested the latest version again and everything looks much better now.

I’ve also given the updated code to Codex for another code review, and I’ll review those results and share the findings with you as soon as possible.

Thanks again for picking up this issue, continuing with the feature, and actually making it real. I really appreciate the effort you’ve put into it.

@ThisIs-Developer ThisIs-Developer left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Codex review — six confirmed issues

Reviewed PR #278 at e5a4a6104022cf0aeafccd52819fa6bf44f6627f against base 9ce2de94c167deb76ccadbb976654791a059d5e9. The PR head was rechecked before posting and is unchanged. The six current findings are attached inline with reproduction details, observed behavior, and suggested fixes.

# Priority Finding Code reference
1 P1 Keep the desktop MathJax bundle compatible with the new configuration desktop-app/resources/js/script.js:4144–4145
2 P2 Switch math font resources along with the font class visual-settings-adapters.js:325–326
3 P2 Resolve automatic code colors against the PDF export theme visual-settings-adapters.js:190–195
4 P2 Remove the built-in token palette when applying a syntax theme visual-settings-adapters.js:217–223
5 P2 Canonicalize emoji aliases before adding a skin-tone suffix visual-settings-adapters.js:444–450
6 P2 Load Modern when resetting after an alternate-font reload visual-settings-adapters.js:292–296

Validation and coverage

  • npm run build: passed.
  • npm run test:unit: 32/32 passed.
  • Chromium/Chrome Playwright coverage across visual-settings.spec.js, export.spec.js, rich-content.spec.js, startup-loading.spec.js, and review-mode.spec.js: 34/34 passed.
  • Additional browser checks used the real rendering libraries and inspected network responses, computed token colors, font classes/resources, and rendered output. These checks exposed failures that the existing passing tests do not assert.
Feature Additional checks Result
Syntax highlighting All 15 choices in light and dark app modes; identical highlighted JavaScript compared with the selected stylesheet in isolation All stylesheets loaded; 10 choices had token-color conflicts in both modes (finding 4)
MathJax All 10 font choices; live switching, reload, representative equations, and reset Live resource switching and reset failures confirmed (findings 2 and 6)
Desktop LaTeX compatibility Base versus PR configuration using the actual bundled MathJax 3.2.2 dependency Default math startup regression confirmed (finding 1)
PDF export Auto syntax highlighting with light app/dark export and dark app/light export; base comparison Code-block export theme regression confirmed (finding 3)
Mermaid 6 themes × 2 looks × 2 app modes × 4 diagram types (flowchart, sequence, class, pie): 96 rendered SVGs; representative reload/reset All tested SVGs rendered with valid dimensions and no console/page errors; no additional Mermaid defect confirmed
Emoji Default plus 5 skin tones in both app modes; canonical names, aliases, explicit tones, unsupported names, native Unicode, and inline code Canonical examples followed the setting; aliases failed (finding 5); explicit tones and protected/unsupported content were preserved

Mermaid's HandDrawn appearance varies by supported diagram type; an unchanged sequence/pie appearance alone was not treated as a PR regression.

Assessment: the feature is not ready to be described as working for every option. These are all six confirmed findings from this review, not a guarantee that no other defects exist. Browser verification was performed in Chromium/Chrome with representative fixtures; Firefox, WebKit, every document/option combination, and a packaged native desktop run were outside the verified coverage.

Comment on lines +4144 to +4145
chtml: {
font: initialFont

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

[P1] Keep the desktop MathJax bundle compatible with the new configuration

The desktop configuration now passes a font name string to chtml.font, but desktop-app/prepare.js:274–275 still downloads MathJax 3.2.2 and the desktop loader uses that local bundle. MathJax 3 expects a font object here. This breaks ordinary desktop LaTeX rendering even when the user leaves the default font selected.

Reproduction: render $$x^2$$ using the desktop dependency version with this configuration. In an isolated real-library comparison, the base configuration resolves startup and renders one equation; the PR configuration reports MathJax(?): t.font.adaptiveCSS is not a function, leaves startup pending, never exposes typesetPromise, and renders zero equations. The application harness with the same dependency substitution also leaves raw LaTeX visible.

Suggested fix: update the desktop bundle and configuration together, or use version-compatible configuration for the existing desktop dependency. This was reproduced against the actual 3.2.2 library in a browser harness; a packaged native desktop application was not run.

Comment on lines +325 to +326
if (fontClass) {
window.MathJax.config.chtml.fontData = fontClass;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

[P2] Switch math font resources along with the font class

Changing chtml.fontData and rebuilding the output jax retains font resource configuration from the previous font. The selected font class changes, but its glyphs are requested from the wrong package, so the live preview does not reliably render the selected mathematical font.

Reproduction: start with Modern and a rendered equation, then select STIX Two without reloading. The renderer becomes MathJaxStix2, but its fontURL remains https://cdn.jsdelivr.net/npm/mathjax-modern-font/chtml/woff; requests such as .../mathjax-modern-font/chtml/woff/mjx-stx-zero.woff return 404. All nine alternate fonts showed failed live font loads in the Modern-boot matrix. A further case—reload with STIX, then switch to Asana in a document containing \mathbb{R}—reduced five rendered equations to zero and rejected startup with Error: dynamic file 'double-struck' failed to load.

Suggested fix: initialize the selected font's complete resource configuration, including its WOFF URL and dynamic font resources, before rebuilding/typesetting. Verify loaded glyph resources and actual rendered equations; checking only the selected setting or font class misses this failure.

Comment on lines +190 to +195
@media print {
.markdown-body pre:has(> code.hljs),
.markdown-body pre > code.hljs,
.markdown-body code.hljs {
background-color: ${bg} !important;
color: ${fg} !important;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

[P2] Resolve automatic code colors against the PDF export theme

These global !important code-block rules use colors resolved from the application theme and also apply to the export document. With the syntax theme set to Auto, they override the selected PDF theme's code-block styling.

Reproduction: use the light application theme and Auto syntax highlighting, then choose a dark PDF export: the page is dark but code blocks retain a white background. Reversing the themes produces dark code blocks on the light export. The same fixture using the base commit's application files produced the expected code-block colors in both directions.

Suggested fix: resolve Auto against the requested export theme for export rendering, or scope preview-only helper rules so they do not override the export styles.

Comment on lines +217 to +223
let link = document.getElementById('mdv-hljs-theme-link');
if (!link) {
link = document.createElement('link');
link.id = 'mdv-hljs-theme-link';
link.rel = 'stylesheet';
link.crossOrigin = 'anonymous';
if (document.head) document.head.appendChild(link);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

[P2] Remove the built-in token palette when applying a syntax theme

Appending the selected theme stylesheet leaves the existing token colors in styles.css:4115–4204 active. More-specific selectors such as .hljs-title.function_ win over the new theme, and tokens without an explicit rule in the selected theme can retain the old palette. The stylesheet loads and the background changes, but the resulting code colors only partially match the selection.

Reproduction: select Monokai and render a JavaScript function such as function hello() { return 42; }. The function name keeps the legacy purple rgb(111, 66, 193) instead of Monokai's green rgb(166, 226, 46). Comparing the same highlighted HTML against an isolated iframe containing only the selected stylesheet confirmed mismatches in 10 of 15 choices, in both light and dark app modes: Monokai, Dracula, Atom One Dark, Atom One Light, Solarized Dark, Solarized Light, VS, VS2015, Nord, and Default. All stylesheet URLs loaded successfully; this is a cascade conflict.

Suggested fix: scope or disable the built-in token palette while an external theme is active, and compare actual token colors in regression coverage rather than asserting only that the link URL changed. The other five choices matched the representative JavaScript fixture; that does not cover every language/token.

Comment on lines +444 to +450
const toneCandidate = `${shortcode}_${_activeEmojiSkinTone}`;
const joy = typeof joypixels !== 'undefined' ? joypixels : (typeof window !== 'undefined' ? window.joypixels : undefined);
if (joy && joy.emojiList) {
if (joy.emojiList[`:${toneCandidate}:`]) {
return toneCandidate;
}
return shortcode;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

[P2] Canonicalize emoji aliases before adding a skin-tone suffix

This lookup adds _toneN to the original shortcode without first resolving JoyPixels aliases. A supported emoji can therefore remain at its default tone when its alias is used, even though the equivalent canonical shortcode follows the selected setting.

Reproduction: render :thumbsup: :+1: :runner: and select any of tone1 through tone5. :thumbsup: follows the selected tone, while :+1: stays yellow; :runner: also remains at its default tone. This reproduced for all five non-default tone choices in both light and dark mode. Canonical shortcodes such as :wave: and :thumbsup: worked, and explicitly toned shortcodes were preserved.

Suggested fix: resolve the input to JoyPixels' canonical shortcode before checking for a toned variant, while preserving explicit tones and leaving genuinely unsupported emojis unchanged.

Comment on lines +292 to +296
// Load external font script if needed (Modern is bundled by default)
if (_activeMathFont !== 'mathjax-modern') {
const fontUrl = `${MATHJAX_FONT_CDN_BASE}${_activeMathFont}-font/chtml.js`;
try {
await loadScriptOnce(fontUrl);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

[P2] Load Modern when resetting after an alternate-font reload

The assumption that Modern is always bundled is false after startup with a persisted alternate font. In that case only the alternate font package is registered. Skipping Modern's loader means there is no Modern class to install, and the later fontData assignment leaves the previous renderer active.

Reproduction: select STIX Two, reload, then click Reset to defaults. The store, selector, and adapter report mathjax-modern, but the output remains MathJaxStix2 with prefix STX and fontData: MathJaxStix2; the registered font packages still contain only mathjax-stix2. A minimal $$x^2$$ document reproduces this, independently of the missing-glyph-resource problem in finding 2. Reset after a Termes reload likewise retained Termes.

Suggested fix: load the Modern package whenever it is absent, including reset/fallback paths, and verify that the active renderer class and font resources match the restored setting.

@ThisIs-Developer

Copy link
Copy Markdown
Owner

Hi @itznan,

I know I’ve shared multiple rounds of feedback. I’m only doing this because I don’t want the feature to become slow or unstable — I want it to be as good as possible before merging.

Thank you again for all the work you’re putting into it. Really appreciate it.

This branch was successfully deployed

1 active deployment
Preview — e5a4a610 Deployed Oct 11, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

accessibility enhancement New feature, improvement, or usability enhancement. ui/ux User interface, layout, interaction, usability, or visual improvements.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement configuration panel to change default visual library settings

3 participants