Changeset 203843 in webkit
- Timestamp:
- Jul 28, 2016 2:38:50 PM (8 years ago)
- Location:
- trunk/Source/WebInspectorUI
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebInspectorUI/ChangeLog
r203840 r203843 1 2016-07-28 Johan K. Jensen <johan_jensen@apple.com> 2 3 Web Inspector: Waterfall view should be visible in Network tab and Network Timeline 4 https://bugs.webkit.org/show_bug.cgi?id=160061 5 6 Reviewed by Joseph Pecoraro. 7 8 Adds a Timeline-column (waterfall) to the Network tab and Network Timeline. 9 10 * Localizations/en.lproj/localizedStrings.js: 11 Add "Timeline" localized string. 12 13 * UserInterface/Views/NetworkGridContentView.js: 14 (WebInspector.NetworkGridContentView): 15 Add the Timeline-column with a TimelineRuler as the headerview, 16 and properties for updating current time. 17 18 (WebInspector.NetworkGridContentView.prototype.get secondsPerPixel): 19 (WebInspector.NetworkGridContentView.prototype.get startTime): 20 (WebInspector.NetworkGridContentView.prototype.get currentTime): 21 (WebInspector.NetworkGridContentView.prototype.get endTime): 22 Acting as a graphDataSource used by TimelineDataGridNode. 23 24 (WebInspector.NetworkGridContentView.prototype.shown): 25 (WebInspector.NetworkGridContentView.prototype.reset): 26 (WebInspector.NetworkGridContentView.prototype.layout): 27 Refresh graphs and update the TimelineRuler on layout changes. 28 29 (WebInspector.NetworkGridContentView.prototype._networkTimelineRecordAdded): 30 Add listeners for when resources are finished to stop the timer. 31 32 (WebInspector.NetworkGridContentView.prototype._update): 33 (WebInspector.NetworkGridContentView.prototype._startUpdatingCurrentTime): 34 (WebInspector.NetworkGridContentView.prototype._stopUpdatingCurrentTime): 35 Adding a timer which updates the TimelineRuler and the layout 36 if any non-finished requests are running. 37 38 * UserInterface/Views/NetworkTimelineView.js: 39 (WebInspector.NetworkTimelineView): 40 Add the Timeline-column with a TimelineRuler as the headerview. 41 42 (WebInspector.NetworkTimelineView.prototype.get secondsPerPixel): 43 (WebInspector.NetworkTimelineView.prototype.layout): 44 Refresh graphs on layout changes. 45 46 * UserInterface/Views/TimelineDataGrid.css: 47 (.tree-outline.timeline-data-grid .item:hover .subtitle): 48 (.data-grid.timeline th): 49 (.data-grid.timeline th.graph-column > .timeline-ruler): 50 (.data-grid.timeline td.graph-column): 51 (.data-grid.timeline td.graph-column > .cell-content): 52 (.data-grid.timeline td.graph-column .timeline-record-bar): 53 1 54 2016-07-28 Chris Dumez <cdumez@apple.com> 2 55 -
trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js
r203132 r203843 707 707 localizedStrings["Time"] = "Time"; 708 708 localizedStrings["Time until the load event fired, click to show the Network Requests timeline"] = "Time until the load event fired, click to show the Network Requests timeline"; 709 localizedStrings["Timeline"] = "Timeline"; 709 710 localizedStrings["Timeline Recording %d"] = "Timeline Recording %d"; 710 711 localizedStrings["Timelines"] = "Timelines"; -
trunk/Source/WebInspectorUI/UserInterface/Views/NetworkGridContentView.js
r202133 r203843 38 38 this._contentTreeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this); 39 39 40 var columns = {domain: {}, type: {}, method: {}, scheme: {}, statusCode: {}, cached: {}, size: {}, transferSize: {}, requestSent: {}, latency: {}, duration: {} };40 var columns = {domain: {}, type: {}, method: {}, scheme: {}, statusCode: {}, cached: {}, size: {}, transferSize: {}, requestSent: {}, latency: {}, duration: {}, graph: {}}; 41 41 42 42 columns.domain.title = WebInspector.UIString("Domain"); … … 80 80 for (var column in columns) 81 81 columns[column].sortable = true; 82 83 this._timelineRuler = new WebInspector.TimelineRuler; 84 this._timelineRuler.allowsClippedLabels = true; 85 86 columns.graph.title = WebInspector.UIString("Timeline"); 87 columns.graph.width = "15%"; 88 columns.graph.headerView = this._timelineRuler; 89 columns.graph.sortable = false; 82 90 83 91 this._dataGrid = new WebInspector.TimelineDataGrid(columns, this._contentTreeOutline); … … 98 106 99 107 this._pendingRecords = []; 108 this._loadingResourceCount = 0; 109 this._lastUpdateTimestamp = NaN; 110 this._scheduledCurrentTimeUpdateIdentifier = undefined; 100 111 } 101 112 102 113 // Public 114 115 get secondsPerPixel() { return this._timelineRuler.secondsPerPixel; } 116 get startTime() { return this._timelineRuler.startTime; } 117 get currentTime() { return this.endTime || this.startTime; } 118 get endTime() { return this._timelineRuler.endTime; } 103 119 104 120 get selectionPathComponents() … … 127 143 128 144 this._dataGrid.shown(); 145 146 if (this._loadingResourceCount && !this._scheduledCurrentTimeUpdateIdentifier) 147 this._startUpdatingCurrentTime(); 129 148 } 130 149 … … 145 164 this._contentTreeOutline.removeChildren(); 146 165 this._dataGrid.reset(); 166 167 if (this._scheduledCurrentTimeUpdateIdentifier) 168 this._stopUpdatingCurrentTime(); 169 170 this._loadingResourceCount = 0; 171 this._lastUpdateTimestamp = NaN; 172 173 this._timelineRuler.startTime = 0; 174 this._timelineRuler.endTime = 0; 147 175 } 148 176 … … 151 179 layout() 152 180 { 181 this._timelineRuler.zeroTime = this.zeroTime; 182 this._timelineRuler.startTime = this.zeroTime; 183 184 for (let dataGridNode of this._dataGrid.children) 185 dataGridNode.refreshGraph(); 186 153 187 this._processPendingRecords(); 154 188 } … … 186 220 console.assert(resourceTimelineRecord instanceof WebInspector.ResourceTimelineRecord); 187 221 222 let update = (event) => { 223 if (event.target[WebInspector.NetworkGridContentView.ResourceDidFinishOrFail]) 224 return; 225 226 event.target.removeEventListener(null, null, this); 227 event.target[WebInspector.NetworkGridContentView.ResourceDidFinishOrFail] = true; 228 229 this._loadingResourceCount--; 230 if (this._loadingResourceCount) 231 return; 232 233 this.debounce(250)._stopUpdatingCurrentTime(); 234 }; 235 188 236 this._pendingRecords.push(resourceTimelineRecord); 189 237 190 238 this.needsLayout(); 239 240 let resource = resourceTimelineRecord.resource; 241 if (resource.finished || resource.failed || resource.canceled) 242 return; 243 244 resource[WebInspector.NetworkGridContentView.ResourceDidFinishOrFail] = false; 245 resource.addEventListener(WebInspector.Resource.Event.LoadingDidFinish, update, this); 246 resource.addEventListener(WebInspector.Resource.Event.LoadingDidFail, update, this); 247 248 this._loadingResourceCount++; 249 if (this._loadingResourceCount && !this._scheduledCurrentTimeUpdateIdentifier) 250 this._startUpdatingCurrentTime(); 191 251 } 192 252 … … 223 283 this.reset(); 224 284 } 285 286 _update(timestamp) 287 { 288 console.assert(this._scheduledCurrentTimeUpdateIdentifier); 289 290 let startTime = this.startTime; 291 let currentTime = this.currentTime; 292 let endTime = this.endTime; 293 let timespanSinceLastUpdate = (timestamp - this._lastUpdateTimestamp) / 1000 || 0; 294 295 currentTime += timespanSinceLastUpdate; 296 297 this._timelineRuler.endTime = currentTime; 298 this._lastUpdateTimestamp = timestamp; 299 this.updateLayout(); 300 301 this._scheduledCurrentTimeUpdateIdentifier = requestAnimationFrame(this._updateCallback); 302 } 303 304 _startUpdatingCurrentTime() 305 { 306 console.assert(!this._scheduledCurrentTimeUpdateIdentifier); 307 if (this._scheduledCurrentTimeUpdateIdentifier) 308 return; 309 310 // Don't update the current time if the Inspector is not visible, as the requestAnimationFrames won't work. 311 if (!WebInspector.visible) 312 return; 313 314 if (!this._updateCallback) 315 this._updateCallback = this._update.bind(this); 316 317 this._scheduledCurrentTimeUpdateIdentifier = requestAnimationFrame(this._updateCallback); 318 } 319 320 _stopUpdatingCurrentTime() 321 { 322 console.assert(this._scheduledCurrentTimeUpdateIdentifier); 323 if (!this._scheduledCurrentTimeUpdateIdentifier) 324 return; 325 326 cancelAnimationFrame(this._scheduledCurrentTimeUpdateIdentifier); 327 this._scheduledCurrentTimeUpdateIdentifier = undefined; 328 } 225 329 }; 330 331 WebInspector.NetworkGridContentView.ResourceDidFinishOrFail = Symbol("ResourceDidFinishOrFail"); -
trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTimelineView.js
r202133 r203843 32 32 console.assert(timeline.type === WebInspector.TimelineRecord.Type.Network); 33 33 34 let columns = {name: {}, domain: {}, type: {}, method: {}, scheme: {}, statusCode: {}, cached: {}, size: {}, transferSize: {}, requestSent: {}, latency: {}, duration: {} };34 let columns = {name: {}, domain: {}, type: {}, method: {}, scheme: {}, statusCode: {}, cached: {}, size: {}, transferSize: {}, requestSent: {}, latency: {}, duration: {}, graph: {}}; 35 35 36 36 columns.name.title = WebInspector.UIString("Name"); … … 40 40 41 41 columns.domain.title = WebInspector.UIString("Domain"); 42 columns.domain.width = " 10%";42 columns.domain.width = "8%"; 43 43 44 44 columns.type.title = WebInspector.UIString("Type"); 45 columns.type.width = " 8%";45 columns.type.width = "7%"; 46 46 47 47 var typeToLabelMap = new Map; … … 55 55 56 56 columns.method.title = WebInspector.UIString("Method"); 57 columns.method.width = " 6%";57 columns.method.width = "4%"; 58 58 59 59 columns.scheme.title = WebInspector.UIString("Scheme"); 60 columns.scheme.width = " 6%";60 columns.scheme.width = "4%"; 61 61 62 62 columns.statusCode.title = WebInspector.UIString("Status"); 63 columns.statusCode.width = " 6%";63 columns.statusCode.width = "4%"; 64 64 65 65 columns.cached.title = WebInspector.UIString("Cached"); 66 columns.cached.width = " 6%";66 columns.cached.width = "4%"; 67 67 68 68 columns.size.title = WebInspector.UIString("Size"); … … 88 88 for (var column in columns) 89 89 columns[column].sortable = true; 90 91 this._timelineRuler = new WebInspector.TimelineRuler; 92 this._timelineRuler.allowsClippedLabels = true; 93 94 columns.graph.title = WebInspector.UIString("Timeline"); 95 columns.graph.width = "15%"; 96 columns.graph.headerView = this._timelineRuler; 97 columns.graph.sortable = false; 90 98 91 99 this._dataGrid = new WebInspector.TimelineDataGrid(columns); … … 108 116 // Public 109 117 118 get secondsPerPixel() { return this._timelineRuler.secondsPerPixel; } 119 110 120 get selectionPathComponents() 111 121 { … … 198 208 layout() 199 209 { 210 this.endTime = Math.min(this.endTime, this.currentTime); 211 212 this._timelineRuler.zeroTime = this.zeroTime; 213 this._timelineRuler.startTime = this.startTime; 214 this._timelineRuler.endTime = this.endTime; 215 216 for (let dataGridNode of this._resourceDataGridNodeMap.values()) 217 dataGridNode.refreshGraph(); 218 200 219 this._processPendingRecords(); 201 220 } -
trunk/Source/WebInspectorUI/UserInterface/Views/TimelineDataGrid.css
r201538 r203843 37 37 color: white; 38 38 } 39 40 .data-grid.timeline th { 41 border-top: none; 42 } 43 44 .data-grid.timeline th.graph-column > .timeline-ruler { 45 position: absolute; 46 top: 0; 47 bottom: 0; 48 } 49 50 .data-grid.timeline td.graph-column { 51 padding: 2px 0; 52 } 53 54 .data-grid.timeline td.graph-column > .cell-content { 55 position: relative; 56 } 57 58 .data-grid.timeline td.graph-column .timeline-record-bar { 59 top: 2px; 60 }
Note: See TracChangeset
for help on using the changeset viewer.