Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / content / browser / resources / service_worker / serviceworker_internals.js
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.
4
5 cr.define('serviceworker', function() {
6   'use strict';
7
8   function initialize() {
9     update();
10   }
11
12   function update() {
13       chrome.send('GetOptions');
14       chrome.send('getAllRegistrations');
15   }
16
17   function onOptions(options) {
18     var template;
19     var container = $('serviceworker-options');
20     if (container.childNodes) {
21       template = container.childNodes[0];
22     }
23     if (!template) {
24       template = jstGetTemplate('serviceworker-options-template');
25       container.appendChild(template);
26     }
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;
36       }
37     }
38   }
39
40   function progressNodeFor(link) {
41     return link.parentNode.querySelector('.operation-status');
42   }
43
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';
52       }).bind(null, link));
53       return false;
54     };
55   };
56
57   var commandCallbacks = [];
58   function sendCommand(command, args, callback) {
59     var callbackId = 0;
60     while (callbackId in commandCallbacks) {
61       callbackId++;
62     }
63     commandCallbacks[callbackId] = callback;
64     chrome.send(command, [callbackId, args]);
65   }
66
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];
71     if (callback) {
72       callback(status);
73     }
74     update();
75   }
76
77   var allLogMessages = {};
78   // Set log for a worker version.
79   function fillLogForVersion(container, partition_id, version) {
80     if (!version) {
81       return;
82     }
83     if (!(partition_id in allLogMessages)) {
84       allLogMessages[partition_id] = {};
85     }
86     var logMessages = allLogMessages[partition_id];
87     if (version.version_id in logMessages) {
88       version.log = logMessages[version.version_id];
89     } else {
90       version.log = '';
91     }
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;
98       }
99     }
100   }
101
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,
109                                   live_registrations,
110                                   live_versions,
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;
117     });
118     [stored_registrations, live_registrations].forEach(function(registrations) {
119       registrations.forEach(function(registration) {
120         [registration.active, registration.waiting].forEach(function(version) {
121           if (version) {
122             version_id_set[version.version_id] = true;
123           }
124         });
125       });
126     });
127     live_registrations.forEach(function(registration) {
128       if (!registration_id_set[registration.registration_id]) {
129         registration.unregistered = true;
130         unregistered_registrations.push(registration);
131       }
132     });
133     live_versions.forEach(function(version) {
134       if (!version_id_set[version.version_id]) {
135         unregistered_versions.push(version);
136       }
137     });
138   }
139
140   // Fired once per partition from the backend.
141   function onPartitionData(live_registrations,
142                            live_versions,
143                            stored_registrations,
144                            partition_id,
145                            partition_path) {
146     var unregistered_registrations = [];
147     var unregistered_versions = [];
148     getUnregisteredWorkers(stored_registrations,
149                            live_registrations,
150                            live_versions,
151                            unregistered_registrations,
152                            unregistered_versions);
153     var template;
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
157     // whole page.
158     for (var i = 0; i < container.childNodes.length; ++i) {
159       if (container.childNodes[i].partition_id == partition_id) {
160         template = container.childNodes[i];
161       }
162     }
163     // This is probably the first time we're loading.
164     if (!template) {
165       template = jstGetTemplate('serviceworker-list-template');
166       container.appendChild(template);
167     }
168     var fillLogFunc = fillLogForVersion.bind(this, container, partition_id);
169     stored_registrations.forEach(function(registration) {
170       [registration.active, registration.waiting].forEach(fillLogFunc);
171     });
172     unregistered_registrations.forEach(function(registration) {
173       [registration.active, registration.waiting].forEach(fillLogFunc);
174     });
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}),
182                template);
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;
190         }
191       }
192     }
193   }
194
195   function onWorkerStarted(partition_id, version_id, process_id, thread_id) {
196     update();
197   }
198
199   function onWorkerStopped(partition_id, version_id, process_id, thread_id) {
200     update();
201   }
202
203   function onErrorReported(partition_id,
204                            version_id,
205                            process_id,
206                            thread_id,
207                            error_info) {
208     outputLogMessage(partition_id,
209                      version_id,
210                      'Error: ' + JSON.stringify(error_info) + '\n');
211   }
212
213   function onConsoleMessageReported(partition_id,
214                                     version_id,
215                                     process_id,
216                                     thread_id,
217                                     message) {
218     outputLogMessage(partition_id,
219                      version_id,
220                      'Console: ' + JSON.stringify(message) + '\n');
221   }
222
223   function onVersionStateChanged(partition_id, version_id) {
224     update();
225   }
226
227   function onRegistrationStored(scope) {
228     update();
229   }
230
231   function onRegistrationDeleted(scope) {
232     update();
233   }
234
235   function outputLogMessage(partition_id, version_id, message) {
236     if (!(partition_id in allLogMessages)) {
237       allLogMessages[partition_id] = {};
238     }
239     var logMessages = allLogMessages[partition_id];
240     if (version_id in logMessages) {
241       logMessages[version_id] += message;
242     } else {
243       logMessages[version_id] = message;
244     }
245
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;
252       }
253     }
254   }
255
256   return {
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,
268   };
269 });
270
271 document.addEventListener('DOMContentLoaded', serviceworker.initialize);