Skip to content

Commit 091bd6b

Browse files
Kateryna ProkopenkoDevtools-frontend LUCI CQ
authored andcommitted
[GM3Restyling] Use <select> for WebAudio context selector
Screenshot: https://imgur.com/a/xenmD3T Bug: 325441856 Change-Id: I33dcb0da74ea93ba26f3d0d6c5827cf74a9b7696 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6372540 Reviewed-by: Kim-Anh Tran <kimanh@chromium.org> Auto-Submit: Kateryna Prokopenko <kprokopenko@chromium.org> Commit-Queue: Kim-Anh Tran <kimanh@chromium.org>
1 parent f58f13c commit 091bd6b

2 files changed

Lines changed: 61 additions & 75 deletions

File tree

front_end/panels/web_audio/AudioContextSelector.ts

Lines changed: 52 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,10 @@
44

55
import * as Common from '../../core/common/common.js';
66
import * as i18n from '../../core/i18n/i18n.js';
7-
import * as Platform from '../../core/platform/platform.js';
7+
import type * as Platform from '../../core/platform/platform.js';
88
import type * as Protocol from '../../generated/protocol.js';
99
import * as UI from '../../ui/legacy/legacy.js';
1010

11-
import audioContextSelectorStyles from './audioContextSelector.css.js';
12-
1311
const UIStrings = {
1412
/**
1513
*@description Text that shows there is no recording
@@ -24,119 +22,103 @@ const UIStrings = {
2422
const str_ = i18n.i18n.registerUIStrings('panels/web_audio/AudioContextSelector.ts', UIStrings);
2523
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
2624

27-
export class AudioContextSelector extends Common.ObjectWrapper.ObjectWrapper<EventTypes> implements
28-
UI.SoftDropDown.Delegate<Protocol.WebAudio.BaseAudioContext> {
25+
export class AudioContextSelector extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
2926
private readonly placeholderText: Platform.UIString.LocalizedString;
27+
private readonly selectElement: HTMLSelectElement;
3028
private readonly items: UI.ListModel.ListModel<Protocol.WebAudio.BaseAudioContext>;
31-
private readonly dropDown: UI.SoftDropDown.SoftDropDown<Protocol.WebAudio.BaseAudioContext>;
3229
private readonly toolbarItemInternal: UI.Toolbar.ToolbarItem;
33-
private selectedContextInternal: Protocol.WebAudio.BaseAudioContext|null;
30+
3431
constructor() {
3532
super();
3633

3734
this.placeholderText = i18nString(UIStrings.noRecordings);
38-
3935
this.items = new UI.ListModel.ListModel();
40-
41-
this.dropDown = new UI.SoftDropDown.SoftDropDown(this.items, this, 'audio-context');
42-
this.dropDown.setPlaceholderText(this.placeholderText);
43-
44-
this.toolbarItemInternal = new UI.Toolbar.ToolbarItem(this.dropDown.element);
45-
this.toolbarItemInternal.setEnabled(false);
36+
this.selectElement = document.createElement('select');
37+
this.toolbarItemInternal = new UI.Toolbar.ToolbarItem(this.selectElement);
4638
this.toolbarItemInternal.setTitle(i18nString(UIStrings.audioContextS, {PH1: this.placeholderText}));
39+
this.selectElement.addEventListener('change', this.onSelectionChanged.bind(this));
40+
this.selectElement.disabled = true;
41+
this.addPlaceholderOption();
42+
4743
this.items.addEventListener(UI.ListModel.Events.ITEMS_REPLACED, this.onListItemReplaced, this);
48-
this.toolbarItemInternal.element.classList.add('toolbar-has-dropdown');
44+
}
4945

50-
this.selectedContextInternal = null;
46+
private addPlaceholderOption(): void {
47+
const placeholderOption = UI.Fragment.html`
48+
<option value="" hidden>${this.placeholderText}</option>`;
49+
this.selectElement.appendChild(placeholderOption);
5150
}
5251

5352
private onListItemReplaced(): void {
54-
const hasItems = Boolean(this.items.length);
55-
this.toolbarItemInternal.setEnabled(hasItems);
56-
if (!hasItems) {
57-
this.toolbarItemInternal.setTitle(i18nString(UIStrings.audioContextS, {PH1: this.placeholderText}));
53+
this.selectElement.removeChildren();
54+
55+
if (this.items.length === 0) {
56+
this.addPlaceholderOption();
57+
this.selectElement.disabled = true;
58+
this.onSelectionChanged();
59+
return;
60+
}
61+
62+
for (const context of this.items) {
63+
const option = UI.Fragment.html`
64+
<option value=${context.contextId}>${this.titleFor(context)}</option>`;
65+
this.selectElement.appendChild(option);
5866
}
67+
this.selectElement.disabled = false;
68+
this.onSelectionChanged();
5969
}
6070

6171
contextCreated({data: context}: Common.EventTarget.EventTargetEvent<Protocol.WebAudio.BaseAudioContext>): void {
6272
this.items.insert(this.items.length, context);
63-
64-
// Select if this is the first item.
65-
if (this.items.length === 1) {
66-
this.dropDown.selectItem(context);
67-
}
73+
this.onListItemReplaced();
6874
}
6975

7076
contextDestroyed({data: contextId}: Common.EventTarget.EventTargetEvent<string>): void {
71-
const contextIndex =
72-
this.items.findIndex((context: Protocol.WebAudio.BaseAudioContext) => context.contextId === contextId);
73-
if (contextIndex > -1) {
74-
this.items.remove(contextIndex);
77+
const index = this.items.findIndex(context => context.contextId === contextId);
78+
if (index !== -1) {
79+
this.items.remove(index);
80+
this.onListItemReplaced();
7581
}
7682
}
7783

7884
contextChanged({data: changedContext}: Common.EventTarget.EventTargetEvent<Protocol.WebAudio.BaseAudioContext>):
7985
void {
80-
const contextIndex = this.items.findIndex(
81-
(context: Protocol.WebAudio.BaseAudioContext) => context.contextId === changedContext.contextId);
82-
if (contextIndex > -1) {
83-
this.items.replace(contextIndex, changedContext);
84-
85-
// If the changed context is currently selected by user. Re-select it
86-
// because the actual element is replaced with a new one.
87-
if (this.selectedContextInternal && this.selectedContextInternal.contextId === changedContext.contextId) {
88-
this.dropDown.selectItem(changedContext);
89-
}
86+
const index = this.items.findIndex(context => context.contextId === changedContext.contextId);
87+
if (index !== -1) {
88+
this.items.replace(index, changedContext);
89+
this.onListItemReplaced();
9090
}
9191
}
9292

93-
createElementForItem(item: Protocol.WebAudio.BaseAudioContext): Element {
94-
const element = document.createElement('div');
95-
const shadowRoot = UI.UIUtils.createShadowRootWithCoreStyles(element, {cssFile: audioContextSelectorStyles});
96-
const title = shadowRoot.createChild('div', 'title');
97-
UI.UIUtils.createTextChild(title, Platform.StringUtilities.trimEndWithMaxLength(this.titleFor(item), 100));
98-
return element;
99-
}
100-
10193
selectedContext(): Protocol.WebAudio.BaseAudioContext|null {
102-
if (!this.selectedContextInternal) {
94+
const selectedValue = this.selectElement.value;
95+
if (!selectedValue) {
10396
return null;
10497
}
105-
106-
return this.selectedContextInternal;
98+
return this.items.find(context => context.contextId === selectedValue) || null;
10799
}
108100

109-
highlightedItemChanged(
110-
from: Protocol.WebAudio.BaseAudioContext|null, to: Protocol.WebAudio.BaseAudioContext|null,
111-
fromElement: Element|null, toElement: Element|null): void {
112-
if (fromElement) {
113-
fromElement.classList.remove('highlighted');
114-
}
115-
if (toElement) {
116-
toElement.classList.add('highlighted');
101+
onSelectionChanged(): void {
102+
const selectedContext = this.selectedContext();
103+
if (selectedContext) {
104+
this.toolbarItemInternal.setTitle(i18nString(UIStrings.audioContextS, {PH1: this.titleFor(selectedContext)}));
105+
} else {
106+
this.toolbarItemInternal.setTitle(i18nString(UIStrings.audioContextS, {PH1: this.placeholderText}));
117107
}
118-
}
119-
120-
isItemSelectable(_item: Protocol.WebAudio.BaseAudioContext): boolean {
121-
return true;
108+
this.dispatchEventToListeners(Events.CONTEXT_SELECTED, selectedContext);
122109
}
123110

124111
itemSelected(item: Protocol.WebAudio.BaseAudioContext|null): void {
125112
if (!item) {
126113
return;
127114
}
128-
129-
// It's possible that no context is selected yet.
130-
if (!this.selectedContextInternal || this.selectedContextInternal.contextId !== item.contextId) {
131-
this.selectedContextInternal = item;
132-
this.toolbarItemInternal.setTitle(i18nString(UIStrings.audioContextS, {PH1: this.titleFor(item)}));
133-
}
134-
135-
this.dispatchEventToListeners(Events.CONTEXT_SELECTED, item);
115+
this.selectElement.value = item.contextId;
116+
this.onSelectionChanged();
136117
}
137118

138119
reset(): void {
139120
this.items.replaceAll([]);
121+
this.onListItemReplaced();
140122
}
141123

142124
titleFor(context: Protocol.WebAudio.BaseAudioContext): string {

front_end/panels/web_audio/WebAudioView.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,7 @@ export class WebAudioView extends UI.ThrottledWidget.ThrottledWidget implements
8282
SelectorEvents.CONTEXT_SELECTED,
8383
(event: Common.EventTarget.EventTargetEvent<Protocol.WebAudio.BaseAudioContext|null>) => {
8484
const context = event.data;
85-
if (context) {
86-
this.updateDetailView(context);
87-
}
85+
this.updateDetailView(context);
8886
void this.doUpdate();
8987
});
9088

@@ -180,10 +178,10 @@ export class WebAudioView extends UI.ThrottledWidget.ThrottledWidget implements
180178
}
181179

182180
private reset(): void {
181+
this.contextSelector.reset();
183182
if (this.landingPage.isShowing()) {
184183
this.landingPage.detach();
185184
}
186-
this.contextSelector.reset();
187185
this.detailViewContainer.removeChildren();
188186
this.landingPage.show(this.detailViewContainer);
189187
this.graphManager.clearGraphs();
@@ -335,7 +333,13 @@ export class WebAudioView extends UI.ThrottledWidget.ThrottledWidget implements
335333
});
336334
}
337335

338-
private updateDetailView(context: Protocol.WebAudio.BaseAudioContext): void {
336+
private updateDetailView(context: Protocol.WebAudio.BaseAudioContext|null): void {
337+
if (!context) {
338+
this.landingPage.detach();
339+
this.detailViewContainer.removeChildren();
340+
this.landingPage.show(this.detailViewContainer);
341+
return;
342+
}
339343
if (this.landingPage.isShowing()) {
340344
this.landingPage.detach();
341345
}

0 commit comments

Comments
 (0)