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
|
@@ -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 '../../ui/components/report_view/report_view.js';
|
|
7
6
|
import '../../ui/kit/kit.js';
|
|
@@ -186,6 +185,116 @@ const {until} = Directives;
|
|
|
186
185
|
const {widget} = UI.Widget;
|
|
187
186
|
const {bindToSetting} = UI.UIUtils;
|
|
188
187
|
|
|
188
|
+
export interface SectionData {
|
|
189
|
+
manager: SDK.ServiceWorkerManager.ServiceWorkerManager;
|
|
190
|
+
registration: SDK.ServiceWorkerManager.ServiceWorkerRegistration;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export interface ServiceWorkersViewInput {
|
|
194
|
+
canManageServiceWorkers: boolean;
|
|
195
|
+
sections: SectionData[];
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function renderToolbar(): LitTemplate {
|
|
199
|
+
const updateOnReloadSetting =
|
|
200
|
+
Common.Settings.Settings.instance().createSetting('service-worker-update-on-reload', false);
|
|
201
|
+
const bypassServiceWorkerSetting = Common.Settings.Settings.instance().createSetting('bypass-service-worker', false);
|
|
202
|
+
// clang-format off
|
|
203
|
+
return html`<devtools-toolbar class="service-worker-toolbar">
|
|
204
|
+
${MobileThrottling.ThrottlingManager.throttlingManager().createOfflineToolbarCheckbox().element}
|
|
205
|
+
<devtools-checkbox title=${i18nString(UIStrings.onPageReloadForceTheService)}
|
|
206
|
+
${bindToSetting(updateOnReloadSetting)}>
|
|
207
|
+
${i18nString(UIStrings.updateOnReload)}
|
|
208
|
+
</devtools-checkbox>
|
|
209
|
+
<devtools-checkbox title=${i18nString(UIStrings.bypassTheServiceWorkerAndLoad)}
|
|
210
|
+
${bindToSetting(bypassServiceWorkerSetting)}>
|
|
211
|
+
${i18nString(UIStrings.bypassForNetwork)}
|
|
212
|
+
</devtools-checkbox>
|
|
213
|
+
</devtools-toolbar>`;
|
|
214
|
+
// clang-format on
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function renderOthersOriginView(): LitTemplate {
|
|
218
|
+
// clang-format off
|
|
219
|
+
return html`<div class="service-workers-other-origin"
|
|
220
|
+
jslog=${VisualLogging.section('other-origin')}>
|
|
221
|
+
<devtools-report>
|
|
222
|
+
<devtools-report-section-header>
|
|
223
|
+
${i18nString(UIStrings.serviceWorkersFromOtherOrigins)}
|
|
224
|
+
</devtools-report-section-header>
|
|
225
|
+
<div class="service-worker-section">
|
|
226
|
+
<devtools-link href="chrome://serviceworker-internals"
|
|
227
|
+
jslogcontext="view-all"
|
|
228
|
+
.allowPrivileged=${true}>
|
|
229
|
+
${i18nString(UIStrings.seeAllRegistrations)}
|
|
230
|
+
</devtools-link>
|
|
231
|
+
</div>
|
|
232
|
+
</devtools-report>
|
|
233
|
+
</div>`;
|
|
234
|
+
// clang-format on
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function getTimeStamp(registration: SDK.ServiceWorkerManager.ServiceWorkerRegistration): number {
|
|
238
|
+
const versions = registration.versionsByMode();
|
|
239
|
+
let timestamp: number|undefined = 0;
|
|
240
|
+
const active = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.ACTIVE);
|
|
241
|
+
const installing = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.INSTALLING);
|
|
242
|
+
const waiting = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.WAITING);
|
|
243
|
+
const redundant = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.REDUNDANT);
|
|
244
|
+
|
|
245
|
+
if (active) {
|
|
246
|
+
timestamp = active.scriptResponseTime;
|
|
247
|
+
} else if (waiting) {
|
|
248
|
+
timestamp = waiting.scriptResponseTime;
|
|
249
|
+
} else if (installing) {
|
|
250
|
+
timestamp = installing.scriptResponseTime;
|
|
251
|
+
} else if (redundant) {
|
|
252
|
+
timestamp = redundant.scriptResponseTime;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return timestamp || 0;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function renderOriginReport(input: ServiceWorkersViewInput): LitTemplate {
|
|
259
|
+
if (!input.canManageServiceWorkers) {
|
|
260
|
+
return nothing;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const sortedSections = [...input.sections];
|
|
264
|
+
sortedSections.sort((a, b) => {
|
|
265
|
+
const aTimestamp = getTimeStamp(a.registration);
|
|
266
|
+
const bTimestamp = getTimeStamp(b.registration);
|
|
267
|
+
return bTimestamp - aTimestamp;
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
// clang-format off
|
|
271
|
+
return html`<div class="service-workers-this-origin" jslog=${VisualLogging.section('this-origin')}>
|
|
272
|
+
<devtools-report .data=${{reportTitle: i18n.i18n.lockedString('Service workers')}}>
|
|
273
|
+
<div class="service-worker-toolbar" slot="toolbar">${renderToolbar()}</div>
|
|
274
|
+
${sortedSections.map(section => html`<devtools-widget class="service-worker-section-container" ${widget(Section, {section})}></devtools-widget>`)}
|
|
275
|
+
</devtools-report>
|
|
276
|
+
</div>`;
|
|
277
|
+
// clang-format on
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
type View = (input: ServiceWorkersViewInput, output: undefined, target: HTMLElement) => void;
|
|
281
|
+
export const DEFAULT_VIEW: View = (input, _output, target): void => {
|
|
282
|
+
// clang-format off
|
|
283
|
+
render(html`
|
|
284
|
+
<!-- This Origin Report -->
|
|
285
|
+
${renderOriginReport(input)}
|
|
286
|
+
${renderOthersOriginView()}`,
|
|
287
|
+
target, {
|
|
288
|
+
container: {
|
|
289
|
+
classes: [
|
|
290
|
+
'service-worker-list',
|
|
291
|
+
(input.sections.length > 0 ? 'service-worker-has-current' : 'service-worker-list-empty')
|
|
292
|
+
]
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
// clang-format on
|
|
296
|
+
};
|
|
297
|
+
|
|
189
298
|
let throttleDisabledForDebugging = false;
|
|
190
299
|
export const setThrottleDisabledForDebugging = (enable: boolean): void => {
|
|
191
300
|
throttleDisabledForDebugging = enable;
|
|
@@ -193,84 +302,55 @@ export const setThrottleDisabledForDebugging = (enable: boolean): void => {
|
|
|
193
302
|
|
|
194
303
|
export class ServiceWorkersView extends UI.Widget.VBox implements
|
|
195
304
|
SDK.TargetManager.SDKModelObserver<SDK.ServiceWorkerManager.ServiceWorkerManager> {
|
|
196
|
-
|
|
197
|
-
private readonly sections: Map<SDK.ServiceWorkerManager.ServiceWorkerRegistration, Section>;
|
|
305
|
+
private readonly sections: Map<SDK.ServiceWorkerManager.ServiceWorkerRegistration, SectionData>;
|
|
198
306
|
private manager: SDK.ServiceWorkerManager.ServiceWorkerManager|null;
|
|
199
307
|
private securityOriginManager: SDK.SecurityOriginManager.SecurityOriginManager|null;
|
|
200
|
-
private readonly sectionToRegistration:
|
|
201
|
-
WeakMap<UI.ReportView.Section, SDK.ServiceWorkerManager.ServiceWorkerRegistration>;
|
|
202
308
|
private readonly eventListeners:
|
|
203
309
|
Map<SDK.ServiceWorkerManager.ServiceWorkerManager, Common.EventTarget.EventDescriptor[]>;
|
|
310
|
+
readonly #output = undefined;
|
|
311
|
+
|
|
312
|
+
#view: (input: ServiceWorkersViewInput, output: undefined, target: HTMLElement) => void;
|
|
204
313
|
|
|
205
|
-
constructor() {
|
|
314
|
+
constructor(view: View = DEFAULT_VIEW) {
|
|
206
315
|
super({
|
|
207
316
|
jslog: `${VisualLogging.pane('service-workers')}`,
|
|
208
317
|
useShadowDom: true,
|
|
209
318
|
});
|
|
319
|
+
this.#view = view;
|
|
210
320
|
this.registerRequiredCSS(serviceWorkersViewStyles);
|
|
211
321
|
|
|
212
|
-
// TODO(crbug.com/1156978): Replace UI.ReportView.ReportView with ReportView.ts web component.
|
|
213
|
-
this.currentWorkersView = new UI.ReportView.ReportView(i18n.i18n.lockedString('Service workers'));
|
|
214
|
-
this.currentWorkersView.setBodyScrollable(false);
|
|
215
|
-
this.contentElement.classList.add('service-worker-list');
|
|
216
|
-
this.currentWorkersView.show(this.contentElement);
|
|
217
|
-
this.currentWorkersView.element.classList.add('service-workers-this-origin');
|
|
218
|
-
this.currentWorkersView.element.setAttribute('jslog', `${VisualLogging.section('this-origin')}`);
|
|
219
|
-
|
|
220
322
|
this.sections = new Map();
|
|
221
323
|
|
|
222
324
|
this.manager = null;
|
|
223
325
|
this.securityOriginManager = null;
|
|
224
326
|
|
|
225
|
-
this.sectionToRegistration = new WeakMap();
|
|
226
|
-
|
|
227
|
-
this.createOthersOriginView();
|
|
228
|
-
this.setupToolbar();
|
|
229
|
-
|
|
230
327
|
this.eventListeners = new Map();
|
|
231
328
|
SDK.TargetManager.TargetManager.instance().observeModels(SDK.ServiceWorkerManager.ServiceWorkerManager, this);
|
|
232
|
-
this.updateListVisibility();
|
|
233
329
|
}
|
|
234
330
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
render(html`<div class="service-workers-other-origin"
|
|
239
|
-
jslog=${VisualLogging.section('other-origin')}>
|
|
240
|
-
<devtools-report>
|
|
241
|
-
<devtools-report-section-header>
|
|
242
|
-
${i18nString(UIStrings.serviceWorkersFromOtherOrigins)}
|
|
243
|
-
</devtools-report-section-header>
|
|
244
|
-
<devtools-report-section>
|
|
245
|
-
<devtools-link href="chrome://serviceworker-internals"
|
|
246
|
-
jslogcontext="view-all"
|
|
247
|
-
.allowPrivileged=${true}>
|
|
248
|
-
${i18nString(UIStrings.seeAllRegistrations)}
|
|
249
|
-
</devtools-link>
|
|
250
|
-
</devtools-report-section>
|
|
251
|
-
</devtools-report>
|
|
252
|
-
</div>`, this.contentElement);
|
|
253
|
-
// clang-format on
|
|
331
|
+
override wasShown(): void {
|
|
332
|
+
super.wasShown();
|
|
333
|
+
this.requestUpdate();
|
|
254
334
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
335
|
+
|
|
336
|
+
override async performUpdate(): Promise<void> {
|
|
337
|
+
if (this.manager) {
|
|
338
|
+
for (const registration of this.manager.registrations().values()) {
|
|
339
|
+
const isCurrent = this.isOriginCurrent(registration.securityOrigin);
|
|
340
|
+
if (isCurrent && !this.sections.has(registration)) {
|
|
341
|
+
this.sections.set(registration, {manager: this.manager, registration});
|
|
342
|
+
} else if (!isCurrent && this.sections.has(registration)) {
|
|
343
|
+
this.sections.delete(registration);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
const input: ServiceWorkersViewInput = {
|
|
349
|
+
canManageServiceWorkers: this.manager !== null,
|
|
350
|
+
sections: Array.from(this.sections.values()).map(data => ({...data})),
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
this.#view(input, this.#output, this.contentElement);
|
|
274
354
|
}
|
|
275
355
|
|
|
276
356
|
modelAdded(serviceWorkerManager: SDK.ServiceWorkerManager.ServiceWorkerManager): void {
|
|
@@ -292,9 +372,9 @@ export class ServiceWorkersView extends UI.Widget.VBox implements
|
|
|
292
372
|
this.manager.addEventListener(SDK.ServiceWorkerManager.Events.REGISTRATION_DELETED, this.registrationDeleted,
|
|
293
373
|
this),
|
|
294
374
|
this.securityOriginManager.addEventListener(SDK.SecurityOriginManager.Events.SecurityOriginAdded,
|
|
295
|
-
this.
|
|
375
|
+
this.requestUpdate, this),
|
|
296
376
|
this.securityOriginManager.addEventListener(SDK.SecurityOriginManager.Events.SecurityOriginRemoved,
|
|
297
|
-
this.
|
|
377
|
+
this.requestUpdate, this),
|
|
298
378
|
]);
|
|
299
379
|
}
|
|
300
380
|
|
|
@@ -309,67 +389,6 @@ export class ServiceWorkersView extends UI.Widget.VBox implements
|
|
|
309
389
|
this.securityOriginManager = null;
|
|
310
390
|
}
|
|
311
391
|
|
|
312
|
-
private getTimeStamp(registration: SDK.ServiceWorkerManager.ServiceWorkerRegistration): number {
|
|
313
|
-
const versions = registration.versionsByMode();
|
|
314
|
-
|
|
315
|
-
let timestamp: number|undefined = 0;
|
|
316
|
-
|
|
317
|
-
const active = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.ACTIVE);
|
|
318
|
-
const installing = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.INSTALLING);
|
|
319
|
-
const waiting = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.WAITING);
|
|
320
|
-
const redundant = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.REDUNDANT);
|
|
321
|
-
|
|
322
|
-
if (active) {
|
|
323
|
-
timestamp = active.scriptResponseTime;
|
|
324
|
-
} else if (waiting) {
|
|
325
|
-
timestamp = waiting.scriptResponseTime;
|
|
326
|
-
} else if (installing) {
|
|
327
|
-
timestamp = installing.scriptResponseTime;
|
|
328
|
-
} else if (redundant) {
|
|
329
|
-
timestamp = redundant.scriptResponseTime;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
return timestamp || 0;
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
private updateSectionVisibility(): void {
|
|
336
|
-
let hasThis = false;
|
|
337
|
-
const movedSections = [];
|
|
338
|
-
for (const section of this.sections.values()) {
|
|
339
|
-
const expectedView = this.getReportViewForOrigin(section.registration.securityOrigin);
|
|
340
|
-
hasThis = hasThis || expectedView === this.currentWorkersView;
|
|
341
|
-
if (section.section.parentWidget() !== expectedView) {
|
|
342
|
-
movedSections.push(section);
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
for (const section of movedSections) {
|
|
347
|
-
const registration = section.registration;
|
|
348
|
-
this.removeRegistrationFromList(registration, true);
|
|
349
|
-
this.updateRegistration(registration, true);
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
this.currentWorkersView.sortSections((aSection, bSection) => {
|
|
353
|
-
const aRegistration = this.sectionToRegistration.get(aSection);
|
|
354
|
-
const bRegistration = this.sectionToRegistration.get(bSection);
|
|
355
|
-
const aTimestamp = aRegistration ? this.getTimeStamp(aRegistration) : 0;
|
|
356
|
-
const bTimestamp = bRegistration ? this.getTimeStamp(bRegistration) : 0;
|
|
357
|
-
// the newest (largest timestamp value) should be the first
|
|
358
|
-
return bTimestamp - aTimestamp;
|
|
359
|
-
});
|
|
360
|
-
|
|
361
|
-
for (const section of this.sections.values()) {
|
|
362
|
-
if (section.section.parentWidget() === this.currentWorkersView ||
|
|
363
|
-
this.isRegistrationVisible(section.registration)) {
|
|
364
|
-
section.section.showWidget();
|
|
365
|
-
} else {
|
|
366
|
-
section.section.hideWidget();
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
this.contentElement.classList.toggle('service-worker-has-current', Boolean(hasThis));
|
|
370
|
-
this.updateListVisibility();
|
|
371
|
-
}
|
|
372
|
-
|
|
373
392
|
private registrationUpdated(
|
|
374
393
|
event: Common.EventTarget.EventTargetEvent<SDK.ServiceWorkerManager.ServiceWorkerRegistration>): void {
|
|
375
394
|
this.updateRegistration(event.data);
|
|
@@ -404,35 +423,32 @@ export class ServiceWorkersView extends UI.Widget.VBox implements
|
|
|
404
423
|
}
|
|
405
424
|
}
|
|
406
425
|
|
|
407
|
-
private
|
|
426
|
+
private isOriginCurrent(origin: string): boolean {
|
|
408
427
|
if (this.securityOriginManager &&
|
|
409
428
|
(this.securityOriginManager.securityOrigins().includes(origin) ||
|
|
410
429
|
this.securityOriginManager.unreachableMainSecurityOrigin() === origin)) {
|
|
411
|
-
return
|
|
430
|
+
return true;
|
|
412
431
|
}
|
|
413
|
-
return
|
|
432
|
+
return false;
|
|
414
433
|
}
|
|
415
434
|
|
|
416
435
|
private updateRegistration(registration: SDK.ServiceWorkerManager.ServiceWorkerRegistration,
|
|
417
436
|
skipUpdate?: boolean): void {
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
437
|
+
if (!this.manager) {
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
let sectionData = this.sections.get(registration);
|
|
441
|
+
if (!sectionData) {
|
|
442
|
+
if (!this.isOriginCurrent(registration.securityOrigin)) {
|
|
423
443
|
return;
|
|
424
444
|
}
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
this.sectionToRegistration.set(uiSection, registration);
|
|
428
|
-
section = new Section((this.manager as SDK.ServiceWorkerManager.ServiceWorkerManager), uiSection, registration);
|
|
429
|
-
this.sections.set(registration, section);
|
|
445
|
+
sectionData = {manager: this.manager, registration};
|
|
446
|
+
this.sections.set(registration, sectionData);
|
|
430
447
|
}
|
|
431
448
|
if (skipUpdate) {
|
|
432
449
|
return;
|
|
433
450
|
}
|
|
434
|
-
this.
|
|
435
|
-
section.scheduleUpdate();
|
|
451
|
+
this.requestUpdate();
|
|
436
452
|
}
|
|
437
453
|
|
|
438
454
|
private registrationDeleted(
|
|
@@ -442,13 +458,9 @@ export class ServiceWorkersView extends UI.Widget.VBox implements
|
|
|
442
458
|
|
|
443
459
|
private removeRegistrationFromList(registration: SDK.ServiceWorkerManager.ServiceWorkerRegistration,
|
|
444
460
|
skipVisibilityUpdate = false): void {
|
|
445
|
-
const section = this.sections.get(registration);
|
|
446
|
-
if (section) {
|
|
447
|
-
section.section.detach();
|
|
448
|
-
}
|
|
449
461
|
this.sections.delete(registration);
|
|
450
462
|
if (!skipVisibilityUpdate) {
|
|
451
|
-
this.
|
|
463
|
+
this.requestUpdate();
|
|
452
464
|
}
|
|
453
465
|
}
|
|
454
466
|
|
|
@@ -458,253 +470,349 @@ export class ServiceWorkersView extends UI.Widget.VBox implements
|
|
|
458
470
|
}
|
|
459
471
|
return false;
|
|
460
472
|
}
|
|
473
|
+
}
|
|
461
474
|
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
475
|
+
export interface SectionViewInput {
|
|
476
|
+
title: string;
|
|
477
|
+
isDeleted: boolean;
|
|
478
|
+
errorsLength: number;
|
|
479
|
+
pushData: string;
|
|
480
|
+
syncTag: string;
|
|
481
|
+
periodicSyncTag: string;
|
|
482
|
+
updateCycleTable: HTMLElement;
|
|
483
|
+
activeVersion?: SDK.ServiceWorkerManager.ServiceWorkerVersion;
|
|
484
|
+
waitingVersion?: SDK.ServiceWorkerManager.ServiceWorkerVersion;
|
|
485
|
+
installingVersion?: SDK.ServiceWorkerManager.ServiceWorkerVersion;
|
|
486
|
+
redundantVersion?: SDK.ServiceWorkerManager.ServiceWorkerVersion;
|
|
487
|
+
renderClientInfo: (clientId: Protocol.Target.TargetID) => Promise<LitTemplate|typeof nothing>;
|
|
488
|
+
onNetworkRequests: () => void;
|
|
489
|
+
onUpdate: () => void;
|
|
490
|
+
onUnregister: () => void;
|
|
491
|
+
onPush: (data: string) => void;
|
|
492
|
+
onSync: (tag: string) => void;
|
|
493
|
+
onPeriodicSync: (tag: string) => void;
|
|
494
|
+
onStop: (versionId: string) => void;
|
|
495
|
+
onStart: () => void;
|
|
496
|
+
onSkipWaiting: () => void;
|
|
465
497
|
}
|
|
466
498
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
499
|
+
function renderHeaderButtons(input: SectionViewInput): LitTemplate {
|
|
500
|
+
// clang-format off
|
|
501
|
+
return html`
|
|
502
|
+
<devtools-button .data=${{
|
|
503
|
+
variant: Buttons.Button.Variant.TEXT,
|
|
504
|
+
title: i18nString(UIStrings.networkRequests),
|
|
505
|
+
jslogContext: 'show-network-requests'
|
|
506
|
+
} as Buttons.Button.ButtonData}
|
|
507
|
+
.disabled=${input.isDeleted}
|
|
508
|
+
@click=${input.onNetworkRequests}>
|
|
509
|
+
${i18nString(UIStrings.networkRequests)}
|
|
510
|
+
</devtools-button>
|
|
511
|
+
<devtools-button .data=${{
|
|
512
|
+
variant: Buttons.Button.Variant.TEXT,
|
|
513
|
+
title: i18nString(UIStrings.update),
|
|
514
|
+
jslogContext: 'update'
|
|
515
|
+
} as Buttons.Button.ButtonData}
|
|
516
|
+
.disabled=${input.isDeleted}
|
|
517
|
+
@click=${input.onUpdate}>
|
|
518
|
+
${i18nString(UIStrings.update)}
|
|
519
|
+
</devtools-button>
|
|
520
|
+
<devtools-button .data=${{
|
|
521
|
+
variant: Buttons.Button.Variant.TEXT,
|
|
522
|
+
title: i18nString(UIStrings.unregisterServiceWorker),
|
|
523
|
+
jslogContext: 'unregister'
|
|
524
|
+
} as Buttons.Button.ButtonData}
|
|
525
|
+
.disabled=${input.isDeleted}
|
|
526
|
+
@click=${input.onUnregister}>
|
|
527
|
+
${i18nString(UIStrings.unregister)}
|
|
528
|
+
</devtools-button>`;
|
|
529
|
+
// clang-format on
|
|
530
|
+
}
|
|
478
531
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
532
|
+
function renderSyncNotificationField(label: string, initialValue: string, placeholder: string,
|
|
533
|
+
callback: (arg0: string) => void, jslogContext: string): LitTemplate {
|
|
534
|
+
// clang-format off
|
|
535
|
+
return html`
|
|
536
|
+
<div class="report-field">
|
|
537
|
+
<div class="report-field-name">${label}</div>
|
|
538
|
+
<div class="report-field-value">
|
|
539
|
+
<form class="service-worker-editor-with-button" @submit=${(e: Event) => {
|
|
540
|
+
const {editor} = e.target as HTMLFormElement;
|
|
541
|
+
callback(editor.value || '');
|
|
542
|
+
e.consume(true);
|
|
543
|
+
}}>
|
|
544
|
+
<input name="editor" class="source-code service-worker-notification-editor harmony-input" type="text"
|
|
545
|
+
.value=${initialValue}
|
|
546
|
+
placeholder=${placeholder}
|
|
547
|
+
aria-label=${label}
|
|
548
|
+
.spellcheck=${false}
|
|
549
|
+
jslog=${VisualLogging.textField().track({change: true}).context(jslogContext)}
|
|
550
|
+
>
|
|
551
|
+
<devtools-button .data=${{
|
|
552
|
+
type: 'submit',
|
|
553
|
+
variant: Buttons.Button.Variant.OUTLINED,
|
|
554
|
+
jslogContext} as Buttons.Button.ButtonData}>
|
|
555
|
+
${label}
|
|
556
|
+
</devtools-button>
|
|
557
|
+
</form>
|
|
558
|
+
</div>
|
|
559
|
+
</div>`;
|
|
560
|
+
// clang-format on
|
|
561
|
+
}
|
|
492
562
|
|
|
493
|
-
|
|
563
|
+
function renderVersion(icon: string, label: string, content: LitTemplate = nothing): LitTemplate {
|
|
564
|
+
// clang-format off
|
|
565
|
+
return html`
|
|
566
|
+
<div class="service-worker-version">
|
|
567
|
+
<div class=${icon}></div>
|
|
568
|
+
<span class="service-worker-version-string" role="alert" aria-live="polite">
|
|
569
|
+
${label}
|
|
570
|
+
</span>
|
|
571
|
+
${content}
|
|
572
|
+
</div>`;
|
|
573
|
+
// clang-format on
|
|
574
|
+
}
|
|
494
575
|
|
|
495
|
-
|
|
496
|
-
|
|
576
|
+
function renderClientsField(input: SectionViewInput,
|
|
577
|
+
version?: SDK.ServiceWorkerManager.ServiceWorkerVersion): LitTemplate {
|
|
578
|
+
if (!version?.controlledClients?.length) {
|
|
579
|
+
return html`<div class="report-field">
|
|
580
|
+
<div class="report-field-name">${i18nString(UIStrings.clients)}</div>
|
|
581
|
+
<div class="report-field-value"></div>
|
|
582
|
+
</div>`;
|
|
583
|
+
}
|
|
584
|
+
// clang-format off
|
|
585
|
+
return html`<div class="report-field">
|
|
586
|
+
<div class="report-field-name">${i18nString(UIStrings.clients)}</div>
|
|
587
|
+
<div class="report-field-value">
|
|
588
|
+
${version.controlledClients.map(client => html`
|
|
589
|
+
<div class="service-worker-client">
|
|
590
|
+
${until(input.renderClientInfo(client))}
|
|
591
|
+
</div>`)}
|
|
592
|
+
</div>
|
|
593
|
+
</div>`;
|
|
594
|
+
// clang-format on
|
|
595
|
+
}
|
|
497
596
|
|
|
498
|
-
|
|
499
|
-
|
|
597
|
+
function renderSourceField(input: SectionViewInput,
|
|
598
|
+
version?: SDK.ServiceWorkerManager.ServiceWorkerVersion): LitTemplate {
|
|
599
|
+
if (!version) {
|
|
600
|
+
return html`<div class="report-field">
|
|
601
|
+
<div class="report-field-name">${i18nString(UIStrings.source)}</div>
|
|
602
|
+
<div class="report-field-value"></div>
|
|
603
|
+
</div>`;
|
|
500
604
|
}
|
|
605
|
+
const fileName = Common.ParsedURL.ParsedURL.extractName(version.scriptURL);
|
|
606
|
+
// clang-format off
|
|
607
|
+
|
|
608
|
+
return html`<div class="report-field">
|
|
609
|
+
<div class="report-field-name">${i18nString(UIStrings.source)}</div>
|
|
610
|
+
<div class="report-field-value">
|
|
611
|
+
<div class="report-field-value-filename">
|
|
612
|
+
${Components.Linkifier.Linkifier.renderLinkifiedUrl(version.scriptURL, {
|
|
613
|
+
text: fileName, tabStop: true, jslogContext: 'source-location'})}
|
|
614
|
+
${input.errorsLength ? html`
|
|
615
|
+
<button
|
|
616
|
+
class="devtools-link link"
|
|
617
|
+
tabindex="0"
|
|
618
|
+
aria-label=${i18nString(UIStrings.sRegistrationErrors, {PH1: input.errorsLength})}
|
|
619
|
+
@click=${() => Common.Console.Console.instance().show()}>
|
|
620
|
+
<devtools-icon name="cross-circle-filled" class="error-icon">
|
|
621
|
+
</devtools-icon>
|
|
622
|
+
${input.errorsLength}
|
|
623
|
+
</button>` : nothing}
|
|
624
|
+
</div>
|
|
625
|
+
${version.scriptResponseTime !== undefined ? html`
|
|
626
|
+
<div class="report-field-value-subtitle">
|
|
627
|
+
${i18nString(UIStrings.receivedS, {PH1: new Date(version.scriptResponseTime * 1000).toLocaleString()})}
|
|
628
|
+
</div>
|
|
629
|
+
` : nothing}
|
|
630
|
+
</div>
|
|
631
|
+
</div>`;
|
|
632
|
+
// clang-format on
|
|
633
|
+
}
|
|
501
634
|
|
|
502
|
-
|
|
503
|
-
|
|
635
|
+
function renderStatusField(input: SectionViewInput, active?: SDK.ServiceWorkerManager.ServiceWorkerVersion,
|
|
636
|
+
waiting?: SDK.ServiceWorkerManager.ServiceWorkerVersion,
|
|
637
|
+
installing?: SDK.ServiceWorkerManager.ServiceWorkerVersion,
|
|
638
|
+
redundant?: SDK.ServiceWorkerManager.ServiceWorkerVersion): LitTemplate {
|
|
639
|
+
// clang-format off
|
|
640
|
+
|
|
641
|
+
return html`<div class="report-field">
|
|
642
|
+
<div class="report-field-name">${i18nString(UIStrings.status)}</div>
|
|
643
|
+
<div class="report-field-value">
|
|
644
|
+
<div class="service-worker-version-stack">
|
|
645
|
+
<div class="service-worker-version-stack-bar"></div>
|
|
646
|
+
${active ? renderVersion(
|
|
647
|
+
'service-worker-active-circle',
|
|
648
|
+
i18nString(UIStrings.sActivatedAndIsS, {
|
|
649
|
+
PH1: active.id,
|
|
650
|
+
PH2: SDK.ServiceWorkerManager.ServiceWorkerVersion.RunningStatus[active.currentState.runningStatus](),
|
|
651
|
+
}),
|
|
652
|
+
active.isRunning() || active.isStarting() ? html`
|
|
653
|
+
<devtools-button .data=${{jslogContext: 'stop', variant: Buttons.Button.Variant.OUTLINED} as Buttons.Button.ButtonData}
|
|
654
|
+
@click=${() => input.onStop(active.id)}>
|
|
655
|
+
${i18nString(UIStrings.stopString)}
|
|
656
|
+
</devtools-button>`
|
|
657
|
+
: active.isStartable() ? html`
|
|
658
|
+
<devtools-button .data=${{jslogContext: 'start', variant: Buttons.Button.Variant.OUTLINED} as Buttons.Button.ButtonData}
|
|
659
|
+
@click=${input.onStart}>
|
|
660
|
+
${i18nString(UIStrings.startString)}
|
|
661
|
+
</devtools-button>`
|
|
662
|
+
: nothing)
|
|
663
|
+
: redundant ? renderVersion(
|
|
664
|
+
'service-worker-redundant-circle',
|
|
665
|
+
i18nString(UIStrings.sIsRedundant, {PH1: redundant.id}))
|
|
666
|
+
: nothing}
|
|
667
|
+
${waiting ? renderVersion(
|
|
668
|
+
'service-worker-waiting-circle',
|
|
669
|
+
i18nString(UIStrings.sWaitingToActivate, {PH1: waiting.id}), html`
|
|
670
|
+
<devtools-button .data=${{
|
|
671
|
+
jslogContext: 'skip-waiting',
|
|
672
|
+
title: i18n.i18n.lockedString('skipWaiting'),
|
|
673
|
+
variant: Buttons.Button.Variant.OUTLINED} as Buttons.Button.ButtonData}
|
|
674
|
+
@click=${input.onSkipWaiting}>
|
|
675
|
+
${i18n.i18n.lockedString('skipWaiting')}
|
|
676
|
+
</devtools-button>
|
|
677
|
+
${waiting.scriptResponseTime !== undefined ? html`
|
|
678
|
+
<div class="service-worker-subtitle">
|
|
679
|
+
${i18nString(UIStrings.receivedS, {PH1: new Date(waiting.scriptResponseTime * 1000).toLocaleString()})}
|
|
680
|
+
</div>
|
|
681
|
+
` : nothing}
|
|
682
|
+
`,
|
|
683
|
+
) : nothing}
|
|
684
|
+
${installing ? renderVersion(
|
|
685
|
+
'service-worker-installing-circle',
|
|
686
|
+
i18nString(UIStrings.sTryingToInstall, {PH1: installing.id}),
|
|
687
|
+
installing.scriptResponseTime !== undefined ? html`
|
|
688
|
+
<div class="service-worker-subtitle">
|
|
689
|
+
${i18nString(UIStrings.receivedS, {PH1: new Date(installing.scriptResponseTime * 1000).toLocaleString()})}
|
|
690
|
+
</div>` : nothing) : nothing}
|
|
691
|
+
</div>
|
|
692
|
+
</div>
|
|
693
|
+
</div>`;
|
|
694
|
+
// clang-format on
|
|
695
|
+
}
|
|
504
696
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
</devtools-button>
|
|
515
|
-
<devtools-button .data=${{
|
|
516
|
-
variant: Buttons.Button.Variant.TEXT,
|
|
517
|
-
title: i18nString(UIStrings.update),
|
|
518
|
-
jslogContext: 'update'
|
|
519
|
-
} as Buttons.Button.ButtonData}
|
|
520
|
-
.disabled=${this.registration.isDeleted}
|
|
521
|
-
@click=${this.updateButtonClicked.bind(this)}>
|
|
522
|
-
${i18nString(UIStrings.update)}
|
|
523
|
-
</devtools-button>
|
|
524
|
-
<devtools-button .data=${{
|
|
525
|
-
variant: Buttons.Button.Variant.TEXT,
|
|
526
|
-
title: i18nString(UIStrings.unregisterServiceWorker),
|
|
527
|
-
jslogContext: 'unregister'
|
|
528
|
-
} as Buttons.Button.ButtonData}
|
|
529
|
-
.disabled=${this.registration.isDeleted}
|
|
530
|
-
@click=${this.unregisterButtonClicked.bind(this)}>
|
|
531
|
-
${i18nString(UIStrings.unregister)}
|
|
532
|
-
</devtools-button>`;
|
|
533
|
-
// clang-format on
|
|
534
|
-
}
|
|
697
|
+
function renderUpdateCycleField(input: SectionViewInput): LitTemplate {
|
|
698
|
+
return html`
|
|
699
|
+
<div class="report-field">
|
|
700
|
+
<div class="report-field-name">${i18nString(UIStrings.updateCycle)}</div>
|
|
701
|
+
<div class="report-field-value">
|
|
702
|
+
${input.updateCycleTable}
|
|
703
|
+
</div>
|
|
704
|
+
</div>`;
|
|
705
|
+
}
|
|
535
706
|
|
|
536
|
-
|
|
537
|
-
|
|
707
|
+
function renderRouterField(input: SectionViewInput): LitTemplate {
|
|
708
|
+
const active = input.activeVersion;
|
|
709
|
+
const title = i18nString(UIStrings.routers);
|
|
710
|
+
if (active?.routerRules && active.routerRules.length > 0) {
|
|
711
|
+
// If there is at least one registered rule in the active version, append the router filed.
|
|
538
712
|
// clang-format off
|
|
539
713
|
return html`
|
|
540
714
|
<div class="report-field">
|
|
541
|
-
|
|
715
|
+
<div class="report-field-name">${title}</div>
|
|
542
716
|
<div class="report-field-value">
|
|
543
|
-
|
|
544
|
-
const {editor} = e.target as HTMLFormElement;
|
|
545
|
-
callback(editor.value || '');
|
|
546
|
-
e.consume(true);
|
|
547
|
-
}}>
|
|
548
|
-
<input name="editor" class="source-code service-worker-notification-editor harmony-input" type="text"
|
|
549
|
-
.value=${initialValue}
|
|
550
|
-
placeholder=${placeholder}
|
|
551
|
-
aria-label=${label}
|
|
552
|
-
.spellcheck=${false}
|
|
553
|
-
jslog=${VisualLogging.textField().track({change: true}).context(jslogContext)}
|
|
554
|
-
>
|
|
555
|
-
<devtools-button .data=${{
|
|
556
|
-
type: 'submit',
|
|
557
|
-
variant: Buttons.Button.Variant.OUTLINED,
|
|
558
|
-
jslogContext} as Buttons.Button.ButtonData}>
|
|
559
|
-
${label}
|
|
560
|
-
</devtools-button>
|
|
561
|
-
</form>
|
|
717
|
+
${widget(ApplicationComponents.ServiceWorkerRouterView.ServiceWorkerRouterView, { rules: active.routerRules })}
|
|
562
718
|
</div>
|
|
563
719
|
</div>`;
|
|
564
720
|
// clang-format on
|
|
565
721
|
}
|
|
722
|
+
return nothing;
|
|
723
|
+
}
|
|
566
724
|
|
|
567
|
-
|
|
568
|
-
if (throttleDisabledForDebugging) {
|
|
569
|
-
void this.performUpdate();
|
|
570
|
-
return;
|
|
571
|
-
}
|
|
572
|
-
void this.throttler.schedule(() => {
|
|
573
|
-
this.requestUpdate();
|
|
574
|
-
return this.updateComplete;
|
|
575
|
-
});
|
|
576
|
-
}
|
|
725
|
+
type SectionView = (input: SectionViewInput, _output: undefined, target: HTMLElement) => void;
|
|
577
726
|
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
727
|
+
export const DEFAULT_SECTION_VIEW: SectionView =
|
|
728
|
+
(input: SectionViewInput, _output: undefined, target: HTMLElement): void => {
|
|
729
|
+
// clang-format off
|
|
730
|
+
render(html`
|
|
731
|
+
<style>${serviceWorkersViewStyles}</style>
|
|
732
|
+
<style>${serviceWorkerUpdateCycleViewStyles}</style>
|
|
733
|
+
<devtools-report-section-header role="heading" aria-level="2"
|
|
734
|
+
aria-label=${i18nString(UIStrings.serviceWorkerForS, { PH1: input.title })}>
|
|
735
|
+
<span style="flex: 1 1 auto">${input.title}</span>
|
|
736
|
+
${renderHeaderButtons(input)}
|
|
737
|
+
</devtools-report-section-header>
|
|
738
|
+
<div class="service-worker-section">
|
|
739
|
+
${renderSourceField(input, input.activeVersion ?? input.redundantVersion)}
|
|
740
|
+
${renderStatusField(input, input.activeVersion, input.waitingVersion, input.installingVersion, input.redundantVersion)}
|
|
741
|
+
${renderClientsField(input, input.activeVersion ?? input.redundantVersion)}
|
|
742
|
+
${renderSyncNotificationField(i18nString(UIStrings.pushString), input.pushData,
|
|
743
|
+
i18nString(UIStrings.pushData), input.onPush, 'push-message')}
|
|
744
|
+
${renderSyncNotificationField(i18nString(UIStrings.syncString), input.syncTag,
|
|
745
|
+
i18nString(UIStrings.syncTag), input.onSync, 'sync-tag')}
|
|
746
|
+
${renderSyncNotificationField(i18nString(UIStrings.periodicSync), input.periodicSyncTag,
|
|
747
|
+
i18nString(UIStrings.periodicSyncTag), input.onPeriodicSync,
|
|
748
|
+
'periodic-sync-tag')}
|
|
749
|
+
${renderUpdateCycleField(input)}
|
|
750
|
+
${renderRouterField(input)}
|
|
751
|
+
</div>
|
|
752
|
+
`, target);
|
|
753
|
+
// clang-format on
|
|
754
|
+
};
|
|
590
755
|
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
756
|
+
export class Section extends UI.Widget.VBox {
|
|
757
|
+
private manager!: SDK.ServiceWorkerManager.ServiceWorkerManager;
|
|
758
|
+
registration!: SDK.ServiceWorkerManager.ServiceWorkerRegistration;
|
|
759
|
+
private sectionInternal!: SectionData;
|
|
760
|
+
private fingerprint: symbol|null;
|
|
761
|
+
private pushNotificationDataSetting!: Common.Settings.Setting<string>;
|
|
762
|
+
private syncTagNameSetting!: Common.Settings.Setting<string>;
|
|
763
|
+
private periodicSyncTagNameSetting!: Common.Settings.Setting<string>;
|
|
764
|
+
private updateCycleView!: ServiceWorkerUpdateCycleView;
|
|
765
|
+
private readonly clientInfoCache: Map<string, Protocol.Target.TargetInfo>;
|
|
766
|
+
private readonly throttler: Common.Throttler.Throttler;
|
|
767
|
+
#view: SectionView;
|
|
768
|
+
|
|
769
|
+
constructor(element: HTMLElement, view = DEFAULT_SECTION_VIEW) {
|
|
770
|
+
super(element);
|
|
771
|
+
this.fingerprint = null;
|
|
772
|
+
this.clientInfoCache = new Map();
|
|
773
|
+
this.throttler = new Common.Throttler.Throttler(500);
|
|
774
|
+
this.#view = view;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
set section(data: SectionData) {
|
|
778
|
+
const registrationChanged = !this.registration || this.registration !== data.registration;
|
|
779
|
+
this.sectionInternal = data;
|
|
780
|
+
this.manager = data.manager;
|
|
781
|
+
this.registration = data.registration;
|
|
782
|
+
|
|
783
|
+
if (!this.pushNotificationDataSetting) {
|
|
784
|
+
this.pushNotificationDataSetting = Common.Settings.Settings.instance().createLocalSetting(
|
|
785
|
+
'push-data', i18nString(UIStrings.testPushMessageFromDevtools));
|
|
786
|
+
this.syncTagNameSetting =
|
|
787
|
+
Common.Settings.Settings.instance().createLocalSetting('sync-tag-name', 'test-tag-from-devtools');
|
|
788
|
+
this.periodicSyncTagNameSetting =
|
|
789
|
+
Common.Settings.Settings.instance().createLocalSetting('periodic-sync-tag-name', 'test-tag-from-devtools');
|
|
597
790
|
}
|
|
598
|
-
// clang-format off
|
|
599
|
-
return html`<div class="report-field">
|
|
600
|
-
<div class="report-field-name">${i18nString(UIStrings.clients)}</div>
|
|
601
|
-
<div class="report-field-value">
|
|
602
|
-
${version.controlledClients.map(client => html`
|
|
603
|
-
<div class="service-worker-client">
|
|
604
|
-
${until(this.renderClientInfo(client))}
|
|
605
|
-
</div>`)}
|
|
606
|
-
</div>
|
|
607
|
-
</div>`;
|
|
608
|
-
// clang-format on
|
|
609
|
-
}
|
|
610
791
|
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
<div class="report-field-name">${i18nString(UIStrings.source)}</div>
|
|
615
|
-
<div class="report-field-value"></div>
|
|
616
|
-
</div>`;
|
|
792
|
+
if (registrationChanged) {
|
|
793
|
+
this.updateCycleView = new ServiceWorkerUpdateCycleView(this.registration);
|
|
794
|
+
this.clientInfoCache.clear();
|
|
617
795
|
}
|
|
618
|
-
|
|
619
|
-
// clang-format off
|
|
796
|
+
}
|
|
620
797
|
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
<div class="report-field-value">
|
|
624
|
-
<div class="report-field-value-filename">
|
|
625
|
-
${Components.Linkifier.Linkifier.renderLinkifiedUrl(version.scriptURL, {
|
|
626
|
-
text: fileName, tabStop: true, jslogContext: 'source-location'})}
|
|
627
|
-
${this.registration.errors.length ? html`
|
|
628
|
-
<button
|
|
629
|
-
class="devtools-link link"
|
|
630
|
-
tabindex="0"
|
|
631
|
-
aria-label=${i18nString(UIStrings.sRegistrationErrors, {PH1: this.registration.errors.length})}
|
|
632
|
-
@click=${() => Common.Console.Console.instance().show()}>
|
|
633
|
-
<devtools-icon name="cross-circle-filled" class="error-icon">
|
|
634
|
-
</devtools-icon>
|
|
635
|
-
${this.registration.errors.length}
|
|
636
|
-
</button>` : nothing}
|
|
637
|
-
</div>
|
|
638
|
-
${version.scriptResponseTime !== undefined ? html`
|
|
639
|
-
<div class="report-field-value-subtitle">
|
|
640
|
-
${i18nString(UIStrings.receivedS, {PH1: new Date(version.scriptResponseTime * 1000).toLocaleString()})}
|
|
641
|
-
</div>
|
|
642
|
-
` : nothing}
|
|
643
|
-
</div>
|
|
644
|
-
</div>`;
|
|
645
|
-
// clang-format on
|
|
798
|
+
get section(): SectionData {
|
|
799
|
+
return this.sectionInternal;
|
|
646
800
|
}
|
|
647
801
|
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
// clang-format off
|
|
802
|
+
getTitle(): string {
|
|
803
|
+
const scopeURL = this.registration.scopeURL;
|
|
804
|
+
return this.registration.isDeleted ? i18nString(UIStrings.sDeleted, {PH1: scopeURL}) : scopeURL;
|
|
805
|
+
}
|
|
653
806
|
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
PH2: SDK.ServiceWorkerManager.ServiceWorkerVersion.RunningStatus[active.currentState.runningStatus](),
|
|
664
|
-
}),
|
|
665
|
-
active.isRunning() || active.isStarting() ? html`
|
|
666
|
-
<devtools-button .data=${{jslogContext: 'stop', variant: Buttons.Button.Variant.OUTLINED} as Buttons.Button.ButtonData}
|
|
667
|
-
@click=${this.stopButtonClicked.bind(this, active.id)}>
|
|
668
|
-
${i18nString(UIStrings.stopString)}
|
|
669
|
-
</devtools-button>`
|
|
670
|
-
: active.isStartable() ? html`
|
|
671
|
-
<devtools-button .data=${{jslogContext: 'start', variant: Buttons.Button.Variant.OUTLINED} as Buttons.Button.ButtonData}
|
|
672
|
-
@click=${this.startButtonClicked.bind(this)}>
|
|
673
|
-
${i18nString(UIStrings.startString)}
|
|
674
|
-
</devtools-button>`
|
|
675
|
-
: nothing)
|
|
676
|
-
: redundant ? this.renderVersion(
|
|
677
|
-
'service-worker-redundant-circle',
|
|
678
|
-
i18nString(UIStrings.sIsRedundant, {PH1: redundant.id}))
|
|
679
|
-
: nothing}
|
|
680
|
-
${waiting ? this.renderVersion(
|
|
681
|
-
'service-worker-waiting-circle',
|
|
682
|
-
i18nString(UIStrings.sWaitingToActivate, {PH1: waiting.id}), html`
|
|
683
|
-
<devtools-button .data=${{
|
|
684
|
-
jslogContext: 'skip-waiting',
|
|
685
|
-
title: i18n.i18n.lockedString('skipWaiting'),
|
|
686
|
-
variant: Buttons.Button.Variant.OUTLINED} as Buttons.Button.ButtonData}
|
|
687
|
-
@click=${this.skipButtonClicked.bind(this)}>
|
|
688
|
-
${i18n.i18n.lockedString('skipWaiting')}
|
|
689
|
-
</devtools-button>
|
|
690
|
-
${waiting.scriptResponseTime !== undefined ? html`
|
|
691
|
-
<div class="service-worker-subtitle">
|
|
692
|
-
${i18nString(UIStrings.receivedS, {PH1: new Date(waiting.scriptResponseTime * 1000).toLocaleString()})}
|
|
693
|
-
</div>
|
|
694
|
-
` : nothing}
|
|
695
|
-
`,
|
|
696
|
-
) : nothing}
|
|
697
|
-
${installing ? this.renderVersion(
|
|
698
|
-
'service-worker-installing-circle',
|
|
699
|
-
i18nString(UIStrings.sTryingToInstall, {PH1: installing.id}),
|
|
700
|
-
installing.scriptResponseTime !== undefined ? html`
|
|
701
|
-
<div class="service-worker-subtitle">
|
|
702
|
-
${i18nString(UIStrings.receivedS, {PH1: new Date(installing.scriptResponseTime * 1000).toLocaleString()})}
|
|
703
|
-
</div>` : nothing) : nothing}
|
|
704
|
-
</div>
|
|
705
|
-
</div>
|
|
706
|
-
</div>`;
|
|
707
|
-
// clang-format on
|
|
807
|
+
override requestUpdate(): void {
|
|
808
|
+
if (throttleDisabledForDebugging) {
|
|
809
|
+
super.requestUpdate();
|
|
810
|
+
return;
|
|
811
|
+
}
|
|
812
|
+
void this.throttler.schedule(() => {
|
|
813
|
+
super.requestUpdate();
|
|
814
|
+
return Promise.resolve();
|
|
815
|
+
});
|
|
708
816
|
}
|
|
709
817
|
|
|
710
818
|
override performUpdate(): Promise<void> {
|
|
@@ -714,36 +822,40 @@ export class Section extends UI.Widget.VBox {
|
|
|
714
822
|
}
|
|
715
823
|
this.fingerprint = fingerprint;
|
|
716
824
|
|
|
717
|
-
// eslint-disable-next-line @devtools/no-lit-render-outside-of-view
|
|
718
|
-
render(this.renderHeaderButtons(), this.section.getHeaderElement());
|
|
719
|
-
|
|
720
825
|
const versions = this.registration.versionsByMode();
|
|
721
|
-
const scopeURL = this.registration.scopeURL;
|
|
722
|
-
const title = this.registration.isDeleted ? i18nString(UIStrings.sDeleted, {PH1: scopeURL}) : scopeURL;
|
|
723
|
-
this.section.setTitle(title);
|
|
724
826
|
|
|
725
827
|
const active = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.ACTIVE);
|
|
726
828
|
const waiting = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.WAITING);
|
|
727
829
|
const installing = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.INSTALLING);
|
|
728
830
|
const redundant = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.REDUNDANT);
|
|
729
831
|
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
832
|
+
const title = this.getTitle();
|
|
833
|
+
|
|
834
|
+
const input: SectionViewInput = {
|
|
835
|
+
title,
|
|
836
|
+
isDeleted: this.registration.isDeleted,
|
|
837
|
+
errorsLength: this.registration.errors?.length ?? 0,
|
|
838
|
+
pushData: this.pushNotificationDataSetting.get(),
|
|
839
|
+
syncTag: this.syncTagNameSetting.get(),
|
|
840
|
+
periodicSyncTag: this.periodicSyncTagNameSetting.get(),
|
|
841
|
+
updateCycleTable: this.updateCycleView.tableElement,
|
|
842
|
+
activeVersion: active,
|
|
843
|
+
waitingVersion: waiting,
|
|
844
|
+
installingVersion: installing,
|
|
845
|
+
redundantVersion: redundant,
|
|
846
|
+
renderClientInfo: this.renderClientInfo.bind(this),
|
|
847
|
+
onNetworkRequests: this.networkRequestsClicked.bind(this),
|
|
848
|
+
onUpdate: this.updateButtonClicked.bind(this),
|
|
849
|
+
onUnregister: this.unregisterButtonClicked.bind(this),
|
|
850
|
+
onPush: this.push.bind(this),
|
|
851
|
+
onSync: this.sync.bind(this),
|
|
852
|
+
onPeriodicSync: this.periodicSync.bind(this),
|
|
853
|
+
onStop: this.stopButtonClicked.bind(this),
|
|
854
|
+
onStart: this.startButtonClicked.bind(this),
|
|
855
|
+
onSkipWaiting: this.skipButtonClicked.bind(this),
|
|
856
|
+
};
|
|
857
|
+
|
|
858
|
+
this.#view(input, undefined, this.contentElement);
|
|
747
859
|
this.updateCycleView.refresh();
|
|
748
860
|
|
|
749
861
|
return Promise.resolve();
|
|
@@ -753,35 +865,6 @@ export class Section extends UI.Widget.VBox {
|
|
|
753
865
|
this.manager.deleteRegistration(this.registration.id);
|
|
754
866
|
}
|
|
755
867
|
|
|
756
|
-
private renderUpdateCycleField(): LitTemplate {
|
|
757
|
-
return html`
|
|
758
|
-
<div class="report-field">
|
|
759
|
-
<div class="report-field-name">${i18nString(UIStrings.updateCycle)}</div>
|
|
760
|
-
<div class="report-field-value">
|
|
761
|
-
${this.updateCycleView.tableElement}
|
|
762
|
-
</div>
|
|
763
|
-
</div>`;
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
private renderRouterField(): LitTemplate {
|
|
767
|
-
const versions = this.registration.versionsByMode();
|
|
768
|
-
const active = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.ACTIVE);
|
|
769
|
-
const title = i18nString(UIStrings.routers);
|
|
770
|
-
if (active?.routerRules && active.routerRules.length > 0) {
|
|
771
|
-
// If there is at least one registered rule in the active version, append the router filed.
|
|
772
|
-
// clang-format off
|
|
773
|
-
return html`
|
|
774
|
-
<div class="report-field">
|
|
775
|
-
<div class="report-field-name">${title}</div>
|
|
776
|
-
<div class="report-field-value">
|
|
777
|
-
${widget(ApplicationComponents.ServiceWorkerRouterView.ServiceWorkerRouterView, { rules: active.routerRules })}
|
|
778
|
-
</div>
|
|
779
|
-
</div>`;
|
|
780
|
-
// clang-format on
|
|
781
|
-
}
|
|
782
|
-
return nothing;
|
|
783
|
-
}
|
|
784
|
-
|
|
785
868
|
private updateButtonClicked(): void {
|
|
786
869
|
void this.manager.updateRegistration(this.registration.id);
|
|
787
870
|
}
|