chrome-devtools-frontend 1.0.1661063 → 1.0.1662289
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/.agents/skills/evaluate-ai-css-completion/SKILL.md +19 -9
- package/.agents/skills/evaluate-ai-css-completion/scripts/evaluate.js +44 -16
- package/.agents/skills/migrate-chromium-test/SKILL.md +7 -2
- package/.agents/skills/ui-eng-vision-local-lit-renderer/SKILL.md +7 -1
- package/docs/ui_engineering.md +75 -42
- package/front_end/core/common/SettingRegistration.ts +0 -5
- package/front_end/core/platform/ArrayUtilities.ts +10 -0
- package/front_end/foundation/README.md +86 -0
- package/front_end/generated/InspectorBackendCommands.ts +4 -5
- package/front_end/generated/protocol.ts +20 -38
- package/front_end/models/bindings/CompilerScriptMapping.ts +5 -4
- package/front_end/models/bindings/ContentProviderBasedProject.ts +2 -3
- package/front_end/models/bindings/DebuggerLanguagePlugins.ts +4 -3
- package/front_end/models/bindings/DefaultScriptMapping.ts +3 -3
- package/front_end/models/bindings/NetworkProject.ts +10 -1
- package/front_end/models/bindings/ResourceMapping.ts +4 -3
- package/front_end/models/bindings/ResourceScriptMapping.ts +2 -1
- package/front_end/models/bindings/SASSSourceMapping.ts +4 -3
- package/front_end/models/bindings/StylesSourceMapping.ts +3 -3
- package/front_end/models/extensions/RecorderExtensionEndpoint.ts +7 -5
- package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +14 -5
- package/front_end/models/issues_manager/CheckFormsIssuesTrigger.ts +8 -9
- package/front_end/models/issues_manager/RelatedIssue.ts +10 -8
- package/front_end/models/javascript_metadata/NativeFunctions.js +1 -1
- package/front_end/models/logs/RequestResolver.ts +2 -2
- package/front_end/models/persistence/AutomaticFileSystemWorkspaceBinding.ts +0 -5
- package/front_end/models/source_map_scopes/FunctionCodeResolver.ts +1 -1
- package/front_end/models/trace/handlers/FramesHandler.ts +4 -7
- package/front_end/models/trace/handlers/ModelHandlers.ts +0 -1
- package/front_end/models/trace/handlers/RendererHandler.ts +2 -15
- package/front_end/models/trace/handlers/Threads.ts +4 -11
- package/front_end/models/trace/insights/DOMSize.ts +1 -1
- package/front_end/models/workspace/WorkspaceImpl.ts +1 -10
- package/front_end/panels/application/ApplicationPanelSidebar.ts +0 -44
- package/front_end/panels/application/CookieItemsView.ts +1 -1
- package/front_end/panels/application/FrameDetailsView.ts +1 -1
- package/front_end/panels/application/ServiceWorkersView.ts +494 -411
- package/front_end/panels/application/application.ts +0 -6
- package/front_end/panels/application/components/components.ts +0 -2
- package/front_end/panels/application/preloading/components/PreloadingDetailsReportView.ts +1 -1
- package/front_end/panels/application/serviceWorkersView.css +40 -4
- package/front_end/panels/browser_debugger/XHRBreakpointsSidebarPane.ts +147 -123
- package/front_end/panels/common/ExtensionServer.ts +3 -3
- package/front_end/panels/console/ConsoleView.ts +1 -1
- package/front_end/panels/emulation/DeviceModeView.ts +139 -70
- package/front_end/panels/issues/AffectedResourcesView.ts +1 -1
- package/front_end/panels/lighthouse/LighthouseProtocolService.ts +53 -12
- package/front_end/panels/network/RequestPayloadView.ts +77 -39
- package/front_end/panels/network/components/ResponseHeaderSection.ts +5 -3
- package/front_end/panels/profiler/HeapSnapshotView.ts +2 -2
- package/front_end/panels/recorder/RecorderController.ts +213 -49
- package/front_end/panels/recorder/RecorderPanel.ts +1 -1
- package/front_end/panels/sources/SourcesNavigator.ts +3 -2
- package/front_end/panels/sources/SourcesView.ts +0 -17
- package/front_end/panels/sources/UISourceCodeFrame.ts +42 -0
- package/front_end/panels/sources/sources.ts +0 -2
- package/front_end/panels/timeline/CompatibilityTracksAppender.ts +0 -17
- package/front_end/panels/timeline/ThreadAppender.ts +0 -106
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/components/report_view/ReportView.ts +11 -5
- package/front_end/ui/components/report_view/report.css +4 -1
- package/front_end/ui/legacy/TextPrompt.ts +49 -1
- package/front_end/ui/legacy/UIUtils.ts +11 -1
- package/front_end/ui/legacy/components/cookie_table/CookiesTable.ts +2 -2
- package/front_end/ui/legacy/textPrompt.css +10 -0
- package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
- package/package.json +1 -1
- package/front_end/models/trace/handlers/AuctionWorkletsHandler.ts +0 -183
- package/front_end/panels/application/InterestGroupStorageModel.ts +0 -81
- package/front_end/panels/application/InterestGroupStorageView.ts +0 -151
- package/front_end/panels/application/InterestGroupTreeElement.ts +0 -65
- package/front_end/panels/application/components/InterestGroupAccessGrid.ts +0 -135
- package/front_end/panels/application/components/interestGroupAccessGrid.css +0 -27
- package/front_end/panels/application/interestGroupStorageView.css +0 -9
- package/front_end/panels/sources/InplaceFormatterEditorAction.ts +0 -149
|
@@ -51,8 +51,7 @@ import {
|
|
|
51
51
|
type StepChanged
|
|
52
52
|
} from './StepView.js';
|
|
53
53
|
|
|
54
|
-
const {html,
|
|
55
|
-
const {customElement, state} = Decorators;
|
|
54
|
+
const {html, Directives: {ref}} = Lit;
|
|
56
55
|
|
|
57
56
|
const UIStrings = {
|
|
58
57
|
/**
|
|
@@ -177,12 +176,6 @@ const GET_EXTENSIONS_URL = 'https://goo.gle/recorder-extension-list' as Platform
|
|
|
177
176
|
const RECORDER_EXPLANATION_URL = 'https://developer.chrome.com/docs/devtools/recorder';
|
|
178
177
|
const FEEDBACK_URL = 'https://goo.gle/recorder-feedback' as Platform.DevToolsPath.UrlString;
|
|
179
178
|
|
|
180
|
-
declare global {
|
|
181
|
-
interface HTMLElementTagNameMap {
|
|
182
|
-
'devtools-recorder-controller': RecorderController;
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
179
|
interface StoredRecording {
|
|
187
180
|
storageName: string;
|
|
188
181
|
flow: Models.Schema.UserFlow;
|
|
@@ -225,45 +218,209 @@ function verifyFlowSize(flow: Models.Schema.UserFlow): void {
|
|
|
225
218
|
}
|
|
226
219
|
}
|
|
227
220
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
221
|
+
export class RecorderController extends UI.Widget.VBox<DocumentFragment> {
|
|
222
|
+
#currentRecordingSession?: Models.RecordingSession.RecordingSession;
|
|
223
|
+
get currentRecordingSession(): Models.RecordingSession.RecordingSession|undefined {
|
|
224
|
+
return this.#currentRecordingSession;
|
|
225
|
+
}
|
|
226
|
+
set currentRecordingSession(value: Models.RecordingSession.RecordingSession|undefined) {
|
|
227
|
+
if (this.#currentRecordingSession !== value) {
|
|
228
|
+
this.#currentRecordingSession = value;
|
|
229
|
+
this.requestUpdate();
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
#currentRecording: StoredRecording|undefined;
|
|
234
|
+
get currentRecording(): StoredRecording|undefined {
|
|
235
|
+
return this.#currentRecording;
|
|
236
|
+
}
|
|
237
|
+
set currentRecording(value: StoredRecording|undefined) {
|
|
238
|
+
if (this.#currentRecording !== value) {
|
|
239
|
+
this.#currentRecording = value;
|
|
240
|
+
this.requestUpdate();
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
#currentStep?: Models.Schema.Step;
|
|
245
|
+
get currentStep(): Models.Schema.Step|undefined {
|
|
246
|
+
return this.#currentStep;
|
|
247
|
+
}
|
|
248
|
+
set currentStep(value: Models.Schema.Step|undefined) {
|
|
249
|
+
if (this.#currentStep !== value) {
|
|
250
|
+
this.#currentStep = value;
|
|
251
|
+
this.requestUpdate();
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
#recordingError?: Error;
|
|
256
|
+
get recordingError(): Error|undefined {
|
|
257
|
+
return this.#recordingError;
|
|
258
|
+
}
|
|
259
|
+
set recordingError(value: Error|undefined) {
|
|
260
|
+
if (this.#recordingError !== value) {
|
|
261
|
+
this.#recordingError = value;
|
|
262
|
+
this.requestUpdate();
|
|
263
|
+
}
|
|
264
|
+
}
|
|
234
265
|
|
|
235
266
|
#storage = Models.RecordingStorage.RecordingStorage.instance();
|
|
236
267
|
#screenshotStorage = Models.ScreenshotStorage.ScreenshotStorage.instance();
|
|
237
268
|
|
|
238
|
-
|
|
239
|
-
|
|
269
|
+
#isRecording = false;
|
|
270
|
+
get isRecording(): boolean {
|
|
271
|
+
return this.#isRecording;
|
|
272
|
+
}
|
|
273
|
+
set isRecording(value: boolean) {
|
|
274
|
+
if (this.#isRecording !== value) {
|
|
275
|
+
this.#isRecording = value;
|
|
276
|
+
this.requestUpdate();
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
#isToggling = false;
|
|
281
|
+
get isToggling(): boolean {
|
|
282
|
+
return this.#isToggling;
|
|
283
|
+
}
|
|
284
|
+
set isToggling(value: boolean) {
|
|
285
|
+
if (this.#isToggling !== value) {
|
|
286
|
+
this.#isToggling = value;
|
|
287
|
+
this.requestUpdate();
|
|
288
|
+
}
|
|
289
|
+
}
|
|
240
290
|
|
|
241
291
|
// TODO: we keep the functionality to allow/disallow replay but right now it's not used.
|
|
242
292
|
// It can be used to decide if we allow replay on a certain target for example.
|
|
243
293
|
#replayAllowed = true;
|
|
244
|
-
|
|
245
|
-
|
|
294
|
+
|
|
295
|
+
#recordingPlayer?: Models.RecordingPlayer.RecordingPlayer;
|
|
296
|
+
get recordingPlayer(): Models.RecordingPlayer.RecordingPlayer|undefined {
|
|
297
|
+
return this.#recordingPlayer;
|
|
298
|
+
}
|
|
299
|
+
set recordingPlayer(value: Models.RecordingPlayer.RecordingPlayer|undefined) {
|
|
300
|
+
if (this.#recordingPlayer !== value) {
|
|
301
|
+
this.#recordingPlayer = value;
|
|
302
|
+
this.requestUpdate();
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
#lastReplayResult?: Models.RecordingPlayer.ReplayResult;
|
|
307
|
+
get lastReplayResult(): Models.RecordingPlayer.ReplayResult|undefined {
|
|
308
|
+
return this.#lastReplayResult;
|
|
309
|
+
}
|
|
310
|
+
set lastReplayResult(value: Models.RecordingPlayer.ReplayResult|undefined) {
|
|
311
|
+
if (this.#lastReplayResult !== value) {
|
|
312
|
+
this.#lastReplayResult = value;
|
|
313
|
+
this.requestUpdate();
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
246
317
|
readonly #replayState: ReplayState = {isPlaying: false, isPausedOnBreakpoint: false};
|
|
247
318
|
|
|
248
|
-
|
|
249
|
-
|
|
319
|
+
#currentPage: Pages = Pages.START_PAGE;
|
|
320
|
+
get currentPage(): Pages {
|
|
321
|
+
return this.#currentPage;
|
|
322
|
+
}
|
|
323
|
+
set currentPage(value: Pages) {
|
|
324
|
+
if (this.#currentPage !== value) {
|
|
325
|
+
this.#currentPage = value;
|
|
326
|
+
this.requestUpdate();
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
#previousPage?: Pages;
|
|
331
|
+
get previousPage(): Pages|undefined {
|
|
332
|
+
return this.#previousPage;
|
|
333
|
+
}
|
|
334
|
+
set previousPage(value: Pages|undefined) {
|
|
335
|
+
if (this.#previousPage !== value) {
|
|
336
|
+
this.#previousPage = value;
|
|
337
|
+
this.requestUpdate();
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
250
341
|
#fileSelector?: HTMLInputElement;
|
|
251
342
|
|
|
252
|
-
|
|
253
|
-
|
|
343
|
+
#sections?: Models.Section.Section[];
|
|
344
|
+
get sections(): Models.Section.Section[]|undefined {
|
|
345
|
+
return this.#sections;
|
|
346
|
+
}
|
|
347
|
+
set sections(value: Models.Section.Section[]|undefined) {
|
|
348
|
+
if (this.#sections !== value) {
|
|
349
|
+
this.#sections = value;
|
|
350
|
+
this.requestUpdate();
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
#settings?: Models.RecordingSettings.RecordingSettings;
|
|
355
|
+
get settings(): Models.RecordingSettings.RecordingSettings|undefined {
|
|
356
|
+
return this.#settings;
|
|
357
|
+
}
|
|
358
|
+
set settings(value: Models.RecordingSettings.RecordingSettings|undefined) {
|
|
359
|
+
if (this.#settings !== value) {
|
|
360
|
+
this.#settings = value;
|
|
361
|
+
this.requestUpdate();
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
#importError?: Error;
|
|
366
|
+
get importError(): Error|undefined {
|
|
367
|
+
return this.#importError;
|
|
368
|
+
}
|
|
369
|
+
set importError(value: Error|undefined) {
|
|
370
|
+
if (this.#importError !== value) {
|
|
371
|
+
this.#importError = value;
|
|
372
|
+
this.requestUpdate();
|
|
373
|
+
}
|
|
374
|
+
}
|
|
254
375
|
|
|
255
|
-
|
|
376
|
+
#exportMenuExpanded = false;
|
|
377
|
+
get exportMenuExpanded(): boolean {
|
|
378
|
+
return this.#exportMenuExpanded;
|
|
379
|
+
}
|
|
380
|
+
set exportMenuExpanded(value: boolean) {
|
|
381
|
+
if (this.#exportMenuExpanded !== value) {
|
|
382
|
+
this.#exportMenuExpanded = value;
|
|
383
|
+
this.requestUpdate();
|
|
384
|
+
}
|
|
385
|
+
}
|
|
256
386
|
|
|
257
|
-
@state() declare private exportMenuExpanded: boolean;
|
|
258
387
|
#exportMenuButton: Buttons.Button.Button|undefined;
|
|
259
388
|
|
|
260
389
|
#stepBreakpointIndexes = new Set<number>();
|
|
261
390
|
|
|
262
391
|
#builtInConverters: readonly Converters.Converter.Converter[];
|
|
263
|
-
|
|
264
|
-
|
|
392
|
+
#extensionConverters: Converters.Converter.Converter[] = [];
|
|
393
|
+
get extensionConverters(): Converters.Converter.Converter[] {
|
|
394
|
+
return this.#extensionConverters;
|
|
395
|
+
}
|
|
396
|
+
set extensionConverters(value: Converters.Converter.Converter[]) {
|
|
397
|
+
if (this.#extensionConverters !== value) {
|
|
398
|
+
this.#extensionConverters = value;
|
|
399
|
+
this.requestUpdate();
|
|
400
|
+
}
|
|
401
|
+
}
|
|
265
402
|
|
|
266
|
-
|
|
403
|
+
#replayExtensions: Extensions.ExtensionManager.Extension[] = [];
|
|
404
|
+
get replayExtensions(): Extensions.ExtensionManager.Extension[] {
|
|
405
|
+
return this.#replayExtensions;
|
|
406
|
+
}
|
|
407
|
+
set replayExtensions(value: Extensions.ExtensionManager.Extension[]) {
|
|
408
|
+
if (this.#replayExtensions !== value) {
|
|
409
|
+
this.#replayExtensions = value;
|
|
410
|
+
this.requestUpdate();
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
#viewDescriptor?: PublicExtensions.RecorderPluginManager.ViewDescriptor;
|
|
415
|
+
get viewDescriptor(): PublicExtensions.RecorderPluginManager.ViewDescriptor|undefined {
|
|
416
|
+
return this.#viewDescriptor;
|
|
417
|
+
}
|
|
418
|
+
set viewDescriptor(value: PublicExtensions.RecorderPluginManager.ViewDescriptor|undefined) {
|
|
419
|
+
if (this.#viewDescriptor !== value) {
|
|
420
|
+
this.#viewDescriptor = value;
|
|
421
|
+
this.requestUpdate();
|
|
422
|
+
}
|
|
423
|
+
}
|
|
267
424
|
#extensionViewShowRequestedListener?:
|
|
268
425
|
(event: Common.EventTarget.EventTargetEvent<PublicExtensions.RecorderPluginManager.ViewDescriptor>) => void;
|
|
269
426
|
|
|
@@ -279,7 +436,8 @@ export class RecorderController extends LitElement {
|
|
|
279
436
|
#createRecordingView?: CreateRecordingView;
|
|
280
437
|
|
|
281
438
|
constructor() {
|
|
282
|
-
|
|
439
|
+
const element = document.createElement('devtools-recorder-controller');
|
|
440
|
+
super(element, {useShadowDom: 'pure'});
|
|
283
441
|
|
|
284
442
|
this.isRecording = false;
|
|
285
443
|
this.isToggling = false;
|
|
@@ -306,11 +464,12 @@ export class RecorderController extends LitElement {
|
|
|
306
464
|
});
|
|
307
465
|
|
|
308
466
|
// used in e2e tests only.
|
|
309
|
-
|
|
467
|
+
/* eslint-disable-next-line @devtools/no-imperative-dom-api */
|
|
468
|
+
this.element.addEventListener('setrecording', (event: Event) => this.#onSetRecording(event));
|
|
310
469
|
}
|
|
311
470
|
|
|
312
|
-
override
|
|
313
|
-
super.
|
|
471
|
+
override onDetach(): void {
|
|
472
|
+
super.onDetach();
|
|
314
473
|
|
|
315
474
|
if (this.currentRecordingSession) {
|
|
316
475
|
void this.currentRecordingSession.stop();
|
|
@@ -623,7 +782,7 @@ export class RecorderController extends LitElement {
|
|
|
623
782
|
Host.userMetrics.recordingReplayFinished(Host.UserMetrics.RecordingReplayFinished.OTHER_ERROR);
|
|
624
783
|
}
|
|
625
784
|
// Dispatch an event for e2e testing.
|
|
626
|
-
this.dispatchEvent(new Events.ReplayFinishedEvent());
|
|
785
|
+
this.element.dispatchEvent(new Events.ReplayFinishedEvent());
|
|
627
786
|
});
|
|
628
787
|
|
|
629
788
|
this.recordingPlayer.addEventListener(Models.RecordingPlayer.Events.DONE, () => {
|
|
@@ -633,7 +792,7 @@ export class RecorderController extends LitElement {
|
|
|
633
792
|
}
|
|
634
793
|
this.lastReplayResult = Models.RecordingPlayer.ReplayResult.SUCCESS;
|
|
635
794
|
// Dispatch an event for e2e testing.
|
|
636
|
-
this.dispatchEvent(new Events.ReplayFinishedEvent());
|
|
795
|
+
this.element.dispatchEvent(new Events.ReplayFinishedEvent());
|
|
637
796
|
Host.userMetrics.recordingReplayFinished(Host.UserMetrics.RecordingReplayFinished.SUCCESS);
|
|
638
797
|
});
|
|
639
798
|
|
|
@@ -708,7 +867,7 @@ export class RecorderController extends LitElement {
|
|
|
708
867
|
this.#setCurrentRecording(await this.#storage.upsertRecording(Models.SchemaUtils.parse(json)));
|
|
709
868
|
this.#setCurrentPage(Pages.RECORDING_PAGE);
|
|
710
869
|
this.#clearError();
|
|
711
|
-
this.dispatchEvent(new Events.SetRecordingFinishedEvent());
|
|
870
|
+
this.element.dispatchEvent(new Events.SetRecordingFinishedEvent());
|
|
712
871
|
}
|
|
713
872
|
|
|
714
873
|
// Used by e2e tests to inspect the current recording.
|
|
@@ -988,7 +1147,7 @@ export class RecorderController extends LitElement {
|
|
|
988
1147
|
this.#setCurrentPage(Pages.RECORDING_PAGE);
|
|
989
1148
|
|
|
990
1149
|
// Dispatch an event for e2e testing.
|
|
991
|
-
this.dispatchEvent(new Events.RecordingStateChangedEvent((this.currentRecording as StoredRecording).flow));
|
|
1150
|
+
this.element.dispatchEvent(new Events.RecordingStateChangedEvent((this.currentRecording as StoredRecording).flow));
|
|
992
1151
|
}
|
|
993
1152
|
|
|
994
1153
|
async #onRecordingFinished(): Promise<void> {
|
|
@@ -1011,7 +1170,7 @@ export class RecorderController extends LitElement {
|
|
|
1011
1170
|
this.isRecording = false;
|
|
1012
1171
|
|
|
1013
1172
|
// Dispatch an event for e2e testing.
|
|
1014
|
-
this.dispatchEvent(new Events.RecordingStateChangedEvent(this.currentRecording.flow));
|
|
1173
|
+
this.element.dispatchEvent(new Events.RecordingStateChangedEvent(this.currentRecording.flow));
|
|
1015
1174
|
}
|
|
1016
1175
|
|
|
1017
1176
|
async onRecordingCancelled(): Promise<void> {
|
|
@@ -1271,10 +1430,10 @@ export class RecorderController extends LitElement {
|
|
|
1271
1430
|
})),
|
|
1272
1431
|
replayAllowed: this.#replayAllowed,
|
|
1273
1432
|
})}
|
|
1274
|
-
@createrecording=${this.#onCreateNewRecording}
|
|
1275
|
-
@deleterecording=${this.#onDeleteRecording}
|
|
1276
|
-
@openrecording=${this.#onRecordingSelected}
|
|
1277
|
-
@playrecording=${this.#onPlayRecordingByName}
|
|
1433
|
+
@createrecording=${this.#onCreateNewRecording.bind(this)}
|
|
1434
|
+
@deleterecording=${this.#onDeleteRecording.bind(this)}
|
|
1435
|
+
@openrecording=${this.#onRecordingSelected.bind(this)}
|
|
1436
|
+
@playrecording=${this.#onPlayRecordingByName.bind(this)}
|
|
1278
1437
|
>
|
|
1279
1438
|
</devtools-widget>
|
|
1280
1439
|
`;
|
|
@@ -1294,7 +1453,7 @@ export class RecorderController extends LitElement {
|
|
|
1294
1453
|
jslogcontext="learn-more"
|
|
1295
1454
|
>${i18nString(UIStrings.learnMore)}</devtools-link>
|
|
1296
1455
|
</div>
|
|
1297
|
-
<devtools-button .variant=${Buttons.Button.Variant.TONAL} jslogContext=${Actions.RecorderActions.CREATE_RECORDING} @click=${this.#onCreateNewRecording}>${i18nString(UIStrings.createRecording)}</devtools-button>
|
|
1456
|
+
<devtools-button .variant=${Buttons.Button.Variant.TONAL} jslogContext=${Actions.RecorderActions.CREATE_RECORDING} @click=${this.#onCreateNewRecording.bind(this)}>${i18nString(UIStrings.createRecording)}</devtools-button>
|
|
1298
1457
|
</div>
|
|
1299
1458
|
`;
|
|
1300
1459
|
// clang-format on
|
|
@@ -1385,7 +1544,12 @@ export class RecorderController extends LitElement {
|
|
|
1385
1544
|
this.exportMenuExpanded = false;
|
|
1386
1545
|
}
|
|
1387
1546
|
|
|
1388
|
-
|
|
1547
|
+
override performUpdate(): void {
|
|
1548
|
+
// eslint-disable-next-line @devtools/no-lit-render-outside-of-view
|
|
1549
|
+
Lit.render(this.render(), this.contentElement);
|
|
1550
|
+
}
|
|
1551
|
+
|
|
1552
|
+
protected render(): Lit.TemplateResult {
|
|
1389
1553
|
const recordings = this.#storage.getRecordings();
|
|
1390
1554
|
const selectValue: string = this.currentRecording ? this.currentRecording.storageName : this.currentPage;
|
|
1391
1555
|
// clang-format off
|
|
@@ -1414,7 +1578,7 @@ export class RecorderController extends LitElement {
|
|
|
1414
1578
|
<div class="wrapper">
|
|
1415
1579
|
<div class="header" jslog=${VisualLogging.toolbar()}>
|
|
1416
1580
|
<devtools-button
|
|
1417
|
-
@click=${this.#onCreateNewRecording}
|
|
1581
|
+
@click=${this.#onCreateNewRecording.bind(this)}
|
|
1418
1582
|
.data=${
|
|
1419
1583
|
{
|
|
1420
1584
|
variant: Buttons.Button.Variant.TOOLBAR,
|
|
@@ -1440,7 +1604,7 @@ export class RecorderController extends LitElement {
|
|
|
1440
1604
|
this.isToggling
|
|
1441
1605
|
}
|
|
1442
1606
|
@click=${(e: Event) => e.stopPropagation()}
|
|
1443
|
-
@change=${this.#onRecordingSelected}
|
|
1607
|
+
@change=${this.#onRecordingSelected.bind(this)}
|
|
1444
1608
|
jslog=${VisualLogging.dropDown('recordings').track({change: true})}
|
|
1445
1609
|
>
|
|
1446
1610
|
${Lit.Directives.repeat(
|
|
@@ -1453,7 +1617,7 @@ export class RecorderController extends LitElement {
|
|
|
1453
1617
|
</select>
|
|
1454
1618
|
<div class="separator"></div>
|
|
1455
1619
|
<devtools-button
|
|
1456
|
-
@click=${this.#onImportRecording}
|
|
1620
|
+
@click=${this.#onImportRecording.bind(this)}
|
|
1457
1621
|
.data=${
|
|
1458
1622
|
{
|
|
1459
1623
|
variant: Buttons.Button.Variant.TOOLBAR,
|
|
@@ -1465,7 +1629,7 @@ export class RecorderController extends LitElement {
|
|
|
1465
1629
|
></devtools-button>
|
|
1466
1630
|
<devtools-button
|
|
1467
1631
|
id='origin'
|
|
1468
|
-
@click=${this.#onExportRecording}
|
|
1632
|
+
@click=${this.#onExportRecording.bind(this)}
|
|
1469
1633
|
${ref(el => {
|
|
1470
1634
|
if (el instanceof HTMLElement) {
|
|
1471
1635
|
this.#exportMenuButton = el as Buttons.Button.Button;
|
|
@@ -1482,8 +1646,8 @@ export class RecorderController extends LitElement {
|
|
|
1482
1646
|
jslog=${VisualLogging.dropDown('export-recording').track({click: true})}
|
|
1483
1647
|
></devtools-button>
|
|
1484
1648
|
<devtools-menu
|
|
1485
|
-
@menucloserequest=${this.#onExportMenuClosed}
|
|
1486
|
-
@menuitemselected=${this.#onExportOptionSelected}
|
|
1649
|
+
@menucloserequest=${this.#onExportMenuClosed.bind(this)}
|
|
1650
|
+
@menuitemselected=${this.#onExportOptionSelected.bind(this)}
|
|
1487
1651
|
.origin=${this.#getExportMenuButton}
|
|
1488
1652
|
.showDivider=${false}
|
|
1489
1653
|
.showSelectedItem=${false}
|
|
@@ -1522,7 +1686,7 @@ export class RecorderController extends LitElement {
|
|
|
1522
1686
|
</devtools-menu-group>
|
|
1523
1687
|
</devtools-menu>
|
|
1524
1688
|
<devtools-button
|
|
1525
|
-
@click=${this.#onDeleteRecording}
|
|
1689
|
+
@click=${this.#onDeleteRecording.bind(this)}
|
|
1526
1690
|
.data=${
|
|
1527
1691
|
{
|
|
1528
1692
|
variant: Buttons.Button.Variant.TOOLBAR,
|
|
@@ -20,7 +20,7 @@ export class RecorderPanel extends UI.Panel.Panel {
|
|
|
20
20
|
super(RecorderPanel.panelName);
|
|
21
21
|
this.element.setAttribute('jslog', `${VisualLogging.panel('chrome-recorder').track({resize: true})}`);
|
|
22
22
|
this.#controller = new RecorderController();
|
|
23
|
-
this.
|
|
23
|
+
this.#controller.show(this.contentElement);
|
|
24
24
|
this.setHideOnDetach();
|
|
25
25
|
}
|
|
26
26
|
|
|
@@ -11,7 +11,7 @@ import * as Host from '../../core/host/host.js';
|
|
|
11
11
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
12
12
|
import * as Platform from '../../core/platform/platform.js';
|
|
13
13
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
14
|
-
import
|
|
14
|
+
import * as Bindings from '../../models/bindings/bindings.js';
|
|
15
15
|
import * as Persistence from '../../models/persistence/persistence.js';
|
|
16
16
|
import * as TextUtils from '../../models/text_utils/text_utils.js';
|
|
17
17
|
import * as Workspace from '../../models/workspace/workspace.js';
|
|
@@ -135,7 +135,8 @@ export class NetworkNavigatorView extends NavigatorView {
|
|
|
135
135
|
|
|
136
136
|
override acceptProject(project: Workspace.Workspace.Project): boolean {
|
|
137
137
|
return project.type() === Workspace.Workspace.projectTypes.Network &&
|
|
138
|
-
SDK.TargetManager.TargetManager.instance().isInScope(
|
|
138
|
+
SDK.TargetManager.TargetManager.instance().isInScope(
|
|
139
|
+
Bindings.NetworkProject.NetworkProject.getTargetForProject(project));
|
|
139
140
|
}
|
|
140
141
|
|
|
141
142
|
onScopeChange(): void {
|
|
@@ -345,9 +345,6 @@ export class SourcesView extends Common.ObjectWrapper.eventMixin<EventTypes, typ
|
|
|
345
345
|
if (view instanceof UI.View.SimpleView) {
|
|
346
346
|
void view.toolbarItems().then(items => {
|
|
347
347
|
this.#scriptViewToolbar.removeToolbarItems();
|
|
348
|
-
for (const action of getRegisteredEditorActions()) {
|
|
349
|
-
this.#scriptViewToolbar.appendToolbarItem(action.getOrCreateButton(this));
|
|
350
|
-
}
|
|
351
348
|
if (Array.isArray(items)) {
|
|
352
349
|
items.map(item => this.#scriptViewToolbar.appendToolbarItem(item));
|
|
353
350
|
} else {
|
|
@@ -657,20 +654,6 @@ export interface EventTypes {
|
|
|
657
654
|
[Events.EDITOR_SELECTED]: Workspace.UISourceCode.UISourceCode;
|
|
658
655
|
}
|
|
659
656
|
|
|
660
|
-
export interface EditorAction {
|
|
661
|
-
getOrCreateButton(sourcesView: SourcesView): UI.Toolbar.ToolbarButton;
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
const registeredEditorActions: Array<() => EditorAction> = [];
|
|
665
|
-
|
|
666
|
-
export function registerEditorAction(editorAction: () => EditorAction): void {
|
|
667
|
-
registeredEditorActions.push(editorAction);
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
export function getRegisteredEditorActions(): EditorAction[] {
|
|
671
|
-
return registeredEditorActions.map(editorAction => editorAction());
|
|
672
|
-
}
|
|
673
|
-
|
|
674
657
|
export class SwitchFileActionDelegate implements UI.ActionRegistration.ActionDelegate {
|
|
675
658
|
private static nextFile(currentUISourceCode: Workspace.UISourceCode.UISourceCode): Workspace.UISourceCode.UISourceCode
|
|
676
659
|
|null {
|
|
@@ -6,8 +6,10 @@
|
|
|
6
6
|
|
|
7
7
|
import * as Common from '../../core/common/common.js';
|
|
8
8
|
import * as Host from '../../core/host/host.js';
|
|
9
|
+
import * as i18n from '../../core/i18n/i18n.js';
|
|
9
10
|
import * as FormatterActions from '../../entrypoints/formatter_worker/FormatterActions.js'; // eslint-disable-line @devtools/es-modules-import
|
|
10
11
|
import * as AiCodeCompletion from '../../models/ai_code_completion/ai_code_completion.js';
|
|
12
|
+
import * as Formatter from '../../models/formatter/formatter.js';
|
|
11
13
|
import * as IssuesManager from '../../models/issues_manager/issues_manager.js';
|
|
12
14
|
import * as Persistence from '../../models/persistence/persistence.js';
|
|
13
15
|
import * as TextUtils from '../../models/text_utils/text_utils.js';
|
|
@@ -30,6 +32,15 @@ import {ResourceOriginPlugin} from './ResourceOriginPlugin.js';
|
|
|
30
32
|
import {SnippetsPlugin} from './SnippetsPlugin.js';
|
|
31
33
|
import {SourcesPanel} from './SourcesPanel.js';
|
|
32
34
|
|
|
35
|
+
const UIStrings = {
|
|
36
|
+
/**
|
|
37
|
+
* @description Title of the format button
|
|
38
|
+
*/
|
|
39
|
+
format: 'Format',
|
|
40
|
+
} as const;
|
|
41
|
+
const str_ = i18n.i18n.registerUIStrings('panels/sources/UISourceCodeFrame.ts', UIStrings);
|
|
42
|
+
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
43
|
+
|
|
33
44
|
export class UISourceCodeFrame extends Common.ObjectWrapper
|
|
34
45
|
.eventMixin<EventTypes, typeof SourceFrame.SourceFrame.SourceFrameImpl>(
|
|
35
46
|
SourceFrame.SourceFrame.SourceFrameImpl) {
|
|
@@ -290,6 +301,24 @@ export class UISourceCodeFrame extends Common.ObjectWrapper
|
|
|
290
301
|
this.maybeSetContent(this.#uiSourceCode.workingCopyContentData());
|
|
291
302
|
}
|
|
292
303
|
|
|
304
|
+
async #formatSourceInPlace(): Promise<void> {
|
|
305
|
+
const contentDataOrError = await this.workingCopy();
|
|
306
|
+
if (TextUtils.ContentData.ContentData.isError(contentDataOrError)) {
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
const content = TextUtils.ContentData.ContentData.textOr(contentDataOrError, '');
|
|
310
|
+
const {formattedContent, formattedMapping} = await Formatter.ScriptFormatter.format(
|
|
311
|
+
Common.Settings.Settings.instance(), this.#uiSourceCode.contentType(), this.contentType, content);
|
|
312
|
+
if (this.#uiSourceCode.workingCopy() === formattedContent) {
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
const selection = this.textEditor.toLineColumn(this.textEditor.state.selection.main.head);
|
|
316
|
+
const [lineNumber, columnNumber] =
|
|
317
|
+
formattedMapping.originalToFormatted(selection.lineNumber, selection.columnNumber);
|
|
318
|
+
this.#uiSourceCode.setWorkingCopy(formattedContent);
|
|
319
|
+
this.revealPosition({lineNumber, columnNumber});
|
|
320
|
+
}
|
|
321
|
+
|
|
293
322
|
private onWorkingCopyCommitted(): void {
|
|
294
323
|
if (!this.#muteSourceCodeEvents) {
|
|
295
324
|
this.maybeSetContent(this.uiSourceCode().workingCopyContentData());
|
|
@@ -433,6 +462,19 @@ export class UISourceCodeFrame extends Common.ObjectWrapper
|
|
|
433
462
|
|
|
434
463
|
override async toolbarItems(): Promise<UI.Toolbar.ToolbarItem[]> {
|
|
435
464
|
const leftToolbarItems = await super.toolbarItems();
|
|
465
|
+
|
|
466
|
+
const isEditable = Persistence.Persistence.PersistenceImpl.instance().hasEditableContent(this.#uiSourceCode);
|
|
467
|
+
const isJavaScript = Common.ResourceType.ResourceType.isJavaScriptMimeType(this.contentType);
|
|
468
|
+
const isInplaceFormattable = isEditable && isJavaScript;
|
|
469
|
+
|
|
470
|
+
if (isInplaceFormattable) {
|
|
471
|
+
const formatButton = new UI.Toolbar.ToolbarButton(i18nString(UIStrings.format), 'brackets');
|
|
472
|
+
formatButton.addEventListener(UI.Toolbar.ToolbarButton.Events.CLICK, () => {
|
|
473
|
+
void this.#formatSourceInPlace();
|
|
474
|
+
});
|
|
475
|
+
leftToolbarItems.unshift(formatButton);
|
|
476
|
+
}
|
|
477
|
+
|
|
436
478
|
const rightToolbarItems = [];
|
|
437
479
|
for (const plugin of this.plugins) {
|
|
438
480
|
leftToolbarItems.push(...plugin.leftToolbarItems());
|
|
@@ -18,7 +18,6 @@ import * as EditingLocationHistoryManager from './EditingLocationHistoryManager.
|
|
|
18
18
|
import * as FilePathScoreFunction from './FilePathScoreFunction.js';
|
|
19
19
|
import * as FilteredUISourceCodeListProvider from './FilteredUISourceCodeListProvider.js';
|
|
20
20
|
import * as GoToLineQuickOpen from './GoToLineQuickOpen.js';
|
|
21
|
-
import * as InplaceFormatterEditorAction from './InplaceFormatterEditorAction.js';
|
|
22
21
|
import * as NavigatorView from './NavigatorView.js';
|
|
23
22
|
import * as OpenFileQuickOpen from './OpenFileQuickOpen.js';
|
|
24
23
|
import * as OutlineQuickOpen from './OutlineQuickOpen.js';
|
|
@@ -54,7 +53,6 @@ export {
|
|
|
54
53
|
FilePathScoreFunction,
|
|
55
54
|
FilteredUISourceCodeListProvider,
|
|
56
55
|
GoToLineQuickOpen,
|
|
57
|
-
InplaceFormatterEditorAction,
|
|
58
56
|
NavigatorView,
|
|
59
57
|
OpenFileQuickOpen,
|
|
60
58
|
OutlineQuickOpen,
|
|
@@ -168,7 +168,6 @@ export const enum VisualLoggingTrackName {
|
|
|
168
168
|
THREAD_MAIN = 'thread.main',
|
|
169
169
|
THREAD_FRAME = 'thread.frame',
|
|
170
170
|
THREAD_WORKER = 'thread.worker',
|
|
171
|
-
THREAD_AUCTION_WORKLET = 'thread.auction-worklet',
|
|
172
171
|
THREAD_RASTERIZER = 'thread.rasterizer',
|
|
173
172
|
THREAD_POOL = 'thread.pool',
|
|
174
173
|
THREAD_OTHER = 'thread.other',
|
|
@@ -301,8 +300,6 @@ export class CompatibilityTracksAppender {
|
|
|
301
300
|
}
|
|
302
301
|
case Trace.Handlers.Threads.ThreadType.WORKER:
|
|
303
302
|
return 3;
|
|
304
|
-
case Trace.Handlers.Threads.ThreadType.AUCTION_WORKLET:
|
|
305
|
-
return 3;
|
|
306
303
|
case Trace.Handlers.Threads.ThreadType.RASTERIZER:
|
|
307
304
|
return 4;
|
|
308
305
|
case Trace.Handlers.Threads.ThreadType.THREAD_POOL:
|
|
@@ -328,20 +325,6 @@ export class CompatibilityTracksAppender {
|
|
|
328
325
|
continue;
|
|
329
326
|
}
|
|
330
327
|
|
|
331
|
-
const matchingWorklet = this.#parsedTrace.data.AuctionWorklets.worklets.get(pid);
|
|
332
|
-
if (matchingWorklet) {
|
|
333
|
-
// Each AuctionWorklet has two key threads:
|
|
334
|
-
// 1. the Utility Thread
|
|
335
|
-
// 2. the V8 Helper Thread - either a bidder or seller. see buildNameForAuctionWorklet()
|
|
336
|
-
// There are other threads in a worklet process, but we don't render them.
|
|
337
|
-
const tids = [matchingWorklet.args.data.utilityThread.tid, matchingWorklet.args.data.v8HelperThread.tid];
|
|
338
|
-
if (tids.includes(tid)) {
|
|
339
|
-
this.#threadAppenders.push(new ThreadAppender(
|
|
340
|
-
this, this.#parsedTrace, pid, tid, '', Trace.Handlers.Threads.ThreadType.AUCTION_WORKLET, entries, tree));
|
|
341
|
-
}
|
|
342
|
-
continue;
|
|
343
|
-
}
|
|
344
|
-
|
|
345
328
|
// The Common case… Add the main thread, or iframe, or thread pool, etc.
|
|
346
329
|
this.#threadAppenders.push(new ThreadAppender(this, this.#parsedTrace, pid, tid, name, type, entries, tree));
|
|
347
330
|
}
|