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 |