diff --git a/ts/a11y/explorer/KeyExplorer.ts b/ts/a11y/explorer/KeyExplorer.ts index b62cf780a..d9b7fb3ec 100644 --- a/ts/a11y/explorer/KeyExplorer.ts +++ b/ts/a11y/explorer/KeyExplorer.ts @@ -223,6 +223,13 @@ export class SpeechExplorer creating an SVG version of the expression, and viewing various other information.
+Finally, selecting the "Insert Hidden MathML" item from the options + submenu will turn of MathJax's speech and Braille generation and + instead use visually hidden MathML that some screen readers can voice, + though support for this is not universal across all screen readers and + operating systems. Selecting speech or Braille generation in their + submenus will remove the hidden MathML again.
+For more help, see the MathJax accessibility documentation.
diff --git a/ts/ui/menu/Menu.ts b/ts/ui/menu/Menu.ts index fa8dd9d4d..acfeec0fc 100644 --- a/ts/ui/menu/Menu.ts +++ b/ts/ui/menu/Menu.ts @@ -1203,6 +1203,16 @@ export class Menu { */ protected setAssistiveMml(mml: boolean) { this.document.options.enableAssistiveMml = mml; + if (mml) { + this.noRerender(() => { + if (this.settings.speech) { + this.menu.pool.lookup('speech').setValue(false); + } + if (this.settings.braille) { + this.menu.pool.lookup('braille').setValue(false); + } + }); + } if (!mml || MathJax._?.a11y?.['assistive-mml']) { this.rerender(); } else { @@ -1236,6 +1246,11 @@ export class Menu { protected setSpeech(speech: boolean) { this.enableAccessibilityItems('Speech', speech); this.document.options.enableSpeech = speech; + if (speech && this.settings.assistiveMml) { + this.noRerender(() => + this.menu.pool.lookup('assistiveMml').setValue(false) + ); + } if (!speech || MathJax._?.a11y?.explorer) { this.rerender(STATE.COMPILED); } else { @@ -1249,6 +1264,11 @@ export class Menu { protected setBraille(braille: boolean) { this.enableAccessibilityItems('Braille', braille); this.document.options.enableBraille = braille; + if (braille && this.settings.assistiveMml) { + this.noRerender(() => + this.menu.pool.lookup('assistiveMml').setValue(false) + ); + } if (!braille || MathJax._?.a11y?.explorer) { this.rerender(STATE.COMPILED); } else { @@ -1381,24 +1401,24 @@ export class Menu { * Reset all menu settings to the (page) defaults */ protected resetDefaults() { - Menu.loading++; // pretend we're loading, to suppress rerendering for each variable change - const pool = this.menu.pool; - const settings = this.defaultSettings; - for (const name of Object.keys(settings) as (keyof MenuSettings)[]) { - const variable = pool.lookup(name); - if (variable) { - if (variable.getValue() !== settings[name]) { - variable.setValue(settings[name] as string | boolean); - const item = (variable as any).items[0]; - if (item) { - item.executeCallbacks_(); + this.noRerender(() => { + const pool = this.menu.pool; + const settings = this.defaultSettings; + for (const name of Object.keys(settings) as (keyof MenuSettings)[]) { + const variable = pool.lookup(name); + if (variable) { + if (variable.getValue() !== settings[name]) { + variable.setValue(settings[name] as string | boolean); + const item = (variable as any).items[0]; + if (item) { + item.executeCallbacks_(); + } } + } else if (Object.hasOwn(this.settings, name)) { + (this.settings as any)[name] = settings[name]; } - } else if (Object.hasOwn(this.settings, name)) { - (this.settings as any)[name] = settings[name]; } - } - Menu.loading--; + }); this.rerender(STATE.COMPILED); } @@ -1694,6 +1714,17 @@ export class Menu { } } + protected noRerender(exec: () => void) { + Menu.loading++; // pretend we're loading, to suppress rerendering durring exec() call + try { + exec(); + Menu.loading--; + } catch (err) { + Menu.loading--; // make sure this resets if there is an error + throw err; + } + } + /** * Copy the serialzied MathML to the clipboard */