Move Webstore URL concepts to //extensions and out
[chromium-blink-merge.git] / chrome / browser / resources / chromeos / provided_file_systems.js
blobafdde09462ebc60d7808a8595d082c569fab0c6e
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 <include src="../../../../third_party/polymer_legacy/platform/platform.js">
6 <include src="../../../../third_party/polymer_legacy/polymer/polymer.js">
8 /**
9 * Formats size to a human readable form.
10 * @param {number} size Size in bytes.
11 * @return {string} Output string in a human-readable format.
13 function formatSizeCommon(size) {
14 if (size < 1024)
15 return size + ' B';
16 if (size < 1024 * 1024)
17 return Math.round(size / 1024) + ' KB';
18 return Math.round(size / 1024 / 1024) + ' MB';
21 // Defines the file-systems element.
22 Polymer('file-systems', {
23 /**
24 * Called when the element is created.
26 ready: function() {
29 /**
30 * Selects an active file system from the list.
31 * @param {Event} event Event.
32 * @param {number} detail Detail.
33 * @param {HTMLElement} sender Sender.
35 rowClicked: function(event, detail, sender) {
36 var requestEventsNode = document.querySelector('#request-events');
37 requestEventsNode.hidden = false;
38 requestEventsNode.model = [];
40 var requestTimelineNode = document.querySelector('#request-timeline');
41 requestTimelineNode.hidden = false;
42 requestTimelineNode.model = [];
44 chrome.send('selectFileSystem', [sender.dataset.extensionId,
45 sender.dataset.id]);
48 /**
49 * List of provided file system information maps.
50 * @type {Array.<Object>}
52 model: []
53 });
55 // Defines the request-log element.
56 Polymer('request-events', {
57 /**
58 * Called when the element is created.
60 ready: function() {
63 /**
64 * Formats time to a hh:mm:ss.xxxx format.
65 * @param {Date} time Input time.
66 * @return {string} Output string in a human-readable format.
68 formatTime: function(time) {
69 return ('0' + time.getHours()).slice(-2) + ':' +
70 ('0' + time.getMinutes()).slice(-2) + ':' +
71 ('0' + time.getSeconds()).slice(-2) + '.' +
72 ('000' + time.getMilliseconds()).slice(-3);
75 /**
76 * Formats size to a human readable form.
77 * @param {number} size Size in bytes.
78 * @return {string} Output string in a human-readable format.
80 formatSize: function(size) {
81 return formatSizeCommon(size);
84 /**
85 * Formats a boolean value to human-readable form.
86 * @param {boolean=} opt_hasMore Input value.
87 * @return {string} Output string in a human-readable format.
89 formatHasMore: function(opt_hasMore) {
90 if (opt_hasMore == undefined)
91 return '';
93 return opt_hasMore ? 'HAS_MORE' : 'LAST';
96 /**
97 * Formats execution time to human-readable form.
98 * @param {boolean=} opt_executionTime Input value.
99 * @return {string} Output string in a human-readable format.
101 formatExecutionTime: function(opt_executionTime) {
102 if (opt_executionTime == undefined)
103 return '';
105 return opt_executionTime + ' ms';
109 * List of events.
110 * @type {Array.<Object>}
112 model: []
115 // Defines the request-timeline element.
116 Polymer('request-timeline', {
118 * Step for zoomin in and out.
119 * @type {number}
120 * @const
122 SCALE_STEP: 1.5,
125 * Height of each row in the chart in pixels.
126 * @type {number}
127 * @const
129 ROW_HEIGHT: 14,
132 * Observes changes in the model.
133 * @type {Object.<string, string>}
135 observe: {
136 'model.length': 'chartUpdate'
140 * Called when the element is created.
142 ready: function() {
143 // Update active requests in the background for nice animation.
144 var activeUpdateAnimation = function() {
145 this.activeUpdate();
146 requestAnimationFrame(activeUpdateAnimation);
147 }.bind(this);
148 activeUpdateAnimation();
152 * Formats size to a human readable form.
153 * @param {number} size Size in bytes.
154 * @return {string} Output string in a human-readable format.
156 formatSize: function(size) {
157 return formatSizeCommon(size);
161 * Zooms in the timeline.
162 * @param {Event} event Event.
163 * @param {number} detail Detail.
164 * @param {HTMLElement} sender Sender.
166 zoomInClicked: function(event, detail, sender) {
167 this.scale *= this.SCALE_STEP;
171 * Zooms out the timeline.
172 * @param {Event} event Event.
173 * @param {number} detail Detail.
174 * @param {HTMLElement} sender Sender.
176 zoomOutClicked: function(event, detail, sender) {
177 this.scale /= this.SCALE_STEP;
181 * Selects or deselects an element on the timeline.
182 * @param {Event} event Event.
183 * @param {number} detail Detail.
184 * @param {HTMLElement} sender Sender.
186 elementClicked: function(event, detail, sender) {
187 if (sender.dataset.id in this.selected) {
188 delete this.selected[sender.dataset.id];
189 sender.classList.remove('selected');
190 } else {
191 this.selected[sender.dataset.id] = true;
192 sender.classList.add('selected');
195 var requestEventsNode = document.querySelector('#request-events');
196 requestEventsNode.hidden = false;
198 requestEventsNode.model = [];
199 for (var i = 0; i < this.model.length; i++) {
200 if (this.model[i].id in this.selected)
201 requestEventsNode.model.push(this.model[i]);
206 * Updates chart elements of active requests, so they grow with time.
208 activeUpdate: function() {
209 if (Object.keys(this.active).length == 0)
210 return;
212 for (var id in this.active) {
213 var index = this.active[id];
214 this.chart[index].length = Date.now() - this.chart[index].time;
219 * Generates <code>chart</code> from the new <code>model</code> value.
221 chartUpdate: function(oldLength, newLength) {
222 // If the new value is empty, then clear the model.
223 if (!newLength) {
224 this.active = {};
225 this.rows = [];
226 this.chart = [];
227 this.timeStart = null;
228 this.idleStart = null;
229 this.idleTotal = 0;
230 this.selected = [];
231 return;
234 // Only adding new entries to the model is supported (or clearing).
235 console.assert(newLength >= oldLength);
237 for (var i = oldLength; i < newLength; i++) {
238 var event = this.model[i];
239 switch (event.eventType) {
240 case 'created':
241 // If this is the first creation event in the chart, then store its
242 // time as beginning time of the chart.
243 if (!this.timeStart)
244 this.timeStart = event.time;
246 // If this event terminates idling, then add the idling time to total
247 // idling time. This is used to avoid gaps in the chart while idling.
248 if (Object.keys(this.active).length == 0 && this.idleStart)
249 this.idleTotal += event.time.getTime() - this.idleStart.getTime();
251 // Find the appropriate row for this chart element.
252 var rowIndex = 0;
253 while (true) {
254 // Add to this row only if there is enough space, and if the row
255 // is of the same type.
256 var addToRow = (rowIndex >= this.rows.length) ||
257 (this.rows[rowIndex].time.getTime() <= event.time.getTime() &&
258 !this.rows[rowIndex].active &&
259 (this.rows[rowIndex].requestType == event.requestType));
261 if (addToRow) {
262 this.chart.push({
263 index: this.chart.length,
264 id: event.id,
265 time: event.time,
266 executionTime: 0,
267 length: 0,
268 requestType: event.requestType,
269 left: event.time - this.timeStart - this.idleTotal,
270 row: rowIndex,
271 modelIndexes: [i]
274 this.rows[rowIndex] = {
275 requestType: event.requestType,
276 time: event.time,
277 active: true
280 this.active[event.id] = this.chart.length - 1;
281 break;
284 rowIndex++;
286 break;
288 case 'fulfilled':
289 case 'rejected':
290 if (!(event.id in this.active))
291 return;
292 var chartIndex = this.active[event.id];
293 this.chart[chartIndex].state = event.eventType;
294 this.chart[chartIndex].executionTime = event.executionTime;
295 this.chart[chartIndex].valueSize = event.valueSize;
296 this.chart[chartIndex].modelIndexes.push(i);
297 break;
299 case 'destroyed':
300 if (!(event.id in this.active))
301 return;
303 var chartIndex = this.active[event.id];
304 this.chart[chartIndex].length =
305 event.time - this.chart[chartIndex].time;
306 this.chart[chartIndex].modelIndexes.push(i);
307 this.rows[this.chart[chartIndex].row].time = event.time;
308 this.rows[this.chart[chartIndex].row].active = false;
309 delete this.active[event.id];
311 // If this was the last active request, then idling starts.
312 if (Object.keys(this.active).length == 0)
313 this.idleStart = event.time;
314 break;
320 * Map of selected requests.
321 * @type {Object.<number, boolean>}
323 selected: {},
326 * Map of requests which has started, but are not completed yet, from
327 * a request id to the chart element index.
328 * @type {Object.<number, number>}}
330 active: {},
333 * List of chart elements, calculated from the model.
334 * @type {Array.<Object>}
336 chart: [],
339 * List of rows in the chart, with the last endTime value on it.
340 * @type {Array.<Object>}
342 rows: [],
345 * Scale of the chart.
346 * @type {number}
348 scale: 1,
351 * Time of the first created request.
352 * @type {Date}
354 timeStart: null,
357 * Time of the last idling started.
358 * @type {Date}
360 idleStart: null,
363 * Total idling time since chart generation started. Used to avoid
364 * generating gaps in the chart when there is no activity. In milliseconds.
365 * @type {number}
367 idleTotal: 0,
370 * List of requests information maps.
371 * @type {Array.<Object>}
373 model: []
377 * Updates the mounted file system list.
378 * @param {Array.<Object>} fileSystems Array containing provided file system
379 * information.
381 function updateFileSystems(fileSystems) {
382 var fileSystemsNode = document.querySelector('#file-systems');
383 fileSystemsNode.model = fileSystems;
387 * Called when a request is created.
388 * @param {Object} event Event.
390 function onRequestEvent(event) {
391 event.time = new Date(event.time); // Convert to a real Date object.
392 var requestTimelineNode = document.querySelector('#request-timeline');
393 requestTimelineNode.model.push(event);
396 document.addEventListener('DOMContentLoaded', function() {
397 var context = document.getCSSCanvasContext('2d', 'dashedPattern', 4, 4);
398 context.beginPath();
399 context.strokeStyle = '#ffffff';
400 context.moveTo(0, 0);
401 context.lineTo(4, 4);
402 context.stroke();
404 chrome.send('updateFileSystems');
406 // Refresh periodically.
407 setInterval(function() {
408 chrome.send('updateFileSystems');
409 }, 1000);