mathMLTree.js (2702B)
1 /** 2 * These objects store data about MathML nodes. This is the MathML equivalent 3 * of the types in domTree.js. Since MathML handles its own rendering, and 4 * since we're mainly using MathML to improve accessibility, we don't manage 5 * any of the styling state that the plain DOM nodes do. 6 * 7 * The `toNode` and `toMarkup` functions work simlarly to how they do in 8 * domTree.js, creating namespaced DOM nodes and HTML text markup respectively. 9 */ 10 11 const utils = require("./utils"); 12 13 /** 14 * This node represents a general purpose MathML node of any type. The 15 * constructor requires the type of node to create (for example, `"mo"` or 16 * `"mspace"`, corresponding to `<mo>` and `<mspace>` tags). 17 */ 18 function MathNode(type, children) { 19 this.type = type; 20 this.attributes = {}; 21 this.children = children || []; 22 } 23 24 /** 25 * Sets an attribute on a MathML node. MathML depends on attributes to convey a 26 * semantic content, so this is used heavily. 27 */ 28 MathNode.prototype.setAttribute = function(name, value) { 29 this.attributes[name] = value; 30 }; 31 32 /** 33 * Converts the math node into a MathML-namespaced DOM element. 34 */ 35 MathNode.prototype.toNode = function() { 36 const node = document.createElementNS( 37 "http://www.w3.org/1998/Math/MathML", this.type); 38 39 for (const attr in this.attributes) { 40 if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) { 41 node.setAttribute(attr, this.attributes[attr]); 42 } 43 } 44 45 for (let i = 0; i < this.children.length; i++) { 46 node.appendChild(this.children[i].toNode()); 47 } 48 49 return node; 50 }; 51 52 /** 53 * Converts the math node into an HTML markup string. 54 */ 55 MathNode.prototype.toMarkup = function() { 56 let markup = "<" + this.type; 57 58 // Add the attributes 59 for (const attr in this.attributes) { 60 if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) { 61 markup += " " + attr + "=\""; 62 markup += utils.escape(this.attributes[attr]); 63 markup += "\""; 64 } 65 } 66 67 markup += ">"; 68 69 for (let i = 0; i < this.children.length; i++) { 70 markup += this.children[i].toMarkup(); 71 } 72 73 markup += "</" + this.type + ">"; 74 75 return markup; 76 }; 77 78 /** 79 * This node represents a piece of text. 80 */ 81 function TextNode(text) { 82 this.text = text; 83 } 84 85 /** 86 * Converts the text node into a DOM text node. 87 */ 88 TextNode.prototype.toNode = function() { 89 return document.createTextNode(this.text); 90 }; 91 92 /** 93 * Converts the text node into HTML markup (which is just the text itself). 94 */ 95 TextNode.prototype.toMarkup = function() { 96 return utils.escape(this.text); 97 }; 98 99 module.exports = { 100 MathNode: MathNode, 101 TextNode: TextNode, 102 };