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', '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 onRunningStateChanged(partition_id, version_id) {
199 function onErrorReported(partition_id,
204 outputLogMessage(partition_id,
206 'Error: ' + JSON.stringify(error_info) + '\n');
209 function onConsoleMessageReported(partition_id,
214 outputLogMessage(partition_id,
216 'Console: ' + JSON.stringify(message) + '\n');
219 function onVersionStateChanged(partition_id, version_id) {
223 function onRegistrationStored(scope) {
227 function onRegistrationDeleted(scope) {
231 function outputLogMessage(partition_id, version_id, message) {
232 if (!(partition_id in allLogMessages)) {
233 allLogMessages[partition_id] = {};
235 var logMessages = allLogMessages[partition_id];
236 if (version_id in logMessages) {
237 logMessages[version_id] += message;
239 logMessages[version_id] = message;
242 var logAreas = document.querySelectorAll('textarea.serviceworker-log');
243 for (var i = 0; i < logAreas.length; ++i) {
244 var logArea = logAreas[i];
245 if (logArea.partition_id == partition_id &&
246 logArea.version_id == version_id) {
247 logArea.value += message;
253 initialize: initialize,
254 onOptions: onOptions,
255 onOperationComplete: onOperationComplete,
256 onPartitionData: onPartitionData,
257 onRunningStateChanged: onRunningStateChanged,
258 onErrorReported: onErrorReported,
259 onConsoleMessageReported: onConsoleMessageReported,
260 onVersionStateChanged: onVersionStateChanged,
261 onRegistrationStored: onRegistrationStored,
262 onRegistrationDeleted: onRegistrationDeleted,
266 document.addEventListener('DOMContentLoaded', serviceworker.initialize);