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");