goog.dom.getElementsByTagNameAndClass_ = function()

in asdoc/library/closure/goog/dom/dom.js [328:381]


goog.dom.getElementsByTagNameAndClass_ = function(
    doc, opt_tag, opt_class, opt_el) {
  var parent = opt_el || doc;
  var tagName =
      (opt_tag && opt_tag != '*') ? String(opt_tag).toUpperCase() : '';

  if (goog.dom.canUseQuerySelector_(parent) && (tagName || opt_class)) {
    var query = tagName + (opt_class ? '.' + opt_class : '');
    return parent.querySelectorAll(query);
  }

  // Use the native getElementsByClassName if available, under the assumption
  // that even when the tag name is specified, there will be fewer elements to
  // filter through when going by class than by tag name
  if (opt_class && parent.getElementsByClassName) {
    var els = parent.getElementsByClassName(opt_class);

    if (tagName) {
      var arrayLike = {};
      var len = 0;

      // Filter for specific tags if requested.
      for (var i = 0, el; el = els[i]; i++) {
        if (tagName == el.nodeName) {
          arrayLike[len++] = el;
        }
      }
      arrayLike.length = len;

      return /** @type {!IArrayLike<!Element>} */ (arrayLike);
    } else {
      return els;
    }
  }

  var els = parent.getElementsByTagName(tagName || '*');

  if (opt_class) {
    var arrayLike = {};
    var len = 0;
    for (var i = 0, el; el = els[i]; i++) {
      var className = el.className;
      // Check if className has a split function since SVG className does not.
      if (typeof className.split == 'function' &&
          goog.array.contains(className.split(/\s+/), opt_class)) {
        arrayLike[len++] = el;
      }
    }
    arrayLike.length = len;
    return /** @type {!IArrayLike<!Element>} */ (arrayLike);
  } else {
    return els;
  }
};