Skip to content

Conversation

@somiaj
Copy link
Contributor

@somiaj somiaj commented Jan 4, 2026

I don't think anything else needs updated. This is the result of npm install mathjax@latest.

Copy link
Member

@drgrice1 drgrice1 left a comment

Choose a reason for hiding this comment

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

I think that this generally is okay. However, version 4.1.0 has changed some styling that is causing issues if dark mode is enabled for the browser. This is perhaps due to the fact that webwork2 doesn't have a dark mode, but when tab focus is on a MathJax rendered math element the contrast is not good. Also, if you right click on a MathJax rendered element and open one of the dialogs (such as the "About MathJax" dialog), then the coloring of all of the links in the page gets messed up and the contrast for that is also not good. It seems that MathJax should scope this injected style instead of adding a style that applies to all links in the page.

@somiaj
Copy link
Contributor Author

somiaj commented Jan 13, 2026

@dpvc Any thoughts on this, that when MathJax detects dark mode is being used, it applies an inline style which can override all links on the page, not just the ones in the mathjax about window?

@pstaabp
Copy link
Member

pstaabp commented Jan 13, 2026

I think we need to hold on this PR until this is fixed.

@somiaj somiaj marked this pull request as draft January 13, 2026 21:16
@dpvc
Copy link
Member

dpvc commented Jan 14, 2026

It seems that MathJax should scope this injected style

Yes, that should have been scoped, but apparently I messed up with the styles for the anchors. Sorry about that. I will fix that for the upcoming 4.1.1 release.

I think we need to hold on this PR until this is fixed.

You may want to wait for 4.1.1 anyway, as that is nearly ready for release (I have to add the fix for this issue, now, and there is one outstanding PR).

If you want to disable the dark-mode colors, you can do that using the following configuration:

MathJax = {
  loader: {
    core: {
      ready() {
        const {DraggableDialog} = MathJax._.ui.dialog.DraggableDialog;
        delete DraggableDialog.styles['@media (prefers-color-scheme: dark)'];
      }
    },
    'output/chtml': {
      ready() {
        const {CHTML} = MathJax._.output.chtml_ts;
        delete CHTML.commonStyles['@media (prefers-color-scheme: dark)'];
        const {ChtmlMaction} = MathJax._.output.chtml.Wrappers.maction;
        delete ChtmlMaction.styles['@media (prefers-color-scheme: dark) /* chtml maction */'];
      }
    },
    'output/svg': {
      ready() {
        const {SVG} = MathJax._.output.svg_ts;
        delete SVG.commonStyles['@media (prefers-color-scheme: dark)'];
        const {SvgMaction} = MathJax._.output.svg.Wrappers.maction;
        delete SvgMaction.styles['@media (prefers-color-scheme: dark) /* svg maction */'];
      }
    },
    'a11y/explorer': {
      ready() {
        const Region = MathJax._.a11y.explorer.Region;
        for (const region of ['LiveRegion', 'HoverRegion', 'ToolTip']) {
          Region[region].style.styles['@media (prefers-color-scheme: dark)'] = {};
        }
        Region.LiveRegion.style.styles['@media (prefers-color-scheme: dark)']['mjx-ignore'] = {ignore: 1};
        MathJax.startup.extendHandler((handler) => {
          delete handler.documentClass.speechStyles['@media (prefers-color-scheme: dark) /* explorer */'];
          return handler;
        });
      }
    }
  }
};

It is also possible to make this into an extension rather than in-lining the code. For example, create the file no-dark-mode.js

if (MathJax.loader) {
  MathJax.loader.checkVersion('[no-dark-mode]', '4.1.0', 'extension');
}

[

  [MathJax._.ui?.dialog, 'core', () => {
    const {DraggableDialog} = MathJax._.ui.dialog.DraggableDialog;
    delete DraggableDialog.styles['@media (prefers-color-scheme: dark)'];
  }],

  [MathJax._.a11y?.explorer, 'a11y/explorer', () => {
    const Region = MathJax._.a11y.explorer.Region;
    for (const region of ['LiveRegion', 'HoverRegion', 'ToolTip']) {
      Region[region].style.styles['@media (prefers-color-scheme: dark)'] = {};
    }
    Region.LiveRegion.style.styles['@media (prefers-color-scheme: dark)']['mjx-ignore'] = {ignore: 1};
    MathJax.startup.extendHandler((handler) => {
      delete handler.documentClass.speechStyles['@media (prefers-color-scheme: dark) /* explorer */'];
      return handler;
    });
  }],
  
  [MathJax._.output?.chtml, 'output/chtml', () => {
    const {CHTML} = MathJax._.output.chtml_ts;
    delete CHTML.commonStyles['@media (prefers-color-scheme: dark)'];
    const {ChtmlMaction} = MathJax._.output.chtml.Wrappers.maction;
    delete ChtmlMaction.styles['@media (prefers-color-scheme: dark) /* chtml maction */'];
  }],

  [MathJax._.output?.svg, 'output/svg', () => {
    const {SVG} = MathJax._.output.svg_ts;
    delete SVG.commonStyles['@media (prefers-color-scheme: dark)'];
    const {SvgMaction} = MathJax._.output.svg.Wrappers.maction;
    delete SvgMaction.styles['@media (prefers-color-scheme: dark) /* svg maction */'];
  }]

].forEach(([immediate, extension, ready]) => {
  if (immediate) {
    ready();
  } else {
    const config = MathJax.config.loader;
    config[extension] ??= {};
    config[extension].extraLoads ??= [];
    const check = config[extension].checkReady;
    config[extension].checkReady = async () => {
      if (check) await check();
      return ready();
    }
  }
});

and then use

MathJax = {
  loader: {
    load: ['[no-dark-mode]'],
    paths: { 'no-dark-mode': './no-dark-mode.js' },
  }
};

where the paths gives the URL to the location where no-dark-mode.js is located.

I may make an official no-dark-mode extension, but it may not be in 4.1.1.

[PS, I tend not to read all the many WW github messages, so I may not always see something like this. I do have a filter for messages that tag me, so if you want to be sure I check something, please do include @dpvc.]

The extension is the code suggested by @dpvc in openwebwork#2878.
@drgrice1
Copy link
Member

I think that the no-dark-mode extension will need to be used by WeBWorK for now since there is no dark mode. Even if the link issue is fixed, there are still issues with the colors used. For instance, since I have dark mode set in my browser, but there is no dark mode on the webwork page, MathJax uses dark mode anyway, and then if keyboard focus is on a MathJax rendered math element I see:
mathjax-4 1 0

As you can see, the contrast is not good there.

With the no-dark-mode extension code suggested by @dpvc this looks like:
mathjax-4 1 0-no-dark

That is very similar to how it looks with MathJax 4.0.0 (except the help icon is far to the right with 4.0.0 in this case).

Perhaps once someone gets around to implementing dark mode for webwork2 things will be different.

@drgrice1
Copy link
Member

@somiaj: I added a pull request to this branch that adds the no-dark-mode extension. It uses the code in a separate file (which does take a bit to implement since you can't just use ./no-dark-mode.js in general).

Add a no-dark-mode extension for MathJax.
@drgrice1
Copy link
Member

I think this will work with the no-dark-mode added. I still think we should wait for the 4.1.1 release to merge this as @dpvc suggested.

@somiaj
Copy link
Contributor Author

somiaj commented Jan 15, 2026

I will keep this as a draft until 4.1.1 comes out and update the PR to move to that.

Though I think it is worth testing before 4.1.1 comes out to maybe catch any more issues to either fix here or to report to @dpvc to help fix any other 4.1.0 issues. Merging this now could help catch other possible issues in 4.1.0 before 4.1.1 comes out since it would be used while testing other PRs.

@drgrice1
Copy link
Member

Yeah, that would be okay.

@somiaj
Copy link
Contributor Author

somiaj commented Jan 15, 2026

Then I will make this not a draft, and let the approvals decide if we want to start testing 4.1.0 early or wait for 4.1.1.

@somiaj somiaj marked this pull request as ready for review January 15, 2026 21:27
Copy link
Member

@drgrice1 drgrice1 left a comment

Choose a reason for hiding this comment

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

I will go ahead and approve then.

@drgrice1
Copy link
Member

I should point out that the fallback value of ./no-dark-mode.js in webworkConfig?.mathJaxDarkModeUrl ?? './no-dark-mode.js' is guaranteed to fail. Fortunately the webworkConfig.mathJaxDarkModeURL will always be defined.

On a related note, the webworkConfig in general needs to be reworked a bit. The point of the ?. qualifier was that if webworkConfig is undefined, then there would be no failure. However, that doesn't work. If the variable exists, but is undefined it does work. But that will never be the case. Instead it may (if things aren't coded right) be the case that the variable doesn't exist, and in that case the script will fail to load. What I should have done was defined window.webworkConfig, and used that everywhere. With that the ?. qualifier will work.

Although, there is an even better way to do this if we switch to modules!

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.

4 participants