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

3.2: Activating Math Menu post reload causes JAWS and NVDA to report formulas as "applications" instead of reading them #3306

Open
salbeira opened this issue Nov 8, 2024 · 2 comments

Comments

@salbeira
Copy link

salbeira commented Nov 8, 2024

Issue Summary

We use MathJax with a customized plugin in Reveal.js slides to produce lecture slides.

Currently we do not enable the math menu of Mathjax on page load as it increases load times of math heavy pages by a lot. We allow users to reenable accessibility features of formulas via a button. Clicking it reconfigures mathjax and orders it to re-render the formulas. Once done, we can use tab to target the formulas, space to open the menu and enter to open the math explorer. Yet the screen reader now stops while reading through a paragraph that contains a formula and simply announces it as an "application" instead of just reading over it.

We got this reported through an audit and can not reproduce it with the software available to us (orca).

Steps to Reproduce:

  1. Load MathJax with these options for faster loading:
enableMenu: false,
menuOptions: {
    settings: {
        explorer: false
    },
},
  1. Enable the features with these pieces of code:
if (window.MathJax) {
  window.MathJax.startup.document.options.enableMenu = true;
  window.MathJax.startup.document.menu.menu
    .findID("Accessibility", "Activate")
    .variable.setter(true);
  window.MathJax.startup.document.menu.loadingPromise.then(() => {
    window.MathJax.startup.document.rerender();
  });
}
  1. Let the screen reader read a paragraph like:

Let a natural number be defined as $n \in \mathbb{N}$, then we can ...

This has been reported to us by an audit. As we do not have access to the exact screen reader software or environment they use, we can only pass on the report, but we would love to know if this is a reproducable issue or something we broke through our configuration.

Technical details:

  • MathJax Version: 3.2
  • Client OS: unknown
  • Browser: unknown

I am using the following MathJax configuration:

    window.MathJax = {
      startup: {
        ready: () => {
          /* Workaround to allow loading of a11y features past initial load
           * Necessary due do a bug in 3.2.2 throwing a Mathjax.retry error. */
          const { mathjax } = window.MathJax._.mathjax;
          const { STATE } = window.MathJax._.core.MathItem;
          const { Menu } = window.MathJax._.ui.menu.Menu;
          const rerender = Menu.prototype.rerender;
          Menu.prototype.rerender = function (start = STATE.TYPESET) {
            mathjax.handleRetriesFor(() => {
              rerender.call(this, start);
            });
          };
        },
      },
      svg: {
        scale: 1.0,
        minScale: 0.5, // smallest scaling factor to use
        mtextInheritFont: true, // true to make mtext elements use surrounding font
        merrorInheritFont: true, // true to make merror text use surrounding font
        mathmlSpacing: false, // true for MathML spacing rules, false for TeX rules
        skipAttributes: {}, // RFDa and other attributes NOT to copy to the output
        exFactor: 0.5, // default size of ex in em units
        displayAlign: "center", // default for indentalign when set to 'auto'
        displayIndent: "0", // default for indentshift when set to 'auto'
        fontCache: "none", // or 'global' or 'none'
        localID: null, // ID to use for local font cache (for single equation processing)
        internalSpeechTitles: true, // insert <title> tags with speech content
        titleID: 0, // initial id number to use for aria-labeledby titles
      },
      tex: {
        tags: "ams",
        inlineMath: [
          // start/end delimiter pairs for in-line math
          ["$", "$"],
          ["\\(", "\\)"],
        ],
        displayMath: [
          // start/end delimiter pairs for display math
          ["$$", "$$"],
          ["\\[", "\\]"],
        ],
        macros: macros,
      },
      options: {
        renderActions: {
          incremental: [1000, incrementalDocument, incrementalItem, false], //adds .fragment classes to multi-line formulas
          adjustLinks: [1001, adjustLinksDocument, adjustLinksItem, false], //adjusts links inside the page that reference formulas
          fixmml: [1002, fixAssistiveMML, "", false], //removes .fragment classes from assistive MML items
        },
        sre: {
          locale: language === "de" ? "de" : "en",
        },
        enableMenu: false,
        menuOptions: {
          settings: {
            explorer: false,
          },
        },
        a11y: {
          backgroundColor: "Green",
          backgroundOpacity: 50,
          foregroundColor: "Black",
          foregroundOpacity: 100,
        },
      },
    };

and loading MathJax via our own locally hosted instance.

Supporting information:

Access to our lecture slides that were audited can be requested privately.

@zorkow
Copy link
Member

zorkow commented Nov 11, 2024

Thank you for reporting the issue. Of the top of my head I could think of the possibility that if the explorer module is loaded a posteriori that the screen reader does not see the live regions we use to push the speech out but only sees the ARIA role, which is an application. I will need to do some testing.

Starting in v4 we are no longer using live regions, but try to communicate directly to screen readers via aria labels and braille labels. We are currently honing the v4.0 explorer, which might offer a solution for this case.

@salbeira
Copy link
Author

Hello, thank you for your response. We have been anticipating any word about the official v4 release ever since last year, it is good to hear that things are still moving along. While testing things again I mentioned that our code is actually incapable of doing the loading on the first pass. For some reason I need to disable and then reenable the thing again in order to have things happen.

  • Turning on only the options.enableMenu succeeds in inserting the menu on the first press.

  • Trying to force on the Accessibility Setting inside the menu causes the first rerender to do nothing. The network traffic loading the missing files when checking the box is the same as when I force it on and benchmarking the time between starting the re-setup and the resolution of the loadingPromise tells me there is a significant timing difference, so I can guess that the loading promise is indeed resolving after the loading of the necessary files is done, yet the rerender doesn't seem to happen or work if I do both steps.

Is there some tried and true way you can recommend me to turn on the accessibility features (as if startup.options.enableMenu and startup.options.menuOptions.settings.explorer have been set to true) after the initial page setup and typeset? I also mention that once I reload the page after the first failed typeset the setting of the menu option also puts a memo into the LocalStorage that the explorer is on. Doing the rerender operations above THEN makes it work on the first try.

It also appears that for some reason the inTabOrder setting is ignored SOMETIMES and sets a tabindex = 1 on the math for no reason.

Seems like to make it work halfway reliably is to set the startup.options.menuOptions.settings.explorer option to be always true. This loads the necessary files on page load and allows the enabling of the menu later through a rerender on first try. I need to re-do all our benchmarks for the initial page load though because initial loading times were the original reason we did the entire swicharoo in the first place.

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

No branches or pull requests

2 participants