Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / devtools / front_end / resources / ServiceWorkersView.js
blobfb79cba4a45b30b00794b462f65e39992d04b290
1 // 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.
5 /**
6 * @constructor
7 * @extends {WebInspector.VBox}
8 * @implements {WebInspector.TargetManager.Observer}
9 */
10 WebInspector.ServiceWorkersView = function()
12 WebInspector.VBox.call(this, true);
13 this.registerRequiredCSS("resources/serviceWorkersView.css");
14 this.contentElement.classList.add("service-workers-view");
16 /** @type {!Set.<string>} */
17 this._securityOriginHosts = new Set();
18 /** @type {!Map.<string, !WebInspector.ServiceWorkerOriginElement>} */
19 this._originHostToOriginElementMap = new Map();
20 /** @type {!Map.<string, !WebInspector.ServiceWorkerOriginElement>} */
21 this._registrationIdToOriginElementMap = new Map();
23 var settingsDiv = createElementWithClass("div", "service-workers-settings");
24 var debugOnStartCheckboxLabel = createCheckboxLabel(WebInspector.UIString("Open DevTools window and pause JavaScript execution on Service Worker startup for debugging."));
25 this._debugOnStartCheckbox = debugOnStartCheckboxLabel.checkboxElement;
26 this._debugOnStartCheckbox.addEventListener("change", this._debugOnStartCheckboxChanged.bind(this), false)
27 this._debugOnStartCheckbox.disabled = true
28 settingsDiv.appendChild(debugOnStartCheckboxLabel);
29 this.contentElement.appendChild(settingsDiv);
31 this._root = this.contentElement.createChild("ol");
32 this._root.classList.add("service-workers-root");
34 WebInspector.targetManager.observeTargets(this);
37 WebInspector.ServiceWorkersView.prototype = {
38 /**
39 * @override
40 * @param {!WebInspector.Target} target
42 targetAdded: function(target)
44 if (this._target)
45 return;
46 this._target = target;
47 this._manager = this._target.serviceWorkerManager;
49 this._debugOnStartCheckbox.disabled = false;
50 this._debugOnStartCheckbox.checked = this._manager.debugOnStart();
52 for (var registration of this._manager.registrations().values())
53 this._updateRegistration(registration);
55 this._manager.addEventListener(WebInspector.ServiceWorkerManager.Events.RegistrationUpdated, this._registrationUpdated, this);
56 this._manager.addEventListener(WebInspector.ServiceWorkerManager.Events.RegistrationDeleted, this._registrationDeleted, this);
57 this._manager.addEventListener(WebInspector.ServiceWorkerManager.Events.DebugOnStartUpdated, this._debugOnStartUpdated, this);
58 this._target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginAdded, this._securityOriginAdded, this);
59 this._target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginRemoved, this._securityOriginRemoved, this);
60 var securityOrigins = this._target.resourceTreeModel.securityOrigins();
61 for (var i = 0; i < securityOrigins.length; ++i)
62 this._addOrigin(securityOrigins[i]);
65 /**
66 * @override
67 * @param {!WebInspector.Target} target
69 targetRemoved: function(target)
71 if (target !== this._target)
72 return;
73 delete this._target;
76 /**
77 * @param {!WebInspector.Event} event
79 _registrationUpdated: function(event)
81 var registration = /** @type {!WebInspector.ServiceWorkerRegistration} */ (event.data);
82 this._updateRegistration(registration);
85 /**
86 * @param {!WebInspector.ServiceWorkerRegistration} registration
88 _updateRegistration: function(registration)
90 var parsedURL = registration.scopeURL.asParsedURL();
91 if (!parsedURL)
92 return;
93 var originHost = parsedURL.host;
94 var originElement = this._originHostToOriginElementMap.get(originHost);
95 if (!originElement) {
96 originElement = new WebInspector.ServiceWorkerOriginElement(this._manager, originHost);
97 if (this._securityOriginHosts.has(originHost))
98 this._appendOriginNode(originElement);
99 this._originHostToOriginElementMap.set(originHost, originElement);
101 this._registrationIdToOriginElementMap.set(registration.id, originElement);
102 originElement._updateRegistration(registration);
106 * @param {!WebInspector.Event} event
108 _registrationDeleted: function(event)
110 var registration = /** @type {!WebInspector.ServiceWorkerRegistration} */ (event.data);
111 var registrationId = registration.id;
112 var originElement = this._registrationIdToOriginElementMap.get(registrationId);
113 if (!originElement)
114 return;
115 this._registrationIdToOriginElementMap.delete(registrationId);
116 originElement._deleteRegistration(registrationId);
117 if (originElement._hasRegistration())
118 return;
119 if (this._securityOriginHosts.has(originElement._originHost))
120 this._removeOriginNode(originElement);
121 this._originHostToOriginElementMap.delete(originElement._originHost);
125 * @param {!WebInspector.Event} event
127 _debugOnStartUpdated: function(event)
129 var debugOnStart = /** @type {boolean} */ (event.data);
130 this._debugOnStartCheckbox.checked = debugOnStart;
134 * @param {!WebInspector.Event} event
136 _securityOriginAdded: function(event)
138 this._addOrigin(/** @type {string} */ (event.data));
142 * @param {string} securityOrigin
144 _addOrigin: function(securityOrigin)
146 var parsedURL = securityOrigin.asParsedURL();
147 if (!parsedURL)
148 return;
149 var originHost = parsedURL.host;
150 if (this._securityOriginHosts.has(originHost))
151 return;
152 this._securityOriginHosts.add(originHost);
153 var originElement = this._originHostToOriginElementMap.get(originHost);
154 if (!originElement)
155 return;
156 this._appendOriginNode(originElement);
160 * @param {!WebInspector.Event} event
162 _securityOriginRemoved: function(event)
164 var securityOrigin = /** @type {string} */ (event.data);
165 var parsedURL = securityOrigin.asParsedURL();
166 if (!parsedURL)
167 return;
168 var originHost = parsedURL.host;
169 if (!this._securityOriginHosts.has(originHost))
170 return;
171 this._securityOriginHosts.delete(originHost);
172 var originElement = this._originHostToOriginElementMap.get(originHost);
173 if (!originElement)
174 return;
175 this._removeOriginNode(originElement);
179 * @param {!WebInspector.ServiceWorkerOriginElement} originElement
181 _appendOriginNode: function(originElement)
183 this._root.appendChild(originElement._element);
187 * @param {!WebInspector.ServiceWorkerOriginElement} originElement
189 _removeOriginNode: function(originElement)
191 this._root.removeChild(originElement._element);
194 _debugOnStartCheckboxChanged: function()
196 if (!this._manager)
197 return;
198 this._manager.setDebugOnStart(this._debugOnStartCheckbox.checked);
199 this._debugOnStartCheckbox.checked = this._manager.debugOnStart();
202 __proto__: WebInspector.VBox.prototype
206 * @constructor
207 * @param {!WebInspector.ServiceWorkerManager} manager
208 * @param {string} originHost
210 WebInspector.ServiceWorkerOriginElement = function(manager, originHost)
212 this._manager = manager;
213 /** @type {!Map.<string, !WebInspector.SWRegistrationElement>} */
214 this._registrationElements = new Map();
215 this._originHost = originHost;
216 this._element = createElementWithClass("div", "service-workers-origin");
217 this._listItemNode = this._element.createChild("li", "service-workers-origin-title");
218 this._listItemNode.createChild("div").createTextChild(originHost);
219 this._childrenListNode = this._element.createChild("ol");
222 WebInspector.ServiceWorkerOriginElement.prototype = {
224 * @return {boolean}
226 _hasRegistration: function()
228 return this._registrationElements.size != 0;
232 * @param {!WebInspector.ServiceWorkerRegistration} registration
234 _updateRegistration: function(registration)
236 var swRegistrationElement = this._registrationElements.get(registration.id);
237 if (swRegistrationElement) {
238 swRegistrationElement._updateRegistration(registration);
239 return;
241 swRegistrationElement = new WebInspector.SWRegistrationElement(this._manager, this, registration);
242 this._registrationElements.set(registration.id, swRegistrationElement);
243 this._childrenListNode.appendChild(swRegistrationElement._element);
247 * @param {string} registrationId
249 _deleteRegistration: function(registrationId)
251 var swRegistrationElement = this._registrationElements.get(registrationId);
252 if (!swRegistrationElement)
253 return;
254 this._registrationElements.delete(registrationId);
255 this._childrenListNode.removeChild(swRegistrationElement._element);
259 * @return {boolean}
261 _visible: function()
263 return !!this._element.parentElement;
268 * @constructor
269 * @param {!WebInspector.ServiceWorkerManager} manager
270 * @param {!WebInspector.ServiceWorkerOriginElement} originElement
271 * @param {!WebInspector.ServiceWorkerRegistration} registration
273 WebInspector.SWRegistrationElement = function(manager, originElement, registration)
275 this._manager = manager;
276 this._originElement = originElement;
277 this._registration = registration;
278 this._element = createElementWithClass("div", "service-workers-registration");
279 var headerNode = this._element.createChild("div", "service-workers-registration-header");
280 this._titleNode = headerNode.createChild("div", "service-workers-registration-title");
281 var buttonsNode = headerNode.createChild("div", "service-workers-registration-buttons");
282 this._updateButton = buttonsNode.createChild("button", "service-workers-button service-workers-update-button");
283 this._updateButton.addEventListener("click", this._updateButtonClicked.bind(this), false);
284 this._updateButton.title = WebInspector.UIString("Update");
285 this._updateButton.disabled = true
286 this._pushButton = buttonsNode.createChild("button", "service-workers-button service-workers-push-button");
287 this._pushButton.addEventListener("click", this._pushButtonClicked.bind(this), false);
288 this._pushButton.title = WebInspector.UIString("Emulate push event");
289 this._pushButton.disabled = true
290 this._deleteButton = buttonsNode.createChild("button", "service-workers-button service-workers-delete-button");
291 this._deleteButton.addEventListener("click", this._deleteButtonClicked.bind(this), false);
292 this._deleteButton.title = WebInspector.UIString("Delete");
293 this._childrenListNode = this._element.createChild("div", "service-workers-registration-content");
295 this._skipWaitingCheckboxLabel = createCheckboxLabel(WebInspector.UIString("Skip waiting"));
296 this._skipWaitingCheckboxLabel.title = WebInspector.UIString("Simulate skipWaiting()");
297 this._skipWaitingCheckboxLabel.classList.add("service-workers-skip-waiting-checkbox-label");
298 this._skipWaitingCheckbox = this._skipWaitingCheckboxLabel.checkboxElement;
299 this._skipWaitingCheckbox.classList.add("service-workers-skip-waiting-checkbox");
300 this._skipWaitingCheckbox.addEventListener("change", this._skipWaitingCheckboxChanged.bind(this), false);
303 * @type {!Object.<string, !Array.<!WebInspector.ServiceWorkerVersion>>}
305 this._categorizedVersions = {};
306 for (var mode in WebInspector.ServiceWorkerVersion.Modes)
307 this._categorizedVersions[WebInspector.ServiceWorkerVersion.Modes[mode]] = [];
309 this._selectedMode = WebInspector.ServiceWorkerVersion.Modes.Active;
312 * @type {!Array.<!WebInspector.SWVersionElement>}
314 this._versionElements = [];
316 this._updateRegistration(registration);
319 WebInspector.SWRegistrationElement.prototype = {
321 * @param {!WebInspector.ServiceWorkerRegistration} registration
323 _updateRegistration: function(registration)
325 this._registration = registration;
326 this._titleNode.textContent = WebInspector.UIString(registration.isDeleted ? "Scope: %s - deleted" : "Scope: %s", registration.scopeURL.asParsedURL().path);
327 this._updateButton.disabled = !!registration.isDeleted;
328 this._deleteButton.disabled = !!registration.isDeleted;
329 this._skipWaitingCheckboxLabel.remove();
331 var lastFocusedVersionId = undefined;
332 if (this._categorizedVersions[this._selectedMode].length)
333 lastFocusedVersionId = this._categorizedVersions[this._selectedMode][0].id;
334 for (var mode in WebInspector.ServiceWorkerVersion.Modes)
335 this._categorizedVersions[WebInspector.ServiceWorkerVersion.Modes[mode]] = [];
336 for (var version of registration.versions.valuesArray()) {
337 if (version.isStoppedAndRedundant() && !version.errorMessages.length)
338 continue;
339 var mode = version.mode();
340 this._categorizedVersions[mode].push(version);
341 if (version.id === lastFocusedVersionId)
342 this._selectedMode = mode;
344 if (!this._categorizedVersions[this._selectedMode].length && this._selectedMode != WebInspector.ServiceWorkerVersion.Modes.Waiting) {
345 for (var mode of [WebInspector.ServiceWorkerVersion.Modes.Active,
346 WebInspector.ServiceWorkerVersion.Modes.Waiting,
347 WebInspector.ServiceWorkerVersion.Modes.Installing,
348 WebInspector.ServiceWorkerVersion.Modes.Redundant]) {
349 if (this._categorizedVersions[mode].length) {
350 this._selectedMode = mode;
351 break;
355 this._pushButton.disabled = !this._categorizedVersions[WebInspector.ServiceWorkerVersion.Modes.Active].length || !!this._registration.isDeleted;
357 this._updateVersionList();
359 if (this._visible() && this._skipWaitingCheckbox.checked) {
360 this._registration.versions.valuesArray().map(callSkipWaitingForInstalledVersions.bind(this));
364 * @this {WebInspector.SWRegistrationElement}
365 * @param {!WebInspector.ServiceWorkerVersion} version
367 function callSkipWaitingForInstalledVersions(version)
369 if (version.isInstalled())
370 this._manager.skipWaiting(version.id);
374 _updateVersionList: function()
376 var fragment = createDocumentFragment();
377 var modeTabList = createElementWithClass("div", "service-workers-versions-mode-tab-list");
378 modeTabList.appendChild(this._createVersionModeTab(WebInspector.ServiceWorkerVersion.Modes.Installing));
379 modeTabList.appendChild(this._createVersionModeTab(WebInspector.ServiceWorkerVersion.Modes.Waiting));
380 modeTabList.appendChild(this._createVersionModeTab(WebInspector.ServiceWorkerVersion.Modes.Active));
381 modeTabList.appendChild(this._createVersionModeTab(WebInspector.ServiceWorkerVersion.Modes.Redundant));
382 fragment.appendChild(modeTabList);
383 fragment.appendChild(this._createSelectedModeVersionsPanel(this._selectedMode));
384 this._childrenListNode.removeChildren();
385 this._childrenListNode.appendChild(fragment);
389 * @param {string} mode
390 * @return {!Element}
392 _createVersionModeTab: function(mode)
394 var versions = this._categorizedVersions[mode];
395 var modeTitle = WebInspector.UIString(mode);
396 var selected = this._selectedMode == mode;
397 var modeTab = createElementWithClass("div", "service-workers-versions-mode-tab");
398 for (var version of versions) {
399 var icon = modeTab.createChild("div", "service-workers-versions-mode-tab-icon service-workers-color-" + (version.id % 10));
400 icon.title = WebInspector.UIString("ID: %s", version.id);
402 var modeTabText = modeTab.createChild("div", "service-workers-versions-mode-tab-text");
403 modeTabText.createTextChild(WebInspector.UIString(modeTitle));
404 if (selected) {
405 modeTab.classList.add("service-workers-versions-mode-tab-selected");
406 modeTabText.classList.add("service-workers-versions-mode-tab-text-selected");
408 if (versions.length || mode == WebInspector.ServiceWorkerVersion.Modes.Waiting) {
409 modeTab.addEventListener("click", this._modeTabClicked.bind(this, mode), false);
410 } else {
411 modeTab.classList.add("service-workers-versions-mode-tab-disabled");
412 modeTabText.classList.add("service-workers-versions-mode-tab-text-disabled");
414 return modeTab;
418 * @param {string} mode
419 * @return {!Element}
421 _createSelectedModeVersionsPanel: function(mode)
423 var versions = this._categorizedVersions[mode];
424 var panelContainer = createElementWithClass("div", "service-workers-versions-panel-container");
425 if (mode == WebInspector.ServiceWorkerVersion.Modes.Waiting) {
426 var panel = createElementWithClass("div", "service-workers-versions-option-panel");
427 panel.appendChild(this._skipWaitingCheckboxLabel);
428 panelContainer.appendChild(panel);
430 var index = 0;
431 var versionElement;
432 for (var i = 0; i < versions.length; ++i) {
433 if (i < this._versionElements.length) {
434 versionElement = this._versionElements[i];
435 versionElement._updateVersion(versions[i]);
436 } else {
437 versionElement = new WebInspector.SWVersionElement(this._manager, this._registration.scopeURL, versions[i]);
438 this._versionElements.push(versionElement);
440 panelContainer.appendChild(versionElement._element);
442 this._versionElements.splice(versions.length);
443 return panelContainer;
447 * @param {string} mode
449 _modeTabClicked: function(mode)
451 if (this._selectedMode == mode)
452 return;
453 this._selectedMode = mode;
454 this._updateVersionList();
458 * @param {!Event} event
460 _deleteButtonClicked: function(event)
462 this._manager.deleteRegistration(this._registration.id);
466 * @param {!Event} event
468 _updateButtonClicked: function(event)
470 this._manager.updateRegistration(this._registration.id);
474 * @param {!Event} event
476 _pushButtonClicked: function(event)
478 var data = "Test push message from DevTools."
479 this._manager.deliverPushMessage(this._registration.id, data);
482 _skipWaitingCheckboxChanged: function()
484 if (!this._skipWaitingCheckbox.checked)
485 return;
486 this._registration.versions.valuesArray().map(callSkipWaitingForInstalledVersions.bind(this));
489 * @this {WebInspector.SWRegistrationElement}
490 * @param {!WebInspector.ServiceWorkerVersion} version
492 function callSkipWaitingForInstalledVersions(version)
494 if (version.isInstalled())
495 this._manager.skipWaiting(version.id);
500 * @return {boolean}
502 _visible: function()
504 return this._originElement._visible();
509 * @constructor
510 * @param {!WebInspector.ServiceWorkerManager} manager
511 * @param {string} scopeURL
512 * @param {!WebInspector.ServiceWorkerVersion} version
514 WebInspector.SWVersionElement = function(manager, scopeURL, version)
516 this._manager = manager;
517 this._scopeURL = scopeURL;
518 this._version = version;
519 this._element = createElementWithClass("div", "service-workers-version");
522 * @type {!Object.<string, !WebInspector.TargetInfo>}
524 this._clientInfoCache = {};
525 this._createElements();
526 this._updateVersion(version);
529 WebInspector.SWVersionElement.prototype = {
530 _createElements: function()
532 var panel = createElementWithClass("div", "service-workers-versions-panel");
533 var leftPanel = panel.createChild("div", "service-workers-versions-panel-left");
534 var rightPanel = panel.createChild("div", "service-workers-versions-panel-right");
535 this._stateCell = this._addTableRow(leftPanel, WebInspector.UIString("State"));
536 this._workerCell = this._addTableRow(leftPanel, WebInspector.UIString("Worker"));
537 this._scriptCell = this._addTableRow(leftPanel, WebInspector.UIString("Script URL"));
538 this._updatedCell = this._addTableRow(leftPanel, WebInspector.UIString("Updated"));
539 this._updatedCell.classList.add("service-worker-script-response-time");
540 this._scriptLastModifiedCell = this._addTableRow(leftPanel, WebInspector.UIString("Last-Modified"));
541 this._scriptLastModifiedCell.classList.add("service-worker-script-last-modified");
542 rightPanel.createChild("div", "service-workers-versions-table-messages-title").createTextChild(WebInspector.UIString("Recent messages"));
543 this._messagesPanel = rightPanel.createChild("div", "service-workers-versions-table-messages-content");
544 this._clientsTitle = rightPanel.createChild("div", "service-workers-versions-table-clients-title");
545 this._clientsTitle.createTextChild(WebInspector.UIString("Controlled clients"));
546 this._clientsPanel = rightPanel.createChild("div", "service-workers-versions-table-clients-content");
547 this._element.appendChild(panel);
551 * @param {!WebInspector.ServiceWorkerVersion} version
553 _updateVersion: function(version)
555 this._stateCell.removeChildren();
556 this._stateCell.createTextChild(version.status);
558 this._workerCell.removeChildren();
559 if (version.isRunning() || version.isStarting() || version.isStartable()) {
560 var runningStatusCell = this._workerCell.createChild("div", "service-workers-versions-table-worker-running-status-cell");
561 var runningStatusLeftCell = runningStatusCell.createChild("div", "service-workers-versions-table-running-status-left-cell");
562 var runningStatusRightCell = runningStatusCell.createChild("div", "service-workers-versions-table-running-status-right-cell");
563 if (version.isRunning() || version.isStarting()) {
564 var stopButton = runningStatusLeftCell.createChild("button", "service-workers-button service-workers-stop-button");
565 stopButton.addEventListener("click", this._stopButtonClicked.bind(this, version.id), false);
566 stopButton.title = WebInspector.UIString("Stop");
567 } else if (version.isStartable()) {
568 var startButton = runningStatusLeftCell.createChild("button", "service-workers-button service-workers-start-button");
569 startButton.addEventListener("click", this._startButtonClicked.bind(this), false);
570 startButton.title = WebInspector.UIString("Start");
572 runningStatusRightCell.createTextChild(version.runningStatus);
573 if (version.isRunning() || version.isStarting()) {
574 var inspectButton = runningStatusRightCell.createChild("div", "service-workers-versions-table-running-status-inspect");
575 inspectButton.createTextChild(WebInspector.UIString("inspect"));
576 inspectButton.addEventListener("click", this._inspectButtonClicked.bind(this, version.id), false);
578 } else {
579 this._workerCell.createTextChild(version.runningStatus);
582 this._scriptCell.removeChildren();
583 this._scriptCell.createTextChild(version.scriptURL.asParsedURL().path);
585 this._updatedCell.removeChildren();
586 if (version.scriptResponseTime)
587 this._updatedCell.createTextChild((new Date(version.scriptResponseTime * 1000)).toConsoleTime());
588 this._scriptLastModifiedCell.removeChildren();
589 if (version.scriptLastModified)
590 this._scriptLastModifiedCell.createTextChild((new Date(version.scriptLastModified * 1000)).toConsoleTime());
592 this._messagesPanel.removeChildren();
593 if (version.scriptLastModified) {
594 var scriptLastModifiedLabel = this._messagesPanel.createChild("label", " service-workers-info service-worker-script-last-modified", "dt-icon-label");
595 scriptLastModifiedLabel.type = "info-icon";
596 scriptLastModifiedLabel.createTextChild(WebInspector.UIString("Last-Modified: %s", (new Date(version.scriptLastModified * 1000)).toConsoleTime()));
598 if (version.scriptResponseTime) {
599 var scriptResponseTimeDiv = this._messagesPanel.createChild("label", " service-workers-info service-worker-script-response-time", "dt-icon-label");
600 scriptResponseTimeDiv.type = "info-icon";
601 scriptResponseTimeDiv.createTextChild(WebInspector.UIString("Server response time: %s", (new Date(version.scriptResponseTime * 1000)).toConsoleTime()));
604 var errorMessages = version.errorMessages;
605 for (var index = 0; index < errorMessages.length; ++index) {
606 var errorDiv = this._messagesPanel.createChild("div", "service-workers-error");
607 errorDiv.createChild("label", "", "dt-icon-label").type = "error-icon";
608 errorDiv.createChild("div", "service-workers-error-message").createTextChild(errorMessages[index].errorMessage);
609 var script_path = errorMessages[index].sourceURL;
610 var script_url;
611 if (script_url = script_path.asParsedURL())
612 script_path = script_url.displayName;
613 if (script_path.length && errorMessages[index].lineNumber != -1)
614 script_path = String.sprintf("(%s:%d)", script_path, errorMessages[index].lineNumber);
615 errorDiv.createChild("div", "service-workers-error-line").createTextChild(script_path);
618 this._clientsTitle.classList.toggle("hidden", version.controlledClients.length == 0);
620 this._clientsPanel.removeChildren();
621 for (var i = 0; i < version.controlledClients.length; ++i) {
622 var client = version.controlledClients[i];
623 var clientLabelText = this._clientsPanel.createChild("div", "service-worker-client");
624 if (this._clientInfoCache[client]) {
625 this._updateClientInfo(clientLabelText, this._clientInfoCache[client]);
627 this._manager.getTargetInfo(client, this._onClientInfo.bind(this, clientLabelText));
632 * @param {!Element} tableElement
633 * @param {string} title
634 * @return {!Element}
636 _addTableRow: function(tableElement, title)
638 var rowElement = tableElement.createChild("div", "service-workers-versions-table-row");
639 rowElement.createChild("div", "service-workers-versions-table-row-title").createTextChild(title);
640 return rowElement.createChild("div", "service-workers-versions-table-row-content");
644 * @param {!Element} element
645 * @param {?WebInspector.TargetInfo} targetInfo
647 _onClientInfo: function(element, targetInfo)
649 if (!targetInfo)
650 return;
651 this._clientInfoCache[targetInfo.id] = targetInfo;
652 this._updateClientInfo(element, targetInfo);
656 * @param {!Element} element
657 * @param {!WebInspector.TargetInfo} targetInfo
659 _updateClientInfo: function(element, targetInfo)
661 if (!(targetInfo.isWebContents() || targetInfo.isFrame())) {
662 element.createTextChild(WebInspector.UIString("Worker: %s", targetInfo.url));
663 return;
665 element.removeChildren();
666 element.createTextChild(WebInspector.UIString("Tab: %s", targetInfo.url));
667 var focusLabel = element.createChild("label", "service-worker-client-focus");
668 focusLabel.createTextChild("focus");
669 focusLabel.addEventListener("click", this._activateTarget.bind(this, targetInfo.id), true);
673 * @param {string} targetId
675 _activateTarget: function(targetId)
677 this._manager.activateTarget(targetId);
681 * @param {!Event} event
683 _startButtonClicked: function(event)
685 this._manager.startWorker(this._scopeURL);
689 * @param {string} versionId
690 * @param {!Event} event
692 _stopButtonClicked: function(versionId, event)
694 this._manager.stopWorker(versionId);
698 * @param {string} versionId
699 * @param {!Event} event
701 _inspectButtonClicked: function(versionId, event)
703 this._manager.inspectWorker(versionId);