chrome-devtools-frontend 1.0.1697595 → 1.0.1697998
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.stylelintignore +2 -0
- package/front_end/core/common/VersionController.ts +5 -1
- package/front_end/core/sdk/AnimationModel.ts +9 -1
- package/front_end/generated/InspectorBackendCommands.ts +1 -1
- package/front_end/generated/protocol.ts +8 -2
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +26 -0
- package/front_end/models/ai_assistance/ai_assistance.ts +4 -4
- package/front_end/models/ai_assistance/skills/performance.md +4 -3
- package/front_end/models/ai_assistance/tools/{GetFunctionCode.ts → GetTraceFunctionCode.ts} +26 -13
- package/front_end/models/ai_assistance/tools/{GetResourceContent.ts → GetTraceResourceContent.ts} +31 -11
- package/front_end/models/ai_assistance/tools/Tool.ts +2 -2
- package/front_end/models/ai_assistance/tools/ToolRegistry.ts +6 -6
- package/front_end/models/elements/DOMChanges.ts +238 -0
- package/front_end/models/elements/elements.ts +2 -0
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +3 -1
- package/front_end/panels/ai_assistance/components/MarkdownRendererWithCodeBlock.ts +25 -5
- package/front_end/panels/browser_debugger/ObjectEventListenersSidebarPane.ts +2 -3
- package/front_end/panels/elements/ElementsTreeElement.ts +98 -20
- package/front_end/panels/elements/ElementsTreeOutline.ts +271 -43
- package/front_end/panels/elements/EventListenersWidget.ts +0 -1
- package/front_end/panels/event_listeners/EventListenersView.ts +241 -297
- package/front_end/panels/linear_memory_inspector/LinearMemoryInspectorController.ts +1 -1
- package/front_end/panels/mobile_throttling/ThrottlingSettingsTab.ts +10 -2
- package/front_end/panels/network/NetworkConfigView.ts +141 -116
- package/front_end/panels/network/NetworkPanel.ts +7 -4
- package/front_end/panels/network/RequestHeadersView.ts +1 -1
- package/front_end/panels/network/forward/BackendLinking.ts +5 -2
- package/front_end/panels/settings/BackendLinkingSettingsTab.ts +7 -2
- package/front_end/panels/timeline/TimelineTreeView.ts +11 -1
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/comments/CommentOverlayManager.ts +169 -40
- package/front_end/ui/comments/CommentThreadWidget.ts +221 -0
- package/front_end/ui/comments/CommentsOverlayWidget.ts +124 -12
- package/front_end/ui/comments/commentThreadWidget.css +173 -0
- package/front_end/ui/comments/comments.ts +2 -0
- package/front_end/ui/comments/commentsOverlay.css +6 -0
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +1 -1
- package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +4 -0
- package/package.json +5 -5
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// Copyright 2015 The Chromium Authors
|
|
2
2
|
// Use of this source code is governed by a BSD-style license that can be
|
|
3
3
|
// found in the LICENSE file.
|
|
4
|
-
/* eslint-disable @devtools/no-imperative-dom-api */
|
|
5
4
|
|
|
6
5
|
import * as Common from '../../core/common/common.js';
|
|
7
6
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
@@ -9,14 +8,18 @@ import type * as Platform from '../../core/platform/platform.js';
|
|
|
9
8
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
10
9
|
import * as Buttons from '../../ui/components/buttons/buttons.js';
|
|
11
10
|
import * as ObjectUI from '../../ui/legacy/components/object_ui/object_ui.js';
|
|
11
|
+
import objectPropertiesSectionStyles from '../../ui/legacy/components/object_ui/objectPropertiesSection.css.js';
|
|
12
12
|
import objectValueStyles from '../../ui/legacy/components/object_ui/objectValue.css.js';
|
|
13
13
|
import * as Components from '../../ui/legacy/components/utils/utils.js';
|
|
14
14
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
15
|
-
import
|
|
15
|
+
import * as Lit from '../../ui/lit/lit.js';
|
|
16
16
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
17
17
|
|
|
18
18
|
import {frameworkEventListeners} from './EventListenersUtils.js';
|
|
19
19
|
import eventListenersViewStyles from './eventListenersView.css.js';
|
|
20
|
+
const {widget} = UI.Widget;
|
|
21
|
+
const {html, render} = Lit;
|
|
22
|
+
const {repeat} = Lit.Directives;
|
|
20
23
|
|
|
21
24
|
const UIStrings = {
|
|
22
25
|
/**
|
|
@@ -51,49 +54,255 @@ const UIStrings = {
|
|
|
51
54
|
const str_ = i18n.i18n.registerUIStrings('panels/event_listeners/EventListenersView.ts', UIStrings);
|
|
52
55
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
53
56
|
|
|
57
|
+
interface ViewInput {
|
|
58
|
+
togglePassiveListener(listener: SDK.DOMDebuggerModel.EventListener): void;
|
|
59
|
+
removeListener(listener: SDK.DOMDebuggerModel.EventListener): boolean;
|
|
60
|
+
reveal(object: SDK.RemoteObject.RemoteObject): void;
|
|
61
|
+
linkifier: Components.Linkifier.Linkifier;
|
|
62
|
+
listeners: Map<string, Array<{object: SDK.RemoteObject.RemoteObject, listener: SDK.DOMDebuggerModel.EventListener}>>;
|
|
63
|
+
filter?: {showFramework: boolean, showPassive: boolean, showBlocking: boolean};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
type View = (input: ViewInput, output: object, target: HTMLElement) => void;
|
|
67
|
+
export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
68
|
+
const types = input.listeners.keys().toArray().sort();
|
|
69
|
+
|
|
70
|
+
const onContextMenu = (event: Event, listener: SDK.DOMDebuggerModel.EventListener,
|
|
71
|
+
object: SDK.RemoteObject.RemoteObject): void => {
|
|
72
|
+
const menu = new UI.ContextMenu.ContextMenu(event);
|
|
73
|
+
if (event.target instanceof HTMLElement && !event.target.closest('.event-listener-tree-subtitle') &&
|
|
74
|
+
event.currentTarget instanceof HTMLElement) {
|
|
75
|
+
const link = event.currentTarget.querySelector('.event-listener-tree-subtitle .devtools-link');
|
|
76
|
+
if (link) {
|
|
77
|
+
menu.appendApplicableItems(link);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (object.subtype === 'node') {
|
|
81
|
+
menu.defaultSection().appendItem(i18nString(UIStrings.openInElementsPanel), () => input.reveal(object),
|
|
82
|
+
{jslogContext: 'reveal-in-elements'});
|
|
83
|
+
}
|
|
84
|
+
menu.defaultSection().appendItem(i18nString(UIStrings.deleteEventListener), () => input.removeListener(listener),
|
|
85
|
+
{disabled: !listener.canRemove(), jslogContext: 'delete-event-listener'});
|
|
86
|
+
menu.defaultSection().appendCheckboxItem(i18nString(UIStrings.passive), () => input.togglePassiveListener(listener),
|
|
87
|
+
{
|
|
88
|
+
checked: listener.passive(),
|
|
89
|
+
disabled: !listener.canTogglePassive(),
|
|
90
|
+
jslogContext: 'passive',
|
|
91
|
+
});
|
|
92
|
+
void menu.show();
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const listenerProperties = (listener: SDK.DOMDebuggerModel.EventListener): Iterable<Lit.TemplateResult> => {
|
|
96
|
+
const runtimeModel = listener.domDebuggerModel().runtimeModel();
|
|
97
|
+
const properties = [
|
|
98
|
+
new ObjectUI.ObjectPropertiesSection.ObjectTreeNode(
|
|
99
|
+
runtimeModel.createRemotePropertyFromPrimitiveValue('useCapture', listener.useCapture()), undefined, {
|
|
100
|
+
readOnly: false,
|
|
101
|
+
propertiesMode: ObjectUI.ObjectPropertiesSection.ObjectPropertiesMode.OWN_AND_INTERNAL_AND_INHERITED,
|
|
102
|
+
}),
|
|
103
|
+
new ObjectUI.ObjectPropertiesSection.ObjectTreeNode(
|
|
104
|
+
runtimeModel.createRemotePropertyFromPrimitiveValue('passive', listener.passive()), undefined, {
|
|
105
|
+
readOnly: false,
|
|
106
|
+
propertiesMode: ObjectUI.ObjectPropertiesSection.ObjectPropertiesMode.OWN_AND_INTERNAL_AND_INHERITED,
|
|
107
|
+
}),
|
|
108
|
+
new ObjectUI.ObjectPropertiesSection.ObjectTreeNode(
|
|
109
|
+
runtimeModel.createRemotePropertyFromPrimitiveValue('once', listener.once()), undefined, {
|
|
110
|
+
readOnly: false,
|
|
111
|
+
propertiesMode: ObjectUI.ObjectPropertiesSection.ObjectPropertiesMode.OWN_AND_INTERNAL_AND_INHERITED,
|
|
112
|
+
}),
|
|
113
|
+
];
|
|
114
|
+
if (typeof listener.handler() !== 'undefined') {
|
|
115
|
+
properties.push(new ObjectUI.ObjectPropertiesSection.ObjectTreeNode(
|
|
116
|
+
new SDK.RemoteObject.RemoteObjectProperty('handler', listener.handler()), undefined, {
|
|
117
|
+
readOnly: false,
|
|
118
|
+
propertiesMode: ObjectUI.ObjectPropertiesSection.ObjectPropertiesMode.OWN_AND_INTERNAL_AND_INHERITED,
|
|
119
|
+
}));
|
|
120
|
+
}
|
|
121
|
+
return ObjectUI.ObjectPropertiesSection.ObjectPropertyTreeElement
|
|
122
|
+
.createPropertyNodes({properties}, true, true, undefined)
|
|
123
|
+
.map(node => html`<devtools-tree-wrapper .treeElement=${node}></devtools-tree-wrapper>`);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const shouldHide = (listenerOrType: SDK.DOMDebuggerModel.EventListener|string): boolean => {
|
|
127
|
+
if (!input.filter) {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
if (typeof listenerOrType === 'string') {
|
|
131
|
+
return input.listeners.get(listenerOrType)?.every(({listener}) => shouldHide(listener)) ?? true;
|
|
132
|
+
}
|
|
133
|
+
const listenerOrigin = listenerOrType.origin();
|
|
134
|
+
if (listenerOrigin === SDK.DOMDebuggerModel.EventListener.Origin.FRAMEWORK_USER && !input.filter.showFramework) {
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
if (listenerOrigin === SDK.DOMDebuggerModel.EventListener.Origin.FRAMEWORK && input.filter.showFramework) {
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
if (!input.filter.showPassive && listenerOrType.passive()) {
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
if (!input.filter.showBlocking && !listenerOrType.passive()) {
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
return false;
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const onKeyDown = (event: KeyboardEvent, listener: SDK.DOMDebuggerModel.EventListener,
|
|
150
|
+
object: SDK.RemoteObject.RemoteObject): void => {
|
|
151
|
+
if (event.target !== event.currentTarget) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (event.key === 'Delete' || event.key === 'Backspace') {
|
|
155
|
+
if (input.removeListener(listener)) {
|
|
156
|
+
event.consume();
|
|
157
|
+
}
|
|
158
|
+
} else if (event.key === 'Enter') {
|
|
159
|
+
input.reveal(object);
|
|
160
|
+
event.consume();
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const hasVisibleListeners = types.some(type => !shouldHide(type));
|
|
165
|
+
|
|
166
|
+
// clang-format off
|
|
167
|
+
render(html`
|
|
168
|
+
<style>${eventListenersViewStyles}</style>
|
|
169
|
+
${!hasVisibleListeners ? html`
|
|
170
|
+
<div autofocus class=placeholder><!--emptyHolder-->
|
|
171
|
+
<span class=gray-info-message>${i18nString(UIStrings.noEventListeners)}</span>
|
|
172
|
+
${widget(UI.EmptyWidget.EmptyWidget, {
|
|
173
|
+
header: i18nString(UIStrings.noEventListeners),
|
|
174
|
+
text: i18nString(UIStrings.eventListenersExplanation),
|
|
175
|
+
})}
|
|
176
|
+
</div>` : html`
|
|
177
|
+
<devtools-tree autofocus class="event-listener-tree monospace" show-selection-on-keyboard-focus .template=${html`
|
|
178
|
+
<ul role=tree>
|
|
179
|
+
<style>${eventListenersViewStyles}</style>
|
|
180
|
+
<style>${objectValueStyles}</style>
|
|
181
|
+
<style>${objectPropertiesSectionStyles}</style>
|
|
182
|
+
${repeat(types, type => type, type => html`
|
|
183
|
+
<li role=treeitem toggle-on-click aria-label="${type}, event listener" ?hidden=${shouldHide(type)}>
|
|
184
|
+
${type}
|
|
185
|
+
<ul role=group>
|
|
186
|
+
${repeat(input.listeners.get(type) ?? [], ({listener}) => listener, ({listener, object}) => html`
|
|
187
|
+
<li role=treeitem
|
|
188
|
+
data-origin=${listener.origin()}
|
|
189
|
+
@contextmenu=${(e: Event) => onContextMenu(e, listener, object)}
|
|
190
|
+
@keydown=${(e: KeyboardEvent) => onKeyDown(e, listener, object)}
|
|
191
|
+
?hidden=${shouldHide(listener)}>
|
|
192
|
+
<span class=event-listener-details>
|
|
193
|
+
${ObjectUI.ObjectPropertiesSection.renderPropertyValue(
|
|
194
|
+
object, /* wasThrown */ false, /* showPreview */ false, input.linkifier)}
|
|
195
|
+
<devtools-button
|
|
196
|
+
.iconName=${'bin'}
|
|
197
|
+
.variant=${Buttons.Button.Variant.ICON}
|
|
198
|
+
.size=${Buttons.Button.Size.MICRO}
|
|
199
|
+
.jslogContext=${'delete-event-listener'}
|
|
200
|
+
title=${i18nString(UIStrings.deleteEventListener)}
|
|
201
|
+
@click=${(event: Event) => {input.removeListener(listener); event.consume();}}
|
|
202
|
+
?hidden=${!listener.canRemove()}></devtools-button>
|
|
203
|
+
${listener.isScrollBlockingType() && listener.canTogglePassive() ? html`
|
|
204
|
+
<button class=event-listener-button
|
|
205
|
+
jslog=${VisualLogging.action('passive').track({click: true})}
|
|
206
|
+
title=${i18nString(UIStrings.toggleWhetherEventListenerIs)}
|
|
207
|
+
@click=${(e: Event) => {input.togglePassiveListener(listener); e.consume();}}>
|
|
208
|
+
${i18nString(UIStrings.togglePassive)}
|
|
209
|
+
</button>` : Lit.nothing}
|
|
210
|
+
<span class=event-listener-tree-subtitle>
|
|
211
|
+
${input.linkifier.linkifyRawLocation(
|
|
212
|
+
listener.location(), listener.sourceURL(), /* FIXME template version */
|
|
213
|
+
undefined, {tabStop: true})}
|
|
214
|
+
</span>
|
|
215
|
+
</span>
|
|
216
|
+
<ul role=group>
|
|
217
|
+
${listenerProperties(listener)}
|
|
218
|
+
</ul>
|
|
219
|
+
</li>`)}
|
|
220
|
+
</ul>
|
|
221
|
+
</li>`)}
|
|
222
|
+
</ul>
|
|
223
|
+
`}></devtools-tree>`}`,
|
|
224
|
+
// clang-format on
|
|
225
|
+
target);
|
|
226
|
+
};
|
|
227
|
+
|
|
54
228
|
export class EventListenersView extends UI.Widget.VBox {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
filter: {showFramework: boolean, showPassive: boolean, showBlocking: boolean}|undefined;
|
|
229
|
+
#objects: Array<SDK.RemoteObject.RemoteObject|null> = [];
|
|
230
|
+
#filter: {showFramework: boolean, showPassive: boolean, showBlocking: boolean}|undefined;
|
|
231
|
+
#view: View;
|
|
232
|
+
#listeners?:
|
|
233
|
+
Map<string, Array<{object: SDK.RemoteObject.RemoteObject, listener: SDK.DOMDebuggerModel.EventListener}>>;
|
|
61
234
|
#linkifier = new Components.Linkifier.Linkifier();
|
|
62
|
-
|
|
63
|
-
constructor(element?: HTMLElement) {
|
|
235
|
+
constructor(element?: HTMLElement, view: View = DEFAULT_VIEW) {
|
|
64
236
|
super(element);
|
|
65
|
-
this
|
|
66
|
-
|
|
67
|
-
this.emptyHolder.createChild('span', 'gray-info-message').textContent = i18nString(UIStrings.noEventListeners);
|
|
68
|
-
const emptyWidget = new UI.EmptyWidget.EmptyWidget(i18nString(UIStrings.noEventListeners),
|
|
69
|
-
i18nString(UIStrings.eventListenersExplanation));
|
|
70
|
-
emptyWidget.show(this.emptyHolder);
|
|
237
|
+
this.#view = view;
|
|
238
|
+
}
|
|
71
239
|
|
|
72
|
-
|
|
73
|
-
this
|
|
74
|
-
this.treeOutline.element.classList.add('event-listener-tree', 'monospace');
|
|
75
|
-
this.treeOutline.setShowSelectionOnKeyboardFocus(true);
|
|
76
|
-
this.treeOutline.setFocusable(true);
|
|
77
|
-
this.treeOutline.registerRequiredCSS(eventListenersViewStyles, objectValueStyles);
|
|
78
|
-
this.element.appendChild(this.treeOutline.element);
|
|
240
|
+
get objects(): Array<SDK.RemoteObject.RemoteObject|null> {
|
|
241
|
+
return this.#objects;
|
|
79
242
|
}
|
|
80
243
|
|
|
81
|
-
|
|
82
|
-
if (
|
|
244
|
+
set objects(val: Array<SDK.RemoteObject.RemoteObject|null>) {
|
|
245
|
+
if (this.#objects === val) {
|
|
83
246
|
return;
|
|
84
247
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
248
|
+
this.#listeners = undefined;
|
|
249
|
+
this.#objects = val;
|
|
250
|
+
this.requestUpdate();
|
|
251
|
+
}
|
|
252
|
+
get filter(): {showFramework: boolean, showPassive: boolean, showBlocking: boolean}|undefined {
|
|
253
|
+
return this.#filter;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
set filter(val: {showFramework: boolean, showPassive: boolean, showBlocking: boolean}|undefined) {
|
|
257
|
+
if (this.#filter === val) {
|
|
258
|
+
return;
|
|
89
259
|
}
|
|
260
|
+
this.#filter = val;
|
|
261
|
+
this.requestUpdate();
|
|
90
262
|
}
|
|
91
263
|
|
|
92
264
|
override async performUpdate(): Promise<void> {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
265
|
+
if (!this.#listeners && this.#objects) {
|
|
266
|
+
this.#listeners =
|
|
267
|
+
await EventListenersView.#loadListeners(this.#objects.filter((o): o is NonNullable<typeof o> => !!o));
|
|
96
268
|
}
|
|
269
|
+
const input: ViewInput = {
|
|
270
|
+
listeners: this.#listeners ?? new Map(),
|
|
271
|
+
filter: this.#filter,
|
|
272
|
+
togglePassiveListener: (listener: SDK.DOMDebuggerModel.EventListener) => {
|
|
273
|
+
void listener.togglePassive().then(() => {
|
|
274
|
+
this.requestUpdate();
|
|
275
|
+
});
|
|
276
|
+
},
|
|
277
|
+
removeListener: (listener: SDK.DOMDebuggerModel.EventListener) => {
|
|
278
|
+
if (!listener.canRemove()) {
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
void listener.remove();
|
|
282
|
+
if (this.#listeners) {
|
|
283
|
+
const list = this.#listeners.get(listener.type());
|
|
284
|
+
if (list) {
|
|
285
|
+
const index = list.findIndex(item => item.listener === listener);
|
|
286
|
+
if (index !== -1) {
|
|
287
|
+
list.splice(index, 1);
|
|
288
|
+
if (list.length === 0) {
|
|
289
|
+
this.#listeners.delete(listener.type());
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
this.requestUpdate();
|
|
295
|
+
return true;
|
|
296
|
+
},
|
|
297
|
+
reveal: (object: SDK.RemoteObject.RemoteObject) => {
|
|
298
|
+
if (object.subtype === 'node') {
|
|
299
|
+
void Common.Revealer.reveal(object);
|
|
300
|
+
}
|
|
301
|
+
},
|
|
302
|
+
linkifier: this.#linkifier,
|
|
303
|
+
};
|
|
304
|
+
this.#view(input, {}, this.contentElement);
|
|
305
|
+
this.eventListenersArrivedForTest();
|
|
97
306
|
}
|
|
98
307
|
|
|
99
308
|
static async #loadListeners(objects: SDK.RemoteObject.RemoteObject[]): Promise<
|
|
@@ -138,271 +347,6 @@ export class EventListenersView extends UI.Widget.VBox {
|
|
|
138
347
|
}
|
|
139
348
|
}
|
|
140
349
|
|
|
141
|
-
async addObjects(objects: Array<SDK.RemoteObject.RemoteObject|null>): Promise<void> {
|
|
142
|
-
// Remove existing event listeners and reset linkifier first.
|
|
143
|
-
const eventTypes = this.treeOutline.rootElement().children();
|
|
144
|
-
for (const eventType of eventTypes) {
|
|
145
|
-
eventType.removeChildren();
|
|
146
|
-
}
|
|
147
|
-
this.#linkifier.reset();
|
|
148
|
-
|
|
149
|
-
const listeners = await EventListenersView.#loadListeners(objects.filter((o): o is NonNullable<typeof o> => !!o));
|
|
150
|
-
|
|
151
|
-
for (const [type, groupedListeners] of listeners) {
|
|
152
|
-
const treeItem = this.getOrCreateTreeElementForType(type);
|
|
153
|
-
for (const {object, listener} of groupedListeners) {
|
|
154
|
-
treeItem.addObjectEventListener(listener, object);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
this.addEmptyHolderIfNeeded();
|
|
159
|
-
this.eventListenersArrivedForTest();
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
showFrameworkListeners(showFramework: boolean, showPassive: boolean, showBlocking: boolean): void {
|
|
163
|
-
const eventTypes = this.treeOutline.rootElement().children();
|
|
164
|
-
for (const eventType of eventTypes) {
|
|
165
|
-
let hiddenEventType = true;
|
|
166
|
-
for (const listenerElement of eventType.children()) {
|
|
167
|
-
const objectListenerElement = listenerElement as ObjectEventListenerBar;
|
|
168
|
-
const listenerOrigin = objectListenerElement.eventListener().origin();
|
|
169
|
-
let hidden = false;
|
|
170
|
-
if (listenerOrigin === SDK.DOMDebuggerModel.EventListener.Origin.FRAMEWORK_USER && !showFramework) {
|
|
171
|
-
hidden = true;
|
|
172
|
-
}
|
|
173
|
-
if (listenerOrigin === SDK.DOMDebuggerModel.EventListener.Origin.FRAMEWORK && showFramework) {
|
|
174
|
-
hidden = true;
|
|
175
|
-
}
|
|
176
|
-
if (!showPassive && objectListenerElement.eventListener().passive()) {
|
|
177
|
-
hidden = true;
|
|
178
|
-
}
|
|
179
|
-
if (!showBlocking && !objectListenerElement.eventListener().passive()) {
|
|
180
|
-
hidden = true;
|
|
181
|
-
}
|
|
182
|
-
objectListenerElement.hidden = hidden;
|
|
183
|
-
hiddenEventType = hiddenEventType && hidden;
|
|
184
|
-
}
|
|
185
|
-
eventType.hidden = hiddenEventType;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
private getOrCreateTreeElementForType(type: string): EventListenersTreeElement {
|
|
190
|
-
let treeItem = this.#treeItemMap.get(type);
|
|
191
|
-
if (!treeItem) {
|
|
192
|
-
treeItem = new EventListenersTreeElement(type, this.#linkifier, this.changeCallback);
|
|
193
|
-
this.#treeItemMap.set(type, treeItem);
|
|
194
|
-
treeItem.hidden = true;
|
|
195
|
-
this.treeOutline.appendChild(treeItem);
|
|
196
|
-
}
|
|
197
|
-
this.emptyHolder.classList.add('hidden');
|
|
198
|
-
return treeItem;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
addEmptyHolderIfNeeded(): void {
|
|
202
|
-
let allHidden = true;
|
|
203
|
-
let firstVisibleChild: UI.TreeOutline.TreeElement|null = null;
|
|
204
|
-
for (const eventType of this.treeOutline.rootElement().children()) {
|
|
205
|
-
eventType.hidden = !eventType.firstChild();
|
|
206
|
-
allHidden = allHidden && eventType.hidden;
|
|
207
|
-
if (!firstVisibleChild && !eventType.hidden) {
|
|
208
|
-
firstVisibleChild = eventType;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
if (allHidden && this.emptyHolder.classList.contains('hidden')) {
|
|
212
|
-
this.emptyHolder.classList.remove('hidden');
|
|
213
|
-
}
|
|
214
|
-
if (firstVisibleChild) {
|
|
215
|
-
firstVisibleChild.select(true /* omitFocus */);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
this.treeOutline.setFocusable(Boolean(firstVisibleChild));
|
|
219
|
-
}
|
|
220
|
-
|
|
221
350
|
private eventListenersArrivedForTest(): void {
|
|
222
351
|
}
|
|
223
352
|
}
|
|
224
|
-
|
|
225
|
-
export class EventListenersTreeElement extends UI.TreeOutline.TreeElement {
|
|
226
|
-
override toggleOnClick: boolean;
|
|
227
|
-
private readonly linkifier: Components.Linkifier.Linkifier;
|
|
228
|
-
private readonly changeCallback: () => void;
|
|
229
|
-
constructor(type: string, linkifier: Components.Linkifier.Linkifier, changeCallback: () => void) {
|
|
230
|
-
super(type);
|
|
231
|
-
this.toggleOnClick = true;
|
|
232
|
-
this.linkifier = linkifier;
|
|
233
|
-
this.changeCallback = changeCallback;
|
|
234
|
-
UI.ARIAUtils.setLabel(this.listItemElement, `${type}, event listener`);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
static comparator(element1: UI.TreeOutline.TreeElement, element2: UI.TreeOutline.TreeElement): number {
|
|
238
|
-
if (element1.title === element2.title) {
|
|
239
|
-
return 0;
|
|
240
|
-
}
|
|
241
|
-
return element1.title > element2.title ? 1 : -1;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
addObjectEventListener(eventListener: SDK.DOMDebuggerModel.EventListener,
|
|
245
|
-
object: SDK.RemoteObject.RemoteObject): void {
|
|
246
|
-
const treeElement = new ObjectEventListenerBar(eventListener, object, this.linkifier, this.changeCallback);
|
|
247
|
-
this.appendChild(treeElement as UI.TreeOutline.TreeElement);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
export class ObjectEventListenerBar extends UI.TreeOutline.TreeElement {
|
|
252
|
-
#eventListener: SDK.DOMDebuggerModel.EventListener;
|
|
253
|
-
editable: boolean;
|
|
254
|
-
private readonly changeCallback: () => void;
|
|
255
|
-
private valueTitle?: Element;
|
|
256
|
-
constructor(eventListener: SDK.DOMDebuggerModel.EventListener, object: SDK.RemoteObject.RemoteObject,
|
|
257
|
-
linkifier: Components.Linkifier.Linkifier, changeCallback: () => void) {
|
|
258
|
-
super('', true);
|
|
259
|
-
this.#eventListener = eventListener;
|
|
260
|
-
this.editable = false;
|
|
261
|
-
this.setTitle(object, linkifier);
|
|
262
|
-
this.changeCallback = changeCallback;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
override async onpopulate(): Promise<void> {
|
|
266
|
-
const properties = [];
|
|
267
|
-
const eventListener = this.#eventListener;
|
|
268
|
-
const runtimeModel = eventListener.domDebuggerModel().runtimeModel();
|
|
269
|
-
properties.push(new ObjectUI.ObjectPropertiesSection.ObjectTreeNode(
|
|
270
|
-
runtimeModel.createRemotePropertyFromPrimitiveValue('useCapture', eventListener.useCapture()), undefined, {
|
|
271
|
-
readOnly: false,
|
|
272
|
-
propertiesMode: ObjectUI.ObjectPropertiesSection.ObjectPropertiesMode.OWN_AND_INTERNAL_AND_INHERITED,
|
|
273
|
-
}));
|
|
274
|
-
properties.push(new ObjectUI.ObjectPropertiesSection.ObjectTreeNode(
|
|
275
|
-
runtimeModel.createRemotePropertyFromPrimitiveValue('passive', eventListener.passive()), undefined, {
|
|
276
|
-
readOnly: false,
|
|
277
|
-
propertiesMode: ObjectUI.ObjectPropertiesSection.ObjectPropertiesMode.OWN_AND_INTERNAL_AND_INHERITED,
|
|
278
|
-
}));
|
|
279
|
-
properties.push(new ObjectUI.ObjectPropertiesSection.ObjectTreeNode(
|
|
280
|
-
runtimeModel.createRemotePropertyFromPrimitiveValue('once', eventListener.once()), undefined, {
|
|
281
|
-
readOnly: false,
|
|
282
|
-
propertiesMode: ObjectUI.ObjectPropertiesSection.ObjectPropertiesMode.OWN_AND_INTERNAL_AND_INHERITED,
|
|
283
|
-
}));
|
|
284
|
-
if (typeof eventListener.handler() !== 'undefined') {
|
|
285
|
-
properties.push(new ObjectUI.ObjectPropertiesSection.ObjectTreeNode(
|
|
286
|
-
new SDK.RemoteObject.RemoteObjectProperty('handler', eventListener.handler()), undefined, {
|
|
287
|
-
readOnly: false,
|
|
288
|
-
propertiesMode: ObjectUI.ObjectPropertiesSection.ObjectPropertiesMode.OWN_AND_INTERNAL_AND_INHERITED,
|
|
289
|
-
}));
|
|
290
|
-
}
|
|
291
|
-
ObjectUI.ObjectPropertiesSection.ObjectPropertyTreeElement.populateWithProperties(this, {properties}, true, true,
|
|
292
|
-
undefined);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
private setTitle(object: SDK.RemoteObject.RemoteObject, linkifier: Components.Linkifier.Linkifier): void {
|
|
296
|
-
const title = this.listItemElement.createChild('span', 'event-listener-details');
|
|
297
|
-
|
|
298
|
-
const propertyValue = ObjectUI.ObjectPropertiesSection.renderPropertyValue(
|
|
299
|
-
object, /* wasThrown */ false, /* showPreview */ false, linkifier, /* isSyntheticProperty */ false,
|
|
300
|
-
/* variableName */ undefined, /* includeNullOrUndefined */ undefined, /* useCustomPreview */ false, element => {
|
|
301
|
-
this.valueTitle = element;
|
|
302
|
-
});
|
|
303
|
-
// eslint-disable-next-line @devtools/no-lit-render-outside-of-view
|
|
304
|
-
render(propertyValue, title);
|
|
305
|
-
|
|
306
|
-
if (this.#eventListener.canRemove()) {
|
|
307
|
-
const deleteButton = new Buttons.Button.Button();
|
|
308
|
-
deleteButton.data = {
|
|
309
|
-
variant: Buttons.Button.Variant.ICON,
|
|
310
|
-
size: Buttons.Button.Size.MICRO,
|
|
311
|
-
iconName: 'bin',
|
|
312
|
-
jslogContext: 'delete-event-listener',
|
|
313
|
-
};
|
|
314
|
-
UI.Tooltip.Tooltip.install(deleteButton, i18nString(UIStrings.deleteEventListener));
|
|
315
|
-
deleteButton.addEventListener('click', event => {
|
|
316
|
-
this.removeListener();
|
|
317
|
-
event.consume();
|
|
318
|
-
}, false);
|
|
319
|
-
title.appendChild(deleteButton);
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
if (this.#eventListener.isScrollBlockingType() && this.#eventListener.canTogglePassive()) {
|
|
323
|
-
const passiveButton = title.createChild('button', 'event-listener-button');
|
|
324
|
-
passiveButton.textContent = i18nString(UIStrings.togglePassive);
|
|
325
|
-
passiveButton.setAttribute('jslog', `${VisualLogging.action('passive').track({click: true})}`);
|
|
326
|
-
UI.Tooltip.Tooltip.install(passiveButton, i18nString(UIStrings.toggleWhetherEventListenerIs));
|
|
327
|
-
passiveButton.addEventListener('click', event => {
|
|
328
|
-
this.togglePassiveListener();
|
|
329
|
-
event.consume();
|
|
330
|
-
}, false);
|
|
331
|
-
title.appendChild(passiveButton);
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
const subtitle = title.createChild('span', 'event-listener-tree-subtitle');
|
|
335
|
-
const linkElement = linkifier.linkifyRawLocation(this.#eventListener.location(), this.#eventListener.sourceURL(),
|
|
336
|
-
undefined, {tabStop: true});
|
|
337
|
-
subtitle.appendChild(linkElement);
|
|
338
|
-
|
|
339
|
-
this.listItemElement.addEventListener('contextmenu', event => {
|
|
340
|
-
const menu = new UI.ContextMenu.ContextMenu(event);
|
|
341
|
-
if (event.target !== linkElement) {
|
|
342
|
-
menu.appendApplicableItems(linkElement);
|
|
343
|
-
}
|
|
344
|
-
if (object.subtype === 'node') {
|
|
345
|
-
menu.defaultSection().appendItem(i18nString(UIStrings.openInElementsPanel),
|
|
346
|
-
() => Common.Revealer.reveal(object), {jslogContext: 'reveal-in-elements'});
|
|
347
|
-
}
|
|
348
|
-
menu.defaultSection().appendItem(
|
|
349
|
-
i18nString(UIStrings.deleteEventListener), this.removeListener.bind(this),
|
|
350
|
-
{disabled: !this.#eventListener.canRemove(), jslogContext: 'delete-event-listener'});
|
|
351
|
-
menu.defaultSection().appendCheckboxItem(i18nString(UIStrings.passive), this.togglePassiveListener.bind(this), {
|
|
352
|
-
checked: this.#eventListener.passive(),
|
|
353
|
-
disabled: !this.#eventListener.canTogglePassive(),
|
|
354
|
-
jslogContext: 'passive',
|
|
355
|
-
});
|
|
356
|
-
void menu.show();
|
|
357
|
-
});
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
private removeListener(): void {
|
|
361
|
-
this.removeListenerBar();
|
|
362
|
-
void this.#eventListener.remove();
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
private togglePassiveListener(): void {
|
|
366
|
-
void this.#eventListener.togglePassive().then(() => this.changeCallback());
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
private removeListenerBar(): void {
|
|
370
|
-
const parent = this.parent;
|
|
371
|
-
if (!parent) {
|
|
372
|
-
return;
|
|
373
|
-
}
|
|
374
|
-
parent.removeChild(this);
|
|
375
|
-
if (!parent.childCount()) {
|
|
376
|
-
parent.collapse();
|
|
377
|
-
}
|
|
378
|
-
let allHidden = true;
|
|
379
|
-
for (const child of parent.children()) {
|
|
380
|
-
if (!child.hidden) {
|
|
381
|
-
allHidden = false;
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
parent.hidden = allHidden;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
eventListener(): SDK.DOMDebuggerModel.EventListener {
|
|
388
|
-
return this.#eventListener;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
override onenter(): boolean {
|
|
392
|
-
if (this.valueTitle) {
|
|
393
|
-
(this.valueTitle as HTMLElement).click();
|
|
394
|
-
return true;
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
return false;
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
override ondelete(): boolean {
|
|
401
|
-
if (this.#eventListener.canRemove()) {
|
|
402
|
-
this.removeListener();
|
|
403
|
-
return true;
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
return false;
|
|
407
|
-
}
|
|
408
|
-
}
|
|
@@ -319,7 +319,7 @@ export class LinearMemoryInspectorController extends SDK.TargetManager.SDKModelO
|
|
|
319
319
|
_event: Event, contextMenu: UI.ContextMenu.ContextMenu,
|
|
320
320
|
target: ObjectUI.ObjectPropertiesSection.ObjectPropertyTreeElement): void {
|
|
321
321
|
if (target.property.object?.isLinearMemoryInspectable()) {
|
|
322
|
-
const expression = target.path
|
|
322
|
+
const expression = target.property.path;
|
|
323
323
|
const object = target.property.object;
|
|
324
324
|
contextMenu.debugSection().appendItem(
|
|
325
325
|
i18nString(UIStrings.openInMemoryInspectorPanel),
|
|
@@ -58,6 +58,14 @@ const UIStrings = {
|
|
|
58
58
|
* @description Label for a textbox that sets the packet loss percentage for real-time networks in the throttling settings tab.
|
|
59
59
|
*/
|
|
60
60
|
packetLoss: 'Packet Loss',
|
|
61
|
+
/**
|
|
62
|
+
* @description Label for a textbox that sets the low-tier mobile device CPU throttling in the throttling settings tab.
|
|
63
|
+
*/
|
|
64
|
+
calibratedLowTierMobile: 'Low-tier mobile device',
|
|
65
|
+
/**
|
|
66
|
+
* @description Label for a textbox that sets the mid-tier mobile device CPU throttling in the throttling settings tab.
|
|
67
|
+
*/
|
|
68
|
+
calibratedMidTierMobile: 'Mid-tier mobile device',
|
|
61
69
|
/**
|
|
62
70
|
* @description Label for a textbox that sets the maximum packet queue length for real-time networks in the throttling settings tab.
|
|
63
71
|
*/
|
|
@@ -241,11 +249,11 @@ export class CPUThrottlingCard {
|
|
|
241
249
|
descriptionEl.textContent = i18nString(UIStrings.cpuCalibrationDescription);
|
|
242
250
|
|
|
243
251
|
this.lowTierMobileDeviceEl = this.element.createChild('div', 'cpu-preset-section');
|
|
244
|
-
this.lowTierMobileDeviceEl.append(
|
|
252
|
+
this.lowTierMobileDeviceEl.append(i18nString(UIStrings.calibratedLowTierMobile));
|
|
245
253
|
this.lowTierMobileDeviceEl.createChild('div', 'cpu-preset-result');
|
|
246
254
|
|
|
247
255
|
this.midTierMobileDeviceEl = this.element.createChild('div', 'cpu-preset-section');
|
|
248
|
-
this.midTierMobileDeviceEl.append(
|
|
256
|
+
this.midTierMobileDeviceEl.append(i18nString(UIStrings.calibratedMidTierMobile));
|
|
249
257
|
this.midTierMobileDeviceEl.createChild('div', 'cpu-preset-result');
|
|
250
258
|
|
|
251
259
|
this.calibrateEl = this.element.createChild('div', 'cpu-preset-section cpu-preset-calibrate');
|