OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * @fileoverview A collection of JavaScript utilities used to simplify working | 6 * @fileoverview A collection of JavaScript utilities used to simplify working |
7 * with the DOM. | 7 * with the DOM. |
8 */ | 8 */ |
9 | 9 |
10 | 10 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 'AUDIO' : 'tag_audio', | 101 'AUDIO' : 'tag_audio', |
102 'BUTTON' : 'tag_button', | 102 'BUTTON' : 'tag_button', |
103 'SELECT' : 'tag_select', | 103 'SELECT' : 'tag_select', |
104 'TABLE' : 'tag_table', | 104 'TABLE' : 'tag_table', |
105 'TEXTAREA' : 'tag_textarea', | 105 'TEXTAREA' : 'tag_textarea', |
106 'VIDEO' : 'tag_video' | 106 'VIDEO' : 'tag_video' |
107 }; | 107 }; |
108 | 108 |
109 /** | 109 /** |
110 * These tags are treated as text formatters. | 110 * These tags are treated as text formatters. |
111 * @type {Array.<string>} | 111 * @type {Array<string>} |
112 */ | 112 */ |
113 cvox.DomUtil.FORMATTING_TAGS = | 113 cvox.DomUtil.FORMATTING_TAGS = |
114 ['B', 'BIG', 'CITE', 'CODE', 'DFN', 'EM', 'I', 'KBD', 'SAMP', 'SMALL', | 114 ['B', 'BIG', 'CITE', 'CODE', 'DFN', 'EM', 'I', 'KBD', 'SAMP', 'SMALL', |
115 'SPAN', 'STRIKE', 'STRONG', 'SUB', 'SUP', 'U', 'VAR']; | 115 'SPAN', 'STRIKE', 'STRONG', 'SUB', 'SUP', 'U', 'VAR']; |
116 | 116 |
117 /** | 117 /** |
118 * Determine if the given node is visible on the page. This does not check if | 118 * Determine if the given node is visible on the page. This does not check if |
119 * it is inside the document view-port as some sites try to communicate with | 119 * it is inside the document view-port as some sites try to communicate with |
120 * screen readers with such elements. | 120 * screen readers with such elements. |
121 * @param {Node} node The node to determine as visible or not. | 121 * @param {Node} node The node to determine as visible or not. |
(...skipping 817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
939 } | 939 } |
940 return text; | 940 return text; |
941 }; | 941 }; |
942 | 942 |
943 | 943 |
944 /** | 944 /** |
945 * Search the whole page for any aria-labelledby attributes and collect | 945 * Search the whole page for any aria-labelledby attributes and collect |
946 * the complete set of ids they map to, so that we can skip elements that | 946 * the complete set of ids they map to, so that we can skip elements that |
947 * just label other elements and not double-speak them. We cache this | 947 * just label other elements and not double-speak them. We cache this |
948 * result and then throw it away at the next event loop. | 948 * result and then throw it away at the next event loop. |
949 * @return {Object.<string, boolean>} Set of all ids that are mapped | 949 * @return {Object<string, boolean>} Set of all ids that are mapped |
950 * by aria-labelledby. | 950 * by aria-labelledby. |
951 */ | 951 */ |
952 cvox.DomUtil.getLabelledByTargets = function() { | 952 cvox.DomUtil.getLabelledByTargets = function() { |
953 if (cvox.labelledByTargets) { | 953 if (cvox.labelledByTargets) { |
954 return cvox.labelledByTargets; | 954 return cvox.labelledByTargets; |
955 } | 955 } |
956 | 956 |
957 // Start by getting all elements with | 957 // Start by getting all elements with |
958 // aria-labelledby on the page since that's probably a short list, | 958 // aria-labelledby on the page since that's probably a short list, |
959 // then see if any of those ids overlap with an id in this element's | 959 // then see if any of those ids overlap with an id in this element's |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1172 | 1172 |
1173 return true; | 1173 return true; |
1174 }; | 1174 }; |
1175 | 1175 |
1176 | 1176 |
1177 /** | 1177 /** |
1178 * Returns a list of all the ancestors of a given node. The last element | 1178 * Returns a list of all the ancestors of a given node. The last element |
1179 * is the current node. | 1179 * is the current node. |
1180 * | 1180 * |
1181 * @param {Node} targetNode The node to get ancestors for. | 1181 * @param {Node} targetNode The node to get ancestors for. |
1182 * @return {Array.<Node>} An array of ancestors for the targetNode. | 1182 * @return {Array<Node>} An array of ancestors for the targetNode. |
1183 */ | 1183 */ |
1184 cvox.DomUtil.getAncestors = function(targetNode) { | 1184 cvox.DomUtil.getAncestors = function(targetNode) { |
1185 var ancestors = new Array(); | 1185 var ancestors = new Array(); |
1186 while (targetNode) { | 1186 while (targetNode) { |
1187 ancestors.push(targetNode); | 1187 ancestors.push(targetNode); |
1188 targetNode = targetNode.parentNode; | 1188 targetNode = targetNode.parentNode; |
1189 } | 1189 } |
1190 ancestors.reverse(); | 1190 ancestors.reverse(); |
1191 while (ancestors.length && !ancestors[0].tagName && !ancestors[0].nodeValue) { | 1191 while (ancestors.length && !ancestors[0].tagName && !ancestors[0].nodeValue) { |
1192 ancestors.shift(); | 1192 ancestors.shift(); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1224 /** | 1224 /** |
1225 * Returns an array of ancestors that are unique for the currentNode when | 1225 * Returns an array of ancestors that are unique for the currentNode when |
1226 * compared to the previousNode. Having such an array is useful in generating | 1226 * compared to the previousNode. Having such an array is useful in generating |
1227 * the node information (identifying when interesting node boundaries have been | 1227 * the node information (identifying when interesting node boundaries have been |
1228 * crossed, etc.). | 1228 * crossed, etc.). |
1229 * | 1229 * |
1230 * @param {Node} previousNode The previous node. | 1230 * @param {Node} previousNode The previous node. |
1231 * @param {Node} currentNode The current node. | 1231 * @param {Node} currentNode The current node. |
1232 * @param {boolean=} opt_fallback True returns node's ancestors in the case | 1232 * @param {boolean=} opt_fallback True returns node's ancestors in the case |
1233 * where node's ancestors is a subset of previousNode's ancestors. | 1233 * where node's ancestors is a subset of previousNode's ancestors. |
1234 * @return {Array.<Node>} An array of unique ancestors for the current node | 1234 * @return {Array<Node>} An array of unique ancestors for the current node |
1235 * (inclusive). | 1235 * (inclusive). |
1236 */ | 1236 */ |
1237 cvox.DomUtil.getUniqueAncestors = function( | 1237 cvox.DomUtil.getUniqueAncestors = function( |
1238 previousNode, currentNode, opt_fallback) { | 1238 previousNode, currentNode, opt_fallback) { |
1239 var prevAncestors = cvox.DomUtil.getAncestors(previousNode); | 1239 var prevAncestors = cvox.DomUtil.getAncestors(previousNode); |
1240 var currentAncestors = cvox.DomUtil.getAncestors(currentNode); | 1240 var currentAncestors = cvox.DomUtil.getAncestors(currentNode); |
1241 var divergence = cvox.DomUtil.compareAncestors(prevAncestors, | 1241 var divergence = cvox.DomUtil.compareAncestors(prevAncestors, |
1242 currentAncestors); | 1242 currentAncestors); |
1243 var diff = currentAncestors.slice(divergence); | 1243 var diff = currentAncestors.slice(divergence); |
1244 return (diff.length == 0 && opt_fallback) ? currentAncestors : diff; | 1244 return (diff.length == 0 && opt_fallback) ? currentAncestors : diff; |
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1961 * is not. | 1961 * is not. |
1962 */ | 1962 */ |
1963 cvox.DomUtil.getContainingTable = function(node, kwargs) { | 1963 cvox.DomUtil.getContainingTable = function(node, kwargs) { |
1964 var ancestors = cvox.DomUtil.getAncestors(node); | 1964 var ancestors = cvox.DomUtil.getAncestors(node); |
1965 return cvox.DomUtil.findTableNodeInList(ancestors, kwargs); | 1965 return cvox.DomUtil.findTableNodeInList(ancestors, kwargs); |
1966 }; | 1966 }; |
1967 | 1967 |
1968 | 1968 |
1969 /** | 1969 /** |
1970 * Extracts a table node from a list of nodes. | 1970 * Extracts a table node from a list of nodes. |
1971 * @param {Array.<Node>} nodes The list of nodes. | 1971 * @param {Array<Node>} nodes The list of nodes. |
1972 * @param {{allowCaptions: (undefined|boolean)}=} kwargs Optional named args. | 1972 * @param {{allowCaptions: (undefined|boolean)}=} kwargs Optional named args. |
1973 * allowCaptions: If true, will return true even if inside a caption. False | 1973 * allowCaptions: If true, will return true even if inside a caption. False |
1974 * by default. | 1974 * by default. |
1975 * @return {Node} The table node if the list of nodes contains a table node. | 1975 * @return {Node} The table node if the list of nodes contains a table node. |
1976 * Null if it does not. | 1976 * Null if it does not. |
1977 */ | 1977 */ |
1978 cvox.DomUtil.findTableNodeInList = function(nodes, kwargs) { | 1978 cvox.DomUtil.findTableNodeInList = function(nodes, kwargs) { |
1979 kwargs = kwargs || {allowCaptions: false}; | 1979 kwargs = kwargs || {allowCaptions: false}; |
1980 // Don't include the caption node because it is actually rendered outside | 1980 // Don't include the caption node because it is actually rendered outside |
1981 // of the table. | 1981 // of the table. |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2204 cvox.DomUtil.findNodes_(root, p, rv, false, 10000); | 2204 cvox.DomUtil.findNodes_(root, p, rv, false, 10000); |
2205 return rv.length; | 2205 return rv.length; |
2206 }; | 2206 }; |
2207 | 2207 |
2208 | 2208 |
2209 /** | 2209 /** |
2210 * Finds the first or all the descendant nodes that match the filter function, | 2210 * Finds the first or all the descendant nodes that match the filter function, |
2211 * using a depth first search. | 2211 * using a depth first search. |
2212 * @param {Node} root The root of the tree to search. | 2212 * @param {Node} root The root of the tree to search. |
2213 * @param {function(Node) : boolean} p The filter function. | 2213 * @param {function(Node) : boolean} p The filter function. |
2214 * @param {Array.<Node>} rv The found nodes are added to this array. | 2214 * @param {Array<Node>} rv The found nodes are added to this array. |
2215 * @param {boolean} findOne If true we exit after the first found node. | 2215 * @param {boolean} findOne If true we exit after the first found node. |
2216 * @param {number} maxChildCount The max child count. This is used as a kill | 2216 * @param {number} maxChildCount The max child count. This is used as a kill |
2217 * switch - if there are more nodes than this, terminate the search. | 2217 * switch - if there are more nodes than this, terminate the search. |
2218 * @return {boolean} Whether the search is complete or not. True in case | 2218 * @return {boolean} Whether the search is complete or not. True in case |
2219 * findOne is true and the node is found. False otherwise. This is the | 2219 * findOne is true and the node is found. False otherwise. This is the |
2220 * findNodes_ function from goog.dom: | 2220 * findNodes_ function from goog.dom: |
2221 * http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/dom
/dom.js. | 2221 * http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/dom
/dom.js. |
2222 * @private | 2222 * @private |
2223 */ | 2223 */ |
2224 cvox.DomUtil.findNodes_ = function(root, p, rv, findOne, maxChildCount) { | 2224 cvox.DomUtil.findNodes_ = function(root, p, rv, findOne, maxChildCount) { |
(...skipping 27 matching lines...) Expand all Loading... |
2252 for (var i = 0; i < nodeList.length; i++) { | 2252 for (var i = 0; i < nodeList.length; i++) { |
2253 nodeArray.push(nodeList[i]); | 2253 nodeArray.push(nodeList[i]); |
2254 } | 2254 } |
2255 return nodeArray; | 2255 return nodeArray; |
2256 }; | 2256 }; |
2257 | 2257 |
2258 | 2258 |
2259 /** | 2259 /** |
2260 * Creates a new element with the same attributes and no children. | 2260 * Creates a new element with the same attributes and no children. |
2261 * @param {Node|Text} node A node to clone. | 2261 * @param {Node|Text} node A node to clone. |
2262 * @param {Object.<string, boolean>} skipattrs Set the attribute to true to | 2262 * @param {Object<string, boolean>} skipattrs Set the attribute to true to |
2263 * skip it during cloning. | 2263 * skip it during cloning. |
2264 * @return {Node|Text} The cloned node. | 2264 * @return {Node|Text} The cloned node. |
2265 */ | 2265 */ |
2266 cvox.DomUtil.shallowChildlessClone = function(node, skipattrs) { | 2266 cvox.DomUtil.shallowChildlessClone = function(node, skipattrs) { |
2267 if (node.nodeName == '#text') { | 2267 if (node.nodeName == '#text') { |
2268 return document.createTextNode(node.nodeValue); | 2268 return document.createTextNode(node.nodeValue); |
2269 } | 2269 } |
2270 | 2270 |
2271 if (node.nodeName == '#comment') { | 2271 if (node.nodeName == '#comment') { |
2272 return document.createComment(node.nodeValue); | 2272 return document.createComment(node.nodeValue); |
2273 } | 2273 } |
2274 | 2274 |
2275 var ret = document.createElement(node.nodeName); | 2275 var ret = document.createElement(node.nodeName); |
2276 for (var i = 0; i < node.attributes.length; ++i) { | 2276 for (var i = 0; i < node.attributes.length; ++i) { |
2277 var attr = node.attributes[i]; | 2277 var attr = node.attributes[i]; |
2278 if (skipattrs && skipattrs[attr.nodeName]) { | 2278 if (skipattrs && skipattrs[attr.nodeName]) { |
2279 continue; | 2279 continue; |
2280 } | 2280 } |
2281 ret.setAttribute(attr.nodeName, attr.nodeValue); | 2281 ret.setAttribute(attr.nodeName, attr.nodeValue); |
2282 } | 2282 } |
2283 return ret; | 2283 return ret; |
2284 }; | 2284 }; |
2285 | 2285 |
2286 | 2286 |
2287 /** | 2287 /** |
2288 * Creates a new element with the same attributes and clones of children. | 2288 * Creates a new element with the same attributes and clones of children. |
2289 * @param {Node|Text} node A node to clone. | 2289 * @param {Node|Text} node A node to clone. |
2290 * @param {Object.<string, boolean>} skipattrs Set the attribute to true to | 2290 * @param {Object<string, boolean>} skipattrs Set the attribute to true to |
2291 * skip it during cloning. | 2291 * skip it during cloning. |
2292 * @return {Node|Text} The cloned node. | 2292 * @return {Node|Text} The cloned node. |
2293 */ | 2293 */ |
2294 cvox.DomUtil.deepClone = function(node, skipattrs) { | 2294 cvox.DomUtil.deepClone = function(node, skipattrs) { |
2295 var ret = cvox.DomUtil.shallowChildlessClone(node, skipattrs); | 2295 var ret = cvox.DomUtil.shallowChildlessClone(node, skipattrs); |
2296 for (var i = 0; i < node.childNodes.length; ++i) { | 2296 for (var i = 0; i < node.childNodes.length; ++i) { |
2297 ret.appendChild(cvox.DomUtil.deepClone(node.childNodes[i], skipattrs)); | 2297 ret.appendChild(cvox.DomUtil.deepClone(node.childNodes[i], skipattrs)); |
2298 } | 2298 } |
2299 return ret; | 2299 return ret; |
2300 }; | 2300 }; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2369 * Null if it is not. | 2369 * Null if it is not. |
2370 */ | 2370 */ |
2371 cvox.DomUtil.getContainingMath = function(node) { | 2371 cvox.DomUtil.getContainingMath = function(node) { |
2372 var ancestors = cvox.DomUtil.getAncestors(node); | 2372 var ancestors = cvox.DomUtil.getAncestors(node); |
2373 return cvox.DomUtil.findMathNodeInList(ancestors); | 2373 return cvox.DomUtil.findMathNodeInList(ancestors); |
2374 }; | 2374 }; |
2375 | 2375 |
2376 | 2376 |
2377 /** | 2377 /** |
2378 * Extracts a math node from a list of nodes. | 2378 * Extracts a math node from a list of nodes. |
2379 * @param {Array.<Node>} nodes The list of nodes. | 2379 * @param {Array<Node>} nodes The list of nodes. |
2380 * @return {Node} The math node if the list of nodes contains a math node. | 2380 * @return {Node} The math node if the list of nodes contains a math node. |
2381 * Null if it does not. | 2381 * Null if it does not. |
2382 */ | 2382 */ |
2383 cvox.DomUtil.findMathNodeInList = function(nodes) { | 2383 cvox.DomUtil.findMathNodeInList = function(nodes) { |
2384 for (var i = 0, node; node = nodes[i]; i++) { | 2384 for (var i = 0, node; node = nodes[i]; i++) { |
2385 if (cvox.DomUtil.isMath(node)) { | 2385 if (cvox.DomUtil.isMath(node)) { |
2386 return node; | 2386 return node; |
2387 } | 2387 } |
2388 } | 2388 } |
2389 return null; | 2389 return null; |
2390 }; | 2390 }; |
2391 | 2391 |
2392 | 2392 |
2393 /** | 2393 /** |
2394 * Checks to see wether a node is a math node. | 2394 * Checks to see wether a node is a math node. |
2395 * @param {Node} node The node to be tested. | 2395 * @param {Node} node The node to be tested. |
2396 * @return {boolean} Whether or not a node is a math node. | 2396 * @return {boolean} Whether or not a node is a math node. |
2397 */ | 2397 */ |
2398 cvox.DomUtil.isMath = function(node) { | 2398 cvox.DomUtil.isMath = function(node) { |
2399 return cvox.DomUtil.isMathml(node) || | 2399 return cvox.DomUtil.isMathml(node) || |
2400 cvox.DomUtil.isMathJax(node) || | 2400 cvox.DomUtil.isMathJax(node) || |
2401 cvox.DomUtil.isMathImg(node) || | 2401 cvox.DomUtil.isMathImg(node) || |
2402 cvox.AriaUtil.isMath(node); | 2402 cvox.AriaUtil.isMath(node); |
2403 }; | 2403 }; |
2404 | 2404 |
2405 | 2405 |
2406 /** | 2406 /** |
2407 * Specifies node classes in which we expect maths expressions a alt text. | 2407 * Specifies node classes in which we expect maths expressions a alt text. |
2408 * @type {{tex: Array.<string>, | 2408 * @type {{tex: Array<string>, |
2409 * asciimath: Array.<string>}} | 2409 * asciimath: Array<string>}} |
2410 */ | 2410 */ |
2411 // These are the classes for which we assume they contain Maths in the ALT or | 2411 // These are the classes for which we assume they contain Maths in the ALT or |
2412 // TITLE attribute. | 2412 // TITLE attribute. |
2413 // tex: Wikipedia; | 2413 // tex: Wikipedia; |
2414 // latex: Wordpress; | 2414 // latex: Wordpress; |
2415 // numberedequation, inlineformula, displayformula: MathWorld; | 2415 // numberedequation, inlineformula, displayformula: MathWorld; |
2416 cvox.DomUtil.ALT_MATH_CLASSES = { | 2416 cvox.DomUtil.ALT_MATH_CLASSES = { |
2417 tex: ['tex', 'latex'], | 2417 tex: ['tex', 'latex'], |
2418 asciimath: ['numberedequation', 'inlineformula', 'displayformula'] | 2418 asciimath: ['numberedequation', 'inlineformula', 'displayformula'] |
2419 }; | 2419 }; |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2533 if (node.nodeType == Node.ELEMENT_NODE) { | 2533 if (node.nodeType == Node.ELEMENT_NODE) { |
2534 return node.tagName; | 2534 return node.tagName; |
2535 } | 2535 } |
2536 return ''; | 2536 return ''; |
2537 }; | 2537 }; |
2538 | 2538 |
2539 | 2539 |
2540 /** | 2540 /** |
2541 * Cleaning up a list of nodes to remove empty text nodes. | 2541 * Cleaning up a list of nodes to remove empty text nodes. |
2542 * @param {NodeList} nodes The nodes list. | 2542 * @param {NodeList} nodes The nodes list. |
2543 * @return {!Array.<Node|string|null>} The cleaned up list of nodes. | 2543 * @return {!Array<Node|string|null>} The cleaned up list of nodes. |
2544 */ | 2544 */ |
2545 cvox.DomUtil.purgeNodes = function(nodes) { | 2545 cvox.DomUtil.purgeNodes = function(nodes) { |
2546 return cvox.DomUtil.toArray(nodes). | 2546 return cvox.DomUtil.toArray(nodes). |
2547 filter(function(node) { | 2547 filter(function(node) { |
2548 return node.nodeType != Node.TEXT_NODE || | 2548 return node.nodeType != Node.TEXT_NODE || |
2549 !node.textContent.match(/^\s+$/);}); | 2549 !node.textContent.match(/^\s+$/);}); |
2550 }; | 2550 }; |
2551 | 2551 |
2552 | 2552 |
2553 /** | 2553 /** |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2597 var describedNode = document.getElementById(describedById); | 2597 var describedNode = document.getElementById(describedById); |
2598 if (describedNode) { | 2598 if (describedNode) { |
2599 desc += ' ' + cvox.DomUtil.getName( | 2599 desc += ' ' + cvox.DomUtil.getName( |
2600 describedNode, true, true, true); | 2600 describedNode, true, true, true); |
2601 } | 2601 } |
2602 } | 2602 } |
2603 } | 2603 } |
2604 } | 2604 } |
2605 return desc; | 2605 return desc; |
2606 }; | 2606 }; |
OLD | NEW |