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

export default class DOMDebuggerModel extends SDK.SDKModel {
  /**
   * @param {!SDK.Target} target
   */
  constructor(target) {
    super(target);
    this._agent = target.domdebuggerAgent();
    this._runtimeModel = /** @type {!SDK.RuntimeModel} */ (target.model(SDK.RuntimeModel));
    this._domModel = /** @type {!SDK.DOMModel} */ (target.model(SDK.DOMModel));
    this._domModel.addEventListener(SDK.DOMModel.Events.DocumentUpdated, this._documentUpdated, this);
    this._domModel.addEventListener(SDK.DOMModel.Events.NodeRemoved, this._nodeRemoved, this);

    /** @type {!Array<!DOMBreakpoint>} */
    this._domBreakpoints = [];
    this._domBreakpointsSetting = Common.settings.createLocalSetting('domBreakpoints', []);
    if (this._domModel.existingDocument()) {
      this._documentUpdated();
    }
  }

  /**
   * @return {!SDK.RuntimeModel}
   */
  runtimeModel() {
    return this._runtimeModel;
  }

  /**
   * @param {!SDK.RemoteObject} remoteObject
   * @return {!Promise<!Array<!SDK.EventListener>>}
   */
  async eventListeners(remoteObject) {
    console.assert(remoteObject.runtimeModel() === this._runtimeModel);
    if (!remoteObject.objectId) {
      return [];
    }

    const payloads = await this._agent.getEventListeners(/** @type {string} */ (remoteObject.objectId));
    const eventListeners = [];
    for (const payload of payloads || []) {
      const location = this._runtimeModel.debuggerModel().createRawLocationByScriptId(
          payload.scriptId, payload.lineNumber, payload.columnNumber);
      if (!location) {
        continue;
      }
      eventListeners.push(new SDK.EventListener(
          this, remoteObject, payload.type, payload.useCapture, payload.passive, payload.once,
          payload.handler ? this._runtimeModel.createRemoteObject(payload.handler) : null,
          payload.originalHandler ? this._runtimeModel.createRemoteObject(payload.originalHandler) : null, location,
          null));
    }
    return eventListeners;
  }

  retrieveDOMBreakpoints() {
    this._domModel.requestDocument();
  }

  /**
   * @return {!Array<!DOMBreakpoint>}
   */
  domBreakpoints() {
    return this._domBreakpoints.slice();
  }

  /**
   * @param {!SDK.DOMNode} node
   * @param {!SDK.DOMDebuggerModel.DOMBreakpoint.Type} type
   * @return {boolean}
   */
  hasDOMBreakpoint(node, type) {
    return this._domBreakpoints.some(breakpoint => (breakpoint.node === node && breakpoint.type === type));
  }

  /**
   * @param {!SDK.DOMNode} node
   * @param {!SDK.DOMDebuggerModel.DOMBreakpoint.Type} type
   * @return {!DOMBreakpoint}
   */
  setDOMBreakpoint(node, type) {
    for (const breakpoint of this._domBreakpoints) {
      if (breakpoint.node === node && breakpoint.type === type) {
        this.toggleDOMBreakpoint(breakpoint, true);
        return breakpoint;
      }
    }
    const breakpoint = new DOMBreakpoint(this, node, type, true);
    this._domBreakpoints.push(breakpoint);
    this._saveDOMBreakpoints();
    this._enableDOMBreakpoint(breakpoint);
    this.dispatchEventToListeners(Events.DOMBreakpointAdded, breakpoint);
    return breakpoint;
  }

  /**
   * @param {!SDK.DOMNode} node
   * @param {!SDK.DOMDebuggerModel.DOMBreakpoint.Type} type
   */
  removeDOMBreakpoint(node, type) {
    this._removeDOMBreakpoints(breakpoint => breakpoint.node === node && breakpoint.type === type);
  }

  removeAllDOMBreakpoints() {
    this._removeDOMBreakpoints(breakpoint => true);
  }

  /**
   * @param {!DOMBreakpoint} breakpoint
   * @param {boolean} enabled
   */
  toggleDOMBreakpoint(breakpoint, enabled) {
    if (enabled === breakpoint.enabled) {
      return;
    }
    breakpoint.enabled = enabled;
    if (enabled) {
      this._enableDOMBreakpoint(breakpoint);
    } else {
      this._disableDOMBreakpoint(breakpoint);
    }
    this.dispatchEventToListeners(Events.DOMBreakpointToggled, breakpoint);
  }

  /**
   * @param {!DOMBreakpoint} breakpoint
   */
  _enableDOMBreakpoint(breakpoint) {
    this._agent.setDOMBreakpoint(breakpoint.node.id, breakpoint.type);
    breakpoint.node.setMarker(Marker, true);
  }

  /**
   * @param {!DOMBreakpoint} breakpoint
   */
  _disableDOMBreakpoint(breakpoint) {
    this._agent.removeDOMBreakpoint(breakpoint.node.id, breakpoint.type);
    breakpoint.node.setMarker(Marker, this._nodeHasBreakpoints(breakpoint.node) ? true : null);
  }

  /**
   * @param {!SDK.DOMNode} node
   * @return {boolean}
   */
  _nodeHasBreakpoints(node) {
    for (const breakpoint of this._domBreakpoints) {
      if (breakpoint.node === node && breakpoint.enabled) {
        return true;
      }
    }
    return false;
  }

  /**
   * @param {!Object} auxData
   * @return {?{type: !SDK.DOMDebuggerModel.DOMBreakpoint.Type, node: !SDK.DOMNode, targetNode: ?SDK.DOMNode, insertion: boolean}}
   */
  resolveDOMBreakpointData(auxData) {
    const type = auxData['type'];
    const node = this._domModel.nodeForId(auxData['nodeId']);
    if (!type || !node) {
      return null;
    }
    let targetNode = null;
    let insertion = false;
    if (type === SDK.DOMDebuggerModel.DOMBreakpoint.Type.SubtreeModified) {
      insertion = auxData['insertion'] || false;
      targetNode = this._domModel.nodeForId(auxData['targetNodeId']);
    }
    return {type: type, node: node, targetNode: targetNode, insertion: insertion};
  }

  /**
   * @return {string}
   */
  _currentURL() {
    const domDocument = this._domModel.existingDocument();
    return domDocument ? domDocument.documentURL : '';
  }

  _documentUpdated() {
    const removed = this._domBreakpoints;
    this._domBreakpoints = [];
    this.dispatchEventToListeners(Events.DOMBreakpointsRemoved, removed);

    const currentURL = this._currentURL();
    for (const breakpoint of this._domBreakpointsSetting.get()) {
      if (breakpoint.url === currentURL) {
        this._domModel.pushNodeByPathToFrontend(breakpoint.path).then(appendBreakpoint.bind(this, breakpoint));
      }
    }

    /**
     * @param {!{type: !SDK.DOMDebuggerModel.DOMBreakpoint.Type, enabled: boolean}} breakpoint
     * @param {?number} nodeId
     * @this {DOMDebuggerModel}
     */
    function appendBreakpoint(breakpoint, nodeId) {
      const node = nodeId ? this._domModel.nodeForId(nodeId) : null;
      if (!node) {
        return;
      }
      const domBreakpoint = new DOMBreakpoint(this, node, breakpoint.type, breakpoint.enabled);
      this._domBreakpoints.push(domBreakpoint);
      if (breakpoint.enabled) {
        this._enableDOMBreakpoint(domBreakpoint);
      }
      this.dispatchEventToListeners(Events.DOMBreakpointAdded, domBreakpoint);
    }
  }

  /**
   * @param {function(!DOMBreakpoint):boolean} filter
   */
  _removeDOMBreakpoints(filter) {
    const removed = [];
    const left = [];
    for (const breakpoint of this._domBreakpoints) {
      if (filter(breakpoint)) {
        removed.push(breakpoint);
        if (breakpoint.enabled) {
          breakpoint.enabled = false;
          this._disableDOMBreakpoint(breakpoint);
        }
      } else {
        left.push(breakpoint);
      }
    }

    if (!removed.length) {
      return;
    }
    this._domBreakpoints = left;
    this._saveDOMBreakpoints();
    this.dispatchEventToListeners(Events.DOMBreakpointsRemoved, removed);
  }

  /**
   * @param {!Common.Event} event
   */
  _nodeRemoved(event) {
    const node = /** @type {!SDK.DOMNode} */ (event.data.node);
    const children = node.children() || [];
    this._removeDOMBreakpoints(breakpoint => breakpoint.node === node || children.indexOf(breakpoint.node) !== -1);
  }

  _saveDOMBreakpoints() {
    const currentURL = this._currentURL();
    const breakpoints = this._domBreakpointsSetting.get().filter(breakpoint => breakpoint.url !== currentURL);
    for (const breakpoint of this._domBreakpoints) {
      breakpoints.push(
          {url: currentURL, path: breakpoint.node.path(), type: breakpoint.type, enabled: breakpoint.enabled});
    }
    this._domBreakpointsSetting.set(breakpoints);
  }
}

/** @enum {symbol} */
export const Events = {
  DOMBreakpointAdded: Symbol('DOMBreakpointAdded'),
  DOMBreakpointToggled: Symbol('DOMBreakpointToggled'),
  DOMBreakpointsRemoved: Symbol('DOMBreakpointsRemoved'),
};

const Marker = 'breakpoint-marker';

export class DOMBreakpoint {
  /**
   * @param {!DOMDebuggerModel} domDebuggerModel
   * @param {!SDK.DOMNode} node
   * @param {!SDK.DOMDebuggerModel.DOMBreakpoint.Type} type
   * @param {boolean} enabled
   */
  constructor(domDebuggerModel, node, type, enabled) {
    this.domDebuggerModel = domDebuggerModel;
    this.node = node;
    this.type = type;
    this.enabled = enabled;
  }
}

export class EventListener {
  /**
   * @param {!DOMDebuggerModel} domDebuggerModel
   * @param {!SDK.RemoteObject} eventTarget
   * @param {string} type
   * @param {boolean} useCapture
   * @param {boolean} passive
   * @param {boolean} once
   * @param {?SDK.RemoteObject} handler
   * @param {?SDK.RemoteObject} originalHandler
   * @param {!SDK.DebuggerModel.Location} location
   * @param {?SDK.RemoteObject} customRemoveFunction
   * @param {!EventListener.Origin=} origin
   */
  constructor(
      domDebuggerModel, eventTarget, type, useCapture, passive, once, handler, originalHandler, location,
      customRemoveFunction, origin) {
    this._domDebuggerModel = domDebuggerModel;
    this._eventTarget = eventTarget;
    this._type = type;
    this._useCapture = useCapture;
    this._passive = passive;
    this._once = once;
    this._handler = handler;
    this._originalHandler = originalHandler || handler;
    this._location = location;
    const script = location.script();
    this._sourceURL = script ? script.contentURL() : '';
    this._customRemoveFunction = customRemoveFunction;
    this._origin = origin || EventListener.Origin.Raw;
  }

  /**
   * @return {!DOMDebuggerModel}
   */
  domDebuggerModel() {
    return this._domDebuggerModel;
  }

  /**
   * @return {string}
   */
  type() {
    return this._type;
  }

  /**
   * @return {boolean}
   */
  useCapture() {
    return this._useCapture;
  }

  /**
   * @return {boolean}
   */
  passive() {
    return this._passive;
  }

  /**
   * @return {boolean}
   */
  once() {
    return this._once;
  }

  /**
   * @return {?SDK.RemoteObject}
   */
  handler() {
    return this._handler;
  }

  /**
   * @return {!SDK.DebuggerModel.Location}
   */
  location() {
    return this._location;
  }

  /**
   * @return {string}
   */
  sourceURL() {
    return this._sourceURL;
  }

  /**
   * @return {?SDK.RemoteObject}
   */
  originalHandler() {
    return this._originalHandler;
  }

  /**
   * @return {boolean}
   */
  canRemove() {
    return !!this._customRemoveFunction || this._origin !== EventListener.Origin.FrameworkUser;
  }

  /**
   * @return {!Promise<undefined>}
   */
  remove() {
    if (!this.canRemove()) {
      return Promise.resolve();
    }

    if (this._origin !== EventListener.Origin.FrameworkUser) {
      /**
       * @param {string} type
       * @param {function()} listener
       * @param {boolean} useCapture
       * @this {Object}
       * @suppressReceiverCheck
       */
      function removeListener(type, listener, useCapture) {
        this.removeEventListener(type, listener, useCapture);
        if (this['on' + type]) {
          this['on' + type] = undefined;
        }
      }

      return /** @type {!Promise<undefined>} */ (this._eventTarget.callFunction(removeListener, [
        SDK.RemoteObject.toCallArgument(this._type), SDK.RemoteObject.toCallArgument(this._originalHandler),
        SDK.RemoteObject.toCallArgument(this._useCapture)
      ]));
    }

    return this._customRemoveFunction
        .callFunction(
            callCustomRemove,
            [
              SDK.RemoteObject.toCallArgument(this._type),
              SDK.RemoteObject.toCallArgument(this._originalHandler),
              SDK.RemoteObject.toCallArgument(this._useCapture),
              SDK.RemoteObject.toCallArgument(this._passive),
            ])
        .then(() => undefined);

    /**
     * @param {string} type
     * @param {function()} listener
     * @param {boolean} useCapture
     * @param {boolean} passive
     * @this {Function}
     * @suppressReceiverCheck
     */
    function callCustomRemove(type, listener, useCapture, passive) {
      this.call(null, type, listener, useCapture, passive);
    }
  }

  /**
   * @return {boolean}
   */
  canTogglePassive() {
    return this._origin !== EventListener.Origin.FrameworkUser;
  }

  /**
   * @return {!Promise<undefined>}
   */
  togglePassive() {
    return /** @type {!Promise<undefined>} */ (this._eventTarget.callFunction(callTogglePassive, [
      SDK.RemoteObject.toCallArgument(this._type),
      SDK.RemoteObject.toCallArgument(this._originalHandler),
      SDK.RemoteObject.toCallArgument(this._useCapture),
      SDK.RemoteObject.toCallArgument(this._passive),
    ]));

    /**
     * @param {string} type
     * @param {function()} listener
     * @param {boolean} useCapture
     * @param {boolean} passive
     * @this {Object}
     * @suppressReceiverCheck
     */
    function callTogglePassive(type, listener, useCapture, passive) {
      this.removeEventListener(type, listener, {capture: useCapture});
      this.addEventListener(type, listener, {capture: useCapture, passive: !passive});
    }
  }

  /**
   * @return {!EventListener.Origin}
   */
  origin() {
    return this._origin;
  }

  markAsFramework() {
    this._origin = EventListener.Origin.Framework;
  }

  /**
   * @return {boolean}
   */
  isScrollBlockingType() {
    return this._type === 'touchstart' || this._type === 'touchmove' || this._type === 'mousewheel' ||
        this._type === 'wheel';
  }
}

/** @enum {string} */
EventListener.Origin = {
  Raw: 'Raw',
  Framework: 'Framework',
  FrameworkUser: 'FrameworkUser'
};

export class EventListenerBreakpoint {
  /**
   * @param {string} instrumentationName
   * @param {string} eventName
   * @param {!Array<string>} eventTargetNames
   * @param {string} category
   * @param {string} title
   */
  constructor(instrumentationName, eventName, eventTargetNames, category, title) {
    this._instrumentationName = instrumentationName;
    this._eventName = eventName;
    this._eventTargetNames = eventTargetNames;
    this._category = category;
    this._title = title;
    this._enabled = false;
  }

  /**
   * @return {string}
   */
  category() {
    return this._category;
  }

  /**
   * @return {boolean}
   */
  enabled() {
    return this._enabled;
  }

  /**
   * @param {boolean} enabled
   */
  setEnabled(enabled) {
    if (this._enabled === enabled) {
      return;
    }
    this._enabled = enabled;
    for (const model of SDK.targetManager.models(DOMDebuggerModel)) {
      this._updateOnModel(model);
    }
  }

  /**
   * @param {!DOMDebuggerModel} model
   */
  _updateOnModel(model) {
    if (this._instrumentationName) {
      if (this._enabled) {
        model._agent.setInstrumentationBreakpoint(this._instrumentationName);
      } else {
        model._agent.removeInstrumentationBreakpoint(this._instrumentationName);
      }
    } else {
      for (const eventTargetName of this._eventTargetNames) {
        if (this._enabled) {
          model._agent.setEventListenerBreakpoint(this._eventName, eventTargetName);
        } else {
          model._agent.removeEventListenerBreakpoint(this._eventName, eventTargetName);
        }
      }
    }
  }

  /**
   * @return {string}
   */
  title() {
    return this._title;
  }
}

EventListenerBreakpoint._listener = 'listener:';
EventListenerBreakpoint._instrumentation = 'instrumentation:';

/**
 * @implements {SDK.SDKModelObserver<!DOMDebuggerModel>}
 */
export class DOMDebuggerManager {
  constructor() {
    this._xhrBreakpointsSetting = Common.settings.createLocalSetting('xhrBreakpoints', []);
    /** @type {!Map<string, boolean>} */
    this._xhrBreakpoints = new Map();
    for (const breakpoint of this._xhrBreakpointsSetting.get()) {
      this._xhrBreakpoints.set(breakpoint.url, breakpoint.enabled);
    }

    /** @type {!Array<!EventListenerBreakpoint>} */
    this._eventListenerBreakpoints = [];
    this._createInstrumentationBreakpoints(
        Common.UIString('Animation'),
        ['requestAnimationFrame', 'cancelAnimationFrame', 'requestAnimationFrame.callback']);
    this._createInstrumentationBreakpoints(
        Common.UIString('Canvas'), ['canvasContextCreated', 'webglErrorFired', 'webglWarningFired']);
    this._createInstrumentationBreakpoints(
        Common.UIString('Geolocation'), ['Geolocation.getCurrentPosition', 'Geolocation.watchPosition']);
    this._createInstrumentationBreakpoints(Common.UIString('Notification'), ['Notification.requestPermission']);
    this._createInstrumentationBreakpoints(Common.UIString('Parse'), ['Element.setInnerHTML', 'Document.write']);
    this._createInstrumentationBreakpoints(Common.UIString('Script'), ['scriptFirstStatement', 'scriptBlockedByCSP']);
    this._createInstrumentationBreakpoints(
        Common.UIString('Timer'),
        ['setTimeout', 'clearTimeout', 'setInterval', 'clearInterval', 'setTimeout.callback', 'setInterval.callback']);
    this._createInstrumentationBreakpoints(Common.UIString('Window'), ['DOMWindow.close']);
    this._createInstrumentationBreakpoints(
        Common.UIString('WebAudio'),
        ['audioContextCreated', 'audioContextClosed', 'audioContextResumed', 'audioContextSuspended']);

    this._createEventListenerBreakpoints(
        Common.UIString('Media'),
        [
          'play',      'pause',          'playing',    'canplay',    'canplaythrough', 'seeking',
          'seeked',    'timeupdate',     'ended',      'ratechange', 'durationchange', 'volumechange',
          'loadstart', 'progress',       'suspend',    'abort',      'error',          'emptied',
          'stalled',   'loadedmetadata', 'loadeddata', 'waiting'
        ],
        ['audio', 'video']);
    this._createEventListenerBreakpoints(
        Common.UIString('Picture-in-Picture'), ['enterpictureinpicture', 'leavepictureinpicture'], ['video']);
    this._createEventListenerBreakpoints(Common.UIString('Picture-in-Picture'), ['resize'], ['PictureInPictureWindow']);
    this._createEventListenerBreakpoints(
        Common.UIString('Clipboard'), ['copy', 'cut', 'paste', 'beforecopy', 'beforecut', 'beforepaste'], ['*']);
    this._createEventListenerBreakpoints(
        Common.UIString('Control'),
        ['resize', 'scroll', 'zoom', 'focus', 'blur', 'select', 'change', 'submit', 'reset'], ['*']);
    this._createEventListenerBreakpoints(Common.UIString('Device'), ['deviceorientation', 'devicemotion'], ['*']);
    this._createEventListenerBreakpoints(
        Common.UIString('DOM Mutation'),
        [
          'DOMActivate', 'DOMFocusIn', 'DOMFocusOut', 'DOMAttrModified', 'DOMCharacterDataModified', 'DOMNodeInserted',
          'DOMNodeInsertedIntoDocument', 'DOMNodeRemoved', 'DOMNodeRemovedFromDocument', 'DOMSubtreeModified',
          'DOMContentLoaded'
        ],
        ['*']);
    this._createEventListenerBreakpoints(
        Common.UIString('Drag / drop'), ['drag', 'dragstart', 'dragend', 'dragenter', 'dragover', 'dragleave', 'drop'],
        ['*']);

    this._createEventListenerBreakpoints(Common.UIString('Keyboard'), ['keydown', 'keyup', 'keypress', 'input'], ['*']);
    this._createEventListenerBreakpoints(
        Common.UIString('Load'), ['load', 'beforeunload', 'unload', 'abort', 'error', 'hashchange', 'popstate'], ['*']);
    this._createEventListenerBreakpoints(
        Common.UIString('Mouse'),
        [
          'auxclick', 'click', 'dblclick', 'mousedown', 'mouseup', 'mouseover', 'mousemove', 'mouseout', 'mouseenter',
          'mouseleave', 'mousewheel', 'wheel', 'contextmenu'
        ],
        ['*']);
    this._createEventListenerBreakpoints(
        Common.UIString('Pointer'),
        [
          'pointerover', 'pointerout', 'pointerenter', 'pointerleave', 'pointerdown', 'pointerup', 'pointermove',
          'pointercancel', 'gotpointercapture', 'lostpointercapture'
        ],
        ['*']);
    this._createEventListenerBreakpoints(
        Common.UIString('Touch'), ['touchstart', 'touchmove', 'touchend', 'touchcancel'], ['*']);
    this._createEventListenerBreakpoints(Common.UIString('Worker'), ['message', 'messageerror'], ['*']);
    this._createEventListenerBreakpoints(
        Common.UIString('XHR'),
        ['readystatechange', 'load', 'loadstart', 'loadend', 'abort', 'error', 'progress', 'timeout'],
        ['xmlhttprequest', 'xmlhttprequestupload']);

    this._resolveEventListenerBreakpoint('instrumentation:setTimeout.callback')._title =
        Common.UIString('setTimeout fired');
    this._resolveEventListenerBreakpoint('instrumentation:setInterval.callback')._title =
        Common.UIString('setInterval fired');
    this._resolveEventListenerBreakpoint('instrumentation:scriptFirstStatement')._title =
        Common.UIString('Script First Statement');
    this._resolveEventListenerBreakpoint('instrumentation:scriptBlockedByCSP')._title =
        Common.UIString('Script Blocked by Content Security Policy');
    this._resolveEventListenerBreakpoint('instrumentation:requestAnimationFrame')._title =
        Common.UIString('Request Animation Frame');
    this._resolveEventListenerBreakpoint('instrumentation:cancelAnimationFrame')._title =
        Common.UIString('Cancel Animation Frame');
    this._resolveEventListenerBreakpoint('instrumentation:requestAnimationFrame.callback')._title =
        Common.UIString('Animation Frame Fired');
    this._resolveEventListenerBreakpoint('instrumentation:webglErrorFired')._title =
        Common.UIString('WebGL Error Fired');
    this._resolveEventListenerBreakpoint('instrumentation:webglWarningFired')._title =
        Common.UIString('WebGL Warning Fired');
    this._resolveEventListenerBreakpoint('instrumentation:Element.setInnerHTML')._title =
        Common.UIString('Set innerHTML');
    this._resolveEventListenerBreakpoint('instrumentation:canvasContextCreated')._title =
        Common.UIString('Create canvas context');
    this._resolveEventListenerBreakpoint('instrumentation:Geolocation.getCurrentPosition')._title =
        'getCurrentPosition';
    this._resolveEventListenerBreakpoint('instrumentation:Geolocation.watchPosition')._title = 'watchPosition';
    this._resolveEventListenerBreakpoint('instrumentation:Notification.requestPermission')._title = 'requestPermission';
    this._resolveEventListenerBreakpoint('instrumentation:DOMWindow.close')._title = 'window.close';
    this._resolveEventListenerBreakpoint('instrumentation:Document.write')._title = 'document.write';
    this._resolveEventListenerBreakpoint('instrumentation:audioContextCreated')._title =
        Common.UIString('Create AudioContext');
    this._resolveEventListenerBreakpoint('instrumentation:audioContextClosed')._title =
        Common.UIString('Close AudioContext');
    this._resolveEventListenerBreakpoint('instrumentation:audioContextResumed')._title =
        Common.UIString('Resume AudioContext');
    this._resolveEventListenerBreakpoint('instrumentation:audioContextSuspended')._title =
        Common.UIString('Suspend AudioContext');

    SDK.targetManager.observeModels(SDK.DOMDebuggerModel, this);
  }

  /**
   * @param {string} category
   * @param {!Array<string>} instrumentationNames
   */
  _createInstrumentationBreakpoints(category, instrumentationNames) {
    for (const instrumentationName of instrumentationNames) {
      this._eventListenerBreakpoints.push(
          new EventListenerBreakpoint(instrumentationName, '', [], category, instrumentationName));
    }
  }

  /**
   * @param {string} category
   * @param {!Array<string>} eventNames
   * @param {!Array<string>} eventTargetNames
   */
  _createEventListenerBreakpoints(category, eventNames, eventTargetNames) {
    for (const eventName of eventNames) {
      this._eventListenerBreakpoints.push(
          new EventListenerBreakpoint('', eventName, eventTargetNames, category, eventName));
    }
  }

  /**
   * @param {string} eventName
   * @param {string=} eventTargetName
   * @return {?EventListenerBreakpoint}
   */
  _resolveEventListenerBreakpoint(eventName, eventTargetName) {
    const instrumentationPrefix = 'instrumentation:';
    const listenerPrefix = 'listener:';
    let instrumentationName = '';
    if (eventName.startsWith(instrumentationPrefix)) {
      instrumentationName = eventName.substring(instrumentationPrefix.length);
      eventName = '';
    } else if (eventName.startsWith(listenerPrefix)) {
      eventName = eventName.substring(listenerPrefix.length);
    } else {
      return null;
    }
    eventTargetName = (eventTargetName || '*').toLowerCase();
    let result = null;
    for (const breakpoint of this._eventListenerBreakpoints) {
      if (instrumentationName && breakpoint._instrumentationName === instrumentationName) {
        result = breakpoint;
      }
      if (eventName && breakpoint._eventName === eventName &&
          breakpoint._eventTargetNames.indexOf(eventTargetName) !== -1) {
        result = breakpoint;
      }
      if (!result && eventName && breakpoint._eventName === eventName &&
          breakpoint._eventTargetNames.indexOf('*') !== -1) {
        result = breakpoint;
      }
    }
    return result;
  }

  /**
   * @return {!Array<!EventListenerBreakpoint>}
   */
  eventListenerBreakpoints() {
    return this._eventListenerBreakpoints.slice();
  }

  /**
   * @param {!Object} auxData
   * @return {string}
   */
  resolveEventListenerBreakpointTitle(auxData) {
    const id = auxData['eventName'];
    if (id === 'instrumentation:webglErrorFired' && auxData['webglErrorName']) {
      let errorName = auxData['webglErrorName'];
      // If there is a hex code of the error, display only this.
      errorName = errorName.replace(/^.*(0x[0-9a-f]+).*$/i, '$1');
      return Common.UIString('WebGL Error Fired (%s)', errorName);
    }
    if (id === 'instrumentation:scriptBlockedByCSP' && auxData['directiveText']) {
      return Common.UIString('Script blocked due to Content Security Policy directive: %s', auxData['directiveText']);
    }
    const breakpoint = this._resolveEventListenerBreakpoint(id, auxData['targetName']);
    if (!breakpoint) {
      return '';
    }
    if (auxData['targetName']) {
      return auxData['targetName'] + '.' + breakpoint._title;
    }
    return breakpoint._title;
  }

  /**
   * @param {!Object} auxData
   * @return {?EventListenerBreakpoint}
   */
  resolveEventListenerBreakpoint(auxData) {
    return this._resolveEventListenerBreakpoint(auxData['eventName'], auxData['targetName']);
  }

  /**
   * @return {!Map<string, boolean>}
   */
  xhrBreakpoints() {
    return this._xhrBreakpoints;
  }

  _saveXHRBreakpoints() {
    const breakpoints = [];
    for (const url of this._xhrBreakpoints.keys()) {
      breakpoints.push({url: url, enabled: this._xhrBreakpoints.get(url)});
    }
    this._xhrBreakpointsSetting.set(breakpoints);
  }

  /**
   * @param {string} url
   * @param {boolean} enabled
   */
  addXHRBreakpoint(url, enabled) {
    this._xhrBreakpoints.set(url, enabled);
    if (enabled) {
      for (const model of SDK.targetManager.models(DOMDebuggerModel)) {
        model._agent.setXHRBreakpoint(url);
      }
    }
    this._saveXHRBreakpoints();
  }

  /**
   * @param {string} url
   */
  removeXHRBreakpoint(url) {
    const enabled = this._xhrBreakpoints.get(url);
    this._xhrBreakpoints.delete(url);
    if (enabled) {
      for (const model of SDK.targetManager.models(DOMDebuggerModel)) {
        model._agent.removeXHRBreakpoint(url);
      }
    }
    this._saveXHRBreakpoints();
  }

  /**
   * @param {string} url
   * @param {boolean} enabled
   */
  toggleXHRBreakpoint(url, enabled) {
    this._xhrBreakpoints.set(url, enabled);
    for (const model of SDK.targetManager.models(DOMDebuggerModel)) {
      if (enabled) {
        model._agent.setXHRBreakpoint(url);
      } else {
        model._agent.removeXHRBreakpoint(url);
      }
    }
    this._saveXHRBreakpoints();
  }

  /**
   * @override
   * @param {!DOMDebuggerModel} domDebuggerModel
   */
  modelAdded(domDebuggerModel) {
    for (const url of this._xhrBreakpoints.keys()) {
      if (this._xhrBreakpoints.get(url)) {
        domDebuggerModel._agent.setXHRBreakpoint(url);
      }
    }
    for (const breakpoint of this._eventListenerBreakpoints) {
      if (breakpoint._enabled) {
        breakpoint._updateOnModel(domDebuggerModel);
      }
    }
  }

  /**
   * @override
   * @param {!DOMDebuggerModel} domDebuggerModel
   */
  modelRemoved(domDebuggerModel) {
  }
}

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

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

/** @constructor */
SDK.DOMDebuggerModel = DOMDebuggerModel;

/** @enum {symbol} */
SDK.DOMDebuggerModel.Events = Events;

/** @constructor */
SDK.DOMDebuggerModel.DOMBreakpoint = DOMBreakpoint;

/** @constructor */
SDK.DOMDebuggerModel.EventListenerBreakpoint = EventListenerBreakpoint;

/** @constructor */
SDK.EventListener = EventListener;

/** @constructor */
SDK.DOMDebuggerManager = DOMDebuggerManager;

SDK.SDKModel.register(SDK.DOMDebuggerModel, SDK.Target.Capability.DOM, false);

/** @typedef {Protocol.DOMDebugger.DOMBreakpointType} */
SDK.DOMDebuggerModel.DOMBreakpoint.Type = Protocol.DOMDebugger.DOMBreakpointType;

/** @type {!SDK.DOMDebuggerManager} */
SDK.domDebuggerManager;
