Changeset 162681 in webkit
- Timestamp:
- Jan 23, 2014 7:41:22 PM (10 years ago)
- Location:
- trunk/Source/WebInspectorUI
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebInspectorUI/ChangeLog
r162564 r162681 1 2014-01-23 Timothy Hatcher <timothy@apple.com> 2 3 Refactor TimelineRecordBar combining logic into a helper function. 4 5 https://bugs.webkit.org/show_bug.cgi?id=127530 6 7 Reviewed by Joseph Pecoraro. 8 9 * UserInterface/LayoutTimelineOverviewGraph.js: 10 (WebInspector.LayoutTimelineOverviewGraph.prototype.updateLayout.createBar): 11 (WebInspector.LayoutTimelineOverviewGraph.prototype.updateLayout): 12 Use TimelineRecordBar.createCombinedBars. 13 14 * UserInterface/NetworkTimelineOverviewGraph.css: 15 (.timeline-overview-graph.network): 16 (.timeline-overview-graph.network > .graph-row > .timeline-record-bar): 17 Cleaned up since we are using TimelineRecordBar. 18 19 * UserInterface/NetworkTimelineOverviewGraph.js: 20 (WebInspector.NetworkTimelineOverviewGraph.prototype.reset): 21 (WebInspector.NetworkTimelineOverviewGraph.prototype.updateLayout.createBar): 22 (WebInspector.NetworkTimelineOverviewGraph.prototype.updateLayout): 23 Use TimelineRecordBar.createCombinedBars. 24 25 * UserInterface/ScriptTimelineOverviewGraph.js: 26 (WebInspector.ScriptTimelineOverviewGraph.prototype.updateLayout.createBar): 27 (WebInspector.ScriptTimelineOverviewGraph.prototype.updateLayout): 28 Use TimelineRecordBar.createCombinedBars. 29 30 * UserInterface/TimelineDataGridNode.js: 31 (WebInspector.TimelineDataGridNode.prototype.refreshGraph.createBar): 32 (WebInspector.TimelineDataGridNode.prototype.refreshGraph): 33 Use TimelineRecordBar.createCombinedBars. 34 35 * UserInterface/TimelineRecordBar.css: 36 (.timeline-record-bar.unfinished > .segment): 37 (.timeline-record-bar.has-inactive-segment > .segment:not(.inactive)): 38 (:focus .selected .timeline-record-bar > .segment.inactive): 39 Improved selected appearance and don't assume .segment.inactive exists. 40 41 * UserInterface/TimelineRecordBar.js: 42 (WebInspector.TimelineRecordBar): 43 (WebInspector.TimelineRecordBar.createCombinedBars.compareByActiveStartTime): Added. 44 (WebInspector.TimelineRecordBar.createCombinedBars): Added. 45 (WebInspector.TimelineRecordBar.prototype.get renderMode): Added. 46 (WebInspector.TimelineRecordBar.prototype.set renderMode): Added. 47 (WebInspector.TimelineRecordBar.prototype.set records): 48 (WebInspector.TimelineRecordBar.prototype.refresh): 49 Lazily create DOM elements. Support rendering one or both segments. Doing this lets 50 combined inactive segments sit behind multiple active segments. 51 1 52 2014-01-22 Timothy Hatcher <timothy@apple.com> 2 53 -
trunk/Source/WebInspectorUI/UserInterface/LayoutTimelineOverviewGraph.js
r162419 r162681 59 59 WebInspector.TimelineOverviewGraph.prototype.updateLayout.call(this); 60 60 61 var startTime = this.startTime; 62 var currentTime = this.currentTime; 63 var endTime = this.endTime; 64 var duration = (endTime - startTime); 61 var visibleWidth = this.element.offsetWidth; 62 var secondsPerPixel = (this.endTime - this.startTime) / visibleWidth; 65 63 66 var visibleWidth = this.element.offsetWidth;67 var secondsPerPixel = duration / visibleWidth;68 64 var recordBarIndex = 0; 69 var barRecords = [];70 65 71 function createBar( barRecords)66 function createBar(records, renderMode) 72 67 { 73 68 var timelineRecordBar = this._timelineRecordBars[recordBarIndex]; 74 69 if (!timelineRecordBar) 75 70 timelineRecordBar = this._timelineRecordBars[recordBarIndex] = new WebInspector.TimelineRecordBar; 76 timelineRecordBar.records = barRecords; 71 timelineRecordBar.renderMode = renderMode; 72 timelineRecordBar.records = records; 77 73 timelineRecordBar.refresh(this); 78 74 if (!timelineRecordBar.element.parentNode) … … 81 77 } 82 78 83 for (var record of this._layoutTimeline.records) { 84 // If this bar is completely before the bounds of the graph, skip this record. 85 if (record.endTime < startTime) 86 continue; 87 88 // If this record is completely after the current time or end time, break out now. 89 // Records are sorted, so all records after this will be beyond the current or end time too. 90 if (record.startTime > currentTime || record.startTime > endTime) 91 break; 92 93 // Check if the previous record is a different type or far enough away to create the bar. 94 if (barRecords.length && WebInspector.TimelineRecordBar.recordsCannotBeCombined(barRecords, record, secondsPerPixel)) { 95 createBar.call(this, barRecords); 96 barRecords = []; 97 } 98 99 barRecords.push(record); 100 } 101 102 // Create the bar for the last record if needed. 103 if (barRecords.length) 104 createBar.call(this, barRecords); 79 WebInspector.TimelineRecordBar.createCombinedBars(this._layoutTimeline.records, secondsPerPixel, this, createBar.bind(this)); 105 80 106 81 // Remove the remaining unused TimelineRecordBars. -
trunk/Source/WebInspectorUI/UserInterface/NetworkTimelineOverviewGraph.css
r162419 r162681 25 25 26 26 .timeline-overview-graph.network { 27 padding-top: 2px27 padding-top: 3px; 28 28 } 29 29 30 30 .timeline-overview-graph.network > .graph-row { 31 position: relative;32 31 height: 5px; 33 32 } 34 33 35 .timeline-overview-graph.network > .graph-row > .bar { 36 position: absolute; 34 .timeline-overview-graph.network > .graph-row > .timeline-record-bar { 37 35 height: 4px; 38 background-color: rgb(120, 176, 225);39 border: 1px solid rgb(61, 147, 200);40 border-radius: 2px;41 36 margin-top: 1px; 42 min-width: 3px;43 37 } 44 38 45 .timeline-overview-graph.network > .graph-row > .bar.inactive { 46 background-color: rgb(167, 204, 237); 47 border-color: rgb(127, 185, 220); 48 } 49 50 .timeline-overview-graph.network > .graph-row > .bar.inactive, 51 .timeline-overview-graph.network > .graph-row > .bar.unfinished { 52 border-top-right-radius: 0; 53 border-bottom-right-radius: 0; 54 border-right: none; 55 } 56 57 .timeline-overview-graph.network > .graph-row > .bar:not(.inactive) { 58 border-top-left-radius: 0; 59 border-bottom-left-radius: 0; 60 z-index: 1; 39 .timeline-overview-graph.network > .graph-row > .timeline-record-bar > .segment:not(.inactive) { 61 40 box-shadow: white 1px 0 0; 62 41 } 63 42 64 .timeline-overview-graph.network:nth-child(even) > .graph-row > . bar:not(.inactive) {43 .timeline-overview-graph.network:nth-child(even) > .graph-row > .timeline-record-bar > .segment:not(.inactive) { 65 44 box-shadow: rgb(247, 247, 247) 1px 0 0; 66 45 } -
trunk/Source/WebInspectorUI/UserInterface/NetworkTimelineOverviewGraph.js
r162419 r162681 44 44 WebInspector.NetworkTimelineOverviewGraph.UnfinishedStyleClassName = "unfinished"; 45 45 WebInspector.NetworkTimelineOverviewGraph.MaximumRowCount = 6; 46 WebInspector.NetworkTimelineOverviewGraph.MinimumBarPaddingPixels = 5;47 46 48 47 WebInspector.NetworkTimelineOverviewGraph.prototype = { … … 63 62 64 63 this.element.removeChildren(); 64 65 for (var rowRecords of this._timelineRecordGridRows) { 66 rowRecords.__element = document.createElement("div"); 67 rowRecords.__element.className = WebInspector.NetworkTimelineOverviewGraph.GraphRowStyleClassName; 68 this.element.appendChild(rowRecords.__element); 69 70 rowRecords.__recordBars = []; 71 } 65 72 }, 66 73 … … 69 76 WebInspector.TimelineOverviewGraph.prototype.updateLayout.call(this); 70 77 71 var startTime = this.startTime; 72 var currentTime = this.currentTime; 73 var endTime = this.endTime; 74 var duration = (endTime - startTime); 78 var visibleWidth = this.element.offsetWidth; 79 var secondsPerPixel = (this.endTime - this.startTime) / visibleWidth; 75 80 76 var visibleWidth = this.element.offsetWidth; 77 var secondsPerPixel = duration / visibleWidth; 81 var recordBarIndex = 0; 78 82 79 function updateElementPosition(element, newPosition, property)83 function createBar(rowElement, rowRecordBars, records, renderMode) 80 84 { 81 newPosition *= 100; 82 newPosition = newPosition.toFixed(2); 83 84 var currentPosition = parseFloat(element.style[property]).toFixed(2); 85 if (currentPosition !== newPosition) 86 element.style[property] = newPosition + "%"; 87 } 88 89 function createBar(barElementCache, rowElement, barStartTime, barEndTime, inactive) 90 { 91 if (barStartTime > currentTime) 92 return; 93 94 var barElement = barElementCache.shift(); 95 if (!barElement) { 96 barElement = document.createElement("div"); 97 barElement.classList.add(WebInspector.NetworkTimelineOverviewGraph.BarStyleClassName); 98 } 99 100 barElement.classList.toggle(WebInspector.NetworkTimelineOverviewGraph.InactiveBarStyleClassName, inactive); 101 102 if (barEndTime >= currentTime) { 103 barEndTime = currentTime; 104 barElement.classList.add(WebInspector.NetworkTimelineOverviewGraph.UnfinishedStyleClassName); 105 } else 106 barElement.classList.remove(WebInspector.NetworkTimelineOverviewGraph.UnfinishedStyleClassName); 107 108 if (inactive) { 109 var newBarRightPosition = 1 - ((barEndTime - startTime) / duration); 110 updateElementPosition(barElement, newBarRightPosition, "right"); 111 barElement.style.removeProperty("left"); 112 } else { 113 var newBarLeftPosition = (barStartTime - startTime) / duration; 114 updateElementPosition(barElement, newBarLeftPosition, "left"); 115 barElement.style.removeProperty("right"); 116 } 117 118 var newBarWidth = ((barEndTime - barStartTime) / duration); 119 updateElementPosition(barElement, newBarWidth, "width"); 120 121 if (!barElement.parendNode) 122 rowElement.appendChild(barElement); 85 var timelineRecordBar = rowRecordBars[recordBarIndex]; 86 if (!timelineRecordBar) 87 timelineRecordBar = rowRecordBars[recordBarIndex] = new WebInspector.TimelineRecordBar; 88 timelineRecordBar.renderMode = renderMode; 89 timelineRecordBar.records = records; 90 timelineRecordBar.refresh(this); 91 if (!timelineRecordBar.element.parentNode) 92 rowElement.appendChild(timelineRecordBar.element); 93 ++recordBarIndex; 123 94 } 124 95 125 96 for (var rowRecords of this._timelineRecordGridRows) { 126 var rowElement = rowRecords.__rowElement; 127 if (!rowElement) { 128 rowElement = rowRecords.__rowElement = document.createElement("div"); 129 rowElement.className = WebInspector.NetworkTimelineOverviewGraph.GraphRowStyleClassName; 130 this.element.appendChild(rowElement); 97 var rowElement = rowRecords.__element; 98 var rowRecordBars = rowRecords.__recordBars; 99 100 recordBarIndex = 0; 101 102 WebInspector.TimelineRecordBar.createCombinedBars(rowRecords, secondsPerPixel, this, createBar.bind(this, rowElement, rowRecordBars)); 103 104 // Remove the remaining unused TimelineRecordBars. 105 for (; recordBarIndex < rowRecordBars.length; ++recordBarIndex) { 106 rowRecordBars[recordBarIndex].records = null; 107 rowRecordBars[recordBarIndex].element.remove(); 131 108 } 132 133 if (!rowRecords.length)134 continue;135 136 // Save the current bar elements to reuse.137 var barElementCache = Array.prototype.slice.call(rowElement.childNodes);138 139 var inactiveStartTime = NaN;140 var inactiveEndTime = NaN;141 var activeStartTime = NaN;142 var activeEndTime = NaN;143 144 for (var record of rowRecords) {145 if (isNaN(record.startTime))146 continue;147 148 // If this bar is completely before the bounds of the graph, skip this record.149 if (record.endTime < startTime)150 continue;151 152 // If this record is completely after the current time or end time, break out now.153 // Records are sorted, so all records after this will be beyond the current or end time too.154 if (record.startTime > currentTime || record.startTime > endTime)155 break;156 157 // Check if the previous record is far enough away to create the inactive bar.158 if (!isNaN(inactiveStartTime) && inactiveEndTime + (secondsPerPixel * WebInspector.NetworkTimelineOverviewGraph.MinimumBarPaddingPixels) <= record.startTime) {159 createBar.call(this, barElementCache, rowElement, inactiveStartTime, inactiveEndTime, true);160 inactiveStartTime = NaN;161 inactiveEndTime = NaN;162 }163 164 // If this is a new bar, peg the start time.165 if (isNaN(inactiveStartTime))166 inactiveStartTime = record.startTime;167 168 // Update the end time to be the maximum we encounter. inactiveEndTime might be NaN, so "|| 0" to prevent Math.max from returning NaN.169 inactiveEndTime = Math.max(inactiveEndTime || 0, record.activeStartTime);170 171 // Check if the previous record is far enough away to create the active bar. We also create it now if the current record has no active state time.172 if (!isNaN(activeStartTime) && (activeEndTime + (secondsPerPixel * WebInspector.NetworkTimelineOverviewGraph.MinimumBarPaddingPixels) <= record.activeStartTime || isNaN(record.activeStartTime))) {173 if (!isNaN(activeEndTime)) {174 createBar.call(this, barElementCache, rowElement, activeStartTime, activeEndTime);175 activeStartTime = NaN;176 activeEndTime = NaN;177 }178 }179 180 if (isNaN(record.activeStartTime))181 continue;182 183 // If this is a new bar, peg the start time.184 if (isNaN(activeStartTime))185 activeStartTime = record.activeStartTime;186 187 // Update the end time to be the maximum we encounter. activeEndTime might be NaN, so "|| 0" to prevent Math.max from returning NaN.188 if (!isNaN(record.endTime))189 activeEndTime = Math.max(activeEndTime || 0, record.endTime);190 }191 192 // Create the inactive bar for the last record if needed.193 if (!isNaN(inactiveStartTime))194 createBar.call(this, barElementCache, rowElement, inactiveStartTime, inactiveEndTime || currentTime, true);195 196 // Create the active bar for the last record if needed.197 if (!isNaN(activeStartTime))198 createBar.call(this, barElementCache, rowElement, activeStartTime, activeEndTime || currentTime);199 200 // Remove any unused bar elements.201 for (var barElement of barElementCache)202 barElement.remove();203 109 } 204 110 }, -
trunk/Source/WebInspectorUI/UserInterface/ScriptTimelineOverviewGraph.js
r162419 r162681 59 59 WebInspector.TimelineOverviewGraph.prototype.updateLayout.call(this); 60 60 61 var startTime = this.startTime; 62 var currentTime = this.currentTime; 63 var endTime = this.endTime; 64 var duration = (endTime - startTime); 61 var visibleWidth = this.element.offsetWidth; 62 var secondsPerPixel = (this.endTime - this.startTime) / visibleWidth; 65 63 66 var visibleWidth = this.element.offsetWidth;67 var secondsPerPixel = duration / visibleWidth;68 64 var recordBarIndex = 0; 69 var barRecords = [];70 65 71 function createBar( barRecords)66 function createBar(records, renderMode) 72 67 { 73 68 var timelineRecordBar = this._timelineRecordBars[recordBarIndex]; 74 69 if (!timelineRecordBar) 75 70 timelineRecordBar = this._timelineRecordBars[recordBarIndex] = new WebInspector.TimelineRecordBar; 76 timelineRecordBar.records = barRecords; 71 timelineRecordBar.renderMode = renderMode; 72 timelineRecordBar.records = records; 77 73 timelineRecordBar.refresh(this); 78 74 if (!timelineRecordBar.element.parentNode) … … 81 77 } 82 78 83 for (var record of this._scriptTimeline.records) { 84 // If this bar is completely before the bounds of the graph, skip this record. 85 if (record.endTime < startTime) 86 continue; 87 88 // If this record is completely after the current time or end time, break out now. 89 // Records are sorted, so all records after this will be beyond the current or end time too. 90 if (record.startTime > currentTime || record.startTime > endTime) 91 break; 92 93 // Check if the previous record is a different type or far enough away to create the bar. 94 if (barRecords.length && WebInspector.TimelineRecordBar.recordsCannotBeCombined(barRecords, record, secondsPerPixel)) { 95 createBar.call(this, barRecords); 96 barRecords = []; 97 } 98 99 barRecords.push(record); 100 } 101 102 // Create the bar for the last record if needed. 103 if (barRecords.length) 104 createBar.call(this, barRecords); 79 WebInspector.TimelineRecordBar.createCombinedBars(this._scriptTimeline.records, secondsPerPixel, this, createBar.bind(this)); 105 80 106 81 // Remove the remaining unused TimelineRecordBars. -
trunk/Source/WebInspectorUI/UserInterface/TimelineDataGridNode.js
r162564 r162681 243 243 var recordBarIndex = 0; 244 244 245 function createBar( barRecords)245 function createBar(records, renderMode) 246 246 { 247 247 var timelineRecordBar = this._timelineRecordBars[recordBarIndex]; 248 248 if (!timelineRecordBar) 249 249 timelineRecordBar = this._timelineRecordBars[recordBarIndex] = new WebInspector.TimelineRecordBar; 250 timelineRecordBar.records = barRecords; 250 timelineRecordBar.renderMode = renderMode; 251 timelineRecordBar.records = records; 251 252 timelineRecordBar.refresh(this._graphDataSource); 252 253 if (!timelineRecordBar.element.parentNode) … … 255 256 } 256 257 257 function createBarsForRecords(records) 258 { 259 var barRecords = []; 260 261 for (var record of records) { 262 if (isNaN(record.startTime)) 263 continue; 264 265 // If this bar is completely before the bounds of the graph, skip this record. 266 if (record.endTime < startTime) 267 continue; 268 269 // If this record is completely after the current time or end time, break out now. 270 // Records are sorted, so all records after this will be beyond the current or end time too. 271 if (record.startTime > currentTime || record.startTime > endTime) 272 break; 273 274 // Check if the previous record can be combined with the current record, if not make a new bar. 275 if (barRecords.length && WebInspector.TimelineRecordBar.recordsCannotBeCombined(barRecords, record, secondsPerPixel)) { 276 createBar.call(this, barRecords); 277 barRecords = []; 278 } 279 280 barRecords.push(record); 281 } 282 283 // Create the bar for the last record if needed. 284 if (barRecords.length) 285 createBar.call(this, barRecords); 286 } 258 var boundCreateBar = createBar.bind(this); 287 259 288 260 if (this.expanded) { 289 261 // When expanded just use the records for this node. 290 createBarsForRecords.call(this, this.records);262 WebInspector.TimelineRecordBar.createCombinedBars(this.records, secondsPerPixel, this._graphDataSource, boundCreateBar); 291 263 } else { 292 264 // When collapsed use the records for this node and its descendants. … … 318 290 319 291 for (var records of recordTypeMap.values()) 320 createBarsForRecords.call(this, records);292 WebInspector.TimelineRecordBar.createCombinedBars(records, secondsPerPixel, this._graphDataSource, boundCreateBar); 321 293 } 322 294 -
trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.css
r162560 r162681 53 53 border-bottom-right-radius: 0 !important; 54 54 border-right: none; 55 margin-right: -1px;56 55 } 57 56 58 .timeline-record-bar > .segment.inactive + .segment{57 .timeline-record-bar.has-inactive-segment > .segment:not(.inactive) { 59 58 border-top-left-radius: 0 !important; 60 59 border-bottom-left-radius: 0 !important; … … 67 66 68 67 :focus .selected .timeline-record-bar > .segment.inactive { 69 opacity: 0.7;68 background-color: rgb(196, 215, 242) !important; 70 69 } 71 70 -
trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.js
r162560 r162681 24 24 */ 25 25 26 WebInspector.TimelineRecordBar = function(records )26 WebInspector.TimelineRecordBar = function(records, renderMode) 27 27 { 28 28 WebInspector.Object.call(this); … … 31 31 this._element.classList.add(WebInspector.TimelineRecordBar.StyleClassName); 32 32 33 this._activeBarElement = document.createElement("div"); 34 this._activeBarElement.classList.add(WebInspector.TimelineRecordBar.BarSegmentStyleClassName); 35 this._element.appendChild(this._activeBarElement); 36 33 this.renderMode = renderMode; 37 34 this.records = records; 38 35 }; … … 48 45 WebInspector.TimelineRecordBar.MinimumMarginPixels = 1; 49 46 50 WebInspector.TimelineRecordBar.recordsCannotBeCombined = function(records, candidateRecord, secondsPerPixel) 47 WebInspector.TimelineRecordBar.RenderMode = { 48 Normal: "timeline-record-bar-normal-render-mode", 49 InactiveOnly: "timeline-record-bar-inactive-only-render-mode", 50 ActiveOnly: "timeline-record-bar-active-only-render-mode" 51 }; 52 53 WebInspector.TimelineRecordBar.createCombinedBars = function(records, secondsPerPixel, graphDataSource, createBarCallback) 51 54 { 52 console.assert(records instanceof Array || records instanceof WebInspector.TimelineRecord);53 console.assert(candidateRecord instanceof WebInspector.TimelineRecord);54 55 if (records instanceof WebInspector.TimelineRecord)56 records = [records];57 58 55 if (!records.length) 59 return true; 60 61 if (candidateRecord.usesActiveStartTime) 62 return true; 63 64 var lastRecord = records.lastValue; 65 if (lastRecord.usesActiveStartTime) 66 return true; 67 68 if (lastRecord.type !== candidateRecord.type) 69 return true; 70 71 if (isNaN(candidateRecord.startTime)) 72 return true; 73 74 var firstRecord = records[0]; 75 var totalDuration = lastRecord.endTime - firstRecord.startTime; 76 77 var minimumMargin = WebInspector.TimelineRecordBar.MinimumMarginPixels * secondsPerPixel; 78 var minimumDuration = WebInspector.TimelineRecordBar.MinimumWidthPixels * secondsPerPixel; 79 80 return firstRecord.startTime + Math.max(minimumDuration, totalDuration) + minimumMargin <= candidateRecord.startTime; 56 return; 57 58 var startTime = graphDataSource.startTime; 59 var currentTime = graphDataSource.currentTime; 60 var endTime = graphDataSource.endTime; 61 62 var visibleRecords = []; 63 var usesActiveStartTime = false; 64 var lastRecordType = null; 65 66 // FIXME: Do a binary search for records that fall inside start and current time. 67 68 for (var record of records) { 69 if (isNaN(record.startTime)) 70 continue; 71 72 // If this bar is completely before the bounds of the graph, skip this record. 73 if (record.endTime < startTime) 74 continue; 75 76 // If this record is completely after the current time or end time, break out now. 77 // Records are sorted, so all records after this will be beyond the current or end time too. 78 if (record.startTime > currentTime || record.startTime > endTime) 79 break; 80 81 if (record.usesActiveStartTime) 82 usesActiveStartTime = true; 83 84 // If one record uses active time the rest are assumed to use it. 85 console.assert(record.usesActiveStartTime === usesActiveStartTime); 86 87 // Only a single record type is supported right now. 88 console.assert(!lastRecordType || record.type === lastRecordType); 89 90 visibleRecords.push(record); 91 92 lastRecordType = record.type; 93 } 94 95 if (!visibleRecords.length) 96 return; 97 98 if (visibleRecords.length === 1) { 99 createBarCallback(visibleRecords, WebInspector.TimelineRecordBar.RenderMode.Normal); 100 return; 101 } 102 103 function compareByActiveStartTime(a, b) 104 { 105 return a.activeStartTime - b.activeStartTime; 106 } 107 108 var minimumDuration = secondsPerPixel * WebInspector.TimelineRecordBar.MinimumWidthPixels; 109 var minimumMargin = secondsPerPixel * WebInspector.TimelineRecordBar.MinimumMarginPixels; 110 111 if (usesActiveStartTime) { 112 var inactiveStartTime = NaN; 113 var inactiveEndTime = NaN; 114 var inactiveRecords = []; 115 116 for (var record of visibleRecords) { 117 // Check if the previous record is far enough away to create the inactive bar. 118 if (!isNaN(inactiveStartTime) && inactiveStartTime + Math.max(inactiveEndTime - inactiveStartTime, minimumDuration) + minimumMargin <= record.startTime) { 119 createBarCallback(inactiveRecords, WebInspector.TimelineRecordBar.RenderMode.InactiveOnly); 120 inactiveRecords = []; 121 inactiveStartTime = NaN; 122 inactiveEndTime = NaN; 123 } 124 125 // If this is a new bar, peg the start time. 126 if (isNaN(inactiveStartTime)) 127 inactiveStartTime = record.startTime; 128 129 // Update the end time to be the maximum we encounter. inactiveEndTime might be NaN, so "|| 0" to prevent Math.max from returning NaN. 130 inactiveEndTime = Math.max(inactiveEndTime || 0, record.activeStartTime); 131 132 inactiveRecords.push(record); 133 } 134 135 // Create the inactive bar for the last record if needed. 136 if (!isNaN(inactiveStartTime)) 137 createBarCallback(inactiveRecords, WebInspector.TimelineRecordBar.RenderMode.InactiveOnly); 138 139 visibleRecords.sort(compareByActiveStartTime); 140 } 141 142 lastRecordType = null; 143 144 var activeStartTime = NaN; 145 var activeEndTime = NaN; 146 var activeRecords = []; 147 148 var startTimeProperty = usesActiveStartTime ? "activeStartTime" : "startTime"; 149 150 for (var record of visibleRecords) { 151 // Check if the previous record is far enough away to create the active bar. We also create it now if the current record has no active state time. 152 if (!isNaN(activeStartTime) && (activeStartTime + Math.max(activeEndTime - activeStartTime, minimumDuration) + minimumMargin <= record[startTimeProperty] 153 || (isNaN(record[startTimeProperty]) && !isNaN(activeEndTime)))) { 154 createBarCallback(activeRecords, WebInspector.TimelineRecordBar.RenderMode.ActiveOnly); 155 activeRecords = []; 156 activeStartTime = NaN; 157 activeEndTime = NaN; 158 } 159 160 if (isNaN(record[startTimeProperty])) 161 continue; 162 163 // If this is a new bar, peg the start time. 164 if (isNaN(activeStartTime)) 165 activeStartTime = record[startTimeProperty]; 166 167 // Update the end time to be the maximum we encounter. activeEndTime might be NaN, so "|| 0" to prevent Math.max from returning NaN. 168 if (!isNaN(record.endTime)) 169 activeEndTime = Math.max(activeEndTime || 0, record.endTime); 170 171 activeRecords.push(record); 172 } 173 174 // Create the active bar for the last record if needed. 175 if (!isNaN(activeStartTime)) 176 createBarCallback(activeRecords, WebInspector.TimelineRecordBar.RenderMode.ActiveOnly); 81 177 }; 82 178 … … 92 188 }, 93 189 190 get renderMode() 191 { 192 return this._renderMode; 193 }, 194 195 set renderMode(renderMode) 196 { 197 this._renderMode = renderMode || WebInspector.TimelineRecordBar.RenderMode.Normal; 198 }, 199 94 200 get records() 95 201 { … … 109 215 this._records = records; 110 216 111 // Combining multiple record bars is not supported with records that have inactive time. 112 console.assert(this._records.length <= 1 || !this._records[0].usesActiveStartTime); 113 114 // Inactive time is only supported with one record. 115 if (this._records.length === 1 && this._records[0].usesActiveStartTime) { 217 // Assume all records are the same type. 218 if (this._records.length) 219 this._element.classList.add(this._records[0].type); 220 }, 221 222 refresh: function(graphDataSource) 223 { 224 if (!this._records || !this._records.length) 225 return false; 226 227 var firstRecord = this._records[0]; 228 var barStartTime = firstRecord.startTime; 229 230 // If this bar has no time info, return early. 231 if (isNaN(barStartTime)) 232 return false; 233 234 var graphStartTime = graphDataSource.startTime; 235 var graphEndTime = graphDataSource.endTime; 236 var graphCurrentTime = graphDataSource.currentTime; 237 238 var barEndTime = this._records.reduce(function(previousValue, currentValue) { return Math.max(previousValue, currentValue.endTime); }, 0); 239 240 // If this bar is completely after the current time, return early. 241 if (barStartTime > graphCurrentTime) 242 return false; 243 244 // If this bar is completely before or after the bounds of the graph, return early. 245 if (barEndTime < graphStartTime || barStartTime > graphEndTime) 246 return false; 247 248 var barUnfinished = isNaN(barEndTime) || barEndTime >= graphCurrentTime; 249 if (barUnfinished) 250 barEndTime = graphCurrentTime; 251 252 var graphDuration = graphEndTime - graphStartTime; 253 254 this._element.classList.toggle(WebInspector.TimelineRecordBar.UnfinishedStyleClassName, barUnfinished); 255 256 var newBarLeftPosition = (barStartTime - graphStartTime) / graphDuration; 257 this._updateElementPosition(this._element, newBarLeftPosition, "left"); 258 259 var newBarWidth = ((barEndTime - graphStartTime) / graphDuration) - newBarLeftPosition; 260 this._updateElementPosition(this._element, newBarWidth, "width"); 261 262 if (!this._activeBarElement && this._renderMode !== WebInspector.TimelineRecordBar.RenderMode.InactiveOnly) { 263 this._activeBarElement = document.createElement("div"); 264 this._activeBarElement.classList.add(WebInspector.TimelineRecordBar.BarSegmentStyleClassName); 265 } 266 267 if (!firstRecord.usesActiveStartTime) { 268 this._element.classList.remove(WebInspector.TimelineRecordBar.HasInactiveSegmentStyleClassName); 269 270 if (this._inactiveBarElement) 271 this._inactiveBarElement.remove(); 272 273 if (this._renderMode === WebInspector.TimelineRecordBar.RenderMode.InactiveOnly) { 274 if (this._activeBarElement) 275 this._activeBarElement.remove(); 276 277 return false; 278 } 279 280 // If this TimelineRecordBar is reused and had an inactive bar previously, clean it up. 281 this._activeBarElement.style.removeProperty("left"); 282 this._activeBarElement.style.removeProperty("width"); 283 284 if (!this._activeBarElement.parentNode) 285 this._element.appendChild(this._activeBarElement); 286 287 return true; 288 } 289 290 this._element.classList.add(WebInspector.TimelineRecordBar.HasInactiveSegmentStyleClassName); 291 292 // Find the earliest active start time for active only rendering, and the latest for the other modes. 293 // This matches the values that TimelineRecordBar.createCombinedBars uses when combining. 294 if (this._renderMode === WebInspector.TimelineRecordBar.RenderMode.ActiveOnly) 295 var barActiveStartTime = this._records.reduce(function(previousValue, currentValue) { return Math.min(previousValue, currentValue.activeStartTime); }, Infinity); 296 else 297 var barActiveStartTime = this._records.reduce(function(previousValue, currentValue) { return Math.max(previousValue, currentValue.activeStartTime); }, 0); 298 299 var barDuration = barEndTime - barStartTime; 300 301 var inactiveUnfinished = isNaN(barActiveStartTime) || barActiveStartTime >= graphCurrentTime; 302 this._element.classList.toggle(WebInspector.TimelineRecordBar.UnfinishedStyleClassName, inactiveUnfinished); 303 304 if (inactiveUnfinished) 305 barActiveStartTime = graphCurrentTime; 306 307 var middlePercentage = (barActiveStartTime - barStartTime) / barDuration; 308 309 if (this._renderMode !== WebInspector.TimelineRecordBar.RenderMode.ActiveOnly) { 116 310 if (!this._inactiveBarElement) { 117 311 this._inactiveBarElement = document.createElement("div"); 118 312 this._inactiveBarElement.classList.add(WebInspector.TimelineRecordBar.BarSegmentStyleClassName); 119 313 this._inactiveBarElement.classList.add(WebInspector.TimelineRecordBar.InactiveStyleClassName); 120 this._element.classList.add(WebInspector.TimelineRecordBar.HasInactiveSegmentStyleClassName); 314 } 315 316 this._updateElementPosition(this._inactiveBarElement, 1 - middlePercentage, "right"); 317 this._updateElementPosition(this._inactiveBarElement, middlePercentage, "width"); 318 319 if (!this._inactiveBarElement.parentNode) 121 320 this._element.insertBefore(this._inactiveBarElement, this._element.firstChild); 122 } 123 } else if (this._inactiveBarElement) { 124 this._element.classList.remove(WebInspector.TimelineRecordBar.HasInactiveSegmentStyleClassName); 125 this._inactiveBarElement.remove(); 126 delete this._inactiveBarElement; 127 } 128 129 // Assume all records are the same type. 130 if (this._records.length) 131 this._element.classList.add(this._records[0].type); 132 }, 133 134 refresh: function(graphDataSource) 135 { 136 if (!this._records || !this._records.length) 137 return; 138 139 var firstRecord = this._records[0]; 140 var barStartTime = firstRecord.startTime; 141 142 // If this bar has no time info, return early. 143 if (isNaN(barStartTime)) 144 return false; 145 146 var graphStartTime = graphDataSource.startTime; 147 var graphEndTime = graphDataSource.endTime; 148 var graphCurrentTime = graphDataSource.currentTime; 149 150 var lastRecord = this._records.lastValue; 151 var barEndTime = lastRecord.endTime; 152 153 // If this bar is completely after the current time, return early. 154 if (barStartTime > graphCurrentTime) 155 return false; 156 157 // If this bar is completely before or after the bounds of the graph, return early. 158 if (barEndTime < graphStartTime || barStartTime > graphEndTime) 159 return false; 160 161 var barUnfinished = isNaN(barEndTime) || barEndTime >= graphCurrentTime; 162 if (barUnfinished) 163 barEndTime = graphCurrentTime; 164 165 var graphDuration = graphEndTime - graphStartTime; 166 167 this._element.classList.toggle(WebInspector.TimelineRecordBar.UnfinishedStyleClassName, barUnfinished); 168 169 var newBarLeftPosition = (barStartTime - graphStartTime) / graphDuration; 170 this._updateElementPosition(this._element, newBarLeftPosition, "left"); 171 172 var newBarWidth = ((barEndTime - graphStartTime) / graphDuration) - newBarLeftPosition; 173 this._updateElementPosition(this._element, newBarWidth, "width"); 174 175 if (!this._inactiveBarElement) { 176 // If this TimelineRecordBar is reused and had an inactive bar previously, 177 // we might need to remove some styles and add the active element back. 178 this._activeBarElement.style.removeProperty("left"); 179 this._activeBarElement.style.removeProperty("width"); 321 } 322 323 if (!inactiveUnfinished && this._renderMode !== WebInspector.TimelineRecordBar.RenderMode.InactiveOnly) { 324 this._updateElementPosition(this._activeBarElement, middlePercentage, "left"); 325 this._updateElementPosition(this._activeBarElement, 1 - middlePercentage, "width"); 326 180 327 if (!this._activeBarElement.parentNode) 181 328 this._element.appendChild(this._activeBarElement); 182 return true; 183 } 184 185 console.assert(firstRecord === lastRecord); 186 187 var barActiveStartTime = Math.max(barStartTime, Math.min(firstRecord.activeStartTime, barEndTime)); 188 var barDuration = barEndTime - barStartTime; 189 190 var inactiveUnfinished = isNaN(barActiveStartTime) || barActiveStartTime >= graphCurrentTime; 191 this._element.classList.toggle(WebInspector.TimelineRecordBar.UnfinishedStyleClassName, inactiveUnfinished); 192 193 if (inactiveUnfinished) 194 barActiveStartTime = graphCurrentTime; 195 196 var middlePercentage = (barActiveStartTime - barStartTime) / barDuration; 197 198 this._updateElementPosition(this._inactiveBarElement, 1 - middlePercentage, "right"); 199 this._updateElementPosition(this._inactiveBarElement, middlePercentage, "width"); 200 201 if (!inactiveUnfinished) { 202 if (!this._activeBarElement.parentNode) 203 this._element.appendChild(this._activeBarElement); 204 205 this._updateElementPosition(this._activeBarElement, middlePercentage, "left"); 206 this._updateElementPosition(this._activeBarElement, 1 - middlePercentage, "width"); 207 } else 329 } else if (this._activeBarElement) 208 330 this._activeBarElement.remove(); 209 331
Note: See TracChangeset
for help on using the changeset viewer.