1/* 2 * Copyright (C) 2013 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26WebInspector.TimelineView = function() 27{ 28 WebInspector.Object.call(this); 29 30 this._contentTreeOutline = WebInspector.timelineSidebarPanel.createContentTreeOutline(); 31 32 this.element = document.createElement("div"); 33 this.element.classList.add(WebInspector.TimelineView.StyleClassName); 34 35 this._zeroTime = 0; 36 this._startTime = 0; 37 this._endTime = 5; 38 this._currentTime = 0; 39}; 40 41WebInspector.TimelineView.StyleClassName = "timeline-view"; 42 43WebInspector.TimelineView.Event = { 44 SelectionPathComponentsDidChange: "timeline-view-selection-path-components-did-change" 45}; 46 47WebInspector.TimelineView.prototype = { 48 constructor: WebInspector.TimelineView, 49 __proto__: WebInspector.Object.prototype, 50 51 // Public 52 53 get navigationSidebarTreeOutline() 54 { 55 return this._contentTreeOutline; 56 }, 57 58 get navigationSidebarTreeOutlineLabel() 59 { 60 // Implemented by sub-classes if needed. 61 return null; 62 }, 63 64 get selectionPathComponents() 65 { 66 if (!this._contentTreeOutline.selectedTreeElement || this._contentTreeOutline.selectedTreeElement.hidden) 67 return null; 68 69 var pathComponent = new WebInspector.GeneralTreeElementPathComponent(this._contentTreeOutline.selectedTreeElement); 70 pathComponent.addEventListener(WebInspector.HierarchicalPathComponent.Event.SiblingWasSelected, this.treeElementPathComponentSelected, this); 71 return [pathComponent]; 72 }, 73 74 get zeroTime() 75 { 76 return this._zeroTime; 77 }, 78 79 set zeroTime(x) 80 { 81 if (this._zeroTime === x) 82 return; 83 84 this._zeroTime = x || 0; 85 86 this.needsLayout(); 87 }, 88 89 get startTime() 90 { 91 return this._startTime; 92 }, 93 94 set startTime(x) 95 { 96 if (this._startTime === x) 97 return; 98 99 this._startTime = x || 0; 100 101 this.needsLayout(); 102 }, 103 104 get endTime() 105 { 106 return this._endTime; 107 }, 108 109 set endTime(x) 110 { 111 if (this._endTime === x) 112 return; 113 114 this._endTime = x || 0; 115 116 this.needsLayout(); 117 }, 118 119 get currentTime() 120 { 121 return this._currentTime; 122 }, 123 124 set currentTime(x) 125 { 126 if (this._currentTime === x) 127 return; 128 129 var oldCurrentTime = this._currentTime; 130 131 this._currentTime = x || 0; 132 133 function checkIfLayoutIsNeeded(currentTime) 134 { 135 // Include some wiggle room since the current time markers can be clipped off the ends a bit and still partially visible. 136 const wiggleTime = 0.05; // 50ms 137 return this._startTime - wiggleTime <= currentTime && currentTime <= this._endTime + wiggleTime; 138 } 139 140 if (checkIfLayoutIsNeeded.call(this, oldCurrentTime) || checkIfLayoutIsNeeded.call(this, this._currentTime)) 141 this.needsLayout(); 142 }, 143 144 get visible() 145 { 146 return this._visible; 147 }, 148 149 reset: function() 150 { 151 this._contentTreeOutline.removeChildren(); 152 }, 153 154 shown: function() 155 { 156 this._visible = true; 157 158 // Implemented by sub-classes if needed. 159 }, 160 161 hidden: function() 162 { 163 // Implemented by sub-classes if needed. 164 165 this._visible = false; 166 }, 167 168 matchTreeElementAgainstCustomFilters: function(treeElement) 169 { 170 // Implemented by sub-classes if needed. 171 return true; 172 }, 173 174 updateLayout: function() 175 { 176 if (this._scheduledLayoutUpdateIdentifier) { 177 cancelAnimationFrame(this._scheduledLayoutUpdateIdentifier); 178 delete this._scheduledLayoutUpdateIdentifier; 179 } 180 181 // Implemented by sub-classes if needed. 182 }, 183 184 updateLayoutIfNeeded: function() 185 { 186 if (!this._scheduledLayoutUpdateIdentifier) 187 return; 188 this.updateLayout(); 189 }, 190 191 // Protected 192 193 treeElementPathComponentSelected: function(event) 194 { 195 // Implemented by sub-classes if needed. 196 }, 197 198 needsLayout: function() 199 { 200 if (!this._visible) 201 return; 202 203 if (this._scheduledLayoutUpdateIdentifier) 204 return; 205 206 this._scheduledLayoutUpdateIdentifier = requestAnimationFrame(this.updateLayout.bind(this)); 207 } 208}; 209