// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

/**
 * @fileoverview DOM manipulation and querying routines.
 */

goog.provide('bot.dom');

goog.require('bot');
goog.require('bot.color');
goog.require('bot.dom.core');
goog.require('bot.locators.css');
goog.require('bot.userAgent');
goog.require('goog.array');
goog.require('goog.dom');
goog.require('goog.dom.DomHelper');
goog.require('goog.dom.NodeType');
goog.require('goog.dom.TagName');
goog.require('goog.math');
goog.require('goog.math.Coordinate');
goog.require('goog.math.Rect');
goog.require('goog.string');
goog.require('goog.style');
goog.require('goog.userAgent');


/**
 * Whether Shadow DOM operations are supported by the browser.
 * @const {boolean}
 */
bot.dom.IS_SHADOW_DOM_ENABLED = (typeof ShadowRoot === 'function');


/**
 * Retrieves the active element for a node's owner document.
 * @param {(!Node|!Window)} nodeOrWindow The node whose owner document to get
 *     the active element for.
 * @return {?Element} The active element, if any.
 */
bot.dom.getActiveElement = function (nodeOrWindow) {
  var active = goog.dom.getActiveElement(
    goog.dom.getOwnerDocument(nodeOrWindow));
  // IE has the habit of returning an empty object from
  // goog.dom.getActiveElement instead of null.
  if (goog.userAgent.IE &&
    active &&
    typeof active.nodeType === 'undefined') {
    return null;
  }
  return active;
};


/**
 * @const
 */
bot.dom.isElement = bot.dom.core.isElement;


/**
 * Returns whether an element is in an interactable state: whether it is shown
 * to the user, ignoring its opacity, and whether it is enabled.
 *
 * @param {!Element} element The element to check.
 * @return {boolean} Whether the element is interactable.
 * @see bot.dom.isShown.
 * @see bot.dom.isEnabled
 */
bot.dom.isInteractable = function (element) {
  return bot.dom.isShown(element, /*ignoreOpacity=*/true) &&
    bot.dom.isEnabled(element) &&
    !bot.dom.hasPointerEventsDisabled_(element);
};


/**
 * @param {!Element} element Element.
 * @return {boolean} Whether element is set by the CSS pointer-events property
 *     not to be interactable.
 * @private
 */
bot.dom.hasPointerEventsDisabled_ = function (element) {
  if (goog.userAgent.IE ||
    (goog.userAgent.GECKO && !bot.userAgent.isEngineVersion('1.9.2'))) {
    // Don't support pointer events
    return false;
  }
  return bot.dom.getEffectiveStyle(element, 'pointer-events') == 'none';
};


/**
 * @const
 */
bot.dom.isSelectable = bot.dom.core.isSelectable;


/**
 * @const
 */
bot.dom.isSelected = bot.dom.core.isSelected;


/**
 * List of the focusable fields, according to
 * http://www.w3.org/TR/html401/interact/scripts.html#adef-onfocus
 * @private {!Array.<!goog.dom.TagName>}
 * @const
 */
bot.dom.FOCUSABLE_FORM_FIELDS_ = [
  goog.dom.TagName.A,
  goog.dom.TagName.AREA,
  goog.dom.TagName.BUTTON,
  goog.dom.TagName.INPUT,
  goog.dom.TagName.LABEL,
  goog.dom.TagName.SELECT,
  goog.dom.TagName.TEXTAREA
];


/**
 * Returns whether a node is a focusable element.  An element may receive focus
 * if it is a form field, has a non-negative tabindex, or is editable.
 * @param {!Element} element The node to test.
 * @return {boolean} Whether the node is focusable.
 */
bot.dom.isFocusable = function (element) {
  return goog.array.some(bot.dom.FOCUSABLE_FORM_FIELDS_, tagNameMatches) ||
    (bot.dom.getAttribute(element, 'tabindex') != null &&
      Number(bot.dom.getProperty(element, 'tabIndex')) >= 0) ||
    bot.dom.isEditable(element);

  function tagNameMatches(tagName) {
    return bot.dom.isElement(element, tagName);
  }
};


/**
 * @const
 */
bot.dom.getProperty = bot.dom.core.getProperty;


/**
 * @const
 */
bot.dom.getAttribute = bot.dom.core.getAttribute;


/**
 * List of elements that support the "disabled" attribute, as defined by the
 * HTML 4.01 specification.
 * @private {!Array.<!goog.dom.TagName>}
 * @const
 * @see http://www.w3.org/TR/html401/interact/forms.html#h-17.12.1
 */
bot.dom.DISABLED_ATTRIBUTE_SUPPORTED_ = [
  goog.dom.TagName.BUTTON,
  goog.dom.TagName.INPUT,
  goog.dom.TagName.OPTGROUP,
  goog.dom.TagName.OPTION,
  goog.dom.TagName.SELECT,
  goog.dom.TagName.TEXTAREA
];


/**
 * Determines if an element is enabled. An element is considered enabled if it
 * does not support the "disabled" attribute, or if it is not disabled.
 * @param {!Element} el The element to test.
 * @return {boolean} Whether the element is enabled.
 */
bot.dom.isEnabled = function (el) {
  var isSupported = goog.array.some(
    bot.dom.DISABLED_ATTRIBUTE_SUPPORTED_,
    function (tagName) { return bot.dom.isElement(el, tagName); });
  if (!isSupported) {
    return true;
  }

  if (bot.dom.getProperty(el, 'disabled')) {
    return false;
  }

  // The element is not explicitly disabled, but if it is an OPTION or OPTGROUP,
  // we must test if it inherits its state from a parent.
  if (el.parentNode &&
    el.parentNode.nodeType == goog.dom.NodeType.ELEMENT &&
    bot.dom.isElement(el, goog.dom.TagName.OPTGROUP) ||
    bot.dom.isElement(el, goog.dom.TagName.OPTION)) {
    return bot.dom.isEnabled(/**@type{!Element}*/(el.parentNode));
  }

  // Is there an ancestor of the current element that is a disabled fieldset
  // and whose child is also an ancestor-or-self of the current element but is
  // not the first legend child of the fieldset. If so then the element is
  // disabled.
  return !goog.dom.getAncestor(el, function (e) {
    var parent = e.parentNode;

    if (parent &&
      bot.dom.isElement(parent, goog.dom.TagName.FIELDSET) &&
      bot.dom.getProperty(/** @type {!Element} */(parent), 'disabled')) {
      if (!bot.dom.isElement(e, goog.dom.TagName.LEGEND)) {
        return true;
      }

      var sibling = e;
      // Are there any previous legend siblings? If so then we are not the
      // first and the element is disabled
      while (sibling = goog.dom.getPreviousElementSibling(sibling)) {
        if (bot.dom.isElement(sibling, goog.dom.TagName.LEGEND)) {
          return true;
        }
      }
    }
    return false;
  }, true);
};


/**
 * List of input types that create text fields.
 * @private {!Array.<string>}
 * @const
 * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#attr-input-type
 */
bot.dom.TEXTUAL_INPUT_TYPES_ = [
  'text',
  'search',
  'tel',
  'url',
  'email',
  'password',
  'number'
];


/**
 * TODO: Add support for designMode elements.
 *
 * @param {!Element} element The element to check.
 * @return {boolean} Whether the element accepts user-typed text.
 */
bot.dom.isTextual = function (element) {
  if (bot.dom.isElement(element, goog.dom.TagName.TEXTAREA)) {
    return true;
  }

  if (bot.dom.isElement(element, goog.dom.TagName.INPUT)) {
    var type = element.type.toLowerCase();
    return goog.array.contains(bot.dom.TEXTUAL_INPUT_TYPES_, type);
  }

  if (bot.dom.isContentEditable(element)) {
    return true;
  }

  return false;
};


/**
 * @param {!Element} element The element to check.
 * @return {boolean} Whether the element is a file input.
 */
bot.dom.isFileInput = function (element) {
  if (bot.dom.isElement(element, goog.dom.TagName.INPUT)) {
    var type = element.type.toLowerCase();
    return type == 'file';
  }

  return false;
};


/**
 * @param {!Element} element The element to check.
 * @param {string} inputType The type of input to check.
 * @return {boolean} Whether the element is an input with specified type.
 */
bot.dom.isInputType = function (element, inputType) {
  if (bot.dom.isElement(element, goog.dom.TagName.INPUT)) {
    var type = element.type.toLowerCase();
    return type == inputType;
  }

  return false;
};


/**
 * @param {!Element} element The element to check.
 * @return {boolean} Whether the element is contentEditable.
 */
bot.dom.isContentEditable = function (element) {
  // Check if browser supports contentEditable.
  if (!goog.isDef(element['contentEditable'])) {
    return false;
  }

  // Checking the element's isContentEditable property is preferred except for
  // IE where that property is not reliable on IE versions 7, 8, and 9.
  if (!goog.userAgent.IE && goog.isDef(element['isContentEditable'])) {
    return element.isContentEditable;
  }

  // For IE and for browsers where contentEditable is supported but
  // isContentEditable is not, traverse up the ancestors:
  function legacyIsContentEditable(e) {
    if (e.contentEditable == 'inherit') {
      var parent = bot.dom.getParentElement(e);
      return parent ? legacyIsContentEditable(parent) : false;
    } else {
      return e.contentEditable == 'true';
    }
  }
  return legacyIsContentEditable(element);
};


/**
 * TODO: Merge isTextual into this function and move to bot.dom.
 * For Puppet, requires adding support to getVisibleText for grabbing
 * text from all textual elements.
 *
 * Whether the element may contain text the user can edit.
 *
 * @param {!Element} element The element to check.
 * @return {boolean} Whether the element accepts user-typed text.
 */
bot.dom.isEditable = function (element) {
  return (bot.dom.isTextual(element) ||
    bot.dom.isFileInput(element) ||
    bot.dom.isInputType(element, 'range') ||
    bot.dom.isInputType(element, 'date') ||
    bot.dom.isInputType(element, 'month') ||
    bot.dom.isInputType(element, 'week') ||
    bot.dom.isInputType(element, 'time') ||
    bot.dom.isInputType(element, 'datetime-local') ||
    bot.dom.isInputType(element, 'color')) &&
    !bot.dom.getProperty(element, 'readOnly');
};


/**
 * Returns the parent element of the given node, or null. This is required
 * because the parent node may not be another element.
 *
 * @param {!Node} node The node who's parent is desired.
 * @return {Element} The parent element, if available, null otherwise.
 */
bot.dom.getParentElement = function (node) {
  var elem = node.parentNode;

  while (elem &&
    elem.nodeType != goog.dom.NodeType.ELEMENT &&
    elem.nodeType != goog.dom.NodeType.DOCUMENT &&
    elem.nodeType != goog.dom.NodeType.DOCUMENT_FRAGMENT) {
    elem = elem.parentNode;
  }
  return /** @type {Element} */ (bot.dom.isElement(elem) ? elem : null);
};


/**
 * Retrieves an explicitly-set, inline style value of an element. This returns
 * '' if there isn't a style attribute on the element or if this style property
 * has not been explicitly set in script.
 *
 * @param {!Element} elem Element to get the style value from.
 * @param {string} styleName Name of the style property in selector-case.
 * @return {string} The value of the style property.
 */
bot.dom.getInlineStyle = function (elem, styleName) {
  return goog.style.getStyle(elem, styleName);
};


/**
 * Retrieves the implicitly-set, effective style of an element, or null if it is
 * unknown. It returns the computed style where available; otherwise it looks
 * up the DOM tree for the first style value not equal to 'inherit,' using the
 * IE currentStyle of each node if available, and otherwise the inline style.
 * Since the computed, current, and inline styles can be different, the return
 * value of this function is not always consistent across browsers. See:
 * http://code.google.com/p/doctype/wiki/ArticleComputedStyleVsCascadedStyle
 *
 * @param {!Element} elem Element to get the style value from.
 * @param {string} propertyName Name of the CSS property.
 * @return {?string} The value of the style property, or null.
 */
bot.dom.getEffectiveStyle = function (elem, propertyName) {
  var styleName = goog.string.toCamelCase(propertyName);
  if (styleName == 'float' ||
    styleName == 'cssFloat' ||
    styleName == 'styleFloat') {
    styleName = bot.userAgent.IE_DOC_PRE9 ? 'styleFloat' : 'cssFloat';
  }
  var style = goog.style.getComputedStyle(elem, styleName) ||
    bot.dom.getCascadedStyle_(elem, styleName);
  if (style === null) {
    return null;
  }
  return bot.color.standardizeColor(styleName, style);
};


/**
 * Looks up the DOM tree for the first style value not equal to 'inherit,' using
 * the currentStyle of each node if available, and otherwise the inline style.
 *
 * @param {!Element} elem Element to get the style value from.
 * @param {string} styleName CSS style property in camelCase.
 * @return {?string} The value of the style property, or null.
 * @private
 */
bot.dom.getCascadedStyle_ = function (elem, styleName) {
  var style = elem.currentStyle || elem.style;
  var value = style[styleName];
  if (!goog.isDef(value) && goog.isFunction(style.getPropertyValue)) {
    value = style.getPropertyValue(styleName);
  }

  if (value != 'inherit') {
    return goog.isDef(value) ? value : null;
  }
  var parent = bot.dom.getParentElement(elem);
  return parent ? bot.dom.getCascadedStyle_(parent, styleName) : null;
};


/**
 * Extracted code from bot.dom.isShown.
 *
 * @param {!Element} elem The element to consider.
 * @param {boolean} ignoreOpacity Whether to ignore the element's opacity
 *     when determining whether it is shown.
 * @param {function(!Element):boolean} parentsDisplayedFn a function that's used
 *     to tell if the chain of ancestors are all shown.
 * @return {boolean} Whether or not the element is visible.
 * @private
 */
bot.dom.isShown_ = function (elem, ignoreOpacity, parentsDisplayedFn) {
  if (!bot.dom.isElement(elem)) {
    throw new Error('Argument to isShown must be of type Element');
  }

  // By convention, BODY element is always shown: BODY represents the document
  // and even if there's nothing rendered in there, user can always see there's
  // the document.
  if (bot.dom.isElement(elem, goog.dom.TagName.BODY)) {
    return true;
  }

  // Option or optgroup is shown iff enclosing select is shown (ignoring the
  // select's opacity).
  if (bot.dom.isElement(elem, goog.dom.TagName.OPTION) ||
    bot.dom.isElement(elem, goog.dom.TagName.OPTGROUP)) {
    var select = /**@type {Element}*/ (goog.dom.getAncestor(elem, function (e) {
      return bot.dom.isElement(e, goog.dom.TagName.SELECT);
    }));
    return !!select && bot.dom.isShown_(select, true, parentsDisplayedFn);
  }

  // Image map elements are shown if image that uses it is shown, and
  // the area of the element is positive.
  var imageMap = bot.dom.maybeFindImageMap_(elem);
  if (imageMap) {
    return !!imageMap.image &&
      imageMap.rect.width > 0 && imageMap.rect.height > 0 &&
      bot.dom.isShown_(
        imageMap.image, ignoreOpacity, parentsDisplayedFn);
  }

  // Any hidden input is not shown.
  if (bot.dom.isElement(elem, goog.dom.TagName.INPUT) &&
    elem.type.toLowerCase() == 'hidden') {
    return false;
  }

  // Any NOSCRIPT element is not shown.
  if (bot.dom.isElement(elem, goog.dom.TagName.NOSCRIPT)) {
    return false;
  }

  // Any element with hidden/collapsed visibility is not shown.
  var visibility = bot.dom.getEffectiveStyle(elem, 'visibility');
  if (visibility == 'collapse' || visibility == 'hidden') {
    return false;
  }

  if (!parentsDisplayedFn(elem)) {
    return false;
  }

  // Any transparent element is not shown.
  if (!ignoreOpacity && bot.dom.getOpacity(elem) == 0) {
    return false;
  }

  // Any element without positive size dimensions is not shown.
  function positiveSize(e) {
    var rect = bot.dom.getClientRect(e);
    if (rect.height > 0 && rect.width > 0) {
      return true;
    }
    // A vertical or horizontal SVG Path element will report zero width or
    // height but is "shown" if it has a positive stroke-width.
    if (bot.dom.isElement(e, 'PATH') && (rect.height > 0 || rect.width > 0)) {
      var strokeWidth = bot.dom.getEffectiveStyle(e, 'stroke-width');
      return !!strokeWidth && (parseInt(strokeWidth, 10) > 0);
    }
    // Zero-sized elements should still be considered to have positive size
    // if they have a child element or text node with positive size, unless
    // the element has an 'overflow' style of 'hidden'.
    return bot.dom.getEffectiveStyle(e, 'overflow') != 'hidden' &&
      goog.array.some(e.childNodes, function (n) {
        return n.nodeType == goog.dom.NodeType.TEXT ||
          (bot.dom.isElement(n) && positiveSize(n));
      });
  }
  if (!positiveSize(elem)) {
    return false;
  }

  // Elements that are hidden by overflow are not shown.
  function hiddenByOverflow(e) {
    return bot.dom.getOverflowState(e) == bot.dom.OverflowState.HIDDEN &&
      goog.array.every(e.childNodes, function (n) {
        return !bot.dom.isElement(n) || hiddenByOverflow(n) ||
          !positiveSize(n);
      });
  }
  return !hiddenByOverflow(elem);
};


/**
 * Determines whether an element is what a user would call "shown". This means
 * that the element is shown in the viewport of the browser, and only has
 * height and width greater than 0px, and that its visibility is not "hidden"
 * and its display property is not "none".
 * Options and Optgroup elements are treated as special cases: they are
 * considered shown iff they have a enclosing select element that is shown.
 *
 * Elements in Shadow DOMs with younger shadow roots are not visible, and
 * elements distributed into shadow DOMs check the visibility of the
 * ancestors in the Composed DOM, rather than their ancestors in the logical
 * DOM.
 *
 * @param {!Element} elem The element to consider.
 * @param {boolean=} opt_ignoreOpacity Whether to ignore the element's opacity
 *     when determining whether it is shown; defaults to false.
 * @return {boolean} Whether or not the element is visible.
 */
bot.dom.isShown = function (elem, opt_ignoreOpacity) {
  /**
   * Determines whether an element or its parents have `display: none` set
   * @param {!Node} e the element
   * @return {!boolean}
   */
  function displayed(e) {
    if (bot.dom.isElement(e)) {
      var elem = /** @type {!Element} */ (e);
      if ((bot.dom.getEffectiveStyle(elem, 'display') == 'none')
        || (bot.dom.getEffectiveStyle(elem, 'content-visibility') == 'hidden')) {
        return false;
      }
    }

    var parent = bot.dom.getParentNodeInComposedDom(e);

    if (bot.dom.IS_SHADOW_DOM_ENABLED && (parent instanceof ShadowRoot)) {
      if (parent.host.shadowRoot && parent.host.shadowRoot !== parent) {
        // There is a younger shadow root, which will take precedence over
        // the shadow this element is in, thus this element won't be
        // displayed.
        return false;
      } else {
        parent = parent.host;
      }
    }

    if (parent && (parent.nodeType == goog.dom.NodeType.DOCUMENT ||
      parent.nodeType == goog.dom.NodeType.DOCUMENT_FRAGMENT)) {
      return true;
    }

    // Child of DETAILS element is not shown unless the DETAILS element is open
    // or the child is a SUMMARY element.
    if (parent && bot.dom.isElement(parent, goog.dom.TagName.DETAILS) &&
      !parent.open && !bot.dom.isElement(e, goog.dom.TagName.SUMMARY)) {
      return false;
    }

    return !!parent && displayed(parent);
  }

  return bot.dom.isShown_(elem, !!opt_ignoreOpacity, displayed);
};


/**
 * The kind of overflow area in which an element may be located. NONE if it does
 * not overflow any ancestor element; HIDDEN if it overflows and cannot be
 * scrolled into view; SCROLL if it overflows but can be scrolled into view.
 *
 * @enum {string}
 */
bot.dom.OverflowState = {
  NONE: 'none',
  HIDDEN: 'hidden',
  SCROLL: 'scroll'
};


/**
 * Returns the overflow state of the given element.
 *
 * If an optional coordinate or rectangle region is provided, returns the
 * overflow state of that region relative to the element. A coordinate is
 * treated as a 1x1 rectangle whose top-left corner is the coordinate.
 *
 * @param {!Element} elem Element.
 * @param {!(goog.math.Coordinate|goog.math.Rect)=} opt_region
 *     Coordinate or rectangle relative to the top-left corner of the element.
 * @return {bot.dom.OverflowState} Overflow state of the element.
 */
bot.dom.getOverflowState = function (elem, opt_region) {
  var region = bot.dom.getClientRegion(elem, opt_region);
  var ownerDoc = goog.dom.getOwnerDocument(elem);
  var htmlElem = ownerDoc.documentElement;
  var bodyElem = ownerDoc.body;
  var htmlOverflowStyle = bot.dom.getEffectiveStyle(htmlElem, 'overflow');
  var treatAsFixedPosition;

  // Return the closest ancestor that the given element may overflow.
  function getOverflowParent(e) {
    var position = bot.dom.getEffectiveStyle(e, 'position');
    if (position == 'fixed') {
      treatAsFixedPosition = true;
      // Fixed-position element may only overflow the viewport.
      return e == htmlElem ? null : htmlElem;
    } else {
      var parent = bot.dom.getParentElement(e);
      while (parent && !canBeOverflowed(parent)) {
        parent = bot.dom.getParentElement(parent);
      }
      return parent;
    }

    function canBeOverflowed(container) {
      // The HTML element can always be overflowed.
      if (container == htmlElem) {
        return true;
      }
      // An element cannot overflow an element with an inline or contents display style.
      var containerDisplay = /** @type {string} */ (
        bot.dom.getEffectiveStyle(container, 'display'));
      if (goog.string.startsWith(containerDisplay, 'inline') ||
        (containerDisplay == 'contents')) {
        return false;
      }
      // An absolute-positioned element cannot overflow a static-positioned one.
      if (position == 'absolute' &&
        bot.dom.getEffectiveStyle(container, 'position') == 'static') {
        return false;
      }
      return true;
    }
  }

  // Return the x and y overflow styles for the given element.
  function getOverflowStyles(e) {
    // When the <html> element has an overflow style of 'visible', it assumes
    // the overflow style of the body, and the body is really overflow:visible.
    var overflowElem = e;
    if (htmlOverflowStyle == 'visible') {
      // Note: bodyElem will be null/undefined in SVG documents.
      if (e == htmlElem && bodyElem) {
        overflowElem = bodyElem;
      } else if (e == bodyElem) {
        return { x: 'visible', y: 'visible' };
      }
    }
    var overflow = {
      x: bot.dom.getEffectiveStyle(overflowElem, 'overflow-x'),
      y: bot.dom.getEffectiveStyle(overflowElem, 'overflow-y')
    };
    // The <html> element cannot have a genuine 'visible' overflow style,
    // because the viewport can't expand; 'visible' is really 'auto'.
    if (e == htmlElem) {
      overflow.x = overflow.x == 'visible' ? 'auto' : overflow.x;
      overflow.y = overflow.y == 'visible' ? 'auto' : overflow.y;
    }
    return overflow;
  }

  // Returns the scroll offset of the given element.
  function getScroll(e) {
    if (e == htmlElem) {
      return new goog.dom.DomHelper(ownerDoc).getDocumentScroll();
    } else {
      return new goog.math.Coordinate(e.scrollLeft, e.scrollTop);
    }
  }

  // Check if the element overflows any ancestor element.
  for (var container = getOverflowParent(elem);
    !!container;
    container = getOverflowParent(container)) {
    var containerOverflow = getOverflowStyles(container);

    // If the container has overflow:visible, the element cannot overflow it.
    if (containerOverflow.x == 'visible' && containerOverflow.y == 'visible') {
      continue;
    }

    var containerRect = bot.dom.getClientRect(container);

    // Zero-sized containers without overflow:visible hide all descendants.
    if (containerRect.width == 0 || containerRect.height == 0) {
      return bot.dom.OverflowState.HIDDEN;
    }

    // Check "underflow": if an element is to the left or above the container
    var underflowsX = region.right < containerRect.left;
    var underflowsY = region.bottom < containerRect.top;
    if ((underflowsX && containerOverflow.x == 'hidden') ||
      (underflowsY && containerOverflow.y == 'hidden')) {
      return bot.dom.OverflowState.HIDDEN;
    } else if ((underflowsX && containerOverflow.x != 'visible') ||
      (underflowsY && containerOverflow.y != 'visible')) {
      // When the element is positioned to the left or above a container, we
      // have to distinguish between the element being completely outside the
      // container and merely scrolled out of view within the container.
      var containerScroll = getScroll(container);
      var unscrollableX = region.right < containerRect.left - containerScroll.x;
      var unscrollableY = region.bottom < containerRect.top - containerScroll.y;
      if ((unscrollableX && containerOverflow.x != 'visible') ||
        (unscrollableY && containerOverflow.x != 'visible')) {
        return bot.dom.OverflowState.HIDDEN;
      }
      var containerState = bot.dom.getOverflowState(container);
      return containerState == bot.dom.OverflowState.HIDDEN ?
        bot.dom.OverflowState.HIDDEN : bot.dom.OverflowState.SCROLL;
    }

    // Check "overflow": if an element is to the right or below a container
    var overflowsX = region.left >= containerRect.left + containerRect.width;
    var overflowsY = region.top >= containerRect.top + containerRect.height;
    if ((overflowsX && containerOverflow.x == 'hidden') ||
      (overflowsY && containerOverflow.y == 'hidden')) {
      return bot.dom.OverflowState.HIDDEN;
    } else if ((overflowsX && containerOverflow.x != 'visible') ||
      (overflowsY && containerOverflow.y != 'visible')) {
      // If the element has fixed position and falls outside the scrollable area
      // of the document, then it is hidden.
      if (treatAsFixedPosition) {
        var docScroll = getScroll(container);
        if ((region.left >= htmlElem.scrollWidth - docScroll.x) ||
          (region.right >= htmlElem.scrollHeight - docScroll.y)) {
          return bot.dom.OverflowState.HIDDEN;
        }
      }
      // If the element can be scrolled into view of the parent, it has a scroll
      // state; unless the parent itself is entirely hidden by overflow, in
      // which it is also hidden by overflow.
      var containerState = bot.dom.getOverflowState(container);
      return containerState == bot.dom.OverflowState.HIDDEN ?
        bot.dom.OverflowState.HIDDEN : bot.dom.OverflowState.SCROLL;
    }
  }

  // Does not overflow any ancestor.
  return bot.dom.OverflowState.NONE;
};


/**
 * A regular expression to match the CSS transform matrix syntax.
 * @private {!RegExp}
 * @const
 */
bot.dom.CSS_TRANSFORM_MATRIX_REGEX_ =
  new RegExp('matrix\\(([\\d\\.\\-]+), ([\\d\\.\\-]+), ' +
    '([\\d\\.\\-]+), ([\\d\\.\\-]+), ' +
    '([\\d\\.\\-]+)(?:px)?, ([\\d\\.\\-]+)(?:px)?\\)');


/**
 * Gets the client rectangle of the DOM element. It often returns the same value
 * as Element.getBoundingClientRect, but is "fixed" for various scenarios:
 * 1. Like goog.style.getClientPosition, it adjusts for the inset border in IE.
 * 2. Gets a rect for <map>'s and <area>'s relative to the image using them.
 * 3. Gets a rect for SVG elements representing their true bounding box.
 * 4. Defines the client rect of the <html> element to be the window viewport.
 *
 * @param {!Element} elem The element to use.
 * @return {!goog.math.Rect} The interaction box of the element.
 */
bot.dom.getClientRect = function (elem) {
  var imageMap = bot.dom.maybeFindImageMap_(elem);
  if (imageMap) {
    return imageMap.rect;
  } else if (bot.dom.isElement(elem, goog.dom.TagName.HTML)) {
    // Define the client rect of the <html> element to be the viewport.
    var doc = goog.dom.getOwnerDocument(elem);
    var viewportSize = goog.dom.getViewportSize(goog.dom.getWindow(doc));
    return new goog.math.Rect(0, 0, viewportSize.width, viewportSize.height);
  } else {
    var nativeRect;
    try {
      // TODO: in IE and Firefox, getBoundingClientRect includes stroke width,
      // but getBBox does not.
      nativeRect = elem.getBoundingClientRect();
    } catch (e) {
      // On IE < 9, calling getBoundingClientRect on an orphan element raises
      // an "Unspecified Error". All other browsers return zeros.
      return new goog.math.Rect(0, 0, 0, 0);
    }

    var rect = new goog.math.Rect(nativeRect.left, nativeRect.top,
      nativeRect.right - nativeRect.left, nativeRect.bottom - nativeRect.top);

    // In IE, the element can additionally be offset by a border around the
    // documentElement or body element that we have to subtract.
    if (goog.userAgent.IE && elem.ownerDocument.body) {
      var doc = goog.dom.getOwnerDocument(elem);
      rect.left -= doc.documentElement.clientLeft + doc.body.clientLeft;
      rect.top -= doc.documentElement.clientTop + doc.body.clientTop;
    }

    return rect;
  }
};


/**
 * If given a <map> or <area> element, finds the corresponding image and client
 * rectangle of the element; otherwise returns null. The return value is an
 * object with 'image' and 'rect' properties. When no image uses the given
 * element, the returned rectangle is present but has zero size.
 *
 * @param {!Element} elem Element to test.
 * @return {?{image: Element, rect: !goog.math.Rect}} Image and rectangle.
 * @private
 */
bot.dom.maybeFindImageMap_ = function (elem) {
  // If not a <map> or <area>, return null indicating so.
  var isMap = bot.dom.isElement(elem, goog.dom.TagName.MAP);
  if (!isMap && !bot.dom.isElement(elem, goog.dom.TagName.AREA)) {
    return null;
  }

  // Get the <map> associated with this element, or null if none.
  var map = isMap ? elem :
    (bot.dom.isElement(elem.parentNode, goog.dom.TagName.MAP) ?
      elem.parentNode : null);

  var image = null, rect = null;
  if (map && map.name) {
    var mapDoc = goog.dom.getOwnerDocument(map);

    // TODO: Restrict to applet, img, input:image, and object nodes.
    var locator = '*[usemap="#' + map.name + '"]';

    // TODO: Break dependency of bot.locators on bot.dom,
    // so bot.locators.findElement can be called here instead.
    image = bot.locators.css.single(locator, mapDoc);

    if (image) {
      rect = bot.dom.getClientRect(image);
      if (!isMap && elem.shape.toLowerCase() != 'default') {
        // Shift and crop the relative area rectangle to the map.
        var relRect = bot.dom.getAreaRelativeRect_(elem);
        var relX = Math.min(Math.max(relRect.left, 0), rect.width);
        var relY = Math.min(Math.max(relRect.top, 0), rect.height);
        var w = Math.min(relRect.width, rect.width - relX);
        var h = Math.min(relRect.height, rect.height - relY);
        rect = new goog.math.Rect(relX + rect.left, relY + rect.top, w, h);
      }
    }
  }

  return { image: image, rect: rect || new goog.math.Rect(0, 0, 0, 0) };
};


/**
 * Returns the bounding box around an <area> element relative to its enclosing
 * <map>. Does not apply to <area> elements with shape=='default'.
 *
 * @param {!Element} area Area element.
 * @return {!goog.math.Rect} Bounding box of the area element.
 * @private
 */
bot.dom.getAreaRelativeRect_ = function (area) {
  var shape = area.shape.toLowerCase();
  var coords = area.coords.split(',');
  if (shape == 'rect' && coords.length == 4) {
    var x = coords[0], y = coords[1];
    return new goog.math.Rect(x, y, coords[2] - x, coords[3] - y);
  } else if (shape == 'circle' && coords.length == 3) {
    var centerX = coords[0], centerY = coords[1], radius = coords[2];
    return new goog.math.Rect(centerX - radius, centerY - radius,
      2 * radius, 2 * radius);
  } else if (shape == 'poly' && coords.length > 2) {
    var minX = coords[0], minY = coords[1], maxX = minX, maxY = minY;
    for (var i = 2; i + 1 < coords.length; i += 2) {
      minX = Math.min(minX, coords[i]);
      maxX = Math.max(maxX, coords[i]);
      minY = Math.min(minY, coords[i + 1]);
      maxY = Math.max(maxY, coords[i + 1]);
    }
    return new goog.math.Rect(minX, minY, maxX - minX, maxY - minY);
  }
  return new goog.math.Rect(0, 0, 0, 0);
};


/**
 * Gets the element's client rectangle as a box, optionally clipped to the
 * given coordinate or rectangle relative to the client's position. A coordinate
 * is treated as a 1x1 rectangle whose top-left corner is the coordinate.
 *
 * @param {!Element} elem The element.
 * @param {!(goog.math.Coordinate|goog.math.Rect)=} opt_region
 *     Coordinate or rectangle relative to the top-left corner of the element.
 * @return {!goog.math.Box} The client region box.
 */
bot.dom.getClientRegion = function (elem, opt_region) {
  var region = bot.dom.getClientRect(elem).toBox();

  if (opt_region) {
    var rect = opt_region instanceof goog.math.Rect ? opt_region :
      new goog.math.Rect(opt_region.x, opt_region.y, 1, 1);
    region.left = goog.math.clamp(
      region.left + rect.left, region.left, region.right);
    region.top = goog.math.clamp(
      region.top + rect.top, region.top, region.bottom);
    region.right = goog.math.clamp(
      region.left + rect.width, region.left, region.right);
    region.bottom = goog.math.clamp(
      region.top + rect.height, region.top, region.bottom);
  }

  return region;
};


/**
 * Trims leading and trailing whitespace from strings, leaving non-breaking
 * space characters in place.
 *
 * @param {string} str The string to trim.
 * @return {string} str without any leading or trailing whitespace characters
 *     except non-breaking spaces.
 * @private
 */
bot.dom.trimExcludingNonBreakingSpaceCharacters_ = function (str) {
  return str.replace(/^[^\S\xa0]+|[^\S\xa0]+$/g, '');
};


/**
 * Helper function for getVisibleText[InDisplayedDom].
 * @param {!Array.<string>} lines Accumulated visible lines of text.
 * @return {string} cleaned up concatenated lines
 * @private
 */
bot.dom.concatenateCleanedLines_ = function (lines) {
  lines = goog.array.map(
    lines,
    bot.dom.trimExcludingNonBreakingSpaceCharacters_);
  var joined = lines.join('\n');
  var trimmed = bot.dom.trimExcludingNonBreakingSpaceCharacters_(joined);

  // Replace non-breakable spaces with regular ones.
  return trimmed.replace(/\xa0/g, ' ');
};


/**
 * @param {!Element} elem The element to consider.
 * @return {string} visible text.
 */
bot.dom.getVisibleText = function (elem) {
  var lines = [];

  if (bot.dom.IS_SHADOW_DOM_ENABLED) {
    bot.dom.appendVisibleTextLinesFromElementInComposedDom_(elem, lines);
  } else {
    bot.dom.appendVisibleTextLinesFromElement_(elem, lines);
  }
  return bot.dom.concatenateCleanedLines_(lines);
};


/**
 * Helper function used by bot.dom.appendVisibleTextLinesFromElement_ and
 * bot.dom.appendVisibleTextLinesFromElementInComposedDom_
 * @param {!Element} elem Element.
 * @param {!Array.<string>} lines Accumulated visible lines of text.
 * @param {function(!Element):boolean} isShownFn function to call to
 *     tell if an element is shown
 * @param {function(!Node, !Array.<string>, boolean, ?string, ?string):void}
 *     childNodeFn function to call to append lines from any child nodes
 * @private
 */
bot.dom.appendVisibleTextLinesFromElementCommon_ = function (
  elem, lines, isShownFn, childNodeFn) {
  function currLine() {
    return /** @type {string|undefined} */ (goog.array.peek(lines)) || '';
  }

  // TODO: Add case here for textual form elements.
  if (bot.dom.isElement(elem, goog.dom.TagName.BR)) {
    lines.push('');
  } else {
    // TODO: properly handle display:run-in
    var isTD = bot.dom.isElement(elem, goog.dom.TagName.TD);
    var display = bot.dom.getEffectiveStyle(elem, 'display');
    // On some browsers, table cells incorrectly show up with block styles.
    var isBlock = !isTD &&
      !goog.array.contains(bot.dom.INLINE_DISPLAY_BOXES_, display);

    // Add a newline before block elems when there is text on the current line,
    // except when the previous sibling has a display: run-in.
    // Also, do not run-in the previous sibling if this element is floated.

    var previousElementSibling = goog.dom.getPreviousElementSibling(elem);
    var prevDisplay = (previousElementSibling) ?
      bot.dom.getEffectiveStyle(previousElementSibling, 'display') : '';
    // TODO: getEffectiveStyle should mask this for us
    var thisFloat = bot.dom.getEffectiveStyle(elem, 'float') ||
      bot.dom.getEffectiveStyle(elem, 'cssFloat') ||
      bot.dom.getEffectiveStyle(elem, 'styleFloat');
    var runIntoThis = prevDisplay == 'run-in' && thisFloat == 'none';
    if (isBlock && !runIntoThis &&
      !goog.string.isEmptyOrWhitespace(currLine())) {
      lines.push('');
    }

    // This element may be considered unshown, but have a child that is
    // explicitly shown (e.g. this element has "visibility:hidden").
    // Nevertheless, any text nodes that are direct descendants of this
    // element will not contribute to the visible text.
    var shown = isShownFn(elem);

    // All text nodes that are children of this element need to know the
    // effective "white-space" and "text-transform" styles to properly
    // compute their contribution to visible text. Compute these values once.
    var whitespace = null, textTransform = null;
    if (shown) {
      whitespace = bot.dom.getEffectiveStyle(elem, 'white-space');
      textTransform = bot.dom.getEffectiveStyle(elem, 'text-transform');
    }

    goog.array.forEach(elem.childNodes, function (node) {
      childNodeFn(node, lines, shown, whitespace, textTransform);
    });

    var line = currLine();

    // Here we differ from standard innerText implementations (if there were
    // such a thing). Usually, table cells are separated by a tab, but we
    // normalize tabs into single spaces.
    if ((isTD || display == 'table-cell') && line &&
      !goog.string.endsWith(line, ' ')) {
      lines[lines.length - 1] += ' ';
    }

    // Add a newline after block elems when there is text on the current line,
    // and the current element isn't marked as run-in.
    if (isBlock && display != 'run-in' &&
      !goog.string.isEmptyOrWhitespace(line)) {
      lines.push('');
    }
  }
};


/**
 * @param {!Element} elem Element.
 * @param {!Array.<string>} lines Accumulated visible lines of text.
 * @private
 */
bot.dom.appendVisibleTextLinesFromElement_ = function (elem, lines) {
  bot.dom.appendVisibleTextLinesFromElementCommon_(
    elem, lines, bot.dom.isShown,
    function (node, lines, shown, whitespace, textTransform) {
      if (node.nodeType == goog.dom.NodeType.TEXT && shown) {
        var textNode = /** @type {!Text} */ (node);
        bot.dom.appendVisibleTextLinesFromTextNode_(textNode, lines,
          whitespace, textTransform);
      } else if (bot.dom.isElement(node)) {
        var castElem = /** @type {!Element} */ (node);
        bot.dom.appendVisibleTextLinesFromElement_(castElem, lines);
      }
    });
};


/**
 * Elements with one of these effective "display" styles are treated as inline
 * display boxes and have their visible text appended to the current line.
 * @private {!Array.<string>}
 * @const
 */
bot.dom.INLINE_DISPLAY_BOXES_ = [
  'inline',
  'inline-block',
  'inline-table',
  'none',
  'table-cell',
  'table-column',
  'table-column-group'
];


/**
 * @param {!Text} textNode Text node.
 * @param {!Array.<string>} lines Accumulated visible lines of text.
 * @param {?string} whitespace Parent element's "white-space" style.
 * @param {?string} textTransform Parent element's "text-transform" style.
 * @private
 */
bot.dom.appendVisibleTextLinesFromTextNode_ = function (textNode, lines,
  whitespace, textTransform) {

  // First, remove zero-width characters. Do this before regularizing spaces as
  // the zero-width space is both zero-width and a space, but we do not want to
  // make it visible by converting it to a regular space.
  // The replaced characters are:
  //   U+200B: Zero-width space
  //   U+200E: Left-to-right mark
  //   U+200F: Right-to-left mark
  var text = textNode.nodeValue.replace(/[\u200b\u200e\u200f]/g, '');

  // Canonicalize the new lines, and then collapse new lines
  // for the whitespace styles that collapse. See:
  // https://developer.mozilla.org/en/CSS/white-space
  text = goog.string.canonicalizeNewlines(text);
  if (whitespace == 'normal' || whitespace == 'nowrap') {
    text = text.replace(/\n/g, ' ');
  }

  // For pre and pre-wrap whitespace styles, convert all breaking spaces to be
  // non-breaking, otherwise, collapse all breaking spaces. Breaking spaces are
  // converted to regular spaces by getVisibleText().
  if (whitespace == 'pre' || whitespace == 'pre-wrap') {
    text = text.replace(/[ \f\t\v\u2028\u2029]/g, '\xa0');
  } else {
    text = text.replace(/[\ \f\t\v\u2028\u2029]+/g, ' ');
  }

  if (textTransform == 'capitalize') {
    // the unicode regex ending with /gu does not work in IE
    var re = goog.userAgent.IE ? /(^|\s|\b)(\S)/g : /(^|\s|\b)(\S)/gu;
    text = text.replace(re, function () {
      return arguments[1] + arguments[2].toUpperCase();
    });
  } else if (textTransform == 'uppercase') {
    text = text.toUpperCase();
  } else if (textTransform == 'lowercase') {
    text = text.toLowerCase();
  }

  var currLine = lines.pop() || '';
  if (goog.string.endsWith(currLine, ' ') &&
    goog.string.startsWith(text, ' ')) {
    text = text.substr(1);
  }
  lines.push(currLine + text);
};


/**
 * Gets the opacity of a node (x-browser).
 * This gets the inline style opacity of the node and takes into account the
 * cascaded or the computed style for this node.
 *
 * @param {!Element} elem Element whose opacity has to be found.
 * @return {number} Opacity between 0 and 1.
 */
bot.dom.getOpacity = function (elem) {
  // TODO: Does this need to deal with rgba colors?
  if (!bot.userAgent.IE_DOC_PRE9) {
    return bot.dom.getOpacityNonIE_(elem);
  } else {
    if (bot.dom.getEffectiveStyle(elem, 'position') == 'relative') {
      // Filter does not apply to non positioned elements.
      return 1;
    }

    var opacityStyle = bot.dom.getEffectiveStyle(elem, 'filter');
    var groups = opacityStyle.match(/^alpha\(opacity=(\d*)\)/) ||
      opacityStyle.match(
        /^progid:DXImageTransform.Microsoft.Alpha\(Opacity=(\d*)\)/);

    if (groups) {
      return Number(groups[1]) / 100;
    } else {
      return 1; // Opaque.
    }
  }
};


/**
 * Implementation of getOpacity for browsers that do support
 * the "opacity" style.
 *
 * @param {!Element} elem Element whose opacity has to be found.
 * @return {number} Opacity between 0 and 1.
 * @private
 */
bot.dom.getOpacityNonIE_ = function (elem) {
  // By default the element is opaque.
  var elemOpacity = 1;

  var opacityStyle = bot.dom.getEffectiveStyle(elem, 'opacity');
  if (opacityStyle) {
    elemOpacity = Number(opacityStyle);
  }

  // Let's apply the parent opacity to the element.
  var parentElement = bot.dom.getParentElement(elem);
  if (parentElement) {
    elemOpacity = elemOpacity * bot.dom.getOpacityNonIE_(parentElement);
  }
  return elemOpacity;
};


/**
 * Returns the display parent element of the given node, or null. This method
 * differs from bot.dom.getParentElement in the presence of ShadowDOM and
 * &lt;shadow&gt; or &lt;content&gt; tags. For example if
 * <ul>
 * <li>div A contains div B
 * <li>div B has a css class .C
 * <li>div A contains a Shadow DOM with a div D
 * <li>div D contains a contents tag selecting all items of class .C
 * </ul>
 * then calling bot.dom.getParentElement on B will return A, but calling
 * getDisplayParentElement on B will return D.
 *
 * @param {!Node} node The node whose parent is desired.
 * @return {Node} The parent node, if available, null otherwise.
 */
bot.dom.getParentNodeInComposedDom = function (node) {
  var /**@type {Node}*/ parent = node.parentNode;

  // Shadow DOM v1
  if (parent && parent.shadowRoot && node.assignedSlot !== undefined) {
    // Can be null on purpose, meaning it has no parent as
    // it hasn't yet been slotted
    return node.assignedSlot ? node.assignedSlot.parentNode : null;
  }

  // Shadow DOM V0 (deprecated)
  if (node.getDestinationInsertionPoints) {
    var destinations = node.getDestinationInsertionPoints();
    if (destinations.length > 0) {
      return destinations[destinations.length - 1];
    }
  }

  return parent;
};


/**
 * @param {!Node} node Node.
 * @param {!Array.<string>} lines Accumulated visible lines of text.
 * @param {boolean} shown whether the node is visible
 * @param {?string} whitespace the node's 'white-space' effectiveStyle
 * @param {?string} textTransform the node's 'text-transform' effectiveStyle
 * @private
 * @suppress {missingProperties}
 */
bot.dom.appendVisibleTextLinesFromNodeInComposedDom_ = function (
  node, lines, shown, whitespace, textTransform) {

  if (node.nodeType == goog.dom.NodeType.TEXT && shown) {
    var textNode = /** @type {!Text} */ (node);
    bot.dom.appendVisibleTextLinesFromTextNode_(textNode, lines,
      whitespace, textTransform);
  } else if (bot.dom.isElement(node)) {
    var castElem = /** @type {!Element} */ (node);

    if (bot.dom.isElement(node, 'CONTENT') || bot.dom.isElement(node, 'SLOT')) {
      var parentNode = node;
      while (parentNode.parentNode) {
        parentNode = parentNode.parentNode;
      }
      if (parentNode instanceof ShadowRoot) {
        // If the element is <content> and we're inside a shadow DOM then just
        // append the contents of the nodes that have been distributed into it.
        var contentElem = /** @type {!Object} */ (node);
        var shadowChildren;
        if (bot.dom.isElement(node, 'CONTENT')) {
          shadowChildren = contentElem.getDistributedNodes();
        } else {
          shadowChildren = contentElem.assignedNodes();
        }
        const childrenToTraverse =
          shadowChildren.length > 0 ? shadowChildren : contentElem.childNodes;
        goog.array.forEach(childrenToTraverse, function (node) {
          bot.dom.appendVisibleTextLinesFromNodeInComposedDom_(
            node, lines, shown, whitespace, textTransform);
        });
      } else {
        // if we're not inside a shadow DOM, then we just treat <content>
        // as an unknown element and use anything inside the tag
        bot.dom.appendVisibleTextLinesFromElementInComposedDom_(
          castElem, lines);
      }
    } else if (bot.dom.isElement(node, 'SHADOW')) {
      // if the element is <shadow> then find the owning shadowRoot
      var parentNode = node;
      while (parentNode.parentNode) {
        parentNode = parentNode.parentNode;
      }
      if (parentNode instanceof ShadowRoot) {
        var thisShadowRoot = /** @type {!ShadowRoot} */ (parentNode);
        if (thisShadowRoot) {
          // then go through the owning shadowRoots older siblings and append
          // their contents
          var olderShadowRoot = thisShadowRoot.olderShadowRoot;
          while (olderShadowRoot) {
            goog.array.forEach(
              olderShadowRoot.childNodes, function (childNode) {
                bot.dom.appendVisibleTextLinesFromNodeInComposedDom_(
                  childNode, lines, shown, whitespace, textTransform);
              });
            olderShadowRoot = olderShadowRoot.olderShadowRoot;
          }
        }
      }
    } else {
      // otherwise append the contents of an element as per normal.
      bot.dom.appendVisibleTextLinesFromElementInComposedDom_(
        castElem, lines);
    }
  }
};


/**
 * Determines whether a given node has been distributed into a ShadowDOM
 * element somewhere.
 * @param {!Node} node The node to check
 * @return {boolean} True if the node has been distributed.
 */
bot.dom.isNodeDistributedIntoShadowDom = function (node) {
  var elemOrText = null;
  if (node.nodeType == goog.dom.NodeType.ELEMENT) {
    elemOrText = /** @type {!Element} */ (node);
  } else if (node.nodeType == goog.dom.NodeType.TEXT) {
    elemOrText = /** @type {!Text} */ (node);
  }
  return elemOrText != null &&
    (elemOrText.assignedSlot != null ||
      (elemOrText.getDestinationInsertionPoints &&
        elemOrText.getDestinationInsertionPoints().length > 0)
    );
};


/**
 * @param {!Element} elem Element.
 * @param {!Array.<string>} lines Accumulated visible lines of text.
 * @private
 */
bot.dom.appendVisibleTextLinesFromElementInComposedDom_ = function (
  elem, lines) {
  if (elem.shadowRoot) {
    goog.array.forEach(elem.shadowRoot.childNodes, function (node) {
      bot.dom.appendVisibleTextLinesFromNodeInComposedDom_(
        node, lines, true, null, null);
    });
  }

  bot.dom.appendVisibleTextLinesFromElementCommon_(
    elem, lines, bot.dom.isShown,
    function (node, lines, shown, whitespace, textTransform) {
      // If the node has been distributed into a shadowDom element
      // to be displayed elsewhere, then we shouldn't append
      // its contents here).
      if (!bot.dom.isNodeDistributedIntoShadowDom(node)) {
        bot.dom.appendVisibleTextLinesFromNodeInComposedDom_(
          node, lines, shown, whitespace, textTransform);
      }
    });
};
