| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 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 | |
| 5 /** | |
| 6 * @constructor | |
| 7 * @extends {WebInspector.TimelineUIUtils} | |
| 8 */ | |
| 9 WebInspector.TracingTimelineUIUtils = function() | |
| 10 { | |
| 11 WebInspector.TimelineUIUtils.call(this); | |
| 12 } | |
| 13 | |
| 14 WebInspector.TracingTimelineUIUtils.prototype = { | |
| 15 /** | |
| 16 * @param {!WebInspector.TimelineModel.Record} record | |
| 17 * @return {boolean} | |
| 18 */ | |
| 19 isBeginFrame: function(record) | |
| 20 { | |
| 21 return record.type() === WebInspector.TracingTimelineModel.RecordType.Be
ginFrame; | |
| 22 }, | |
| 23 | |
| 24 /** | |
| 25 * @param {!WebInspector.TimelineModel.Record} record | |
| 26 * @return {boolean} | |
| 27 */ | |
| 28 isProgram: function(record) | |
| 29 { | |
| 30 return record.type() === WebInspector.TracingTimelineModel.RecordType.Pr
ogram; | |
| 31 }, | |
| 32 | |
| 33 /** | |
| 34 * @param {string} recordType | |
| 35 * @return {boolean} | |
| 36 */ | |
| 37 isCoalescable: function(recordType) | |
| 38 { | |
| 39 return !!WebInspector.TracingTimelineUIUtils._coalescableRecordTypes[rec
ordType]; | |
| 40 }, | |
| 41 | |
| 42 /** | |
| 43 * @param {!WebInspector.TimelineModel.Record} record | |
| 44 * @return {boolean} | |
| 45 */ | |
| 46 isEventDivider: function(record) | |
| 47 { | |
| 48 return WebInspector.TracingTimelineUIUtils.isMarkerEvent(record.traceEve
nt()); | |
| 49 }, | |
| 50 | |
| 51 /** | |
| 52 * @param {!WebInspector.TimelineModel.Record} record | |
| 53 * @return {?Object} | |
| 54 */ | |
| 55 countersForRecord: function(record) | |
| 56 { | |
| 57 return record.type() === WebInspector.TracingTimelineModel.RecordType.Up
dateCounters ? record.data() : null; | |
| 58 }, | |
| 59 | |
| 60 /** | |
| 61 * @param {!WebInspector.TimelineModel.Record} record | |
| 62 * @return {?Object} | |
| 63 */ | |
| 64 highlightQuadForRecord: function(record) | |
| 65 { | |
| 66 return record.traceEvent().highlightQuad || null; | |
| 67 }, | |
| 68 | |
| 69 /** | |
| 70 * @param {!WebInspector.TimelineModel.Record} record | |
| 71 * @return {string} | |
| 72 */ | |
| 73 titleForRecord: function(record) | |
| 74 { | |
| 75 var event = record.traceEvent(); | |
| 76 return WebInspector.TracingTimelineUIUtils.eventTitle(event, record.time
lineModel()); | |
| 77 }, | |
| 78 | |
| 79 /** | |
| 80 * @param {!WebInspector.TimelineModel.Record} record | |
| 81 * @return {!WebInspector.TimelineCategory} | |
| 82 */ | |
| 83 categoryForRecord: function(record) | |
| 84 { | |
| 85 return WebInspector.TracingTimelineUIUtils.eventStyle(record.traceEvent(
)).category; | |
| 86 }, | |
| 87 | |
| 88 /** | |
| 89 * @param {!WebInspector.TimelineModel.Record} record | |
| 90 * @param {!WebInspector.Linkifier} linkifier | |
| 91 * @return {?Node} | |
| 92 */ | |
| 93 buildDetailsNode: function(record, linkifier) | |
| 94 { | |
| 95 return WebInspector.TracingTimelineUIUtils.buildDetailsNodeForTraceEvent
(record.traceEvent(), linkifier); | |
| 96 }, | |
| 97 | |
| 98 /** | |
| 99 * @param {!WebInspector.TimelineModel.Record} record | |
| 100 * @param {!WebInspector.TimelineModel} model | |
| 101 * @param {!WebInspector.Linkifier} linkifier | |
| 102 * @param {function(!DocumentFragment)} callback | |
| 103 */ | |
| 104 generateDetailsContent: function(record, model, linkifier, callback) | |
| 105 { | |
| 106 if (!(model instanceof WebInspector.TracingTimelineModel)) | |
| 107 throw new Error("Illegal argument."); | |
| 108 var tracingTimelineModel = /** @type {!WebInspector.TracingTimelineModel
} */ (model); | |
| 109 WebInspector.TracingTimelineUIUtils.buildTraceEventDetails(record.traceE
vent(), tracingTimelineModel, linkifier, callback); | |
| 110 }, | |
| 111 | |
| 112 /** | |
| 113 * @return {!Element} | |
| 114 */ | |
| 115 createBeginFrameDivider: function() | |
| 116 { | |
| 117 return this.createEventDivider(WebInspector.TracingTimelineModel.RecordT
ype.BeginFrame); | |
| 118 }, | |
| 119 | |
| 120 /** | |
| 121 * @param {string} recordType | |
| 122 * @param {string=} title | |
| 123 * @return {!Element} | |
| 124 */ | |
| 125 createEventDivider: function(recordType, title) | |
| 126 { | |
| 127 return WebInspector.TracingTimelineUIUtils._createEventDivider(recordTyp
e, title); | |
| 128 }, | |
| 129 | |
| 130 /** | |
| 131 * @param {!WebInspector.TimelineModel.Record} record | |
| 132 * @param {!RegExp} regExp | |
| 133 * @return {boolean} | |
| 134 */ | |
| 135 testContentMatching: function(record, regExp) | |
| 136 { | |
| 137 var traceEvent = record.traceEvent(); | |
| 138 var title = WebInspector.TracingTimelineUIUtils.eventStyle(traceEvent).t
itle; | |
| 139 var tokens = [title]; | |
| 140 for (var argName in traceEvent.args) { | |
| 141 var argValue = traceEvent.args[argName]; | |
| 142 for (var key in argValue) | |
| 143 tokens.push(argValue[key]); | |
| 144 } | |
| 145 return regExp.test(tokens.join("|")); | |
| 146 }, | |
| 147 | |
| 148 /** | |
| 149 * @param {!Object} total | |
| 150 * @param {!WebInspector.TimelineModel.Record} record | |
| 151 */ | |
| 152 aggregateTimeForRecord: function(total, record) | |
| 153 { | |
| 154 var traceEvent = record.traceEvent(); | |
| 155 var model = record._model; | |
| 156 WebInspector.TracingTimelineUIUtils._aggregatedStatsForTraceEvent(total,
model, traceEvent); | |
| 157 }, | |
| 158 | |
| 159 /** | |
| 160 * @return {!WebInspector.TimelineModel.Filter} | |
| 161 */ | |
| 162 hiddenRecordsFilter: function() | |
| 163 { | |
| 164 return new WebInspector.TimelineRecordVisibleTypeFilter(WebInspector.Tra
cingTimelineUIUtils._visibleTypes()); | |
| 165 }, | |
| 166 | |
| 167 /** | |
| 168 * @return {?WebInspector.TimelineModel.Filter} | |
| 169 */ | |
| 170 hiddenEmptyRecordsFilter: function() | |
| 171 { | |
| 172 var hiddenEmptyRecords = [WebInspector.TimelineModel.RecordType.EventDis
patch]; | |
| 173 return new WebInspector.TimelineRecordHiddenEmptyTypeFilter(hiddenEmptyR
ecords); | |
| 174 }, | |
| 175 | |
| 176 __proto__: WebInspector.TimelineUIUtils.prototype | |
| 177 } | |
| 178 | |
| 179 /** | |
| 180 * @constructor | |
| 181 * @param {string} title | |
| 182 * @param {!WebInspector.TimelineCategory} category | |
| 183 * @param {boolean=} hidden | |
| 184 */ | |
| 185 WebInspector.TimelineRecordStyle = function(title, category, hidden) | |
| 186 { | |
| 187 this.title = title; | |
| 188 this.category = category; | |
| 189 this.hidden = !!hidden; | |
| 190 } | |
| 191 | |
| 192 /** | |
| 193 * @return {!Object.<string, !WebInspector.TimelineRecordStyle>} | |
| 194 */ | |
| 195 WebInspector.TracingTimelineUIUtils._initEventStyles = function() | |
| 196 { | |
| 197 if (WebInspector.TracingTimelineUIUtils._eventStylesMap) | |
| 198 return WebInspector.TracingTimelineUIUtils._eventStylesMap; | |
| 199 | |
| 200 var recordTypes = WebInspector.TracingTimelineModel.RecordType; | |
| 201 var categories = WebInspector.TimelineUIUtils.categories(); | |
| 202 | |
| 203 var eventStyles = {}; | |
| 204 eventStyles[recordTypes.Program] = new WebInspector.TimelineRecordStyle(WebI
nspector.UIString("Other"), categories["other"]); | |
| 205 eventStyles[recordTypes.EventDispatch] = new WebInspector.TimelineRecordStyl
e(WebInspector.UIString("Event"), categories["scripting"]); | |
| 206 eventStyles[recordTypes.RequestMainThreadFrame] = new WebInspector.TimelineR
ecordStyle(WebInspector.UIString("Request Main Thread Frame"), categories["rende
ring"], true); | |
| 207 eventStyles[recordTypes.BeginFrame] = new WebInspector.TimelineRecordStyle(W
ebInspector.UIString("Frame Start"), categories["rendering"], true); | |
| 208 eventStyles[recordTypes.BeginMainThreadFrame] = new WebInspector.TimelineRec
ordStyle(WebInspector.UIString("Frame Start (main thread)"), categories["renderi
ng"], true); | |
| 209 eventStyles[recordTypes.DrawFrame] = new WebInspector.TimelineRecordStyle(We
bInspector.UIString("Draw Frame"), categories["rendering"], true); | |
| 210 eventStyles[recordTypes.ScheduleStyleRecalculation] = new WebInspector.Timel
ineRecordStyle(WebInspector.UIString("Schedule Style Recalculation"), categories
["rendering"], true); | |
| 211 eventStyles[recordTypes.RecalculateStyles] = new WebInspector.TimelineRecord
Style(WebInspector.UIString("Recalculate Style"), categories["rendering"]); | |
| 212 eventStyles[recordTypes.InvalidateLayout] = new WebInspector.TimelineRecordS
tyle(WebInspector.UIString("Invalidate Layout"), categories["rendering"], true); | |
| 213 eventStyles[recordTypes.Layout] = new WebInspector.TimelineRecordStyle(WebIn
spector.UIString("Layout"), categories["rendering"]); | |
| 214 eventStyles[recordTypes.PaintSetup] = new WebInspector.TimelineRecordStyle(W
ebInspector.UIString("Paint Setup"), categories["painting"]); | |
| 215 eventStyles[recordTypes.UpdateLayer] = new WebInspector.TimelineRecordStyle(
WebInspector.UIString("Update Layer"), categories["painting"], true); | |
| 216 eventStyles[recordTypes.UpdateLayerTree] = new WebInspector.TimelineRecordSt
yle(WebInspector.UIString("Update Layer Tree"), categories["rendering"]); | |
| 217 eventStyles[recordTypes.Paint] = new WebInspector.TimelineRecordStyle(WebIns
pector.UIString("Paint"), categories["painting"]); | |
| 218 eventStyles[recordTypes.RasterTask] = new WebInspector.TimelineRecordStyle(W
ebInspector.UIString("Paint"), categories["painting"]); | |
| 219 eventStyles[recordTypes.ScrollLayer] = new WebInspector.TimelineRecordStyle(
WebInspector.UIString("Scroll"), categories["rendering"]); | |
| 220 eventStyles[recordTypes.CompositeLayers] = new WebInspector.TimelineRecordSt
yle(WebInspector.UIString("Composite Layers"), categories["painting"]); | |
| 221 eventStyles[recordTypes.ParseHTML] = new WebInspector.TimelineRecordStyle(We
bInspector.UIString("Parse HTML"), categories["loading"]); | |
| 222 eventStyles[recordTypes.TimerInstall] = new WebInspector.TimelineRecordStyle
(WebInspector.UIString("Install Timer"), categories["scripting"]); | |
| 223 eventStyles[recordTypes.TimerRemove] = new WebInspector.TimelineRecordStyle(
WebInspector.UIString("Remove Timer"), categories["scripting"]); | |
| 224 eventStyles[recordTypes.TimerFire] = new WebInspector.TimelineRecordStyle(We
bInspector.UIString("Timer Fired"), categories["scripting"]); | |
| 225 eventStyles[recordTypes.XHRReadyStateChange] = new WebInspector.TimelineReco
rdStyle(WebInspector.UIString("XHR Ready State Change"), categories["scripting"]
); | |
| 226 eventStyles[recordTypes.XHRLoad] = new WebInspector.TimelineRecordStyle(WebI
nspector.UIString("XHR Load"), categories["scripting"]); | |
| 227 eventStyles[recordTypes.EvaluateScript] = new WebInspector.TimelineRecordSty
le(WebInspector.UIString("Evaluate Script"), categories["scripting"]); | |
| 228 eventStyles[recordTypes.MarkLoad] = new WebInspector.TimelineRecordStyle(Web
Inspector.UIString("Load event"), categories["scripting"], true); | |
| 229 eventStyles[recordTypes.MarkDOMContent] = new WebInspector.TimelineRecordSty
le(WebInspector.UIString("DOMContentLoaded event"), categories["scripting"], tru
e); | |
| 230 eventStyles[recordTypes.MarkFirstPaint] = new WebInspector.TimelineRecordSty
le(WebInspector.UIString("First paint"), categories["painting"], true); | |
| 231 eventStyles[recordTypes.TimeStamp] = new WebInspector.TimelineRecordStyle(We
bInspector.UIString("Timestamp"), categories["scripting"]); | |
| 232 eventStyles[recordTypes.ConsoleTime] = new WebInspector.TimelineRecordStyle(
WebInspector.UIString("Console Time"), categories["scripting"]); | |
| 233 eventStyles[recordTypes.ResourceSendRequest] = new WebInspector.TimelineReco
rdStyle(WebInspector.UIString("Send Request"), categories["loading"]); | |
| 234 eventStyles[recordTypes.ResourceReceiveResponse] = new WebInspector.Timeline
RecordStyle(WebInspector.UIString("Receive Response"), categories["loading"]); | |
| 235 eventStyles[recordTypes.ResourceFinish] = new WebInspector.TimelineRecordSty
le(WebInspector.UIString("Finish Loading"), categories["loading"]); | |
| 236 eventStyles[recordTypes.ResourceReceivedData] = new WebInspector.TimelineRec
ordStyle(WebInspector.UIString("Receive Data"), categories["loading"]); | |
| 237 eventStyles[recordTypes.FunctionCall] = new WebInspector.TimelineRecordStyle
(WebInspector.UIString("Function Call"), categories["scripting"]); | |
| 238 eventStyles[recordTypes.GCEvent] = new WebInspector.TimelineRecordStyle(WebI
nspector.UIString("GC Event"), categories["scripting"]); | |
| 239 eventStyles[recordTypes.JSFrame] = new WebInspector.TimelineRecordStyle(WebI
nspector.UIString("JS Frame"), categories["scripting"]); | |
| 240 eventStyles[recordTypes.RequestAnimationFrame] = new WebInspector.TimelineRe
cordStyle(WebInspector.UIString("Request Animation Frame"), categories["scriptin
g"]); | |
| 241 eventStyles[recordTypes.CancelAnimationFrame] = new WebInspector.TimelineRec
ordStyle(WebInspector.UIString("Cancel Animation Frame"), categories["scripting"
]); | |
| 242 eventStyles[recordTypes.FireAnimationFrame] = new WebInspector.TimelineRecor
dStyle(WebInspector.UIString("Animation Frame Fired"), categories["scripting"]); | |
| 243 eventStyles[recordTypes.WebSocketCreate] = new WebInspector.TimelineRecordSt
yle(WebInspector.UIString("Create WebSocket"), categories["scripting"]); | |
| 244 eventStyles[recordTypes.WebSocketSendHandshakeRequest] = new WebInspector.Ti
melineRecordStyle(WebInspector.UIString("Send WebSocket Handshake"), categories[
"scripting"]); | |
| 245 eventStyles[recordTypes.WebSocketReceiveHandshakeResponse] = new WebInspecto
r.TimelineRecordStyle(WebInspector.UIString("Receive WebSocket Handshake"), cate
gories["scripting"]); | |
| 246 eventStyles[recordTypes.WebSocketDestroy] = new WebInspector.TimelineRecordS
tyle(WebInspector.UIString("Destroy WebSocket"), categories["scripting"]); | |
| 247 eventStyles[recordTypes.EmbedderCallback] = new WebInspector.TimelineRecordS
tyle(WebInspector.UIString("Embedder Callback"), categories["scripting"]); | |
| 248 eventStyles[recordTypes.DecodeImage] = new WebInspector.TimelineRecordStyle(
WebInspector.UIString("Image Decode"), categories["painting"]); | |
| 249 eventStyles[recordTypes.ResizeImage] = new WebInspector.TimelineRecordStyle(
WebInspector.UIString("Image Resize"), categories["painting"]); | |
| 250 WebInspector.TracingTimelineUIUtils._eventStylesMap = eventStyles; | |
| 251 return eventStyles; | |
| 252 } | |
| 253 | |
| 254 WebInspector.TracingTimelineUIUtils._coalescableRecordTypes = {}; | |
| 255 WebInspector.TracingTimelineUIUtils._coalescableRecordTypes[WebInspector.Tracing
TimelineModel.RecordType.Layout] = 1; | |
| 256 WebInspector.TracingTimelineUIUtils._coalescableRecordTypes[WebInspector.Tracing
TimelineModel.RecordType.Paint] = 1; | |
| 257 WebInspector.TracingTimelineUIUtils._coalescableRecordTypes[WebInspector.Tracing
TimelineModel.RecordType.RasterTask] = 1; | |
| 258 WebInspector.TracingTimelineUIUtils._coalescableRecordTypes[WebInspector.Tracing
TimelineModel.RecordType.DecodeImage] = 1; | |
| 259 WebInspector.TracingTimelineUIUtils._coalescableRecordTypes[WebInspector.Tracing
TimelineModel.RecordType.ResizeImage] = 1; | |
| 260 | |
| 261 /** | |
| 262 * @param {!WebInspector.TracingModel.Event} event | |
| 263 * @return {!{title: string, category: !WebInspector.TimelineCategory}} | |
| 264 */ | |
| 265 WebInspector.TracingTimelineUIUtils.eventStyle = function(event) | |
| 266 { | |
| 267 var eventStyles = WebInspector.TracingTimelineUIUtils._initEventStyles(); | |
| 268 if (event.category === WebInspector.TracingModel.ConsoleEventCategory) | |
| 269 return { title: event.name, category: WebInspector.TimelineUIUtils.categ
ories()["scripting"] }; | |
| 270 | |
| 271 var result = eventStyles[event.name]; | |
| 272 if (!result) { | |
| 273 result = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Unk
nown: %s", event.name), WebInspector.TimelineUIUtils.categories()["other"]); | |
| 274 eventStyles[event.name] = result; | |
| 275 } | |
| 276 return result; | |
| 277 } | |
| 278 | |
| 279 /** | |
| 280 * @param {!WebInspector.TracingModel.Event} event | |
| 281 * @return {string} | |
| 282 */ | |
| 283 WebInspector.TracingTimelineUIUtils.markerEventColor = function(event) | |
| 284 { | |
| 285 var red = "rgb(255, 0, 0)"; | |
| 286 var blue = "rgb(0, 0, 255)"; | |
| 287 var orange = "rgb(255, 178, 23)"; | |
| 288 var green = "rgb(0, 130, 0)"; | |
| 289 | |
| 290 if (event.category === WebInspector.TracingModel.ConsoleEventCategory) | |
| 291 return orange; | |
| 292 | |
| 293 var recordTypes = WebInspector.TracingTimelineModel.RecordType; | |
| 294 var eventName = event.name; | |
| 295 switch (eventName) { | |
| 296 case recordTypes.MarkDOMContent: return blue; | |
| 297 case recordTypes.MarkLoad: return red; | |
| 298 case recordTypes.MarkFirstPaint: return green; | |
| 299 case recordTypes.TimeStamp: return orange; | |
| 300 } | |
| 301 return green; | |
| 302 } | |
| 303 | |
| 304 /** | |
| 305 * @param {!WebInspector.TracingModel.Event} event | |
| 306 * @param {!WebInspector.TimelineModel} model | |
| 307 * @return {string} | |
| 308 */ | |
| 309 WebInspector.TracingTimelineUIUtils.eventTitle = function(event, model) | |
| 310 { | |
| 311 var title = WebInspector.TracingTimelineUIUtils.eventStyle(event).title; | |
| 312 if (event.category === WebInspector.TracingModel.ConsoleEventCategory) | |
| 313 return title; | |
| 314 if (event.name === WebInspector.TracingTimelineModel.RecordType.TimeStamp) | |
| 315 return WebInspector.UIString("%s: %s", title, event.args["data"]["messag
e"]); | |
| 316 if (WebInspector.TracingTimelineUIUtils.isMarkerEvent(event)) { | |
| 317 var startTime = Number.millisToString(event.startTime - model.minimumRec
ordTime()); | |
| 318 return WebInspector.UIString("%s at %s", title, startTime); | |
| 319 } | |
| 320 return title; | |
| 321 } | |
| 322 | |
| 323 /** | |
| 324 * @param {!WebInspector.TracingModel.Event} event | |
| 325 * @return {boolean} | |
| 326 */ | |
| 327 WebInspector.TracingTimelineUIUtils.isMarkerEvent = function(event) | |
| 328 { | |
| 329 var recordTypes = WebInspector.TracingTimelineModel.RecordType; | |
| 330 switch (event.name) { | |
| 331 case recordTypes.TimeStamp: | |
| 332 case recordTypes.MarkFirstPaint: | |
| 333 return true; | |
| 334 case recordTypes.MarkDOMContent: | |
| 335 case recordTypes.MarkLoad: | |
| 336 return event.args["data"]["isMainFrame"]; | |
| 337 default: | |
| 338 return false; | |
| 339 } | |
| 340 } | |
| 341 | |
| 342 /** | |
| 343 * @param {!WebInspector.TracingModel.Event} event | |
| 344 * @return {boolean} | |
| 345 */ | |
| 346 WebInspector.TracingTimelineUIUtils.isTallMarkerEvent = function(event) | |
| 347 { | |
| 348 return event.name !== WebInspector.TracingTimelineModel.RecordType.TimeStamp
; | |
| 349 } | |
| 350 | |
| 351 /** | |
| 352 * @param {!WebInspector.TracingModel.Event} event | |
| 353 * @param {!WebInspector.Linkifier} linkifier | |
| 354 * @return {?Node} | |
| 355 */ | |
| 356 WebInspector.TracingTimelineUIUtils.buildDetailsNodeForTraceEvent = function(eve
nt, linkifier) | |
| 357 { | |
| 358 var recordType = WebInspector.TracingTimelineModel.RecordType; | |
| 359 var target = event.thread.target(); | |
| 360 var details; | |
| 361 var detailsText; | |
| 362 var eventData = event.args["data"]; | |
| 363 switch (event.name) { | |
| 364 case recordType.GCEvent: | |
| 365 var delta = event.args["usedHeapSizeBefore"] - event.args["usedHeapSizeA
fter"]; | |
| 366 detailsText = WebInspector.UIString("%s collected", Number.bytesToString
(delta)); | |
| 367 break; | |
| 368 case recordType.TimerFire: | |
| 369 detailsText = eventData["timerId"]; | |
| 370 break; | |
| 371 case recordType.FunctionCall: | |
| 372 details = linkifyLocation(eventData["scriptId"], eventData["scriptName"]
, eventData["scriptLine"], 0); | |
| 373 break; | |
| 374 case recordType.JSFrame: | |
| 375 details = linkifyLocation(eventData["scriptId"], eventData["url"], event
Data["lineNumber"], eventData["columnNumber"]); | |
| 376 detailsText = WebInspector.CPUProfileDataModel.beautifyFunctionName(even
tData["functionName"]); | |
| 377 if (details && detailsText) | |
| 378 details.textContent = detailsText; | |
| 379 break; | |
| 380 case recordType.FireAnimationFrame: | |
| 381 detailsText = eventData["id"]; | |
| 382 break; | |
| 383 case recordType.EventDispatch: | |
| 384 detailsText = eventData ? eventData["type"] : null; | |
| 385 break; | |
| 386 case recordType.Paint: | |
| 387 var width = WebInspector.TimelineUIUtils.quadWidth(eventData.clip); | |
| 388 var height = WebInspector.TimelineUIUtils.quadHeight(eventData.clip); | |
| 389 if (width && height) | |
| 390 detailsText = WebInspector.UIString("%d\u2009\u00d7\u2009%d", width,
height); | |
| 391 break; | |
| 392 case recordType.TimerInstall: | |
| 393 case recordType.TimerRemove: | |
| 394 details = linkifyTopCallFrame(); | |
| 395 detailsText = eventData["timerId"]; | |
| 396 break; | |
| 397 case recordType.RequestAnimationFrame: | |
| 398 case recordType.CancelAnimationFrame: | |
| 399 details = linkifyTopCallFrame(); | |
| 400 detailsText = eventData["id"]; | |
| 401 break; | |
| 402 case recordType.ParseHTML: | |
| 403 case recordType.RecalculateStyles: | |
| 404 details = linkifyTopCallFrame(); | |
| 405 break; | |
| 406 case recordType.EvaluateScript: | |
| 407 var url = eventData["url"]; | |
| 408 if (url) | |
| 409 details = linkifyLocation("", url, eventData["lineNumber"], 0); | |
| 410 break; | |
| 411 case recordType.XHRReadyStateChange: | |
| 412 case recordType.XHRLoad: | |
| 413 case recordType.ResourceSendRequest: | |
| 414 var url = eventData["url"]; | |
| 415 if (url) | |
| 416 detailsText = WebInspector.displayNameForURL(url); | |
| 417 break; | |
| 418 case recordType.ResourceReceivedData: | |
| 419 case recordType.ResourceReceiveResponse: | |
| 420 case recordType.ResourceFinish: | |
| 421 var initiator = event.initiator; | |
| 422 if (initiator) { | |
| 423 var url = initiator.args["data"]["url"]; | |
| 424 if (url) | |
| 425 detailsText = WebInspector.displayNameForURL(url); | |
| 426 } | |
| 427 break; | |
| 428 case recordType.EmbedderCallback: | |
| 429 detailsText = eventData["callbackName"]; | |
| 430 break; | |
| 431 | |
| 432 case recordType.PaintImage: | |
| 433 case recordType.DecodeImage: | |
| 434 case recordType.ResizeImage: | |
| 435 case recordType.DecodeLazyPixelRef: | |
| 436 var url = event.imageURL; | |
| 437 if (url) | |
| 438 detailsText = WebInspector.displayNameForURL(url); | |
| 439 break; | |
| 440 | |
| 441 default: | |
| 442 if (event.category === WebInspector.TracingModel.ConsoleEventCategory) | |
| 443 detailsText = null; | |
| 444 else | |
| 445 details = linkifyTopCallFrame(); | |
| 446 break; | |
| 447 } | |
| 448 | |
| 449 if (!details && detailsText) | |
| 450 details = createTextNode(detailsText); | |
| 451 return details; | |
| 452 | |
| 453 /** | |
| 454 * @param {string} scriptId | |
| 455 * @param {string} url | |
| 456 * @param {number} lineNumber | |
| 457 * @param {number=} columnNumber | |
| 458 */ | |
| 459 function linkifyLocation(scriptId, url, lineNumber, columnNumber) | |
| 460 { | |
| 461 if (!url) | |
| 462 return null; | |
| 463 | |
| 464 // FIXME(62725): stack trace line/column numbers are one-based. | |
| 465 return linkifier.linkifyScriptLocation(target, scriptId, url, lineNumber
- 1, (columnNumber ||1) - 1, "timeline-details"); | |
| 466 } | |
| 467 | |
| 468 /** | |
| 469 * @return {?Element} | |
| 470 */ | |
| 471 function linkifyTopCallFrame() | |
| 472 { | |
| 473 var stackTrace = event.stackTrace; | |
| 474 if (!stackTrace) { | |
| 475 var initiator = event.initiator; | |
| 476 if (initiator) | |
| 477 stackTrace = initiator.stackTrace; | |
| 478 } | |
| 479 if (!stackTrace || !stackTrace.length) | |
| 480 return null; | |
| 481 return linkifier.linkifyConsoleCallFrame(target, stackTrace[0], "timelin
e-details"); | |
| 482 } | |
| 483 } | |
| 484 | |
| 485 /** | |
| 486 * @param {!WebInspector.TracingModel.Event} event | |
| 487 * @param {!WebInspector.TracingTimelineModel} model | |
| 488 * @param {!WebInspector.Linkifier} linkifier | |
| 489 * @param {function(!DocumentFragment)} callback | |
| 490 */ | |
| 491 WebInspector.TracingTimelineUIUtils.buildTraceEventDetails = function(event, mod
el, linkifier, callback) | |
| 492 { | |
| 493 var target = event.thread.target(); | |
| 494 var relatedNode = null; | |
| 495 var barrier = new CallbackBarrier(); | |
| 496 if (!event.previewElement) { | |
| 497 if (event.imageURL && target) | |
| 498 WebInspector.DOMPresentationUtils.buildImagePreviewContents(target,
event.imageURL, false, barrier.createCallback(saveImage)); | |
| 499 else if (event.picture) | |
| 500 WebInspector.TracingTimelineUIUtils.buildPicturePreviewContent(event
, barrier.createCallback(saveImage)); | |
| 501 } | |
| 502 if (event.backendNodeId && target) | |
| 503 target.domModel.pushNodesByBackendIdsToFrontend([event.backendNodeId], b
arrier.createCallback(setRelatedNode)); | |
| 504 if (event.invalidationTrackingEvents) | |
| 505 WebInspector.TracingTimelineUIUtils._pushInvalidationNodeIdsToFrontend(e
vent, barrier.createCallback(updateInvalidationNodeIds)); | |
| 506 barrier.callWhenDone(callbackWrapper); | |
| 507 | |
| 508 /** | |
| 509 * @param {!Element=} element | |
| 510 */ | |
| 511 function saveImage(element) | |
| 512 { | |
| 513 event.previewElement = element || null; | |
| 514 } | |
| 515 | |
| 516 /** | |
| 517 * @param {?Array.<!DOMAgent.NodeId>} nodeIds | |
| 518 */ | |
| 519 function setRelatedNode(nodeIds) | |
| 520 { | |
| 521 if (nodeIds) | |
| 522 relatedNode = target.domModel.nodeForId(nodeIds[0]); | |
| 523 } | |
| 524 | |
| 525 /** | |
| 526 * @param {?Array.<!DOMAgent.NodeId>} frontendNodeIds | |
| 527 * @param {?Array.<!DOMAgent.NodeId>} backendNodeIds | |
| 528 */ | |
| 529 function updateInvalidationNodeIds(frontendNodeIds, backendNodeIds) | |
| 530 { | |
| 531 if (!frontendNodeIds) | |
| 532 return; | |
| 533 if (frontendNodeIds.length !== backendNodeIds.length) { | |
| 534 console.error("Did not resolve the correct number of invalidation no
de ids."); | |
| 535 return; | |
| 536 } | |
| 537 | |
| 538 var backendToFrontendNodeIdMap = {}; | |
| 539 backendNodeIds.forEach(function(backendNodeId, index) { | |
| 540 backendToFrontendNodeIdMap[backendNodeId] = frontendNodeIds[index]; | |
| 541 }); | |
| 542 | |
| 543 if (event.nodeId) | |
| 544 event.frontendNodeId = backendToFrontendNodeIdMap[event.nodeId]; | |
| 545 event.invalidationTrackingEvents.forEach(function(invalidation) { | |
| 546 if (invalidation.nodeId) | |
| 547 invalidation.frontendNodeId = backendToFrontendNodeIdMap[invalid
ation.nodeId]; | |
| 548 }); | |
| 549 } | |
| 550 | |
| 551 function callbackWrapper() | |
| 552 { | |
| 553 callback(WebInspector.TracingTimelineUIUtils._buildTraceEventDetailsSync
hronously(event, model, linkifier, relatedNode)); | |
| 554 } | |
| 555 } | |
| 556 | |
| 557 /** | |
| 558 * @param {!WebInspector.TracingModel.Event} event | |
| 559 * @param {!WebInspector.TracingTimelineModel} model | |
| 560 * @param {!WebInspector.Linkifier} linkifier | |
| 561 * @param {?WebInspector.DOMNode} relatedNode | |
| 562 * @return {!DocumentFragment} | |
| 563 */ | |
| 564 WebInspector.TracingTimelineUIUtils._buildTraceEventDetailsSynchronously = funct
ion(event, model, linkifier, relatedNode) | |
| 565 { | |
| 566 var fragment = createDocumentFragment(); | |
| 567 var stats = {}; | |
| 568 var hasChildren = WebInspector.TracingTimelineUIUtils._aggregatedStatsForTra
ceEvent(stats, model, event); | |
| 569 | |
| 570 var selfTime = event.selfTime; | |
| 571 var selfCategory = WebInspector.TracingTimelineUIUtils.eventStyle(event).cat
egory; | |
| 572 // JSFrame events have 0 selfTime so we need to work around this below and a
dd the event's time to scripting category. | |
| 573 if (event.name === WebInspector.TracingTimelineModel.RecordType.JSFrame && !
event.selfTime && event.duration) { | |
| 574 selfTime = event.duration; | |
| 575 for (var categoryName in stats) | |
| 576 selfTime -= stats[categoryName]; | |
| 577 stats[selfCategory.name] = selfTime + (stats[selfCategory.name] || 0); | |
| 578 } | |
| 579 | |
| 580 var pieChart = hasChildren ? | |
| 581 WebInspector.TimelineUIUtils.generatePieChart(stats, selfCategory, selfT
ime) : | |
| 582 WebInspector.TimelineUIUtils.generatePieChart(stats); | |
| 583 | |
| 584 var recordTypes = WebInspector.TracingTimelineModel.RecordType; | |
| 585 | |
| 586 // This message may vary per event.name; | |
| 587 var relatedNodeLabel; | |
| 588 | |
| 589 var contentHelper = new WebInspector.TimelineDetailsContentHelper(event.thre
ad.target(), linkifier, true); | |
| 590 contentHelper.appendTextRow(WebInspector.UIString("Type"), WebInspector.Trac
ingTimelineUIUtils.eventTitle(event, model)); | |
| 591 contentHelper.appendTextRow(WebInspector.UIString("Self Time"), Number.milli
sToString(event.selfTime, true)); | |
| 592 contentHelper.appendTextRow(WebInspector.UIString("Start Time"), Number.mill
isToString((event.startTime - model.minimumRecordTime()))); | |
| 593 contentHelper.appendElementRow(WebInspector.UIString("Aggregated Time"), pie
Chart); | |
| 594 var eventData = event.args["data"]; | |
| 595 var initiator = event.initiator; | |
| 596 | |
| 597 switch (event.name) { | |
| 598 case recordTypes.GCEvent: | |
| 599 var delta = event.args["usedHeapSizeBefore"] - event.args["usedHeapSizeA
fter"]; | |
| 600 contentHelper.appendTextRow(WebInspector.UIString("Collected"), Number.b
ytesToString(delta)); | |
| 601 break; | |
| 602 case recordTypes.TimerFire: | |
| 603 case recordTypes.TimerInstall: | |
| 604 case recordTypes.TimerRemove: | |
| 605 contentHelper.appendTextRow(WebInspector.UIString("Timer ID"), eventData
["timerId"]); | |
| 606 if (event.name === recordTypes.TimerInstall) { | |
| 607 contentHelper.appendTextRow(WebInspector.UIString("Timeout"), Number
.millisToString(eventData["timeout"])); | |
| 608 contentHelper.appendTextRow(WebInspector.UIString("Repeats"), !event
Data["singleShot"]); | |
| 609 } | |
| 610 break; | |
| 611 case recordTypes.FireAnimationFrame: | |
| 612 contentHelper.appendTextRow(WebInspector.UIString("Callback ID"), eventD
ata["id"]); | |
| 613 break; | |
| 614 case recordTypes.FunctionCall: | |
| 615 if (eventData["scriptName"]) | |
| 616 contentHelper.appendLocationRow(WebInspector.UIString("Location"), e
ventData["scriptName"], eventData["scriptLine"]); | |
| 617 break; | |
| 618 case recordTypes.ResourceSendRequest: | |
| 619 case recordTypes.ResourceReceiveResponse: | |
| 620 case recordTypes.ResourceReceivedData: | |
| 621 case recordTypes.ResourceFinish: | |
| 622 var url = (event.name === recordTypes.ResourceSendRequest) ? eventData["
url"] : initiator.args["data"]["url"]; | |
| 623 if (url) | |
| 624 contentHelper.appendElementRow(WebInspector.UIString("Resource"), We
bInspector.linkifyResourceAsNode(url)); | |
| 625 if (eventData["requestMethod"]) | |
| 626 contentHelper.appendTextRow(WebInspector.UIString("Request Method"),
eventData["requestMethod"]); | |
| 627 if (typeof eventData["statusCode"] === "number") | |
| 628 contentHelper.appendTextRow(WebInspector.UIString("Status Code"), ev
entData["statusCode"]); | |
| 629 if (eventData["mimeType"]) | |
| 630 contentHelper.appendTextRow(WebInspector.UIString("MIME Type"), even
tData["mimeType"]); | |
| 631 if (eventData["encodedDataLength"]) | |
| 632 contentHelper.appendTextRow(WebInspector.UIString("Encoded Data Leng
th"), WebInspector.UIString("%d Bytes", eventData["encodedDataLength"])); | |
| 633 break; | |
| 634 case recordTypes.EvaluateScript: | |
| 635 var url = eventData["url"]; | |
| 636 if (url) | |
| 637 contentHelper.appendLocationRow(WebInspector.UIString("Script"), url
, eventData["lineNumber"]); | |
| 638 break; | |
| 639 case recordTypes.Paint: | |
| 640 var clip = eventData["clip"]; | |
| 641 contentHelper.appendTextRow(WebInspector.UIString("Location"), WebInspec
tor.UIString("(%d, %d)", clip[0], clip[1])); | |
| 642 var clipWidth = WebInspector.TimelineUIUtils.quadWidth(clip); | |
| 643 var clipHeight = WebInspector.TimelineUIUtils.quadHeight(clip); | |
| 644 contentHelper.appendTextRow(WebInspector.UIString("Dimensions"), WebInsp
ector.UIString("%d × %d", clipWidth, clipHeight)); | |
| 645 // Fall-through intended. | |
| 646 | |
| 647 case recordTypes.PaintSetup: | |
| 648 case recordTypes.Rasterize: | |
| 649 case recordTypes.ScrollLayer: | |
| 650 relatedNodeLabel = WebInspector.UIString("Layer root"); | |
| 651 break; | |
| 652 case recordTypes.PaintImage: | |
| 653 case recordTypes.DecodeLazyPixelRef: | |
| 654 case recordTypes.DecodeImage: | |
| 655 case recordTypes.ResizeImage: | |
| 656 case recordTypes.DrawLazyPixelRef: | |
| 657 relatedNodeLabel = WebInspector.UIString("Image element"); | |
| 658 if (event.imageURL) | |
| 659 contentHelper.appendElementRow(WebInspector.UIString("Image URL"), W
ebInspector.linkifyResourceAsNode(event.imageURL)); | |
| 660 break; | |
| 661 case recordTypes.RecalculateStyles: // We don't want to see default details. | |
| 662 contentHelper.appendTextRow(WebInspector.UIString("Elements affected"),
event.args["elementCount"]); | |
| 663 break; | |
| 664 case recordTypes.Layout: | |
| 665 var beginData = event.args["beginData"]; | |
| 666 contentHelper.appendTextRow(WebInspector.UIString("Nodes that need layou
t"), beginData["dirtyObjects"]); | |
| 667 contentHelper.appendTextRow(WebInspector.UIString("Layout tree size"), b
eginData["totalObjects"]); | |
| 668 contentHelper.appendTextRow(WebInspector.UIString("Layout scope"), | |
| 669 beginData["partialLayout"] ? WebInspector.UI
String("Partial") : WebInspector.UIString("Whole document")); | |
| 670 relatedNodeLabel = WebInspector.UIString("Layout root"); | |
| 671 break; | |
| 672 case recordTypes.ConsoleTime: | |
| 673 contentHelper.appendTextRow(WebInspector.UIString("Message"), event.name
); | |
| 674 break; | |
| 675 case recordTypes.WebSocketCreate: | |
| 676 case recordTypes.WebSocketSendHandshakeRequest: | |
| 677 case recordTypes.WebSocketReceiveHandshakeResponse: | |
| 678 case recordTypes.WebSocketDestroy: | |
| 679 var initiatorData = initiator ? initiator.args["data"] : eventData; | |
| 680 if (typeof initiatorData["webSocketURL"] !== "undefined") | |
| 681 contentHelper.appendTextRow(WebInspector.UIString("URL"), initiatorD
ata["webSocketURL"]); | |
| 682 if (typeof initiatorData["webSocketProtocol"] !== "undefined") | |
| 683 contentHelper.appendTextRow(WebInspector.UIString("WebSocket Protoco
l"), initiatorData["webSocketProtocol"]); | |
| 684 if (typeof eventData["message"] !== "undefined") | |
| 685 contentHelper.appendTextRow(WebInspector.UIString("Message"), eventD
ata["message"]); | |
| 686 break; | |
| 687 case recordTypes.EmbedderCallback: | |
| 688 contentHelper.appendTextRow(WebInspector.UIString("Callback Function"),
eventData["callbackName"]); | |
| 689 break; | |
| 690 default: | |
| 691 var detailsNode = WebInspector.TracingTimelineUIUtils.buildDetailsNodeFo
rTraceEvent(event, linkifier); | |
| 692 if (detailsNode) | |
| 693 contentHelper.appendElementRow(WebInspector.UIString("Details"), det
ailsNode); | |
| 694 break; | |
| 695 } | |
| 696 | |
| 697 if (relatedNode) | |
| 698 contentHelper.appendElementRow(relatedNodeLabel || WebInspector.UIString
("Related node"), WebInspector.DOMPresentationUtils.linkifyNodeReference(related
Node)); | |
| 699 | |
| 700 if (eventData && eventData["scriptName"] && event.name !== recordTypes.Funct
ionCall) | |
| 701 contentHelper.appendLocationRow(WebInspector.UIString("Function Call"),
eventData["scriptName"], eventData["scriptLine"]); | |
| 702 | |
| 703 var warning = event.warning; | |
| 704 if (warning) { | |
| 705 var div = createElement("div"); | |
| 706 div.textContent = warning; | |
| 707 contentHelper.appendElementRow(WebInspector.UIString("Warning"), div); | |
| 708 } | |
| 709 if (event.previewElement) | |
| 710 contentHelper.appendElementRow(WebInspector.UIString("Preview"), event.p
reviewElement); | |
| 711 | |
| 712 if (event.stackTrace || (event.initiator && event.initiator.stackTrace) || e
vent.invalidationTrackingEvents) | |
| 713 WebInspector.TracingTimelineUIUtils._generateCauses(event, contentHelper
); | |
| 714 | |
| 715 fragment.appendChild(contentHelper.element); | |
| 716 | |
| 717 return fragment; | |
| 718 } | |
| 719 | |
| 720 /** | |
| 721 * @param {!WebInspector.TracingModel.Event} event | |
| 722 * @param {!WebInspector.TimelineDetailsContentHelper} contentHelper | |
| 723 */ | |
| 724 WebInspector.TracingTimelineUIUtils._generateCauses = function(event, contentHel
per) | |
| 725 { | |
| 726 var recordTypes = WebInspector.TracingTimelineModel.RecordType; | |
| 727 | |
| 728 var callSiteStackLabel; | |
| 729 var stackLabel; | |
| 730 var initiator = event.initiator; | |
| 731 | |
| 732 switch (event.name) { | |
| 733 case recordTypes.TimerFire: | |
| 734 callSiteStackLabel = WebInspector.UIString("Timer installed"); | |
| 735 break; | |
| 736 case recordTypes.FireAnimationFrame: | |
| 737 callSiteStackLabel = WebInspector.UIString("Animation frame requested"); | |
| 738 break; | |
| 739 case recordTypes.RecalculateStyles: | |
| 740 stackLabel = WebInspector.UIString("Recalculation was forced"); | |
| 741 break; | |
| 742 case recordTypes.Layout: | |
| 743 callSiteStackLabel = WebInspector.UIString("First layout invalidation"); | |
| 744 stackLabel = WebInspector.UIString("Layout forced"); | |
| 745 break; | |
| 746 } | |
| 747 | |
| 748 // Direct cause. | |
| 749 if (event.stackTrace) | |
| 750 contentHelper.appendStackTrace(stackLabel || WebInspector.UIString("Stac
k trace"), event.stackTrace); | |
| 751 | |
| 752 // Indirect causes. | |
| 753 if (event.invalidationTrackingEvents) { // Full invalidation tracking (exper
imental). | |
| 754 WebInspector.TracingTimelineUIUtils._generateInvalidations(event, conten
tHelper); | |
| 755 } else if (initiator && initiator.stackTrace) { // Partial invalidation trac
king. | |
| 756 contentHelper.appendStackTrace(callSiteStackLabel || WebInspector.UIStri
ng("First invalidated"), initiator.stackTrace); | |
| 757 } | |
| 758 } | |
| 759 | |
| 760 /** | |
| 761 * @param {!WebInspector.TracingModel.Event} event | |
| 762 * @param {!WebInspector.TimelineDetailsContentHelper} contentHelper | |
| 763 */ | |
| 764 WebInspector.TracingTimelineUIUtils._generateInvalidations = function(event, con
tentHelper) | |
| 765 { | |
| 766 if (!event.invalidationTrackingEvents) | |
| 767 return; | |
| 768 | |
| 769 var target = event.thread.target(); | |
| 770 var invalidations = {}; | |
| 771 event.invalidationTrackingEvents.forEach(function(invalidation) { | |
| 772 if (!invalidations[invalidation.type]) | |
| 773 invalidations[invalidation.type] = [invalidation]; | |
| 774 else | |
| 775 invalidations[invalidation.type].push(invalidation); | |
| 776 }); | |
| 777 | |
| 778 Object.keys(invalidations).forEach(function(type) { | |
| 779 WebInspector.TracingTimelineUIUtils._generateInvalidationsForType( | |
| 780 type, target, invalidations[type], contentHelper); | |
| 781 }); | |
| 782 } | |
| 783 | |
| 784 /** | |
| 785 * @param {string} type | |
| 786 * @param {?WebInspector.Target} target | |
| 787 * @param {!Object} invalidationEvents | |
| 788 * @param {!WebInspector.TimelineDetailsContentHelper} contentHelper | |
| 789 */ | |
| 790 WebInspector.TracingTimelineUIUtils._generateInvalidationsForType = function(typ
e, target, invalidationEvents, contentHelper) | |
| 791 { | |
| 792 var title; | |
| 793 switch (type) { | |
| 794 case WebInspector.TracingTimelineModel.RecordType.StyleRecalcInvalidationTra
cking: | |
| 795 title = WebInspector.UIString("Style invalidations"); | |
| 796 break; | |
| 797 case WebInspector.TracingTimelineModel.RecordType.LayoutInvalidationTracking
: | |
| 798 title = WebInspector.UIString("Layout invalidations"); | |
| 799 break; | |
| 800 default: | |
| 801 title = WebInspector.UIString("Other invalidations"); | |
| 802 break; | |
| 803 } | |
| 804 | |
| 805 var detailsNode = createElementWithClass("div", "timeline-details-view-row")
; | |
| 806 var titleElement = detailsNode.createChild("span", "timeline-details-view-ro
w-title"); | |
| 807 titleElement.textContent = WebInspector.UIString("%s: ", title); | |
| 808 var eventsList = detailsNode.createChild("ol"); | |
| 809 invalidationEvents.forEach(appendInvalidations); | |
| 810 | |
| 811 contentHelper.element.appendChild(detailsNode); | |
| 812 | |
| 813 | |
| 814 function appendInvalidations(invalidation, index) | |
| 815 { | |
| 816 var row = eventsList.createChild("li"); | |
| 817 var nodeRow = row.createChild("div"); | |
| 818 var node = target.domModel.nodeForId(invalidation.frontendNodeId); | |
| 819 if (node) | |
| 820 nodeRow.appendChild(WebInspector.DOMPresentationUtils.linkifyNodeRef
erence(node)); | |
| 821 else if (invalidation.nodeName) | |
| 822 nodeRow.textContent = WebInspector.UIString("[ %s ]", invalidation.n
odeName); | |
| 823 else | |
| 824 nodeRow.textContent = WebInspector.UIString("[ unknown node ]"); | |
| 825 | |
| 826 if (invalidation.reason) { | |
| 827 var reasonRow = row.createChild("div"); | |
| 828 var reason = invalidation.reason; | |
| 829 reasonRow.textContent = WebInspector.UIString("Reason: %s.", reason)
; | |
| 830 } | |
| 831 | |
| 832 if (invalidation.stackTrace) | |
| 833 contentHelper.createChildStackTraceElement(row, invalidation.stackTr
ace); | |
| 834 } | |
| 835 } | |
| 836 | |
| 837 /** | |
| 838 * @param {!WebInspector.TracingModel.Event} event | |
| 839 * @param {function(?Array.<number>, ?Array.<number>)} callback | |
| 840 */ | |
| 841 WebInspector.TracingTimelineUIUtils._pushInvalidationNodeIdsToFrontend = functio
n(event, callback) | |
| 842 { | |
| 843 var backendNodeIds = []; | |
| 844 | |
| 845 var dedupedNodeIds = {}; | |
| 846 if (event.nodeId) { | |
| 847 backendNodeIds.push(event.nodeId); | |
| 848 dedupedNodeIds[event.nodeId] = true; | |
| 849 } | |
| 850 event.invalidationTrackingEvents.forEach(function(invalidation) { | |
| 851 if (invalidation.nodeId && !dedupedNodeIds[invalidation.nodeId]) { | |
| 852 backendNodeIds.push(invalidation.nodeId); | |
| 853 dedupedNodeIds[invalidation.nodeId] = true; | |
| 854 } | |
| 855 }); | |
| 856 | |
| 857 var target = event.thread.target(); | |
| 858 target.domModel.pushNodesByBackendIdsToFrontend(backendNodeIds, function(fro
ntendNodeIds) { | |
| 859 callback(frontendNodeIds, backendNodeIds); | |
| 860 }); | |
| 861 } | |
| 862 | |
| 863 /** | |
| 864 * @param {!Object} total | |
| 865 * @param {!WebInspector.TracingTimelineModel} model | |
| 866 * @param {!WebInspector.TracingModel.Event} event | |
| 867 * @return {boolean} | |
| 868 */ | |
| 869 WebInspector.TracingTimelineUIUtils._aggregatedStatsForTraceEvent = function(tot
al, model, event) | |
| 870 { | |
| 871 var events = model.inspectedTargetEvents(); | |
| 872 /** | |
| 873 * @param {number} startTime | |
| 874 * @param {!WebInspector.TracingModel.Event} e | |
| 875 * @return {number} | |
| 876 */ | |
| 877 function eventComparator(startTime, e) | |
| 878 { | |
| 879 return startTime - e.startTime; | |
| 880 } | |
| 881 var index = events.binaryIndexOf(event.startTime, eventComparator); | |
| 882 var hasChildren = false; | |
| 883 var endTime = event.endTime; | |
| 884 if (endTime) { | |
| 885 for (var i = index; i < events.length; i++) { | |
| 886 var nextEvent = events[i]; | |
| 887 if (nextEvent.startTime >= endTime) | |
| 888 break; | |
| 889 if (!nextEvent.selfTime) | |
| 890 continue; | |
| 891 if (nextEvent.thread !== event.thread) | |
| 892 continue; | |
| 893 if (i > index) | |
| 894 hasChildren = true; | |
| 895 var categoryName = WebInspector.TracingTimelineUIUtils.eventStyle(ne
xtEvent).category.name; | |
| 896 total[categoryName] = (total[categoryName] || 0) + nextEvent.selfTim
e; | |
| 897 } | |
| 898 } | |
| 899 if (WebInspector.TracingModel.isAsyncPhase(event.phase)) { | |
| 900 if (event.endTime) { | |
| 901 var aggregatedTotal = 0; | |
| 902 for (var categoryName in total) | |
| 903 aggregatedTotal += total[categoryName]; | |
| 904 total["idle"] = Math.max(0, event.endTime - event.startTime - aggreg
atedTotal); | |
| 905 } | |
| 906 return false; | |
| 907 } | |
| 908 return hasChildren; | |
| 909 } | |
| 910 | |
| 911 /** | |
| 912 * @param {!WebInspector.TracingModel.Event} event | |
| 913 * @param {function(!Element=)} callback | |
| 914 */ | |
| 915 WebInspector.TracingTimelineUIUtils.buildPicturePreviewContent = function(event,
callback) | |
| 916 { | |
| 917 | |
| 918 new WebInspector.LayerPaintEvent(event).loadPicture(onSnapshotLoaded); | |
| 919 /** | |
| 920 * @param {?Array.<number>} rect | |
| 921 * @param {?WebInspector.PaintProfilerSnapshot} snapshot | |
| 922 */ | |
| 923 function onSnapshotLoaded(rect, snapshot) | |
| 924 { | |
| 925 if (!snapshot) { | |
| 926 callback(); | |
| 927 return; | |
| 928 } | |
| 929 snapshot.requestImage(null, null, 1, onGotImage); | |
| 930 snapshot.dispose(); | |
| 931 } | |
| 932 | |
| 933 /** | |
| 934 * @param {string=} imageURL | |
| 935 */ | |
| 936 function onGotImage(imageURL) | |
| 937 { | |
| 938 if (!imageURL) { | |
| 939 callback(); | |
| 940 return; | |
| 941 } | |
| 942 var container = createElement("div"); | |
| 943 container.className = "image-preview-container"; | |
| 944 var img = container.createChild("img"); | |
| 945 img.src = imageURL; | |
| 946 callback(container); | |
| 947 } | |
| 948 } | |
| 949 | |
| 950 /** | |
| 951 * @param {string} recordType | |
| 952 * @param {string=} title | |
| 953 * @return {!Element} | |
| 954 */ | |
| 955 WebInspector.TracingTimelineUIUtils._createEventDivider = function(recordType, t
itle) | |
| 956 { | |
| 957 var eventDivider = createElement("div"); | |
| 958 eventDivider.className = "resources-event-divider"; | |
| 959 var recordTypes = WebInspector.TracingTimelineModel.RecordType; | |
| 960 | |
| 961 if (recordType === recordTypes.MarkDOMContent) | |
| 962 eventDivider.className += " resources-blue-divider"; | |
| 963 else if (recordType === recordTypes.MarkLoad) | |
| 964 eventDivider.className += " resources-red-divider"; | |
| 965 else if (recordType === recordTypes.MarkFirstPaint) | |
| 966 eventDivider.className += " resources-green-divider"; | |
| 967 else if (recordType === recordTypes.TimeStamp || recordType === recordTypes.
ConsoleTime) | |
| 968 eventDivider.className += " resources-orange-divider"; | |
| 969 else if (recordType === recordTypes.BeginFrame) | |
| 970 eventDivider.className += " timeline-frame-divider"; | |
| 971 | |
| 972 if (title) | |
| 973 eventDivider.title = title; | |
| 974 | |
| 975 return eventDivider; | |
| 976 } | |
| 977 | |
| 978 /** | |
| 979 * @return {!Array.<string>} | |
| 980 */ | |
| 981 WebInspector.TracingTimelineUIUtils._visibleTypes = function() | |
| 982 { | |
| 983 var eventStyles = WebInspector.TracingTimelineUIUtils._initEventStyles(); | |
| 984 var result = []; | |
| 985 for (var name in eventStyles) { | |
| 986 if (!eventStyles[name].hidden) | |
| 987 result.push(name); | |
| 988 } | |
| 989 return result; | |
| 990 } | |
| 991 | |
| 992 /** | |
| 993 * @return {!WebInspector.TracingTimelineModel.Filter} | |
| 994 */ | |
| 995 WebInspector.TracingTimelineUIUtils.hiddenEventsFilter = function() | |
| 996 { | |
| 997 return new WebInspector.TracingTimelineModel.InclusiveEventNameFilter(WebIns
pector.TracingTimelineUIUtils._visibleTypes()); | |
| 998 } | |
| OLD | NEW |