1// Copyright (c) 2012 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 5var DetailsView = (function() { 6 'use strict'; 7 8 // We inherit from DivView. 9 var superClass = DivView; 10 11 /** 12 * The DetailsView displays the "log" view. This class keeps track of the 13 * selected SourceEntries, and repaints when they change. 14 * 15 * @constructor 16 */ 17 function DetailsView(boxId) { 18 superClass.call(this, boxId); 19 this.sourceEntries_ = []; 20 // Map of source IDs to their corresponding DIVs. 21 this.sourceIdToDivMap_ = {}; 22 // True when there's an asychronous repaint outstanding. 23 this.outstandingRepaint_ = false; 24 // ID of source entry we should jump to after the oustanding repaint. 25 // 0 if none, or there's no such repaint. 26 this.outstandingScrollToId_ = 0; 27 } 28 29 // The delay between updates to repaint. 30 var REPAINT_TIMEOUT_MS = 50; 31 32 DetailsView.prototype = { 33 // Inherit the superclass's methods. 34 __proto__: superClass.prototype, 35 36 setData: function(sourceEntries) { 37 // Make a copy of the array (in case the caller mutates it), and sort it 38 // by the source ID. 39 this.sourceEntries_ = createSortedCopy_(sourceEntries); 40 41 // Repaint the view. 42 if (this.isVisible() && !this.outstandingRepaint_) { 43 this.outstandingRepaint_ = true; 44 window.setTimeout(this.repaint.bind(this), 45 REPAINT_TIMEOUT_MS); 46 } 47 }, 48 49 repaint: function() { 50 this.outstandingRepaint_ = false; 51 this.sourceIdToDivMap_ = {}; 52 this.getNode().innerHTML = ''; 53 54 var node = this.getNode(); 55 56 for (var i = 0; i < this.sourceEntries_.length; ++i) { 57 if (i != 0) 58 addNode(node, 'hr'); 59 60 var sourceEntry = this.sourceEntries_[i]; 61 var div = addNode(node, 'div'); 62 div.className = 'log-source-entry'; 63 64 var p = addNode(div, 'p'); 65 addNodeWithText(p, 'h4', 66 sourceEntry.getSourceId() + ': ' + 67 sourceEntry.getSourceTypeString()); 68 69 if (sourceEntry.getDescription()) 70 addNodeWithText(p, 'h4', sourceEntry.getDescription()); 71 72 var logEntries = sourceEntry.getLogEntries(); 73 var startDate = timeutil.convertTimeTicksToDate(logEntries[0].time); 74 var startTimeDiv = addNodeWithText(p, 'div', 'Start Time: '); 75 timeutil.addNodeWithDate(startTimeDiv, startDate); 76 77 sourceEntry.printAsText(div); 78 79 this.sourceIdToDivMap_[sourceEntry.getSourceId()] = div; 80 } 81 82 if (this.outstandingScrollToId_) { 83 this.scrollToSourceId(this.outstandingScrollToId_); 84 this.outstandingScrollToId_ = 0; 85 } 86 }, 87 88 show: function(isVisible) { 89 superClass.prototype.show.call(this, isVisible); 90 if (isVisible) { 91 this.repaint(); 92 } else { 93 this.getNode().innerHTML = ''; 94 } 95 }, 96 97 /** 98 * Scrolls to the source indicated by |sourceId|, if displayed. If a 99 * repaint is outstanding, waits for it to complete before scrolling. 100 */ 101 scrollToSourceId: function(sourceId) { 102 if (this.outstandingRepaint_) { 103 this.outstandingScrollToId_ = sourceId; 104 return; 105 } 106 var div = this.sourceIdToDivMap_[sourceId]; 107 if (div) 108 div.scrollIntoView(); 109 } 110 }; 111 112 function createSortedCopy_(origArray) { 113 var sortedArray = origArray.slice(0); 114 sortedArray.sort(function(a, b) { 115 return a.getSourceId() - b.getSourceId(); 116 }); 117 return sortedArray; 118 } 119 120 return DetailsView; 121})(); 122