Skip to content

Commit c7fdff3

Browse files
authored
Merge pull request #1051 from mathjax/refactor/explorer_expansion
Refactor/explorer expansion
2 parents 42fd15d + 2ff396e commit c7fdff3

File tree

1 file changed

+40
-3
lines changed

1 file changed

+40
-3
lines changed

ts/a11y/explorer/KeyExplorer.ts

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,32 @@ export class SpeechExplorer extends AbstractExplorer<string> implements KeyExplo
294294
['>', this.nextRules.bind(this)],
295295
['<', this.nextStyle.bind(this)],
296296
['x', this.summary.bind(this)],
297+
['-', this.expand.bind(this)],
297298
]);
298299

300+
/**
301+
* Checks if a node is actionable, i.e., corresponds to an maction.
302+
*
303+
* @param {HTMLElement} node The (rendered) node under consideration.
304+
* @returns {HTMLElement} The node corresponding to an maction element.
305+
*/
306+
private actionable(node: HTMLElement): HTMLElement {
307+
const parent = node?.parentNode as HTMLElement;
308+
return parent && this.highlighter.isMactionNode(parent) ? parent : null;
309+
}
310+
311+
/**
312+
* Expands or collapses the currently focused node.
313+
*
314+
* @param {HTMLElement} node The focused node.
315+
*/
316+
public expand(node: HTMLElement) {
317+
const expandable = this.actionable(node);
318+
if (expandable) {
319+
expandable.dispatchEvent(new Event('click'));
320+
}
321+
}
322+
299323
/**
300324
* Computes the summary for this expression. This is temporary and will be
301325
* replaced by the full speech on focus out.
@@ -408,9 +432,22 @@ export class SpeechExplorer extends AbstractExplorer<string> implements KeyExplo
408432
// Here we refocus after a restart: We either find the previously focused
409433
// node or we assume that it is inside the collapsed expression tree and
410434
// focus on the collapsed element.
411-
this.current =
412-
this.node.querySelector(`[data-semantic-id="${this.restarted}"]`) ||
413-
this.node.querySelector(`[data-semantic-type="dummy"]`);
435+
this.current = this.node.querySelector(`[data-semantic-id="${this.restarted}"]`)
436+
if (!this.current) {
437+
const dummies = Array.from(
438+
this.node.querySelectorAll(`[data-semantic-type="dummy"]`))
439+
.map(x => x.getAttribute('data-semantic-id'))
440+
let internal = this.generators.element.querySelector(
441+
`[data-semantic-id="${this.restarted}"]`);
442+
while (internal && internal !== this.generators.element) {
443+
let sid = internal.getAttribute('data-semantic-id');
444+
if (dummies.indexOf(sid) !== -1) {
445+
this.current = this.node.querySelector(`[data-semantic-id="${sid}"]`);
446+
break;
447+
};
448+
internal = internal.parentNode as Element;
449+
}
450+
}
414451
this.restarted = null;
415452
}
416453
if (!this.current) {

0 commit comments

Comments
 (0)