Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / resources / chromeos / chromevox / common / math_util.js
blob4de27ae3913c391bdc4db2706d1eba62e0b82ca2
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 /**
6  * @fileoverview DOM utility functions to aid in math expressions navigation.
7  */
9 goog.provide('cvox.MathUtil');
11 goog.require('cvox.ChromeVox');
12 goog.require('cvox.XpathUtil');
15 /**
16  * Checks if a node is in a given class of MathML nodes.
17  * @private
18  * @param {!Node} node The node to test.
19  * @param {Array<string>} tags List of tag names.
20  * @return {boolean} True if node has a tag name included in tags.
21  */
22 cvox.MathUtil.isMathmlNodeOfClass_ = function(node, tags) {
23   return tags.indexOf(node.tagName.toUpperCase()) != -1;
27 /**
28  * Checks if a node is in a given class of MathJax nodes.
29  * @private
30  * @param {!Node} node The node to test.
31  * @param {Array<string>} tags List of tag names.
32  * @return {boolean} True if node has a tag name included in tags.
33  */
34 cvox.MathUtil.isMathjaxNodeOfClass_ = function(node, tags) {
35   if (node.tagName == 'SPAN') {
36     var classes = node.className.split(' ');
37     return classes.some(function(x)
38                         {return tags.indexOf(x.toUpperCase()) != -1;});
39   }
40   return false;
44 /**
45  * Checks if a node is an element node that belongs to a given class
46  * of MathML or MathJax nodes.
47  * @private
48  * @param {!Node} node The node to test.
49  * @param {Array<string>} tags List of tag names.
50  * @return {boolean} True if node has a tag name included in tags.
51  */
52 cvox.MathUtil.isMathNodeOfClass_ = function(node, tags) {
53   return (node.nodeType == Node.ELEMENT_NODE &&
54           (cvox.MathUtil.isMathmlNodeOfClass_(node, tags) ||
55            cvox.MathUtil.isMathjaxNodeOfClass_(node, tags)));
59 /**
60  * Array of MathML Token Elements.
61  * @type {!Array<string>}
62  */
63 cvox.MathUtil.TOKEN_LIST = ['MI', 'MN', 'MO', 'MTEXT', 'MSPACE', 'MS'];
66 /**
67  *  Checks if an element of a math expression is a Token Element.
68  * Token elements are the following:
69  * <mi> identifier.
70  * <mn> number.
71  * <mo> operator, fence, or separator.
72  * <mtext> text.
73  * <mspace> space.
74  * <ms> string literal.
75  * @param {!Node} element The element of the math expression.
76  * @return {boolean} True if element is a token.
77  */
78 cvox.MathUtil.isToken = function(element) {
79   return cvox.MathUtil.isMathNodeOfClass_(element, cvox.MathUtil.TOKEN_LIST);
83 /**
84  * Array of MathML Layout Schemata.
85  * @type {!Array<string>}
86  */
87 cvox.MathUtil.LAYOUT_LIST = ['MROW', 'MFRAC', 'MSQRT', 'MROOT', 'MSTYLE',
88                              'MERROR', 'MPADDED', 'MPHANTOM', 'MFENCED',
89                              'MENCLOSE'];
92 /**
93  *  Checks if an element of a math expression is a Layout Schema.
94  * Layout elements are the following:
95  * <mrow> group any number of sub-expressions horizontally
96  * <mfrac> form a fraction from two sub-expressions
97  * <msqrt> form a square root (radical without an index)
98  * <mroot> form a radical with specified index
99  * <mstyle> style change
100  * <merror> enclose a syntax error message from a preprocessor
101  * <mpadded> adjust space around content
102  * <mphantom> make content invisible but preserve its size
103  * <mfenced> surround content with a pair of fences
104  * <menclose> enclose content with a stretching symbol such as a long
105  * division sign.
106  * @param {!Node} element The element of the math expression.
107  * @return {boolean} True if element is a layout schema.
108  */
109 cvox.MathUtil.isLayout = function(element) {
110   return cvox.MathUtil.isMathNodeOfClass_(element, cvox.MathUtil.LAYOUT_LIST);
115  * Array of MathML Script Schemata.
116  * @type {!Array<string>}
117  */
118 cvox.MathUtil.SCRIPT_LIST = ['MSUB', 'MSUP', 'MSUBSUP', 'MUNDER', 'MOVER',
119                              'MUNDEROVER', 'MMULTISCRIPTS', 'MPRESCRIPTS'];
123  *  Checks if an element of a math expression is a Script Schema.
124  * Script elements are the following:
125  * <msub> attach a subscript to a base.
126  * <msup> attach a superscript to a base.
127  * <msubsup> attach a subscript-superscript pair to a base.
128  * <munder> attach an underscript to a base.
129  * <mover> attach an overscript to a base.
130  * <munderover> attach an underscript-overscript pair to a base.
131  * <mmultiscripts> attach prescripts and tensor indices to a base.
132  * Prescripts are optional.
133  * <mprescripts> two elements prescripts of mmultiscripts. Only makes sense
134  * in that environment (although not illegal outside)!  Two
135  * arguments mandatory (can be <none/>).
136  * @param {!Node} element The element of the math expression.
137  * @return {boolean} True if element is a script schema.
138  */
139 cvox.MathUtil.isScript = function(element) {
140   return cvox.MathUtil.isMathNodeOfClass_(element, cvox.MathUtil.SCRIPT_LIST);
145  * Array of MathML Table and Matrix tokens.
146  * @type {!Array<string>}
147  */
148 cvox.MathUtil.TABLES_LIST = ['MTABLE', 'MLABELEDTR', 'MTR', 'MTD',
149                              'MALIGNGROUP', 'MALIGNMARK'];
153  *  Checks if an element of a math expression is a Tables Schema.
154  * Tables elements are the following:
155  * <mtable> table or matrix.
156  * <mlabeledtr> row in a table or matrix with a label or equation number.
157  * <mtr> row in a table or matrix.
158  * <mtd> one entry in a table or matrix.
159  * <maligngroup> and
160  * <malignmark> alignment markers.
161  * @param {!Node} element The element of the math expression.
162  * @return {boolean} True if element is a tables schema.
163  */
164 cvox.MathUtil.isTables = function(element) {
165   return cvox.MathUtil.isMathNodeOfClass_(element, cvox.MathUtil.TABLES_LIST);
170  * Array of MathML Elementary Layout Schemata.
171  * @type {!Array<string>}
172  */
173 cvox.MathUtil.ELEMENTARY_LIST = ['MSTACK', 'MLONGDIV', 'MSGROUP', 'MSROW',
174                                  'MSCARRIES', 'MSCARRY', 'MSLINE'];
178  *  Checks if an element of a math expression is a Elementary Schema.
179  * Elementary elements are the following:
180  * <mstack> columns of aligned characters.
181  * <mlongdiv> similar to msgroup, with the addition of a divisor and result.
182  * <msgroup> a group of rows in an mstack that are shifted by similar amounts.
183  * <msrow> a row in an mstack.
184  * <mscarries> row in an mstack that whose contents represent carries
185  *             or borrows.
186  * <mscarry> one entry in an mscarries.
187  * <msline> horizontal line inside of mstack.
188  * @param {!Node} element The element of the math expression.
189  * @return {boolean} True if element is a elementary schema.
190  */
191 cvox.MathUtil.isElementary = function(element) {
192   return cvox.MathUtil.isMathNodeOfClass_(element,
193                                           cvox.MathUtil.ELEMENTARY_LIST);
198  * Array of all valid tags in a MathML expression.
199  * This is a union of all other token lists.
200  * @type {!Array<string>}
201  */
202 cvox.MathUtil.MATHML_TAG_LIST = [cvox.MathUtil.TOKEN_LIST,
203                                  cvox.MathUtil.LAYOUT_LIST,
204                                  cvox.MathUtil.SCRIPT_LIST,
205                                  cvox.MathUtil.TABLES_LIST,
206                                  cvox.MathUtil.ELEMENTARY_LIST].reduce(
207                                      function(x, y) { return x.concat(y); });
211  * Checks if a node is valid element of a MathML expression.
212  * @param {!Node} element The element of the math expression.
213  * @return {boolean} True if element has a valid MathML tag.
214  */
215 cvox.MathUtil.isMathmlTag = function(element) {
216   return cvox.MathUtil.isMathNodeOfClass_(element,
217                                           cvox.MathUtil.MATHML_TAG_LIST);
222  * Array of MathML Whitespace and Alignment tokens.
223  * These are elements that can occur in the other token lists.
224  * @type {!Array<string>}
225  */
226 cvox.MathUtil.WHITESPACE_LIST = ['MSROW', 'MROW', 'MSPACE',
227                                  'MPHANTOM', 'MPADDED'];
231  * Checks if an element of a math expression is whitespace or an
232  * alignment marker.
233  * @param {!Node} element The element of the math expression.
234  * @return {boolean} True if element is a whitespace node.
235  */
236 cvox.MathUtil.isWhitespace = function(element) {
237   return cvox.MathUtil.isMathNodeOfClass_(element,
238                                           cvox.MathUtil.WHITESPACE_LIST);
243  * Checks if an element of a math expression is a legal mathml markup element
244  * but not a whitespace or an alignment marker.
245  * @param {!Node} element The element of the math expression.
246  * @return {boolean} True if element is a non-whitespace node.
247  */
248 cvox.MathUtil.isNotWhitespace = function(element) {
249   return (cvox.MathUtil.isMathmlTag(element) &&
250           !cvox.MathUtil.isWhitespace(element));
255  * Computes the union of two arrays (not in a strictly set theoretical sense
256  * as all duplicate elements in either array still remain as duplicates!).
257  * @param {Array} a An array.
258  * @param {Array} b Another array.
259  * @return {Array} Union of a and b.
260  */
261 cvox.MathUtil.union = function(a, b) {
262   return a.concat(b.filter(function(x) {return a.indexOf(x) < 0;}));