chrome-devtools-frontend 1.0.1667564 → 1.0.1668390
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/devtools-setting-migration/SKILL.md +290 -0
- package/.agents/skills/ui-eng-vision-widget-promoter/SKILL.md +11 -4
- package/.agents/skills/ui-widgets/SKILL.md +25 -1
- package/docs/ui_engineering.md +44 -1
- package/front_end/core/common/Settings.ts +11 -4
- package/front_end/core/root/Runtime.ts +5 -0
- package/front_end/core/sdk/CSSModel.test.api.ts +102 -0
- package/front_end/core/sdk/CSSModel.ts +3 -2
- package/front_end/core/sdk/DebuggerModel.ts +3 -2
- package/front_end/core/sdk/SDKSettings.ts +19 -0
- package/front_end/core/sdk/sdk-meta.ts +0 -62
- package/front_end/core/sdk/sdk.ts +2 -0
- package/front_end/entrypoints/main/MainImpl.ts +10 -3
- package/front_end/foundation/Universe.ts +7 -0
- package/front_end/models/ai_assistance/AiAgent2.ts +1 -1
- package/front_end/models/ai_assistance/BuiltInAi.ts +11 -6
- package/front_end/models/ai_assistance/ChangeManager.ts +17 -1
- package/front_end/models/javascript_metadata/NativeFunctions.js +22 -9
- package/front_end/models/source_map_scopes/NamesResolver.ts +23 -17
- package/front_end/panels/application/ServiceWorkerUpdateCycleView.ts +78 -118
- package/front_end/panels/application/preloading/components/preloadingDetailsReportView.css +13 -13
- package/front_end/panels/console/ConsoleInsightTeaser.ts +3 -2
- package/front_end/panels/emulation/DeviceModeToolbar.ts +2 -2
- package/front_end/panels/emulation/DeviceModeView.ts +63 -104
- package/front_end/panels/sensors/LocationsSettingsTab.ts +244 -34
- package/front_end/panels/sensors/locationsSettingsTab.css +74 -0
- package/front_end/panels/sources/DebuggerPlugin.ts +2 -2
- package/front_end/panels/sources/sources-meta.ts +55 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/legacy/Dialog.ts +93 -4
- package/front_end/ui/legacy/InspectorView.ts +1 -5
- package/front_end/ui/legacy/PopoverHelper.ts +5 -5
- package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
- package/package.json +1 -1
|
@@ -452,30 +452,6 @@ const UIStrings = {
|
|
|
452
452
|
*/
|
|
453
453
|
networkCacheExplanation:
|
|
454
454
|
'Disabling the network cache will simulate a network experience similar to a first time visitor.',
|
|
455
|
-
/**
|
|
456
|
-
* @description Setting under the Sources category to toggle usage of JavaScript source maps.
|
|
457
|
-
*/
|
|
458
|
-
javaScriptSourceMaps: 'JavaScript source maps',
|
|
459
|
-
/**
|
|
460
|
-
* @description Title of an option under the Sources category that can be invoked through the Command Menu.
|
|
461
|
-
*/
|
|
462
|
-
enableJavaScriptSourceMaps: 'Enable JavaScript source maps',
|
|
463
|
-
/**
|
|
464
|
-
* @description Title of an option under the Sources category that can be invoked through the Command Menu.
|
|
465
|
-
*/
|
|
466
|
-
disableJavaScriptSourceMaps: 'Disable JavaScript source maps',
|
|
467
|
-
/**
|
|
468
|
-
* @description Title of a setting under the Sources category.
|
|
469
|
-
*/
|
|
470
|
-
cssSourceMaps: 'CSS source maps',
|
|
471
|
-
/**
|
|
472
|
-
* @description Title of an option under the Sources category that can be invoked through the Command Menu.
|
|
473
|
-
*/
|
|
474
|
-
enableCssSourceMaps: 'Enable CSS source maps',
|
|
475
|
-
/**
|
|
476
|
-
* @description Title of an option under the Sources category that can be invoked through the Command Menu.
|
|
477
|
-
*/
|
|
478
|
-
disableCssSourceMaps: 'Disable CSS source maps',
|
|
479
455
|
/**
|
|
480
456
|
* @description Title of a setting under the Console category in Settings.
|
|
481
457
|
*/
|
|
@@ -1391,44 +1367,6 @@ Common.Settings.registerSettingExtension({
|
|
|
1391
1367
|
},
|
|
1392
1368
|
});
|
|
1393
1369
|
|
|
1394
|
-
Common.Settings.registerSettingExtension({
|
|
1395
|
-
category: Common.Settings.SettingCategory.SOURCES,
|
|
1396
|
-
storageType: Common.Settings.SettingStorageType.SYNCED,
|
|
1397
|
-
title: i18nLazyString(UIStrings.javaScriptSourceMaps),
|
|
1398
|
-
settingName: 'js-source-maps-enabled',
|
|
1399
|
-
settingType: Common.Settings.SettingType.BOOLEAN,
|
|
1400
|
-
defaultValue: true,
|
|
1401
|
-
options: [
|
|
1402
|
-
{
|
|
1403
|
-
value: true,
|
|
1404
|
-
title: i18nLazyString(UIStrings.enableJavaScriptSourceMaps),
|
|
1405
|
-
},
|
|
1406
|
-
{
|
|
1407
|
-
value: false,
|
|
1408
|
-
title: i18nLazyString(UIStrings.disableJavaScriptSourceMaps),
|
|
1409
|
-
},
|
|
1410
|
-
],
|
|
1411
|
-
});
|
|
1412
|
-
|
|
1413
|
-
Common.Settings.registerSettingExtension({
|
|
1414
|
-
category: Common.Settings.SettingCategory.SOURCES,
|
|
1415
|
-
storageType: Common.Settings.SettingStorageType.SYNCED,
|
|
1416
|
-
title: i18nLazyString(UIStrings.cssSourceMaps),
|
|
1417
|
-
settingName: 'css-source-maps-enabled',
|
|
1418
|
-
settingType: Common.Settings.SettingType.BOOLEAN,
|
|
1419
|
-
defaultValue: true,
|
|
1420
|
-
options: [
|
|
1421
|
-
{
|
|
1422
|
-
value: true,
|
|
1423
|
-
title: i18nLazyString(UIStrings.enableCssSourceMaps),
|
|
1424
|
-
},
|
|
1425
|
-
{
|
|
1426
|
-
value: false,
|
|
1427
|
-
title: i18nLazyString(UIStrings.disableCssSourceMaps),
|
|
1428
|
-
},
|
|
1429
|
-
],
|
|
1430
|
-
});
|
|
1431
|
-
|
|
1432
1370
|
Common.Settings.registerSettingExtension({
|
|
1433
1371
|
category: Common.Settings.SettingCategory.CONSOLE,
|
|
1434
1372
|
storageType: Common.Settings.SettingStorageType.SYNCED,
|
|
@@ -75,6 +75,7 @@ import * as ScopeTreeCache from './ScopeTreeCache.js';
|
|
|
75
75
|
import * as ScreenCaptureModel from './ScreenCaptureModel.js';
|
|
76
76
|
import * as Script from './Script.js';
|
|
77
77
|
import * as SDKModel from './SDKModel.js';
|
|
78
|
+
import * as SDKSettings from './SDKSettings.js';
|
|
78
79
|
import * as SecurityOriginManager from './SecurityOriginManager.js';
|
|
79
80
|
import * as ServerSentEventProtocol from './ServerSentEventsProtocol.js';
|
|
80
81
|
import * as ServerTiming from './ServerTiming.js';
|
|
@@ -160,6 +161,7 @@ export {
|
|
|
160
161
|
ScreenCaptureModel,
|
|
161
162
|
Script,
|
|
162
163
|
SDKModel,
|
|
164
|
+
SDKSettings,
|
|
163
165
|
SecurityOriginManager,
|
|
164
166
|
ServerSentEventProtocol,
|
|
165
167
|
ServerTiming,
|
|
@@ -373,8 +373,15 @@ export class MainImpl {
|
|
|
373
373
|
Root.ExperimentNames.ExperimentName.PROTOCOL_MONITOR, protocolMonitorExperiment);
|
|
374
374
|
|
|
375
375
|
// Debugging
|
|
376
|
-
Root.Runtime.experiments.
|
|
377
|
-
|
|
376
|
+
const instrumentationBreakpointsExperiment = Root.Runtime.experiments.registerHostExperiment({
|
|
377
|
+
name: Root.ExperimentNames.ExperimentName.INSTRUMENTATION_BREAKPOINTS,
|
|
378
|
+
title: 'Instrumentation breakpoints',
|
|
379
|
+
aboutFlag: 'devtools-instrumentation-breakpoints',
|
|
380
|
+
isEnabled: Root.Runtime.hostConfig.devToolsInstrumentationBreakpoints?.enabled ?? false,
|
|
381
|
+
requiresChromeRestart: false,
|
|
382
|
+
});
|
|
383
|
+
this.#migrateValueFromLegacyToHostExperiment(Root.ExperimentNames.ExperimentName.INSTRUMENTATION_BREAKPOINTS,
|
|
384
|
+
instrumentationBreakpointsExperiment);
|
|
378
385
|
|
|
379
386
|
Root.Runtime.experiments.registerHostExperiment({
|
|
380
387
|
name: Root.ExperimentNames.ExperimentName.DURABLE_MESSAGES,
|
|
@@ -471,7 +478,7 @@ export class MainImpl {
|
|
|
471
478
|
void this.#universe.liveMetrics.enable();
|
|
472
479
|
CrUXManager.CrUXManager.instance();
|
|
473
480
|
|
|
474
|
-
const builtInAi =
|
|
481
|
+
const builtInAi = this.#universe.builtInAi;
|
|
475
482
|
builtInAi.addEventListener(
|
|
476
483
|
AiAssistanceModel.BuiltInAi.Events.DOWNLOADED_AND_SESSION_CREATED,
|
|
477
484
|
() => Snackbar.Snackbar.Snackbar.show({message: i18nString(UIStrings.aiModelDownloaded)}));
|
|
@@ -216,6 +216,9 @@ export class Universe {
|
|
|
216
216
|
const aiHistoryStorage = new AiAssistance.AiHistoryStorage.AiHistoryStorage(settings);
|
|
217
217
|
context.set(AiAssistance.AiHistoryStorage.AiHistoryStorage, aiHistoryStorage);
|
|
218
218
|
|
|
219
|
+
const builtInAi = new AiAssistance.BuiltInAi.BuiltInAi();
|
|
220
|
+
context.set(AiAssistance.BuiltInAi.BuiltInAi, builtInAi);
|
|
221
|
+
|
|
219
222
|
this.autofillManager = new AutofillManager.AutofillManager.AutofillManager(targetManager, frameManager);
|
|
220
223
|
context.set(AutofillManager.AutofillManager.AutofillManager, this.autofillManager);
|
|
221
224
|
}
|
|
@@ -233,6 +236,10 @@ export class Universe {
|
|
|
233
236
|
return this.context.get(AiAssistance.AiHistoryStorage.AiHistoryStorage);
|
|
234
237
|
}
|
|
235
238
|
|
|
239
|
+
get builtInAi(): AiAssistance.BuiltInAi.BuiltInAi {
|
|
240
|
+
return this.context.get(AiAssistance.BuiltInAi.BuiltInAi);
|
|
241
|
+
}
|
|
242
|
+
|
|
236
243
|
get breakpointManager(): Breakpoints.BreakpointManager.BreakpointManager {
|
|
237
244
|
return this.context.get(Breakpoints.BreakpointManager.BreakpointManager);
|
|
238
245
|
}
|
|
@@ -82,7 +82,7 @@ export class AiAgent2 extends AiAgent<unknown> {
|
|
|
82
82
|
|
|
83
83
|
constructor(opts: AiAgent2Options) {
|
|
84
84
|
super(opts);
|
|
85
|
-
this.#changes = new ChangeManager(opts.targetManager);
|
|
85
|
+
this.#changes = opts.changeManager ?? new ChangeManager(opts.targetManager);
|
|
86
86
|
this.#lighthouseRecording = opts.lighthouseRecording;
|
|
87
87
|
this.#execJs = opts.execJs ?? executeJsCode;
|
|
88
88
|
this.#allowedOrigin = opts.allowedOrigin;
|
|
@@ -6,8 +6,6 @@ import * as Common from '../../core/common/common.js';
|
|
|
6
6
|
import * as Host from '../../core/host/host.js';
|
|
7
7
|
import * as Root from '../../core/root/root.js';
|
|
8
8
|
|
|
9
|
-
let builtInAiInstance: BuiltInAi|undefined;
|
|
10
|
-
|
|
11
9
|
export interface LanguageModel {
|
|
12
10
|
promptStreaming: (arg0: string, opts?: {
|
|
13
11
|
signal?: AbortSignal,
|
|
@@ -33,10 +31,11 @@ export class BuiltInAi extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
|
|
|
33
31
|
#currentlyCreatingSession = false;
|
|
34
32
|
|
|
35
33
|
static instance(): BuiltInAi {
|
|
36
|
-
if (
|
|
37
|
-
|
|
34
|
+
if (!Root.DevToolsContext.globalInstance().has(BuiltInAi)) {
|
|
35
|
+
Root.DevToolsContext.globalInstance().set(BuiltInAi, new BuiltInAi());
|
|
38
36
|
}
|
|
39
|
-
|
|
37
|
+
|
|
38
|
+
return Root.DevToolsContext.globalInstance().get(BuiltInAi);
|
|
40
39
|
}
|
|
41
40
|
|
|
42
41
|
constructor() {
|
|
@@ -107,6 +106,12 @@ export class BuiltInAi extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
|
|
|
107
106
|
}
|
|
108
107
|
|
|
109
108
|
#isGpuAvailable(): boolean {
|
|
109
|
+
// In node-based API tests, there is no global `document` available. Since this
|
|
110
|
+
// class is instantiated during Universe bootstrapping, we need to guard against
|
|
111
|
+
// using document when not in the browser.
|
|
112
|
+
if (typeof document === 'undefined') {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
110
115
|
const canvas = document.createElement('canvas');
|
|
111
116
|
try {
|
|
112
117
|
const webgl = canvas.getContext('webgl');
|
|
@@ -197,7 +202,7 @@ Your instructions are as follows:
|
|
|
197
202
|
}
|
|
198
203
|
|
|
199
204
|
static removeInstance(): void {
|
|
200
|
-
|
|
205
|
+
Root.DevToolsContext.globalInstance().delete(BuiltInAi);
|
|
201
206
|
}
|
|
202
207
|
|
|
203
208
|
async * getConsoleInsight(prompt: string, abortController: AbortController): AsyncGenerator<string> {
|
|
@@ -25,13 +25,15 @@ function formatStyles(styles: Record<string, string>, indent = 2): string {
|
|
|
25
25
|
* primarily for stylesheet generation based on all changes.
|
|
26
26
|
*/
|
|
27
27
|
export class ChangeManager {
|
|
28
|
+
readonly #targetManager: SDK.TargetManager.TargetManager;
|
|
28
29
|
readonly #stylesheetMutex = new Common.Mutex.Mutex();
|
|
29
30
|
readonly #cssModelToStylesheetId =
|
|
30
31
|
new Map<SDK.CSSModel.CSSModel, Map<Protocol.Page.FrameId, Protocol.DOM.StyleSheetId>>();
|
|
31
32
|
readonly #stylesheetChanges = new Map<Protocol.DOM.StyleSheetId, Change[]>();
|
|
32
33
|
|
|
33
34
|
constructor(targetManager: SDK.TargetManager.TargetManager = SDK.TargetManager.TargetManager.instance()) {
|
|
34
|
-
targetManager
|
|
35
|
+
this.#targetManager = targetManager;
|
|
36
|
+
this.#targetManager.addModelListener(
|
|
35
37
|
SDK.ResourceTreeModel.ResourceTreeModel,
|
|
36
38
|
SDK.ResourceTreeModel.Events.PrimaryPageChanged,
|
|
37
39
|
this.clear,
|
|
@@ -39,6 +41,20 @@ export class ChangeManager {
|
|
|
39
41
|
);
|
|
40
42
|
}
|
|
41
43
|
|
|
44
|
+
dispose(): void {
|
|
45
|
+
this.#targetManager.removeModelListener(
|
|
46
|
+
SDK.ResourceTreeModel.ResourceTreeModel,
|
|
47
|
+
SDK.ResourceTreeModel.Events.PrimaryPageChanged,
|
|
48
|
+
this.clear,
|
|
49
|
+
this,
|
|
50
|
+
);
|
|
51
|
+
for (const cssModel of this.#cssModelToStylesheetId.keys()) {
|
|
52
|
+
cssModel.removeEventListener(SDK.CSSModel.Events.ModelDisposed, this.#onCssModelDisposed, this);
|
|
53
|
+
}
|
|
54
|
+
this.#cssModelToStylesheetId.clear();
|
|
55
|
+
this.#stylesheetChanges.clear();
|
|
56
|
+
}
|
|
57
|
+
|
|
42
58
|
async clear(): Promise<void> {
|
|
43
59
|
const models = Array.from(this.#cssModelToStylesheetId.keys());
|
|
44
60
|
const results = await Promise.allSettled(models.map(async model => {
|
|
@@ -117,11 +117,6 @@ export const NativeFunctions = [
|
|
|
117
117
|
signatures: [["id"]],
|
|
118
118
|
receivers: ["Clients","BackgroundFetchManager"]
|
|
119
119
|
},
|
|
120
|
-
{
|
|
121
|
-
name: "get",
|
|
122
|
-
signatures: [["entry"]],
|
|
123
|
-
receivers: ["RouteMap"]
|
|
124
|
-
},
|
|
125
120
|
{
|
|
126
121
|
name: "set",
|
|
127
122
|
signatures: [["v"]],
|
|
@@ -2003,6 +1998,11 @@ export const NativeFunctions = [
|
|
|
2003
1998
|
signatures: [["start","end"]],
|
|
2004
1999
|
receivers: ["SourceBuffer"]
|
|
2005
2000
|
},
|
|
2001
|
+
{
|
|
2002
|
+
name: "remove",
|
|
2003
|
+
signatures: [["slot"]],
|
|
2004
|
+
receivers: ["GPUResourceTable"]
|
|
2005
|
+
},
|
|
2006
2006
|
{
|
|
2007
2007
|
name: "remove",
|
|
2008
2008
|
signatures: [["manifest_ids"]],
|
|
@@ -3302,6 +3302,11 @@ export const NativeFunctions = [
|
|
|
3302
3302
|
signatures: [["response"]],
|
|
3303
3303
|
receivers: ["MediaKeySession"]
|
|
3304
3304
|
},
|
|
3305
|
+
{
|
|
3306
|
+
name: "update",
|
|
3307
|
+
signatures: [["slot","resource"]],
|
|
3308
|
+
receivers: ["GPUResourceTable"]
|
|
3309
|
+
},
|
|
3305
3310
|
{
|
|
3306
3311
|
name: "createObjectStore",
|
|
3307
3312
|
signatures: [["name","?options"]]
|
|
@@ -6685,6 +6690,14 @@ export const NativeFunctions = [
|
|
|
6685
6690
|
name: "writeTimestamp",
|
|
6686
6691
|
signatures: [["querySet","queryIndex"]]
|
|
6687
6692
|
},
|
|
6693
|
+
{
|
|
6694
|
+
name: "setResourceTable",
|
|
6695
|
+
signatures: [["table"]]
|
|
6696
|
+
},
|
|
6697
|
+
{
|
|
6698
|
+
name: "createResourceTable",
|
|
6699
|
+
signatures: [["descriptor"]]
|
|
6700
|
+
},
|
|
6688
6701
|
{
|
|
6689
6702
|
name: "GPUInternalError",
|
|
6690
6703
|
signatures: [["message"]]
|
|
@@ -6713,6 +6726,10 @@ export const NativeFunctions = [
|
|
|
6713
6726
|
name: "multiDrawIndexedIndirect",
|
|
6714
6727
|
signatures: [["indirectBuffer","indirectOffset","maxDrawCount","?drawCountBuffer","?drawCountBufferOffset"]]
|
|
6715
6728
|
},
|
|
6729
|
+
{
|
|
6730
|
+
name: "insert",
|
|
6731
|
+
signatures: [["resource"]]
|
|
6732
|
+
},
|
|
6716
6733
|
{
|
|
6717
6734
|
name: "GPUUncapturedErrorEvent",
|
|
6718
6735
|
signatures: [["type","gpuUncapturedErrorEventInitDict"]]
|
|
@@ -8469,10 +8486,6 @@ export const NativeFunctions = [
|
|
|
8469
8486
|
name: "removeProcessingInstruction",
|
|
8470
8487
|
signatures: [["pi"]]
|
|
8471
8488
|
},
|
|
8472
|
-
{
|
|
8473
|
-
name: "RouteEvent",
|
|
8474
|
-
signatures: [["type"]]
|
|
8475
|
-
},
|
|
8476
8489
|
{
|
|
8477
8490
|
name: "ResizeObserver",
|
|
8478
8491
|
signatures: [["callback"]]
|
|
@@ -187,21 +187,21 @@ const enum Punctuation {
|
|
|
187
187
|
EQUALS = 'equals',
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
-
const resolveDebuggerScope =
|
|
191
|
-
scope: SDK.DebuggerModel.ScopeChainEntry,
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
190
|
+
const resolveDebuggerScope =
|
|
191
|
+
async(scope: SDK.DebuggerModel.ScopeChainEntry,
|
|
192
|
+
debuggerWorkspaceBinding: Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding):
|
|
193
|
+
Promise<{variableMapping: Map<string, string>, thisMapping: string | null}> => {
|
|
194
|
+
if (!scope.callFrame()
|
|
195
|
+
.debuggerModel.target()
|
|
196
|
+
.targetManager()
|
|
197
|
+
.settings.resolve(SDK.SDKSettings.jsSourceMapsEnabledSettingDescriptor)
|
|
198
|
+
.get()) {
|
|
199
|
+
return {variableMapping: new Map(), thisMapping: null};
|
|
200
|
+
}
|
|
201
|
+
const script = scope.callFrame().script;
|
|
202
|
+
const scopeChain = await findScopeChainForDebuggerScope(scope);
|
|
203
|
+
return await resolveScope(script, scopeChain, debuggerWorkspaceBinding);
|
|
204
|
+
};
|
|
205
205
|
|
|
206
206
|
const resolveScope = async(script: SDK.Script.Script, scopeChain: Formatter.FormatterWorkerPool.ScopeTreeNode[],
|
|
207
207
|
debuggerWorkspaceBinding: Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding):
|
|
@@ -400,7 +400,10 @@ export const allVariablesInCallFrame = async(
|
|
|
400
400
|
callFrame: SDK.DebuggerModel.CallFrame,
|
|
401
401
|
debuggerWorkspaceBinding: Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding):
|
|
402
402
|
Promise<Map<string, string|null>> => {
|
|
403
|
-
if (!callFrame.debuggerModel.target()
|
|
403
|
+
if (!callFrame.debuggerModel.target()
|
|
404
|
+
.targetManager()
|
|
405
|
+
.settings.resolve(SDK.SDKSettings.jsSourceMapsEnabledSettingDescriptor)
|
|
406
|
+
.get()) {
|
|
404
407
|
return new Map<string, string|null>();
|
|
405
408
|
}
|
|
406
409
|
const cachedMap = cachedMapByCallFrame.get(callFrame);
|
|
@@ -443,7 +446,10 @@ export const allVariablesAtPosition =
|
|
|
443
446
|
if (!script) {
|
|
444
447
|
return reverseMapping;
|
|
445
448
|
}
|
|
446
|
-
if (!script.debuggerModel.target()
|
|
449
|
+
if (!script.debuggerModel.target()
|
|
450
|
+
.targetManager()
|
|
451
|
+
.settings.resolve(SDK.SDKSettings.jsSourceMapsEnabledSettingDescriptor)
|
|
452
|
+
.get()) {
|
|
447
453
|
return reverseMapping;
|
|
448
454
|
}
|
|
449
455
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
7
7
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
8
8
|
import * as Protocol from '../../generated/protocol.js';
|
|
9
|
-
import
|
|
9
|
+
import {html, render} from '../../ui/lit/lit.js';
|
|
10
10
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
11
11
|
|
|
12
12
|
const UIStrings = {
|
|
@@ -39,13 +39,16 @@ export class ServiceWorkerUpdateCycleView {
|
|
|
39
39
|
private registration: SDK.ServiceWorkerManager.ServiceWorkerRegistration;
|
|
40
40
|
private rows: HTMLTableRowElement[];
|
|
41
41
|
private selectedRowIndex: number;
|
|
42
|
+
private expandedRows = new Set<string>();
|
|
42
43
|
tableElement: HTMLElement;
|
|
43
44
|
constructor(registration: SDK.ServiceWorkerManager.ServiceWorkerRegistration) {
|
|
44
45
|
this.registration = registration;
|
|
45
46
|
this.rows = [];
|
|
46
47
|
this.selectedRowIndex = -1;
|
|
47
48
|
this.tableElement = document.createElement('table');
|
|
48
|
-
this.
|
|
49
|
+
this.tableElement.classList.add('service-worker-update-timing-table');
|
|
50
|
+
this.tableElement.setAttribute('jslog', `${VisualLogging.tree('update-timing-table')}`);
|
|
51
|
+
this.refresh();
|
|
49
52
|
}
|
|
50
53
|
|
|
51
54
|
calculateServiceWorkerUpdateRanges(): ServiceWorkerUpdateRange[] {
|
|
@@ -132,119 +135,87 @@ export class ServiceWorkerUpdateCycleView {
|
|
|
132
135
|
return [];
|
|
133
136
|
}
|
|
134
137
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
+
refresh(): void {
|
|
139
|
+
const tableHeader = html`
|
|
140
|
+
<tr class="service-worker-update-timing-table-header">
|
|
141
|
+
<td>${i18nString(UIStrings.version)}</td>
|
|
142
|
+
<td>${i18nString(UIStrings.updateActivity)}</td>
|
|
143
|
+
<td>${i18nString(UIStrings.timeline)}</td>
|
|
144
|
+
</tr>
|
|
145
|
+
`;
|
|
138
146
|
const timeRanges = this.calculateServiceWorkerUpdateRanges();
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
UI.UIUtils.createTextChild(serverHeader.createChild('td'), i18nString(UIStrings.updateActivity));
|
|
146
|
-
UI.UIUtils.createTextChild(serverHeader.createChild('td'), i18nString(UIStrings.timeline));
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
private removeRows(): void {
|
|
150
|
-
const rows = this.tableElement.getElementsByTagName('tr');
|
|
151
|
-
while (rows[0]) {
|
|
152
|
-
if (rows[0].parentNode) {
|
|
153
|
-
rows[0].parentNode.removeChild(rows[0]);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
this.rows = [];
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
private updateTimingTable(timeRanges: ServiceWorkerUpdateRange[]): void {
|
|
160
|
-
this.selectedRowIndex = -1;
|
|
161
|
-
this.removeRows();
|
|
162
|
-
this.createTimingTableHead();
|
|
163
|
-
const timeRangeArray = timeRanges;
|
|
164
|
-
if (timeRangeArray.length === 0) {
|
|
147
|
+
if (timeRanges.length === 0) {
|
|
148
|
+
// clang-format off
|
|
149
|
+
// eslint-disable-next-line @devtools/no-lit-render-outside-of-view
|
|
150
|
+
render(tableHeader, this.tableElement, {host: this});
|
|
151
|
+
// clang-format on
|
|
152
|
+
this.rows = [];
|
|
165
153
|
return;
|
|
166
154
|
}
|
|
167
155
|
|
|
168
|
-
const startTimes =
|
|
169
|
-
const endTimes =
|
|
156
|
+
const startTimes = timeRanges.map(r => r.start);
|
|
157
|
+
const endTimes = timeRanges.map(r => r.end);
|
|
170
158
|
const startTime = startTimes.reduce((a, b) => Math.min(a, b));
|
|
171
159
|
const endTime = endTimes.reduce((a, b) => Math.max(a, b));
|
|
172
160
|
const scale = 100 / (endTime - startTime);
|
|
173
161
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
162
|
+
// clang-format off
|
|
163
|
+
// eslint-disable-next-line @devtools/no-lit-render-outside-of-view
|
|
164
|
+
render(html`
|
|
165
|
+
${tableHeader}
|
|
166
|
+
${timeRanges.map(range => {
|
|
167
|
+
const phaseName = range.phase;
|
|
168
|
+
const left = (scale * (range.start - startTime));
|
|
169
|
+
const right = (scale * (endTime - range.end));
|
|
170
|
+
const key = `${range.id}-${range.phase}`;
|
|
171
|
+
const expanded = this.expandedRows.has(key);
|
|
172
|
+
|
|
173
|
+
return html`
|
|
174
|
+
<tr class="service-worker-update-timeline" jslog=${VisualLogging.treeItem('update-timeline').track({
|
|
182
175
|
click: true,
|
|
183
176
|
resize: true,
|
|
184
177
|
keydown: 'ArrowLeft|ArrowRight|ArrowUp|ArrowDown|Enter|Space',
|
|
185
|
-
})}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
178
|
+
})}>
|
|
179
|
+
<td class="service-worker-update-timing-bar-clickable" tabindex="0" role="switch"
|
|
180
|
+
aria-checked=${expanded ? 'true' : 'false'}
|
|
181
|
+
@focus=${this.onFocus}
|
|
182
|
+
@keydown=${(e: Event) => this.onKeydown(e, key)}
|
|
183
|
+
@click=${(e: Event) => this.onClick(e, key)}
|
|
184
|
+
jslog=${VisualLogging.expand('timing-info').track({click: true})}>
|
|
185
|
+
#${range.id}
|
|
186
|
+
</td>
|
|
187
|
+
<td>${phaseName}</td>
|
|
188
|
+
<td>
|
|
189
|
+
<div class="service-worker-update-timing-row">
|
|
190
|
+
<span class="service-worker-update-timing-bar ${phaseName.toLowerCase()}"
|
|
191
|
+
style="left: ${left}%; right: ${right}%;">\u200B</span>
|
|
192
|
+
</div>
|
|
193
|
+
</td>
|
|
194
|
+
</tr>
|
|
195
|
+
<tr class="service-worker-update-timing-bar-details ${expanded ? 'service-worker-update-timing-bar-details-expanded' : 'service-worker-update-timing-bar-details-collapsed'}" tabindex="0">
|
|
196
|
+
<td colspan="3"><span>${i18nString(UIStrings.startTimeS, {PH1: new Date(range.start).toISOString()})}</span></td>
|
|
197
|
+
</tr>
|
|
198
|
+
<tr class="service-worker-update-timing-bar-details ${expanded ? 'service-worker-update-timing-bar-details-expanded' : 'service-worker-update-timing-bar-details-collapsed'}" tabindex="0">
|
|
199
|
+
<td colspan="3"><span>${i18nString(UIStrings.endTimeS, {PH1: new Date(range.end).toISOString()})}</span></td>
|
|
200
|
+
</tr>
|
|
201
|
+
`;
|
|
202
|
+
})}
|
|
203
|
+
`, this.tableElement, {host: this});
|
|
204
|
+
// clang-format on
|
|
205
|
+
|
|
206
|
+
this.rows = Array.from(this.tableElement.querySelectorAll<HTMLTableRowElement>('.service-worker-update-timeline'));
|
|
207
|
+
if (this.selectedRowIndex >= this.rows.length) {
|
|
208
|
+
this.selectedRowIndex = -1;
|
|
208
209
|
}
|
|
209
210
|
}
|
|
210
211
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
startRow.classList.add('service-worker-update-timing-bar-details-collapsed');
|
|
217
|
-
const startTimeItem = startRow.createChild('td');
|
|
218
|
-
startTimeItem.colSpan = 3;
|
|
219
|
-
const startTime = (new Date(range.start)).toISOString();
|
|
220
|
-
UI.UIUtils.createTextChild(startTimeItem.createChild('span'), i18nString(UIStrings.startTimeS, {PH1: startTime}));
|
|
221
|
-
startRow.tabIndex = 0;
|
|
222
|
-
|
|
223
|
-
const endRow = this.tableElement.createChild('tr', 'service-worker-update-timing-bar-details');
|
|
224
|
-
endRow.classList.add('service-worker-update-timing-bar-details-collapsed');
|
|
225
|
-
const endTimeItem = endRow.createChild('td');
|
|
226
|
-
endTimeItem.colSpan = 3;
|
|
227
|
-
const endTime = (new Date(range.end)).toISOString();
|
|
228
|
-
UI.UIUtils.createTextChild(endTimeItem.createChild('span'), i18nString(UIStrings.endTimeS, {PH1: endTime}));
|
|
229
|
-
endRow.tabIndex = 0;
|
|
230
|
-
|
|
231
|
-
tr.addEventListener('keydown', (event: Event) => {
|
|
232
|
-
this.onKeydown(event, startRow, endRow);
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
tr.addEventListener('click', (event: Event) => {
|
|
236
|
-
this.onClick(event, startRow, endRow);
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
private toggle(startRow: Element, endRow: Element, target: Element, expanded: boolean): void {
|
|
241
|
-
if (target.classList.contains('service-worker-update-timing-bar-clickable')) {
|
|
242
|
-
startRow.classList.toggle('service-worker-update-timing-bar-details-collapsed');
|
|
243
|
-
startRow.classList.toggle('service-worker-update-timing-bar-details-expanded');
|
|
244
|
-
endRow.classList.toggle('service-worker-update-timing-bar-details-collapsed');
|
|
245
|
-
endRow.classList.toggle('service-worker-update-timing-bar-details-expanded');
|
|
246
|
-
UI.ARIAUtils.setChecked(target, !expanded);
|
|
212
|
+
private toggle(key: string, expanded: boolean): void {
|
|
213
|
+
if (expanded) {
|
|
214
|
+
this.expandedRows.delete(key);
|
|
215
|
+
} else {
|
|
216
|
+
this.expandedRows.add(key);
|
|
247
217
|
}
|
|
218
|
+
this.refresh();
|
|
248
219
|
}
|
|
249
220
|
|
|
250
221
|
private onFocus(event: Event): void {
|
|
@@ -260,21 +231,20 @@ export class ServiceWorkerUpdateCycleView {
|
|
|
260
231
|
this.selectedRowIndex = this.rows.indexOf(tr);
|
|
261
232
|
}
|
|
262
233
|
|
|
263
|
-
private onKeydown(event: Event,
|
|
234
|
+
private onKeydown(event: Event, key: string): void {
|
|
264
235
|
if (!event.target) {
|
|
265
236
|
return;
|
|
266
237
|
}
|
|
267
|
-
const target: HTMLElement = event.target as HTMLElement;
|
|
268
238
|
const keyboardEvent = event as KeyboardEvent;
|
|
269
|
-
const expanded =
|
|
239
|
+
const expanded = this.expandedRows.has(key);
|
|
270
240
|
|
|
271
241
|
if (keyboardEvent.key === 'Enter' || keyboardEvent.key === ' ') {
|
|
272
|
-
this.toggle(
|
|
242
|
+
this.toggle(key, expanded);
|
|
273
243
|
event.preventDefault();
|
|
274
244
|
return;
|
|
275
245
|
}
|
|
276
246
|
if ((!expanded && keyboardEvent.key === 'ArrowRight') || (expanded && keyboardEvent.key === 'ArrowLeft')) {
|
|
277
|
-
this.toggle(
|
|
247
|
+
this.toggle(key, expanded);
|
|
278
248
|
event.preventDefault();
|
|
279
249
|
return;
|
|
280
250
|
}
|
|
@@ -346,21 +316,11 @@ export class ServiceWorkerUpdateCycleView {
|
|
|
346
316
|
this.focusRow(this.rows[this.selectedRowIndex]);
|
|
347
317
|
}
|
|
348
318
|
|
|
349
|
-
private onClick(event: Event,
|
|
350
|
-
const
|
|
351
|
-
|
|
352
|
-
return;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
const expanded = tr.getAttribute('aria-checked') === 'true';
|
|
356
|
-
this.toggle(startRow, endRow, tr, expanded);
|
|
319
|
+
private onClick(event: Event, key: string): void {
|
|
320
|
+
const expanded = this.expandedRows.has(key);
|
|
321
|
+
this.toggle(key, expanded);
|
|
357
322
|
event.preventDefault();
|
|
358
323
|
}
|
|
359
|
-
|
|
360
|
-
refresh(): void {
|
|
361
|
-
const timeRanges = this.calculateServiceWorkerUpdateRanges();
|
|
362
|
-
this.updateTimingTable(timeRanges);
|
|
363
|
-
}
|
|
364
324
|
}
|
|
365
325
|
|
|
366
326
|
export const enum ServiceWorkerUpdateNames {
|