explorer.js
20 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
MathJax.Hub.Register.StartupHook("Sre Ready", function() {
var o, r, s = MathJax.Hub.config.menuSettings, l = {};
MathJax.Hub.Register.StartupHook("MathEvents Ready", function() {
o = MathJax.Extension.MathEvents.Event.False, r = MathJax.Extension.MathEvents.Event.KEY;
});
var h = MathJax.Extension.explorer = {
version: "1.6.0",
dependents: [],
defaults: {
walker: "table",
highlight: "none",
background: "blue",
foreground: "black",
speech: !0,
generation: "lazy",
subtitle: !1,
ruleset: "mathspeak-default"
},
eagerComplexity: 80,
prefix: "Assistive-",
hook: null,
locHook: null,
oldrules: null,
addMenuOption: function(e, t) {
s[h.prefix + e] = t;
},
addDefaults: function() {
for (var e, t = MathJax.Hub.CombineConfig("explorer", h.defaults), a = Object.keys(t), i = 0; e = a[i]; i++) void 0 === s[h.prefix + e] && h.addMenuOption(e, t[e]);
h.setSpeechOption(), u.Reset();
},
setOption: function(e, t) {
s[h.prefix + e] !== t && (h.addMenuOption(e, t), u.Reset());
},
getOption: function(e) {
return s[h.prefix + e];
},
speechOption: function(e) {
h.oldrules !== e.value && (h.setSpeechOption(), u.Regenerate());
},
setSpeechOption: function() {
var e = s[h.prefix + "ruleset"], t = e.split("-");
sre.System.getInstance().setupEngine({
locale: MathJax.Localization.locale,
domain: h.Domain(t[0]),
style: t[1]
}), h.oldrules = e;
},
Domain: function(e) {
switch (e) {
case "chromevox":
return "default";
case "clearspeak":
return "clearspeak";
case "mathspeak":
default:
return "mathspeak";
}
},
Enable: function(e, t) {
s.explorer = !0, t && (l.explorer = !0), MathJax.Extension.collapsible.Enable(!1, t),
MathJax.Extension.AssistiveMML && (MathJax.Extension.AssistiveMML.config.disabled = !0,
s.assistiveMML = !1, t && (l.assistiveMML = !1)), this.DisableMenus(!1), this.hook || (this.hook = MathJax.Hub.Register.MessageHook("New Math", [ "Register", this.Explorer ])),
this.locHook || (this.locHook = MathJax.Hub.Register.MessageHook("Locale Reset", [ "RemoveSpeech", this.Explorer ])),
e && MathJax.Hub.Queue([ "Reprocess", MathJax.Hub ]);
},
Disable: function(e, t) {
s.explorer = !1, t && (l.explorer = !1), this.DisableMenus(!0), this.hook && (MathJax.Hub.UnRegister.MessageHook(this.hook),
this.hook = null);
for (var a = this.dependents.length - 1; 0 <= a; a--) {
var i = this.dependents[a];
i.Disable && i.Disable(!1, t);
}
},
DisableMenus: function(e) {
if (MathJax.Menu) {
var t = MathJax.Menu.menu.FindId("Accessibility", "Explorer");
if (t) {
for (var a, i = (t = t.submenu).items, n = 2; a = i[n]; n++) a.disabled = e;
e || !t.FindId("SpeechOutput") || s[h.prefix + "speech"] || (t.FindId("Subtitles").disabled = !0);
}
}
},
Dependent: function(e) {
this.dependents.push(e);
}
}, n = MathJax.Object.Subclass({
div: null,
inner: null,
Init: function() {
this.div = n.Create("assertive"), this.inner = MathJax.HTML.addElement(this.div, "div");
},
Add: function() {
n.added || (document.body.appendChild(this.div), n.added = !0);
},
Show: function(e, t) {
this.div.classList.add("MJX_LiveRegion_Show");
var a = e.getBoundingClientRect(), i = a.bottom + 10 + window.pageYOffset, n = a.left + window.pageXOffset;
this.div.style.top = i + "px", this.div.style.left = n + "px";
var o = t.colorString();
this.inner.style.backgroundColor = o.background, this.inner.style.color = o.foreground;
},
Hide: function(e) {
this.div.classList.remove("MJX_LiveRegion_Show");
},
Clear: function() {
this.Update(""), this.inner.style.top = "", this.inner.style.backgroundColor = "";
},
Update: function(e) {
h.getOption("speech") && n.Update(this.inner, e);
}
}, {
ANNOUNCE: "Navigatable Math in page. Explore with enter or shift space and arrow keys. Expand or collapse elements hitting enter.",
announced: !1,
added: !1,
styles: {
".MJX_LiveRegion": {
position: "absolute",
top: "0",
height: "1px",
width: "1px",
padding: "1px",
overflow: "hidden"
},
".MJX_LiveRegion_Show": {
top: "0",
position: "absolute",
width: "auto",
height: "auto",
padding: "0px 0px",
opacity: 1,
"z-index": "202",
left: 0,
right: 0,
margin: "0 auto",
"background-color": "white",
"box-shadow": "0px 10px 20px #888",
border: "2px solid #CCCCCC"
}
},
Create: function(e) {
var t = MathJax.HTML.Element("div", {
className: "MJX_LiveRegion"
});
return t.setAttribute("aria-live", e), t;
},
Update: MathJax.Hub.Browser.isPC ? function(e, t) {
e.textContent = "", setTimeout(function() {
e.textContent = t;
}, 100);
} : function(e, t) {
e.textContent = "", e.textContent = t;
},
Announce: function() {
var e;
h.getOption("speech") && (n.announced = !0, MathJax.Ajax.Styles(n.styles), e = n.Create("polite"),
document.body.appendChild(e), n.Update(e, n.ANNOUNCE), setTimeout(function() {
document.body.removeChild(e);
}, 1e3));
}
});
MathJax.Extension.explorer.LiveRegion = n;
var e = MathJax.Ajax.fileURL(MathJax.Ajax.config.path.a11y), u = MathJax.Extension.explorer.Explorer = {
liveRegion: n(),
walker: null,
highlighter: null,
hoverer: null,
flamer: null,
speechDiv: null,
earconFile: e + "/invalid_keypress" + (-1 !== [ "Firefox", "Chrome", "Opera" ].indexOf(MathJax.Hub.Browser.name) ? ".ogg" : ".mp3"),
expanded: !1,
focusoutEvent: MathJax.Hub.Browser.isFirefox ? "blur" : "focusout",
focusinEvent: "focus",
ignoreFocusOut: !1,
jaxCache: {},
messageID: null,
Reset: function() {
u.FlameEnriched();
},
Register: function(e) {
var t, a;
!h.hook || (t = document.getElementById(e[1])) && t.id && ((a = MathJax.Hub.getJaxFor(t.id)) && a.enriched && (u.StateChange(t.id, a),
u.liveRegion.Add(), u.AddEvent(t)));
},
StateChange: function(e, t) {
u.GetHighlighter(.2);
var a = u.jaxCache[e];
a && a === t.root || (a && sre.Walker.resetState(e + "-Frame"), u.jaxCache[e] = t.root);
},
AddAria: function(e) {
e.setAttribute("role", "application"), e.setAttribute("aria-label", "Math");
},
AddHook: function(i) {
u.RemoveHook(), u.hook = MathJax.Hub.Register.MessageHook("End Math", function(e) {
var t = e[1].id + "-Frame", a = document.getElementById(t);
i && t === u.expanded && (u.ActivateWalker(a, i), a.focus(), u.expanded = !1);
});
},
RemoveHook: function() {
u.hook && (MathJax.Hub.UnRegister.MessageHook(u.hook), u.hook = null);
},
AddMessage: function() {
return MathJax.Message.Set("Generating Speech Output");
},
RemoveMessage: function(e) {
e && MathJax.Message.Clear(e);
},
AddEvent: function(e) {
var t, a = e.id + "-Frame", i = e.previousSibling;
i && (t = i.id !== a ? i.firstElementChild : i, u.AddAria(t), u.AddMouseEvents(t),
"MathJax_MathML" === t.className && (t = t.firstElementChild), t && (t.onkeydown = u.Keydown,
u.Flame(t), t.addEventListener(u.focusinEvent, function(e) {
h.hook && (n.announced || n.Announce());
}), t.addEventListener(u.focusoutEvent, function(e) {
h.hook && (u.ignoreFocusOut && (u.ignoreFocusOut = !1, "enter" === u.walker.moved) ? e.target.focus() : u.walker && u.DeactivateWalker());
}), h.getOption("speech") && u.AddSpeech(t)));
},
AddSpeech: function(e) {
var t = e.id, a = MathJax.Hub.getJaxFor(t).root.toMathML();
if (e.getAttribute("haslabel") || u.AddMathLabel(a, t), !e.getAttribute("hasspeech")) switch (MathJax.Hub.config.explorer.generation) {
case "eager":
u.AddSpeechEager(a, t);
break;
case "mixed":
e.querySelectorAll("[data-semantic-complexity]").length >= h.eagerComplexity && u.AddSpeechEager(a, t);
}
},
AddSpeechLazy: function(e) {
var t = new sre.TreeSpeechGenerator();
t.setRebuilt(u.walker.getRebuilt()), t.getSpeech(u.walker.rootNode, u.walker.getXml()),
e.setAttribute("hasspeech", "true");
},
AddSpeechEager: function(e, t) {
u.MakeSpeechTask(e, t, sre.TreeSpeechGenerator, function(e, t) {
e.setAttribute("hasspeech", "true");
}, 5);
},
AddMathLabel: function(e, t) {
u.MakeSpeechTask(e, t, sre.SummarySpeechGenerator, function(e, t) {
e.setAttribute("haslabel", "true"), e.setAttribute("aria-label", t);
}, 5);
},
MakeSpeechTask: function(i, n, o, r, e) {
var s = u.AddMessage();
setTimeout(function() {
var e = new o(), t = document.getElementById(n), a = new sre.DummyWalker(t, e, u.highlighter, i).speech();
a && r(t, a), u.RemoveMessage(s);
}, e);
},
Keydown: function(e) {
var t = e.keyCode;
if (t === r.ESCAPE) {
if (!u.walker) return;
return u.RemoveHook(), u.DeactivateWalker(), void o(e);
}
if (u.walker && u.walker.isActive()) {
t = t === r.RETURN ? r.DASH : t, void 0 !== u.walker.modifier && (u.walker.modifier = e.shiftKey);
var a = u.walker.move(t);
if (null === a) return;
if (a) {
if ("expand" === u.walker.moved) {
if (u.expanded = u.walker.node.id, MathJax.Hub.Browser.isEdge) return u.ignoreFocusOut = !0,
void u.DeactivateWalker();
if (MathJax.Hub.Browser.isFirefox || MathJax.Hub.Browser.isMSIE) return void u.DeactivateWalker();
}
u.liveRegion.Update(u.walker.speech()), u.Highlight();
} else u.PlayEarcon();
o(e);
} else {
var i = e.target;
if (t === r.SPACE && !e.shiftKey) return MathJax.Extension.MathEvents.Event.ContextMenu(e, i),
void o(e);
if (h.hook && (t === r.RETURN || t === r.SPACE && e.shiftKey)) {
var n = MathJax.Hub.getJaxFor(i);
return u.ActivateWalker(i, n), u.AddHook(n), void o(e);
}
}
},
GetHighlighter: function(e) {
u.highlighter = sre.HighlighterFactory.highlighter({
color: h.getOption("background"),
alpha: e
}, {
color: h.getOption("foreground"),
alpha: 1
}, {
renderer: MathJax.Hub.outputJax["jax/mml"][0].id,
browser: MathJax.Hub.Browser.name
});
},
AddMouseEvents: function(e) {
sre.HighlighterFactory.addEvents(e, {
mouseover: u.MouseOver,
mouseout: u.MouseOut
}, {
renderer: MathJax.Hub.outputJax["jax/mml"][0].id,
browser: MathJax.Hub.Browser.name
});
},
MouseOver: function(e) {
var t;
"none" !== h.getOption("highlight") && ("hover" === h.getOption("highlight") && (t = e.currentTarget,
u.GetHighlighter(.1), u.highlighter.highlight([ t ]), u.hoverer = !0), o(e));
},
MouseOut: function(e) {
return u.hoverer && (u.highlighter.unhighlight(), u.hoverer = !1), o(e);
},
Flame: function(e) {
if ("flame" === h.getOption("highlight")) return u.GetHighlighter(.05), u.highlighter.highlightAll(e),
void (u.flamer = !0);
},
UnFlame: function() {
u.flamer && (u.highlighter.unhighlightAll(), u.flamer = null);
},
FlameEnriched: function() {
u.UnFlame();
for (var e, t = 0, a = MathJax.Hub.getAllJax(); e = a[t]; t++) u.Flame(e.SourceElement().previousSibling);
},
Walkers: {
syntactic: sre.SyntaxWalker,
table: sre.TableWalker,
semantic: sre.SemanticWalker,
none: sre.DummyWalker
},
ActivateWalker: function(e, t) {
var a = h.getOption("speech"), i = h.getOption("walker") ? u.Walkers[MathJax.Hub.config.explorer.walker] : u.Walkers.none, n = a ? new sre.DirectSpeechGenerator() : new sre.DummySpeechGenerator(), o = sre.System.getInstance().engineSetup();
n.setOptions({
locale: o.locale,
domain: o.domain,
style: o.style,
modality: "speech"
}), u.GetHighlighter(.2), u.walker = new i(e, n, u.highlighter, t.root.toMathML()),
a && !e.getAttribute("hasspeech") && u.AddSpeechLazy(e), u.walker.activate(), a && (h.getOption("subtitle") && u.liveRegion.Show(e, u.highlighter),
u.liveRegion.Update(u.walker.speech())), u.Highlight(), u.ignoreFocusOut && setTimeout(function() {
u.ignoreFocusOut = !1;
}, 500);
},
DeactivateWalker: function() {
var e = sre.System.getInstance().engineSetup(), t = "clearspeak" === e.domain ? "default" : e.style;
h.setOption("ruleset", e.domain + "-" + t), u.liveRegion.Clear(), u.liveRegion.Hide(),
u.Unhighlight(), u.currentHighlight = null, u.walker.deactivate(), u.walker = null;
},
Highlight: function() {
u.Unhighlight(), u.highlighter.highlight(u.walker.getFocus().getNodes());
},
Unhighlight: function() {
u.highlighter.unhighlight();
},
PlayEarcon: function() {
new Audio(u.earconFile).play();
},
SpeechOutput: function() {
u.Reset();
[ "Subtitles" ].forEach(function(e) {
var t = MathJax.Menu.menu.FindId("Accessibility", "Explorer", e);
t && (t.disabled = !t.disabled);
}), u.Regenerate();
},
RemoveSpeech: function() {
h.setSpeechOption();
for (var e, t = 0, a = MathJax.Hub.getAllJax(); e = a[t]; t++) {
var i = document.getElementById(e.inputID + "-Frame");
i && (i.removeAttribute("hasspeech"), i.removeAttribute("haslabel"));
}
},
Regenerate: function() {
for (var e, t = 0, a = MathJax.Hub.getAllJax(); e = a[t]; t++) {
var i = document.getElementById(e.inputID + "-Frame");
i && (i.removeAttribute("hasspeech"), u.AddSpeech(i));
}
},
Startup: function() {
var e = MathJax.Extension.collapsible;
e && e.Dependent(h), h.addDefaults();
}
};
MathJax.Hub.Register.StartupHook("End Extensions", function() {
h[!1 === s.explorer ? "Disable" : "Enable"](), MathJax.Hub.Startup.signal.Post("Explorer Ready"),
MathJax.Hub.Register.StartupHook("MathMenu Ready", function() {
l = MathJax.Menu.cookie;
var e, t = MathJax.Menu.ITEM, a = MathJax.Menu.menu, i = {
action: u.Reset
}, n = {
action: h.speechOption
}, o = t.SUBMENU([ "Explorer", "Explorer" ], t.CHECKBOX([ "Active", "Active" ], "explorer", {
action: function(e) {
h[s.explorer ? "Enable" : "Disable"](!0, !0), MathJax.Menu.saveCookie();
}
}), t.RULE(), t.CHECKBOX([ "Walker", "Walker" ], "Assistive-walker"), t.SUBMENU([ "Highlight", "Highlight" ], t.RADIO([ "none", "None" ], "Assistive-highlight", i), t.RADIO([ "hover", "Hover" ], "Assistive-highlight", i), t.RADIO([ "flame", "Flame" ], "Assistive-highlight", i)), t.SUBMENU([ "Background", "Background" ], t.RADIO([ "blue", "Blue" ], "Assistive-background", i), t.RADIO([ "red", "Red" ], "Assistive-background", i), t.RADIO([ "green", "Green" ], "Assistive-background", i), t.RADIO([ "yellow", "Yellow" ], "Assistive-background", i), t.RADIO([ "cyan", "Cyan" ], "Assistive-background", i), t.RADIO([ "magenta", "Magenta" ], "Assistive-background", i), t.RADIO([ "white", "White" ], "Assistive-background", i), t.RADIO([ "black", "Black" ], "Assistive-background", i)), t.SUBMENU([ "Foreground", "Foreground" ], t.RADIO([ "black", "Black" ], "Assistive-foreground", i), t.RADIO([ "white", "White" ], "Assistive-foreground", i), t.RADIO([ "magenta", "Magenta" ], "Assistive-foreground", i), t.RADIO([ "cyan", "Cyan" ], "Assistive-foreground", i), t.RADIO([ "yellow", "Yellow" ], "Assistive-foreground", i), t.RADIO([ "green", "Green" ], "Assistive-foreground", i), t.RADIO([ "red", "Red" ], "Assistive-foreground", i), t.RADIO([ "blue", "Blue" ], "Assistive-foreground", i)), t.RULE(), t.CHECKBOX([ "SpeechOutput", "Speech Output" ], "Assistive-speech", {
action: u.SpeechOutput
}), t.CHECKBOX([ "Subtitles", "Subtitles" ], "Assistive-subtitle", {
disabled: !s["Assistive-speech"]
}), t.RULE(), t.SUBMENU([ "Mathspeak", "Mathspeak Rules" ], t.RADIO([ "mathspeak-default", "Verbose" ], "Assistive-ruleset", n), t.RADIO([ "mathspeak-brief", "Brief" ], "Assistive-ruleset", n), t.RADIO([ "mathspeak-sbrief", "Superbrief" ], "Assistive-ruleset", n)), t.RADIO([ "clearspeak-default", "Clearspeak Rules" ], "Assistive-ruleset", n), t.SUBMENU([ "Chromevox", "ChromeVox Rules" ], t.RADIO([ "chromevox-default", "Verbose" ], "Assistive-ruleset", n), t.RADIO([ "chromevox-alternative", "Alternative" ], "Assistive-ruleset", n))), r = (a.FindId("Accessibility") || {}).submenu;
r ? null !== (e = r.IndexOfId("Explorer")) ? r.items[e] = o : (e = r.IndexOfId("CollapsibleMath"),
r.items.splice(e + 1, 0, o)) : (e = a.IndexOfId("CollapsibleMath"), a.items.splice(e + 1, 0, o)),
s.explorer || h.DisableMenus(!0);
}, 20);
}, 20);
}), MathJax.Hub.Register.StartupHook("SVG Jax Ready", function() {
MathJax.Hub.Config({
SVG: {
addMMLclasses: !0
}
});
var t, e = MathJax.OutputJax.SVG;
parseFloat(e.version) < 2.7 && (t = e.getJaxFromMath, e.Augment({
getJaxFromMath: function(e) {
return e.parentNode.className.match(/MathJax_SVG_Display/) && (e = e.parentNode),
t.call(this, e);
}
}));
}), MathJax.Ajax.config.path.a11y || (MathJax.Ajax.config.path.a11y = MathJax.Hub.config.root + "/extensions/a11y"),
MathJax.Ajax.Require("[a11y]/collapsible.js"), MathJax.Hub.Register.StartupHook("Collapsible Ready", function() {
MathJax.Extension.explorer.Explorer.Startup(), MathJax.Ajax.loadComplete("[a11y]/explorer.js");
});