/*
 * Copyright (C) 2011 Google Inc.  All rights reserved.
 * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
 * Copyright (C) 2007 Matt Lilek (pewtermoose@gmail.com).
 * Copyright (C) 2009 Joseph Pecoraro
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
export const highlightedSearchResultClassName = 'highlighted-search-result';
export const highlightedCurrentSearchResultClassName = 'current-search-result';

/**
 * @param {!Element} element
 * @param {?function(!MouseEvent): boolean} elementDragStart
 * @param {function(!MouseEvent)} elementDrag
 * @param {?function(!MouseEvent)} elementDragEnd
 * @param {?string} cursor
 * @param {?string=} hoverCursor
 * @param {number=} startDelay
 */
export function installDragHandle(
    element, elementDragStart, elementDrag, elementDragEnd, cursor, hoverCursor, startDelay) {
  /**
   * @param {!Event} event
   */
  function onMouseDown(event) {
    const dragHandler = new DragHandler();
    const dragStart = dragHandler.elementDragStart.bind(
        dragHandler, element, elementDragStart, elementDrag, elementDragEnd, cursor, event);
    if (startDelay) {
      startTimer = setTimeout(dragStart, startDelay);
    } else {
      dragStart();
    }
  }

  function onMouseUp() {
    if (startTimer) {
      clearTimeout(startTimer);
    }
    startTimer = null;
  }

  let startTimer;
  element.addEventListener('mousedown', onMouseDown, false);
  if (startDelay) {
    element.addEventListener('mouseup', onMouseUp, false);
  }
  if (hoverCursor !== null) {
    element.style.cursor = hoverCursor || cursor || '';
  }
}

/**
 * @param {!Element} targetElement
 * @param {?function(!MouseEvent):boolean} elementDragStart
 * @param {function(!MouseEvent)} elementDrag
 * @param {?function(!MouseEvent)} elementDragEnd
 * @param {?string} cursor
 * @param {!Event} event
 */
export function elementDragStart(targetElement, elementDragStart, elementDrag, elementDragEnd, cursor, event) {
  const dragHandler = new DragHandler();
  dragHandler.elementDragStart(targetElement, elementDragStart, elementDrag, elementDragEnd, cursor, event);
}

/**
 * @unrestricted
 */
class DragHandler {
  constructor() {
    this._elementDragMove = this._elementDragMove.bind(this);
    this._elementDragEnd = this._elementDragEnd.bind(this);
    this._mouseOutWhileDragging = this._mouseOutWhileDragging.bind(this);
  }

  _createGlassPane() {
    this._glassPaneInUse = true;
    if (!DragHandler._glassPaneUsageCount++) {
      DragHandler._glassPane = new UI.GlassPane();
      DragHandler._glassPane.setPointerEventsBehavior(UI.GlassPane.PointerEventsBehavior.BlockedByGlassPane);
      DragHandler._glassPane.show(DragHandler._documentForMouseOut);
    }
  }

  _disposeGlassPane() {
    if (!this._glassPaneInUse) {
      return;
    }
    this._glassPaneInUse = false;
    if (--DragHandler._glassPaneUsageCount) {
      return;
    }
    DragHandler._glassPane.hide();
    delete DragHandler._glassPane;
    delete DragHandler._documentForMouseOut;
  }

  /**
   * @param {!Element} targetElement
   * @param {?function(!MouseEvent):boolean} elementDragStart
   * @param {function(!MouseEvent)} elementDrag
   * @param {?function(!MouseEvent)} elementDragEnd
   * @param {?string} cursor
   * @param {!Event} event
   */
  elementDragStart(targetElement, elementDragStart, elementDrag, elementDragEnd, cursor, event) {
    // Only drag upon left button. Right will likely cause a context menu. So will ctrl-click on mac.
    if (event.button || (Host.isMac() && event.ctrlKey)) {
      return;
    }

    if (this._elementDraggingEventListener) {
      return;
    }

    if (elementDragStart && !elementDragStart(/** @type {!MouseEvent} */ (event))) {
      return;
    }

    const targetDocument = event.target.ownerDocument;
    this._elementDraggingEventListener = elementDrag;
    this._elementEndDraggingEventListener = elementDragEnd;
    console.assert(
        (DragHandler._documentForMouseOut || targetDocument) === targetDocument, 'Dragging on multiple documents.');
    DragHandler._documentForMouseOut = targetDocument;
    this._dragEventsTargetDocument = targetDocument;
    try {
      this._dragEventsTargetDocumentTop = targetDocument.defaultView.top.document;
    } catch (e) {
      this._dragEventsTargetDocumentTop = this._dragEventsTargetDocument;
    }

    targetDocument.addEventListener('mousemove', this._elementDragMove, true);
    targetDocument.addEventListener('mouseup', this._elementDragEnd, true);
    targetDocument.addEventListener('mouseout', this._mouseOutWhileDragging, true);
    if (targetDocument !== this._dragEventsTargetDocumentTop) {
      this._dragEventsTargetDocumentTop.addEventListener('mouseup', this._elementDragEnd, true);
    }

    if (typeof cursor === 'string') {
      this._restoreCursorAfterDrag = restoreCursor.bind(this, targetElement.style.cursor);
      targetElement.style.cursor = cursor;
      targetDocument.body.style.cursor = cursor;
    }
    /**
     * @param {string} oldCursor
     * @this {DragHandler}
     */
    function restoreCursor(oldCursor) {
      targetDocument.body.style.removeProperty('cursor');
      targetElement.style.cursor = oldCursor;
      this._restoreCursorAfterDrag = null;
    }
    event.preventDefault();
  }

  _mouseOutWhileDragging() {
    this._unregisterMouseOutWhileDragging();
    this._createGlassPane();
  }

  _unregisterMouseOutWhileDragging() {
    if (!DragHandler._documentForMouseOut) {
      return;
    }
    DragHandler._documentForMouseOut.removeEventListener('mouseout', this._mouseOutWhileDragging, true);
  }

  _unregisterDragEvents() {
    if (!this._dragEventsTargetDocument) {
      return;
    }
    this._dragEventsTargetDocument.removeEventListener('mousemove', this._elementDragMove, true);
    this._dragEventsTargetDocument.removeEventListener('mouseup', this._elementDragEnd, true);
    if (this._dragEventsTargetDocument !== this._dragEventsTargetDocumentTop) {
      this._dragEventsTargetDocumentTop.removeEventListener('mouseup', this._elementDragEnd, true);
    }
    delete this._dragEventsTargetDocument;
    delete this._dragEventsTargetDocumentTop;
  }

  /**
   * @param {!Event} event
   */
  _elementDragMove(event) {
    if (event.buttons !== 1) {
      this._elementDragEnd(event);
      return;
    }
    if (this._elementDraggingEventListener(/** @type {!MouseEvent} */ (event))) {
      this._cancelDragEvents(event);
    }
  }

  /**
   * @param {!Event} event
   */
  _cancelDragEvents(event) {
    this._unregisterDragEvents();
    this._unregisterMouseOutWhileDragging();

    if (this._restoreCursorAfterDrag) {
      this._restoreCursorAfterDrag();
    }

    this._disposeGlassPane();

    delete this._elementDraggingEventListener;
    delete this._elementEndDraggingEventListener;
  }

  /**
   * @param {!Event} event
   */
  _elementDragEnd(event) {
    const elementDragEnd = this._elementEndDraggingEventListener;
    this._cancelDragEvents(/** @type {!MouseEvent} */ (event));
    event.preventDefault();
    if (elementDragEnd) {
      elementDragEnd(/** @type {!MouseEvent} */ (event));
    }
  }
}

DragHandler._glassPaneUsageCount = 0;

/**
 * @param {?Node=} node
 * @return {boolean}
 */
export function isBeingEdited(node) {
  if (!node || node.nodeType !== Node.ELEMENT_NODE) {
    return false;
  }
  let element = /** {!Element} */ (node);
  if (element.classList.contains('text-prompt') || element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {
    return true;
  }

  if (!UI.__editingCount) {
    return false;
  }

  while (element) {
    if (element.__editing) {
      return true;
    }
    element = element.parentElementOrShadowHost();
  }
  return false;
}

/**
 * @return {boolean}
 * @suppressGlobalPropertiesCheck
 */
export function isEditing() {
  if (UI.__editingCount) {
    return true;
  }

  const focused = document.deepActiveElement();
  if (!focused) {
    return false;
  }
  return focused.classList.contains('text-prompt') || focused.nodeName === 'INPUT' || focused.nodeName === 'TEXTAREA';
}

/**
 * @param {!Element} element
 * @param {boolean} value
 * @return {boolean}
 */
export function markBeingEdited(element, value) {
  if (value) {
    if (element.__editing) {
      return false;
    }
    element.classList.add('being-edited');
    element.__editing = true;
    UI.__editingCount = (UI.__editingCount || 0) + 1;
  } else {
    if (!element.__editing) {
      return false;
    }
    element.classList.remove('being-edited');
    delete element.__editing;
    --UI.__editingCount;
  }
  return true;
}

// Avoids Infinity, NaN, and scientific notation (e.g. 1e20), see crbug.com/81165.
const _numberRegex = /^(-?(?:\d+(?:\.\d+)?|\.\d+))$/;

export const StyleValueDelimiters = ' \xA0\t\n"\':;,/()';

/**
 * @param {!Event} event
 * @return {?string}
 */
function _valueModificationDirection(event) {
  let direction = null;
  if (event.type === 'mousewheel') {
    // When shift is pressed while spinning mousewheel, delta comes as wheelDeltaX.
    if (event.wheelDeltaY > 0 || event.wheelDeltaX > 0) {
      direction = 'Up';
    } else if (event.wheelDeltaY < 0 || event.wheelDeltaX < 0) {
      direction = 'Down';
    }
  } else {
    if (event.key === 'ArrowUp' || event.key === 'PageUp') {
      direction = 'Up';
    } else if (event.key === 'ArrowDown' || event.key === 'PageDown') {
      direction = 'Down';
    }
  }
  return direction;
}

/**
 * @param {string} hexString
 * @param {!Event} event
 * @return {?string}
 */
function _modifiedHexValue(hexString, event) {
  const direction = _valueModificationDirection(event);
  if (!direction) {
    return null;
  }

  const mouseEvent = /** @type {!MouseEvent} */ (event);
  const number = parseInt(hexString, 16);
  if (isNaN(number) || !isFinite(number)) {
    return null;
  }

  const hexStrLen = hexString.length;
  const channelLen = hexStrLen / 3;

  // Colors are either rgb or rrggbb.
  if (channelLen !== 1 && channelLen !== 2) {
    return null;
  }

  // Precision modifier keys work with both mousewheel and up/down keys.
  // When ctrl is pressed, increase R by 1.
  // When shift is pressed, increase G by 1.
  // When alt is pressed, increase B by 1.
  // If no shortcut keys are pressed then increase hex value by 1.
  // Keys can be pressed together to increase RGB channels. e.g trying different shades.
  let delta = 0;
  if (UI.KeyboardShortcut.eventHasCtrlOrMeta(mouseEvent)) {
    delta += Math.pow(16, channelLen * 2);
  }
  if (mouseEvent.shiftKey) {
    delta += Math.pow(16, channelLen);
  }
  if (mouseEvent.altKey) {
    delta += 1;
  }
  if (delta === 0) {
    delta = 1;
  }
  if (direction === 'Down') {
    delta *= -1;
  }

  // Increase hex value by 1 and clamp from 0 ... maxValue.
  const maxValue = Math.pow(16, hexStrLen) - 1;
  const result = Number.constrain(number + delta, 0, maxValue);

  // Ensure the result length is the same as the original hex value.
  let resultString = result.toString(16).toUpperCase();
  for (let i = 0, lengthDelta = hexStrLen - resultString.length; i < lengthDelta; ++i) {
    resultString = '0' + resultString;
  }
  return resultString;
}

/**
 * @param {number} number
 * @param {!Event} event
 * @param {number=} modifierMultiplier
 * @return {?number}
 */
function _modifiedFloatNumber(number, event, modifierMultiplier) {
  const direction = _valueModificationDirection(event);
  if (!direction) {
    return null;
  }

  const mouseEvent = /** @type {!MouseEvent} */ (event);

  // Precision modifier keys work with both mousewheel and up/down keys.
  // When ctrl is pressed, increase by 100.
  // When shift is pressed, increase by 10.
  // When alt is pressed, increase by 0.1.
  // Otherwise increase by 1.
  let delta = 1;
  if (UI.KeyboardShortcut.eventHasCtrlOrMeta(mouseEvent)) {
    delta = 100;
  } else if (mouseEvent.shiftKey) {
    delta = 10;
  } else if (mouseEvent.altKey) {
    delta = 0.1;
  }

  if (direction === 'Down') {
    delta *= -1;
  }
  if (modifierMultiplier) {
    delta *= modifierMultiplier;
  }

  // Make the new number and constrain it to a precision of 6, this matches numbers the engine returns.
  // Use the Number constructor to forget the fixed precision, so 1.100000 will print as 1.1.
  const result = Number((number + delta).toFixed(6));
  if (!String(result).match(_numberRegex)) {
    return null;
  }
  return result;
}

/**
 * @param {string} wordString
 * @param {!Event} event
 * @param {function(string, number, string):string=} customNumberHandler
 * @return {?string}
 */
export function createReplacementString(wordString, event, customNumberHandler) {
  let prefix;
  let suffix;
  let number;
  let replacementString = null;
  let matches = /(.*#)([\da-fA-F]+)(.*)/.exec(wordString);
  if (matches && matches.length) {
    prefix = matches[1];
    suffix = matches[3];
    number = _modifiedHexValue(matches[2], event);
    if (number !== null) {
      replacementString = prefix + number + suffix;
    }
  } else {
    matches = /(.*?)(-?(?:\d+(?:\.\d+)?|\.\d+))(.*)/.exec(wordString);
    if (matches && matches.length) {
      prefix = matches[1];
      suffix = matches[3];
      number = _modifiedFloatNumber(parseFloat(matches[2]), event);
      if (number !== null) {
        replacementString =
            customNumberHandler ? customNumberHandler(prefix, number, suffix) : prefix + number + suffix;
      }
    }
  }
  return replacementString;
}

/**
 * @param {!Event} event
 * @param {!Element} element
 * @param {function(string,string)=} finishHandler
 * @param {function(string)=} suggestionHandler
 * @param {function(string, number, string):string=} customNumberHandler
 * @return {boolean}
 */
export function handleElementValueModifications(event, element, finishHandler, suggestionHandler, customNumberHandler) {
  /**
   * @return {?Range}
   * @suppressGlobalPropertiesCheck
   */
  function createRange() {
    return document.createRange();
  }

  const arrowKeyOrMouseWheelEvent =
      (event.key === 'ArrowUp' || event.key === 'ArrowDown' || event.type === 'mousewheel');
  const pageKeyPressed = (event.key === 'PageUp' || event.key === 'PageDown');
  if (!arrowKeyOrMouseWheelEvent && !pageKeyPressed) {
    return false;
  }

  const selection = element.getComponentSelection();
  if (!selection.rangeCount) {
    return false;
  }

  const selectionRange = selection.getRangeAt(0);
  if (!selectionRange.commonAncestorContainer.isSelfOrDescendant(element)) {
    return false;
  }

  const originalValue = element.textContent;
  const wordRange =
      selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, StyleValueDelimiters, element);
  const wordString = wordRange.toString();

  if (suggestionHandler && suggestionHandler(wordString)) {
    return false;
  }

  const replacementString = createReplacementString(wordString, event, customNumberHandler);

  if (replacementString) {
    const replacementTextNode = createTextNode(replacementString);

    wordRange.deleteContents();
    wordRange.insertNode(replacementTextNode);

    const finalSelectionRange = createRange();
    finalSelectionRange.setStart(replacementTextNode, 0);
    finalSelectionRange.setEnd(replacementTextNode, replacementString.length);

    selection.removeAllRanges();
    selection.addRange(finalSelectionRange);

    event.handled = true;
    event.preventDefault();

    if (finishHandler) {
      finishHandler(originalValue, replacementString);
    }

    return true;
  }
  return false;
}

/**
 * @param {number} ms
 * @param {number=} precision
 * @return {string}
 */
Number.preciseMillisToString = function(ms, precision) {
  precision = precision || 0;
  const format = '%.' + precision + 'f\xa0ms';
  return Common.UIString(format, ms);
};

/** @type {!Common.UIStringFormat} */
export const _microsFormat = new Common.UIStringFormat('%.0f\xa0\u03bcs');

/** @type {!Common.UIStringFormat} */
export const _subMillisFormat = new Common.UIStringFormat('%.2f\xa0ms');

/** @type {!Common.UIStringFormat} */
export const _millisFormat = new Common.UIStringFormat('%.0f\xa0ms');

/** @type {!Common.UIStringFormat} */
export const _secondsFormat = new Common.UIStringFormat('%.2f\xa0s');

/** @type {!Common.UIStringFormat} */
export const _minutesFormat = new Common.UIStringFormat('%.1f\xa0min');

/** @type {!Common.UIStringFormat} */
export const _hoursFormat = new Common.UIStringFormat('%.1f\xa0hrs');

/** @type {!Common.UIStringFormat} */
export const _daysFormat = new Common.UIStringFormat('%.1f\xa0days');

/**
 * @param {number} ms
 * @param {boolean=} higherResolution
 * @return {string}
 */
Number.millisToString = function(ms, higherResolution) {
  if (!isFinite(ms)) {
    return '-';
  }

  if (ms === 0) {
    return '0';
  }

  if (higherResolution && ms < 0.1) {
    return _microsFormat.format(ms * 1000);
  }
  if (higherResolution && ms < 1000) {
    return _subMillisFormat.format(ms);
  }
  if (ms < 1000) {
    return _millisFormat.format(ms);
  }

  const seconds = ms / 1000;
  if (seconds < 60) {
    return _secondsFormat.format(seconds);
  }

  const minutes = seconds / 60;
  if (minutes < 60) {
    return _minutesFormat.format(minutes);
  }

  const hours = minutes / 60;
  if (hours < 24) {
    return _hoursFormat.format(hours);
  }

  const days = hours / 24;
  return _daysFormat.format(days);
};

/**
 * @param {number} seconds
 * @param {boolean=} higherResolution
 * @return {string}
 */
Number.secondsToString = function(seconds, higherResolution) {
  if (!isFinite(seconds)) {
    return '-';
  }
  return Number.millisToString(seconds * 1000, higherResolution);
};

/**
 * @param {number} bytes
 * @return {string}
 */
Number.bytesToString = function(bytes) {
  if (bytes < 1024) {
    return Common.UIString('%.0f\xa0B', bytes);
  }

  const kilobytes = bytes / 1024;
  if (kilobytes < 100) {
    return Common.UIString('%.1f\xa0KB', kilobytes);
  }
  if (kilobytes < 1024) {
    return Common.UIString('%.0f\xa0KB', kilobytes);
  }

  const megabytes = kilobytes / 1024;
  if (megabytes < 100) {
    return Common.UIString('%.1f\xa0MB', megabytes);
  } else {
    return Common.UIString('%.0f\xa0MB', megabytes);
  }
};

/**
 * @param {number} num
 * @return {string}
 */
Number.withThousandsSeparator = function(num) {
  let str = num + '';
  const re = /(\d+)(\d{3})/;
  while (str.match(re)) {
    str = str.replace(re, '$1\xa0$2');
  }  // \xa0 is a non-breaking space
  return str;
};

/**
 * @param {string} format
 * @param {?ArrayLike} substitutions
 * @return {!Element}
 */
export function formatLocalized(format, substitutions) {
  const formatters = {s: substitution => substitution};
  /**
   * @param {!Element} a
   * @param {string|!Element} b
   * @return {!Element}
   */
  function append(a, b) {
    a.appendChild(typeof b === 'string' ? createTextNode(b) : b);
    return a;
  }
  return String.format(Common.UIString(format), substitutions, formatters, createElement('span'), append)
      .formattedResult;
}

/**
 * @return {string}
 */
export function openLinkExternallyLabel() {
  return Common.UIString('Open in new tab');
}

/**
 * @return {string}
 */
export function copyLinkAddressLabel() {
  return Common.UIString('Copy link address');
}

/**
 * @return {string}
 */
export function anotherProfilerActiveLabel() {
  return Common.UIString('Another profiler is already active');
}

/**
 * @param {string|undefined} description
 * @return {string}
 */
export function asyncStackTraceLabel(description) {
  if (description) {
    if (description === 'Promise.resolve') {
      return ls`Promise resolved (async)`;
    } else if (description === 'Promise.reject') {
      return ls`Promise rejected (async)`;
    }
    return ls`${description} (async)`;
  }
  return Common.UIString('Async Call');
}

/**
 * @param {!Element} element
 */
export function installComponentRootStyles(element) {
  _injectCoreStyles(element);
  element.classList.add('platform-' + Host.platform());

  // Detect overlay scrollbar enable by checking for nonzero scrollbar width.
  if (!Host.isMac() && measuredScrollbarWidth(element.ownerDocument) === 0) {
    element.classList.add('overlay-scrollbar-enabled');
  }
}

/** @type {number} */
let _measuredScrollbarWidth;

/**
 * @param {?Document} document
 * @return {number}
 */
export function measuredScrollbarWidth(document) {
  if (typeof _measuredScrollbarWidth === 'number') {
    return _measuredScrollbarWidth;
  }
  if (!document) {
    return 16;
  }
  const scrollDiv = document.createElement('div');
  scrollDiv.setAttribute('style', 'width: 100px; height: 100px; overflow: scroll;');
  document.body.appendChild(scrollDiv);
  _measuredScrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
  document.body.removeChild(scrollDiv);
  return _measuredScrollbarWidth;
}

/**
 * @param {!Element} element
 * @param {string=} cssFile
 * @param {boolean=} delegatesFocus
 * @return {!DocumentFragment}
 */
export function createShadowRootWithCoreStyles(element, cssFile, delegatesFocus) {
  const shadowRoot = element.attachShadow({mode: 'open', delegatesFocus});
  _injectCoreStyles(shadowRoot);
  if (cssFile) {
    appendStyle(shadowRoot, cssFile);
  }
  shadowRoot.addEventListener('focus', _focusChanged.bind(UI), true);
  return shadowRoot;
}

/**
 * @param {!Element|!ShadowRoot} root
 */
function _injectCoreStyles(root) {
  appendStyle(root, 'ui/inspectorCommon.css');
  appendStyle(root, 'ui/textButton.css');
  UI.themeSupport.injectHighlightStyleSheets(root);
  UI.themeSupport.injectCustomStyleSheets(root);
}

/**
 * @param {!Document} document
 * @param {!Event} event
 */
function _windowFocused(document, event) {
  if (event.target.document.nodeType === Node.DOCUMENT_NODE) {
    document.body.classList.remove('inactive');
  }
  UI._keyboardFocus = true;
  const listener = () => {
    const activeElement = document.deepActiveElement();
    if (activeElement) {
      activeElement.removeAttribute('data-keyboard-focus');
    }
    UI._keyboardFocus = false;
  };
  document.defaultView.requestAnimationFrame(() => {
    UI._keyboardFocus = false;
    document.removeEventListener('mousedown', listener, true);
  });
  document.addEventListener('mousedown', listener, true);
}

/**
 * @param {!Document} document
 * @param {!Event} event
 */
function _windowBlurred(document, event) {
  if (event.target.document.nodeType === Node.DOCUMENT_NODE) {
    document.body.classList.add('inactive');
  }
}

/**
 * @param {!Event} event
 */
function _focusChanged(event) {
  const document = event.target && event.target.ownerDocument;
  const element = document ? document.deepActiveElement() : null;
  UI.Widget.focusWidgetForNode(element);
  UI.XWidget.focusWidgetForNode(element);
  if (!UI._keyboardFocus) {
    return;
  }

  UI.markAsFocusedByKeyboard(element);
}

UI.markAsFocusedByKeyboard = function(element) {
  element.setAttribute('data-keyboard-focus', 'true');
  element.addEventListener('blur', () => element.removeAttribute('data-keyboard-focus'), {once: true, capture: true});
};

/**
 * @unrestricted
 */
export class ElementFocusRestorer {
  /**
   * @param {!Element} element
   */
  constructor(element) {
    this._element = element;
    this._previous = element.ownerDocument.deepActiveElement();
    element.focus();
  }

  restore() {
    if (!this._element) {
      return;
    }
    if (this._element.hasFocus() && this._previous) {
      this._previous.focus();
    }
    this._previous = null;
    this._element = null;
  }
}

/**
 * @param {!Element} element
 * @param {number} offset
 * @param {number} length
 * @param {!Array.<!Object>=} domChanges
 * @return {?Element}
 */
export function highlightSearchResult(element, offset, length, domChanges) {
  const result = highlightSearchResults(element, [new TextUtils.SourceRange(offset, length)], domChanges);
  return result.length ? result[0] : null;
}

/**
 * @param {!Element} element
 * @param {!Array.<!TextUtils.SourceRange>} resultRanges
 * @param {!Array.<!Object>=} changes
 * @return {!Array.<!Element>}
 */
export function highlightSearchResults(element, resultRanges, changes) {
  return highlightRangesWithStyleClass(element, resultRanges, highlightedSearchResultClassName, changes);
}

/**
 * @param {!Element} element
 * @param {string} className
 */
export function runCSSAnimationOnce(element, className) {
  function animationEndCallback() {
    element.classList.remove(className);
    element.removeEventListener('webkitAnimationEnd', animationEndCallback, false);
  }

  if (element.classList.contains(className)) {
    element.classList.remove(className);
  }

  element.addEventListener('webkitAnimationEnd', animationEndCallback, false);
  element.classList.add(className);
}

/**
 * @param {!Element} element
 * @param {!Array.<!TextUtils.SourceRange>} resultRanges
 * @param {string} styleClass
 * @param {!Array.<!Object>=} changes
 * @return {!Array.<!Element>}
 */
export function highlightRangesWithStyleClass(element, resultRanges, styleClass, changes) {
  changes = changes || [];
  const highlightNodes = [];
  const textNodes = element.childTextNodes();
  const lineText = textNodes
                       .map(function(node) {
                         return node.textContent;
                       })
                       .join('');
  const ownerDocument = element.ownerDocument;

  if (textNodes.length === 0) {
    return highlightNodes;
  }

  const nodeRanges = [];
  let rangeEndOffset = 0;
  for (let i = 0; i < textNodes.length; ++i) {
    const range = {};
    range.offset = rangeEndOffset;
    range.length = textNodes[i].textContent.length;
    rangeEndOffset = range.offset + range.length;
    nodeRanges.push(range);
  }

  let startIndex = 0;
  for (let i = 0; i < resultRanges.length; ++i) {
    const startOffset = resultRanges[i].offset;
    const endOffset = startOffset + resultRanges[i].length;

    while (startIndex < textNodes.length &&
           nodeRanges[startIndex].offset + nodeRanges[startIndex].length <= startOffset) {
      startIndex++;
    }
    let endIndex = startIndex;
    while (endIndex < textNodes.length && nodeRanges[endIndex].offset + nodeRanges[endIndex].length < endOffset) {
      endIndex++;
    }
    if (endIndex === textNodes.length) {
      break;
    }

    const highlightNode = ownerDocument.createElement('span');
    highlightNode.className = styleClass;
    highlightNode.textContent = lineText.substring(startOffset, endOffset);

    const lastTextNode = textNodes[endIndex];
    const lastText = lastTextNode.textContent;
    lastTextNode.textContent = lastText.substring(endOffset - nodeRanges[endIndex].offset);
    changes.push({node: lastTextNode, type: 'changed', oldText: lastText, newText: lastTextNode.textContent});

    if (startIndex === endIndex) {
      lastTextNode.parentElement.insertBefore(highlightNode, lastTextNode);
      changes.push({node: highlightNode, type: 'added', nextSibling: lastTextNode, parent: lastTextNode.parentElement});
      highlightNodes.push(highlightNode);

      const prefixNode =
          ownerDocument.createTextNode(lastText.substring(0, startOffset - nodeRanges[startIndex].offset));
      lastTextNode.parentElement.insertBefore(prefixNode, highlightNode);
      changes.push({node: prefixNode, type: 'added', nextSibling: highlightNode, parent: lastTextNode.parentElement});
    } else {
      const firstTextNode = textNodes[startIndex];
      const firstText = firstTextNode.textContent;
      const anchorElement = firstTextNode.nextSibling;

      firstTextNode.parentElement.insertBefore(highlightNode, anchorElement);
      changes.push(
          {node: highlightNode, type: 'added', nextSibling: anchorElement, parent: firstTextNode.parentElement});
      highlightNodes.push(highlightNode);

      firstTextNode.textContent = firstText.substring(0, startOffset - nodeRanges[startIndex].offset);
      changes.push({node: firstTextNode, type: 'changed', oldText: firstText, newText: firstTextNode.textContent});

      for (let j = startIndex + 1; j < endIndex; j++) {
        const textNode = textNodes[j];
        const text = textNode.textContent;
        textNode.textContent = '';
        changes.push({node: textNode, type: 'changed', oldText: text, newText: textNode.textContent});
      }
    }
    startIndex = endIndex;
    nodeRanges[startIndex].offset = endOffset;
    nodeRanges[startIndex].length = lastTextNode.textContent.length;
  }
  return highlightNodes;
}

export function applyDomChanges(domChanges) {
  for (let i = 0, size = domChanges.length; i < size; ++i) {
    const entry = domChanges[i];
    switch (entry.type) {
      case 'added':
        entry.parent.insertBefore(entry.node, entry.nextSibling);
        break;
      case 'changed':
        entry.node.textContent = entry.newText;
        break;
    }
  }
}

export function revertDomChanges(domChanges) {
  for (let i = domChanges.length - 1; i >= 0; --i) {
    const entry = domChanges[i];
    switch (entry.type) {
      case 'added':
        entry.node.remove();
        break;
      case 'changed':
        entry.node.textContent = entry.oldText;
        break;
    }
  }
}

/**
 * @param {!Element} element
 * @param {?Element=} containerElement
 * @return {!UI.Size}
 */
export function measurePreferredSize(element, containerElement) {
  const oldParent = element.parentElement;
  const oldNextSibling = element.nextSibling;
  containerElement = containerElement || element.ownerDocument.body;
  containerElement.appendChild(element);
  element.positionAt(0, 0);
  const result = element.getBoundingClientRect();

  element.positionAt(undefined, undefined);
  if (oldParent) {
    oldParent.insertBefore(element, oldNextSibling);
  } else {
    element.remove();
  }
  return new UI.Size(result.width, result.height);
}

/**
 * @unrestricted
 */
class InvokeOnceHandlers {
  /**
   * @param {boolean} autoInvoke
   */
  constructor(autoInvoke) {
    this._handlers = null;
    this._autoInvoke = autoInvoke;
  }

  /**
   * @param {!Object} object
   * @param {function()} method
   */
  add(object, method) {
    if (!this._handlers) {
      this._handlers = new Map();
      if (this._autoInvoke) {
        this.scheduleInvoke();
      }
    }
    let methods = this._handlers.get(object);
    if (!methods) {
      methods = new Set();
      this._handlers.set(object, methods);
    }
    methods.add(method);
  }

  /**
   * @suppressGlobalPropertiesCheck
   */
  scheduleInvoke() {
    if (this._handlers) {
      requestAnimationFrame(this._invoke.bind(this));
    }
  }

  _invoke() {
    const handlers = this._handlers;
    this._handlers = null;
    const keys = handlers.keysArray();
    for (let i = 0; i < keys.length; ++i) {
      const object = keys[i];
      const methods = handlers.get(object).valuesArray();
      for (let j = 0; j < methods.length; ++j) {
        methods[j].call(object);
      }
    }
  }
}

let _coalescingLevel = 0;
let _postUpdateHandlers = null;

export function startBatchUpdate() {
  if (!_coalescingLevel++) {
    _postUpdateHandlers = new InvokeOnceHandlers(false);
  }
}

export function endBatchUpdate() {
  if (--_coalescingLevel) {
    return;
  }
  _postUpdateHandlers.scheduleInvoke();
  _postUpdateHandlers = null;
}

/**
 * @param {!Object} object
 * @param {function()} method
 */
export function invokeOnceAfterBatchUpdate(object, method) {
  if (!_postUpdateHandlers) {
    _postUpdateHandlers = new InvokeOnceHandlers(true);
  }
  _postUpdateHandlers.add(object, method);
}

/**
 * @param {!Window} window
 * @param {!Function} func
 * @param {!Array.<{from:number, to:number}>} params
 * @param {number} duration
 * @param {function()=} animationComplete
 * @return {function()}
 */
export function animateFunction(window, func, params, duration, animationComplete) {
  const start = window.performance.now();
  let raf = window.requestAnimationFrame(animationStep);

  function animationStep(timestamp) {
    const progress = Number.constrain((timestamp - start) / duration, 0, 1);
    func(...params.map(p => p.from + (p.to - p.from) * progress));
    if (progress < 1) {
      raf = window.requestAnimationFrame(animationStep);
    } else if (animationComplete) {
      animationComplete();
    }
  }

  return () => window.cancelAnimationFrame(raf);
}

/**
 * @unrestricted
 */
export class LongClickController extends Common.Object {
  /**
   * @param {!Element} element
   * @param {function(!Event)} callback
   * @param {function(!Event)} isEditKeyFunc
   */
  constructor(element, callback, isEditKeyFunc = event => isEnterOrSpaceKey(event)) {
    super();
    this._element = element;
    this._callback = callback;
    this._editKey = isEditKeyFunc;
    this._enable();
  }

  reset() {
    if (this._longClickInterval) {
      clearInterval(this._longClickInterval);
      delete this._longClickInterval;
    }
  }

  _enable() {
    if (this._longClickData) {
      return;
    }
    const boundKeyDown = keyDown.bind(this);
    const boundKeyUp = keyUp.bind(this);
    const boundMouseDown = mouseDown.bind(this);
    const boundMouseUp = mouseUp.bind(this);
    const boundReset = this.reset.bind(this);


    this._element.addEventListener('keydown', boundKeyDown, false);
    this._element.addEventListener('keyup', boundKeyUp, false);
    this._element.addEventListener('mousedown', boundMouseDown, false);
    this._element.addEventListener('mouseout', boundReset, false);
    this._element.addEventListener('mouseup', boundMouseUp, false);
    this._element.addEventListener('click', boundReset, true);

    this._longClickData = {mouseUp: boundMouseUp, mouseDown: boundMouseDown, reset: boundReset};

    /**
     * @param {!Event} e
     * @this {LongClickController}
     */
    function keyDown(e) {
      if (this._editKey(e)) {
        e.consume(true);
        const callback = this._callback;
        this._longClickInterval = setTimeout(callback.bind(null, e), LongClickController.TIME_MS);
      }
    }

    /**
     * @param {!Event} e
     * @this {UI.LongClickController}
     */
    function keyUp(e) {
      if (this._editKey(e)) {
        e.consume(true);
        this.reset();
      }
    }

    /**
     * @param {!Event} e
     * @this {UI.LongClickController}
     */
    function mouseDown(e) {
      if (e.which !== 1) {
        return;
      }
      const callback = this._callback;
      this._longClickInterval = setTimeout(callback.bind(null, e), LongClickController.TIME_MS);
    }

    /**
     * @param {!Event} e
     * @this {LongClickController}
     */
    function mouseUp(e) {
      if (e.which !== 1) {
        return;
      }
      this.reset();
    }
  }

  dispose() {
    if (!this._longClickData) {
      return;
    }
    this._element.removeEventListener('mousedown', this._longClickData.mouseDown, false);
    this._element.removeEventListener('mouseout', this._longClickData.reset, false);
    this._element.removeEventListener('mouseup', this._longClickData.mouseUp, false);
    this._element.addEventListener('click', this._longClickData.reset, true);
    delete this._longClickData;
  }
}

LongClickController.TIME_MS = 200;

/**
 * @param {!Document} document
 * @param {!Common.Setting} themeSetting
 */
export function initializeUIUtils(document, themeSetting) {
  document.body.classList.toggle('inactive', !document.hasFocus());
  document.defaultView.addEventListener('focus', _windowFocused.bind(UI, document), false);
  document.defaultView.addEventListener('blur', _windowBlurred.bind(UI, document), false);
  document.addEventListener('focus', _focusChanged.bind(UI), true);
  document.addEventListener('keydown', event => {
    UI._keyboardFocus = true;
    document.defaultView.requestAnimationFrame(() => void(UI._keyboardFocus = false));
  }, true);

  if (!UI.themeSupport) {
    UI.themeSupport = new ThemeSupport(themeSetting);
  }
  UI.themeSupport.applyTheme(document);

  const body = /** @type {!Element} */ (document.body);
  appendStyle(body, 'ui/inspectorStyle.css');
  UI.GlassPane.setContainer(/** @type {!Element} */ (document.body));
}

/**
 * @param {string} name
 * @return {string}
 */
export function beautifyFunctionName(name) {
  return name || Common.UIString('(anonymous)');
}

/**
 * @param {string} localName
 * @param {string} typeExtension
 * @param {function(new:HTMLElement, *)} definition
 * @return {function()}
 * @suppressGlobalPropertiesCheck
 */
export function registerCustomElement(localName, typeExtension, definition) {
  self.customElements.define(typeExtension, class extends definition {
    constructor() {
      super();
      // TODO(einbinder) convert to classes and custom element tags
      this.setAttribute('is', typeExtension);
    }
  }, {extends: localName});
  return () => createElement(localName, typeExtension);
}

/**
 * @param {string} text
 * @param {function(!Event)=} clickHandler
 * @param {string=} className
 * @param {boolean=} primary
 * @return {!Element}
 */
export function createTextButton(text, clickHandler, className, primary) {
  const element = createElementWithClass('button', className || '');
  element.textContent = text;
  element.classList.add('text-button');
  if (primary) {
    element.classList.add('primary-button');
  }
  if (clickHandler) {
    element.addEventListener('click', clickHandler, false);
  }
  element.type = 'button';
  return element;
}

/**
 * @param {string=} className
 * @param {string=} type
 * @return {!Element}
 */
export function createInput(className, type) {
  const element = createElementWithClass('input', className || '');
  element.spellcheck = false;
  element.classList.add('harmony-input');
  if (type) {
    element.type = type;
  }
  return element;
}

/**
 * @param {string} title
 * @param {string=} className
 * @param {!Element=} associatedControl
 * @return {!Element}
 */
export function createLabel(title, className, associatedControl) {
  const element = createElementWithClass('label', className || '');
  element.textContent = title;
  if (associatedControl) {
    UI.ARIAUtils.bindLabelToControl(element, associatedControl);
  }

  return element;
}

/**
 * @param {string} name
 * @param {string} title
 * @param {boolean=} checked
 * @return {!Element}
 */
export function createRadioLabel(name, title, checked) {
  const element = createElement('span', 'dt-radio');
  element.radioElement.name = name;
  element.radioElement.checked = !!checked;
  element.labelElement.createTextChild(title);
  return element;
}

/**
 * @param {string} title
 * @param {string} iconClass
 * @return {!Element}
 */
export function createIconLabel(title, iconClass) {
  const element = createElement('span', 'dt-icon-label');
  element.createChild('span').textContent = title;
  element.type = iconClass;
  return element;
}

/**
 * @return {!Element}
 * @param {number} min
 * @param {number} max
 * @param {number} tabIndex
 */
export function createSlider(min, max, tabIndex) {
  const element = createElement('span', 'dt-slider');
  element.sliderElement.min = min;
  element.sliderElement.max = max;
  element.sliderElement.step = 1;
  element.sliderElement.tabIndex = tabIndex;
  return element;
}

/**
 * @param {!Node} node
 * @param {string} cssFile
 * @suppressGlobalPropertiesCheck
 */
export function appendStyle(node, cssFile) {
  const content = Root.Runtime.cachedResources[cssFile] || '';
  if (!content) {
    console.error(cssFile + ' not preloaded. Check module.json');
  }
  let styleElement = createElement('style');
  styleElement.textContent = content;
  node.appendChild(styleElement);

  const themeStyleSheet = UI.themeSupport.themeStyleSheet(cssFile, content);
  if (themeStyleSheet) {
    styleElement = createElement('style');
    styleElement.textContent = themeStyleSheet + '\n' + Root.Runtime.resolveSourceURL(cssFile + '.theme');
    node.appendChild(styleElement);
  }
}

export class CheckboxLabel extends HTMLSpanElement {
  constructor() {
    super();
    /** @type {!DocumentFragment} */
    this._shadowRoot;
    /** @type {!HTMLInputElement} */
    this.checkboxElement;
    /** @type {!Element} */
    this.textElement;
    CheckboxLabel._lastId = (CheckboxLabel._lastId || 0) + 1;
    const id = 'ui-checkbox-label' + CheckboxLabel._lastId;
    this._shadowRoot = createShadowRootWithCoreStyles(this, 'ui/checkboxTextLabel.css');
    this.checkboxElement = /** @type {!HTMLInputElement} */ (this._shadowRoot.createChild('input'));
    this.checkboxElement.type = 'checkbox';
    this.checkboxElement.setAttribute('id', id);
    this.textElement = this._shadowRoot.createChild('label', 'dt-checkbox-text');
    this.textElement.setAttribute('for', id);
    this._shadowRoot.createChild('slot');
  }

  /**
   * @param {string=} title
   * @param {boolean=} checked
   * @param {string=} subtitle
   * @return {!CheckboxLabel}
   */
  static create(title, checked, subtitle) {
    if (!CheckboxLabel._constructor) {
      CheckboxLabel._constructor = registerCustomElement('span', 'dt-checkbox', CheckboxLabel);
    }
    const element = /** @type {!CheckboxLabel} */ (CheckboxLabel._constructor());
    element.checkboxElement.checked = !!checked;
    if (title !== undefined) {
      element.textElement.textContent = title;
      if (subtitle !== undefined) {
        element.textElement.createChild('div', 'dt-checkbox-subtitle').textContent = subtitle;
      }
    }
    return element;
  }

  /**
   * @param {string} color
   * @this {Element}
   */
  set backgroundColor(color) {
    this.checkboxElement.classList.add('dt-checkbox-themed');
    this.checkboxElement.style.backgroundColor = color;
  }

  /**
   * @param {string} color
   * @this {Element}
   */
  set checkColor(color) {
    this.checkboxElement.classList.add('dt-checkbox-themed');
    const stylesheet = createElement('style');
    stylesheet.textContent = 'input.dt-checkbox-themed:checked:after { background-color: ' + color + '}';
    this._shadowRoot.appendChild(stylesheet);
  }

  /**
   * @param {string} color
   * @this {Element}
   */
  set borderColor(color) {
    this.checkboxElement.classList.add('dt-checkbox-themed');
    this.checkboxElement.style.borderColor = color;
  }
}

(function() {
let labelId = 0;
registerCustomElement('span', 'dt-radio', class extends HTMLSpanElement {
  constructor() {
    super();
    this.radioElement = this.createChild('input', 'dt-radio-button');
    this.labelElement = this.createChild('label');

    const id = 'dt-radio-button-id' + (++labelId);
    this.radioElement.id = id;
    this.radioElement.type = 'radio';
    this.labelElement.htmlFor = id;
    const root = createShadowRootWithCoreStyles(this, 'ui/radioButton.css');
    root.createChild('slot');
    this.addEventListener('click', radioClickHandler, false);
  }
});

/**
   * @param {!Event} event
   * @suppressReceiverCheck
   * @this {Element}
   */
function radioClickHandler(event) {
  if (this.radioElement.checked || this.radioElement.disabled) {
    return;
  }
  this.radioElement.checked = true;
  this.radioElement.dispatchEvent(new Event('change'));
}

registerCustomElement('span', 'dt-icon-label', class extends HTMLSpanElement {
  constructor() {
    super();
    const root = createShadowRootWithCoreStyles(this);
    this._iconElement = UI.Icon.create();
    this._iconElement.style.setProperty('margin-right', '4px');
    root.appendChild(this._iconElement);
    root.createChild('slot');
  }

  /**
     * @param {string} type
     * @this {Element}
     */
  set type(type) {
    this._iconElement.setIconType(type);
  }
});

registerCustomElement('span', 'dt-slider', class extends HTMLSpanElement {
  constructor() {
    super();
    const root = createShadowRootWithCoreStyles(this, 'ui/slider.css');
    this.sliderElement = createElementWithClass('input', 'dt-range-input');
    this.sliderElement.type = 'range';
    root.appendChild(this.sliderElement);
  }

  /**
     * @param {number} amount
     * @this {Element}
     */
  set value(amount) {
    this.sliderElement.value = amount;
  }

  /**
     * @this {Element}
     */
  get value() {
    return this.sliderElement.value;
  }
});

registerCustomElement('span', 'dt-small-bubble', class extends HTMLSpanElement {
  constructor() {
    super();
    const root = createShadowRootWithCoreStyles(this, 'ui/smallBubble.css');
    this._textElement = root.createChild('div');
    this._textElement.className = 'info';
    this._textElement.createChild('slot');
  }

  /**
     * @param {string} type
     * @this {Element}
     */
  set type(type) {
    this._textElement.className = type;
  }
});

registerCustomElement('div', 'dt-close-button', class extends HTMLDivElement {
  constructor() {
    super();
    const root = createShadowRootWithCoreStyles(this, 'ui/closeButton.css');
    this._buttonElement = root.createChild('div', 'close-button');
    UI.ARIAUtils.setAccessibleName(this._buttonElement, ls`Close`);
    UI.ARIAUtils.markAsButton(this._buttonElement);
    const regularIcon = UI.Icon.create('smallicon-cross', 'default-icon');
    this._hoverIcon = UI.Icon.create('mediumicon-red-cross-hover', 'hover-icon');
    this._activeIcon = UI.Icon.create('mediumicon-red-cross-active', 'active-icon');
    this._buttonElement.appendChild(regularIcon);
    this._buttonElement.appendChild(this._hoverIcon);
    this._buttonElement.appendChild(this._activeIcon);
  }

  /**
     * @param {boolean} gray
     * @this {Element}
     */
  set gray(gray) {
    if (gray) {
      this._hoverIcon.setIconType('mediumicon-gray-cross-hover');
      this._activeIcon.setIconType('mediumicon-gray-cross-active');
    } else {
      this._hoverIcon.setIconType('mediumicon-red-cross-hover');
      this._activeIcon.setIconType('mediumicon-red-cross-active');
    }
  }

  /**
   * @param {string} name
   * @this {Element}
   */
  setAccessibleName(name) {
    UI.ARIAUtils.setAccessibleName(this._buttonElement, name);
  }

  /**
   * @param {boolean} tabbable
   * @this {Element}
   */
  setTabbable(tabbable) {
    if (tabbable) {
      this._buttonElement.tabIndex = 0;
    } else {
      this._buttonElement.tabIndex = -1;
    }
  }
});
})();

/**
 * @param {!Element} input
 * @param {function(string)} apply
 * @param {function(string):{valid: boolean, errorMessage: (string|undefined)}} validate
 * @param {boolean} numeric
 * @param {number=} modifierMultiplier
 * @return {function(string)}
 */
export function bindInput(input, apply, validate, numeric, modifierMultiplier) {
  input.addEventListener('change', onChange, false);
  input.addEventListener('input', onInput, false);
  input.addEventListener('keydown', onKeyDown, false);
  input.addEventListener('focus', input.select.bind(input), false);

  function onInput() {
    input.classList.toggle('error-input', !validate(input.value));
  }

  function onChange() {
    const {valid} = validate(input.value);
    input.classList.toggle('error-input', !valid);
    if (valid) {
      apply(input.value);
    }
  }

  /**
   * @param {!Event} event
   */
  function onKeyDown(event) {
    if (isEnterKey(event)) {
      const {valid} = validate(input.value);
      if (valid) {
        apply(input.value);
      }
      event.preventDefault();
      return;
    }

    if (!numeric) {
      return;
    }

    const value = _modifiedFloatNumber(parseFloat(input.value), event, modifierMultiplier);
    const stringValue = value ? String(value) : '';
    const {valid} = validate(stringValue);
    if (!valid || !value) {
      return;
    }

    input.value = stringValue;
    apply(input.value);
    event.preventDefault();
  }

  /**
   * @param {string} value
   */
  function setValue(value) {
    if (value === input.value) {
      return;
    }
    const {valid} = validate(value);
    input.classList.toggle('error-input', !valid);
    input.value = value;
  }

  return setValue;
}

/**
 * @param {!CanvasRenderingContext2D} context
 * @param {string} text
 * @param {number} maxWidth
 * @param {function(string, number):string} trimFunction
 * @return {string}
 */
export function trimText(context, text, maxWidth, trimFunction) {
  const maxLength = 200;
  if (maxWidth <= 10) {
    return '';
  }
  if (text.length > maxLength) {
    text = trimFunction(text, maxLength);
  }
  const textWidth = measureTextWidth(context, text);
  if (textWidth <= maxWidth) {
    return text;
  }

  let l = 0;
  let r = text.length;
  let lv = 0;
  let rv = textWidth;
  while (l < r && lv !== rv && lv !== maxWidth) {
    const m = Math.ceil(l + (r - l) * (maxWidth - lv) / (rv - lv));
    const mv = measureTextWidth(context, trimFunction(text, m));
    if (mv <= maxWidth) {
      l = m;
      lv = mv;
    } else {
      r = m - 1;
      rv = mv;
    }
  }
  text = trimFunction(text, l);
  return text !== '\u2026' ? text : '';
}

/**
 * @param {!CanvasRenderingContext2D} context
 * @param {string} text
 * @param {number} maxWidth
 * @return {string}
 */
export function trimTextMiddle(context, text, maxWidth) {
  return trimText(context, text, maxWidth, (text, width) => text.trimMiddle(width));
}

/**
 * @param {!CanvasRenderingContext2D} context
 * @param {string} text
 * @param {number} maxWidth
 * @return {string}
 */
export function trimTextEnd(context, text, maxWidth) {
  return trimText(context, text, maxWidth, (text, width) => text.trimEndWithMaxLength(width));
}

/**
 * @param {!CanvasRenderingContext2D} context
 * @param {string} text
 * @return {number}
 */
export function measureTextWidth(context, text) {
  const maxCacheableLength = 200;
  if (text.length > maxCacheableLength) {
    return context.measureText(text).width;
  }

  let widthCache = measureTextWidth._textWidthCache;
  if (!widthCache) {
    widthCache = new Map();
    measureTextWidth._textWidthCache = widthCache;
  }
  const font = context.font;
  let textWidths = widthCache.get(font);
  if (!textWidths) {
    textWidths = new Map();
    widthCache.set(font, textWidths);
  }
  let width = textWidths.get(text);
  if (!width) {
    width = context.measureText(text).width;
    textWidths.set(text, width);
  }
  return width;
}

/**
 * @unrestricted
 */
export class ThemeSupport {
  /**
   * @param {!Common.Setting} setting
   */
  constructor(setting) {
    const systemPreferredTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'default';
    this._themeName = setting.get() === 'systemPreferred' ? systemPreferredTheme : setting.get();
    this._themableProperties = new Set([
      'color', 'box-shadow', 'text-shadow', 'outline-color', 'background-image', 'background-color',
      'border-left-color', 'border-right-color', 'border-top-color', 'border-bottom-color', '-webkit-border-image',
      'fill', 'stroke'
    ]);
    /** @type {!Map<string, string>} */
    this._cachedThemePatches = new Map();
    this._setting = setting;
    this._customSheets = new Set();
  }

  /**
   * @return {boolean}
   */
  hasTheme() {
    return this._themeName !== 'default';
  }

  /**
   * @return {string}
   */
  themeName() {
    return this._themeName;
  }

  /**
   * @param {!Element|!ShadowRoot} element
   */
  injectHighlightStyleSheets(element) {
    this._injectingStyleSheet = true;
    appendStyle(element, 'ui/inspectorSyntaxHighlight.css');
    if (this._themeName === 'dark') {
      appendStyle(element, 'ui/inspectorSyntaxHighlightDark.css');
    }
    this._injectingStyleSheet = false;
  }

   /**
   * @param {!Element|!ShadowRoot} element
   */
  injectCustomStyleSheets(element) {
    for (const sheet of this._customSheets){
      const styleElement = createElement('style');
      styleElement.textContent = sheet;
      element.appendChild(styleElement);
    }
  }

  /**
   * @param {string} sheetText
   */
  addCustomStylesheet(sheetText) {
    this._customSheets.add(sheetText);
  }

  /**
   * @param {!Document} document
   */
  applyTheme(document) {
    if (!this.hasTheme()) {
      return;
    }

    if (this._themeName === 'dark') {
      document.documentElement.classList.add('-theme-with-dark-background');
    }

    const styleSheets = document.styleSheets;
    const result = [];
    for (let i = 0; i < styleSheets.length; ++i) {
      result.push(this._patchForTheme(styleSheets[i].href, styleSheets[i]));
    }
    result.push('/*# sourceURL=inspector.css.theme */');

    const styleElement = createElement('style');
    styleElement.textContent = result.join('\n');
    document.head.appendChild(styleElement);
  }

  /**
   * @param {string} id
   * @param {string} text
   * @return {string}
   * @suppressGlobalPropertiesCheck
   */
  themeStyleSheet(id, text) {
    if (!this.hasTheme() || this._injectingStyleSheet) {
      return '';
    }

    let patch = this._cachedThemePatches.get(id);
    if (!patch) {
      const styleElement = createElement('style');
      styleElement.textContent = text;
      document.body.appendChild(styleElement);
      patch = this._patchForTheme(id, styleElement.sheet);
      document.body.removeChild(styleElement);
    }
    return patch;
  }

  /**
   * @param {string} id
   * @param {!StyleSheet} styleSheet
   * @return {string}
   */
  _patchForTheme(id, styleSheet) {
    const cached = this._cachedThemePatches.get(id);
    if (cached) {
      return cached;
    }

    try {
      const rules = styleSheet.cssRules;
      const result = [];
      for (let j = 0; j < rules.length; ++j) {
        if (rules[j] instanceof CSSImportRule) {
          result.push(this._patchForTheme(rules[j].styleSheet.href, rules[j].styleSheet));
          continue;
        }
        const output = [];
        const style = rules[j].style;
        const selectorText = rules[j].selectorText;
        for (let i = 0; style && i < style.length; ++i) {
          this._patchProperty(selectorText, style, style[i], output);
        }
        if (output.length) {
          result.push(rules[j].selectorText + '{' + output.join('') + '}');
        }
      }

      const fullText = result.join('\n');
      this._cachedThemePatches.set(id, fullText);
      return fullText;
    } catch (e) {
      this._setting.set('default');
      return '';
    }
  }

  /**
   * @param {string} selectorText
   * @param {!CSSStyleDeclaration} style
   * @param {string} name
   * @param {!Array<string>} output
   *
   * Theming API is primarily targeted at making dark theme look good.
   * - If rule has ".-theme-preserve" in selector, it won't be affected.
   * - One can create specializations for dark themes via body.-theme-with-dark-background selector in host context.
   */
  _patchProperty(selectorText, style, name, output) {
    if (!this._themableProperties.has(name)) {
      return;
    }

    const value = style.getPropertyValue(name);
    if (!value || value === 'none' || value === 'inherit' || value === 'initial' || value === 'transparent') {
      return;
    }
    if (name === 'background-image' && value.indexOf('gradient') === -1) {
      return;
    }

    if (selectorText.indexOf('-theme-') !== -1) {
      return;
    }

    let colorUsage = ThemeSupport.ColorUsage.Unknown;
    if (name.indexOf('background') === 0 || name.indexOf('border') === 0) {
      colorUsage |= ThemeSupport.ColorUsage.Background;
    }
    if (name.indexOf('background') === -1) {
      colorUsage |= ThemeSupport.ColorUsage.Foreground;
    }

    output.push(name);
    output.push(':');
    const items = value.replace(Common.Color.Regex, '\0$1\0').split('\0');
    for (let i = 0; i < items.length; ++i) {
      output.push(this.patchColorText(items[i], /** @type {!ThemeSupport.ColorUsage} */ (colorUsage)));
    }
    if (style.getPropertyPriority(name)) {
      output.push(' !important');
    }
    output.push(';');
  }

  /**
   * @param {string} text
   * @param {!ThemeSupport.ColorUsage} colorUsage
   * @return {string}
   */
  patchColorText(text, colorUsage) {
    const color = Common.Color.parse(text);
    if (!color) {
      return text;
    }
    const outColor = this.patchColor(color, colorUsage);
    let outText = outColor.asString(null);
    if (!outText) {
      outText = outColor.asString(outColor.hasAlpha() ? Common.Color.Format.RGBA : Common.Color.Format.RGB);
    }
    return outText || text;
  }

  /**
   * @param {!Common.Color} color
   * @param {!ThemeSupport.ColorUsage} colorUsage
   * @return {!Common.Color}
   */
  patchColor(color, colorUsage) {
    const hsla = color.hsla();
    this._patchHSLA(hsla, colorUsage);
    const rgba = [];
    Common.Color.hsl2rgb(hsla, rgba);
    return new Common.Color(rgba, color.format());
  }

  /**
   * @param {!Array<number>} hsla
   * @param {!ThemeSupport.ColorUsage} colorUsage
   */
  _patchHSLA(hsla, colorUsage) {
    const hue = hsla[0];
    const sat = hsla[1];
    let lit = hsla[2];
    const alpha = hsla[3];

    switch (this._themeName) {
      case 'dark':
        const minCap = colorUsage & ThemeSupport.ColorUsage.Background ? 0.14 : 0;
        const maxCap = colorUsage & ThemeSupport.ColorUsage.Foreground ? 0.9 : 1;
        lit = 1 - lit;
        if (lit < minCap * 2) {
          lit = minCap + lit / 2;
        } else if (lit > 2 * maxCap - 1) {
          lit = maxCap - 1 / 2 + lit / 2;
        }

        break;
    }
    hsla[0] = Number.constrain(hue, 0, 1);
    hsla[1] = Number.constrain(sat, 0, 1);
    hsla[2] = Number.constrain(lit, 0, 1);
    hsla[3] = Number.constrain(alpha, 0, 1);
  }
}

/**
 * @enum {number}
 */
ThemeSupport.ColorUsage = {
  Unknown: 0,
  Foreground: 1 << 0,
  Background: 1 << 1,
};

/**
 * @param {string} article
 * @param {string} title
 * @return {!Element}
 */
export function createDocumentationLink(article, title) {
  return UI.XLink.create('https://developers.google.com/web/tools/chrome-devtools/' + article, title);
}

/**
 * @param {string} url
 * @return {!Promise<?Image>}
 */
export function loadImage(url) {
  return new Promise(fulfill => {
    const image = new Image();
    image.addEventListener('load', () => fulfill(image));
    image.addEventListener('error', () => fulfill(null));
    image.src = url;
  });
}

/**
 * @param {?string} data
 * @return {!Promise<?Image>}
 */
export function loadImageFromData(data) {
  return data ? loadImage('data:image/jpg;base64,' + data) : Promise.resolve(null);
}

/**
 * @param {function(!File)} callback
 * @return {!Node}
 */
export function createFileSelectorElement(callback) {
  const fileSelectorElement = createElement('input');
  fileSelectorElement.type = 'file';
  fileSelectorElement.style.display = 'none';
  fileSelectorElement.setAttribute('tabindex', -1);
  fileSelectorElement.onchange = onChange;
  function onChange(event) {
    callback(fileSelectorElement.files[0]);
  }
  return fileSelectorElement;
}

/**
 * @const
 * @type {number}
 */
export const MaxLengthForDisplayedURLs = 150;

export class MessageDialog {
  /**
   * @param {string} message
   * @param {!Document|!Element=} where
   * @return {!Promise}
   */
  static async show(message, where) {
    const dialog = new UI.Dialog();
    dialog.setSizeBehavior(UI.GlassPane.SizeBehavior.MeasureContent);
    dialog.setDimmed(true);
    const shadowRoot = createShadowRootWithCoreStyles(dialog.contentElement, 'ui/confirmDialog.css');
    const content = shadowRoot.createChild('div', 'widget');
    await new Promise(resolve => {
      const okButton = createTextButton(Common.UIString('OK'), resolve, '', true);
      content.createChild('div', 'message').createChild('span').textContent = message;
      content.createChild('div', 'button').appendChild(okButton);
      dialog.setOutsideClickCallback(event => {
        event.consume();
        resolve();
      });
      dialog.show(where);
      okButton.focus();
    });
    dialog.hide();
  }
}

export class ConfirmDialog {
  /**
   * @param {string} message
   * @param {!Document|!Element=} where
   * @return {!Promise<boolean>}
   */
  static async show(message, where) {
    const dialog = new UI.Dialog();
    dialog.setSizeBehavior(UI.GlassPane.SizeBehavior.MeasureContent);
    dialog.setDimmed(true);
    const shadowRoot = createShadowRootWithCoreStyles(dialog.contentElement, 'ui/confirmDialog.css');
    const content = shadowRoot.createChild('div', 'widget');
    content.createChild('div', 'message').createChild('span').textContent = message;
    const buttonsBar = content.createChild('div', 'button');
    const result = await new Promise(resolve => {
      buttonsBar.appendChild(createTextButton(Common.UIString('OK'), () => resolve(true), '', true));
      buttonsBar.appendChild(createTextButton(Common.UIString('Cancel'), () => resolve(false)));
      dialog.setOutsideClickCallback(event => {
        event.consume();
        resolve(false);
      });
      dialog.show(where);
    });
    dialog.hide();
    return result;
  }
}

/**
 * @param {!UI.ToolbarButton} toolbarButton
 * @return {!Element}
 */
export function createInlineButton(toolbarButton) {
  const element = createElement('span');
  const shadowRoot = createShadowRootWithCoreStyles(element, 'ui/inlineButton.css');
  element.classList.add('inline-button');
  const toolbar = new UI.Toolbar('');
  toolbar.appendToolbarItem(toolbarButton);
  shadowRoot.appendChild(toolbar.element);
  return element;
}

/**
 * @param {string} text
 * @param {number} maxLength
 * @return {!DocumentFragment}
 */
export function createExpandableText(text, maxLength) {
  const clickHandler = () => {
    if (expandElement.parentElement) {
      expandElement.parentElement.insertBefore(createTextNode(text.slice(maxLength)), expandElement);
    }
    expandElement.remove();
  };
  const fragment = createDocumentFragment();
  fragment.textContent = text.slice(0, maxLength);
  const expandElement = fragment.createChild('span');
  const totalBytes = Number.bytesToString(2 * text.length);
  if (text.length < 10000000) {
    expandElement.setAttribute('data-text', ls`Show more (${totalBytes})`);
    expandElement.classList.add('expandable-inline-button');
    expandElement.addEventListener('click', clickHandler);
    expandElement.addEventListener('keydown', event => {
      if (event.key === 'Enter' || event.key === ' ') {
        clickHandler();
      }
    });
    UI.ARIAUtils.markAsButton(expandElement);

  } else {
    expandElement.setAttribute('data-text', ls`long text was truncated (${totalBytes})`);
    expandElement.classList.add('undisplayable-text');
  }

  const copyButton = fragment.createChild('span', 'expandable-inline-button');
  copyButton.setAttribute('data-text', ls`Copy`);
  copyButton.addEventListener('click', () => {
    Host.InspectorFrontendHost.copyText(text);
  });
  copyButton.addEventListener('keydown', event => {
    if (event.key === 'Enter' || event.key === ' ') {
      Host.InspectorFrontendHost.copyText(text);
    }
  });
  UI.ARIAUtils.markAsButton(copyButton);
  return fragment;
}

/**
 * @interface
 */
export class Renderer {
  /**
   * @param {!Object} object
   * @param {!UI.Renderer.Options=} options
   * @return {!Promise<?{node: !Node, tree: ?UI.TreeOutline}>}
   */
  render(object, options) {
  }
}

/**
   * @param {!Object} object
   * @param {!UI.Renderer.Options=} options
   * @return {!Promise<?{node: !Node, tree: ?UI.TreeOutline}>}
   */
Renderer.render = async function(object, options) {
  if (!object) {
    throw new Error('Can\'t render ' + object);
  }
  const renderer = await self.runtime.extension(Renderer, object).instance();
  return renderer ? renderer.render(object, options || {}) : null;
};

/**
 * @param {number} timestamp
 * @param {boolean} full
 * @return {string}
 */
export function formatTimestamp(timestamp, full) {
  const date = new Date(timestamp);
  const yymmdd = date.getFullYear() + '-' + leadZero(date.getMonth() + 1, 2) + '-' + leadZero(date.getDate(), 2);
  const hhmmssfff = leadZero(date.getHours(), 2) + ':' + leadZero(date.getMinutes(), 2) + ':' +
      leadZero(date.getSeconds(), 2) + '.' + leadZero(date.getMilliseconds(), 3);
  return full ? (yymmdd + ' ' + hhmmssfff) : hhmmssfff;

  /**
   * @param {number} value
   * @param {number} length
   * @return {string}
   */
  function leadZero(value, length) {
    const valueString = String(value);
    return valueString.padStart(length, '0');
  }
}

/* Legacy exported object*/
self.UI = self.UI || {};

/* Legacy exported object*/
UI = UI || {};

/** @type {?ThemeSupport} */
UI.themeSupport;

UI.highlightedSearchResultClassName = highlightedSearchResultClassName;
UI.highlightedCurrentSearchResultClassName = highlightedCurrentSearchResultClassName;
UI.StyleValueDelimiters = StyleValueDelimiters;
UI.MaxLengthForDisplayedURLs = MaxLengthForDisplayedURLs;

/** @constructor */
UI.ElementFocusRestorer = ElementFocusRestorer;

/** @constructor */
UI.LongClickController = LongClickController;

/** @constructor */
UI.ThemeSupport = ThemeSupport;

/** @constructor */
UI.MessageDialog = MessageDialog;

/** @constructor */
UI.ConfirmDialog = ConfirmDialog;

/** @constructor */
UI.CheckboxLabel = CheckboxLabel;

/** @interface */
UI.Renderer = Renderer;

/** @typedef {!{title: (string|!Element|undefined), editable: (boolean|undefined) }} */
UI.Renderer.Options;

UI.installDragHandle = installDragHandle;
UI.elementDragStart = elementDragStart;
UI.isBeingEdited = isBeingEdited;
UI.isEditing = isEditing;
UI.markBeingEdited = markBeingEdited;
UI.createReplacementString = createReplacementString;
UI.handleElementValueModifications = handleElementValueModifications;
UI.formatLocalized = formatLocalized;
UI.openLinkExternallyLabel = openLinkExternallyLabel;
UI.copyLinkAddressLabel = copyLinkAddressLabel;
UI.anotherProfilerActiveLabel = anotherProfilerActiveLabel;
UI.asyncStackTraceLabel = asyncStackTraceLabel;
UI.installComponentRootStyles = installComponentRootStyles;
UI.measuredScrollbarWidth = measuredScrollbarWidth;
UI.createShadowRootWithCoreStyles = createShadowRootWithCoreStyles;
UI.highlightSearchResult = highlightSearchResult;
UI.highlightSearchResults = highlightSearchResults;
UI.runCSSAnimationOnce = runCSSAnimationOnce;
UI.highlightRangesWithStyleClass = highlightRangesWithStyleClass;
UI.applyDomChanges = applyDomChanges;
UI.revertDomChanges = revertDomChanges;
UI.measurePreferredSize = measurePreferredSize;
UI.startBatchUpdate = startBatchUpdate;
UI.endBatchUpdate = endBatchUpdate;
UI.invokeOnceAfterBatchUpdate = invokeOnceAfterBatchUpdate;
UI.animateFunction = animateFunction;
UI.initializeUIUtils = initializeUIUtils;
UI.beautifyFunctionName = beautifyFunctionName;
UI.registerCustomElement = registerCustomElement;
UI.createTextButton = createTextButton;
UI.createInput = createInput;
UI.createLabel = createLabel;
UI.createRadioLabel = createRadioLabel;
UI.createIconLabel = createIconLabel;
UI.createSlider = createSlider;
UI.appendStyle = appendStyle;
UI.bindInput = bindInput;
UI.trimText = trimText;
UI.trimTextMiddle = trimTextMiddle;
UI.trimTextEnd = trimTextEnd;
UI.measureTextWidth = measureTextWidth;
UI.createDocumentationLink = createDocumentationLink;
UI.loadImage = loadImage;
UI.loadImageFromData = loadImageFromData;
UI.createFileSelectorElement = createFileSelectorElement;
UI.createInlineButton = createInlineButton;
UI.createExpandableText = createExpandableText;
UI.formatTimestamp = formatTimestamp;
