Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // | |
|
yurys
2014/06/04 06:47:23
Pleas remove empty // lines around the license hea
| |
| 2 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 3 // Use of this source code is governed by a BSD-style license that can be | |
| 4 // found in the LICENSE file. | |
| 5 // | |
| 6 | |
| 7 /** | |
| 8 */ | |
| 9 WebInspector.TracingTimelineUIUtils = function() { } | |
| 10 | |
| 11 /** | |
| 12 * @param {!WebInspector.TracingModel.Event} event | |
| 13 * @param {!WebInspector.Linkifier} linkifier | |
| 14 * @param {boolean} loadedFromFile | |
| 15 * @param {?WebInspector.TimelineTraceEventBindings} bindings | |
| 16 * @param {!WebInspector.Target} target | |
| 17 * @return {?Node} | |
| 18 */ | |
| 19 WebInspector.TracingTimelineUIUtils.buildDetailsNodeForTraceEvent = function(eve nt, linkifier, loadedFromFile, bindings, target) | |
| 20 { | |
| 21 var recordType = WebInspector.TimelineTraceEventBindings.RecordType; | |
| 22 | |
| 23 var details; | |
| 24 var detailsText; | |
| 25 var eventData = event.args.data; | |
| 26 switch (event.name) { | |
| 27 case recordType.GCEvent: | |
| 28 var delta = event.args["usedHeapSizeBefore"] - event.args["usedHeapSizeA fter"]; | |
| 29 detailsText = WebInspector.UIString("%s collected", Number.bytesToString (delta)); | |
| 30 break; | |
| 31 case recordType.TimerFire: | |
| 32 detailsText = eventData["timerId"]; | |
| 33 break; | |
| 34 case recordType.FunctionCall: | |
| 35 details = linkifyLocation(eventData["scriptId"], eventData["scriptName"] , eventData["scriptLine"], 0); | |
| 36 break; | |
| 37 case recordType.FireAnimationFrame: | |
| 38 detailsText = eventData["id"]; | |
| 39 break; | |
| 40 case recordType.EventDispatch: | |
| 41 detailsText = eventData ? eventData["type"] : null; | |
| 42 break; | |
| 43 case recordType.Paint: | |
| 44 var width = WebInspector.TimelineUIUtils._quadWidth(eventData.clip); | |
| 45 var height = WebInspector.TimelineUIUtils._quadHeight(eventData.clip); | |
| 46 if (width && height) | |
| 47 detailsText = WebInspector.UIString("%d\u2009\u00d7\u2009%d", width, height); | |
| 48 break; | |
| 49 case recordType.TimerInstall: | |
| 50 case recordType.TimerRemove: | |
| 51 details = linkifyTopCallFrame(); | |
| 52 detailsText = eventData["timerId"]; | |
| 53 break; | |
| 54 case recordType.RequestAnimationFrame: | |
| 55 case recordType.CancelAnimationFrame: | |
| 56 details = linkifyTopCallFrame(); | |
| 57 detailsText = eventData["id"]; | |
| 58 break; | |
| 59 case recordType.ParseHTML: | |
| 60 case recordType.RecalculateStyles: | |
| 61 details = linkifyTopCallFrame(); | |
| 62 break; | |
| 63 case recordType.EvaluateScript: | |
| 64 var url = eventData["url"]; | |
| 65 if (url) | |
| 66 details = linkifyLocation("", url, eventData["lineNumber"], 0); | |
| 67 break; | |
| 68 case recordType.XHRReadyStateChange: | |
| 69 case recordType.XHRLoad: | |
| 70 case recordType.ResourceSendRequest: | |
| 71 case recordType.DecodeImage: | |
| 72 case recordType.ResizeImage: | |
| 73 var url = eventData["url"]; | |
| 74 if (url) | |
| 75 detailsText = WebInspector.displayNameForURL(url); | |
| 76 break; | |
| 77 case recordType.ResourceReceivedData: | |
| 78 case recordType.ResourceReceiveResponse: | |
| 79 case recordType.ResourceFinish: | |
| 80 var initiator = event.initiator; | |
| 81 if (initiator) { | |
| 82 var url = initiator.args.data["url"]; | |
| 83 if (url) | |
| 84 detailsText = WebInspector.displayNameForURL(url); | |
| 85 } | |
| 86 break; | |
| 87 case recordType.ConsoleTime: | |
| 88 detailsText = eventData["message"]; | |
| 89 break; | |
| 90 case recordType.EmbedderCallback: | |
| 91 detailsText = eventData["callbackName"]; | |
| 92 break; | |
| 93 | |
| 94 case recordType.PaintImage: | |
| 95 case recordType.DecodeImage: | |
| 96 case recordType.ResizeImage: | |
| 97 case recordType.DecodeLazyPixelRef: | |
| 98 var url = event.imageURL; | |
| 99 if (url) | |
| 100 detailsText = WebInspector.displayNameForURL(url); | |
| 101 break; | |
| 102 | |
| 103 default: | |
| 104 details = linkifyTopCallFrame(); | |
| 105 break; | |
| 106 } | |
| 107 | |
| 108 if (!details && detailsText) | |
| 109 details = document.createTextNode(detailsText); | |
| 110 return details; | |
| 111 | |
| 112 /** | |
| 113 * @param {string} scriptId | |
| 114 * @param {string} url | |
| 115 * @param {number} lineNumber | |
| 116 * @param {number=} columnNumber | |
| 117 */ | |
| 118 function linkifyLocation(scriptId, url, lineNumber, columnNumber) | |
| 119 { | |
| 120 if (!loadedFromFile && scriptId !== "0") { | |
| 121 var location = new WebInspector.DebuggerModel.Location( | |
| 122 target, | |
| 123 scriptId, | |
| 124 lineNumber - 1, | |
| 125 (columnNumber || 1) - 1); | |
| 126 return linkifier.linkifyRawLocation(location, "timeline-details"); | |
| 127 } | |
| 128 | |
| 129 if (!url) | |
| 130 return null; | |
| 131 | |
| 132 // FIXME(62725): stack trace line/column numbers are one-based. | |
| 133 columnNumber = columnNumber ? columnNumber - 1 : 0; | |
| 134 return linkifier.linkifyLocation(target, url, lineNumber - 1, columnNumb er, "timeline-details"); | |
| 135 } | |
| 136 | |
| 137 /** | |
| 138 * @param {!ConsoleAgent.CallFrame} callFrame | |
| 139 */ | |
| 140 function linkifyCallFrame(callFrame) | |
| 141 { | |
| 142 return linkifyLocation(callFrame.scriptId, callFrame.url, callFrame.line Number, callFrame.columnNumber); | |
| 143 } | |
| 144 | |
| 145 /** | |
| 146 * @return {?Element} | |
| 147 */ | |
| 148 function linkifyTopCallFrame() | |
| 149 { | |
| 150 if (!bindings) | |
| 151 return null; | |
| 152 var stackTrace = event.stackTrace; | |
| 153 if (!stackTrace) { | |
| 154 var initiator = event.initiator; | |
| 155 if (initiator) | |
| 156 stackTrace = initiator.stackTrace; | |
| 157 } | |
| 158 if (!stackTrace || !stackTrace.length) | |
| 159 return null; | |
| 160 return linkifyCallFrame(stackTrace[0]); | |
| 161 } | |
| 162 } | |
| 163 | |
| 164 /** | |
| 165 * @param {!WebInspector.TracingModel.Event} event | |
| 166 * @param {!WebInspector.TracingModel} model | |
| 167 * @param {!WebInspector.Linkifier} linkifier | |
| 168 * @param {function(!DocumentFragment)} callback | |
| 169 * @param {boolean} loadedFromFile | |
| 170 * @param {?WebInspector.TimelineTraceEventBindings} bindings | |
| 171 * @param {!WebInspector.Target} target | |
| 172 */ | |
| 173 WebInspector.TracingTimelineUIUtils.buildTraceEventDetails = function(event, mod el, linkifier, callback, loadedFromFile, bindings, target) | |
| 174 { | |
| 175 var relatedNode = null; | |
| 176 var barrier = new CallbackBarrier(); | |
| 177 if (event.imageURL && !event.previewElement) | |
| 178 WebInspector.DOMPresentationUtils.buildImagePreviewContents(target, even t.imageURL, false, barrier.createCallback(saveImage)); | |
| 179 if (event.backendNodeId) | |
| 180 target.domModel.pushNodesByBackendIdsToFrontend([event.backendNodeId], b arrier.createCallback(setRelatedNode)); | |
| 181 barrier.callWhenDone(callbackWrapper); | |
| 182 | |
| 183 /** | |
| 184 * @param {!Element=} element | |
| 185 */ | |
| 186 function saveImage(element) | |
| 187 { | |
| 188 event.previewElement = element || null; | |
| 189 } | |
| 190 | |
| 191 /** | |
| 192 * @param {?Array.<!DOMAgent.NodeId>} nodeIds | |
| 193 */ | |
| 194 function setRelatedNode(nodeIds) | |
| 195 { | |
| 196 if (nodeIds) | |
| 197 relatedNode = target.domModel.nodeForId(nodeIds[0]); | |
| 198 } | |
| 199 | |
| 200 function callbackWrapper() | |
| 201 { | |
| 202 callback(WebInspector.TracingTimelineUIUtils._buildTraceEventDetailsSync hronously(event, model, linkifier, relatedNode, loadedFromFile, bindings, target )); | |
| 203 } | |
| 204 } | |
| 205 | |
| 206 /** | |
| 207 * @param {!WebInspector.TracingModel.Event} event | |
| 208 * @param {!WebInspector.TracingModel} model | |
| 209 * @param {!WebInspector.Linkifier} linkifier | |
| 210 * @param {?WebInspector.DOMNode} relatedNode | |
| 211 * @param {boolean} loadedFromFile | |
| 212 * @param {?WebInspector.TimelineTraceEventBindings} bindings | |
| 213 * @param {!WebInspector.Target} target | |
| 214 * @return {!DocumentFragment} | |
| 215 */ | |
| 216 WebInspector.TracingTimelineUIUtils._buildTraceEventDetailsSynchronously = funct ion(event, model, linkifier, relatedNode, loadedFromFile, bindings, target) | |
| 217 { | |
| 218 var fragment = document.createDocumentFragment(); | |
| 219 var stats = WebInspector.TracingTimelineUIUtils._aggregatedStatsForTraceEven t(model, event); | |
| 220 var pieChart = stats.hasChildren ? | |
| 221 WebInspector.TimelineUIUtils.generatePieChart(stats.aggregatedStats, Web Inspector.TimelineUIUtils.styleForTimelineEvent(event.name).category, event.self Time / 1000) : | |
| 222 WebInspector.TimelineUIUtils.generatePieChart(stats.aggregatedStats); | |
| 223 fragment.appendChild(pieChart); | |
| 224 | |
| 225 var recordTypes = WebInspector.TimelineTraceEventBindings.RecordType; | |
| 226 | |
| 227 // The messages may vary per event.name; | |
| 228 var callSiteStackTraceLabel; | |
| 229 var callStackLabel; | |
| 230 var relatedNodeLabel; | |
| 231 | |
| 232 var contentHelper = new WebInspector.TimelineDetailsContentHelper(target, li nkifier, true); | |
| 233 contentHelper.appendTextRow(WebInspector.UIString("Self Time"), Number.milli sToString(event.selfTime / 1000, true)); | |
| 234 contentHelper.appendTextRow(WebInspector.UIString("Start Time"), Number.mill isToString((event.startTime - model.minimumRecordTime()) / 1000)); | |
| 235 var eventData = event.args.data; | |
| 236 var initiator = event.initiator; | |
| 237 | |
| 238 switch (event.name) { | |
| 239 case recordTypes.GCEvent: | |
| 240 var delta = event.args["usedHeapSizeBefore"] - event.args["usedHeapSizeA fter"]; | |
| 241 contentHelper.appendTextRow(WebInspector.UIString("Collected"), Number.b ytesToString(delta)); | |
| 242 break; | |
| 243 case recordTypes.TimerFire: | |
| 244 callSiteStackTraceLabel = WebInspector.UIString("Timer installed"); | |
| 245 // Fall-through intended. | |
| 246 | |
| 247 case recordTypes.TimerInstall: | |
| 248 case recordTypes.TimerRemove: | |
| 249 contentHelper.appendTextRow(WebInspector.UIString("Timer ID"), eventData ["timerId"]); | |
| 250 if (event.name === recordTypes.TimerInstall) { | |
| 251 contentHelper.appendTextRow(WebInspector.UIString("Timeout"), Number .millisToString(eventData["timeout"])); | |
| 252 contentHelper.appendTextRow(WebInspector.UIString("Repeats"), !event Data["singleShot"]); | |
| 253 } | |
| 254 break; | |
| 255 case recordTypes.FireAnimationFrame: | |
| 256 callSiteStackTraceLabel = WebInspector.UIString("Animation frame request ed"); | |
| 257 contentHelper.appendTextRow(WebInspector.UIString("Callback ID"), eventD ata["id"]); | |
| 258 break; | |
| 259 case recordTypes.FunctionCall: | |
| 260 if (eventData["scriptName"]) | |
| 261 contentHelper.appendLocationRow(WebInspector.UIString("Location"), e ventData["scriptName"], eventData["scriptLine"]); | |
| 262 break; | |
| 263 case recordTypes.ResourceSendRequest: | |
| 264 case recordTypes.ResourceReceiveResponse: | |
| 265 case recordTypes.ResourceReceivedData: | |
| 266 case recordTypes.ResourceFinish: | |
| 267 var url = (event.name === recordTypes.ResourceSendRequest) ? eventData[" url"] : initiator.args.data["url"]; | |
| 268 if (url) | |
| 269 contentHelper.appendElementRow(WebInspector.UIString("Resource"), We bInspector.linkifyResourceAsNode(url)); | |
| 270 if (event.previewElement) | |
| 271 contentHelper.appendElementRow(WebInspector.UIString("Preview"), eve nt.previewElement); | |
| 272 if (eventData["requestMethod"]) | |
| 273 contentHelper.appendTextRow(WebInspector.UIString("Request Method"), eventData["requestMethod"]); | |
| 274 if (typeof eventData["statusCode"] === "number") | |
| 275 contentHelper.appendTextRow(WebInspector.UIString("Status Code"), ev entData["statusCode"]); | |
| 276 if (eventData["mimeType"]) | |
| 277 contentHelper.appendTextRow(WebInspector.UIString("MIME Type"), even tData["mimeType"]); | |
| 278 if (eventData["encodedDataLength"]) | |
| 279 contentHelper.appendTextRow(WebInspector.UIString("Encoded Data Leng th"), WebInspector.UIString("%d Bytes", eventData["encodedDataLength"])); | |
| 280 break; | |
| 281 case recordTypes.EvaluateScript: | |
| 282 var url = eventData["url"]; | |
| 283 if (url) | |
| 284 contentHelper.appendLocationRow(WebInspector.UIString("Script"), url , eventData["lineNumber"]); | |
| 285 break; | |
| 286 case recordTypes.Paint: | |
| 287 var clip = eventData["clip"]; | |
| 288 contentHelper.appendTextRow(WebInspector.UIString("Location"), WebInspec tor.UIString("(%d, %d)", clip[0], clip[1])); | |
| 289 var clipWidth = WebInspector.TimelineUIUtils._quadWidth(clip); | |
| 290 var clipHeight = WebInspector.TimelineUIUtils._quadHeight(clip); | |
| 291 contentHelper.appendTextRow(WebInspector.UIString("Dimensions"), WebInsp ector.UIString("%d × %d", clipWidth, clipHeight)); | |
| 292 // Fall-through intended. | |
| 293 | |
| 294 case recordTypes.PaintSetup: | |
| 295 case recordTypes.Rasterize: | |
| 296 case recordTypes.ScrollLayer: | |
| 297 relatedNodeLabel = WebInspector.UIString("Layer root"); | |
| 298 break; | |
| 299 case recordTypes.PaintImage: | |
| 300 case recordTypes.DecodeLazyPixelRef: | |
| 301 case recordTypes.DecodeImage: | |
| 302 case recordTypes.ResizeImage: | |
| 303 case recordTypes.DrawLazyPixelRef: | |
| 304 relatedNodeLabel = WebInspector.UIString("Image element"); | |
| 305 if (event.imageURL) | |
| 306 contentHelper.appendElementRow(WebInspector.UIString("Image URL"), W ebInspector.linkifyResourceAsNode(event.imageURL)); | |
| 307 if (event.previewElement) | |
| 308 contentHelper.appendElementRow(WebInspector.UIString("Preview"), eve nt.previewElement); | |
| 309 break; | |
| 310 case recordTypes.RecalculateStyles: // We don't want to see default details. | |
| 311 contentHelper.appendTextRow(WebInspector.UIString("Elements affected"), event.args["elementCount"]); | |
| 312 callStackLabel = WebInspector.UIString("Styles recalculation forced"); | |
| 313 break; | |
| 314 case recordTypes.Layout: | |
| 315 var beginData = event.args["beginData"]; | |
| 316 contentHelper.appendTextRow(WebInspector.UIString("Nodes that need layou t"), beginData["dirtyObjects"]); | |
| 317 contentHelper.appendTextRow(WebInspector.UIString("Layout tree size"), b eginData["totalObjects"]); | |
| 318 contentHelper.appendTextRow(WebInspector.UIString("Layout scope"), | |
| 319 beginData["partialLayout"] ? WebInspector.UI String("Partial") : WebInspector.UIString("Whole document")); | |
| 320 callSiteStackTraceLabel = WebInspector.UIString("Layout invalidated"); | |
| 321 callStackLabel = WebInspector.UIString("Layout forced"); | |
| 322 relatedNodeLabel = WebInspector.UIString("Layout root"); | |
| 323 break; | |
| 324 case recordTypes.ConsoleTime: | |
| 325 contentHelper.appendTextRow(WebInspector.UIString("Message"), eventData[ "message"]); | |
| 326 break; | |
| 327 case recordTypes.WebSocketCreate: | |
| 328 case recordTypes.WebSocketSendHandshakeRequest: | |
| 329 case recordTypes.WebSocketReceiveHandshakeResponse: | |
| 330 case recordTypes.WebSocketDestroy: | |
| 331 var initiatorData = initiator ? initiator.args.data : eventData; | |
| 332 if (typeof initiatorData["webSocketURL"] !== "undefined") | |
| 333 contentHelper.appendTextRow(WebInspector.UIString("URL"), initiatorD ata["webSocketURL"]); | |
| 334 if (typeof initiatorData["webSocketProtocol"] !== "undefined") | |
| 335 contentHelper.appendTextRow(WebInspector.UIString("WebSocket Protoco l"), initiatorData["webSocketProtocol"]); | |
| 336 if (typeof eventData["message"] !== "undefined") | |
| 337 contentHelper.appendTextRow(WebInspector.UIString("Message"), eventD ata["message"]); | |
| 338 break; | |
| 339 case recordTypes.EmbedderCallback: | |
| 340 contentHelper.appendTextRow(WebInspector.UIString("Callback Function"), eventData["callbackName"]); | |
| 341 break; | |
| 342 default: | |
| 343 var detailsNode = WebInspector.TracingTimelineUIUtils.buildDetailsNodeFo rTraceEvent(event, linkifier, loadedFromFile, bindings, target); | |
| 344 if (detailsNode) | |
| 345 contentHelper.appendElementRow(WebInspector.UIString("Details"), det ailsNode); | |
| 346 break; | |
| 347 } | |
| 348 | |
| 349 if (relatedNode) | |
| 350 contentHelper.appendElementRow(relatedNodeLabel || WebInspector.UIString ("Related node"), WebInspector.DOMPresentationUtils.linkifyNodeReference(related Node)); | |
| 351 | |
| 352 if (eventData && eventData["scriptName"] && event.name !== recordTypes.Funct ionCall) | |
| 353 contentHelper.appendLocationRow(WebInspector.UIString("Function Call"), eventData["scriptName"], eventData["scriptLine"]); | |
| 354 | |
| 355 if (initiator) { | |
| 356 var callSiteStackTrace = initiator.stackTrace; | |
| 357 if (callSiteStackTrace) | |
| 358 contentHelper.appendStackTrace(callSiteStackTraceLabel || WebInspect or.UIString("Call Site stack"), callSiteStackTrace); | |
| 359 } | |
| 360 var eventStackTrace = event.stackTrace; | |
| 361 if (eventStackTrace) | |
| 362 contentHelper.appendStackTrace(callStackLabel || WebInspector.UIString(" Call Stack"), eventStackTrace); | |
| 363 | |
| 364 var warning = event.warning; | |
| 365 if (warning) { | |
| 366 var div = document.createElement("div"); | |
| 367 div.textContent = warning; | |
| 368 contentHelper.appendElementRow(WebInspector.UIString("Warning"), div); | |
| 369 } | |
| 370 fragment.appendChild(contentHelper.element); | |
| 371 return fragment; | |
| 372 } | |
| 373 | |
| 374 /** | |
| 375 * @param {!WebInspector.TracingModel} model | |
| 376 * @param {!WebInspector.TracingModel.Event} event | |
| 377 * @return {!{ aggregatedStats: !Object, hasChildren: boolean }} | |
| 378 */ | |
| 379 WebInspector.TracingTimelineUIUtils._aggregatedStatsForTraceEvent = function(mod el, event) | |
| 380 { | |
| 381 var events = model.inspectedTargetEvents(); | |
| 382 /** | |
| 383 * @param {number} startTime | |
| 384 * @param {!WebInspector.TracingModel.Event} e | |
| 385 * @return {number} | |
| 386 */ | |
| 387 function eventComparator(startTime, e) | |
| 388 { | |
| 389 return startTime - e.startTime; | |
| 390 } | |
| 391 var index = events.binaryIndexOf(event.startTime, eventComparator); | |
| 392 var hasChildren = false; | |
| 393 var aggregatedStats = {}; | |
| 394 var endTime = event.endTime; | |
| 395 if (endTime) { | |
| 396 for (var i = index; i < events.length; i++) { | |
| 397 var nextEvent = events[i]; | |
| 398 if (nextEvent.startTime >= endTime) | |
| 399 break; | |
| 400 if (!nextEvent.selfTime) | |
| 401 continue; | |
| 402 if (i > index) | |
| 403 hasChildren = true; | |
| 404 var category = WebInspector.TimelineUIUtils.styleForTimelineEvent(ne xtEvent.name).category.name; | |
| 405 aggregatedStats[category] = (aggregatedStats[category] || 0) + nextE vent.selfTime / 1000; | |
| 406 } | |
| 407 } | |
| 408 return { aggregatedStats: aggregatedStats, hasChildren: hasChildren }; | |
| 409 } | |
| 410 | |
| 411 | |
| OLD | NEW |