From 96f6e3050a1bc78cbcd33877c4c960331640c01c Mon Sep 17 00:00:00 2001
From: "Davide P. Cervone"
Date: Thu, 13 Nov 2025 21:38:25 -0500
Subject: [PATCH 1/5] Make assistive-mml unset speech/braille and vice-versa
---
ts/ui/menu/Menu.ts | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/ts/ui/menu/Menu.ts b/ts/ui/menu/Menu.ts
index 745b694cb..ca9aece62 100644
--- a/ts/ui/menu/Menu.ts
+++ b/ts/ui/menu/Menu.ts
@@ -1180,6 +1180,16 @@ export class Menu {
*/
protected setAssistiveMml(mml: boolean) {
this.document.options.enableAssistiveMml = mml;
+ if (mml) {
+ Menu.loading++; // pretend we're loading, to suppress rerendering for each variable change
+ if (this.settings.speech) {
+ this.menu.pool.lookup('speech').setValue(false);
+ }
+ if (this.settings.braille) {
+ this.menu.pool.lookup('braille').setValue(false);
+ }
+ Menu.loading--;
+ }
if (!mml || MathJax._?.a11y?.['assistive-mml']) {
this.rerender();
} else {
@@ -1213,6 +1223,11 @@ export class Menu {
protected setSpeech(speech: boolean) {
this.enableAccessibilityItems('Speech', speech);
this.document.options.enableSpeech = speech;
+ if (speech && this.settings.assistiveMml) {
+ Menu.loading++; // pretend we're loading, to suppress rerendering for each variable change
+ this.menu.pool.lookup('assistiveMml').setValue(false);
+ Menu.loading--;
+ }
if (!speech || MathJax._?.a11y?.explorer) {
this.rerender(STATE.COMPILED);
} else {
@@ -1226,6 +1241,11 @@ export class Menu {
protected setBraille(braille: boolean) {
this.enableAccessibilityItems('Braille', braille);
this.document.options.enableBraille = braille;
+ if (braille && this.settings.assistiveMml) {
+ Menu.loading++; // pretend we're loading, to suppress rerendering for each variable change
+ this.menu.pool.lookup('assistiveMml').setValue(false);
+ Menu.loading--;
+ }
if (!braille || MathJax._?.a11y?.explorer) {
this.rerender(STATE.COMPILED);
} else {
From 671b673ac3be97222552508b7ca61fb1333fda01 Mon Sep 17 00:00:00 2001
From: "Davide P. Cervone"
Date: Thu, 20 Nov 2025 14:16:53 -0500
Subject: [PATCH 2/5] Add noRerender() function, as request in review
---
ts/ui/menu/Menu.ts | 65 +++++++++++++++++++++++++---------------------
1 file changed, 36 insertions(+), 29 deletions(-)
diff --git a/ts/ui/menu/Menu.ts b/ts/ui/menu/Menu.ts
index ca9aece62..5adf37566 100644
--- a/ts/ui/menu/Menu.ts
+++ b/ts/ui/menu/Menu.ts
@@ -1181,14 +1181,14 @@ export class Menu {
protected setAssistiveMml(mml: boolean) {
this.document.options.enableAssistiveMml = mml;
if (mml) {
- Menu.loading++; // pretend we're loading, to suppress rerendering for each variable change
- if (this.settings.speech) {
- this.menu.pool.lookup('speech').setValue(false);
- }
- if (this.settings.braille) {
- this.menu.pool.lookup('braille').setValue(false);
- }
- Menu.loading--;
+ 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();
@@ -1224,9 +1224,7 @@ export class Menu {
this.enableAccessibilityItems('Speech', speech);
this.document.options.enableSpeech = speech;
if (speech && this.settings.assistiveMml) {
- Menu.loading++; // pretend we're loading, to suppress rerendering for each variable change
- this.menu.pool.lookup('assistiveMml').setValue(false);
- Menu.loading--;
+ this.noRerender(() => this.menu.pool.lookup('assistiveMml').setValue(false));
}
if (!speech || MathJax._?.a11y?.explorer) {
this.rerender(STATE.COMPILED);
@@ -1242,9 +1240,7 @@ export class Menu {
this.enableAccessibilityItems('Braille', braille);
this.document.options.enableBraille = braille;
if (braille && this.settings.assistiveMml) {
- Menu.loading++; // pretend we're loading, to suppress rerendering for each variable change
- this.menu.pool.lookup('assistiveMml').setValue(false);
- Menu.loading--;
+ this.noRerender(() => this.menu.pool.lookup('assistiveMml').setValue(false));
}
if (!braille || MathJax._?.a11y?.explorer) {
this.rerender(STATE.COMPILED);
@@ -1363,24 +1359,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);
}
@@ -1682,6 +1678,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
*/
From 7e1618d27ebe24745fcfac0a692c81beb681ec5e Mon Sep 17 00:00:00 2001
From: "Davide P. Cervone"
Date: Thu, 20 Nov 2025 14:34:37 -0500
Subject: [PATCH 3/5] Add more information to the help dialog about hidden
MathML.
---
ts/a11y/explorer/KeyExplorer.ts | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/ts/a11y/explorer/KeyExplorer.ts b/ts/a11y/explorer/KeyExplorer.ts
index d12eee9a4..1901b088b 100644
--- a/ts/a11y/explorer/KeyExplorer.ts
+++ b/ts/a11y/explorer/KeyExplorer.ts
@@ -194,6 +194,13 @@ MathML version of the expression or its original source format,
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.
From 5f3b73b581d2e0abbd6bdf00467024686c22bac3 Mon Sep 17 00:00:00 2001
From: "Davide P. Cervone"
Date: Thu, 20 Nov 2025 14:48:01 -0500
Subject: [PATCH 4/5] Fix formatting
---
ts/a11y/explorer/KeyExplorer.ts | 2 +-
ts/ui/menu/Menu.ts | 10 +++++++---
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/ts/a11y/explorer/KeyExplorer.ts b/ts/a11y/explorer/KeyExplorer.ts
index 82421b4b5..d1a6cc248 100644
--- a/ts/a11y/explorer/KeyExplorer.ts
+++ b/ts/a11y/explorer/KeyExplorer.ts
@@ -234,7 +234,7 @@ export class SpeechExplorer
href="https://docs.mathjax.org/en/latest/basic/accessibility.html"
target="_blank">MathJax accessibility documentation.
`;
- }
+ }
/**
* Help for the different OS versions
diff --git a/ts/ui/menu/Menu.ts b/ts/ui/menu/Menu.ts
index 4cbd03d86..acfeec0fc 100644
--- a/ts/ui/menu/Menu.ts
+++ b/ts/ui/menu/Menu.ts
@@ -1247,7 +1247,9 @@ export class Menu {
this.enableAccessibilityItems('Speech', speech);
this.document.options.enableSpeech = speech;
if (speech && this.settings.assistiveMml) {
- this.noRerender(() => this.menu.pool.lookup('assistiveMml').setValue(false));
+ this.noRerender(() =>
+ this.menu.pool.lookup('assistiveMml').setValue(false)
+ );
}
if (!speech || MathJax._?.a11y?.explorer) {
this.rerender(STATE.COMPILED);
@@ -1263,7 +1265,9 @@ export class Menu {
this.enableAccessibilityItems('Braille', braille);
this.document.options.enableBraille = braille;
if (braille && this.settings.assistiveMml) {
- this.noRerender(() => this.menu.pool.lookup('assistiveMml').setValue(false));
+ this.noRerender(() =>
+ this.menu.pool.lookup('assistiveMml').setValue(false)
+ );
}
if (!braille || MathJax._?.a11y?.explorer) {
this.rerender(STATE.COMPILED);
@@ -1715,7 +1719,7 @@ export class Menu {
try {
exec();
Menu.loading--;
- } catch(err) {
+ } catch (err) {
Menu.loading--; // make sure this resets if there is an error
throw err;
}
From c084317eec18c68b4c8a7cc9bd785f79759ec494 Mon Sep 17 00:00:00 2001
From: "Davide P. Cervone"
Date: Thu, 20 Nov 2025 14:57:02 -0500
Subject: [PATCH 5/5] Fix indentation.
---
ts/a11y/explorer/KeyExplorer.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ts/a11y/explorer/KeyExplorer.ts b/ts/a11y/explorer/KeyExplorer.ts
index d1a6cc248..d9b7fb3ec 100644
--- a/ts/a11y/explorer/KeyExplorer.ts
+++ b/ts/a11y/explorer/KeyExplorer.ts
@@ -233,7 +233,7 @@ export class SpeechExplorer
For more help, see the MathJax accessibility documentation.
- `;
+ `;
}
/**