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 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
);