Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(753)

Side by Side Diff: chrome/browser/resources/quota_internals/event_handler.js

Issue 7053009: Add chrome://quota-internals/ resources (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Add comment, merge test.html to index.html. Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 // require cr.js
6 // require cr/event_target.js
7 // require cr/ui.js
8 // require cr/ui/tabs.js
9 // require cr/ui/tree.js
10 // require cr/util.js
11
12 (function() {
13 'use strict';
14
15 /**
16 * Return true if |obj| is {}.
17 * @param {Object} obj Object to be checked.
18 */
19 function isEmptyObject(obj) {
20 for (var i in obj)
21 return false;
22 return true;
23 }
24
25 /**
26 * Copy properties from |src| to |dest|.
27 * @param {Object} src Source of the copy.
28 * @param {Object} dest Destination of the copy.
29 * @return {Object} |dest|.
30 */
31 var overwrite_ = function(src, dest) {
32 for (var i in src)
33 dest[i] = src[i];
34 return dest;
35 };
36
37 /**
38 * Apply localization to |element| with i18n_template.js if available.
39 * @param {Element} element Element to be localized.
40 */
41 var localize_ = function(element) {
42 if (window.i18nTemplate && cr.quota.localizedStrings)
43 i18nTemplate.process(element, cr.quota.localizedStrings);
44 };
45
46 var normalizer_ = {
47 /**
48 * Returns 'N/A' (Not Available) text if |v| is undefined.
49 * @param {Object} v Object to print.
50 * @return {string} 'N/A' or ''.
51 */
52 avail_: function(v) {
53 return v === undefined ?
54 '<span i18n-content="text-not_available">N/A</span>' : '';
55 },
56
57 /**
58 * Returns 'true', 'false' or 'N/A' for boolean |v|.
59 * @param {?boolean} v Boolean to print.
60 * @return {string} 'N/A', 'true' or 'false'.
61 */
62 bool: function(v) {
63 return normalizer_.avail_(v) ||
64 (v ? '<span i18n-content="text-true">true</span>' :
65 '<span i18n-content="text-false">false</span>');
66 },
67
68 /**
69 * Returns |v| itself unless |v| is not undefined,
70 * else returns 'N/A' text.
71 * @param {?string} v String to print.
72 * @return {string} 'N/A' or |v|.
73 */
74 text: function(v) {
75 return normalizer_.avail_(v) || v;
76 },
77
78 /**
79 * Returns formatted string from toString'ed integer.
80 * e.g. numBytes(123456789) = "123.45 MB (123,456,789 B)"
81 * If |v| is undefined, this function returns "N/A".
82 * @param {?string} v Digits to print.
83 * @return {string} 'N/A' or formatted |v|.
84 */
85 numBytes: function(v) {
86 return normalizer_.avail_(v) || (function() {
87 var result = ' B';
88 var prefix_index = 0;
89 while (v.length > 3) {
90 result = ',' + v.slice(-3) + result;
91 v = v.slice(0, -3);
92 ++prefix_index;
93 }
94
95 if (prefix_index > 0) {
96 var p = result.slice(1, 3);
97 result = v + result;
98
99 var PREFIX = [' ', ' K', ' M', ' G', ' T', ' P'];
100 prefix_index = Math.min(prefix_index, PREFIX.length - 1);
101 result =
102 v + '.' + p +
103 PREFIX[prefix_index] + 'B' +
104 ' (' + result + ')';
105 } else {
106 result = v + result;
107 }
108
109 return result;
110 })();
111 },
112
113 /**
114 * Return formatted date |v| unless |v| is not undefined.
115 * @param {?number} v Number of milliseconds since
116 * UNIX epock time (0:00, Jan 1, 1970, UTC).
117 * @return {string} Formatted text of date or 'N/A'.
118 */
119 date: function(v) {
120 return normalizer_.avail_(v) || (function() {
121 // TODO(tzik): show relative time
122 return new Date(v).toString();
123 })();
124 },
125
126 /**
127 * Return toString'ed number |v| unless |v| is not undefined.
128 * @param {?number} v Number to print.
129 * @return {string} toString'ed |v| or 'N/A'.
130 */
131 num: function(v) {
132 return normalizer_.avail_(v) || v.toString();
133 }
134 };
135
136 /**
137 * Available disk space
138 * @type {number|undefined}
139 */
140 var available_space = undefined;
141
142 /**
143 * Root of the quota data tree,
144 * holding userdata as |tree_view_object.detail|.
145 * @type {cr.ui.Tree}
146 */
147 var tree_view_object = undefined;
148
149 /**
150 * Key-value styled statistics data.
151 * This WebUI does not touch contents, just show.
152 * The value is hold as |stats[key].detail|
153 * @type {Object<string,Element>}
154 */
155 var stats = {};
156
157 /**
158 * Initialize and return |tree_view_object|.
159 * @return {cr.ui.Tree} Initialized |tree_view_object|.
160 */
161 function getTreeViewObject() {
162 if (!tree_view_object) {
163 tree_view_object = $('tree-view');
164 cr.ui.decorate(tree_view_object, cr.ui.Tree);
165 tree_view_object.detail = {payload: {}, children: {}};
166 tree_view_object.addEventListener('change', updateDescription);
167 }
168 return tree_view_object;
169 }
170
171 /**
172 * Initialize and return a tree item represents specified storage type.
173 * @param {!string} type Storage type.
174 * @return {cr.ui.TreeItem} Initialized |storage_object|.
175 */
176 function getStorageObject(type) {
177 var tree_view_object = getTreeViewObject();
178 var storage_object = tree_view_object.detail.children[type];
179 if (!storage_object) {
180 storage_object = new cr.ui.TreeItem({
181 label: type,
182 detail: {payload: {}, children: {}}
183 });
184 storage_object.mayHaveChildren_ = true;
185 tree_view_object.detail.children[type] = storage_object;
186 tree_view_object.add(storage_object);
187 }
188 return storage_object;
189 }
190
191 /**
192 * Initialize and return a tree item represents specified
193 * storage type and hostname.
194 * @param {!string} type Storage type.
195 * @param {!string} host Hostname.
196 * @return {cr.ui.TreeItem} Initialized |host_object|.
197 */
198 function getHostObject(type, host) {
199 var storage_object = getStorageObject(type);
200 var host_object = storage_object.detail.children[host];
201 if (!host_object) {
202 host_object = new cr.ui.TreeItem({
203 label: host,
204 detail: {payload: {}, children: {}}
205 });
206 host_object.mayHaveChildren_ = true;
207 storage_object.detail.children[host] = host_object;
208 storage_object.add(host_object);
209 }
210 return host_object;
211 }
212
213 /**
214 * Iinitialize and return a tree item represents specified
215 * storage type, hostname and origin url.
216 * @param {!string} type Storage type.
217 * @param {!string} host Hostname.
218 * @param {!string} origin Origin URL.
219 * @return {cr.ui.TreeItem} Initialized |origin_object|.
220 */
221 function getOriginObject(type, host, origin) {
222 var host_object = getHostObject(type, host);
223 var origin_object = host_object.detail.children[origin];
224 if (!origin_object) {
225 origin_object = new cr.ui.TreeItem({
226 label: origin,
227 detail: {payload: {}, children: {}}
228 });
229 origin_object.mayHaveChildren_ = false;
230 host_object.detail.children[origin] = origin_object;
231 host_object.add(origin_object);
232 }
233 return origin_object;
234 }
235
236 /**
237 * Event Handler for |cr.quota.onAvailableSpaceUpdated|.
238 * |event.detail| contains |available_space| size.
239 * |available_space| is a (toString'ed) 64bit integer,
240 * that represents total available disk space.
241 * @param {CustomEvent} event AvailableSpaceUpdated event.
242 */
243 function handleAvailableSpace(event) {
244 /**
245 * @type {string}
246 */
247 available_space = event.detail;
248 $('diskspace-entry').innerHTML = normalizer_.numBytes(available_space);
249 };
250
251 /**
252 * Event Handler for |cr.quota.onGlobalDataUpdated|.
253 * |event.detail| contains a record which has:
254 * |type|:
255 * Storage type, that is either 'temporary' or 'persistent'
256 * |usage|:
257 * Total storage usage of all hosts,
258 * toString'ed 64bit integer.
259 * |unlimited_usage|:
260 * Total storage usage of unlimited-quota origins,
261 * toString'ed 64bit integer.
262 * |quota|:
263 * Total quota of the storage, toString'ed 64bit integer.
264 *
265 * |usage|, |unlimited_usage| and |quota| can be missing,
266 * and some additional field can be included.
267 * @param {CustomEvent} event GlobalDataUpdated event.
268 */
269 function handleGlobalData(event) {
270 /**
271 * @type {{
272 * type: {!string},
273 * usage: {?string},
274 * unlimited_usage: {?string}
275 * quota: {?string}
276 * }}
277 */
278 var data = event.detail;
279 var storage_object = getStorageObject(data.type);
280 overwrite_(data, storage_object.detail.payload);
281 storage_object.reveal();
282 };
283
284 /**
285 * Event Handler for |cr.quota.onHostDataUpdated|.
286 * |event.detail| contains records which have:
287 * |host|:
288 * Hostname of the entry. (e.g. 'example.com')
289 * |type|:
290 * Storage type. 'temporary' or 'persistent'
291 * |usage|:
292 * Total storage usage of the host, toString'ed 64bit integer.
293 * |quota|:
294 * Per-host quota, toString'ed 64bit integer.
295 *
296 * |usage| and |quota| can be missing,
297 * and some additional field can be included.
298 * @param {CustomEvent} event HostDataUpdated event.
299 */
300 function handleHostData(event) {
301 /**
302 * @type {Array<{
303 * host: {!string},
304 * type: {!string},
305 * usage: {?string},
306 * quota: {?string}
307 * }}
308 */
309 var data_array = event.detail;
310
311 for (var i = 0; i < data_array.length; ++i) {
312 var data = data_array[i];
313 var host_object = getHostObject(data.type, data.host);
314 overwrite_(data, host_object.detail.payload);
315 host_object.reveal();
316 }
317 }
318
319 /**
320 * Event Handler for |cr.quota.onOriginDataUpdated|.
321 * |event.detail| contains records which have:
322 * |origin|:
323 * Origin URL of the entry.
324 * |type|:
325 * Storage type of the entry. 'temporary' or 'persistent'.
326 * |host|:
327 * Hostname of the entry.
328 * |in_use|:
329 * Whether the origin is in use or not.
330 * |used_count|:
331 * Used count of the storage from the origin.
332 * |last_access_time|:
333 * Last storage access time from the origin.
334 * Number of seconds since Jan 1, 1970.
335 *
336 * |in_use|, |used_count| and |last_access_time| can be missing,
337 * and some additional field can be included.
338 * @param {CustomEvent} event OriginDataUpdated event.
339 */
340 function handleOriginData(event) {
341 /**
342 * @type {Array<{
343 * origin: {!string},
344 * type: {!string},
345 * host: {!string},
346 * in_use: {?boolean},
347 * used_count: {?number},
348 * last_access_time: {?number}
349 * }>}
350 */
351 var data_array = event.detail;
352
353 for (var i = 0; i < data_array.length; ++i) {
354 var data = data_array[i];
355 var origin_object = getOriginObject(data.type, data.host, data.origin);
356 overwrite_(data, origin_object.detail.payload);
357 origin_object.reveal();
358 }
359 }
360
361 /**
362 * Event Handler for |cr.quota.onStatisticsUpdated|.
363 * |event.detail| contains misc statistics data as dictionary.
364 * @param {CustomEvent} event StatisticsUpdated event.
365 */
366 function handleStatistics(event) {
367 var data = event.detail;
368 for (var key in data) {
369 var entry = stats[key];
370 if (!entry) {
371 entry = cr.doc.createElement('tr');
372 $('stat-entries').appendChild(entry);
373 stats[key] = entry;
374 }
375 entry.detail = data[key];
376 entry.innerHTML =
377 '<td>' + normalizer_.text(key) + '</td>' +
378 '<td>' + normalizer_.text(entry.detail) + '</td>';
379 localize_(entry);
380 }
381 }
382
383 /**
384 * Update description on 'tree-item-description' field with
385 * selected item in Tree view.
386 */
387 function updateDescription() {
388 var item = getTreeViewObject().selectedItem;
389 var tbody = $('tree-item-description');
390 tbody.innerHTML = '';
391
392 if (item) {
393 var keyAndLabel = [['type', 'Storage Type'],
394 ['host', 'Host Name'],
395 ['origin', 'Origin URL'],
396 ['usage', 'Total Storage Usage', normalizer_.numBytes],
397 ['unlimited_usage', 'Usage of Unlimited Origins',
398 normalizer_.numBytes],
399 ['quota', 'Quota', normalizer_.numBytes],
400 ['in_use', 'Origin is in use?'],
401 ['used_count', 'Used count'],
402 ['last_access_time', 'Last Access Time',
403 normalizer_.date]
404 ];
405 for (var i = 0; i < keyAndLabel.length; ++i) {
406 var key = keyAndLabel[i][0];
407 var label = keyAndLabel[i][1];
408 var entry = item.detail.payload[key];
409 if (entry === undefined)
410 continue;
411
412 var normalize = keyAndLabel[i][2] || normalizer_.text;
413
414 var row = cr.doc.createElement('tr');
415 row.innerHTML =
416 '<td>' + label + '</td>' +
417 '<td>' + normalize(entry) + '</td>';
418 localize_(row);
419 tbody.appendChild(row);
420 }
421 }
422 }
423
424 /**
425 * Dump |tree_view_object| or subtree to a object.
426 * @param {?{cr.ui.Tree|cr.ui.TreeItem}} opt_treeitem
427 * @return {Object} Dump result object from |tree_view_object|.
428 */
429 function dumpTreeToObj(opt_treeitem) {
430 var treeitem = opt_treeitem || getTreeViewObject();
431 var res = {};
432 res.payload = treeitem.detail.payload;
433 res.children = [];
434 for (var i in treeitem.detail.children) {
435 var child = treeitem.detail.children[i];
436 res.children.push(dumpTreeToObj(child));
437 }
438
439 if (isEmptyObject(res.payload))
440 delete res.payload;
441
442 if (res.children.length == 0)
443 delete res.children;
444 return res;
445 }
446
447 /**
448 * Dump |stats| to a object.
449 * @return {Object} Dump result object from |stats|.
450 */
451 function dumpStatsToObj() {
452 var result = {};
453 for (var key in stats)
454 result[key] = stats[key].detail;
455 return result;
456 }
457
458 /**
459 * Event handler for 'dump-button' 'click'ed.
460 * Dump and show all data from WebUI page to 'dump-field' element.
461 */
462 function dump() {
463 var separator = '========\n';
464
465 $('dump-field').textContent =
466 separator +
467 'Summary\n' +
468 separator +
469 JSON.stringify({available_space: available_space}, null, 2) + '\n' +
470 separator +
471 'Usage And Quota\n' +
472 separator +
473 JSON.stringify(dumpTreeToObj(), null, 2) + '\n' +
474 separator +
475 'Misc Statistics\n' +
476 separator +
477 JSON.stringify(dumpStatsToObj(), null, 2);
478 }
479
480 function onLoad() {
481 cr.ui.decorate('tabbox', cr.ui.TabBox);
482 localize_(document);
483
484 cr.quota.onAvailableSpaceUpdated.addEventListener('update',
485 handleAvailableSpace);
486 cr.quota.onGlobalDataUpdated.addEventListener('update', handleGlobalData);
487 cr.quota.onHostDataUpdated.addEventListener('update', handleHostData);
488 cr.quota.onOriginDataUpdated.addEventListener('update', handleOriginData);
489 cr.quota.onStatisticsUpdated.addEventListener('update', handleStatistics);
490 cr.quota.requestData();
491
492 $('refresh-button').addEventListener('click', cr.quota.requestData, false);
493 $('dump-button').addEventListener('click', dump, false);
494 }
495
496 cr.doc.addEventListener('DOMContentLoaded', onLoad, false);
497 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698