// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

goog.provide('__crWeb.findInPage');

goog.require('__crWeb.base');

/**
 * Based on code from the Google iOS app.
 *
 * @fileoverview A find in page tool. It can:
 *   1. Search for given string in the DOM, and highlight them in yellow color;
 *   2. Allow users to navigate through all match results, and highlight the
 * selected one in orange color;
 */

(function() {
/**
 * Namespace for this file.
 */
__gCrWeb.findInPage = {};

 // Store common namespace object in a global __gCrWeb object referenced by a
 // string, so it does not get renamed by closure compiler during the
 // minification.
__gCrWeb['findInPage'] = __gCrWeb.findInPage;

/**
 * A string made by concatenating textContent.toLowerCase() of all TEXT nodes
 * within current web page.
 * @type {string}
 */
let allText_ = '';

/**
 * A Section contains the info of one TEXT node in the |allText_|. The node's
 * textContent is [begin, end) of |allText_|.
 */
class Section {
  /**
   * @param {number} begin Beginning index of |node|.textContent in |allText_|.
   * @param {number} end Ending index of |node|.textContent in |allText_|.
   * @param {Node} node The TEXT Node of this section.
   */
  constructor(begin, end, node) {
    this.begin = begin;
    this.end = end;
    this.node = node;
  }
}

/**
 * All the sections_ in |allText_|.
 * @type {Array<Section>}
 */
let sections_ = [];

/**
 * The index of the Section where the last PartialMatch is found.
 */
let sectionsIndex_ = 0;

/**
 * Do binary search in |sections_|[sectionsIndex_, ...) to find the first
 * Section S which has S.end > |index|.
 * @param {number} index The search target. This should be a valid index of
 *     |allText_|.
 * @return {number} The index of the result in |sections_|.
 */
function findFirstSectionEndsAfter_(index) {
  let left = sectionsIndex_;
  let right = sections_.length;
  while (left < right) {
    let mid = Math.floor((left + right) / 2);
    if (sections_[mid].end <= index) {
      left = mid + 1;
    } else {
      right = mid;
    }
  }
  return left;
}

/**
 * A Match represents a match result in the document. |this.nodes| stores all
 * the <chrome_find> Nodes created for highlighting the matched text. If it
 * contains only one Node, it means the match is found within one HTML TEXT
 * Node, otherwise the match involves multiple HTML TEXT Nodes.
 */
class Match {
  constructor() {
    this.nodes = [];
  }

  /**
   * Returns if all <chrome_find> Nodes of this match are visible.
   * @return {Boolean} If the Match is visible.
   */
  visible() {
    for (let i = 0; i < this.nodes.length; ++i) {
      if (!isElementVisible_(this.nodes[i]))
        return false;
    }
    return true;
  }

  /**
   * Adds orange color highlight for "selected match result", over the yellow
   * color highlight for "normal match result".
   * @return {undefined}
   */
  addSelectHighlight() {
    for (let i = 0; i < this.nodes.length; ++i) {
      this.nodes[i].className = (this.nodes[i].className || '') + ' findysel';
    }
  }

  /**
   * Clears the orange color highlight.
   * @return {undefined}
   */
  removeSelectHighlight() {
    for (let i = 0; i < this.nodes.length; ++i) {
      this.nodes[i].className =
          (this.nodes[i].className || '').replace(/\sfindysel/g, '');
    }
  }
}

/**
 * The list of all the matches in current page.
 * @type {Array<Match>}
 */
__gCrWeb.findInPage.matches = [];

/**
 * Index of the current highlighted choice.  -1 means none.
 * @type {number}
 */
__gCrWeb.findInPage.selectedMatchIndex = -1;

/**
 * The ID for the next Match found in |allText_|. This ID is used for
 * identifying PartialMatches of the Match, so that when
 * |processPartialMatchesInCurrentSection| is called, the <chrome_find> Nodes
 * created for each PartialMatch can be recorded in the corresponding Match.
 */
let matchId_ = 0;

/**
 * A part of a Match, within a Section. A Match may cover multiple sections_ in
 * |allText_|, so it must be split into multiple PartialMatches and then
 * dispatched into the Sections they belong. The range of a PartialMatch in
 * |allText_| is [begin, end). Exactly one <chrome_find> will be created for
 * each PartialMatch.
 */
class PartialMatch {
  /**
   * @param {number} matchId ID of the Match to which this PartialMatch belongs.
   * @param {number} begin Beginning index of partial match text in |allText_|.
   * @param {number} end Ending index of partial match text in |allText_|.
   */
  constructor(matchId, begin, end) {
    this.matchId = matchId;
    this.begin = begin;
    this.end = end;
  }
}

/**
 * A temporary array used for storing all PartialMatches inside current Section.
 * @type {Array<PartialMatch>}
 */
let partialMatches_ = [];

/**
 * A Replacement represents a DOM operation that swaps |oldNode| with |newNodes|
 * under the parent of |oldNode| to highlight the match result inside |oldNode|.
 * |newNodes| may contain plain TEXT Nodes for unhighlighted parts and
 * <chrome_find> nodes for highlighted parts. This operation will be executed
 * reversely when clearing current highlights for next FindInPage action.
 */
class Replacement {
  /**
   * @param {Node} oldNode The HTML Node containing search result.
   * @param {Array<Node>} newNodes New HTML Nodes created for substitution of
   *     |oldNode|.
   */
  constructor(oldNode, newNodes) {
    this.oldNode = oldNode;
    this.newNodes = newNodes;
  }

  /**
   * Executes the replacement to highlight search result.
   * @return {undefined}
   */
  doSwap() {
    let parentNode = this.oldNode.parentNode;
    if (!parentNode)
      return;
    for (var i = 0; i < this.newNodes.length; ++i) {
      parentNode.insertBefore(this.newNodes[i], this.oldNode);
    }
    parentNode.removeChild(this.oldNode);
  }

  /**
   * Executes the replacement reversely to clear the highlight.
   * @return {undefined}
   */
  undoSwap() {
    let parentNode = this.newNodes[0].parentNode;
    if (!parentNode)
      return;
    parentNode.insertBefore(this.oldNode, this.newNodes[0]);
    for (var i = 0; i < this.newNodes.length; ++i) {
      parentNode.removeChild(this.newNodes[i]);
    }
  }
}

/**
 * The replacements of current FindInPage action.
 * @type {Array<Replacement>}
 */
let replacements_ = [];

/**
 * The index of the Replacement from which the highlight process continue when
 * pumpSearch is called.
 * @type {Number}
 */
let replacementsIndex_ = 0;

/**
 * The total number of visible matches found.
 * @type {Number}
 */
let visibleFound_ = 0;


/**
 * Process all PartialMatches inside current Section. For current Section's
 * node.textContent, all texts that are match results will be wrapped in
 * <chrome_find>, and other texts will be put inside plain TEXT Nodes. All
 * created Nodes will be stored in the Replacement of current Section, and all
 * <chrome_find> Nodes will also be recorded in their belonging Matches.
 * |partialMatches_| will be cleared when processing ends.
 * @return {undefined}
 */
function processPartialMatchesInCurrentSection() {
  if (partialMatches_.length == 0)
    return;
  let section = sections_[sectionsIndex_];
  let oldNode = section.node;
  let newNodes = [];
  let previousEnd = section.begin;
  for (let i = 0; i < partialMatches_.length; ++i) {
    let partialMatch = partialMatches_[i];
    // Create the TEXT node for leading non-matching string piece. Notice that
    // substr must be taken from TEXT Node.textContent instead of |allText_|
    // since it's in lower case.
    if (partialMatch.begin > previousEnd) {
      newNodes.push(
          oldNode.ownerDocument.createTextNode(oldNode.textContent.substring(
              previousEnd - section.begin,
              partialMatch.begin - section.begin)));
    }
    // Create the <chrome_find> Node for matching text.
    let newNode = oldNode.ownerDocument.createElement('chrome_find');
    newNode.setAttribute('class', CSS_CLASS_NAME);
    newNode.innerHTML = escapeHTML_(oldNode.textContent.substring(
        partialMatch.begin - section.begin, partialMatch.end - section.begin));
    newNodes.push(newNode);
    previousEnd = partialMatch.end;

    // Record the <chrome_find> Node in corresponding Match.
    __gCrWeb.findInPage.matches[partialMatch.matchId].nodes.push(newNode);
  }
  // Create the TEXT node for trailing non-matching string piece.
  if (previousEnd != section.end) {
    newNodes.push(
        oldNode.ownerDocument.createTextNode(oldNode.textContent.substring(
            previousEnd - section.begin, section.end - section.begin)));
  }

  // Create the Replacement of current Section.
  replacements_.push(new Replacement(oldNode, newNodes));

  partialMatches_ = [];
}

/**
 * The style DOM element that we add.
 * @type {Element}
 */
let styleElement_ = null;

/**
 * Maximum number of visible elements to count
 * @type {number}
 */
const MAX_VISIBLE_ELEMENTS = 100;

/**
 * A search is in progress.
 * @type {boolean}
 */
let searchInProgress_ = false;

/**
 * Node names that are not going to be processed.
 * @type {Object}
 */
const IGNORE_NODE_NAMES = new Set(['SCRIPT', 'STYLE', 'EMBED',
  'OBJECT', 'SELECT', 'TEXTAREA', 'IFRAME']);

/**
 * Class name of CSS element.
 * @type {string}
 */
const CSS_CLASS_NAME = 'find_in_page';

/**
 * ID of CSS style.
 * @type {string}
 */
const CSS_STYLE_ID = '__gCrWeb.findInPageStyle';

/**
 * Result passed back to app to indicate pumpSearch has reached timeout.
 * @type {number}
 */
const TIMEOUT = -1;

/**
 * Regex to escape regex special characters in a string.
 * @type {RegExp}
 */
const REGEX_ESCAPER = /([.?*+^$[\]\\(){}|-])/g;

/**
 * @return {Match} The currently selected Match.
 */
function getCurrentSelectedMatch_() {
  return __gCrWeb.findInPage.matches[__gCrWeb.findInPage.selectedMatchIndex];
};

/**
 * Creates the regex needed to find the text.
 * @param {string} findText Phrase to look for.
 * @return {RegExp} regex needed to find the text.
 */
function getRegex_(findText) {
  let regexString = '(' + escapeRegex_(findText) + ')';
  return new RegExp(regexString, 'ig');
};

/**
 * A timer that checks timeout for long tasks.
 */
class Timer {
  /**
   * @param {Number} timeoutMs Timeout in milliseconds.
   */
  constructor(timeoutMs) {
    this.beginTime = Date.now();
    this.timeoutMs = timeoutMs;
  }

  /**
   * @return {Boolean} Whether this timer has been reached.
   */
  overtime() {
    return Date.now() - this.beginTime > this.timeoutMs;
  }
}

 /**
  * Looks for a phrase in the DOM.
  * @param {string} string Phrase to look for like "ben franklin".
  * @param {number} timeout Maximum time to run.
  * @return {number} that represents the total matches found.
  */
__gCrWeb.findInPage.findString = function(string, timeout) {
  // Enable findInPage module if hasn't been done yet.
  if (!__gCrWeb.findInPage.hasInitialized) {
    enable_();
    __gCrWeb.findInPage.hasInitialized = true;
  }

  if (__gCrWeb.findInPage.matches && __gCrWeb.findInPage.matches.length) {
    // Clean up a previous run.
    cleanUp_();
  }
  if (!string) {
    // No searching for emptyness.
    return 0;
  }

  // Holds what nodes we have not processed yet.
  __gCrWeb.findInPage.stack = [document.body];

  // Number of visible elements found.
  visibleFound_ = 0;

  // Index tracking variables so search can be broken up into multiple calls.
  visibleIndex_ = 0;

  __gCrWeb.findInPage.regex = getRegex_(string);

  searchInProgress_ = true;

  return __gCrWeb.findInPage.pumpSearch(timeout);
};

/**
 * Do following steps:
 *   1. Do a DFS in the page, concatenate all TEXT Nodes' content into
 *      |allText_|, and create |sections_| to record which part of |allText_|
 *      belongs to which Node;
 *   2. Do regex match in |allText_| to find all matches, create |replacements_|
 *      for highlighting all results and |matches_| for
 *      highlighting selected result;
 *   3. Execute |replacements_| to highlight all results;
 *   4. Check the visibility of each Match;
 *
 * If |timeout| has been reached, the function will return TIMEOUT, and the
 * caller need to call this function again to continue searching. This prevents
 * the Js thread from blocking the WebView's UI.
 *
 * @param {number} timeout Only run find in page until timeout.
 * @return {number} that represents the total matches found.
 */
__gCrWeb.findInPage.pumpSearch = function(timeout) {
  // TODO(crbug.com/895531): It would be better if this DCHECKed.
  if (searchInProgress_ == false) {
    return 0;
  }

  let timer = new Timer(timeout);

  // Go through every node in DFS fashion.
  while (__gCrWeb.findInPage.stack.length) {
    let node = __gCrWeb.findInPage.stack.pop();
    let children = node.childNodes;
    if (children && children.length) {
      // add all (reasonable) children
      for (let i = children.length - 1; i >= 0; --i) {
        let child = children[i];
        if ((child.nodeType == 1 || child.nodeType == 3) &&
            !IGNORE_NODE_NAMES.has(child.nodeName)) {
          __gCrWeb.findInPage.stack.push(children[i]);
        }
      }
    }

    // Build up |allText_| and |sections_|.
    if (node.nodeType == 3 && node.parentNode) {
      sections_.push(new Section(allText_.length, allText_.length +
          node.textContent.length, node));
      allText_ += node.textContent.toLowerCase();
    }

    if (timer.overtime()) {
      return TIMEOUT;
    }
  }

  // Do regex match in |allText_|, create |matches| and |replacements|. The
  // regex is set on __gCrWeb, so its state is kept between continuous calls on
  // pumpSearch.
  let regex = __gCrWeb.findInPage.regex;
  if (regex) {
    for (let res; res = regex.exec(allText_);) {
      // The range of current Match in |allText_| is [begin, end).
      let begin = res.index;
      let end = begin + res[0].length;
      __gCrWeb.findInPage.matches.push(new Match());

      // Find the Section where current Match starts.
      let oldSectionIndex = sectionsIndex_;
      let newSectionIndex = findFirstSectionEndsAfter_(begin);
      // If current Match starts at a new Section, process current Section and
      // move to the new Section.
      if (newSectionIndex > oldSectionIndex) {
        processPartialMatchesInCurrentSection();
        sectionsIndex_ = newSectionIndex;
      }

      // Create all PartialMatches of current Match.
      while (true) {
        let section = sections_[sectionsIndex_];
        partialMatches_.push(new PartialMatch(matchId_, Math.max(
            section.begin, begin), Math.min(section.end, end)));
        // If current Match.end exceeds current Section.end, process current
        // Section and move to next Section.
        if (section.end < end) {
          processPartialMatchesInCurrentSection();
          ++sectionsIndex_;
        } else {
          // Current Match ends in current Section.
          break;
        }
      }
      ++matchId_;

      if (timer.overtime()) {
        return TIMEOUT;
      }
    }
    // Process remaining PartialMatches.
    processPartialMatchesInCurrentSection();
    __gCrWeb.findInPage.regex = undefined;
  }

  // Execute replacements to highlight search results.
  for (let i = replacementsIndex_; i < replacements_.length; ++i) {
    if (timer.overtime()) {
      replacementsIndex_ = i;
      return TIMEOUT;
    }
    replacements_[i].doSwap();
  }

  // Count visible elements.
  let max = __gCrWeb.findInPage.matches.length;
  let maxVisible = MAX_VISIBLE_ELEMENTS;
  for (let index = visibleIndex_; index < max; index++) {
    let match = __gCrWeb.findInPage.matches[index];
    if (timer.overtime()) {
      visibleIndex_ = index;
      return TIMEOUT;
    }

    // Stop after |maxVisible| elements.
    if (visibleFound_ > maxVisible) {
      match.visibleIndex = maxVisible;
      continue;
    }

    if (match.visible()) {
      visibleFound_++;
      match.visibleIndex = visibleFound_;
    }
  }

  searchInProgress_ = false;

  return visibleFound_;
};

/**
 * Removes highlights of previous search and reset all global vars.
 * @return {undefined}
 */
function cleanUp_() {
  for (let i = 0; i < replacements_.length; ++i) {
    replacements_[i].undoSwap();
  }

  allText_ = '';
  sections_ = [];
  sectionsIndex_ = 0;

  __gCrWeb.findInPage.matches = [];
  __gCrWeb.findInPage.selectedMatchIndex = -1;
  matchId_ = 0;
  partialMatches_ = [];

  replacements_ = [];
  replacementsIndex_ = 0;
};

/**
 * Increments the index of the current selected Match or, if the index is
 * already at the end, sets it to the index of the first Match in the page.
 */
__gCrWeb.findInPage.incrementIndex = function() {
  if (__gCrWeb.findInPage.selectedMatchIndex >=
      __gCrWeb.findInPage.matches.length - 1) {
    __gCrWeb.findInPage.selectedMatchIndex = 0;
  } else {
    __gCrWeb.findInPage.selectedMatchIndex++;
  }
};

/**
 * Switches to the next result, animating a little highlight in the process.
 * @return {string} JSON encoded array of coordinates to scroll to, or blank if
 *     nothing happened.
 */
__gCrWeb.findInPage.goNext = function() {
  if (!__gCrWeb.findInPage.matches || __gCrWeb.findInPage.matches.length == 0) {
    return '';
  }
  if (__gCrWeb.findInPage.selectedMatchIndex >= 0) {
    // Remove previous highlight.
    getCurrentSelectedMatch_().removeSelectHighlight();
  }
  // Iterate through to the next index, but because they might not be visible,
  // keep trying until you find one that is.  Make sure we don't loop forever by
  // stopping on what we are currently highlighting.
  let oldIndex = __gCrWeb.findInPage.selectedMatchIndex;
  __gCrWeb.findInPage.incrementIndex();
  while (!getCurrentSelectedMatch_().visible()) {
    if (oldIndex === __gCrWeb.findInPage.selectedMatchIndex) {
      // Checked all matches but didn't find anything else visible.
      return '';
    }
    __gCrWeb.findInPage.incrementIndex();
    if (0 === __gCrWeb.findInPage.selectedMatchIndex && oldIndex < 0) {
      // Didn't find anything visible and haven't highlighted anything yet.
      return '';
    }
  }
  // Return scroll dimensions.
  return findScrollDimensions_();
};

/**
 * Decrements the index of the current selected Match or, if the index is
 * already at the beginning, sets it to the index of the last Match in the page.
 */
__gCrWeb.findInPage.decrementIndex = function() {
  if (__gCrWeb.findInPage.selectedMatchIndex <= 0) {
    __gCrWeb.findInPage.selectedMatchIndex =
        __gCrWeb.findInPage.matches.length - 1;
  } else {
    __gCrWeb.findInPage.selectedMatchIndex--;
  }
};

/**
 * Switches to the previous result, animating a little highlight in the process.
 * @return {string} JSON encoded array of coordinates to scroll to, or blank if
 *     nothing happened.
 */
__gCrWeb.findInPage.goPrev = function() {
  if (!__gCrWeb.findInPage.matches || __gCrWeb.findInPage.matches.length == 0) {
    return '';
  }
  if (__gCrWeb.findInPage.selectedMatchIndex >= 0) {
    // Remove previous highlight.
    getCurrentSelectedMatch_().removeSelectHighlight();
  }
  // Iterate through to the next index, but because they might not be visible,
  // keep trying until you find one that is.  Make sure we don't loop forever by
  // stopping on what we are currently highlighting.
  let old = __gCrWeb.findInPage.selectedMatchIndex;
  __gCrWeb.findInPage.decrementIndex();
  while (!getCurrentSelectedMatch_().visible()) {
    __gCrWeb.findInPage.decrementIndex();
    if (old == __gCrWeb.findInPage.selectedMatchIndex) {
      // Checked all matches but didn't find anything.
      return '';
    }
  }

  // Return scroll dimensions.
  return findScrollDimensions_();
};

/**
 * Normalize coordinates according to the current document dimensions. Don't go
 * too far off the screen in either direction. Try to center if possible.
 * @param {Element} elem Element to find normalized coordinates for.
 * @return {Array<number>} Normalized coordinates.
 */
function getNormalizedCoordinates_(elem) {
  let pos = findAbsolutePosition_(elem);
  let maxX = Math.max(getBodyWidth_(), pos[0] + elem.offsetWidth);
  let maxY = Math.max(getBodyHeight_(), pos[1] + elem.offsetHeight);
  // Don't go too far off the screen in either direction.  Try to center if
  // possible.
  let xPos = Math.max(
      0, Math.min(maxX - window.innerWidth, pos[0] - (window.innerWidth / 2)));
  let yPos = Math.max(
      0,
      Math.min(maxY - window.innerHeight, pos[1] - (window.innerHeight / 2)));
  return [xPos, yPos];
};

/**
 * Scale coordinates according to the width of the screen, in case the screen
 * is zoomed out.
 * @param {Array<number>} coordinates Coordinates to scale.
 * @return {Array<number>} Scaled coordinates.
 */
function scaleCoordinates_(coordinates) {
  let scaleFactor = pageWidth_ / window.innerWidth;
  return [coordinates[0] * scaleFactor, coordinates[1] * scaleFactor];
};

/**
 * Finds the position of the result.
 * @return {string} JSON encoded array of the scroll coordinates "[x, y]".
 */
function findScrollDimensions_() {
  let match = getCurrentSelectedMatch_();
  if (!match) {
    return '';
  }
  let normalized = getNormalizedCoordinates_(match.nodes[0]);
  let xPos = normalized[0];
  let yPos = normalized[1];

  match.addSelectHighlight();
  let scaled = scaleCoordinates_(normalized);
  let index = match.visibleIndex;
  scaled.unshift(index);
  return __gCrWeb.stringify(scaled);
};

/**
 * Enable the __gCrWeb.findInPage module.
 * Mainly just adds the style for the classes.
 */
function enable_() {
  if (styleElement_) {
    // Already enabled.
    return;
  }
  addDocumentStyle_(document);
};

/**
 * Gets the scale ratio between the application window and the web document.
 * @return {number} Scale.
 */
function getPageScale_() {
  return (pageWidth_ / getBodyWidth_());
};

/**
 * Adds the appropriate style element to the page.
 */
function addDocumentStyle_(thisDocument) {
  let styleContent = [];
  function addCSSRule(name, style) {
    styleContent.push(name, '{', style, '}');
  };
  let scale = getPageScale_();
  let zoom = (1.0 / scale);
  let left = ((1 - scale) / 2 * 100);
  addCSSRule(
      '.' + CSS_CLASS_NAME,
      'background-color:#ffff00 !important;' +
          'padding:0px;margin:0px;' +
          'overflow:visible !important;');
  addCSSRule(
      '.findysel',
      'background-color:#ff9632 !important;' +
          'padding:0px;margin:0px;' +
          'overflow:visible !important;');
  styleElement_ = thisDocument.createElement('style');
  styleElement_.id = CSS_STYLE_ID;
  styleElement_.setAttribute('type', 'text/css');
  styleElement_.appendChild(thisDocument.createTextNode(styleContent.join('')));
  thisDocument.body.appendChild(styleElement_);
};

/**
 * Removes the style element from the page.
 */
function removeStyle_() {
  if (styleElement_) {
    let style = document.getElementById(CSS_STYLE_ID);
    document.body.removeChild(style);
    styleElement_ = null;
  }
};

/**
 * Disables the __gCrWeb.findInPage module.
 * Basically just removes the style and class names.
 */
__gCrWeb.findInPage.disable = function() {
  if (styleElement_) {
    removeStyle_();
    window.setTimeout(cleanUp_, 0);
  }
  __gCrWeb.findInPage.hasInitialized = false;
};

/**
 * Returns the width of the document.body.  Sometimes though the body lies to
 * try to make the page not break rails, so attempt to find those as well.
 * An example: wikipedia pages for the ipad.
 * @return {number} Width of the document body.
 */
function getBodyWidth_() {
  let body = document.body;
  let documentElement = document.documentElement;
  return Math.max(
      body.scrollWidth, documentElement.scrollWidth, body.offsetWidth,
      documentElement.offsetWidth, body.clientWidth,
      documentElement.clientWidth);
};

/**
 * Returns the height of the document.body.  Sometimes though the body lies to
 * try to make the page not break rails, so attempt to find those as well.
 * An example: wikipedia pages for the ipad.
 * @return {number} Height of the document body.
 */
function getBodyHeight_() {
  let body = document.body;
  let documentElement = document.documentElement;
  return Math.max(
      body.scrollHeight, documentElement.scrollHeight, body.offsetHeight,
      documentElement.offsetHeight, body.clientHeight,
      documentElement.clientHeight);
};

/**
 * Helper function that determines if an element is visible.
 * @param {Element} elem Element to check.
 * @return {boolean} Whether elem is visible or not.
 */
function isElementVisible_(elem) {
  if (!elem) {
    return false;
  }
  let top = 0;
  let left = 0;
  let bottom = Infinity;
  let right = Infinity;

  let originalElement = elem;
  let nextOffsetParent = originalElement.offsetParent;

  // We are currently handling all scrolling through the app, which means we can
  // only scroll the window, not any scrollable containers in the DOM itself. So
  // for now this function returns false if the element is scrolled outside the
  // viewable area of its ancestors.
  // TODO(crbug.com/915357): handle scrolling within the DOM.
  let bodyHeight = getBodyHeight_();
  let bodyWidth = getBodyWidth_();

  while (elem && elem.nodeName.toUpperCase() != 'BODY') {
    let computedStyle =
        elem.ownerDocument.defaultView.getComputedStyle(elem, null);

    if (elem.style.display === 'none' || elem.style.visibility === 'hidden' ||
        elem.style.opacity === 0 || computedStyle.display === 'none' ||
        computedStyle.visibility === 'hidden' || computedStyle.opacity === 0) {
      return false;
    }

    // For the original element and all ancestor offsetParents, trim down the
    // visible area of the original element.
    if (elem.isSameNode(originalElement) || elem.isSameNode(nextOffsetParent)) {
      let visible = elem.getBoundingClientRect();
      if (elem.style.overflow === 'hidden' &&
          (visible.width === 0 || visible.height === 0))
        return false;

      top = Math.max(top, visible.top + window.pageYOffset);
      bottom = Math.min(bottom, visible.bottom + window.pageYOffset);
      left = Math.max(left, visible.left + window.pageXOffset);
      right = Math.min(right, visible.right + window.pageXOffset);

      // The element is not within the original viewport.
      let notWithinViewport = top < 0 || left < 0;

      // The element is flowing off the boundary of the page. Note this is
      // not comparing to the size of the window, but the calculated offset
      // size of the document body. This can happen if the element is within
      // a scrollable container in the page.
      let offPage = right > bodyWidth || bottom > bodyHeight;
      if (notWithinViewport || offPage) {
        return false;
      }
      nextOffsetParent = elem.offsetParent;
    }

    elem = elem.parentNode;
  }
  return true;
};

/**
 * Helper function to find the absolute position of an element on the page.
 * @param {Element} elem Element to check.
 * @return {Array<number>} [x, y] positions.
 */
function findAbsolutePosition_(elem) {
  let boundingRect = elem.getBoundingClientRect();
  return [
    boundingRect.left + window.pageXOffset,
    boundingRect.top + window.pageYOffset
  ];
};

/**
 * @param {string} text Text to escape.
 * @return {string} escaped text.
 */
function escapeHTML_(text) {
  let unusedDiv = document.createElement('div');
  unusedDiv.innerText = text;
  return unusedDiv.innerHTML;
};

/**
 * Escapes regexp special characters.
 * @param {string} text Text to escape.
 * @return {string} escaped text.
 */
function escapeRegex_(text) {
  return text.replace(REGEX_ESCAPER, '\\$1');
};

window.addEventListener('pagehide', __gCrWeb.findInPage.disable);

})();
