1 // Copyright 2014 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 cr.define('serviceworker', function() {
8 function initialize() {
13 chrome.send('GetOptions');
14 chrome.send('getAllRegistrations');
17 function onOptions(options) {
19 var container = $('serviceworker-options');
20 if (container.childNodes) {
21 template = container.childNodes[0];
24 template = jstGetTemplate('serviceworker-options-template');
25 container.appendChild(template);
27 jstProcess(new JsEvalContext(options), template);
28 var inputs = container.querySelectorAll('input[type=\'checkbox\']');
29 for (var i = 0; i < inputs.length; ++i) {
30 if (!inputs[i].hasClickEvent) {
31 inputs[i].addEventListener('click', (function(event) {
32 chrome.send('SetOption',
33 [event.target.className, event.target.checked]);
34 }).bind(this), false);
35 inputs[i].hasClickEvent = true;
40 function progressNodeFor(link) {
41 return link.parentNode.querySelector('.operation-status');
44 // All commands are completed with 'onOperationComplete'.
45 var COMMANDS = ['stop', 'sync', 'push', 'inspect', 'unregister', 'start'];
46 function commandHandler(command) {
47 return function(event) {
48 var link = event.target;
49 progressNodeFor(link).style.display = 'inline';
50 sendCommand(command, link.cmdArgs, (function(status) {
51 progressNodeFor(link).style.display = 'none';
57 var commandCallbacks = [];
58 function sendCommand(command, args, callback) {
60 while (callbackId in commandCallbacks) {
63 commandCallbacks[callbackId] = callback;
64 chrome.send(command, [callbackId, args]);
67 // Fired from the backend after the command call has completed.
68 function onOperationComplete(status, callbackId) {
69 var callback = commandCallbacks[callbackId];
70 delete commandCallbacks[callbackId];
77 var allLogMessages = {};
78 // Set log for a worker version.
79 function fillLogForVersion(container, partition_id, version) {
83 if (!(partition_id in allLogMessages)) {
84 allLogMessages[partition_id] = {};
86 var logMessages = allLogMessages[partition_id];
87 if (version.version_id in logMessages) {
88 version.log = logMessages[version.version_id];
92 var logAreas = container.querySelectorAll('textarea.serviceworker-log');
93 for (var i = 0; i < logAreas.length; ++i) {
94 var logArea = logAreas[i];
95 if (logArea.partition_id == partition_id &&
96 logArea.version_id == version.version_id) {
97 logArea.value = version.log;
102 // Get the unregistered workers.
103 // |unregistered_registrations| will be filled with the registrations which
104 // are in |live_registrations| but not in |stored_registrations|.
105 // |unregistered_versions| will be filled with the versions which
106 // are in |live_versions| but not in |stored_registrations| nor in
107 // |live_registrations|.
108 function getUnregisteredWorkers(stored_registrations,
111 unregistered_registrations,
112 unregistered_versions) {
113 var registration_id_set = {};
114 var version_id_set = {};
115 stored_registrations.forEach(function(registration) {
116 registration_id_set[registration.registration_id] = true;
118 [stored_registrations, live_registrations].forEach(function(registrations) {
119 registrations.forEach(function(registration) {
120 [registration.active, registration.waiting].forEach(function(version) {
122 version_id_set[version.version_id] = true;
127 live_registrations.forEach(function(registration) {
128 if (!registration_id_set[registration.registration_id]) {
129 registration.unregistered = true;
130 unregistered_registrations.push(registration);
133 live_versions.forEach(function(version) {
134 if (!version_id_set[version.version_id]) {
135 unregistered_versions.push(version);
140 // Fired once per partition from the backend.
141 function onPartitionData(live_registrations,
143 stored_registrations,
146 var unregistered_registrations = [];
147 var unregistered_versions = [];
148 getUnregisteredWorkers(stored_registrations,
151 unregistered_registrations,
152 unregistered_versions);
154 var container = $('serviceworker-list');
155 // Existing templates are keyed by partition_id. This allows
156 // the UI to be updated in-place rather than refreshing the
158 for (var i = 0; i < container.childNodes.length; ++i) {
159 if (container.childNodes[i].partition_id == partition_id) {
160 template = container.childNodes[i];
163 // This is probably the first time we're loading.
165 template = jstGetTemplate('serviceworker-list-template');
166 container.appendChild(template);
168 var fillLogFunc = fillLogForVersion.bind(this, container, partition_id);
169 stored_registrations.forEach(function(registration) {
170 [registration.active, registration.waiting].forEach(fillLogFunc);
172 unregistered_registrations.forEach(function(registration) {
173 [registration.active, registration.waiting].forEach(fillLogFunc);
175 unregistered_versions.forEach(fillLogFunc);
176 jstProcess(new JsEvalContext({
177 stored_registrations: stored_registrations,
178 unregistered_registrations: unregistered_registrations,
179 unregistered_versions: unregistered_versions,
180 partition_id: partition_id,
181 partition_path: partition_path}),
183 for (var i = 0; i < COMMANDS.length; ++i) {
184 var handler = commandHandler(COMMANDS[i]);
185 var links = container.querySelectorAll('button.' + COMMANDS[i]);
186 for (var j = 0; j < links.length; ++j) {
187 if (!links[j].hasClickEvent) {
188 links[j].addEventListener('click', handler, false);
189 links[j].hasClickEvent = true;
195 function onWorkerStarted(partition_id, version_id, process_id, thread_id) {
199 function onWorkerStopped(partition_id, version_id, process_id, thread_id) {
203 function onErrorReported(partition_id,
208 outputLogMessage(partition_id,
210 'Error: ' + JSON.stringify(error_info) + '\n');
213 function onConsoleMessageReported(partition_id,
218 outputLogMessage(partition_id,
220 'Console: ' + JSON.stringify(message) + '\n');
223 function onVersionStateChanged(partition_id, version_id) {
227 function onRegistrationStored(scope) {
231 function onRegistrationDeleted(scope) {
235 function outputLogMessage(partition_id, version_id, message) {
236 if (!(partition_id in allLogMessages)) {
237 allLogMessages[partition_id] = {};
239 var logMessages = allLogMessages[partition_id];
240 if (version_id in logMessages) {
241 logMessages[version_id] += message;
243 logMessages[version_id] = message;
246 var logAreas = document.querySelectorAll('textarea.serviceworker-log');
247 for (var i = 0; i < logAreas.length; ++i) {
248 var logArea = logAreas[i];
249 if (logArea.partition_id == partition_id &&
250 logArea.version_id == version_id) {
251 logArea.value += message;
257 initialize: initialize,
258 onOptions: onOptions,
259 onOperationComplete: onOperationComplete,
260 onPartitionData: onPartitionData,
261 onWorkerStarted: onWorkerStarted,
262 onWorkerStopped: onWorkerStopped,
263 onErrorReported: onErrorReported,
264 onConsoleMessageReported: onConsoleMessageReported,
265 onVersionStateChanged: onVersionStateChanged,
266 onRegistrationStored: onRegistrationStored,
267 onRegistrationDeleted: onRegistrationDeleted,
271 document.addEventListener('DOMContentLoaded', serviceworker.initialize);