From 79c72f2c9a0c093515f0ff99dc0bba3dc3616ae2 Mon Sep 17 00:00:00 2001 From: calixteman Date: Sun, 30 Nov 2025 23:11:15 +0100 Subject: [PATCH] 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. --- test/integration/accessibility_spec.mjs | 6 +++++- web/struct_tree_layer_builder.js | 23 ++++++++++++++++++++--- 2 files changed, 25 insertions(+), 4 deletions(-) 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");