Skip to content

Commit 808bd65

Browse files
ktranDevtools-frontend LUCI CQ
authored andcommitted
[GM3Restyling] Update event listeners empty states
Screenshots: https://imgur.com/a/FNvetVN Bug: 325443331 Change-Id: I79e9f6dc26a76ea419d4cf30ae81da0c4d5a8d46 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6280727 Reviewed-by: Kateryna Prokopenko <[email protected]> Commit-Queue: Kim-Anh Tran <[email protected]>
1 parent 77fced7 commit 808bd65

File tree

5 files changed

+108
-9
lines changed

5 files changed

+108
-9
lines changed

front_end/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ group("unittests") {
164164
"panels/developer_resources:unittests",
165165
"panels/elements:unittests",
166166
"panels/emulation:unittests",
167+
"panels/event_listeners:unittests",
167168
"panels/explain:unittests",
168169
"panels/issues:unittests",
169170
"panels/layer_viewer:unittests",

front_end/panels/event_listeners/BUILD.gn

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,14 @@ devtools_entrypoint("bundle") {
4646

4747
visibility += devtools_panels_visibility
4848
}
49+
50+
ts_library("unittests") {
51+
testonly = true
52+
53+
sources = [ "EventListenersView.test.ts" ]
54+
55+
deps = [
56+
":bundle",
57+
"../../testing",
58+
]
59+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright 2025 The Chromium Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import {describeWithLocale} from '../../testing/EnvironmentHelpers.js';
6+
7+
import * as EventListeners from './event_listeners.js';
8+
9+
describeWithLocale('EventListenersView placeholder', () => {
10+
function assertElementDisplayStyle(
11+
view: EventListeners.EventListenersView.EventListenersView, selector: string, style: string) {
12+
const element = view.element.querySelector(selector);
13+
assert.exists(element);
14+
assert.deepEqual(window.getComputedStyle(element).display, style);
15+
}
16+
17+
it('shows one-liner if in sources', () => {
18+
const eventListenersView = new EventListeners.EventListenersView.EventListenersView(() => {});
19+
const container = document.createElement('div');
20+
container.classList.add('sources', 'panel');
21+
eventListenersView.markAsRoot();
22+
eventListenersView.show(container);
23+
24+
document.body.appendChild(container);
25+
assertElementDisplayStyle(eventListenersView, '.empty-view-scroller', 'none');
26+
assertElementDisplayStyle(eventListenersView, '.placeholder .gray-info-message', 'block');
27+
28+
assert.deepEqual(
29+
eventListenersView.contentElement.querySelector('.placeholder .gray-info-message')?.textContent,
30+
'No event listeners');
31+
32+
eventListenersView.detach();
33+
container.remove();
34+
});
35+
36+
it('shows empty widget if in elements panel', () => {
37+
const eventListenersView = new EventListeners.EventListenersView.EventListenersView(() => {});
38+
const container = document.createElement('div');
39+
container.classList.add('elements', 'panel');
40+
eventListenersView.markAsRoot();
41+
eventListenersView.show(container);
42+
43+
document.body.appendChild(container);
44+
assertElementDisplayStyle(eventListenersView, '.empty-view-scroller', 'block');
45+
assertElementDisplayStyle(eventListenersView, '.placeholder .gray-info-message', 'none');
46+
47+
assert.deepEqual(
48+
eventListenersView.contentElement.querySelector('.empty-state-header')?.textContent, 'No event listeners');
49+
assert.deepEqual(
50+
eventListenersView.contentElement.querySelector('.empty-state-description')?.textContent,
51+
'On this page you will find registered event listeners');
52+
53+
eventListenersView.detach();
54+
container.remove();
55+
});
56+
});

front_end/panels/event_listeners/EventListenersView.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ const UIStrings = {
2222
*@description Empty holder text content in Event Listeners View of the Event Listener Debugging pane in the Sources panel
2323
*/
2424
noEventListeners: 'No event listeners',
25+
/**
26+
*@description Empty holder text content in Event Listeners View of the Event Listener Debugging pane in the Elements panel
27+
*/
28+
eventListenersExplanation: 'On this page you will find registered event listeners',
2529
/**
2630
*@description Delete button title in Event Listeners View of the Event Listener Debugging pane in the Sources panel
2731
*/
@@ -54,19 +58,23 @@ export class EventListenersView extends UI.Widget.VBox {
5458
private readonly treeItemMap: Map<string, EventListenersTreeElement>;
5559
constructor(changeCallback: () => void, enableDefaultTreeFocus: boolean|undefined = false) {
5660
super();
61+
this.registerRequiredCSS(eventListenersViewStyles);
5762
this.changeCallback = changeCallback;
5863
this.enableDefaultTreeFocus = enableDefaultTreeFocus;
64+
65+
this.emptyHolder = this.element.createChild('div', 'placeholder hidden');
66+
this.emptyHolder.createChild('span', 'gray-info-message').textContent = i18nString(UIStrings.noEventListeners);
67+
const emptyWidget = new UI.EmptyWidget.EmptyWidget(
68+
i18nString(UIStrings.noEventListeners), i18nString(UIStrings.eventListenersExplanation));
69+
emptyWidget.show(this.emptyHolder);
70+
5971
this.treeOutline = new UI.TreeOutline.TreeOutlineInShadow();
6072
this.treeOutline.setComparator(EventListenersTreeElement.comparator);
61-
this.treeOutline.element.classList.add('monospace');
73+
this.treeOutline.element.classList.add('event-listener-tree', 'monospace');
6274
this.treeOutline.setShowSelectionOnKeyboardFocus(true);
6375
this.treeOutline.setFocusable(true);
6476
this.treeOutline.registerRequiredCSS(eventListenersViewStyles, objectValueStyles);
6577
this.element.appendChild(this.treeOutline.element);
66-
this.emptyHolder = document.createElement('div');
67-
this.emptyHolder.classList.add('gray-info-message');
68-
this.emptyHolder.textContent = i18nString(UIStrings.noEventListeners);
69-
this.emptyHolder.tabIndex = -1;
7078
this.linkifier = new Components.Linkifier.Linkifier();
7179
this.treeItemMap = new Map();
7280
}
@@ -75,7 +83,7 @@ export class EventListenersView extends UI.Widget.VBox {
7583
if (!this.enableDefaultTreeFocus) {
7684
return;
7785
}
78-
if (!this.emptyHolder.parentNode) {
86+
if (!this.emptyHolder.classList.contains('hidden')) {
7987
this.treeOutline.forceSelect();
8088
} else {
8189
this.emptyHolder.focus();
@@ -198,7 +206,7 @@ export class EventListenersView extends UI.Widget.VBox {
198206
treeItem.hidden = true;
199207
this.treeOutline.appendChild(treeItem);
200208
}
201-
this.emptyHolder.remove();
209+
this.emptyHolder.classList.add('hidden');
202210
return treeItem;
203211
}
204212

@@ -212,8 +220,8 @@ export class EventListenersView extends UI.Widget.VBox {
212220
firstVisibleChild = eventType;
213221
}
214222
}
215-
if (allHidden && !this.emptyHolder.parentNode) {
216-
this.element.appendChild(this.emptyHolder);
223+
if (allHidden && this.emptyHolder.classList.contains('hidden')) {
224+
this.emptyHolder.classList.remove('hidden');
217225
}
218226
if (firstVisibleChild) {
219227
firstVisibleChild.select(true /* omitFocus */);

front_end/panels/event_listeners/eventListenersView.css

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,29 @@
6767
}
6868
}
6969

70+
.placeholder:not(.hidden) + .event-listener-tree {
71+
display: none;
72+
}
73+
74+
.placeholder {
75+
display: flex;
76+
margin: auto;
77+
align-items: center;
78+
justify-content: center;
79+
}
80+
81+
.sources.panel .empty-view-scroller {
82+
display: none;
83+
}
84+
85+
.elements.panel .placeholder {
86+
display: block;
87+
88+
.gray-info-message {
89+
display: none;
90+
}
91+
}
92+
7093
.tree-outline-disclosure li:hover .event-listener-button {
7194
display: inline;
7295
}

0 commit comments

Comments
 (0)