Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: Source/devtools/front_end/timeline/TracingTimelineUIUtils.js

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

Powered by Google App Engine
This is Rietveld 408576698