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.
5 cr.define('media', function() {
9 * This class represents a file cached by net.
11 function CacheEntry() {
12 this.read_ = new media.DisjointRangeSet;
13 this.written_ = new media.DisjointRangeSet;
14 this.available_ = new media.DisjointRangeSet;
16 // Set to true when we know the entry is sparse.
21 // The <details> element representing this CacheEntry.
22 this.details_ = document.createElement('details');
23 this.details_.className = 'cache-entry';
24 this.details_.open = false;
26 // The <details> summary line. It contains a chart of requested file ranges
27 // and the url if we know it.
28 var summary = document.createElement('summary');
30 this.summaryText_ = document.createTextNode('');
31 summary.appendChild(this.summaryText_);
33 summary.appendChild(document.createTextNode(' '));
35 // Controls to modify this CacheEntry.
36 var controls = document.createElement('span');
37 controls.className = 'cache-entry-controls';
38 summary.appendChild(controls);
39 summary.appendChild(document.createElement('br'));
41 // A link to clear recorded data from this CacheEntry.
42 var clearControl = document.createElement('a');
43 clearControl.href = 'javascript:void(0)';
44 clearControl.onclick = this.clear.bind(this);
45 clearControl.textContent = '(clear entry)';
46 controls.appendChild(clearControl);
48 this.details_.appendChild(summary);
50 // The canvas for drawing cache writes.
51 this.writeCanvas = document.createElement('canvas');
52 this.writeCanvas.width = media.BAR_WIDTH;
53 this.writeCanvas.height = media.BAR_HEIGHT;
54 this.details_.appendChild(this.writeCanvas);
56 // The canvas for drawing cache reads.
57 this.readCanvas = document.createElement('canvas');
58 this.readCanvas.width = media.BAR_WIDTH;
59 this.readCanvas.height = media.BAR_HEIGHT;
60 this.details_.appendChild(this.readCanvas);
62 // A tabular representation of the data in the above canvas.
63 this.detailTable_ = document.createElement('table');
64 this.detailTable_.className = 'cache-table';
65 this.details_.appendChild(this.detailTable_);
68 CacheEntry.prototype = {
70 * Mark a range of bytes as read from the cache.
71 * @param {int} start The first byte read.
72 * @param {int} length The number of bytes read.
74 readBytes: function(start, length) {
75 start = parseInt(start);
76 length = parseInt(length);
77 this.read_.add(start, start + length);
78 this.available_.add(start, start + length);
83 * Mark a range of bytes as written to the cache.
84 * @param {int} start The first byte written.
85 * @param {int} length The number of bytes written.
87 writeBytes: function(start, length) {
88 start = parseInt(start);
89 length = parseInt(length);
90 this.written_.add(start, start + length);
91 this.available_.add(start, start + length);
96 * Merge this CacheEntry with another, merging recorded ranges and flags.
97 * @param {CacheEntry} other The CacheEntry to merge into this one.
99 merge: function(other) {
100 this.read_.merge(other.read_);
101 this.written_.merge(other.written_);
102 this.available_.merge(other.available_);
103 this.sparse = this.sparse || other.sparse;
104 this.key = this.key || other.key;
105 this.size = this.size || other.size;
109 * Clear all recorded ranges from this CacheEntry and redraw this.details_.
112 this.read_ = new media.DisjointRangeSet;
113 this.written_ = new media.DisjointRangeSet;
114 this.available_ = new media.DisjointRangeSet;
115 this.generateDetails();
119 * Helper for drawCacheReadsToCanvas() and drawCacheWritesToCanvas().
121 * Accepts the entries to draw, a canvas fill style, and the canvas to
124 drawCacheEntriesToCanvas: function(entries, fillStyle, canvas) {
125 // Don't bother drawing anything if we don't know the total size.
130 var width = canvas.width;
131 var height = canvas.height;
132 var context = canvas.getContext('2d');
133 var fileSize = this.size;
135 context.fillStyle = '#aaa';
136 context.fillRect(0, 0, width, height);
138 function drawRange(start, end) {
139 var left = start / fileSize * width;
140 var right = end / fileSize * width;
141 context.fillRect(left, 0, right - left, height);
144 context.fillStyle = fillStyle;
145 entries.map(function(start, end) {
146 drawRange(start, end);
151 * Draw cache writes to the given canvas.
153 * It should consist of a horizontal bar with highlighted sections to
154 * represent which parts of a file have been written to the cache.
156 * e.g. |xxxxxx----------x|
158 drawCacheWritesToCanvas: function(canvas) {
159 this.drawCacheEntriesToCanvas(this.written_, '#00a', canvas);
163 * Draw cache reads to the given canvas.
165 * It should consist of a horizontal bar with highlighted sections to
166 * represent which parts of a file have been read from the cache.
168 * e.g. |xxxxxx----------x|
170 drawCacheReadsToCanvas: function(canvas) {
171 this.drawCacheEntriesToCanvas(this.read_, '#0a0', canvas);
175 * Update this.details_ to contain everything we currently know about
178 generateDetails: function() {
179 function makeElement(tag, content) {
180 var toReturn = document.createElement(tag);
181 toReturn.textContent = content;
185 this.details_.id = this.key;
186 this.summaryText_.textContent = this.key || 'Unknown File';
188 this.detailTable_.textContent = '';
189 var header = document.createElement('thead');
190 var footer = document.createElement('tfoot');
191 var body = document.createElement('tbody');
192 this.detailTable_.appendChild(header);
193 this.detailTable_.appendChild(footer);
194 this.detailTable_.appendChild(body);
196 var headerRow = document.createElement('tr');
197 headerRow.appendChild(makeElement('th', 'Read From Cache'));
198 headerRow.appendChild(makeElement('th', 'Written To Cache'));
199 header.appendChild(headerRow);
201 var footerRow = document.createElement('tr');
202 var footerCell = document.createElement('td');
203 footerCell.textContent = 'Out of ' + (this.size || 'unkown size');
204 footerCell.setAttribute('colspan', 2);
205 footerRow.appendChild(footerCell);
206 footer.appendChild(footerRow);
208 var read = this.read_.map(function(start, end) {
209 return start + ' - ' + end;
211 var written = this.written_.map(function(start, end) {
212 return start + ' - ' + end;
215 var length = Math.max(read.length, written.length);
216 for (var i = 0; i < length; i++) {
217 var row = document.createElement('tr');
218 row.appendChild(makeElement('td', read[i] || ''));
219 row.appendChild(makeElement('td', written[i] || ''));
220 body.appendChild(row);
223 this.drawCacheWritesToCanvas(this.writeCanvas);
224 this.drawCacheReadsToCanvas(this.readCanvas);
228 * Render this CacheEntry as a <li>.
229 * @return {HTMLElement} A <li> representing this CacheEntry.
231 toListItem: function() {
232 this.generateDetails();
234 var result = document.createElement('li');
235 result.appendChild(this.details_);
241 CacheEntry: CacheEntry