// Copyright 2017 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.

/**
 * @fileoverview using private properties isn't a Closure violation in tests.
 * @suppress {accessControls}
 */

/**
 * @param {string} idValue
 * @param {!Function} callback
 */
ElementsTestRunner.selectNodeWithId = function(idValue, callback) {
  callback = TestRunner.safeWrap(callback);
  function onNodeFound(node) {
    ElementsTestRunner.selectNode(node).then(callback.bind(null, node));
  }
  ElementsTestRunner.nodeWithId(idValue, onNodeFound);
};

/**
 * @param {!Object} node
 * @return {!Promise.<undefined>}
 */
ElementsTestRunner.selectNode = function(node) {
  return Common.Revealer.reveal(node);
};

/**
 * @param {string} idValue
 * @param {!Function} callback
 */
ElementsTestRunner.nodeWithId = function(idValue, callback) {
  ElementsTestRunner.findNode(node => node.getAttribute('id') === idValue, callback);
};

/**
 * @param {string} idValue
 * @param {!Function} callback
 */
ElementsTestRunner.nodeWithIdPromise = function(idValue) {
  return new Promise(resolve => ElementsTestRunner.findNode(node => node.getAttribute('id') === idValue, resolve));
};

/**
 * @param {function(!Element): boolean} matchFunction
 * @param {!Function} callback
 */
ElementsTestRunner.findNode = async function(matchFunction, callback) {
  callback = TestRunner.safeWrap(callback);
  let result = null;
  let pendingRequests = 0;
  async function processChildren(node) {
    try {
      if (result) {
        return;
      }

      if (node._childDocumentPromiseForTesting) {
        await node._childDocumentPromiseForTesting;
      }

      const pseudoElementsMap = node.pseudoElements();
      const pseudoElements = pseudoElementsMap ? pseudoElementsMap.valuesArray() : [];
      const children = (node.children() || []).concat(node.shadowRoots()).concat(pseudoElements);
      if (node.templateContent()) {
        children.push(node.templateContent());
      } else if (node.contentDocument()) {
        children.push(node.contentDocument());
      } else if (node.importedDocument()) {
        children.push(node.importedDocument());
      }

      for (let i = 0; i < children.length; ++i) {
        const childNode = children[i];
        if (matchFunction(childNode)) {
          result = childNode;
          callback(result);
          return;
        }
        pendingRequests++;
        childNode.getChildNodes(processChildren.bind(null, childNode));
      }
    } finally {
      pendingRequests--;
    }

    if (!result && !pendingRequests) {
      callback(null);
    }
  }

  const doc = TestRunner.domModel.existingDocument() || await TestRunner.domModel.requestDocument();
  pendingRequests++;
  doc.getChildNodes(processChildren.bind(null, doc));
};

/**
 * @param {function(!Element): boolean} matchFunction
 * @param {!Promise}
 */
ElementsTestRunner.findNodePromise = function(matchFunction) {
  return new Promise(resolve => ElementsTestRunner.findNode(matchFunction, resolve));
};

/**
 * @param {!EventListeners.EventListenersView} eventListenersView
 * @param {function():void} callback
 * @param {boolean=} force
 */
ElementsTestRunner.expandAndDumpEventListeners = function(eventListenersView, callback, force) {
  function listenersArrived() {
    const listenerTypes = eventListenersView._treeOutline.rootElement().children();
    for (let i = 0; i < listenerTypes.length; ++i) {
      listenerTypes[i].expand();
      const listenerItems = listenerTypes[i].children();
      for (let j = 0; j < listenerItems.length; ++j) {
        listenerItems[j].expand();
      }
    }
    TestRunner.deprecatedRunAfterPendingDispatches(objectsExpanded);
  }

  function objectsExpanded() {
    const listenerTypes = eventListenersView._treeOutline.rootElement().children();
    for (let i = 0; i < listenerTypes.length; ++i) {
      if (!listenerTypes[i].children().length) {
        continue;
      }
      const eventType = listenerTypes[i]._title;
      TestRunner.addResult('');
      TestRunner.addResult('======== ' + eventType + ' ========');
      const listenerItems = listenerTypes[i].children();
      for (let j = 0; j < listenerItems.length; ++j) {
        TestRunner.addResult('== ' + listenerItems[j].eventListener().origin());
        TestRunner.dumpObjectPropertyTreeElement(listenerItems[j]);
      }
    }
    callback();
  }

  if (force) {
    listenersArrived();
  } else {
    TestRunner.addSniffer(
        EventListeners.EventListenersView.prototype, '_eventListenersArrivedForTest', listenersArrived);
  }
};

/**
 * @param {!EventListeners.EventListenersView} eventListenersView
 * @param {boolean=} force
 * @return {!Promise}
 */
ElementsTestRunner.expandAndDumpEventListenersPromise = function(eventListenersView, force) {
  return new Promise(resolve => ElementsTestRunner.expandAndDumpEventListeners(eventListenersView, resolve, force));
};

ElementsTestRunner.inlineStyleSection = function() {
  return UI.panels.elements._stylesWidget._sectionBlocks[0].sections[0];
};

ElementsTestRunner.computedStyleWidget = function() {
  return UI.panels.elements._computedStyleWidget;
};

ElementsTestRunner.dumpComputedStyle = function(doNotAutoExpand, printInnerText) {
  const computed = ElementsTestRunner.computedStyleWidget();
  const treeOutline = computed._propertiesOutline;
  const children = treeOutline.rootElement().children();

  for (const treeElement of children) {
    const property = treeElement[Elements.ComputedStyleWidget._propertySymbol];

    if (property.name === 'width' || property.name === 'height') {
      continue;
    }

    let dumpText = '';
    dumpText += text(treeElement.title.querySelector('.property-name'));
    dumpText += text(treeElement.title.querySelector('.property-value'));
    TestRunner.addResult(dumpText);

    if (doNotAutoExpand && !treeElement.expanded) {
      continue;
    }

    for (const trace of treeElement.children()) {
      const title = trace.title;
      let dumpText = '';

      if (trace.title.classList.contains('property-trace-inactive')) {
        dumpText += 'OVERLOADED ';
      }

      dumpText += text(title.querySelector('.property-trace-value'));
      dumpText += ' - ';
      dumpText += text(title.querySelector('.property-trace-selector'));
      const link = title.querySelector('.trace-link');

      if (link) {
        dumpText += ' ' + extractLinkText(link);
      }

      TestRunner.addResult('    ' + dumpText);
    }
  }

  function text(node) {
    return printInnerText ? node.innerText : node.textContent;
  }
};

ElementsTestRunner.findComputedPropertyWithName = function(name) {
  const computed = ElementsTestRunner.computedStyleWidget();
  const treeOutline = computed._propertiesOutline;
  const children = treeOutline.rootElement().children();

  for (const treeElement of children) {
    const property = treeElement[Elements.ComputedStyleWidget._propertySymbol];

    if (property.name === name) {
      return treeElement;
    }
  }

  return null;
};

ElementsTestRunner.firstMatchedStyleSection = function() {
  return UI.panels.elements._stylesWidget._sectionBlocks[0].sections[1];
};

ElementsTestRunner.firstMediaTextElementInSection = function(section) {
  return section.element.querySelector('.media-text');
};

ElementsTestRunner.querySelector = async function(selector, callback) {
  const doc = await TestRunner.domModel.requestDocument();
  const nodeId = await TestRunner.domModel.querySelector(doc.id, selector);
  callback(TestRunner.domModel.nodeForId(nodeId));
};

ElementsTestRunner.shadowRootByHostId = function(idValue, callback) {
  function shadowRootMatches(node) {
    return node.isShadowRoot() && node.parentNode.getAttribute('id') === idValue;
  }

  ElementsTestRunner.findNode(shadowRootMatches, callback);
};

ElementsTestRunner.nodeWithClass = function(classValue, callback) {
  function nodeClassMatches(node) {
    const classAttr = node.getAttribute('class');
    return classAttr && classAttr.indexOf(classValue) > -1;
  }

  ElementsTestRunner.findNode(nodeClassMatches, callback);
};

ElementsTestRunner.expandedNodeWithId = function(idValue) {
  let result;
  ElementsTestRunner.nodeWithId(idValue, node => result = node);
  return result;
};

function waitForStylesRebuild(matchFunction, callback, requireRebuild) {
  (function sniff(node, rebuild) {
    if ((rebuild || !requireRebuild) && node && matchFunction(node)) {
      callback();
      return;
    }

    TestRunner.addSniffer(Elements.StylesSidebarPane.prototype, '_nodeStylesUpdatedForTest', sniff);
  })(null);
}

ElementsTestRunner.waitForStyles = function(idValue, callback, requireRebuild) {
  callback = TestRunner.safeWrap(callback);

  function nodeWithId(node) {
    return node.getAttribute('id') === idValue;
  }

  waitForStylesRebuild(nodeWithId, callback, requireRebuild);
};

ElementsTestRunner.waitForStyleCommitted = function(next) {
  TestRunner.addSniffer(Elements.StylePropertyTreeElement.prototype, '_editingCommitted', (...args) => {
    Promise.all(args).then(next);
  });
};

ElementsTestRunner.waitForStylesForClass = function(classValue, callback, requireRebuild) {
  callback = TestRunner.safeWrap(callback);

  function nodeWithClass(node) {
    const classAttr = node.getAttribute('class');
    return classAttr && classAttr.indexOf(classValue) > -1;
  }

  waitForStylesRebuild(nodeWithClass, callback, requireRebuild);
};

ElementsTestRunner.waitForSelectorCommitted = function(callback) {
  TestRunner.addSniffer(Elements.StylePropertiesSection.prototype, '_editingSelectorCommittedForTest', callback);
};

ElementsTestRunner.waitForMediaTextCommitted = function(callback) {
  TestRunner.addSniffer(Elements.StylePropertiesSection.prototype, '_editingMediaTextCommittedForTest', callback);
};

ElementsTestRunner.waitForStyleApplied = function(callback) {
  TestRunner.addSniffer(Elements.StylePropertyTreeElement.prototype, 'styleTextAppliedForTest', callback);
};

ElementsTestRunner.waitForStyleAppliedPromise = function() {
  return new Promise(resolve => ElementsTestRunner.waitForStyleApplied(resolve));
};

ElementsTestRunner.selectNodeAndWaitForStyles = function(idValue, callback) {
  callback = TestRunner.safeWrap(callback);
  let targetNode;
  ElementsTestRunner.waitForStyles(idValue, stylesUpdated, true);
  ElementsTestRunner.selectNodeWithId(idValue, nodeSelected);

  function nodeSelected(node) {
    targetNode = node;
  }

  function stylesUpdated() {
    callback(targetNode);
  }
};

ElementsTestRunner.selectNodeAndWaitForStylesPromise = function(idValue) {
  return new Promise(x => ElementsTestRunner.selectNodeAndWaitForStyles(idValue, x));
};

ElementsTestRunner.selectPseudoElementAndWaitForStyles = function(parentId, pseudoType, callback) {
  callback = TestRunner.safeWrap(callback);
  let targetNode;
  waitForStylesRebuild(isPseudoElement, stylesUpdated, true);
  ElementsTestRunner.findNode(isPseudoElement, nodeFound);

  function nodeFound(node) {
    targetNode = node;
    Common.Revealer.reveal(node);
  }

  function stylesUpdated() {
    callback(targetNode);
  }

  function isPseudoElement(node) {
    return node.parentNode && node.parentNode.getAttribute('id') === parentId && node.pseudoType() === pseudoType;
  }
};

ElementsTestRunner.selectNodeAndWaitForStylesWithComputed = function(idValue, callback) {
  callback = TestRunner.safeWrap(callback);
  ElementsTestRunner.selectNodeAndWaitForStyles(idValue, onSidebarRendered);

  function onSidebarRendered(node) {
    ElementsTestRunner.computedStyleWidget().doUpdate().then(callback.bind(null, node));
  }
};

ElementsTestRunner.firstElementsTreeOutline = function() {
  return UI.panels.elements._treeOutlines[0];
};

ElementsTestRunner.filterMatchedStyles = function(text) {
  const regex = (text ? new RegExp(text, 'i') : null);
  TestRunner.addResult('Filtering styles by: ' + text);
  UI.panels.elements._stylesWidget._onFilterChanged(regex);
};

ElementsTestRunner.dumpRenderedMatchedStyles = function() {
  const sectionBlocks = UI.panels.elements._stylesWidget._sectionBlocks;

  for (const block of sectionBlocks) {
    for (const section of block.sections) {
      if (section.element.classList.contains('hidden')) {
        continue;
      }

      dumpRenderedSection(section);
    }
  }

  function dumpRenderedSection(section) {
    TestRunner.addResult(section._selectorElement.textContent + ' {');
    const rootElement = section.propertiesTreeOutline.rootElement();

    for (let i = 0; i < rootElement.childCount(); ++i) {
      dumpRenderedProperty(rootElement.childAt(i));
    }

    TestRunner.addResult('}');
  }

  function dumpRenderedProperty(property) {
    let text = new Array(4).join(' ');
    text += property.nameElement.textContent;
    text += ':';

    if (property.isExpandable()) {
      text += (property.expanded ? 'v' : '>');
    } else {
      text += ' ';
    }

    text += property.valueElement.textContent;

    if (property.listItemElement.classList.contains('filter-match')) {
      text = 'F' + text.substring(1);
    }

    TestRunner.addResult(text);

    if (!property.expanded) {
      return;
    }

    const indent = new Array(8).join(' ');

    for (let i = 0; i < property.childCount(); ++i) {
      const childProperty = property.childAt(i);
      let text = indent;
      text += String.sprintf('%s: %s', childProperty.nameElement.textContent, childProperty.valueElement.textContent);

      if (childProperty.listItemElement.classList.contains('filter-match')) {
        text = 'F' + text.substring(1);
      }

      TestRunner.addResult(text);
    }
  }
};

ElementsTestRunner.dumpSelectedElementStyles = function(
    excludeComputed, excludeMatched, omitLonghands, includeSelectorGroupMarks, printInnerText) {
  const sectionBlocks = UI.panels.elements._stylesWidget._sectionBlocks;

  if (!excludeComputed) {
    ElementsTestRunner.dumpComputedStyle(false /* doNotAutoExpand */, printInnerText);
  }

  for (const block of sectionBlocks) {
    for (const section of block.sections) {
      if (section.style().parentRule && excludeMatched) {
        continue;
      }

      if (section.element.previousSibling && section.element.previousSibling.className === 'sidebar-separator') {
        let nodeDescription = '';

        if (section.element.previousSibling.firstElementChild) {
          nodeDescription = text(section.element.previousSibling.firstElementChild.shadowRoot.lastChild);
        }

        TestRunner.addResult('======== ' + text(section.element.previousSibling) + nodeDescription + ' ========');
      }

      printStyleSection(section, omitLonghands, includeSelectorGroupMarks, printInnerText);
    }
  }

  function text(node) {
    return printInnerText ? node.innerText : node.textContent;
  }
};

function printStyleSection(section, omitLonghands, includeSelectorGroupMarks, printInnerText) {
  if (!section) {
    return;
  }

  TestRunner.addResult(
      '[expanded] ' + ((section.propertiesTreeOutline.element.classList.contains('no-affect') ? '[no-affect] ' : '')));
  const medias = section._titleElement.querySelectorAll('.media-list .media');

  for (let i = 0; i < medias.length; ++i) {
    const media = medias[i];
    TestRunner.addResult(text(media));
  }

  const selector =
      section._titleElement.querySelector('.selector') || section._titleElement.querySelector('.keyframe-key');
  let selectorText = (includeSelectorGroupMarks ? buildMarkedSelectors(selector) : text(selector));
  selectorText += text(selector.nextSibling);
  const anchor = section._titleElement.querySelector('.styles-section-subtitle');

  if (anchor) {
    const anchorText = extractLinkText(anchor);
    selectorText += String.sprintf(' (%s)', anchorText);
  }

  TestRunner.addResult(selectorText);
  ElementsTestRunner.dumpStyleTreeOutline(section.propertiesTreeOutline, (omitLonghands ? 1 : 2), printInnerText);
  if (!section._showAllButton.classList.contains('hidden')) {
    TestRunner.addResult(text(section._showAllButton));
  }
  TestRunner.addResult('');

  function text(node) {
    return printInnerText ? node.innerText : node.textContent;
  }
}

function extractLinkText(element) {
  const anchor = element.querySelector('.devtools-link');

  if (!anchor) {
    return element.textContent;
  }

  const anchorText = anchor.textContent;
  const info = Components.Linkifier._linkInfo(anchor);
  const uiLocation = info && info.uiLocation;
  const anchorTarget =
      (uiLocation ?
           uiLocation.uiSourceCode.name() + ':' + (uiLocation.lineNumber + 1) + ':' + (uiLocation.columnNumber + 1) :
           '');
  return anchorText + ' -> ' + anchorTarget;
}

function buildMarkedSelectors(element) {
  let result = '';

  for (let node = element.firstChild; node; node = node.nextSibling) {
    if (node.nodeType === Node.ELEMENT_NODE && node.classList.contains('selector-matches')) {
      result += '[$' + node.textContent + '$]';
    } else {
      result += node.textContent;
    }
  }

  return result;
}

ElementsTestRunner.toggleStyleProperty = function(propertyName, checked) {
  const treeItem = ElementsTestRunner.getElementStylePropertyTreeItem(propertyName);

  treeItem._toggleDisabled(!checked);
};

ElementsTestRunner.toggleMatchedStyleProperty = function(propertyName, checked) {
  const treeItem = ElementsTestRunner.getMatchedStylePropertyTreeItem(propertyName);

  treeItem._toggleDisabled(!checked);
};

ElementsTestRunner.eventListenersWidget = function() {
  UI.viewManager.showView('elements.eventListeners');
  return self.runtime.sharedInstance(Elements.EventListenersWidget);
};

ElementsTestRunner.showEventListenersWidget = function() {
  return UI.viewManager.showView('elements.eventListeners');
};

/**
 * @return {Promise}
 */
ElementsTestRunner.showComputedStyles = function() {
  UI.panels.elements.sidebarPaneView.tabbedPane().selectTab('Computed', true);
  return ElementsTestRunner.computedStyleWidget().doUpdate();
};

ElementsTestRunner.expandAndDumpSelectedElementEventListeners = function(callback, force) {
  ElementsTestRunner.expandAndDumpEventListeners(
      ElementsTestRunner.eventListenersWidget()._eventListenersView, callback, force);
};

ElementsTestRunner.removeFirstEventListener = function() {
  const treeOutline = ElementsTestRunner.eventListenersWidget()._eventListenersView._treeOutline;
  const listenerTypes = treeOutline.rootElement().children();

  for (let i = 0; i < listenerTypes.length; i++) {
    const listeners = listenerTypes[i].children();

    if (listeners.length && !listenerTypes[i].hidden) {
      listeners[0].eventListener().remove();
      listeners[0]._removeListenerBar();
      break;
    }
  }
};

ElementsTestRunner.dumpObjectPropertySectionDeep = function(section) {
  function domNodeToString(node) {
    if (node) {
      return '\'' + node.textContent + '\'';
    } else {
      return 'null';
    }
  }

  function dumpTreeElementRecursively(treeElement, prefix) {
    if ('nameElement' in treeElement) {
      TestRunner.addResult(
          prefix + domNodeToString(treeElement.nameElement) + ' => ' + domNodeToString(treeElement.valueElement));
    } else {
      TestRunner.addResult(prefix + treeElement.title);
    }

    for (let i = 0; i < treeElement.childCount(); i++) {
      dumpTreeElementRecursively(treeElement.childAt(i), prefix + '    ');
    }
  }

  const childNodes = section.propertiesTreeOutline.rootElement().children();

  for (let i = 0; i < childNodes.length; i++) {
    dumpTreeElementRecursively(childNodes[i], '');
  }

};

ElementsTestRunner.getElementStylePropertyTreeItem = function(propertyName) {
  return ElementsTestRunner.getFirstPropertyTreeItemForSection(ElementsTestRunner.inlineStyleSection(), propertyName);
};

ElementsTestRunner.getMatchedStylePropertyTreeItem = function(propertyName) {
  const sectionBlocks = UI.panels.elements._stylesWidget._sectionBlocks;

  for (const block of sectionBlocks) {
    for (const section of block.sections) {
      const treeItem = ElementsTestRunner.getFirstPropertyTreeItemForSection(section, propertyName);

      if (treeItem) {
        return treeItem;
      }
    }
  }

  return null;
};

ElementsTestRunner.getFirstPropertyTreeItemForSection = function(section, propertyName) {
  const outline = section.propertiesTreeOutline.rootElement();

  for (let i = 0; i < outline.childCount(); ++i) {
    const treeItem = outline.childAt(i);

    if (treeItem.name === propertyName) {
      return treeItem;
    }
  }

  return null;
};

ElementsTestRunner.dumpStyleTreeOutline = function(treeItem, depth, printInnerText) {
  const children = treeItem.rootElement().children();

  for (let i = 0; i < children.length; ++i) {
    ElementsTestRunner.dumpStyleTreeItem(children[i], '', depth || 2, printInnerText);
  }
};

ElementsTestRunner.dumpStyleTreeItem = function(treeItem, prefix, depth, printInnerText) {
  const textContent = printInnerText ? treeItem.listItemElement.innerText :
                                       TestRunner.textContentWithoutStyles(treeItem.listItemElement);
  if (textContent.indexOf(' width:') !== -1 || textContent.indexOf(' height:') !== -1) {
    return;
  }

  if (treeItem.listItemElement.classList.contains('inherited')) {
    return;
  }

  let typePrefix = '';

  if (treeItem.listItemElement.classList.contains('overloaded') ||
      treeItem.listItemElement.classList.contains('inactive') ||
      treeItem.listItemElement.classList.contains('not-parsed-ok')) {
    typePrefix += '/-- overloaded --/ ';
  }

  if (treeItem.listItemElement.classList.contains('disabled')) {
    typePrefix += '/-- disabled --/ ';
  }

  TestRunner.addResult(prefix + typePrefix + textContent);

  if (--depth) {
    treeItem.expand();
    const children = treeItem.children();

    for (let i = 0; children && i < children.length; ++i) {
      ElementsTestRunner.dumpStyleTreeItem(children[i], prefix + '    ', depth);
    }
  }
};

ElementsTestRunner.dumpElementsTree = function(rootNode, depth, resultsArray) {
  function beautify(element) {
    return element.innerText.replace(/\u200b/g, '').replace(/\n/g, '\\n').trim();
  }

  function dumpMap(name, map) {
    const result = [];

    for (const id of map.keys()) {
      result.push(id + '=' + map.get(id));
    }

    if (!result.length) {
      return '';
    }

    return name + ':[' + result.join(',') + ']';
  }

  function markersDataDump(treeItem) {
    if (treeItem._elementCloseTag) {
      return '';
    }

    let markers = '';
    const node = treeItem._node;

    if (node) {
      markers += dumpMap('markers', node._markers);
      const dump = (node._subtreeMarkerCount ? 'subtreeMarkerCount:' + node._subtreeMarkerCount : '');

      if (dump) {
        if (markers) {
          markers += ', ';
        }

        markers += dump;
      }

      if (markers) {
        markers = ' [' + markers + ']';
      }
    }

    return markers;
  }

  function print(treeItem, prefix, depth) {
    if (!treeItem.root) {
      let expander;

      if (treeItem.isExpandable()) {
        if (treeItem.expanded) {
          expander = '- ';
        } else {
          expander = '+ ';
        }
      } else {
        expander = '  ';
      }

      const markers = markersDataDump(treeItem);
      let value = prefix + expander + beautify(treeItem.listItemElement) + markers;

      if (treeItem.shadowHostToolbar) {
        value = prefix + expander + 'shadow-root ';

        for (let i = 0; i < treeItem.shadowHostToolbar.children.length; ++i) {
          const button = treeItem.shadowHostToolbar.children[i];
          const toggled = button.disabled;
          const name = ((toggled ? '<' : '')) + button.textContent + ((toggled ? '>' : ''));
          value += name + ' ';
        }
      }

      if (resultsArray) {
        resultsArray.push(value);
      } else {
        TestRunner.addResult(value);
      }
    }

    if (!treeItem.expanded) {
      return;
    }

    const children = treeItem.children();
    const newPrefix = (treeItem.root ? '' : prefix + '    ');

    for (let i = 0; depth && children && i < children.length; ++i) {
      if (!children[i]._elementCloseTag) {
        print(children[i], newPrefix, depth - 1);
      } else {
        print(children[i], prefix, depth);
      }
    }
  }

  const treeOutline = ElementsTestRunner.firstElementsTreeOutline();
  treeOutline.runPendingUpdates();
  print((rootNode ? treeOutline.findTreeElement(rootNode) : treeOutline.rootElement()), '', depth || 10000);
};

ElementsTestRunner.dumpDOMUpdateHighlights = function(rootNode, callback, depth) {
  let hasHighlights = false;
  TestRunner.addSniffer(Elements.ElementsTreeOutline.prototype, '_updateModifiedNodes', didUpdate);

  function didUpdate() {
    const treeOutline = ElementsTestRunner.firstElementsTreeOutline();
    print((rootNode ? treeOutline.findTreeElement(rootNode) : treeOutline.rootElement()), '', depth || 10000);

    if (!hasHighlights) {
      TestRunner.addResult('<No highlights>');
    }

    if (callback) {
      callback();
    }
  }

  function print(treeItem, prefix, depth) {
    if (!treeItem.root) {
      const elementXPath = Elements.DOMPath.xPath(treeItem.node(), true);
      const highlightedElements = treeItem.listItemElement.querySelectorAll('.dom-update-highlight');

      for (let i = 0; i < highlightedElements.length; ++i) {
        const element = highlightedElements[i];
        const classList = element.classList;
        let xpath = elementXPath;

        if (classList.contains('webkit-html-attribute-name')) {
          xpath += '/@' + element.textContent + ' (empty)';
        } else if (classList.contains('webkit-html-attribute-value')) {
          name = element.parentElement.querySelector('.webkit-html-attribute-name').textContent;
          xpath += '/@' + name + ' ' + element.textContent;
        } else if (classList.contains('webkit-html-text-node')) {
          xpath += '/text() "' + element.textContent + '"';
        }

        TestRunner.addResult(prefix + xpath);
        hasHighlights = true;
      }
    }

    if (!treeItem.expanded) {
      return;
    }

    const children = treeItem.children();
    const newPrefix = (treeItem.root ? '' : prefix + '    ');

    for (let i = 0; depth && children && i < children.length; ++i) {
      if (!children[i]._elementCloseTag) {
        print(children[i], newPrefix, depth - 1);
      }
    }
  }
};

ElementsTestRunner.expandElementsTree = function(callback) {
  let expandedSomething = false;
  callback = TestRunner.safeWrap(callback);

  function expand(treeItem) {
    const children = treeItem.children();

    for (let i = 0; children && i < children.length; ++i) {
      const child = children[i];

      if (child.isExpandable() && !child.expanded) {
        child.expand();
        expandedSomething = true;
      }

      expand(child);
    }
  }

  function onAllNodesAvailable() {
    ElementsTestRunner.firstElementsTreeOutline().runPendingUpdates();
    expand(ElementsTestRunner.firstElementsTreeOutline().rootElement());
    setTimeout(callback.bind(null, expandedSomething));
  }

  ElementsTestRunner.findNode(function() {
    return false;
  }, onAllNodesAvailable);
};

ElementsTestRunner.expandAndDump = function() {
  TestRunner.addResult('\nDump tree');
  let callback;
  const result = new Promise(f => callback = f);
  ElementsTestRunner.expandElementsTree(() => {
    ElementsTestRunner.dumpElementsTree();
    callback();
  });
  return result;
};

ElementsTestRunner.dumpDOMAgentTree = function(node) {
  if (!TestRunner.domModel._document) {
    return;
  }

  function dump(node, prefix) {
    TestRunner.addResult(prefix + node.nodeName());
    prefix = prefix + '    ';

    if (node.templateContent()) {
      dump(node.templateContent(), prefix);
    }

    if (node.contentDocument()) {
      dump(node.contentDocument(), prefix);
    }

    if (node.importedDocument()) {
      dump(node.importedDocument(), prefix);
    }

    const shadowRoots = node.shadowRoots();

    for (let i = 0; i < shadowRoots.length; ++i) {
      dump(shadowRoots[i], prefix);
    }

    const children = node.children();

    for (let i = 0; children && i < children.length; ++i) {
      dump(children[i], prefix);
    }
  }

  dump(node, '');
};

ElementsTestRunner.rangeText = function(range) {
  if (!range) {
    return '[undefined-undefined]';
  }

  return '[' + range.startLine + ':' + range.startColumn + '-' + range.endLine + ':' + range.endColumn + ']';
};

ElementsTestRunner.generateUndoTest = function(testBody) {
  function result(next) {
    const testNode = ElementsTestRunner.expandedNodeWithId(/function\s([^(]*)/.exec(testBody)[1]);
    TestRunner.addResult('Initial:');
    ElementsTestRunner.dumpElementsTree(testNode);
    testBody(undo);

    function undo() {
      TestRunner.addResult('Post-action:');
      ElementsTestRunner.dumpElementsTree(testNode);
      ElementsTestRunner.expandElementsTree(expandedCallback);

      function expandedCallback(expandedSomething) {
        if (expandedSomething) {
          TestRunner.addResult('== Expanded: ==');
          ElementsTestRunner.dumpElementsTree(testNode);
        }

        SDK.domModelUndoStack.undo().then(redo);
      }
    }

    function redo() {
      TestRunner.addResult('Post-undo (initial):');
      ElementsTestRunner.dumpElementsTree(testNode);
      ElementsTestRunner.expandElementsTree(expandedCallback);

      function expandedCallback(expandedSomething) {
        if (expandedSomething) {
          TestRunner.addResult('== Expanded: ==');
          ElementsTestRunner.dumpElementsTree(testNode);
        }

        SDK.domModelUndoStack.redo().then(done);
      }
    }

    function done() {
      TestRunner.addResult('Post-redo (action):');
      ElementsTestRunner.dumpElementsTree(testNode);
      ElementsTestRunner.expandElementsTree(expandedCallback);

      function expandedCallback(expandedSomething) {
        if (expandedSomething) {
          TestRunner.addResult('== Expanded: ==');
          ElementsTestRunner.dumpElementsTree(testNode);
        }

        next();
      }
    }
  }

  result.toString = function() {
    return testBody.toString();
  };

  return result;
};

const indent = '    ';

ElementsTestRunner.dumpRulesArray = function(rules, currentIndent) {
  if (!rules) {
    return;
  }

  currentIndent = currentIndent || '';

  for (let i = 0; i < rules.length; ++i) {
    ElementsTestRunner.dumpRule(rules[i], currentIndent);
  }
};

ElementsTestRunner.dumpRuleMatchesArray = function(matches, currentIndent) {
  if (!matches) {
    return;
  }

  currentIndent = currentIndent || '';

  for (let i = 0; i < matches.length; ++i) {
    ElementsTestRunner.dumpRule(matches[i].rule, currentIndent);
  }
};

ElementsTestRunner.dumpRule = function(rule, currentIndent) {
  function selectorRange() {
    const selectors = rule.selectorList.selectors;

    if (!selectors || !selectors[0].range) {
      return '';
    }

    const ranges = [];

    for (let i = 0; i < selectors.length; ++i) {
      const range = selectors[i].range;
      ranges.push(range.startLine + ':' + range.startColumn + '-' + range.endLine + ':' + range.endColumn);
    }

    return ', ' + ranges.join('; ');
  }

  currentIndent = currentIndent || '';

  if (!rule.type || rule.type === 'style') {
    TestRunner.addResult(currentIndent + rule.selectorList.text + ': [' + rule.origin + selectorRange() + '] {');
    ElementsTestRunner.dumpStyle(rule.style, currentIndent + indent);
    TestRunner.addResult(currentIndent + '}');
    return;
  }

  if (rule.type === 'media') {
    TestRunner.addResult(currentIndent + '@media ' + rule.mediaText + ' {');
    ElementsTestRunner.dumpRulesArray(rule.childRules, currentIndent + indent);
    TestRunner.addResult(currentIndent + '}');
    return;
  }

  if (rule.type === 'import') {
    TestRunner.addResult(
        currentIndent + '@import: header=' + ElementsTestRunner.rangeText(rule.headerRange) +
        ', body=' + ElementsTestRunner.rangeText(rule.bodyRange));

    return;
  }

  if (rule.type === 'page' || rule.type === 'font-face') {
    if (rule.type === 'page') {
      TestRunner.addResult(currentIndent + rule.selectorList.text + ' {');
    } else {
      TestRunner.addResult(
          currentIndent + '@' + rule.type + ' ' + ((rule.selectorList.text ? rule.selectorList.text + ' ' : '')) + '{');
    }

    ElementsTestRunner.dumpStyle(rule.style, currentIndent + indent);
    TestRunner.addResult(currentIndent + '}');
    return;
  }

  if (rule.type === 'charset') {
    TestRunner.addResult('@charset');
    return;
  }

  TestRunner.addResult(
      currentIndent + '[UNKNOWN RULE]: header=' + ElementsTestRunner.rangeText(rule.headerRange) +
      ', body=' + ElementsTestRunner.rangeText(rule.bodyRange));
};

ElementsTestRunner.dumpStyle = function(style, currentIndent) {
  currentIndent = currentIndent || '';

  if (!style) {
    TestRunner.addResult(currentIndent + '[NO STYLE]');
    return;
  }

  for (let i = 0; i < style.cssProperties.length; ++i) {
    const property = style.cssProperties[i];

    if (!property.disabled) {
      TestRunner.addResult(
          currentIndent + '[\'' + property.name + '\':\'' + property.value + '\'' +
          ((property.important ? ' is-important' : '')) + (('parsedOk' in property ? ' non-parsed' : '')) + '] @' +
          ElementsTestRunner.rangeText(property.range) + ' ');
    } else {
      TestRunner.addResult(currentIndent + '[text=\'' + property.text + '\'] disabled');
    }
  }
};

ElementsTestRunner.dumpCSSStyleDeclaration = function(style, currentIndent) {
  currentIndent = currentIndent || '';

  if (!style) {
    TestRunner.addResult(currentIndent + '[NO STYLE]');
    return;
  }

  const properties = style.allProperties();

  for (let i = 0; i < properties.length; ++i) {
    const property = properties[i];

    if (!property.disabled) {
      TestRunner.addResult(
          currentIndent + '[\'' + property.name + '\':\'' + property.value + '\'' +
          ((property.important ? ' is-important' : '')) + ((!property['parsedOk'] ? ' non-parsed' : '')) + '] @' +
          ElementsTestRunner.rangeText(property.range) + ' ');
    } else {
      TestRunner.addResult(currentIndent + '[text=\'' + property.text + '\'] disabled');
    }
  }
};

ElementsTestRunner.dumpBreadcrumb = function(message) {
  if (message) {
    TestRunner.addResult(message + ':');
  }

  const result = [];
  const crumbs = UI.panels.elements._breadcrumbs.crumbsElement;
  let crumb = crumbs.lastChild;

  while (crumb) {
    result.unshift(crumb.textContent);
    crumb = crumb.previousSibling;
  }

  TestRunner.addResult(result.join(' > '));
};

ElementsTestRunner.matchingSelectors = function(matchedStyles, rule) {
  const selectors = [];
  const matchingSelectors = matchedStyles.matchingSelectors(rule);

  for (let i = 0; i < matchingSelectors.length; ++i) {
    selectors.push(rule.selectors[matchingSelectors[i]].text);
  }

  return '[' + selectors.join(', ') + ']';
};

ElementsTestRunner.addNewRuleInStyleSheet = function(styleSheetHeader, selector, callback) {
  TestRunner.addSniffer(
      Elements.StylesSidebarPane.prototype, '_addBlankSection', onBlankSection.bind(null, selector, callback));
  UI.panels.elements._stylesWidget._createNewRuleInStyleSheet(styleSheetHeader);
};

ElementsTestRunner.addNewRule = function(selector, callback) {
  UI.panels.elements._stylesWidget.contentElement.querySelector('.styles-pane-toolbar')
      .shadowRoot.querySelector('.largeicon-add')
      .click();
  TestRunner.addSniffer(
      Elements.StylesSidebarPane.prototype, '_addBlankSection', onBlankSection.bind(null, selector, callback));
};

function onBlankSection(selector, callback) {
  const section = ElementsTestRunner.firstMatchedStyleSection();

  if (typeof selector === 'string') {
    section._selectorElement.textContent = selector;
  }

  section._selectorElement.dispatchEvent(TestRunner.createKeyEvent('Enter'));
  ElementsTestRunner.waitForSelectorCommitted(callback.bind(null, section));
}

ElementsTestRunner.dumpInspectorHighlightJSON = function(idValue, callback) {
  ElementsTestRunner.nodeWithId(idValue, nodeResolved);

  async function nodeResolved(node) {
    const result = await TestRunner.OverlayAgent.getHighlightObjectForTest(node.id);
    TestRunner.addResult(idValue + JSON.stringify(result, null, 2));
    callback();
  }
};

ElementsTestRunner.dumpInspectorDistanceJSON = function(idValue, callback) {
  ElementsTestRunner.nodeWithId(idValue, nodeResolved);

  async function nodeResolved(node) {
    const result = await TestRunner.OverlayAgent.getHighlightObjectForTest(node.id, true);
    const info = result['distanceInfo'];
    if (!info) {
      TestRunner.addResult(`${idValue}: No distance info`);
    } else {
      if (info['style']) {
        info['style'] = '<style data>';
      }
      TestRunner.addResult(idValue + JSON.stringify(info, null, 2));
    }
    callback();
  }
};

ElementsTestRunner.dumpInspectorHighlightStyleJSON = async function(idValue) {
  const node = await ElementsTestRunner.nodeWithIdPromise(idValue);
  const result = await TestRunner.OverlayAgent.getHighlightObjectForTest(node.id, false, true /* includeStyle */);
  const info = result['elementInfo'] ? result['elementInfo']['style'] : null;
  if (!info) {
    TestRunner.addResult(`${idValue}: No style info`);
  } else {
    if (info['font-family']) {
      info['font-family'] = '<font-family value>';
    }
    TestRunner.addResult(idValue + JSON.stringify(info, null, 2));
  }
};

ElementsTestRunner.waitForAnimationAdded = function(callback) {
  TestRunner.addSniffer(Animation.AnimationTimeline.prototype, '_addAnimationGroup', callback);
};

ElementsTestRunner.dumpAnimationTimeline = function(timeline) {
  for (const ui of timeline._uiAnimations) {
    TestRunner.addResult(ui.animation().type());
    TestRunner.addResult(ui._nameElement.innerHTML);
    TestRunner.addResult(ui._svg.innerHTML);
  }
};
