blob: 3ebd1ba8f00bb2b744c7ffb3958559d1bd86c115 [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';
8import * as SDK from '../sdk/sdk.js';
9import * as UI from '../ui/ui.js';
10
Blink Reformat4c46d092018-04-07 15:32:3711/**
Tim van der Lippe0efccf02020-02-12 15:15:3912 * @implements {SDK.SDKModel.SDKModelObserver<!SDK.ServiceWorkerManager.ServiceWorkerManager>}
Blink Reformat4c46d092018-04-07 15:32:3713 */
Tim van der Lippe0efccf02020-02-12 15:15:3914export class ServiceWorkersView extends UI.Widget.VBox {
Blink Reformat4c46d092018-04-07 15:32:3715 constructor() {
16 super(true);
17 this.registerRequiredCSS('resources/serviceWorkersView.css');
18
Tim van der Lippe0efccf02020-02-12 15:15:3919 this._currentWorkersView = new UI.ReportView.ReportView(Common.UIString.UIString('Service Workers'));
Blink Reformat4c46d092018-04-07 15:32:3720 this._currentWorkersView.setBodyScrollable(false);
21 this.contentElement.classList.add('service-worker-list');
22 this._currentWorkersView.show(this.contentElement);
23 this._currentWorkersView.element.classList.add('service-workers-this-origin');
24
25 this._toolbar = this._currentWorkersView.createToolbar();
Erik Luo5e5a8362018-05-31 23:43:2226 this._toolbar.makeWrappable(true /* growVertically */);
Blink Reformat4c46d092018-04-07 15:32:3727
Tim van der Lippe0efccf02020-02-12 15:15:3928 /** @type {!Map<!SDK.ServiceWorkerManager.ServiceWorkerRegistration, !Section>} */
Blink Reformat4c46d092018-04-07 15:32:3729 this._sections = new Map();
Harley Li68cc13c2019-02-25 21:47:2530 /** @type {symbol} */
31 this._registrationSymbol = Symbol('Resources.ServiceWorkersView');
Blink Reformat4c46d092018-04-07 15:32:3732
Tim van der Lippe0efccf02020-02-12 15:15:3933 /** @type {?SDK.ServiceWorkerManager.ServiceWorkerManager} */
Blink Reformat4c46d092018-04-07 15:32:3734 this._manager = null;
Tim van der Lippe0efccf02020-02-12 15:15:3935 /** @type {?SDK.SecurityOriginManager.SecurityOriginManager} */
Blink Reformat4c46d092018-04-07 15:32:3736 this._securityOriginManager = null;
37
Tim van der Lippe0efccf02020-02-12 15:15:3938 this._filterThrottler = new Common.Throttler.Throttler(300);
Blink Reformat4c46d092018-04-07 15:32:3739
40 this._otherWorkers = this.contentElement.createChild('div', 'service-workers-other-origin');
41 this._otherSWFilter = this._otherWorkers.createChild('div', 'service-worker-filter');
42 this._otherSWFilter.setAttribute('tabindex', 0);
43 this._otherSWFilter.setAttribute('role', 'switch');
44 this._otherSWFilter.setAttribute('aria-checked', false);
Blink Reformat4c46d092018-04-07 15:32:3745 const filterLabel = this._otherSWFilter.createChild('label', 'service-worker-filter-label');
Tim van der Lippe0efccf02020-02-12 15:15:3946 filterLabel.textContent = Common.UIString.UIString('Service workers from other origins');
Tim van der Lippec85c3122019-09-19 11:27:0447 self.onInvokeElement(this._otherSWFilter, event => {
Tim van der Lippe1d6e57a2019-09-30 11:55:3448 if (event.target === this._otherSWFilter || event.target === filterLabel) {
Jeff Fisher5096e5f2019-08-14 10:05:5149 this._toggleFilter();
Tim van der Lippe1d6e57a2019-09-30 11:55:3450 }
Jeff Fisher5096e5f2019-08-14 10:05:5151 });
Blink Reformat4c46d092018-04-07 15:32:3752
Tim van der Lippe0efccf02020-02-12 15:15:3953 const toolbar = new UI.Toolbar.Toolbar('service-worker-filter-toolbar', this._otherSWFilter);
54 this._filter = new UI.Toolbar.ToolbarInput(ls`Filter service worker`, '', 1);
55 this._filter.addEventListener(UI.Toolbar.ToolbarInput.Event.TextChanged, () => this._filterChanged());
Blink Reformat4c46d092018-04-07 15:32:3756 toolbar.appendToolbarItem(this._filter);
57
Tim van der Lippe0efccf02020-02-12 15:15:3958 this._otherWorkersView = new UI.ReportView.ReportView();
Blink Reformat4c46d092018-04-07 15:32:3759 this._otherWorkersView.setBodyScrollable(false);
60 this._otherWorkersView.show(this._otherWorkers);
61 this._otherWorkersView.element.classList.add('service-workers-for-other-origins');
62
63 this._updateCollapsedStyle();
64
Tim van der Lippe0efccf02020-02-12 15:15:3965 this._toolbar.appendToolbarItem(
66 MobileThrottling.ThrottlingManager.throttlingManager().createOfflineToolbarCheckbox());
Paul Lewis6bcdb182020-01-23 11:08:0567 const updateOnReloadSetting = self.Common.settings.createSetting('serviceWorkerUpdateOnReload', false);
Tim van der Lippe0efccf02020-02-12 15:15:3968 updateOnReloadSetting.setTitle(Common.UIString.UIString('Update on reload'));
69 const forceUpdate = new UI.Toolbar.ToolbarSettingCheckbox(
Harley Li38795b32019-01-10 22:32:2670 updateOnReloadSetting, ls`On page reload, force the service worker to update, and activate it`);
Blink Reformat4c46d092018-04-07 15:32:3771 this._toolbar.appendToolbarItem(forceUpdate);
Paul Lewis6bcdb182020-01-23 11:08:0572 const bypassServiceWorkerSetting = self.Common.settings.createSetting('bypassServiceWorker', false);
Tim van der Lippe0efccf02020-02-12 15:15:3973 bypassServiceWorkerSetting.setTitle(Common.UIString.UIString('Bypass for network'));
74 const fallbackToNetwork = new UI.Toolbar.ToolbarSettingCheckbox(
Harley Li34d68fa2019-01-12 02:21:2475 bypassServiceWorkerSetting, ls`Bypass the service worker and load resources from the network`);
Blink Reformat4c46d092018-04-07 15:32:3776 this._toolbar.appendToolbarItem(fallbackToNetwork);
77
Tim van der Lippe0efccf02020-02-12 15:15:3978 /** @type {!Map<!SDK.ServiceWorkerManager.ServiceWorkerManager, !Array<!Common.EventTarget.EventDescriptor>>}*/
Blink Reformat4c46d092018-04-07 15:32:3779 this._eventListeners = new Map();
Paul Lewisdaac1062020-03-05 14:37:1080 SDK.SDKModel.TargetManager.instance().observeModels(SDK.ServiceWorkerManager.ServiceWorkerManager, this);
Blink Reformat4c46d092018-04-07 15:32:3781 this._updateListVisibility();
82 }
83
84 /**
85 * @override
Tim van der Lippe0efccf02020-02-12 15:15:3986 * @param {!SDK.ServiceWorkerManager.ServiceWorkerManager} serviceWorkerManager
Blink Reformat4c46d092018-04-07 15:32:3787 */
88 modelAdded(serviceWorkerManager) {
Tim van der Lippe1d6e57a2019-09-30 11:55:3489 if (this._manager) {
Blink Reformat4c46d092018-04-07 15:32:3790 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:3491 }
Blink Reformat4c46d092018-04-07 15:32:3792 this._manager = serviceWorkerManager;
Tim van der Lippe0efccf02020-02-12 15:15:3993 this._securityOriginManager = serviceWorkerManager.target().model(SDK.SecurityOriginManager.SecurityOriginManager);
Blink Reformat4c46d092018-04-07 15:32:3794
Tim van der Lippe1d6e57a2019-09-30 11:55:3495 for (const registration of this._manager.registrations().values()) {
Blink Reformat4c46d092018-04-07 15:32:3796 this._updateRegistration(registration);
Tim van der Lippe1d6e57a2019-09-30 11:55:3497 }
Blink Reformat4c46d092018-04-07 15:32:3798
99 this._eventListeners.set(serviceWorkerManager, [
100 this._manager.addEventListener(
101 SDK.ServiceWorkerManager.Events.RegistrationUpdated, this._registrationUpdated, this),
102 this._manager.addEventListener(
103 SDK.ServiceWorkerManager.Events.RegistrationDeleted, this._registrationDeleted, this),
104 this._securityOriginManager.addEventListener(
105 SDK.SecurityOriginManager.Events.SecurityOriginAdded, this._updateSectionVisibility, this),
106 this._securityOriginManager.addEventListener(
107 SDK.SecurityOriginManager.Events.SecurityOriginRemoved, this._updateSectionVisibility, this),
108 ]);
109 }
110
111 /**
112 * @override
Tim van der Lippe0efccf02020-02-12 15:15:39113 * @param {!SDK.ServiceWorkerManager.ServiceWorkerManager} serviceWorkerManager
Blink Reformat4c46d092018-04-07 15:32:37114 */
115 modelRemoved(serviceWorkerManager) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34116 if (!this._manager || this._manager !== serviceWorkerManager) {
Blink Reformat4c46d092018-04-07 15:32:37117 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34118 }
Blink Reformat4c46d092018-04-07 15:32:37119
Tim van der Lippe0efccf02020-02-12 15:15:39120 Common.EventTarget.EventTarget.removeEventListeners(this._eventListeners.get(serviceWorkerManager));
Blink Reformat4c46d092018-04-07 15:32:37121 this._eventListeners.delete(serviceWorkerManager);
122 this._manager = null;
123 this._securityOriginManager = null;
124 }
125
Harley Li68cc13c2019-02-25 21:47:25126
127 /**
Tim van der Lippe0efccf02020-02-12 15:15:39128 * @param {!SDK.ServiceWorkerManager.ServiceWorkerRegistration} registration
Harley Li68cc13c2019-02-25 21:47:25129 * @return {number}
130 */
131 _getTimeStamp(registration) {
132 const versions = registration.versionsByMode();
133
134 let timestamp = 0;
135
Tim van der Lippe0efccf02020-02-12 15:15:39136 const active = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.Active);
137 const installing = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.Installing);
138 const waiting = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.Waiting);
139 const redundant = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.Redundant);
Harley Li68cc13c2019-02-25 21:47:25140
Tim van der Lippe1d6e57a2019-09-30 11:55:34141 if (active) {
Harley Li68cc13c2019-02-25 21:47:25142 timestamp = active.scriptResponseTime;
Tim van der Lippe1d6e57a2019-09-30 11:55:34143 } else if (waiting) {
Harley Li68cc13c2019-02-25 21:47:25144 timestamp = waiting.scriptResponseTime;
Tim van der Lippe1d6e57a2019-09-30 11:55:34145 } else if (installing) {
Harley Li68cc13c2019-02-25 21:47:25146 timestamp = installing.scriptResponseTime;
Tim van der Lippe1d6e57a2019-09-30 11:55:34147 } else if (redundant) {
Harley Li68cc13c2019-02-25 21:47:25148 timestamp = redundant.scriptResponseTime;
Tim van der Lippe1d6e57a2019-09-30 11:55:34149 }
Harley Li68cc13c2019-02-25 21:47:25150
151 return timestamp;
152 }
153
Blink Reformat4c46d092018-04-07 15:32:37154 _updateSectionVisibility() {
155 let hasOthers = false;
156 let hasThis = false;
157 const movedSections = [];
158 for (const section of this._sections.values()) {
159 const expectedView = this._getReportViewForOrigin(section._registration.securityOrigin);
160 hasOthers |= expectedView === this._otherWorkersView;
161 hasThis |= expectedView === this._currentWorkersView;
Tim van der Lippe1d6e57a2019-09-30 11:55:34162 if (section._section.parentWidget() !== expectedView) {
Blink Reformat4c46d092018-04-07 15:32:37163 movedSections.push(section);
Tim van der Lippe1d6e57a2019-09-30 11:55:34164 }
Blink Reformat4c46d092018-04-07 15:32:37165 }
166
167 for (const section of movedSections) {
168 const registration = section._registration;
169 this._removeRegistrationFromList(registration);
170 this._updateRegistration(registration, true);
171 }
172
Harley Li68cc13c2019-02-25 21:47:25173 this._currentWorkersView.sortSections((a, b) => {
174 const aTimestamp = this._getTimeStamp(a[this._registrationSymbol]);
175 const bTimestamp = this._getTimeStamp(b[this._registrationSymbol]);
176 // the newest (largest timestamp value) should be the first
177 return bTimestamp - aTimestamp;
178 });
179
Blink Reformat4c46d092018-04-07 15:32:37180 const scorer = new Sources.FilePathScoreFunction(this._filter.value());
181 this._otherWorkersView.sortSections((a, b) => {
182 const cmp = scorer.score(b.title(), null) - scorer.score(a.title(), null);
183 return cmp === 0 ? a.title().localeCompare(b.title()) : cmp;
184 });
185 for (const section of this._sections.values()) {
186 if (section._section.parentWidget() === this._currentWorkersView ||
Tim van der Lippe1d6e57a2019-09-30 11:55:34187 this._isRegistrationVisible(section._registration)) {
Blink Reformat4c46d092018-04-07 15:32:37188 section._section.showWidget();
Tim van der Lippe1d6e57a2019-09-30 11:55:34189 } else {
Blink Reformat4c46d092018-04-07 15:32:37190 section._section.hideWidget();
Tim van der Lippe1d6e57a2019-09-30 11:55:34191 }
Blink Reformat4c46d092018-04-07 15:32:37192 }
Tim van der Lippeffa78622019-09-16 12:07:12193 this.contentElement.classList.toggle('service-worker-has-current', !!hasThis);
Blink Reformat4c46d092018-04-07 15:32:37194 this._otherWorkers.classList.toggle('hidden', !hasOthers);
195 this._updateListVisibility();
196 }
197
198 /**
Tim van der Lippec02a97c2020-02-14 14:39:27199 * @param {!Common.EventTarget.EventTargetEvent} event
Blink Reformat4c46d092018-04-07 15:32:37200 */
201 _registrationUpdated(event) {
Tim van der Lippe0efccf02020-02-12 15:15:39202 const registration = /** @type {!SDK.ServiceWorkerManager.ServiceWorkerRegistration} */ (event.data);
Blink Reformat4c46d092018-04-07 15:32:37203 this._updateRegistration(registration);
204 this._gcRegistrations();
205 }
206
207 _gcRegistrations() {
208 let hasNonDeletedRegistrations = false;
209 const securityOrigins = new Set(this._securityOriginManager.securityOrigins());
210 for (const registration of this._manager.registrations().values()) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34211 if (!securityOrigins.has(registration.securityOrigin) && !this._isRegistrationVisible(registration)) {
Blink Reformat4c46d092018-04-07 15:32:37212 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:34213 }
Blink Reformat4c46d092018-04-07 15:32:37214 if (!registration.canBeRemoved()) {
215 hasNonDeletedRegistrations = true;
216 break;
217 }
218 }
219
Tim van der Lippe1d6e57a2019-09-30 11:55:34220 if (!hasNonDeletedRegistrations) {
Blink Reformat4c46d092018-04-07 15:32:37221 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34222 }
Blink Reformat4c46d092018-04-07 15:32:37223
224 for (const registration of this._manager.registrations().values()) {
225 const visible = securityOrigins.has(registration.securityOrigin) || this._isRegistrationVisible(registration);
Tim van der Lippe1d6e57a2019-09-30 11:55:34226 if (!visible && registration.canBeRemoved()) {
Blink Reformat4c46d092018-04-07 15:32:37227 this._removeRegistrationFromList(registration);
Tim van der Lippe1d6e57a2019-09-30 11:55:34228 }
Blink Reformat4c46d092018-04-07 15:32:37229 }
230 }
231
232 /**
233 * @param {string} origin
Tim van der Lippe0efccf02020-02-12 15:15:39234 * @return {!UI.ReportView.ReportView}
Blink Reformat4c46d092018-04-07 15:32:37235 */
236 _getReportViewForOrigin(origin) {
Harley Liddf2b682019-03-08 22:35:23237 if (this._securityOriginManager.securityOrigins().includes(origin) ||
Tim van der Lippe1d6e57a2019-09-30 11:55:34238 this._securityOriginManager.unreachableMainSecurityOrigin() === origin) {
Blink Reformat4c46d092018-04-07 15:32:37239 return this._currentWorkersView;
Tim van der Lippe1d6e57a2019-09-30 11:55:34240 }
Mathias Bynensf06e8c02020-02-28 13:58:28241 return this._otherWorkersView;
Blink Reformat4c46d092018-04-07 15:32:37242 }
243
244 /**
Tim van der Lippe0efccf02020-02-12 15:15:39245 * @param {!SDK.ServiceWorkerManager.ServiceWorkerRegistration} registration
Blink Reformat4c46d092018-04-07 15:32:37246 * @param {boolean=} skipUpdate
247 */
248 _updateRegistration(registration, skipUpdate) {
249 let section = this._sections.get(registration);
250 if (!section) {
Harley Li09a58712019-06-07 19:25:54251 const title = registration.scopeURL;
Harley Li68cc13c2019-02-25 21:47:25252 const uiSection = this._getReportViewForOrigin(registration.securityOrigin).appendSection(title);
Rob Pavezacb832182019-10-16 23:13:00253 uiSection.setUiGroupTitle(ls`Service worker for ${title}`);
Harley Li68cc13c2019-02-25 21:47:25254 uiSection[this._registrationSymbol] = registration;
Tim van der Lippe097cdec2020-01-06 14:44:17255 section = new Section(
Tim van der Lippe0efccf02020-02-12 15:15:39256 /** @type {!SDK.ServiceWorkerManager.ServiceWorkerManager} */ (this._manager), uiSection, registration);
Blink Reformat4c46d092018-04-07 15:32:37257 this._sections.set(registration, section);
258 }
Tim van der Lippe1d6e57a2019-09-30 11:55:34259 if (skipUpdate) {
Blink Reformat4c46d092018-04-07 15:32:37260 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34261 }
Blink Reformat4c46d092018-04-07 15:32:37262 this._updateSectionVisibility();
263 section._scheduleUpdate();
264 }
265
266 /**
Tim van der Lippec02a97c2020-02-14 14:39:27267 * @param {!Common.EventTarget.EventTargetEvent} event
Blink Reformat4c46d092018-04-07 15:32:37268 */
269 _registrationDeleted(event) {
Tim van der Lippe0efccf02020-02-12 15:15:39270 const registration = /** @type {!SDK.ServiceWorkerManager.ServiceWorkerRegistration} */ (event.data);
Blink Reformat4c46d092018-04-07 15:32:37271 this._removeRegistrationFromList(registration);
272 }
273
274 /**
Tim van der Lippe0efccf02020-02-12 15:15:39275 * @param {!SDK.ServiceWorkerManager.ServiceWorkerRegistration} registration
Blink Reformat4c46d092018-04-07 15:32:37276 */
277 _removeRegistrationFromList(registration) {
278 const section = this._sections.get(registration);
Tim van der Lippe1d6e57a2019-09-30 11:55:34279 if (section) {
Blink Reformat4c46d092018-04-07 15:32:37280 section._section.detach();
Tim van der Lippe1d6e57a2019-09-30 11:55:34281 }
Blink Reformat4c46d092018-04-07 15:32:37282 this._sections.delete(registration);
283 this._updateSectionVisibility();
284 }
285
286 /**
Tim van der Lippe0efccf02020-02-12 15:15:39287 * @param {!SDK.ServiceWorkerManager.ServiceWorkerRegistration} registration
Blink Reformat4c46d092018-04-07 15:32:37288 * @return {boolean}
289 */
290 _isRegistrationVisible(registration) {
291 const filterString = this._filter.value();
Tim van der Lippe1d6e57a2019-09-30 11:55:34292 if (!filterString || !registration.scopeURL) {
Blink Reformat4c46d092018-04-07 15:32:37293 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:34294 }
Blink Reformat4c46d092018-04-07 15:32:37295
296 const regex = String.filterRegex(filterString);
297 return registration.scopeURL.match(regex);
298 }
299
300 _filterChanged() {
301 this._updateCollapsedStyle();
302 this._filterThrottler.schedule(() => Promise.resolve(this._updateSectionVisibility()));
303 }
304
305 _updateCollapsedStyle() {
306 const expanded = this._otherSWFilter.getAttribute('aria-checked') === 'true';
307 this._otherWorkers.classList.toggle('service-worker-filter-collapsed', !expanded);
Tim van der Lippe1d6e57a2019-09-30 11:55:34308 if (expanded) {
Blink Reformat4c46d092018-04-07 15:32:37309 this._otherWorkersView.showWidget();
Tim van der Lippe1d6e57a2019-09-30 11:55:34310 } else {
Blink Reformat4c46d092018-04-07 15:32:37311 this._otherWorkersView.hideWidget();
Tim van der Lippe1d6e57a2019-09-30 11:55:34312 }
Blink Reformat4c46d092018-04-07 15:32:37313 this._otherWorkersView.setHeaderVisible(false);
314 }
315
Blink Reformat4c46d092018-04-07 15:32:37316 _updateListVisibility() {
317 this.contentElement.classList.toggle('service-worker-list-empty', this._sections.size === 0);
318 }
319
320 _toggleFilter() {
321 const expanded = this._otherSWFilter.getAttribute('aria-checked') === 'true';
322 this._otherSWFilter.setAttribute('aria-checked', !expanded);
323 this._filterChanged();
324 }
Tim van der Lippe097cdec2020-01-06 14:44:17325}
Blink Reformat4c46d092018-04-07 15:32:37326
Tim van der Lippe097cdec2020-01-06 14:44:17327export class Section {
Blink Reformat4c46d092018-04-07 15:32:37328 /**
Tim van der Lippe0efccf02020-02-12 15:15:39329 * @param {!SDK.ServiceWorkerManager.ServiceWorkerManager} manager
Blink Reformat4c46d092018-04-07 15:32:37330 * @param {!UI.ReportView.Section} section
Tim van der Lippe0efccf02020-02-12 15:15:39331 * @param {!SDK.ServiceWorkerManager.ServiceWorkerRegistration} registration
Blink Reformat4c46d092018-04-07 15:32:37332 */
333 constructor(manager, section, registration) {
334 this._manager = manager;
335 this._section = section;
336 this._registration = registration;
337 /** @type {?symbol} */
338 this._fingerprint = null;
Tim van der Lippe0efccf02020-02-12 15:15:39339 this._pushNotificationDataSetting = self.Common.settings.createLocalSetting(
340 'pushData', Common.UIString.UIString('Test push message from DevTools.'));
Paul Lewis6bcdb182020-01-23 11:08:05341 this._syncTagNameSetting = self.Common.settings.createLocalSetting('syncTagName', 'test-tag-from-devtools');
Mugdha Lakhanidb7c9b12019-08-09 13:48:04342 this._periodicSyncTagNameSetting =
Paul Lewis6bcdb182020-01-23 11:08:05343 self.Common.settings.createLocalSetting('periodicSyncTagName', 'test-tag-from-devtools');
Blink Reformat4c46d092018-04-07 15:32:37344
345 this._toolbar = section.createToolbar();
346 this._toolbar.renderAsLinks();
Tim van der Lippe0efccf02020-02-12 15:15:39347 this._updateButton =
348 new UI.Toolbar.ToolbarButton(Common.UIString.UIString('Update'), undefined, Common.UIString.UIString('Update'));
349 this._updateButton.addEventListener(UI.Toolbar.ToolbarButton.Events.Click, this._updateButtonClicked, this);
Blink Reformat4c46d092018-04-07 15:32:37350 this._toolbar.appendToolbarItem(this._updateButton);
Tim van der Lippe0efccf02020-02-12 15:15:39351 this._deleteButton = new UI.Toolbar.ToolbarButton(
352 Common.UIString.UIString('Unregister service worker'), undefined, Common.UIString.UIString('Unregister'));
353 this._deleteButton.addEventListener(UI.Toolbar.ToolbarButton.Events.Click, this._unregisterButtonClicked, this);
Blink Reformat4c46d092018-04-07 15:32:37354 this._toolbar.appendToolbarItem(this._deleteButton);
355
356 // Preserve the order.
Tim van der Lippe0efccf02020-02-12 15:15:39357 this._sourceField = this._wrapWidget(this._section.appendField(Common.UIString.UIString('Source')));
358 this._statusField = this._wrapWidget(this._section.appendField(Common.UIString.UIString('Status')));
359 this._clientsField = this._wrapWidget(this._section.appendField(Common.UIString.UIString('Clients')));
Blink Reformat4c46d092018-04-07 15:32:37360 this._createSyncNotificationField(
Tim van der Lippe0efccf02020-02-12 15:15:39361 Common.UIString.UIString('Push'), this._pushNotificationDataSetting.get(),
362 Common.UIString.UIString('Push data'), this._push.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37363 this._createSyncNotificationField(
Tim van der Lippe0efccf02020-02-12 15:15:39364 Common.UIString.UIString('Sync'), this._syncTagNameSetting.get(), Common.UIString.UIString('Sync tag'),
365 this._sync.bind(this));
Mugdha Lakhani71b51fa2020-01-02 15:04:58366 this._createSyncNotificationField(
367 ls`Periodic Sync`, this._periodicSyncTagNameSetting.get(), ls`Periodic Sync tag`,
368 tag => this._periodicSync(tag));
Blink Reformat4c46d092018-04-07 15:32:37369
Tim van der Lippe0efccf02020-02-12 15:15:39370 this._linkifier = new Components.Linkifier.Linkifier();
Blink Reformat4c46d092018-04-07 15:32:37371 /** @type {!Map<string, !Protocol.Target.TargetInfo>} */
372 this._clientInfoCache = new Map();
Tim van der Lippe0efccf02020-02-12 15:15:39373 this._throttler = new Common.Throttler.Throttler(500);
Blink Reformat4c46d092018-04-07 15:32:37374 }
375
376 /**
377 * @param {string} label
378 * @param {string} initialValue
379 * @param {string} placeholder
380 * @param {function(string)} callback
381 */
382 _createSyncNotificationField(label, initialValue, placeholder, callback) {
383 const form =
384 this._wrapWidget(this._section.appendField(label)).createChild('form', 'service-worker-editor-with-button');
385 const editor = form.createChild('input', 'source-code service-worker-notification-editor');
Tim van der Lippe0efccf02020-02-12 15:15:39386 const button = UI.UIUtils.createTextButton(label);
Blink Reformat4c46d092018-04-07 15:32:37387 button.type = 'submit';
388 form.appendChild(button);
389
390 editor.value = initialValue;
391 editor.placeholder = placeholder;
Junyi Xiaod3e71a42019-04-23 04:49:04392 UI.ARIAUtils.setAccessibleName(editor, label);
Blink Reformat4c46d092018-04-07 15:32:37393
394 form.addEventListener('submit', e => {
395 callback(editor.value || '');
396 e.consume(true);
397 });
398 }
399
400 _scheduleUpdate() {
Tim van der Lippe097cdec2020-01-06 14:44:17401 if (ServiceWorkersView._noThrottle) {
Blink Reformat4c46d092018-04-07 15:32:37402 this._update();
403 return;
404 }
405 this._throttler.schedule(this._update.bind(this));
406 }
407
408 /**
409 * @param {string} versionId
Tim van der Lippe0efccf02020-02-12 15:15:39410 * @return {?SDK.SDKModel.Target}
Blink Reformat4c46d092018-04-07 15:32:37411 */
412 _targetForVersionId(versionId) {
413 const version = this._manager.findVersion(versionId);
Tim van der Lippe1d6e57a2019-09-30 11:55:34414 if (!version || !version.targetId) {
Blink Reformat4c46d092018-04-07 15:32:37415 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34416 }
Paul Lewisdaac1062020-03-05 14:37:10417 return SDK.SDKModel.TargetManager.instance().targetById(version.targetId);
Blink Reformat4c46d092018-04-07 15:32:37418 }
419
420 /**
421 * @param {!Element} versionsStack
422 * @param {string} icon
423 * @param {string} label
424 * @return {!Element}
425 */
426 _addVersion(versionsStack, icon, label) {
427 const installingEntry = versionsStack.createChild('div', 'service-worker-version');
428 installingEntry.createChild('div', icon);
429 installingEntry.createChild('span').textContent = label;
430 return installingEntry;
431 }
432
433 /**
Tim van der Lippe0efccf02020-02-12 15:15:39434 * @param {!SDK.ServiceWorkerManager.ServiceWorkerVersion} version
Blink Reformat4c46d092018-04-07 15:32:37435 */
436 _updateClientsField(version) {
437 this._clientsField.removeChildren();
Tim van der Lippe0efccf02020-02-12 15:15:39438 this._section.setFieldVisible(Common.UIString.UIString('Clients'), version.controlledClients.length);
Blink Reformat4c46d092018-04-07 15:32:37439 for (const client of version.controlledClients) {
440 const clientLabelText = this._clientsField.createChild('div', 'service-worker-client');
441 if (this._clientInfoCache.has(client)) {
442 this._updateClientInfo(
443 clientLabelText, /** @type {!Protocol.Target.TargetInfo} */ (this._clientInfoCache.get(client)));
444 }
445 this._manager.target().targetAgent().getTargetInfo(client).then(this._onClientInfo.bind(this, clientLabelText));
446 }
447 }
448
449 /**
Tim van der Lippe0efccf02020-02-12 15:15:39450 * @param {!SDK.ServiceWorkerManager.ServiceWorkerVersion} version
Blink Reformat4c46d092018-04-07 15:32:37451 */
452 _updateSourceField(version) {
453 this._sourceField.removeChildren();
Tim van der Lippe0efccf02020-02-12 15:15:39454 const fileName = Common.ParsedURL.ParsedURL.extractName(version.scriptURL);
Blink Reformat4c46d092018-04-07 15:32:37455 const name = this._sourceField.createChild('div', 'report-field-value-filename');
Tim van der Lippe0efccf02020-02-12 15:15:39456 const link = Components.Linkifier.Linkifier.linkifyURL(version.scriptURL, {text: fileName});
Junyi Xiaod3e71a42019-04-23 04:49:04457 link.tabIndex = 0;
458 name.appendChild(link);
Blink Reformat4c46d092018-04-07 15:32:37459 if (this._registration.errors.length) {
Tim van der Lippe0efccf02020-02-12 15:15:39460 const errorsLabel = UI.UIUtils.createIconLabel(String(this._registration.errors.length), 'smallicon-error');
Blink Reformat4c46d092018-04-07 15:32:37461 errorsLabel.classList.add('link');
Junyi Xiaod3e71a42019-04-23 04:49:04462 errorsLabel.tabIndex = 0;
463 UI.ARIAUtils.setAccessibleName(errorsLabel, ls`${this._registration.errors.length} registration errors`);
Paul Lewisa83ea612020-03-04 13:01:36464 self.onInvokeElement(errorsLabel, () => Common.Console.Console.instance().show());
Blink Reformat4c46d092018-04-07 15:32:37465 name.appendChild(errorsLabel);
466 }
John Abd-El-Malek7fa90c82018-08-27 18:39:55467 this._sourceField.createChild('div', 'report-field-value-subtitle').textContent =
Tim van der Lippe0efccf02020-02-12 15:15:39468 Common.UIString.UIString('Received %s', new Date(version.scriptResponseTime * 1000).toLocaleString());
Blink Reformat4c46d092018-04-07 15:32:37469 }
470
471 /**
472 * @return {!Promise}
473 */
474 _update() {
475 const fingerprint = this._registration.fingerprint();
Tim van der Lippe1d6e57a2019-09-30 11:55:34476 if (fingerprint === this._fingerprint) {
Blink Reformat4c46d092018-04-07 15:32:37477 return Promise.resolve();
Tim van der Lippe1d6e57a2019-09-30 11:55:34478 }
Blink Reformat4c46d092018-04-07 15:32:37479 this._fingerprint = fingerprint;
480
481 this._toolbar.setEnabled(!this._registration.isDeleted);
482
483 const versions = this._registration.versionsByMode();
Harley Li09a58712019-06-07 19:25:54484 const scopeURL = this._registration.scopeURL;
Tim van der Lippe0efccf02020-02-12 15:15:39485 const title = this._registration.isDeleted ? Common.UIString.UIString('%s - deleted', scopeURL) : scopeURL;
Blink Reformat4c46d092018-04-07 15:32:37486 this._section.setTitle(title);
487
Tim van der Lippe0efccf02020-02-12 15:15:39488 const active = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.Active);
489 const waiting = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.Waiting);
490 const installing = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.Installing);
491 const redundant = versions.get(SDK.ServiceWorkerManager.ServiceWorkerVersion.Modes.Redundant);
Blink Reformat4c46d092018-04-07 15:32:37492
493 this._statusField.removeChildren();
494 const versionsStack = this._statusField.createChild('div', 'service-worker-version-stack');
495 versionsStack.createChild('div', 'service-worker-version-stack-bar');
496
497 if (active) {
498 this._updateSourceField(active);
Tim van der Lippe0efccf02020-02-12 15:15:39499 const localizedRunningStatus = SDK.ServiceWorkerManager.ServiceWorkerVersion.RunningStatus[active.runningStatus];
Blink Reformat4c46d092018-04-07 15:32:37500 const activeEntry = this._addVersion(
Mandy Chen9c1200c2019-09-24 18:36:01501 versionsStack, 'service-worker-active-circle', ls`#${active.id} activated and is ${localizedRunningStatus}`);
Blink Reformat4c46d092018-04-07 15:32:37502
503 if (active.isRunning() || active.isStarting()) {
Tim van der Lippe0efccf02020-02-12 15:15:39504 this._createLink(activeEntry, Common.UIString.UIString('stop'), this._stopButtonClicked.bind(this, active.id));
Tim van der Lippe1d6e57a2019-09-30 11:55:34505 if (!this._targetForVersionId(active.id)) {
Tim van der Lippe0efccf02020-02-12 15:15:39506 this._createLink(
507 activeEntry, Common.UIString.UIString('inspect'), this._inspectButtonClicked.bind(this, active.id));
Tim van der Lippe1d6e57a2019-09-30 11:55:34508 }
Blink Reformat4c46d092018-04-07 15:32:37509 } else if (active.isStartable()) {
Tim van der Lippe0efccf02020-02-12 15:15:39510 this._createLink(activeEntry, Common.UIString.UIString('start'), this._startButtonClicked.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37511 }
512 this._updateClientsField(active);
513 } else if (redundant) {
514 this._updateSourceField(redundant);
515 this._addVersion(
Tim van der Lippe0efccf02020-02-12 15:15:39516 versionsStack, 'service-worker-redundant-circle', Common.UIString.UIString('#%s is redundant', redundant.id));
Blink Reformat4c46d092018-04-07 15:32:37517 this._updateClientsField(redundant);
518 }
519
520 if (waiting) {
521 const waitingEntry = this._addVersion(
Tim van der Lippe0efccf02020-02-12 15:15:39522 versionsStack, 'service-worker-waiting-circle',
523 Common.UIString.UIString('#%s waiting to activate', waiting.id));
524 this._createLink(waitingEntry, Common.UIString.UIString('skipWaiting'), this._skipButtonClicked.bind(this));
John Abd-El-Malek7fa90c82018-08-27 18:39:55525 waitingEntry.createChild('div', 'service-worker-subtitle').textContent =
Tim van der Lippe0efccf02020-02-12 15:15:39526 Common.UIString.UIString('Received %s', new Date(waiting.scriptResponseTime * 1000).toLocaleString());
Tim van der Lippe1d6e57a2019-09-30 11:55:34527 if (!this._targetForVersionId(waiting.id) && (waiting.isRunning() || waiting.isStarting())) {
Tim van der Lippe0efccf02020-02-12 15:15:39528 this._createLink(
529 waitingEntry, Common.UIString.UIString('inspect'), this._inspectButtonClicked.bind(this, waiting.id));
Tim van der Lippe1d6e57a2019-09-30 11:55:34530 }
Blink Reformat4c46d092018-04-07 15:32:37531 }
532 if (installing) {
533 const installingEntry = this._addVersion(
Tim van der Lippe0efccf02020-02-12 15:15:39534 versionsStack, 'service-worker-installing-circle',
535 Common.UIString.UIString('#%s trying to install', installing.id));
John Abd-El-Malek7fa90c82018-08-27 18:39:55536 installingEntry.createChild('div', 'service-worker-subtitle').textContent =
Tim van der Lippe0efccf02020-02-12 15:15:39537 Common.UIString.UIString('Received %s', new Date(installing.scriptResponseTime * 1000).toLocaleString());
Junyi Xiaod3e71a42019-04-23 04:49:04538 if (!this._targetForVersionId(installing.id) && (installing.isRunning() || installing.isStarting())) {
539 this._createLink(
Tim van der Lippe0efccf02020-02-12 15:15:39540 installingEntry, Common.UIString.UIString('inspect'), this._inspectButtonClicked.bind(this, installing.id));
Junyi Xiaod3e71a42019-04-23 04:49:04541 }
Blink Reformat4c46d092018-04-07 15:32:37542 }
543 return Promise.resolve();
544 }
545
546 /**
Junyi Xiaod3e71a42019-04-23 04:49:04547 * @param {!Element} parent
548 * @param {string} title
549 * @param {function()} listener
550 * @param {string=} className
551 * @param {boolean=} useCapture
552 * @return {!Element}
553 */
554 _createLink(parent, title, listener, className, useCapture) {
555 const button = parent.createChild('button', className);
556 button.classList.add('link');
557 button.textContent = title;
558 button.tabIndex = 0;
559 button.addEventListener('click', listener, useCapture);
560 return button;
561 }
562
563 /**
Tim van der Lippec02a97c2020-02-14 14:39:27564 * @param {!Common.EventTarget.EventTargetEvent} event
Blink Reformat4c46d092018-04-07 15:32:37565 */
566 _unregisterButtonClicked(event) {
567 this._manager.deleteRegistration(this._registration.id);
568 }
569
570 /**
Tim van der Lippec02a97c2020-02-14 14:39:27571 * @param {!Common.EventTarget.EventTargetEvent} event
Blink Reformat4c46d092018-04-07 15:32:37572 */
573 _updateButtonClicked(event) {
574 this._manager.updateRegistration(this._registration.id);
575 }
576
577 /**
578 * @param {string} data
579 */
580 _push(data) {
581 this._pushNotificationDataSetting.set(data);
582 this._manager.deliverPushMessage(this._registration.id, data);
583 }
584
585 /**
586 * @param {string} tag
587 */
588 _sync(tag) {
589 this._syncTagNameSetting.set(tag);
590 this._manager.dispatchSyncEvent(this._registration.id, tag, true);
591 }
592
593 /**
Mugdha Lakhanidb7c9b12019-08-09 13:48:04594 * @param {string} tag
595 */
596 _periodicSync(tag) {
597 this._periodicSyncTagNameSetting.set(tag);
598 this._manager.dispatchPeriodicSyncEvent(this._registration.id, tag);
599 }
600
601 /**
Blink Reformat4c46d092018-04-07 15:32:37602 * @param {!Element} element
603 * @param {?Protocol.Target.TargetInfo} targetInfo
604 */
605 _onClientInfo(element, targetInfo) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34606 if (!targetInfo) {
Blink Reformat4c46d092018-04-07 15:32:37607 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34608 }
Blink Reformat4c46d092018-04-07 15:32:37609 this._clientInfoCache.set(targetInfo.targetId, targetInfo);
610 this._updateClientInfo(element, targetInfo);
611 }
612
613 /**
614 * @param {!Element} element
615 * @param {!Protocol.Target.TargetInfo} targetInfo
616 */
617 _updateClientInfo(element, targetInfo) {
618 if (targetInfo.type !== 'page' && targetInfo.type === 'iframe') {
Harley Lia8a622f2018-11-01 23:58:09619 const clientString = element.createChild('span', 'service-worker-client-string');
Lorne Mitchell81a1a972019-03-06 18:13:13620 clientString.createTextChild(ls`Worker: ${targetInfo.url}`);
Blink Reformat4c46d092018-04-07 15:32:37621 return;
622 }
623 element.removeChildren();
Harley Lia8a622f2018-11-01 23:58:09624 const clientString = element.createChild('span', 'service-worker-client-string');
625 clientString.createTextChild(targetInfo.url);
Junyi Xiaod3e71a42019-04-23 04:49:04626 this._createLink(
627 element, ls`focus`, this._activateTarget.bind(this, targetInfo.targetId), 'service-worker-client-focus-link');
Blink Reformat4c46d092018-04-07 15:32:37628 }
629
630 /**
631 * @param {string} targetId
632 */
633 _activateTarget(targetId) {
634 this._manager.target().targetAgent().activateTarget(targetId);
635 }
636
637 _startButtonClicked() {
638 this._manager.startWorker(this._registration.scopeURL);
639 }
640
641 _skipButtonClicked() {
642 this._manager.skipWaiting(this._registration.scopeURL);
643 }
644
645 /**
646 * @param {string} versionId
647 */
648 _stopButtonClicked(versionId) {
649 this._manager.stopWorker(versionId);
650 }
651
652 /**
653 * @param {string} versionId
654 */
655 _inspectButtonClicked(versionId) {
656 this._manager.inspectWorker(versionId);
657 }
658
659 /**
660 * @param {!Element} container
661 * @return {!Element}
662 */
663 _wrapWidget(container) {
Tim van der Lippe0efccf02020-02-12 15:15:39664 const shadowRoot = UI.Utils.createShadowRootWithCoreStyles(container);
665 UI.Utils.appendStyle(shadowRoot, 'resources/serviceWorkersView.css');
Blink Reformat4c46d092018-04-07 15:32:37666 const contentElement = createElement('div');
667 shadowRoot.appendChild(contentElement);
668 return contentElement;
669 }
Tim van der Lippe097cdec2020-01-06 14:44:17670}