From ad004ac6687d9593240c6725a52ed17f774eceba Mon Sep 17 00:00:00 2001 From: "Davide P. Cervone" Date: Sun, 14 Sep 2014 13:47:20 -0400 Subject: [PATCH] Preserve RDFa and other non-standard attributes from MathML elements in the HTML-CSS or SVG output. Resolves issue #860, and also handles #502 as a side-effect. --- unpacked/MathJax.js | 8 ++++++- unpacked/jax/element/mml/jax.js | 6 +++++ unpacked/jax/output/HTML-CSS/jax.js | 33 ++++++++++++++++++++++------ unpacked/jax/output/SVG/jax.js | 34 ++++++++++++++++++++++++----- 4 files changed, 67 insertions(+), 14 deletions(-) diff --git a/unpacked/MathJax.js b/unpacked/MathJax.js index 1d6946d05..0c6bcb1fe 100644 --- a/unpacked/MathJax.js +++ b/unpacked/MathJax.js @@ -1895,7 +1895,13 @@ MathJax.Hub = { // localized HTML snippet structure for message to use message: ["[",["MathProcessingError","Math Processing Error"],"]"], style: {color: "#CC0000", "font-style":"italic"} // style for message - } + }, + + ignoreMMLattributes: {} // attributes not to copy to HTML-CSS or SVG output + // from MathML input (in addition to the ones in MML.nocopyAttributes). + // An id set to true will be ignored, one set to false will + // be allowed (even if other criteria normally would prevent + // it from being copied); use false carefully! }, preProcessors: MathJax.Callback.Hooks(true), // list of callbacks for preprocessing (initialized by extensions) diff --git a/unpacked/jax/element/mml/jax.js b/unpacked/jax/element/mml/jax.js index f8f56f1ef..0492c765d 100644 --- a/unpacked/jax/element/mml/jax.js +++ b/unpacked/jax/element/mml/jax.js @@ -226,6 +226,12 @@ MathJax.ElementJax.mml.Augment({ "color", "background", "id", "class", "href", "style" ], + nocopyAttributes: { + fontfamily: true, fontsize: true, fontweight: true, fontstyle: true, + color: true, background: true, + id: true, class: true, href: true, style: true, + xmlns: true + }, Error: function (message,def) { var mml = this.merror(message), dir = MathJax.Localization.fontDirection(), diff --git a/unpacked/jax/output/HTML-CSS/jax.js b/unpacked/jax/output/HTML-CSS/jax.js index dd05492c7..0f141a184 100644 --- a/unpacked/jax/output/HTML-CSS/jax.js +++ b/unpacked/jax/output/HTML-CSS/jax.js @@ -582,11 +582,6 @@ div = this.Element("div",{className:"MathJax_Display"}); div.appendChild(span); } else if (this.msieDisappearingBug) {span.style.display = "inline-block"} - // - // Mark math for screen readers - // (screen readers don't know about role="math" yet, so use "textbox" instead) - // - div.setAttribute("role","textbox"); div.setAttribute("aria-readonly","true"); div.className += " MathJax_Processing"; script.parentNode.insertBefore(div,script); // @@ -1834,8 +1829,30 @@ if (this.styles.padding) {span.style.padding = ""} } if (this.href) {span.parentNode.bbox = span.bbox} + this.HTMLaddAttributes(span); return span; }, + HTMLaddAttributes: function(span) { + // + // Copy RDFa, aria, and other tags from the MathML to the HTML-CSS + // output spans Don't copy those in the MML.nocopyAttributes list, + // the ignoreMMLattributes configuration list, or anything tha + // already exists as a property of the span (e.g., no "onlick", etc.) + // If a name in the ignoreMMLattributes object is set to false, then + // the attribute WILL be copied. + // + if (this.attrNames) { + var copy = this.attrNames, skip = MML.nocopyAttributes, ignore = HUB.config.ignoreMMLattributes; + var defaults = (this.type === "mstyle" ? MML.math.prototype.defaults : this.defaults); + for (var i = 0, m = copy.length; i < m; i++) { + var id = copy[i]; + if (ignore[id] == false || (!skip[id] && !ignore[id] && + defaults[id] == null && typeof(span[id]) === "undefined")) { + span.setAttribute(id,this.attr[id]) + } + } + } + }, HTMLspanElement: function () { if (!this.spanID) {return null} return document.getElementById((this.id||"MathJax-Span-"+this.spanID)+HTMLCSS.idPostfix); @@ -2782,10 +2799,12 @@ MML.math.Augment({ toHTML: function (span,node) { - var alttext = this.Get("alttext"); - if (alttext && alttext !== "") {node.setAttribute("aria-label",alttext)} var nobr = HTMLCSS.addElement(span,"nobr",{isMathJax: true}); span = this.HTMLcreateSpan(nobr); + var alttext = this.Get("alttext"); + if (alttext && !span.getAttribute("aria-label")) span.setAttribute("aria-label",alttext); + if (!span.getAttribute("role")) span.setAttribute("role","math"); + span.setAttribute("tabindex",0); var stack = HTMLCSS.createStack(span), box = HTMLCSS.createBox(stack), math; // Move font-size from outer span to stack to avoid line separation // problem in strict HTML mode diff --git a/unpacked/jax/output/SVG/jax.js b/unpacked/jax/output/SVG/jax.js index 4045a1ee9..47bbd1206 100644 --- a/unpacked/jax/output/SVG/jax.js +++ b/unpacked/jax/output/SVG/jax.js @@ -227,11 +227,6 @@ div = HTML.Element("div",{className:"MathJax_SVG_Display"}); div.appendChild(span); } - // - // Mark math for screen readers - // (screen readers don't know about role="math" yet, so use "textbox" instead) - // - div.setAttribute("role","textbox"); div.setAttribute("aria-readonly","true"); div.className += " MathJax_SVG_Processing"; script.parentNode.insertBefore(div,script); // @@ -1136,13 +1131,36 @@ svg.element.style.cssText = style; if (svg.element.style.fontSize) {svg.element.style.fontSize = ""} // handled by scale svg.element.style.border = svg.element.style.padding = ""; - if (svg.removeable) {svg.removeable = svg.element.style.cssText === ""} + if (svg.removeable) {svg.removeable = (svg.element.style.cssText === "")} } + this.SVGaddAttributes(svg); }, SVGaddClass: function (node,name) { var classes = node.getAttribute("class"); node.setAttribute("class",(classes ? classes+" " : "")+name); }, + SVGaddAttributes: function (svg) { + // + // Copy RDFa, aria, and other tags from the MathML to the HTML-CSS + // output spans Don't copy those in the MML.nocopyAttributes list, + // the ignoreMMLattributes configuration list, or anything tha + // already exists as a property of the span (e.g., no "onlick", etc.) + // If a name in the ignoreMMLattributes object is set to false, then + // the attribute WILL be copied. + // + if (this.attrNames) { + var copy = this.attrNames, skip = MML.nocopyAttributes, ignore = HUB.config.ignoreMMLattributes; + var defaults = (this.type === "mstyle" ? MML.math.prototype.defaults : this.defaults); + for (var i = 0, m = copy.length; i < m; i++) { + var id = copy[i]; + if (ignore[id] == false || (!skip[id] && !ignore[id] && + defaults[id] == null && typeof(svg.element[id]) === "undefined")) { + svg.element.setAttribute(id,this.attr[id]); + svg.removeable = false; + } + } + } + }, // // WebKit currently scrolls to the BOTTOM of an svg element if it contains the // target of the link, so implement link by hand, to the containing span element. @@ -2058,6 +2076,10 @@ // // Add it to the MathJax span // + var alttext = this.Get("alttext"); + if (alttext && !svg.element.getAttribute("aria-label")) span.setAttribute("aria-label",alttext); + if (!svg.element.getAttribute("role")) span.setAttribute("role","math"); + span.setAttribute("tabindex",0); span.appendChild(svg.element); svg.element = null; // // Handle indentalign and indentshift for single-line displays