UNPKG

chrome-devtools-frontend

Version:
158 lines (136 loc) 6.29 kB
// Copyright 2014 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. /* eslint-disable rulesdir/no-imperative-dom-api */ import type * as Common from '../../core/common/common.js'; import * as i18n from '../../core/i18n/i18n.js'; import * as SDK from '../../core/sdk/sdk.js'; import * as IconButton from '../../ui/components/icon_button/icon_button.js'; import * as UI from '../../ui/legacy/legacy.js'; import * as VisualLogging from '../../ui/visual_logging/visual_logging.js'; import threadsSidebarPaneStyles from './threadsSidebarPane.css.js'; const UIStrings = { /** *@description Text in Threads Sidebar Pane of the Sources panel */ paused: 'paused', } as const; const str_ = i18n.i18n.registerUIStrings('panels/sources/ThreadsSidebarPane.ts', UIStrings); const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_); export class ThreadsSidebarPane extends UI.Widget.VBox implements SDK.TargetManager.SDKModelObserver<SDK.DebuggerModel.DebuggerModel>, UI.ListControl.ListDelegate<SDK.DebuggerModel.DebuggerModel> { private readonly items: UI.ListModel.ListModel<SDK.DebuggerModel.DebuggerModel>; private readonly list: UI.ListControl.ListControl<SDK.DebuggerModel.DebuggerModel>; private selectedModel: SDK.DebuggerModel.DebuggerModel|null; constructor() { super(true); this.registerRequiredCSS(threadsSidebarPaneStyles); this.contentElement.setAttribute('jslog', `${VisualLogging.section('sources.threads')}`); this.items = new UI.ListModel.ListModel(); this.list = new UI.ListControl.ListControl(this.items, this, UI.ListControl.ListMode.NonViewport); const currentTarget = UI.Context.Context.instance().flavor(SDK.Target.Target); this.selectedModel = currentTarget !== null ? currentTarget.model(SDK.DebuggerModel.DebuggerModel) : null; this.contentElement.appendChild(this.list.element); UI.Context.Context.instance().addFlavorChangeListener(SDK.Target.Target, this.targetFlavorChanged, this); SDK.TargetManager.TargetManager.instance().observeModels(SDK.DebuggerModel.DebuggerModel, this); } static shouldBeShown(): boolean { return SDK.TargetManager.TargetManager.instance().models(SDK.DebuggerModel.DebuggerModel).length >= 2; } createElementForItem(debuggerModel: SDK.DebuggerModel.DebuggerModel): Element { const element = document.createElement('div'); element.classList.add('thread-item'); const title = element.createChild('div', 'thread-item-title'); const pausedState = element.createChild('div', 'thread-item-paused-state'); const icon = new IconButton.Icon.Icon(); icon.data = { iconName: 'large-arrow-right-filled', color: 'var(--icon-arrow-main-thread)', width: '14px', height: '14px', }; icon.classList.add('selected-thread-icon'); element.appendChild(icon); element.tabIndex = -1; self.onInvokeElement(element, event => { UI.Context.Context.instance().setFlavor(SDK.Target.Target, debuggerModel.target()); event.consume(true); }); const isSelected = UI.Context.Context.instance().flavor(SDK.Target.Target) === debuggerModel.target(); element.classList.toggle('selected', isSelected); UI.ARIAUtils.setSelected(element, isSelected); function updateTitle(): void { const executionContext = debuggerModel.runtimeModel().defaultExecutionContext(); title.textContent = executionContext?.label() ? executionContext.label() : debuggerModel.target().name(); } function updatePausedState(): void { pausedState.textContent = debuggerModel.isPaused() ? i18nString(UIStrings.paused) : ''; } function targetNameChanged(event: Common.EventTarget.EventTargetEvent<SDK.Target.Target>): void { const target = event.data; if (target === debuggerModel.target()) { updateTitle(); } } debuggerModel.addEventListener(SDK.DebuggerModel.Events.DebuggerPaused, updatePausedState); debuggerModel.addEventListener(SDK.DebuggerModel.Events.DebuggerResumed, updatePausedState); debuggerModel.runtimeModel().addEventListener(SDK.RuntimeModel.Events.ExecutionContextChanged, updateTitle); SDK.TargetManager.TargetManager.instance().addEventListener( SDK.TargetManager.Events.NAME_CHANGED, targetNameChanged); updatePausedState(); updateTitle(); return element; } heightForItem(_debuggerModel: SDK.DebuggerModel.DebuggerModel): number { console.assert(false); // Should not be called. return 0; } isItemSelectable(_debuggerModel: SDK.DebuggerModel.DebuggerModel): boolean { return true; } selectedItemChanged( _from: SDK.DebuggerModel.DebuggerModel|null, _to: SDK.DebuggerModel.DebuggerModel|null, fromElement: Element|null, toElement: Element|null): void { const fromEle = (fromElement as HTMLElement | null); if (fromEle) { fromEle.tabIndex = -1; } const toEle = (toElement as HTMLElement | null); if (toEle) { this.setDefaultFocusedElement(toEle); toEle.tabIndex = 0; if (this.hasFocus()) { toEle.focus(); } } } updateSelectedItemARIA(_fromElement: Element|null, _toElement: Element|null): boolean { return false; } modelAdded(debuggerModel: SDK.DebuggerModel.DebuggerModel): void { this.items.insert(this.items.length, debuggerModel); const currentTarget = UI.Context.Context.instance().flavor(SDK.Target.Target); if (currentTarget === debuggerModel.target()) { this.list.selectItem(debuggerModel); } } modelRemoved(debuggerModel: SDK.DebuggerModel.DebuggerModel): void { this.items.remove(this.items.indexOf(debuggerModel)); } private targetFlavorChanged({data: target}: Common.EventTarget.EventTargetEvent<SDK.Target.Target>): void { const hadFocus = this.hasFocus(); const debuggerModel = target.model(SDK.DebuggerModel.DebuggerModel); this.list.selectItem(debuggerModel); if (debuggerModel) { this.list.refreshItem(debuggerModel); } if (this.selectedModel !== null) { this.list.refreshItem(this.selectedModel); } this.selectedModel = debuggerModel; if (hadFocus) { this.focus(); } } }