diff --git a/test/integration/accessibility_spec.mjs b/test/integration/accessibility_spec.mjs index 52815f181..71d7a7bce 100644 --- a/test/integration/accessibility_spec.mjs +++ b/test/integration/accessibility_spec.mjs @@ -420,8 +420,12 @@ describe("accessibility", () => { expect(mathML) .withContext(`In ${browserName}`) .toEqual( - `` + `𝑐=𝑎2+𝑏2` ); + const ariaHidden = await page.$eval("span#p76R_mc16", el => + el.getAttribute("aria-hidden") + ); + expect(ariaHidden).withContext(`In ${browserName}`).toEqual("true"); }) ); }); diff --git a/web/struct_tree_layer_builder.js b/web/struct_tree_layer_builder.js index 94d7617c3..f52b6acc0 100644 --- a/web/struct_tree_layer_builder.js +++ b/web/struct_tree_layer_builder.js @@ -323,9 +323,26 @@ class StructTreeLayerBuilder { let element; if ("role" in node) { const { role } = node; - element = MathMLElements.has(role) - ? document.createElementNS(MathMLNamespace, role) - : document.createElement("span"); + if (MathMLElements.has(role)) { + element = document.createElementNS(MathMLNamespace, role); + let text = ""; + for (const { type, id } of node.children || []) { + if (type !== "content" || !id) { + continue; + } + const elem = document.getElementById(id); + if (!elem) { + continue; + } + text += elem.textContent.trim() || ""; + // Aria-hide the element in order to avoid duplicate reading of the + // math content by screen readers. + elem.ariaHidden = "true"; + } + element.textContent = text; + } else { + element = document.createElement("span"); + } const match = role.match(HEADING_PATTERN); if (match) { element.setAttribute("role", "heading");