blob: 6a6a4ffa188f672ac17d79a97163eb7a48c27296 [file] [log] [blame]
// Copyright (c) 2015 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.
/**
* @unrestricted
*/
export class EventListenerBreakpointsSidebarPane extends UI.VBox {
constructor() {
super(true);
this._categoriesTreeOutline = new UI.TreeOutlineInShadow();
this._categoriesTreeOutline.registerRequiredCSS('browser_debugger/eventListenerBreakpoints.css');
this._categoriesTreeOutline.setShowSelectionOnKeyboardFocus(/* show */ true);
this.contentElement.appendChild(this._categoriesTreeOutline.element);
/** @type {!Map<string, !BrowserDebugger.EventListenerBreakpointsSidebarPane.Item>} */
this._categories = new Map();
const categories = SDK.domDebuggerManager.eventListenerBreakpoints().map(breakpoint => breakpoint.category());
categories.sort();
for (const category of categories) {
if (!this._categories.has(category)) {
this._createCategory(category);
}
}
if (categories.length > 0) {
const firstCategory = this._categories.get(categories[0]);
firstCategory.element.select();
}
/** @type {!Map<!SDK.DOMDebuggerModel.EventListenerBreakpoint, !BrowserDebugger.EventListenerBreakpointsSidebarPane.Item>} */
this._breakpoints = new Map();
for (const breakpoint of SDK.domDebuggerManager.eventListenerBreakpoints()) {
this._createBreakpoint(breakpoint);
}
SDK.targetManager.addModelListener(SDK.DebuggerModel, SDK.DebuggerModel.Events.DebuggerPaused, this._update, this);
SDK.targetManager.addModelListener(SDK.DebuggerModel, SDK.DebuggerModel.Events.DebuggerResumed, this._update, this);
UI.context.addFlavorChangeListener(SDK.Target, this._update, this);
}
/**
* @override
*/
focus() {
this._categoriesTreeOutline.forceSelect();
}
/**
* @param {string} name
*/
_createCategory(name) {
const labelNode = UI.CheckboxLabel.create(name);
labelNode.checkboxElement.addEventListener('click', this._categoryCheckboxClicked.bind(this, name), true);
labelNode.checkboxElement.tabIndex = -1;
const treeElement = new UI.TreeElement(labelNode);
treeElement.listItemElement.addEventListener('keydown', event => {
if (event.key === ' ') {
this._categories.get(name).checkbox.click();
event.consume(true);
}
});
UI.ARIAUtils.setChecked(treeElement.listItemElement, false);
this._categoriesTreeOutline.appendChild(treeElement);
this._categories.set(name, {element: treeElement, checkbox: labelNode.checkboxElement});
}
/**
* @param {!SDK.DOMDebuggerModel.EventListenerBreakpoint} breakpoint
*/
_createBreakpoint(breakpoint) {
const labelNode = UI.CheckboxLabel.create(breakpoint.title());
labelNode.classList.add('source-code');
labelNode.checkboxElement.addEventListener('click', this._breakpointCheckboxClicked.bind(this, breakpoint), true);
labelNode.checkboxElement.tabIndex = -1;
const treeElement = new UI.TreeElement(labelNode);
treeElement.listItemElement.addEventListener('keydown', event => {
if (event.key === ' ') {
this._breakpoints.get(breakpoint).checkbox.click();
event.consume(true);
}
});
UI.ARIAUtils.setChecked(treeElement.listItemElement, false);
treeElement.listItemElement.createChild('div', 'breakpoint-hit-marker');
this._categories.get(breakpoint.category()).element.appendChild(treeElement);
this._breakpoints.set(breakpoint, {element: treeElement, checkbox: labelNode.checkboxElement});
}
_update() {
const target = UI.context.flavor(SDK.Target);
const debuggerModel = target ? target.model(SDK.DebuggerModel) : null;
const details = debuggerModel ? debuggerModel.debuggerPausedDetails() : null;
if (!details || details.reason !== SDK.DebuggerModel.BreakReason.EventListener || !details.auxData) {
if (this._highlightedElement) {
UI.ARIAUtils.setDescription(this._highlightedElement, '');
this._highlightedElement.classList.remove('breakpoint-hit');
delete this._highlightedElement;
}
return;
}
const breakpoint = SDK.domDebuggerManager.resolveEventListenerBreakpoint(/** @type {!Object} */ (details.auxData));
if (!breakpoint) {
return;
}
UI.viewManager.showView('sources.eventListenerBreakpoints');
this._categories.get(breakpoint.category()).element.expand();
this._highlightedElement = this._breakpoints.get(breakpoint).element.listItemElement;
UI.ARIAUtils.setDescription(this._highlightedElement, ls`breakpoint hit`);
this._highlightedElement.classList.add('breakpoint-hit');
}
/**
* @param {string} category
*/
_categoryCheckboxClicked(category) {
const item = this._categories.get(category);
const enabled = item.checkbox.checked;
UI.ARIAUtils.setChecked(item.element.listItemElement, enabled);
for (const breakpoint of this._breakpoints.keys()) {
if (breakpoint.category() === category) {
breakpoint.setEnabled(enabled);
this._breakpoints.get(breakpoint).checkbox.checked = enabled;
}
}
}
/**
* @param {!SDK.DOMDebuggerModel.EventListenerBreakpoint} breakpoint
*/
_breakpointCheckboxClicked(breakpoint) {
const item = this._breakpoints.get(breakpoint);
breakpoint.setEnabled(item.checkbox.checked);
UI.ARIAUtils.setChecked(item.element.listItemElement, item.checkbox.checked);
let hasEnabled = false;
let hasDisabled = false;
for (const other of this._breakpoints.keys()) {
if (other.category() === breakpoint.category()) {
if (other.enabled()) {
hasEnabled = true;
} else {
hasDisabled = true;
}
}
}
const category = this._categories.get(breakpoint.category());
category.checkbox.checked = hasEnabled;
category.checkbox.indeterminate = hasEnabled && hasDisabled;
if (category.checkbox.indeterminate) {
UI.ARIAUtils.setCheckboxAsIndeterminate(category.element.listItemElement);
} else {
UI.ARIAUtils.setChecked(category.element.listItemElement, hasEnabled);
}
}
}
/* Legacy exported object */
self.BrowserDebugger = self.BrowserDebugger || {};
/* Legacy exported object */
BrowserDebugger = BrowserDebugger || {};
/**
* @constructor
*/
BrowserDebugger.EventListenerBreakpointsSidebarPane = EventListenerBreakpointsSidebarPane;
/** @typedef {!{element: !UI.TreeElement, checkbox: !Element}} */
BrowserDebugger.EventListenerBreakpointsSidebarPane.Item;