blob: d4345d1fdd4a8383b367c24b8c2fba8ad2d08b70 [file] [log] [blame]
Blink Reformat4c46d092018-04-07 15:32:371// Copyright (c) 2015 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Tim van der Lippe097cdec2020-01-06 14:44:174
Tim van der Lippe0efccf02020-02-12 15:15:395import * as Common from '../common/common.js';
6import * as Components from '../components/components.js';
7import * as MobileThrottling from '../mobile_throttling/mobile_throttling.js';
chait pinnamaneni6bc1c122020-10-30 17:30:528import * as Network from '../network/network.js';
Tim van der Lippe0efccf02020-02-12 15:15:399import * as SDK from '../sdk/sdk.js';
10import * as UI from '../ui/ui.js';
11
Sigurd Schneider370b00f2020-10-28 17:30:3212let throttleDisabledForDebugging = false;
13/**
14 * @param {boolean} enable
15 */
16export const setThrottleDisabledForDebugging = enable => {
17 throttleDisabledForDebugging = enable;
18};
19
Blink Reformat4c46d092018-04-07 15:32:3720/**
Tim van der Lippe0efccf02020-02-12 15:15:3921 * @implements {SDK.SDKModel.SDKModelObserver<!SDK.ServiceWorkerManager.ServiceWorkerManager>}
Blink Reformat4c46d092018-04-07 15:32:3722 */
Tim van der Lippe0efccf02020-02-12 15:15:3923export class ServiceWorkersView extends UI.Widget.VBox {
Blink Reformat4c46d092018-04-07 15:32:3724 constructor() {
25 super(true);
Jack Franklin71519f82020-11-03 12:08:5926 this.registerRequiredCSS('resources/serviceWorkersView.css', {enableLegacyPatching: true});
Blink Reformat4c46d092018-04-07 15:32:3727
Tim van der Lippe0efccf02020-02-12 15:15:3928 this._currentWorkersView = new UI.ReportView.ReportView(Common.UIString.UIString('Service Workers'));
Blink Reformat4c46d092018-04-07 15:32:3729 this._currentWorkersView.setBodyScrollable(false);
30 this.contentElement.classList.add('service-worker-list');
31 this._currentWorkersView.show(this.contentElement);
32 this._currentWorkersView.element.classList.add('service-workers-this-origin');
33
34 this._toolbar = this._currentWorkersView.createToolbar();
Erik Luo5e5a8362018-05-31 23:43:2235 this._toolbar.makeWrappable(true /* growVertically */);
Blink Reformat4c46d092018-04-07 15:32:3736
Tim van der Lippe0efccf02020-02-12 15:15:3937 /** @type {!Map<!SDK.ServiceWorkerManager.ServiceWorkerRegistration, !Section>} */
Blink Reformat4c46d092018-04-07 15:32:3738 this._sections = new Map();
Blink Reformat4c46d092018-04-07 15:32:3739
Tim van der Lippe0efccf02020-02-12 15:15:3940 /** @type {?SDK.ServiceWorkerManager.ServiceWorkerManager} */
Blink Reformat4c46d092018-04-07 15:32:3741 this._manager = null;
Tim van der Lippe0efccf02020-02-12 15:15:3942 /** @type {?SDK.SecurityOriginManager.SecurityOriginManager} */
Blink Reformat4c46d092018-04-07 15:32:3743 this._securityOriginManager = null;
44
chait pinnamaneni6bc1c122020-10-30 17:30:5245 /** @type {!WeakMap<!UI.ReportView.Section, !SDK.ServiceWorkerManager.ServiceWorkerRegistration>} */
46 this._sectionToRegistration = new WeakMap();
47
Nidhi Jaju1788bac2020-08-07 15:13:3048 const othersDiv = this.contentElement.createChild('div', 'service-workers-other-origin');
49 const othersView = new UI.ReportView.ReportView();
50 othersView.setHeaderVisible(false);
51 othersView.show(othersDiv);
52 const othersSection = othersView.appendSection(Common.UIString.UIString('Service workers from other origins'));
53 const othersSectionRow = othersSection.appendRow();
54 const seeOthers = UI.Fragment.html
55 `<a class="devtools-link" role="link" tabindex="0" href="chrome://serviceworker-internals" target="_blank" style="display: inline; cursor: pointer;">See all registrations</a>`;
56 self.onInvokeElement(seeOthers, event => {
Sigurd Schneider370b00f2020-10-28 17:30:3257 const mainTarget = SDK.SDKModel.TargetManager.instance().mainTarget();
58 mainTarget && mainTarget.targetAgent().invoke_createTarget({url: 'chrome://serviceworker-internals?devtools'});
Nidhi Jaju1788bac2020-08-07 15:13:3059 event.consume(true);
60 });
61 othersSectionRow.appendChild(seeOthers);
Blink Reformat4c46d092018-04-07 15:32:3762
Tim van der Lippe0efccf02020-02-12 15:15:3963 this._toolbar.appendToolbarItem(
64 MobileThrottling.ThrottlingManager.throttlingManager().createOfflineToolbarCheckbox());
Paul Lewis2d7d65c2020-03-16 17:26:3065 const updateOnReloadSetting =
66 Common.Settings.Settings.instance().createSetting('serviceWorkerUpdateOnReload', false);
Tim van der Lippe0efccf02020-02-12 15:15:3967 updateOnReloadSetting.setTitle(Common.UIString.UIString('Update on reload'));
68 const forceUpdate = new UI.Toolbar.ToolbarSettingCheckbox(
Harley Li38795b32019-01-10 22:32:2669 updateOnReloadSetting, ls`On page reload, force the service worker to update, and activate it`);
Blink Reformat4c46d092018-04-07 15:32:3770 this._toolbar.appendToolbarItem(forceUpdate);
Paul Lewis2d7d65c2020-03-16 17:26:3071 const bypassServiceWorkerSetting = Common.Settings.Settings.instance().createSetting('bypassServiceWorker', false);
Tim van der Lippe0efccf02020-02-12 15:15:3972 bypassServiceWorkerSetting.setTitle(Common.UIString.UIString('Bypass for network'));
73 const fallbackToNetwork = new UI.Toolbar.ToolbarSettingCheckbox(
Harley Li34d68fa2019-01-12 02:21:2474 bypassServiceWorkerSetting, ls`Bypass the service worker and load resources from the network`);
Blink Reformat4c46d092018-04-07 15:32:3775 this._toolbar.appendToolbarItem(fallbackToNetwork);
76
Tim van der Lippe0efccf02020-02-12 15:15:3977 /** @type {!Map<!SDK.ServiceWorkerManager.ServiceWorkerManager, !Array<!Common.EventTarget.EventDescriptor>>}*/
Blink Reformat4c46d092018-04-07 15:32:3778 this._eventListeners = new Map();
Paul Lewisdaac1062020-03-05 14:37:1079 SDK.SDKModel.TargetManager.instance().observeModels(SDK.ServiceWorkerManager.ServiceWorkerManager, this);
Blink Reformat4c46d092018-04-07 15:32:3780 this._updateListVisibility();
chait pinnamaneni6bc1c122020-10-30 17:30:5281
82 /**
83 * @param {!Event} event
84 */
85 const drawerChangeHandler = event => {
86 // @ts-ignore: No support for custom event listener
87 const isDrawerOpen = event.detail && event.detail.isDrawerOpen;
88 if (this._manager && !isDrawerOpen && this._manager.serviceWorkerNetworkRequestsPanelOpen) {
89 const networkLocation = UI.ViewManager.ViewManager.instance().locationNameForViewId('network');
90 UI.ViewManager.ViewManager.instance().showViewInLocation('network', networkLocation, false);
91 Network.NetworkPanel.NetworkPanel.revealAndFilter([]);
92 this._manager.serviceWorkerNetworkRequestsPanelOpen = false;
93 }
94 };
95 document.body.addEventListener(UI.InspectorView.Events.DrawerChange, drawerChangeHandler);
Blink Reformat4c46d092018-04-07 15:32:3796 }
97
98 /**
99 * @override
Tim van der Lippe0efccf02020-02-12 15:15:39100 * @param {!SDK.ServiceWorkerManager.ServiceWorkerManager} serviceWorkerManager
Blink Reformat4c46d092018-04-07 15:32:37101 */
102 modelAdded(serviceWorkerManager) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34103 if (this._manager) {
Blink Reformat4c46d092018-04-07 15:32:37104 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34105 }
Blink Reformat4c46d092018-04-07 15:32:37106 this._manager = serviceWorkerManager;
Sigurd Schneider370b00f2020-10-28 17:30:32107 this._securityOriginManager =
108 /** @type {!SDK.SecurityOriginManager.SecurityOriginManager} */ (
109 serviceWorkerManager.target().model(SDK.SecurityOriginManager.SecurityOriginManager));
Blink Reformat4c46d092018-04-07 15:32:37110
Tim van der Lippe1d6e57a2019-09-30 11:55:34111 for (const registration of this._manager.registrations().values()) {
Blink Reformat4c46d092018-04-07 15:32:37112 this._updateRegistration(registration);
Tim van der Lippe1d6e57a2019-09-30 11:55:34113 }
Blink Reformat4c46d092018-04-07 15:32:37114
115 this._eventListeners.set(serviceWorkerManager, [
116 this._manager.addEventListener(
117 SDK.ServiceWorkerManager.Events.RegistrationUpdated, this._registrationUpdated, this),
118 this._manager.addEventListener(
119 SDK.ServiceWorkerManager.Events.RegistrationDeleted, this._registrationDeleted, this),
120 this._securityOriginManager.addEventListener(
121 SDK.SecurityOriginManager.Events.SecurityOriginAdded, this._updateSectionVisibility, this),
122 this._securityOriginManager.addEventListener(
123 SDK.SecurityOriginManager.Events.SecurityOriginRemoved, this._updateSectionVisibility, this),
124 ]);
125 }
126
127 /**
128 * @override
Tim van der Lippe0efccf02020-02-12 15:15:39129 * @param {!SDK.ServiceWorkerManager.ServiceWorkerManager} serviceWorkerManager
Blink Reformat4c46d092018-04-07 15:32:37130 */
131 modelRemoved(serviceWorkerManager) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34132 if (!this._manager || this._manager !== serviceWorkerManager) {
Blink Reformat4c46d092018-04-07 15:32:37133 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34134 }
Blink Reformat4c46d092018-04-07 15:32:37135
Sigurd Schneider370b00f2020-10-28 17:30:32136 Common.EventTarget.EventTarget.removeEventListeners(this._eventListeners.get(serviceWorkerManager) || []);
Blink Reformat4c46d092018-04-07 15:32:37137 this._eventListeners.delete(serviceWorkerManager);
138 this._manager = null;
139 this._securityOriginManager = null;
140 }
141
Harley Li68cc13c2019-02-25 21:47:25142 /**
Tim van der Lippe0efccf02020-02-12 15:15:39143 * @param {!SDK.ServiceWorkerManager.ServiceWorkerRegistration} registration
Harley Li68cc13c2019-02-25 21:47:25144 * @return {number}
145 */
146 _getTimeStamp(registration) {
147 const versions = registration.versionsByMode();
148
Sigurd Schneidera38b8672020-05-20 11:31:45149 /** @type {number|undefined} */
Harley Li68cc13c2019-02-25 21:47:25150 let timestamp = 0;
151
Tim van der Lippe0efccf02020-02-12 15:15:39152 const active = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.Active);
153 const installing = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.Installing);
154 const waiting = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.Waiting);
155 const redundant = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.Redundant);
Harley Li68cc13c2019-02-25 21:47:25156
Tim van der Lippe1d6e57a2019-09-30 11:55:34157 if (active) {
Harley Li68cc13c2019-02-25 21:47:25158 timestamp = active.scriptResponseTime;
Tim van der Lippe1d6e57a2019-09-30 11:55:34159 } else if (waiting) {
Harley Li68cc13c2019-02-25 21:47:25160 timestamp = waiting.scriptResponseTime;
Tim van der Lippe1d6e57a2019-09-30 11:55:34161 } else if (installing) {
Harley Li68cc13c2019-02-25 21:47:25162 timestamp = installing.scriptResponseTime;
Tim van der Lippe1d6e57a2019-09-30 11:55:34163 } else if (redundant) {
Harley Li68cc13c2019-02-25 21:47:25164 timestamp = redundant.scriptResponseTime;
Tim van der Lippe1d6e57a2019-09-30 11:55:34165 }
Harley Li68cc13c2019-02-25 21:47:25166
Sigurd Schneidera38b8672020-05-20 11:31:45167 return timestamp || 0;
Harley Li68cc13c2019-02-25 21:47:25168 }
169
Blink Reformat4c46d092018-04-07 15:32:37170 _updateSectionVisibility() {
Blink Reformat4c46d092018-04-07 15:32:37171 let hasThis = false;
172 const movedSections = [];
173 for (const section of this._sections.values()) {
174 const expectedView = this._getReportViewForOrigin(section._registration.securityOrigin);
Sigurd Schneider370b00f2020-10-28 17:30:32175 hasThis = hasThis || expectedView === this._currentWorkersView;
Tim van der Lippe1d6e57a2019-09-30 11:55:34176 if (section._section.parentWidget() !== expectedView) {
Blink Reformat4c46d092018-04-07 15:32:37177 movedSections.push(section);
Tim van der Lippe1d6e57a2019-09-30 11:55:34178 }
Blink Reformat4c46d092018-04-07 15:32:37179 }
180
181 for (const section of movedSections) {
182 const registration = section._registration;
183 this._removeRegistrationFromList(registration);
184 this._updateRegistration(registration, true);
185 }
186
Sigurd Schneider370b00f2020-10-28 17:30:32187 this._currentWorkersView.sortSections((aSection, bSection) => {
188 const aRegistration = this._sectionToRegistration.get(aSection);
189 const bRegistration = this._sectionToRegistration.get(bSection);
190 const aTimestamp = aRegistration ? this._getTimeStamp(aRegistration) : 0;
191 const bTimestamp = bRegistration ? this._getTimeStamp(bRegistration) : 0;
Harley Li68cc13c2019-02-25 21:47:25192 // the newest (largest timestamp value) should be the first
193 return bTimestamp - aTimestamp;
194 });
195
Blink Reformat4c46d092018-04-07 15:32:37196 for (const section of this._sections.values()) {
197 if (section._section.parentWidget() === this._currentWorkersView ||
Tim van der Lippe1d6e57a2019-09-30 11:55:34198 this._isRegistrationVisible(section._registration)) {
Blink Reformat4c46d092018-04-07 15:32:37199 section._section.showWidget();
Tim van der Lippe1d6e57a2019-09-30 11:55:34200 } else {
Blink Reformat4c46d092018-04-07 15:32:37201 section._section.hideWidget();
Tim van der Lippe1d6e57a2019-09-30 11:55:34202 }
Blink Reformat4c46d092018-04-07 15:32:37203 }
Tim van der Lippeffa78622019-09-16 12:07:12204 this.contentElement.classList.toggle('service-worker-has-current', !!hasThis);
Blink Reformat4c46d092018-04-07 15:32:37205 this._updateListVisibility();
206 }
207
208 /**
Tim van der Lippec02a97c2020-02-14 14:39:27209 * @param {!Common.EventTarget.EventTargetEvent} event
Blink Reformat4c46d092018-04-07 15:32:37210 */
211 _registrationUpdated(event) {
Tim van der Lippe0efccf02020-02-12 15:15:39212 const registration = /** @type {!SDK.ServiceWorkerManager.ServiceWorkerRegistration} */ (event.data);
Blink Reformat4c46d092018-04-07 15:32:37213 this._updateRegistration(registration);
214 this._gcRegistrations();
215 }
216
217 _gcRegistrations() {
Sigurd Schneider370b00f2020-10-28 17:30:32218 if (!this._manager || !this._securityOriginManager) {
219 return;
220 }
Blink Reformat4c46d092018-04-07 15:32:37221 let hasNonDeletedRegistrations = false;
222 const securityOrigins = new Set(this._securityOriginManager.securityOrigins());
223 for (const registration of this._manager.registrations().values()) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34224 if (!securityOrigins.has(registration.securityOrigin) && !this._isRegistrationVisible(registration)) {
Blink Reformat4c46d092018-04-07 15:32:37225 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:34226 }
Blink Reformat4c46d092018-04-07 15:32:37227 if (!registration.canBeRemoved()) {
228 hasNonDeletedRegistrations = true;
229 break;
230 }
231 }
232
Tim van der Lippe1d6e57a2019-09-30 11:55:34233 if (!hasNonDeletedRegistrations) {
Blink Reformat4c46d092018-04-07 15:32:37234 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34235 }
Blink Reformat4c46d092018-04-07 15:32:37236
237 for (const registration of this._manager.registrations().values()) {
238 const visible = securityOrigins.has(registration.securityOrigin) || this._isRegistrationVisible(registration);
Tim van der Lippe1d6e57a2019-09-30 11:55:34239 if (!visible && registration.canBeRemoved()) {
Blink Reformat4c46d092018-04-07 15:32:37240 this._removeRegistrationFromList(registration);
Tim van der Lippe1d6e57a2019-09-30 11:55:34241 }
Blink Reformat4c46d092018-04-07 15:32:37242 }
243 }
244
245 /**
246 * @param {string} origin
Nidhi Jajua3e34a82020-08-07 14:46:21247 * @return {?UI.ReportView.ReportView}
Blink Reformat4c46d092018-04-07 15:32:37248 */
249 _getReportViewForOrigin(origin) {
Sigurd Schneider370b00f2020-10-28 17:30:32250 if (this._securityOriginManager &&
251 (this._securityOriginManager.securityOrigins().includes(origin) ||
252 this._securityOriginManager.unreachableMainSecurityOrigin() === origin)) {
Blink Reformat4c46d092018-04-07 15:32:37253 return this._currentWorkersView;
Tim van der Lippe1d6e57a2019-09-30 11:55:34254 }
Nidhi Jajua3e34a82020-08-07 14:46:21255 return null;
Blink Reformat4c46d092018-04-07 15:32:37256 }
257
258 /**
Tim van der Lippe0efccf02020-02-12 15:15:39259 * @param {!SDK.ServiceWorkerManager.ServiceWorkerRegistration} registration
Blink Reformat4c46d092018-04-07 15:32:37260 * @param {boolean=} skipUpdate
261 */
262 _updateRegistration(registration, skipUpdate) {
263 let section = this._sections.get(registration);
264 if (!section) {
Harley Li09a58712019-06-07 19:25:54265 const title = registration.scopeURL;
Nidhi Jajua3e34a82020-08-07 14:46:21266 const reportView = this._getReportViewForOrigin(registration.securityOrigin);
267 if (!reportView) {
268 return;
269 }
270 const uiSection = reportView.appendSection(title);
Rob Pavezacb832182019-10-16 23:13:00271 uiSection.setUiGroupTitle(ls`Service worker for ${title}`);
Sigurd Schneider370b00f2020-10-28 17:30:32272 this._sectionToRegistration.set(uiSection, registration);
Tim van der Lippe097cdec2020-01-06 14:44:17273 section = new Section(
Tim van der Lippe0efccf02020-02-12 15:15:39274 /** @type {!SDK.ServiceWorkerManager.ServiceWorkerManager} */ (this._manager), uiSection, registration);
Blink Reformat4c46d092018-04-07 15:32:37275 this._sections.set(registration, section);
276 }
Tim van der Lippe1d6e57a2019-09-30 11:55:34277 if (skipUpdate) {
Blink Reformat4c46d092018-04-07 15:32:37278 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34279 }
Blink Reformat4c46d092018-04-07 15:32:37280 this._updateSectionVisibility();
281 section._scheduleUpdate();
282 }
283
284 /**
Tim van der Lippec02a97c2020-02-14 14:39:27285 * @param {!Common.EventTarget.EventTargetEvent} event
Blink Reformat4c46d092018-04-07 15:32:37286 */
287 _registrationDeleted(event) {
Tim van der Lippe0efccf02020-02-12 15:15:39288 const registration = /** @type {!SDK.ServiceWorkerManager.ServiceWorkerRegistration} */ (event.data);
Blink Reformat4c46d092018-04-07 15:32:37289 this._removeRegistrationFromList(registration);
290 }
291
292 /**
Tim van der Lippe0efccf02020-02-12 15:15:39293 * @param {!SDK.ServiceWorkerManager.ServiceWorkerRegistration} registration
Blink Reformat4c46d092018-04-07 15:32:37294 */
295 _removeRegistrationFromList(registration) {
296 const section = this._sections.get(registration);
Tim van der Lippe1d6e57a2019-09-30 11:55:34297 if (section) {
Blink Reformat4c46d092018-04-07 15:32:37298 section._section.detach();
Tim van der Lippe1d6e57a2019-09-30 11:55:34299 }
Blink Reformat4c46d092018-04-07 15:32:37300 this._sections.delete(registration);
301 this._updateSectionVisibility();
302 }
303
304 /**
Tim van der Lippe0efccf02020-02-12 15:15:39305 * @param {!SDK.ServiceWorkerManager.ServiceWorkerRegistration} registration
Blink Reformat4c46d092018-04-07 15:32:37306 * @return {boolean}
307 */
308 _isRegistrationVisible(registration) {
Nidhi Jajua3e34a82020-08-07 14:46:21309 if (!registration.scopeURL) {
Blink Reformat4c46d092018-04-07 15:32:37310 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:34311 }
Nidhi Jajua3e34a82020-08-07 14:46:21312 return false;
Blink Reformat4c46d092018-04-07 15:32:37313 }
314
Blink Reformat4c46d092018-04-07 15:32:37315 _updateListVisibility() {
316 this.contentElement.classList.toggle('service-worker-list-empty', this._sections.size === 0);
317 }
Tim van der Lippe097cdec2020-01-06 14:44:17318}
Blink Reformat4c46d092018-04-07 15:32:37319
Tim van der Lippe097cdec2020-01-06 14:44:17320export class Section {
Blink Reformat4c46d092018-04-07 15:32:37321 /**
Tim van der Lippe0efccf02020-02-12 15:15:39322 * @param {!SDK.ServiceWorkerManager.ServiceWorkerManager} manager
Blink Reformat4c46d092018-04-07 15:32:37323 * @param {!UI.ReportView.Section} section
Tim van der Lippe0efccf02020-02-12 15:15:39324 * @param {!SDK.ServiceWorkerManager.ServiceWorkerRegistration} registration
Blink Reformat4c46d092018-04-07 15:32:37325 */
326 constructor(manager, section, registration) {
327 this._manager = manager;
328 this._section = section;
329 this._registration = registration;
330 /** @type {?symbol} */
331 this._fingerprint = null;
Paul Lewis2d7d65c2020-03-16 17:26:30332 this._pushNotificationDataSetting = Common.Settings.Settings.instance().createLocalSetting(
Tim van der Lippe0efccf02020-02-12 15:15:39333 'pushData', Common.UIString.UIString('Test push message from DevTools.'));
Paul Lewis2d7d65c2020-03-16 17:26:30334 this._syncTagNameSetting =
335 Common.Settings.Settings.instance().createLocalSetting('syncTagName', 'test-tag-from-devtools');
Mugdha Lakhanidb7c9b12019-08-09 13:48:04336 this._periodicSyncTagNameSetting =
Paul Lewis2d7d65c2020-03-16 17:26:30337 Common.Settings.Settings.instance().createLocalSetting('periodicSyncTagName', 'test-tag-from-devtools');
Blink Reformat4c46d092018-04-07 15:32:37338
339 this._toolbar = section.createToolbar();
340 this._toolbar.renderAsLinks();
chait pinnamaneni6bc1c122020-10-30 17:30:52341 this._networkRequests = new UI.Toolbar.ToolbarButton(
342 Common.UIString.UIString('Network requests'), undefined, Common.UIString.UIString('Network requests'));
343 this._networkRequests.addEventListener(UI.Toolbar.ToolbarButton.Events.Click, this._networkRequestsClicked, this);
344 this._toolbar.appendToolbarItem(this._networkRequests);
Tim van der Lippe0efccf02020-02-12 15:15:39345 this._updateButton =
346 new UI.Toolbar.ToolbarButton(Common.UIString.UIString('Update'), undefined, Common.UIString.UIString('Update'));
347 this._updateButton.addEventListener(UI.Toolbar.ToolbarButton.Events.Click, this._updateButtonClicked, this);
Blink Reformat4c46d092018-04-07 15:32:37348 this._toolbar.appendToolbarItem(this._updateButton);
Tim van der Lippe0efccf02020-02-12 15:15:39349 this._deleteButton = new UI.Toolbar.ToolbarButton(
350 Common.UIString.UIString('Unregister service worker'), undefined, Common.UIString.UIString('Unregister'));
351 this._deleteButton.addEventListener(UI.Toolbar.ToolbarButton.Events.Click, this._unregisterButtonClicked, this);
Blink Reformat4c46d092018-04-07 15:32:37352 this._toolbar.appendToolbarItem(this._deleteButton);
353
354 // Preserve the order.
Tim van der Lippe0efccf02020-02-12 15:15:39355 this._sourceField = this._wrapWidget(this._section.appendField(Common.UIString.UIString('Source')));
356 this._statusField = this._wrapWidget(this._section.appendField(Common.UIString.UIString('Status')));
357 this._clientsField = this._wrapWidget(this._section.appendField(Common.UIString.UIString('Clients')));
Blink Reformat4c46d092018-04-07 15:32:37358 this._createSyncNotificationField(
Tim van der Lippe0efccf02020-02-12 15:15:39359 Common.UIString.UIString('Push'), this._pushNotificationDataSetting.get(),
360 Common.UIString.UIString('Push data'), this._push.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37361 this._createSyncNotificationField(
Tim van der Lippe0efccf02020-02-12 15:15:39362 Common.UIString.UIString('Sync'), this._syncTagNameSetting.get(), Common.UIString.UIString('Sync tag'),
363 this._sync.bind(this));
Mugdha Lakhani71b51fa2020-01-02 15:04:58364 this._createSyncNotificationField(
365 ls`Periodic Sync`, this._periodicSyncTagNameSetting.get(), ls`Periodic Sync tag`,
366 tag => this._periodicSync(tag));
Blink Reformat4c46d092018-04-07 15:32:37367
Tim van der Lippe0efccf02020-02-12 15:15:39368 this._linkifier = new Components.Linkifier.Linkifier();
Blink Reformat4c46d092018-04-07 15:32:37369 /** @type {!Map<string, !Protocol.Target.TargetInfo>} */
370 this._clientInfoCache = new Map();
Tim van der Lippe0efccf02020-02-12 15:15:39371 this._throttler = new Common.Throttler.Throttler(500);
Blink Reformat4c46d092018-04-07 15:32:37372 }
373
374 /**
375 * @param {string} label
376 * @param {string} initialValue
377 * @param {string} placeholder
Sigurd Schneider370b00f2020-10-28 17:30:32378 * @param {function(string):void} callback
Blink Reformat4c46d092018-04-07 15:32:37379 */
380 _createSyncNotificationField(label, initialValue, placeholder, callback) {
381 const form =
382 this._wrapWidget(this._section.appendField(label)).createChild('form', 'service-worker-editor-with-button');
Wolfgang Beyer83ae1012020-09-28 09:10:43383 const editor = UI.UIUtils.createInput('source-code service-worker-notification-editor');
384 form.appendChild(editor);
Tim van der Lippe0efccf02020-02-12 15:15:39385 const button = UI.UIUtils.createTextButton(label);
Blink Reformat4c46d092018-04-07 15:32:37386 button.type = 'submit';
387 form.appendChild(button);
388
389 editor.value = initialValue;
390 editor.placeholder = placeholder;
Junyi Xiaod3e71a42019-04-23 04:49:04391 UI.ARIAUtils.setAccessibleName(editor, label);
Blink Reformat4c46d092018-04-07 15:32:37392
Sigurd Schneider370b00f2020-10-28 17:30:32393 form.addEventListener(
394 'submit',
395 /** @param {!Event} e */
396 e => {
397 callback(editor.value || '');
398 e.consume(true);
399 });
Blink Reformat4c46d092018-04-07 15:32:37400 }
401
402 _scheduleUpdate() {
Sigurd Schneider370b00f2020-10-28 17:30:32403 if (throttleDisabledForDebugging) {
Blink Reformat4c46d092018-04-07 15:32:37404 this._update();
405 return;
406 }
407 this._throttler.schedule(this._update.bind(this));
408 }
409
410 /**
411 * @param {string} versionId
Tim van der Lippe0efccf02020-02-12 15:15:39412 * @return {?SDK.SDKModel.Target}
Blink Reformat4c46d092018-04-07 15:32:37413 */
414 _targetForVersionId(versionId) {
415 const version = this._manager.findVersion(versionId);
Tim van der Lippe1d6e57a2019-09-30 11:55:34416 if (!version || !version.targetId) {
Blink Reformat4c46d092018-04-07 15:32:37417 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34418 }
Paul Lewisdaac1062020-03-05 14:37:10419 return SDK.SDKModel.TargetManager.instance().targetById(version.targetId);
Blink Reformat4c46d092018-04-07 15:32:37420 }
421
422 /**
423 * @param {!Element} versionsStack
424 * @param {string} icon
425 * @param {string} label
426 * @return {!Element}
427 */
428 _addVersion(versionsStack, icon, label) {
429 const installingEntry = versionsStack.createChild('div', 'service-worker-version');
430 installingEntry.createChild('div', icon);
Michael Liaofeb41512020-08-20 22:45:41431 const statusString = installingEntry.createChild('span', 'service-worker-version-string');
432 statusString.textContent = label;
433 UI.ARIAUtils.markAsAlert(statusString);
Blink Reformat4c46d092018-04-07 15:32:37434 return installingEntry;
435 }
436
437 /**
Tim van der Lippe0efccf02020-02-12 15:15:39438 * @param {!SDK.ServiceWorkerManager.ServiceWorkerVersion} version
Blink Reformat4c46d092018-04-07 15:32:37439 */
440 _updateClientsField(version) {
441 this._clientsField.removeChildren();
Sigurd Schneidera38b8672020-05-20 11:31:45442 this._section.setFieldVisible(Common.UIString.UIString('Clients'), !!version.controlledClients.length);
Blink Reformat4c46d092018-04-07 15:32:37443 for (const client of version.controlledClients) {
444 const clientLabelText = this._clientsField.createChild('div', 'service-worker-client');
445 if (this._clientInfoCache.has(client)) {
446 this._updateClientInfo(
447 clientLabelText, /** @type {!Protocol.Target.TargetInfo} */ (this._clientInfoCache.get(client)));
448 }
Sigurd Schneider370b00f2020-10-28 17:30:32449 this._manager.target()
450 .targetAgent()
451 .invoke_getTargetInfo({targetId: client})
452 .then(this._onClientInfo.bind(this, clientLabelText));
Blink Reformat4c46d092018-04-07 15:32:37453 }
454 }
455
456 /**
Tim van der Lippe0efccf02020-02-12 15:15:39457 * @param {!SDK.ServiceWorkerManager.ServiceWorkerVersion} version
Blink Reformat4c46d092018-04-07 15:32:37458 */
459 _updateSourceField(version) {
460 this._sourceField.removeChildren();
Tim van der Lippe0efccf02020-02-12 15:15:39461 const fileName = Common.ParsedURL.ParsedURL.extractName(version.scriptURL);
Blink Reformat4c46d092018-04-07 15:32:37462 const name = this._sourceField.createChild('div', 'report-field-value-filename');
Sigurd Schneider370b00f2020-10-28 17:30:32463 const link = Components.Linkifier.Linkifier.linkifyURL(
464 version.scriptURL, /** @type {!Components.Linkifier.LinkifyURLOptions} */ ({text: fileName}));
Junyi Xiaod3e71a42019-04-23 04:49:04465 link.tabIndex = 0;
466 name.appendChild(link);
Blink Reformat4c46d092018-04-07 15:32:37467 if (this._registration.errors.length) {
Tim van der Lippe0efccf02020-02-12 15:15:39468 const errorsLabel = UI.UIUtils.createIconLabel(String(this._registration.errors.length), 'smallicon-error');
Blink Reformat4c46d092018-04-07 15:32:37469 errorsLabel.classList.add('link');
Junyi Xiaod3e71a42019-04-23 04:49:04470 errorsLabel.tabIndex = 0;
471 UI.ARIAUtils.setAccessibleName(errorsLabel, ls`${this._registration.errors.length} registration errors`);
Paul Lewisa83ea612020-03-04 13:01:36472 self.onInvokeElement(errorsLabel, () => Common.Console.Console.instance().show());
Blink Reformat4c46d092018-04-07 15:32:37473 name.appendChild(errorsLabel);
474 }
Sigurd Schneider370b00f2020-10-28 17:30:32475 if (version.scriptResponseTime !== undefined) {
476 this._sourceField.createChild('div', 'report-field-value-subtitle').textContent =
477 Common.UIString.UIString('Received %s', new Date(version.scriptResponseTime * 1000).toLocaleString());
478 }
Blink Reformat4c46d092018-04-07 15:32:37479 }
480
481 /**
Sigurd Schneider370b00f2020-10-28 17:30:32482 * @return {!Promise<void>}
Blink Reformat4c46d092018-04-07 15:32:37483 */
484 _update() {
485 const fingerprint = this._registration.fingerprint();
Tim van der Lippe1d6e57a2019-09-30 11:55:34486 if (fingerprint === this._fingerprint) {
Blink Reformat4c46d092018-04-07 15:32:37487 return Promise.resolve();
Tim van der Lippe1d6e57a2019-09-30 11:55:34488 }
Blink Reformat4c46d092018-04-07 15:32:37489 this._fingerprint = fingerprint;
490
491 this._toolbar.setEnabled(!this._registration.isDeleted);
492
493 const versions = this._registration.versionsByMode();
Harley Li09a58712019-06-07 19:25:54494 const scopeURL = this._registration.scopeURL;
Tim van der Lippe0efccf02020-02-12 15:15:39495 const title = this._registration.isDeleted ? Common.UIString.UIString('%s - deleted', scopeURL) : scopeURL;
Blink Reformat4c46d092018-04-07 15:32:37496 this._section.setTitle(title);
497
Tim van der Lippe0efccf02020-02-12 15:15:39498 const active = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.Active);
499 const waiting = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.Waiting);
500 const installing = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.Installing);
501 const redundant = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.Redundant);
Blink Reformat4c46d092018-04-07 15:32:37502
503 this._statusField.removeChildren();
504 const versionsStack = this._statusField.createChild('div', 'service-worker-version-stack');
505 versionsStack.createChild('div', 'service-worker-version-stack-bar');
506
507 if (active) {
508 this._updateSourceField(active);
Tim van der Lippe0efccf02020-02-12 15:15:39509 const localizedRunningStatus = SDK.ServiceWorkerManager.ServiceWorkerVersion.RunningStatus[active.runningStatus];
Blink Reformat4c46d092018-04-07 15:32:37510 const activeEntry = this._addVersion(
Mandy Chen9c1200c2019-09-24 18:36:01511 versionsStack, 'service-worker-active-circle', ls`#${active.id} activated and is ${localizedRunningStatus}`);
Blink Reformat4c46d092018-04-07 15:32:37512
513 if (active.isRunning() || active.isStarting()) {
Tim van der Lippe0efccf02020-02-12 15:15:39514 this._createLink(activeEntry, Common.UIString.UIString('stop'), this._stopButtonClicked.bind(this, active.id));
Tim van der Lippe1d6e57a2019-09-30 11:55:34515 if (!this._targetForVersionId(active.id)) {
Tim van der Lippe0efccf02020-02-12 15:15:39516 this._createLink(
517 activeEntry, Common.UIString.UIString('inspect'), this._inspectButtonClicked.bind(this, active.id));
Tim van der Lippe1d6e57a2019-09-30 11:55:34518 }
Blink Reformat4c46d092018-04-07 15:32:37519 } else if (active.isStartable()) {
Tim van der Lippe0efccf02020-02-12 15:15:39520 this._createLink(activeEntry, Common.UIString.UIString('start'), this._startButtonClicked.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37521 }
522 this._updateClientsField(active);
523 } else if (redundant) {
524 this._updateSourceField(redundant);
525 this._addVersion(
Tim van der Lippe0efccf02020-02-12 15:15:39526 versionsStack, 'service-worker-redundant-circle', Common.UIString.UIString('#%s is redundant', redundant.id));
Blink Reformat4c46d092018-04-07 15:32:37527 this._updateClientsField(redundant);
528 }
529
530 if (waiting) {
531 const waitingEntry = this._addVersion(
Tim van der Lippe0efccf02020-02-12 15:15:39532 versionsStack, 'service-worker-waiting-circle',
533 Common.UIString.UIString('#%s waiting to activate', waiting.id));
534 this._createLink(waitingEntry, Common.UIString.UIString('skipWaiting'), this._skipButtonClicked.bind(this));
Sigurd Schneider370b00f2020-10-28 17:30:32535 if (waiting.scriptResponseTime !== undefined) {
536 waitingEntry.createChild('div', 'service-worker-subtitle').textContent =
537 Common.UIString.UIString('Received %s', new Date(waiting.scriptResponseTime * 1000).toLocaleString());
538 }
Tim van der Lippe1d6e57a2019-09-30 11:55:34539 if (!this._targetForVersionId(waiting.id) && (waiting.isRunning() || waiting.isStarting())) {
Tim van der Lippe0efccf02020-02-12 15:15:39540 this._createLink(
541 waitingEntry, Common.UIString.UIString('inspect'), this._inspectButtonClicked.bind(this, waiting.id));
Tim van der Lippe1d6e57a2019-09-30 11:55:34542 }
Blink Reformat4c46d092018-04-07 15:32:37543 }
544 if (installing) {
545 const installingEntry = this._addVersion(
Tim van der Lippe0efccf02020-02-12 15:15:39546 versionsStack, 'service-worker-installing-circle',
547 Common.UIString.UIString('#%s trying to install', installing.id));
Sigurd Schneider370b00f2020-10-28 17:30:32548 if (installing.scriptResponseTime !== undefined) {
549 installingEntry.createChild('div', 'service-worker-subtitle').textContent =
550 Common.UIString.UIString('Received %s', new Date(installing.scriptResponseTime * 1000).toLocaleString());
551 }
Junyi Xiaod3e71a42019-04-23 04:49:04552 if (!this._targetForVersionId(installing.id) && (installing.isRunning() || installing.isStarting())) {
553 this._createLink(
Tim van der Lippe0efccf02020-02-12 15:15:39554 installingEntry, Common.UIString.UIString('inspect'), this._inspectButtonClicked.bind(this, installing.id));
Junyi Xiaod3e71a42019-04-23 04:49:04555 }
Blink Reformat4c46d092018-04-07 15:32:37556 }
557 return Promise.resolve();
558 }
559
560 /**
Junyi Xiaod3e71a42019-04-23 04:49:04561 * @param {!Element} parent
562 * @param {string} title
Sigurd Schneider370b00f2020-10-28 17:30:32563 * @param {function():void} listener
Junyi Xiaod3e71a42019-04-23 04:49:04564 * @param {string=} className
565 * @param {boolean=} useCapture
566 * @return {!Element}
567 */
568 _createLink(parent, title, listener, className, useCapture) {
Sigurd Schneider370b00f2020-10-28 17:30:32569 const button = /** @type {!HTMLElement} */ (document.createElement('button'));
570 if (className) {
571 button.className = className;
572 }
Wolfgang Beyer83ae1012020-09-28 09:10:43573 button.classList.add('link', 'devtools-link');
Junyi Xiaod3e71a42019-04-23 04:49:04574 button.textContent = title;
575 button.tabIndex = 0;
576 button.addEventListener('click', listener, useCapture);
Sigurd Schneider370b00f2020-10-28 17:30:32577 parent.appendChild(button);
Junyi Xiaod3e71a42019-04-23 04:49:04578 return button;
579 }
580
581 /**
Tim van der Lippec02a97c2020-02-14 14:39:27582 * @param {!Common.EventTarget.EventTargetEvent} event
Blink Reformat4c46d092018-04-07 15:32:37583 */
584 _unregisterButtonClicked(event) {
585 this._manager.deleteRegistration(this._registration.id);
586 }
587
588 /**
Tim van der Lippec02a97c2020-02-14 14:39:27589 * @param {!Common.EventTarget.EventTargetEvent} event
Blink Reformat4c46d092018-04-07 15:32:37590 */
591 _updateButtonClicked(event) {
592 this._manager.updateRegistration(this._registration.id);
593 }
594
595 /**
chait pinnamaneni6bc1c122020-10-30 17:30:52596 * @param {!Common.EventTarget.EventTargetEvent} event
597 */
598 _networkRequestsClicked(event) {
599 const applicationTabLocation = UI.ViewManager.ViewManager.instance().locationNameForViewId('resources');
600 const networkTabLocation = applicationTabLocation === 'drawer-view' ? 'panel' : 'drawer-view';
601 UI.ViewManager.ViewManager.instance().showViewInLocation('network'networkTabLocation);
602
603 Network.NetworkPanel.NetworkPanel.revealAndFilter([
604 {
605 filterType: Network.NetworkLogView.FilterType.Is,
606 filterValue: Network.NetworkLogView.IsFilterType.ServiceWorkerIntercepted,
607 },
608 ]);
609
610 const requests = SDK.NetworkLog.NetworkLog.instance().requests();
611 let lastRequest = null;
612 if (Array.isArray(requests)) {
613 for (const request of requests) {
614 if (!lastRequest && request.fetchedViaServiceWorker) {
615 lastRequest = request;
616 }
617 if (request.fetchedViaServiceWorker && lastRequest &&
618 lastRequest.responseReceivedTime < request.responseReceivedTime) {
619 lastRequest = request;
620 }
621 }
622 }
623 if (lastRequest) {
624 Network.NetworkPanel.NetworkPanel.selectAndShowRequest(
625 lastRequest, Network.NetworkItemView.Tabs.Timing, {clearFilter: false});
626 }
627
628 this._manager.serviceWorkerNetworkRequestsPanelOpen = true;
629 }
630
631 /**
Blink Reformat4c46d092018-04-07 15:32:37632 * @param {string} data
633 */
634 _push(data) {
635 this._pushNotificationDataSetting.set(data);
636 this._manager.deliverPushMessage(this._registration.id, data);
637 }
638
639 /**
640 * @param {string} tag
641 */
642 _sync(tag) {
643 this._syncTagNameSetting.set(tag);
644 this._manager.dispatchSyncEvent(this._registration.id, tag, true);
645 }
646
647 /**
Mugdha Lakhanidb7c9b12019-08-09 13:48:04648 * @param {string} tag
649 */
650 _periodicSync(tag) {
651 this._periodicSyncTagNameSetting.set(tag);
652 this._manager.dispatchPeriodicSyncEvent(this._registration.id, tag);
653 }
654
655 /**
Blink Reformat4c46d092018-04-07 15:32:37656 * @param {!Element} element
Sigurd Schneider370b00f2020-10-28 17:30:32657 * @param {!Protocol.Target.GetTargetInfoResponse} targetInfoResponse
Blink Reformat4c46d092018-04-07 15:32:37658 */
Sigurd Schneider370b00f2020-10-28 17:30:32659 _onClientInfo(element, targetInfoResponse) {
660 const targetInfo = targetInfoResponse.targetInfo;
Tim van der Lippe1d6e57a2019-09-30 11:55:34661 if (!targetInfo) {
Blink Reformat4c46d092018-04-07 15:32:37662 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34663 }
Blink Reformat4c46d092018-04-07 15:32:37664 this._clientInfoCache.set(targetInfo.targetId, targetInfo);
665 this._updateClientInfo(element, targetInfo);
666 }
667
668 /**
669 * @param {!Element} element
670 * @param {!Protocol.Target.TargetInfo} targetInfo
671 */
672 _updateClientInfo(element, targetInfo) {
673 if (targetInfo.type !== 'page' && targetInfo.type === 'iframe') {
Harley Lia8a622f2018-11-01 23:58:09674 const clientString = element.createChild('span', 'service-worker-client-string');
Sigurd Schneider23c52972020-10-13 09:31:14675 UI.UIUtils.createTextChild(clientString, ls`Worker: ${targetInfo.url}`);
Blink Reformat4c46d092018-04-07 15:32:37676 return;
677 }
678 element.removeChildren();
Harley Lia8a622f2018-11-01 23:58:09679 const clientString = element.createChild('span', 'service-worker-client-string');
Sigurd Schneider23c52972020-10-13 09:31:14680 UI.UIUtils.createTextChild(clientString, targetInfo.url);
Junyi Xiaod3e71a42019-04-23 04:49:04681 this._createLink(
682 element, ls`focus`, this._activateTarget.bind(this, targetInfo.targetId), 'service-worker-client-focus-link');
Blink Reformat4c46d092018-04-07 15:32:37683 }
684
685 /**
686 * @param {string} targetId
687 */
688 _activateTarget(targetId) {
Sigurd Schneider370b00f2020-10-28 17:30:32689 this._manager.target().targetAgent().invoke_activateTarget({targetId});
Blink Reformat4c46d092018-04-07 15:32:37690 }
691
692 _startButtonClicked() {
693 this._manager.startWorker(this._registration.scopeURL);
694 }
695
696 _skipButtonClicked() {
697 this._manager.skipWaiting(this._registration.scopeURL);
698 }
699
700 /**
701 * @param {string} versionId
702 */
703 _stopButtonClicked(versionId) {
704 this._manager.stopWorker(versionId);
705 }
706
707 /**
708 * @param {string} versionId
709 */
710 _inspectButtonClicked(versionId) {
711 this._manager.inspectWorker(versionId);
712 }
713
714 /**
715 * @param {!Element} container
716 * @return {!Element}
717 */
718 _wrapWidget(container) {
Tim van der Lippe0efccf02020-02-12 15:15:39719 const shadowRoot = UI.Utils.createShadowRootWithCoreStyles(container);
Jack Franklin71519f82020-11-03 12:08:59720 UI.Utils.appendStyle(shadowRoot, 'resources/serviceWorkersView.css', {enableLegacyPatching: true});
Sigurd Schneider370b00f2020-10-28 17:30:32721 const contentElement = document.createElement('div');
Blink Reformat4c46d092018-04-07 15:32:37722 shadowRoot.appendChild(contentElement);
723 return contentElement;
724 }
Tim van der Lippe097cdec2020-01-06 14:44:17725}