Home | History | Annotate | Download | only in common
      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.
      4 
      5 /**
      6  * @fileoverview A collection of JavaScript utilities used to simplify working
      7  * with xpaths.
      8  */
      9 
     10 
     11 goog.provide('cvox.XpathUtil');
     12 
     13 
     14 /**
     15  * Utilities for simplifying working with xpaths
     16  * @constructor
     17  */
     18 cvox.XpathUtil = function() {
     19  };
     20 
     21 
     22 /**
     23  * Mapping for some default namespaces.
     24  * @const
     25  * @private
     26  */
     27 cvox.XpathUtil.nameSpaces_ = {
     28   'xhtml' : 'http://www.w3.org/1999/xhtml',
     29   'mathml': 'http://www.w3.org/1998/Math/MathML'
     30 };
     31 
     32 
     33 /**
     34  * Resolve some default name spaces.
     35  * @param {string} prefix Namespace prefix.
     36  * @return {string} The corresponding namespace URI.
     37  */
     38 cvox.XpathUtil.resolveNameSpace = function(prefix) {
     39   return cvox.XpathUtil.nameSpaces_[prefix] || null;
     40 };
     41 
     42 
     43 /**
     44  * Given an XPath expression and rootNode, it returns an array of children nodes
     45  * that match. The code for this function was taken from Mihai Parparita's GMail
     46  * Macros Greasemonkey Script.
     47  * http://gmail-greasemonkey.googlecode.com/svn/trunk/scripts/gmail-new-macros.user.js
     48  * @param {string} expression The XPath expression to evaluate.
     49  * @param {Node} rootNode The HTML node to start evaluating the XPath from.
     50  * @return {Array} The array of children nodes that match.
     51  */
     52 cvox.XpathUtil.evalXPath = function(expression, rootNode) {
     53   try {
     54     var xpathIterator = rootNode.ownerDocument.evaluate(
     55       expression,
     56       rootNode,
     57       cvox.XpathUtil.resolveNameSpace,
     58       XPathResult.ORDERED_NODE_ITERATOR_TYPE,
     59       null); // no existing results
     60   } catch (err) {
     61     return [];
     62   }
     63   var results = [];
     64   // Convert result to JS array
     65   for (var xpathNode = xpathIterator.iterateNext();
     66        xpathNode;
     67        xpathNode = xpathIterator.iterateNext()) {
     68     results.push(xpathNode);
     69   }
     70   return results;
     71 };
     72 
     73 /**
     74  * Given a rootNode, it returns an array of all its leaf nodes.
     75  * @param {Node} rootNode The node to get the leaf nodes from.
     76  * @return {Array} The array of leaf nodes for the given rootNode.
     77  */
     78 cvox.XpathUtil.getLeafNodes = function(rootNode) {
     79   try {
     80     var xpathIterator = rootNode.ownerDocument.evaluate(
     81       './/*[count(*)=0]',
     82       rootNode,
     83       null, // no namespace resolver
     84       XPathResult.ORDERED_NODE_ITERATOR_TYPE,
     85       null); // no existing results
     86   } catch (err) {
     87     return [];
     88   }
     89   var results = [];
     90   // Convert result to JS array
     91   for (var xpathNode = xpathIterator.iterateNext();
     92        xpathNode;
     93        xpathNode = xpathIterator.iterateNext()) {
     94     results.push(xpathNode);
     95   }
     96   return results;
     97 };
     98 
     99 /**
    100  * Returns whether or not xpath is supported.
    101  * @return {boolean} True if xpath is supported.
    102  */
    103 cvox.XpathUtil.xpathSupported = function() {
    104   if (typeof(XPathResult) == 'undefined') {
    105     return false;
    106   }
    107   return true;
    108 };
    109 
    110 
    111 /**
    112  * Given an XPath expression and rootNode, it evaluates the XPath expression as
    113  * a boolean type and returns the result.
    114  * @param {string} expression The XPath expression to evaluate.
    115  * @param {Node} rootNode The HTML node to start evaluating the XPath from.
    116  * @return {boolean} The result of evaluating the xpath expression.
    117  */
    118 cvox.XpathUtil.evaluateBoolean = function(expression, rootNode) {
    119   try {
    120     var xpathResult = rootNode.ownerDocument.evaluate(
    121         expression,
    122         rootNode,
    123         cvox.XpathUtil.resolveNameSpace,
    124         XPathResult.BOOLEAN_TYPE,
    125         null); // no existing results
    126   } catch (err) {
    127     return false;
    128   }
    129   return xpathResult.booleanValue;
    130 };
    131 
    132 
    133 /**
    134  * Given an XPath expression and rootNode, it evaluates the XPath expression as
    135  * a string type and returns the result.
    136  * @param {string} expression The XPath expression to evaluate.
    137  * @param {Node} rootNode The HTML node to start evaluating the XPath from.
    138  * @return {string} The result of evaluating the Xpath expression.
    139  */
    140 cvox.XpathUtil.evaluateString = function(expression, rootNode) {
    141   try {
    142     var xpathResult = rootNode.ownerDocument.evaluate(
    143         expression,
    144         rootNode,
    145         cvox.XpathUtil.resolveNameSpace,
    146         XPathResult.STRING_TYPE,
    147         null); // no existing results
    148   } catch (err) {
    149     return '';
    150   }
    151   return xpathResult.stringValue;
    152 };
    153