Remove the old signature of NotificationManager::closePersistent().
[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.
11  */
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.
24    */
25   ready: function() {
26   },
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.
33    */
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]);
45   },
47   /**
48    * List of provided file system information maps.
49    * @type {Array<Object>}
50    */
51   model: []
52 });
54 // Defines the request-log element.
55 Polymer('request-events', {
56   /**
57    * Called when the element is created.
58    */
59   ready: function() {
60   },
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.
66    */
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);
72   },
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.
78    */
79   formatSize: function(size) {
80     return formatSizeCommon(size);
81   },
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.
87    */
88   formatHasMore: function(opt_hasMore) {
89     if (opt_hasMore == undefined)
90       return '';
92     return opt_hasMore ? 'HAS_MORE' : 'LAST';
93   },
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.
99    */
100   formatExecutionTime: function(opt_executionTime) {
101     if (opt_executionTime == undefined)
102       return '';
104     return opt_executionTime + ' ms';
105   },
107   /**
108    * List of events.
109    * @type {Array<Object>}
110    */
111   model: []
114 // Defines the request-timeline element.
115 Polymer('request-timeline', {
116   /**
117    * Step for zoomin in and out.
118    * @type {number}
119    * @const
120    */
121   SCALE_STEP: 1.5,
123   /**
124    * Height of each row in the chart in pixels.
125    * @type {number}
126    * @const
127    */
128   ROW_HEIGHT: 14,
130   /**
131    * Observes changes in the model.
132    * @type {Object<string, string>}
133    */
134   observe: {
135     'model.length': 'chartUpdate'
136   },
138   /**
139    * Called when the element is created.
140    */
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();
148   },
150   /**
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.
154    */
155   formatSize: function(size) {
156     return formatSizeCommon(size);
157   },
159   /**
160    * Zooms in the timeline.
161    * @param {Event} event Event.
162    * @param {number} detail Detail.
163    * @param {HTMLElement} sender Sender.
164    */
165   zoomInClicked: function(event, detail, sender) {
166     this.scale *= this.SCALE_STEP;
167   },
169   /**
170    * Zooms out the timeline.
171    * @param {Event} event Event.
172    * @param {number} detail Detail.
173    * @param {HTMLElement} sender Sender.
174    */
175   zoomOutClicked: function(event, detail, sender) {
176     this.scale /= this.SCALE_STEP;
177   },
179   /**
180    * Selects or deselects an element on the timeline.
181    * @param {Event} event Event.
182    * @param {number} detail Detail.
183    * @param {HTMLElement} sender Sender.
184    */
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');
192     }
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]);
201     }
202   },
204   /**
205    * Updates chart elements of active requests, so they grow with time.
206    */
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;
214     }
215   },
217   /**
218    * Generates <code>chart</code> from the new <code>model</code> value.
219    */
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;
231     }
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]
271               });
273               this.rows[rowIndex] = {
274                 requestType: event.requestType,
275                 time: event.time,
276                 active: true
277               };
279               this.active[event.id] = this.chart.length - 1;
280               break;
281             }
283             rowIndex++;
284           }
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;
314       }
315     }
316   },
318   /**
319    * Map of selected requests.
320    * @type {Object<number, boolean>}
321    */
322   selected: {},
324   /**
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>}}
328    */
329   active: {},
331   /**
332    * List of chart elements, calculated from the model.
333    * @type {Array<Object>}
334    */
335   chart: [],
337   /**
338    * List of rows in the chart, with the last endTime value on it.
339    * @type {Array<Object>}
340    */
341   rows: [],
343   /**
344    * Scale of the chart.
345    * @type {number}
346    */
347   scale: 1,
349   /**
350    * Time of the first created request.
351    * @type {Date}
352    */
353   timeStart: null,
355   /**
356    * Time of the last idling started.
357    * @type {Date}
358    */
359   idleStart: null,
361   /**
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}
365    */
366   idleTotal: 0,
368   /**
369    * List of requests information maps.
370    * @type {Array<Object>}
371    */
372   model: []
376  * Updates the mounted file system list.
377  * @param {Array<Object>} fileSystems Array containing provided file system
378  *     information.
379  */
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.
388  */
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);