Changeset 181626 in webkit
- Timestamp:
- Mar 17, 2015 1:43:30 AM (9 years ago)
- Location:
- trunk/Source/WebInspectorUI
- Files:
-
- 9 added
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebInspectorUI/ChangeLog
r181614 r181626 1 2015-03-17 Matt Baker <mattbaker@apple.com> 2 3 Web Inspector: Show rendering frames (and FPS) in Layout and Rendering timeline 4 https://bugs.webkit.org/show_bug.cgi?id=142029 5 6 Reviewed by Timothy Hatcher. 7 8 Add UI for showing runloop records and their child records as a frame histogram, 9 with the recording time on the x-axis and the frame duration on the y-axis. Each frame 10 is comprised of colored regions representing the time spent in various activities (script, 11 layout, etc). 12 13 Eventually the Frames timeline will replace the Layout & Rendering timeline. Until the views 14 for the new timeline are finalized the Layout & Rendering timeline will remain in place. 15 16 * Localizations/en.lproj/localizedStrings.js: 17 * UserInterface/Main.html: 18 New string and files. 19 20 * UserInterface/Controllers/TimelineManager.js: 21 (WebInspector.TimelineManager.prototype.eventRecorded): 22 (WebInspector.TimelineManager.prototype.pageDidLoad): 23 (WebInspector.TimelineManager.prototype._processNestedRecords): 24 (WebInspector.TimelineManager.prototype._processRecord): 25 (WebInspector.TimelineManager.prototype._processEvent): 26 (WebInspector.TimelineManager.prototype._loadNewRecording): 27 (WebInspector.TimelineManager.prototype.eventRecorded.processRecord): Deleted. 28 Added support for new runloop record type and nested record handling. 29 30 * UserInterface/Images/Frames.png: Added. 31 * UserInterface/Images/Frames@2x.png: Added. 32 * UserInterface/Images/FramesLarge.png: Added. 33 * UserInterface/Images/FramesLarge@2x.png: Added. 34 New images for runloop timeline overview graph and runloop tree records. 35 36 * UserInterface/Models/RunLoopTimelineRecord.js: Added. 37 (WebInspector.RunLoopTimelineRecord): 38 (WebInspector.RunLoopTimelineRecord.prototype.get children): 39 (WebInspector.RunLoopTimelineRecord.prototype.get durationRemainder): 40 (WebInspector.RunLoopTimelineRecord.prototype.durationForRecords.get var): 41 Extends TimelineRecord to add child records and subframe duration details. 42 43 * UserInterface/Models/Timeline.js: 44 (WebInspector.Timeline.prototype.get displayName): 45 (WebInspector.Timeline.prototype.get iconClassName): 46 New UI strings and icons. 47 48 * UserInterface/Models/TimelineRecord.js: 49 * UserInterface/Views/ContentView.js: 50 (WebInspector.ContentView): 51 * UserInterface/Views/LayoutTimelineView.js: 52 (WebInspector.LayoutTimelineView.prototype._layoutTimelineRecordAdded): 53 * UserInterface/Views/TimelineRecordTreeElement.js: 54 (WebInspector.TimelineRecordTreeElement): 55 Added support for new runloop record type. 56 57 * UserInterface/Views/RunLoopTimelineOverviewGraph.css: Added. 58 (.timeline-overview-graph.runloop > .divider): 59 (.timeline-overview-graph.runloop > .divider > span): 60 New styles for runloop timeline graph. 61 62 * UserInterface/Views/RunLoopTimelineOverviewGraph.js: Added. 63 (WebInspector.RunLoopTimelineOverviewGraph): 64 (WebInspector.RunLoopTimelineOverviewGraph.prototype.updateLayout.createFrame): 65 (WebInspector.RunLoopTimelineOverviewGraph.prototype.get graphHeightSeconds.this): 66 (WebInspector.RunLoopTimelineOverviewGraph.prototype.get graphHeightSeconds): 67 (WebInspector.RunLoopTimelineOverviewGraph.prototype._updateDividers.createDividerAtPosition.get if): 68 New overview graph for displaying TimelineRecordFrames and horizontal frame budget dividers. 69 70 * UserInterface/Views/TimelineIcons.css: 71 (.runloop-icon .icon): 72 (.runloop-icon.large .icon): 73 (.runloop-record .icon): 74 * UserInterface/Views/TimelineSidebarPanel.js: 75 New runloop icon styles. 76 77 * UserInterface/Views/TimelineOverviewGraph.js: 78 (WebInspector.TimelineOverviewGraph): 79 Updated factory to support creation of the new overview graph. 80 81 * UserInterface/Views/TimelineRecordFrame.css: Added. 82 (.timeline-record-frame): 83 (.timeline-record-frame > .frame): 84 (.timeline-record-frame > .dropped): 85 (.timeline-record-frame > .frame > .duration): 86 (.timeline-record-frame > .frame > .duration:first-child): 87 (.timeline-record-frame > .frame > .duration:last-child): 88 (.timeline-record-frame > .frame > .duration.timeline-record-type-network): 89 (.timeline-record-frame > .frame > .duration.timeline-record-type-layout): 90 (.timeline-record-frame > .frame > .duration.timeline-record-type-script): 91 New styles for frame bars in the runloop timeline graph. 92 93 * UserInterface/Views/TimelineRecordFrame.js: Added. 94 (WebInspector.TimelineRecordFrame): 95 (WebInspector.TimelineRecordFrame.createCombinedFrames): 96 (WebInspector.TimelineRecordFrame.prototype.get element): 97 (WebInspector.TimelineRecordFrame.prototype.get duration): 98 (WebInspector.TimelineRecordFrame.prototype.get records): 99 (WebInspector.TimelineRecordFrame.prototype.set records): 100 (WebInspector.TimelineRecordFrame.prototype._updateChildElements.createDurationElement): 101 New view representing a single frame within the runloop overview graph. 102 103 * WebInspectorUI.vcxproj/WebInspectorUI.vcxproj: 104 * WebInspectorUI.vcxproj/WebInspectorUI.vcxproj.filters: 105 New files. 106 1 107 2015-03-16 Joseph Pecoraro <pecoraro@apple.com> 2 108 -
trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js
r181452 r181626 398 398 localizedStrings["Role"] = "Role"; 399 399 localizedStrings["Rules"] = "Rules"; 400 localizedStrings["Runloop Executed"] = "Runloop Executed"; 400 401 localizedStrings["Scheme"] = "Scheme"; 401 402 localizedStrings["Scope Chain"] = "Scope Chain"; -
trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js
r181185 r181626 163 163 }, 164 164 165 eventRecorded: function( originalRecordPayload)165 eventRecorded: function(recordPayload) 166 166 { 167 167 // Called from WebInspector.TimelineObserver. … … 170 170 return; 171 171 172 function processRecord(recordPayload, parentRecordPayload) 173 { 174 var startTime = this.activeRecording.computeElapsedTime(recordPayload.startTime); 175 var endTime = this.activeRecording.computeElapsedTime(recordPayload.endTime); 176 var callFrames = this._callFramesFromPayload(recordPayload.stackTrace); 177 178 var significantCallFrame = null; 179 if (callFrames) { 180 for (var i = 0; i < callFrames.length; ++i) { 181 if (callFrames[i].nativeCode) 182 continue; 183 significantCallFrame = callFrames[i]; 184 break; 185 } 186 } 187 188 var sourceCodeLocation = significantCallFrame && significantCallFrame.sourceCodeLocation; 189 190 switch (recordPayload.type) { 191 case TimelineAgent.EventType.MarkLoad: 192 console.assert(isNaN(endTime)); 193 194 var frame = WebInspector.frameResourceManager.frameForIdentifier(recordPayload.frameId); 195 console.assert(frame); 196 if (!frame) 197 break; 198 199 frame.markLoadEvent(startTime); 200 201 if (!frame.isMainFrame()) 202 break; 203 204 var eventMarker = new WebInspector.TimelineMarker(startTime, WebInspector.TimelineMarker.Type.LoadEvent); 205 this._activeRecording.addEventMarker(eventMarker); 206 207 this._stopAutoRecordingSoon(); 208 break; 209 210 case TimelineAgent.EventType.MarkDOMContent: 211 console.assert(isNaN(endTime)); 212 213 var frame = WebInspector.frameResourceManager.frameForIdentifier(recordPayload.frameId); 214 console.assert(frame); 215 if (!frame) 216 break; 217 218 frame.markDOMContentReadyEvent(startTime); 219 220 if (!frame.isMainFrame()) 221 break; 222 223 var eventMarker = new WebInspector.TimelineMarker(startTime, WebInspector.TimelineMarker.Type.DOMContentEvent); 224 this._activeRecording.addEventMarker(eventMarker); 225 break; 226 227 case TimelineAgent.EventType.ScheduleStyleRecalculation: 228 console.assert(isNaN(endTime)); 229 230 // Pass the startTime as the endTime since this record type has no duration. 231 this._addRecord(new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.InvalidateStyles, startTime, startTime, callFrames, sourceCodeLocation)); 232 break; 233 234 case TimelineAgent.EventType.RecalculateStyles: 235 this._addRecord(new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.RecalculateStyles, startTime, endTime, callFrames, sourceCodeLocation)); 236 break; 237 238 case TimelineAgent.EventType.InvalidateLayout: 239 console.assert(isNaN(endTime)); 240 241 // Pass the startTime as the endTime since this record type has no duration. 242 this._addRecord(new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.InvalidateLayout, startTime, startTime, callFrames, sourceCodeLocation)); 243 break; 244 245 case TimelineAgent.EventType.Layout: 246 var layoutRecordType = sourceCodeLocation ? WebInspector.LayoutTimelineRecord.EventType.ForcedLayout : WebInspector.LayoutTimelineRecord.EventType.Layout; 247 248 // COMPATIBILITY (iOS 6): Layout records did not contain area properties. This is not exposed via a quad "root". 249 var quad = recordPayload.data.root ? new WebInspector.Quad(recordPayload.data.root) : null; 250 if (quad) 251 this._addRecord(new WebInspector.LayoutTimelineRecord(layoutRecordType, startTime, endTime, callFrames, sourceCodeLocation, quad.points[0].x, quad.points[0].y, quad.width, quad.height, quad)); 252 else 253 this._addRecord(new WebInspector.LayoutTimelineRecord(layoutRecordType, startTime, endTime, callFrames, sourceCodeLocation)); 254 break; 255 256 case TimelineAgent.EventType.Paint: 257 // COMPATIBILITY (iOS 6): Paint records data contained x, y, width, height properties. This became a quad "clip". 258 var quad = recordPayload.data.clip ? new WebInspector.Quad(recordPayload.data.clip) : null; 259 if (quad) 260 this._addRecord(new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.Paint, startTime, endTime, callFrames, sourceCodeLocation, null, null, quad.width, quad.height, quad)); 261 else 262 this._addRecord(new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.Paint, startTime, endTime, callFrames, sourceCodeLocation, recordPayload.data.x, recordPayload.data.y, recordPayload.data.width, recordPayload.data.height)); 263 break; 264 265 case TimelineAgent.EventType.EvaluateScript: 266 if (!sourceCodeLocation) { 267 var mainFrame = WebInspector.frameResourceManager.mainFrame; 268 var scriptResource = mainFrame.url === recordPayload.data.url ? mainFrame.mainResource : mainFrame.resourceForURL(recordPayload.data.url, true); 269 if (scriptResource) { 270 // The lineNumber is 1-based, but we expect 0-based. 271 var lineNumber = recordPayload.data.lineNumber - 1; 272 273 // FIXME: No column number is provided. 274 sourceCodeLocation = scriptResource.createSourceCodeLocation(lineNumber, 0); 275 } 276 } 277 278 var profileData = recordPayload.data.profile; 279 280 switch (parentRecordPayload && parentRecordPayload.type) { 281 case TimelineAgent.EventType.TimerFire: 282 this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.TimerFired, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.timerId, profileData)); 283 break; 284 default: 285 this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.ScriptEvaluated, startTime, endTime, callFrames, sourceCodeLocation, null, profileData)); 286 break; 287 } 288 289 break; 290 291 case TimelineAgent.EventType.TimeStamp: 292 var eventMarker = new WebInspector.TimelineMarker(startTime, WebInspector.TimelineMarker.Type.TimeStamp); 293 this._activeRecording.addEventMarker(eventMarker); 294 break; 295 296 case TimelineAgent.EventType.ConsoleProfile: 297 var profileData = recordPayload.data.profile; 298 console.assert(profileData); 299 this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.ConsoleProfileRecorded, startTime, endTime, callFrames, sourceCodeLocation, recordPayload.data.title, profileData)); 300 break; 301 302 case TimelineAgent.EventType.FunctionCall: 303 // FunctionCall always happens as a child of another record, and since the FunctionCall record 304 // has useful info we just make the timeline record here (combining the data from both records). 305 if (!parentRecordPayload) 306 break; 307 308 if (!sourceCodeLocation) { 309 var mainFrame = WebInspector.frameResourceManager.mainFrame; 310 var scriptResource = mainFrame.url === recordPayload.data.scriptName ? mainFrame.mainResource : mainFrame.resourceForURL(recordPayload.data.scriptName, true); 311 if (scriptResource) { 312 // The lineNumber is 1-based, but we expect 0-based. 313 var lineNumber = recordPayload.data.scriptLine - 1; 314 315 // FIXME: No column number is provided. 316 sourceCodeLocation = scriptResource.createSourceCodeLocation(lineNumber, 0); 317 } 318 } 319 320 var profileData = recordPayload.data.profile; 321 322 switch (parentRecordPayload.type) { 323 case TimelineAgent.EventType.TimerFire: 324 this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.TimerFired, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.timerId, profileData)); 325 break; 326 case TimelineAgent.EventType.EventDispatch: 327 this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.EventDispatched, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.type, profileData)); 328 break; 329 case TimelineAgent.EventType.XHRLoad: 330 this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.EventDispatched, startTime, endTime, callFrames, sourceCodeLocation, "load", profileData)); 331 break; 332 case TimelineAgent.EventType.XHRReadyStateChange: 333 this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.EventDispatched, startTime, endTime, callFrames, sourceCodeLocation, "readystatechange", profileData)); 334 break; 335 case TimelineAgent.EventType.FireAnimationFrame: 336 this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.AnimationFrameFired, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.id, profileData)); 337 break; 338 } 339 340 break; 341 342 case TimelineAgent.EventType.ProbeSample: 343 // Pass the startTime as the endTime since this record type has no duration. 344 sourceCodeLocation = WebInspector.probeManager.probeForIdentifier(recordPayload.data.probeId).breakpoint.sourceCodeLocation; 345 this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.ProbeSampleRecorded, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.probeId)); 346 break; 347 348 case TimelineAgent.EventType.TimerInstall: 349 console.assert(isNaN(endTime)); 350 351 // Pass the startTime as the endTime since this record type has no duration. 352 this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.TimerInstalled, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.timerId)); 353 break; 354 355 case TimelineAgent.EventType.TimerRemove: 356 console.assert(isNaN(endTime)); 357 358 // Pass the startTime as the endTime since this record type has no duration. 359 this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.TimerRemoved, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.timerId)); 360 break; 361 362 case TimelineAgent.EventType.RequestAnimationFrame: 363 console.assert(isNaN(endTime)); 364 365 // Pass the startTime as the endTime since this record type has no duration. 366 this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.AnimationFrameRequested, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.timerId)); 367 break; 368 369 case TimelineAgent.EventType.CancelAnimationFrame: 370 console.assert(isNaN(endTime)); 371 372 // Pass the startTime as the endTime since this record type has no duration. 373 this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.AnimationFrameCanceled, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.timerId)); 374 break; 375 } 376 } 172 var records = this._processNestedRecords(recordPayload); 173 records.forEach(function(currentValue) { 174 this._addRecord(currentValue); 175 }.bind(this)); 176 }, 177 178 pageDidLoad: function(timestamp) 179 { 180 if (isNaN(WebInspector.frameResourceManager.mainFrame.loadEventTimestamp)) 181 WebInspector.frameResourceManager.mainFrame.markLoadEvent(this.activeRecording.computeElapsedTime(timestamp)); 182 }, 183 184 // Private 185 186 _processNestedRecords: function(childRecordPayloads, parentRecordPayload) 187 { 188 // Convert to a single item array if needed. 189 if (!(childRecordPayloads instanceof Array)) 190 childRecordPayloads = [childRecordPayloads]; 191 192 var records = []; 377 193 378 194 // Iterate over the records tree using a stack. Doing this recursively has 379 195 // been known to cause a call stack overflow. https://webkit.org/b/79106 380 var stack = [{array: [originalRecordPayload], parent:null, index: 0}];196 var stack = [{array: childRecordPayloads, parent: parentRecordPayload || null, index: 0}]; 381 197 while (stack.length) { 382 198 var entry = stack.lastValue; 383 199 var recordPayloads = entry.array; 384 var parentRecordPayload = entry.parent;385 200 386 201 if (entry.index < recordPayloads.length) { 387 202 var recordPayload = recordPayloads[entry.index]; 388 389 processRecord.call(this, recordPayload, parentRecordPayload); 203 var record = this._processEvent(recordPayload, entry.parent); 204 if (record) 205 records.push(record); 390 206 391 207 if (recordPayload.children) … … 395 211 stack.pop(); 396 212 } 397 }, 398 399 pageDidLoad: function(timestamp) 400 { 401 if (isNaN(WebInspector.frameResourceManager.mainFrame.loadEventTimestamp)) 402 WebInspector.frameResourceManager.mainFrame.markLoadEvent(this.activeRecording.computeElapsedTime(timestamp)); 403 }, 404 405 // Private 213 214 return records; 215 }, 216 217 _processRecord: function(recordPayload, parentRecordPayload) 218 { 219 var startTime = this.activeRecording.computeElapsedTime(recordPayload.startTime); 220 var endTime = this.activeRecording.computeElapsedTime(recordPayload.endTime); 221 var callFrames = this._callFramesFromPayload(recordPayload.stackTrace); 222 223 var significantCallFrame = null; 224 if (callFrames) { 225 for (var i = 0; i < callFrames.length; ++i) { 226 if (callFrames[i].nativeCode) 227 continue; 228 significantCallFrame = callFrames[i]; 229 break; 230 } 231 } 232 233 var sourceCodeLocation = significantCallFrame && significantCallFrame.sourceCodeLocation; 234 235 switch (recordPayload.type) { 236 case TimelineAgent.EventType.ScheduleStyleRecalculation: 237 console.assert(isNaN(endTime)); 238 239 // Pass the startTime as the endTime since this record type has no duration. 240 return new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.InvalidateStyles, startTime, startTime, callFrames, sourceCodeLocation); 241 242 case TimelineAgent.EventType.RecalculateStyles: 243 return new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.RecalculateStyles, startTime, endTime, callFrames, sourceCodeLocation); 244 245 case TimelineAgent.EventType.InvalidateLayout: 246 console.assert(isNaN(endTime)); 247 248 // Pass the startTime as the endTime since this record type has no duration. 249 return new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.InvalidateLayout, startTime, startTime, callFrames, sourceCodeLocation); 250 251 case TimelineAgent.EventType.Layout: 252 var layoutRecordType = sourceCodeLocation ? WebInspector.LayoutTimelineRecord.EventType.ForcedLayout : WebInspector.LayoutTimelineRecord.EventType.Layout; 253 254 // COMPATIBILITY (iOS 6): Layout records did not contain area properties. This is not exposed via a quad "root". 255 var quad = recordPayload.data.root ? new WebInspector.Quad(recordPayload.data.root) : null; 256 if (quad) 257 return new WebInspector.LayoutTimelineRecord(layoutRecordType, startTime, endTime, callFrames, sourceCodeLocation, quad.points[0].x, quad.points[0].y, quad.width, quad.height, quad); 258 else 259 return new WebInspector.LayoutTimelineRecord(layoutRecordType, startTime, endTime, callFrames, sourceCodeLocation); 260 261 case TimelineAgent.EventType.Paint: 262 // COMPATIBILITY (iOS 6): Paint records data contained x, y, width, height properties. This became a quad "clip". 263 var quad = recordPayload.data.clip ? new WebInspector.Quad(recordPayload.data.clip) : null; 264 if (quad) 265 return new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.Paint, startTime, endTime, callFrames, sourceCodeLocation, null, null, quad.width, quad.height, quad); 266 else 267 return new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.Paint, startTime, endTime, callFrames, sourceCodeLocation, recordPayload.data.x, recordPayload.data.y, recordPayload.data.width, recordPayload.data.height); 268 269 case TimelineAgent.EventType.RunLoop: 270 if (!recordPayload.children) 271 return null; 272 273 var children = this._processNestedRecords(recordPayload.children, recordPayload); 274 return new WebInspector.RunLoopTimelineRecord(startTime, endTime, children); 275 276 case TimelineAgent.EventType.EvaluateScript: 277 if (!sourceCodeLocation) { 278 var mainFrame = WebInspector.frameResourceManager.mainFrame; 279 var scriptResource = mainFrame.url === recordPayload.data.url ? mainFrame.mainResource : mainFrame.resourceForURL(recordPayload.data.url, true); 280 if (scriptResource) { 281 // The lineNumber is 1-based, but we expect 0-based. 282 var lineNumber = recordPayload.data.lineNumber - 1; 283 284 // FIXME: No column number is provided. 285 sourceCodeLocation = scriptResource.createSourceCodeLocation(lineNumber, 0); 286 } 287 } 288 289 var profileData = recordPayload.data.profile; 290 291 switch (parentRecordPayload && parentRecordPayload.type) { 292 case TimelineAgent.EventType.TimerFire: 293 return new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.TimerFired, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.timerId, profileData); 294 default: 295 return new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.ScriptEvaluated, startTime, endTime, callFrames, sourceCodeLocation, null, profileData); 296 } 297 298 break; 299 300 case TimelineAgent.EventType.ConsoleProfile: 301 var profileData = recordPayload.data.profile; 302 console.assert(profileData); 303 return new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.ConsoleProfileRecorded, startTime, endTime, callFrames, sourceCodeLocation, recordPayload.data.title, profileData); 304 305 case TimelineAgent.EventType.FunctionCall: 306 // FunctionCall always happens as a child of another record, and since the FunctionCall record 307 // has useful info we just make the timeline record here (combining the data from both records). 308 if (!parentRecordPayload) 309 break; 310 311 if (!sourceCodeLocation) { 312 var mainFrame = WebInspector.frameResourceManager.mainFrame; 313 var scriptResource = mainFrame.url === recordPayload.data.scriptName ? mainFrame.mainResource : mainFrame.resourceForURL(recordPayload.data.scriptName, true); 314 if (scriptResource) { 315 // The lineNumber is 1-based, but we expect 0-based. 316 var lineNumber = recordPayload.data.scriptLine - 1; 317 318 // FIXME: No column number is provided. 319 sourceCodeLocation = scriptResource.createSourceCodeLocation(lineNumber, 0); 320 } 321 } 322 323 var profileData = recordPayload.data.profile; 324 325 switch (parentRecordPayload.type) { 326 case TimelineAgent.EventType.TimerFire: 327 return new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.TimerFired, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.timerId, profileData); 328 case TimelineAgent.EventType.EventDispatch: 329 return new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.EventDispatched, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.type, profileData); 330 case TimelineAgent.EventType.XHRLoad: 331 return new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.EventDispatched, startTime, endTime, callFrames, sourceCodeLocation, "load", profileData); 332 case TimelineAgent.EventType.XHRReadyStateChange: 333 return new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.EventDispatched, startTime, endTime, callFrames, sourceCodeLocation, "readystatechange", profileData); 334 case TimelineAgent.EventType.FireAnimationFrame: 335 return new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.AnimationFrameFired, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.id, profileData); 336 } 337 338 break; 339 340 case TimelineAgent.EventType.ProbeSample: 341 // Pass the startTime as the endTime since this record type has no duration. 342 sourceCodeLocation = WebInspector.probeManager.probeForIdentifier(recordPayload.data.probeId).breakpoint.sourceCodeLocation; 343 return new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.ProbeSampleRecorded, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.probeId); 344 345 case TimelineAgent.EventType.TimerInstall: 346 console.assert(isNaN(endTime)); 347 348 // Pass the startTime as the endTime since this record type has no duration. 349 return new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.TimerInstalled, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.timerId); 350 351 case TimelineAgent.EventType.TimerRemove: 352 console.assert(isNaN(endTime)); 353 354 // Pass the startTime as the endTime since this record type has no duration. 355 return new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.TimerRemoved, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.timerId); 356 357 case TimelineAgent.EventType.RequestAnimationFrame: 358 console.assert(isNaN(endTime)); 359 360 // Pass the startTime as the endTime since this record type has no duration. 361 return new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.AnimationFrameRequested, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.timerId); 362 363 case TimelineAgent.EventType.CancelAnimationFrame: 364 console.assert(isNaN(endTime)); 365 366 // Pass the startTime as the endTime since this record type has no duration. 367 return new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.AnimationFrameCanceled, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.timerId); 368 } 369 370 return null; 371 }, 372 373 _processEvent: function(recordPayload, parentRecordPayload) 374 { 375 var startTime = this.activeRecording.computeElapsedTime(recordPayload.startTime); 376 var endTime = this.activeRecording.computeElapsedTime(recordPayload.endTime); 377 378 switch (recordPayload.type) { 379 case TimelineAgent.EventType.MarkLoad: 380 console.assert(isNaN(endTime)); 381 382 var frame = WebInspector.frameResourceManager.frameForIdentifier(recordPayload.frameId); 383 console.assert(frame); 384 if (!frame) 385 break; 386 387 frame.markLoadEvent(startTime); 388 389 if (!frame.isMainFrame()) 390 break; 391 392 var eventMarker = new WebInspector.TimelineMarker(startTime, WebInspector.TimelineMarker.Type.LoadEvent); 393 this._activeRecording.addEventMarker(eventMarker); 394 395 this._stopAutoRecordingSoon(); 396 break; 397 398 case TimelineAgent.EventType.MarkDOMContent: 399 console.assert(isNaN(endTime)); 400 401 var frame = WebInspector.frameResourceManager.frameForIdentifier(recordPayload.frameId); 402 console.assert(frame); 403 if (!frame) 404 break; 405 406 frame.markDOMContentReadyEvent(startTime); 407 408 if (!frame.isMainFrame()) 409 break; 410 411 var eventMarker = new WebInspector.TimelineMarker(startTime, WebInspector.TimelineMarker.Type.DOMContentEvent); 412 this._activeRecording.addEventMarker(eventMarker); 413 break; 414 415 case TimelineAgent.EventType.TimeStamp: 416 var eventMarker = new WebInspector.TimelineMarker(startTime, WebInspector.TimelineMarker.Type.TimeStamp); 417 this._activeRecording.addEventMarker(eventMarker); 418 break; 419 420 default: 421 return this._processRecord(recordPayload, parentRecordPayload); 422 } 423 424 return null; 425 }, 406 426 407 427 _loadNewRecording: function() … … 412 432 var identifier = this._nextRecordingIdentifier++; 413 433 var newRecording = new WebInspector.TimelineRecording(identifier, WebInspector.UIString("Timeline Recording %d").format(identifier)); 414 newRecording.addTimeline(new WebInspector.Timeline(WebInspector.TimelineRecord.Type.Network)); 415 newRecording.addTimeline(new WebInspector.Timeline(WebInspector.TimelineRecord.Type.Layout)); 416 newRecording.addTimeline(new WebInspector.Timeline(WebInspector.TimelineRecord.Type.Script)); 434 newRecording.addTimeline(new WebInspector.Timeline(WebInspector.TimelineRecord.Type.Network, newRecording)); 435 newRecording.addTimeline(new WebInspector.Timeline(WebInspector.TimelineRecord.Type.RunLoop, newRecording)); 436 newRecording.addTimeline(new WebInspector.Timeline(WebInspector.TimelineRecord.Type.Layout, newRecording)); 437 newRecording.addTimeline(new WebInspector.Timeline(WebInspector.TimelineRecord.Type.Script, newRecording)); 417 438 418 439 this._recordings.push(newRecording); -
trunk/Source/WebInspectorUI/UserInterface/Main.html
r181610 r181626 115 115 <link rel="stylesheet" href="Views/ResourceTreeElement.css"> 116 116 <link rel="stylesheet" href="Views/RulesStyleDetailsPanel.css"> 117 <link rel="stylesheet" href="Views/RunLoopTimelineOverviewGraph.css"> 117 118 <link rel="stylesheet" href="Views/ScopeBar.css"> 118 119 <link rel="stylesheet" href="Views/ScriptContentView.css"> … … 135 136 <link rel="stylesheet" href="Views/TimelineOverview.css"> 136 137 <link rel="stylesheet" href="Views/TimelineRecordBar.css"> 138 <link rel="stylesheet" href="Views/TimelineRecordFrame.css"> 137 139 <link rel="stylesheet" href="Views/TimelineRecordingContentView.css"> 138 140 <link rel="stylesheet" href="Views/TimelineRuler.css"> … … 273 275 <script src="Models/ResourceTimelineRecord.js"></script> 274 276 <script src="Models/Revision.js"></script> 277 <script src="Models/RunLoopTimelineRecord.js"></script> 275 278 <script src="Models/ScopeChainNode.js"></script> 276 279 <script src="Models/Script.js"></script> … … 449 452 <script src="Views/ResourceTimelineDataGridNodePathComponent.js"></script> 450 453 <script src="Views/RulesStyleDetailsPanel.js"></script> 454 <script src="Views/RunLoopTimelineOverviewGraph.js"></script> 451 455 <script src="Views/ScopeBar.js"></script> 452 456 <script src="Views/ScopeBarItem.js"></script> … … 472 476 <script src="Views/TimelineOverview.js"></script> 473 477 <script src="Views/TimelineRecordBar.js"></script> 478 <script src="Views/TimelineRecordFrame.js"></script> 474 479 <script src="Views/TimelineRecordingContentView.js"></script> 475 480 <script src="Views/TimelineRuler.js"></script> -
trunk/Source/WebInspectorUI/UserInterface/Models/Timeline.js
r181185 r181626 81 81 if (this._type === WebInspector.TimelineRecord.Type.Script) 82 82 return WebInspector.UIString("JavaScript & Events"); 83 if (this._type === WebInspector.TimelineRecord.Type.RunLoop) 84 return WebInspector.UIString("Frames"); 83 85 84 86 console.error("Timeline has unknown type:", this._type, this); … … 91 93 if (this._type === WebInspector.TimelineRecord.Type.Layout) 92 94 return WebInspector.TimelineSidebarPanel.ColorsIconStyleClass; 95 if (this._type === WebInspector.TimelineRecord.Type.RunLoop) 96 return WebInspector.TimelineSidebarPanel.RunLoopIconStyleClass; 93 97 if (this._type === WebInspector.TimelineRecord.Type.Script) 94 98 return WebInspector.TimelineSidebarPanel.ScriptIconStyleClass; -
trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecord.js
r164543 r181626 47 47 Network: "timeline-record-type-network", 48 48 Layout: "timeline-record-type-layout", 49 Script: "timeline-record-type-script" 49 Script: "timeline-record-type-script", 50 RunLoop: "timeline-record-type-runloop" 50 51 }; 51 52 -
trunk/Source/WebInspectorUI/UserInterface/Views/ContentView.js
r181011 r181626 48 48 return new WebInspector.NetworkTimelineView(representedObject); 49 49 50 if (timelineType === WebInspector.TimelineRecord.Type.Layout )50 if (timelineType === WebInspector.TimelineRecord.Type.Layout || timelineType === WebInspector.TimelineRecord.Type.RunLoop) 51 51 return new WebInspector.LayoutTimelineView(representedObject); 52 52 -
trunk/Source/WebInspectorUI/UserInterface/Views/LayoutTimelineView.js
r181011 r181626 28 28 WebInspector.TimelineView.call(this, timeline); 29 29 30 console.assert(timeline.type === WebInspector.TimelineRecord.Type.Layout );30 console.assert(timeline.type === WebInspector.TimelineRecord.Type.Layout || WebInspector.TimelineRecord.Type.RunLoop); 31 31 32 32 this.navigationSidebarTreeOutline.onselect = this._treeElementSelected.bind(this); … … 186 186 { 187 187 var layoutTimelineRecord = event.data.record; 188 console.assert(layoutTimelineRecord instanceof WebInspector.LayoutTimelineRecord );188 console.assert(layoutTimelineRecord instanceof WebInspector.LayoutTimelineRecord || layoutTimelineRecord instanceof WebInspector.RunLoopTimelineRecord); 189 189 190 190 this._pendingRecords.push(layoutTimelineRecord); -
trunk/Source/WebInspectorUI/UserInterface/Views/TimelineIcons.css
r172241 r181626 64 64 } 65 65 66 .runloop-icon .icon { 67 content: -webkit-image-set(url(../Images/Frames.png) 1x, url(../Images/Frames@2x.png) 2x); 68 } 69 70 .runloop-icon.large .icon { 71 content: -webkit-image-set(url(../Images/FramesLarge.png) 1x, url(../Images/FramesLarge@2x.png) 2x); 72 } 73 66 74 .stopwatch-icon .icon { 67 75 content: -webkit-image-set(url(../Images/Stopwatch.png) 1x, url(../Images/Stopwatch@2x.png) 2x); … … 82 90 .paint-record .icon { 83 91 content: url(../Images/TimelineRecordPaint.svg); 92 } 93 94 .runloop-record .icon { 95 content: -webkit-image-set(url(../Images/Frames.png) 1x, url(../Images/Frames@2x.png) 2x); 84 96 } 85 97 -
trunk/Source/WebInspectorUI/UserInterface/Views/TimelineOverviewGraph.js
r179701 r181626 40 40 if (timelineType === WebInspector.TimelineRecord.Type.Script) 41 41 return new WebInspector.ScriptTimelineOverviewGraph(timeline); 42 43 if (timelineType === WebInspector.TimelineRecord.Type.RunLoop) 44 return new WebInspector.RunLoopTimelineOverviewGraph(timeline); 42 45 43 46 throw Error("Can't make a graph for an unknown timeline."); -
trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordTreeElement.js
r175784 r181626 100 100 break; 101 101 102 case WebInspector.TimelineRecord.Type.RunLoop: 103 title = WebInspector.UIString("Runloop Executed"); 104 iconStyleClass = WebInspector.TimelineRecordTreeElement.RunLoopRecordIconStyleClass; 105 break; 106 102 107 default: 103 108 console.error("Unknown TimelineRecord type: " + timelineRecord.type, timelineRecord); … … 115 120 WebInspector.TimelineRecordTreeElement.LayoutRecordIconStyleClass = "layout-record"; 116 121 WebInspector.TimelineRecordTreeElement.PaintRecordIconStyleClass = "paint-record"; 122 WebInspector.TimelineRecordTreeElement.RunLoopRecordIconStyleClass = "runloop-record"; 117 123 WebInspector.TimelineRecordTreeElement.EvaluatedRecordIconStyleClass = "evaluated-record"; 118 124 WebInspector.TimelineRecordTreeElement.EventRecordIconStyleClass = "event-record"; -
trunk/Source/WebInspectorUI/UserInterface/Views/TimelineSidebarPanel.js
r180001 r181626 140 140 WebInspector.TimelineSidebarPanel.ColorsIconStyleClass = "colors-icon"; 141 141 WebInspector.TimelineSidebarPanel.ScriptIconStyleClass = "script-icon"; 142 WebInspector.TimelineSidebarPanel.RunLoopIconStyleClass = "runloop-icon"; 142 143 WebInspector.TimelineSidebarPanel.TimelineRecordingContentViewShowingStyleClass = "timeline-recording-content-view-showing"; 143 144 -
trunk/Source/WebInspectorUI/WebInspectorUI.vcxproj/WebInspectorUI.vcxproj
r181610 r181626 526 526 <None Include="..\UserInterface\Images\ForwardArrow.svg" /> 527 527 <None Include="..\UserInterface\Images\ForwardArrowLegacy.svg" /> 528 <None Include="..\UserInterface\Images\Frames.png" /> 529 <None Include="..\UserInterface\Images\Frames%402x.png" /> 530 <None Include="..\UserInterface\Images\FramesLarge.png" /> 531 <None Include="..\UserInterface\Images\FramesLarge%402x.png" /> 528 532 <None Include="..\UserInterface\Images\Function.svg" /> 529 533 <None Include="..\UserInterface\Images\GoToArrow.svg" /> … … 748 752 <None Include="..\UserInterface\RulesStyleDetailsPanel.css" /> 749 753 <None Include="..\UserInterface\RulesStyleDetailsPanel.js" /> 754 <None Include="..\UserInterface\RunLoopTimelineOverviewGraph.css" /> 755 <None Include="..\UserInterface\RunLoopTimelineOverviewGraph.js" /> 756 <None Include="..\UserInterface\RunLoopTimelineRecord.js" /> 750 757 <None Include="..\UserInterface\RuntimeObserver.js" /> 751 758 <None Include="..\UserInterface\ScopeBar.css" /> … … 809 816 <None Include="..\UserInterface\TimelineOverview.js" /> 810 817 <None Include="..\UserInterface\TimelineRecord.js" /> 818 <None Include="..\UserInterface\TimelineRecordFrame.css" /> 819 <None Include="..\UserInterface\TimelineRecordFrame.js" /> 811 820 <None Include="..\UserInterface\TimelinesContentView.css" /> 812 821 <None Include="..\UserInterface\TimelinesContentView.js" /> -
trunk/Source/WebInspectorUI/WebInspectorUI.vcxproj/WebInspectorUI.vcxproj.filters
r181610 r181626 826 826 <Filter>UserInterface</Filter> 827 827 </None> 828 <None Include="..\UserInterface\RunLoopTimelineOverviewGraph.css"> 829 <Filter>UserInterface</Filter> 830 </None> 831 <None Include="..\UserInterface\RunLoopTimelineOverviewGraph.js"> 832 <Filter>UserInterface</Filter> 833 </None> 834 <None Include="..\UserInterface\RunLoopTimelineRecord.js"> 835 <Filter>UserInterface</Filter> 836 </None> 828 837 <None Include="..\UserInterface\RuntimeObserver.js"> 829 838 <Filter>UserInterface</Filter> … … 1007 1016 </None> 1008 1017 <None Include="..\UserInterface\TimelineRecord.js"> 1018 <Filter>UserInterface</Filter> 1019 </None> 1020 <None Include="..\UserInterface\TimelineRecordFrame.css"> 1021 <Filter>UserInterface</Filter> 1022 </None> 1023 <None Include="..\UserInterface\TimelineRecordFrame.js"> 1009 1024 <Filter>UserInterface</Filter> 1010 1025 </None>
Note: See TracChangeset
for help on using the changeset viewer.