Skip to content

Commit 79c72f2

Browse files
committed
Inject the text from the text layer in the MathML tags when they're in the struct tree (bug 1998046)
This way, the screen readers can read the math content properly. The elements in the text layer will also have aria-hidden="true" to avoid duplication.
1 parent 8435e8f commit 79c72f2

2 files changed

Lines changed: 25 additions & 4 deletions

File tree

test/integration/accessibility_spec.mjs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,8 +420,12 @@ describe("accessibility", () => {
420420
expect(mathML)
421421
.withContext(`In ${browserName}`)
422422
.toEqual(
423-
`<mi aria-owns="p76R_mc16"></mi><mo aria-owns="p76R_mc17"></mo><msqrt><mrow><msup><mi aria-owns="p76R_mc18"></mi><mn aria-owns="p76R_mc19"></mn></msup><mo aria-owns="p76R_mc20"></mo><msup><mi aria-owns="p76R_mc21"></mi><mn aria-owns="p76R_mc22"></mn></msup></mrow></msqrt>`
423+
`<mi aria-owns="p76R_mc16">𝑐</mi><mo aria-owns="p76R_mc17">=</mo><msqrt><mrow><msup><mi aria-owns="p76R_mc18">𝑎</mi><mn aria-owns="p76R_mc19">2</mn></msup><mo aria-owns="p76R_mc20">+</mo><msup><mi aria-owns="p76R_mc21">𝑏</mi><mn aria-owns="p76R_mc22">2</mn></msup></mrow></msqrt>`
424424
);
425+
const ariaHidden = await page.$eval("span#p76R_mc16", el =>
426+
el.getAttribute("aria-hidden")
427+
);
428+
expect(ariaHidden).withContext(`In ${browserName}`).toEqual("true");
425429
})
426430
);
427431
});

web/struct_tree_layer_builder.js

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -323,9 +323,26 @@ class StructTreeLayerBuilder {
323323
let element;
324324
if ("role" in node) {
325325
const { role } = node;
326-
element = MathMLElements.has(role)
327-
? document.createElementNS(MathMLNamespace, role)
328-
: document.createElement("span");
326+
if (MathMLElements.has(role)) {
327+
element = document.createElementNS(MathMLNamespace, role);
328+
let text = "";
329+
for (const { type, id } of node.children || []) {
330+
if (type !== "content" || !id) {
331+
continue;
332+
}
333+
const elem = document.getElementById(id);
334+
if (!elem) {
335+
continue;
336+
}
337+
text += elem.textContent.trim() || "";
338+
// Aria-hide the element in order to avoid duplicate reading of the
339+
// math content by screen readers.
340+
elem.ariaHidden = "true";
341+
}
342+
element.textContent = text;
343+
} else {
344+
element = document.createElement("span");
345+
}
329346
const match = role.match(HEADING_PATTERN);
330347
if (match) {
331348
element.setAttribute("role", "heading");

0 commit comments

Comments
 (0)