Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / resources / chromeos / provided_file_systems.js
blob007bf00e94772913f458957961c02ff63d687cce
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/components/polymer/polymer.js">
7 /**
8 * Formats size to a human readable form.
9 * @param {number} size Size in bytes.
10 * @return {string} Output string in a human-readable format.
12 function formatSizeCommon(size) {
13 if (size < 1024)
14 return size + ' B';
15 if (size < 1024 * 1024)
16 return Math.round(size / 1024) + ' KB';
17 return Math.round(size / 1024 / 1024) + ' MB';
20 // Defines the file-systems element.
21 Polymer('file-systems', {
22 /**
23 * Called when the element is created.
25 ready: function() {
28 /**
29 * Selects an active file system from the list.
30 * @param {Event} event Event.
31 * @param {number} detail Detail.
32 * @param {HTMLElement} sender Sender.
34 rowClicked: function(event, detail, sender) {
35 var requestEventsNode = document.querySelector('#request-events');
36 requestEventsNode.hidden = false;
37 requestEventsNode.model = [];
39 var requestTimelineNode = document.querySelector('#request-timeline');
40 requestTimelineNode.hidden = false;
41 requestTimelineNode.model = [];
43 chrome.send('selectFileSystem', [sender.dataset.extensionId,
44 sender.dataset.id]);
47 /**
48 * List of provided file system information maps.
49 * @type {Array<Object>}
51 model: []
52 });
54 // Defines the request-log element.
55 Polymer('request-events', {
56 /**
57 * Called when the element is created.
59 ready: function() {
62 /**
63 * Formats time to a hh:mm:ss.xxxx format.
64 * @param {Date} time Input time.
65 * @return {string} Output string in a human-readable format.
67 formatTime: function(time) {
68 return ('0' + time.getHours()).slice(-2) + ':' +
69 ('0' + time.getMinutes()).slice(-2) + ':' +
70 ('0' + time.getSeconds()).slice(-2) + '.' +
71 ('000' + time.getMilliseconds()).slice(-3);
74 /**
75 * Formats size to a human readable form.
76 * @param {number} size Size in bytes.
77 * @return {string} Output string in a human-readable format.
79 formatSize: function(size) {
80 return formatSizeCommon(size);
83 /**
84 * Formats a boolean value to human-readable form.
85 * @param {boolean=} opt_hasMore Input value.
86 * @return {string} Output string in a human-readable format.
88 formatHasMore: function(opt_hasMore) {
89 if (opt_hasMore == undefined)
90 return '';
92 return opt_hasMore ? 'HAS_MORE' : 'LAST';
95 /**
96 * Formats execution time to human-readable form.
97 * @param {boolean=} opt_executionTime Input value.
98 * @return {string} Output string in a human-readable format.
100 formatExecutionTime: function(opt_executionTime) {
101 if (opt_executionTime == undefined)
102 return '';
104 return opt_executionTime + ' ms';
108 * List of events.
109 * @type {Array<Object>}
111 model: []
114 // Defines the request-timeline element.
115 Polymer('request-timeline', {
117 * Step for zoomin in and out.
118 * @type {number}
119 * @const
121 SCALE_STEP: 1.5,
124 * Height of each row in the chart in pixels.
125 * @type {number}
126 * @const
128 ROW_HEIGHT: 14,
131 * Observes changes in the model.
132 * @type {Object<string, string>}
134 observe: {
135 'model.length': 'chartUpdate'
139 * Called when the element is created.
141 ready: function() {
142 // Update active requests in the background for nice animation.
143 var activeUpdateAnimation = function() {
144 this.activeUpdate();
145 requestAnimationFrame(activeUpdateAnimation);
146 }.bind(this);
147 activeUpdateAnimation();
151 * Formats size to a human readable form.
152 * @param {number} size Size in bytes.
153 * @return {string} Output string in a human-readable format.
155 formatSize: function(size) {
156 return formatSizeCommon(size);
160 * Zooms in the timeline.
161 * @param {Event} event Event.
162 * @param {number} detail Detail.
163 * @param {HTMLElement} sender Sender.
165 zoomInClicked: function(event, detail, sender) {
166 this.scale *= this.SCALE_STEP;
170 * Zooms out the timeline.
171 * @param {Event} event Event.
172 * @param {number} detail Detail.
173 * @param {HTMLElement} sender Sender.
175 zoomOutClicked: function(event, detail, sender) {
176 this.scale /= this.SCALE_STEP;
180 * Selects or deselects an element on the timeline.
181 * @param {Event} event Event.
182 * @param {number} detail Detail.
183 * @param {HTMLElement} sender Sender.
185 elementClicked: function(event, detail, sender) {
186 if (sender.dataset.id in this.selected) {
187 delete this.selected[sender.dataset.id];
188 sender.classList.remove('selected');
189 } else {
190 this.selected[sender.dataset.id] = true;
191 sender.classList.add('selected');
194 var requestEventsNode = document.querySelector('#request-events');
195 requestEventsNode.hidden = false;
197 requestEventsNode.model = [];
198 for (var i = 0; i < this.model.length; i++) {
199 if (this.model[i].id in this.selected)
200 requestEventsNode.model.push(this.model[i]);
205 * Updates chart elements of active requests, so they grow with time.
207 activeUpdate: function() {
208 if (Object.keys(this.active).length == 0)
209 return;
211 for (var id in this.active) {
212 var index = this.active[id];
213 this.chart[index].length = Date.now() - this.chart[index].time;
218 * Generates <code>chart</code> from the new <code>model</code> value.
220 chartUpdate: function(oldLength, newLength) {
221 // If the new value is empty, then clear the model.
222 if (!newLength) {
223 this.active = {};
224 this.rows = [];
225 this.chart = [];
226 this.timeStart = null;
227 this.idleStart = null;
228 this.idleTotal = 0;
229 this.selected = [];
230 return;
233 // Only adding new entries to the model is supported (or clearing).
234 console.assert(newLength >= oldLength);
236 for (var i = oldLength; i < newLength; i++) {
237 var event = this.model[i];
238 switch (event.eventType) {
239 case 'created':
240 // If this is the first creation event in the chart, then store its
241 // time as beginning time of the chart.
242 if (!this.timeStart)
243 this.timeStart = event.time;
245 // If this event terminates idling, then add the idling time to total
246 // idling time. This is used to avoid gaps in the chart while idling.
247 if (Object.keys(this.active).length == 0 && this.idleStart)
248 this.idleTotal += event.time.getTime() - this.idleStart.getTime();
250 // Find the appropriate row for this chart element.
251 var rowIndex = 0;
252 while (true) {
253 // Add to this row only if there is enough space, and if the row
254 // is of the same type.
255 var addToRow = (rowIndex >= this.rows.length) ||
256 (this.rows[rowIndex].time.getTime() <= event.time.getTime() &&
257 !this.rows[rowIndex].active &&
258 (this.rows[rowIndex].requestType == event.requestType));
260 if (addToRow) {
261 this.chart.push({
262 index: this.chart.length,
263 id: event.id,
264 time: event.time,
265 executionTime: 0,
266 length: 0,
267 requestType: event.requestType,
268 left: event.time - this.timeStart - this.idleTotal,
269 row: rowIndex,
270 modelIndexes: [i]
273 this.rows[rowIndex] = {
274 requestType: event.requestType,
275 time: event.time,
276 active: true
279 this.active[event.id] = this.chart.length - 1;
280 break;
283 rowIndex++;
285 break;
287 case 'fulfilled':
288 case 'rejected':
289 if (!(event.id in this.active))
290 return;
291 var chartIndex = this.active[event.id];
292 this.chart[chartIndex].state = event.eventType;
293 this.chart[chartIndex].executionTime = event.executionTime;
294 this.chart[chartIndex].valueSize = event.valueSize;
295 this.chart[chartIndex].modelIndexes.push(i);
296 break;
298 case 'destroyed':
299 if (!(event.id in this.active))
300 return;
302 var chartIndex = this.active[event.id];
303 this.chart[chartIndex].length =
304 event.time - this.chart[chartIndex].time;
305 this.chart[chartIndex].modelIndexes.push(i);
306 this.rows[this.chart[chartIndex].row].time = event.time;
307 this.rows[this.chart[chartIndex].row].active = false;
308 delete this.active[event.id];
310 // If this was the last active request, then idling starts.
311 if (Object.keys(this.active).length == 0)
312 this.idleStart = event.time;
313 break;
319 * Map of selected requests.
320 * @type {Object<number, boolean>}
322 selected: {},
325 * Map of requests which has started, but are not completed yet, from
326 * a request id to the chart element index.
327 * @type {Object<number, number>}}
329 active: {},
332 * List of chart elements, calculated from the model.
333 * @type {Array<Object>}
335 chart: [],
338 * List of rows in the chart, with the last endTime value on it.
339 * @type {Array<Object>}
341 rows: [],
344 * Scale of the chart.
345 * @type {number}
347 scale: 1,
350 * Time of the first created request.
351 * @type {Date}
353 timeStart: null,
356 * Time of the last idling started.
357 * @type {Date}
359 idleStart: null,
362 * Total idling time since chart generation started. Used to avoid
363 * generating gaps in the chart when there is no activity. In milliseconds.
364 * @type {number}
366 idleTotal: 0,
369 * List of requests information maps.
370 * @type {Array<Object>}
372 model: []
376 * Updates the mounted file system list.
377 * @param {Array<Object>} fileSystems Array containing provided file system
378 * information.
380 function updateFileSystems(fileSystems) {
381 var fileSystemsNode = document.querySelector('#file-systems');
382 fileSystemsNode.model = fileSystems;
386 * Called when a request is created.
387 * @param {Object} event Event.
389 function onRequestEvent(event) {
390 event.time = new Date(event.time); // Convert to a real Date object.
391 var requestTimelineNode = document.querySelector('#request-timeline');
392 requestTimelineNode.model.push(event);
395 document.addEventListener('DOMContentLoaded', function() {
396 var context = document.getCSSCanvasContext('2d', 'dashedPattern', 4, 4);
397 context.beginPath();
398 context.strokeStyle = '#ffffff';
399 context.moveTo(0, 0);
400 context.lineTo(4, 4);
401 context.stroke();
403 chrome.send('updateFileSystems');
405 // Refresh periodically.
406 setInterval(function() {
407 chrome.send('updateFileSystems');
408 }, 1000);