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.TimelineUIUtilsImpl = function() | |
10 { | |
11 WebInspector.TimelineUIUtils.call(this); | |
12 } | |
13 | |
14 WebInspector.TimelineUIUtilsImpl.prototype = { | |
15 /** | |
16 * @param {!WebInspector.TimelineModel.Record} record | |
17 * @return {boolean} | |
18 */ | |
19 isBeginFrame: function(record) | |
20 { | |
21 return record.type() === WebInspector.TimelineModel.RecordType.BeginFram
e; | |
22 }, | |
23 /** | |
24 * @param {!WebInspector.TimelineModel.Record} record | |
25 * @return {boolean} | |
26 */ | |
27 isProgram: function(record) | |
28 { | |
29 return record.type() === WebInspector.TimelineModel.RecordType.Program; | |
30 }, | |
31 /** | |
32 * @param {string} recordType | |
33 * @return {boolean} | |
34 */ | |
35 isCoalescable: function(recordType) | |
36 { | |
37 return !!WebInspector.TimelineUIUtilsImpl._coalescableRecordTypes[record
Type]; | |
38 }, | |
39 | |
40 /** | |
41 * @param {!WebInspector.TimelineModel.Record} record | |
42 * @return {boolean} | |
43 */ | |
44 isEventDivider: function(record) | |
45 { | |
46 return WebInspector.TimelineUIUtilsImpl.isEventDivider(record); | |
47 }, | |
48 | |
49 /** | |
50 * @param {!WebInspector.TimelineModel.Record} record | |
51 * @return {?Object} | |
52 */ | |
53 countersForRecord: function(record) | |
54 { | |
55 return record.type() === WebInspector.TimelineModel.RecordType.UpdateCou
nters ? record.data() : null; | |
56 }, | |
57 | |
58 /** | |
59 * @param {!WebInspector.TimelineModel.Record} record | |
60 * @return {?Object} | |
61 */ | |
62 highlightQuadForRecord: function(record) | |
63 { | |
64 var recordTypes = WebInspector.TimelineModel.RecordType; | |
65 switch(record.type()) { | |
66 case recordTypes.Layout: | |
67 return record.data().root; | |
68 case recordTypes.Paint: | |
69 return record.data().clip; | |
70 default: | |
71 return null; | |
72 } | |
73 }, | |
74 | |
75 /** | |
76 * @param {!WebInspector.TimelineModel.Record} record | |
77 * @return {string} | |
78 */ | |
79 titleForRecord: function(record) | |
80 { | |
81 return WebInspector.TimelineUIUtilsImpl._recordTitle(record); | |
82 }, | |
83 | |
84 /** | |
85 * @param {!WebInspector.TimelineModel.Record} record | |
86 * @return {!WebInspector.TimelineCategory} | |
87 */ | |
88 categoryForRecord: function(record) | |
89 { | |
90 return WebInspector.TimelineUIUtilsImpl.recordStyle(record).category; | |
91 }, | |
92 | |
93 /** | |
94 * @param {!WebInspector.TimelineModel.Record} record | |
95 * @param {!WebInspector.Linkifier} linkifier | |
96 * @return {?Node} | |
97 */ | |
98 buildDetailsNode: function(record, linkifier) | |
99 { | |
100 return WebInspector.TimelineUIUtilsImpl.buildDetailsNode(record, linkifi
er); | |
101 }, | |
102 | |
103 /** | |
104 * @param {!WebInspector.TimelineModel.Record} record | |
105 * @param {!WebInspector.TimelineModel} model | |
106 * @param {!WebInspector.Linkifier} linkifier | |
107 * @param {function(!DocumentFragment)} callback | |
108 */ | |
109 generateDetailsContent: function(record, model, linkifier, callback) | |
110 { | |
111 WebInspector.TimelineUIUtilsImpl.generateDetailsContent(record, model, l
inkifier, callback); | |
112 }, | |
113 | |
114 /** | |
115 * @return {!Element} | |
116 */ | |
117 createBeginFrameDivider: function() | |
118 { | |
119 return this.createEventDivider(WebInspector.TimelineModel.RecordType.Beg
inFrame); | |
120 }, | |
121 | |
122 /** | |
123 * @param {string} recordType | |
124 * @param {string=} title | |
125 * @return {!Element} | |
126 */ | |
127 createEventDivider: function(recordType, title) | |
128 { | |
129 return WebInspector.TimelineUIUtilsImpl._createEventDivider(recordType,
title); | |
130 }, | |
131 | |
132 /** | |
133 * @param {!WebInspector.TimelineModel.Record} record | |
134 * @param {!RegExp} regExp | |
135 * @return {boolean} | |
136 */ | |
137 testContentMatching: function(record, regExp) | |
138 { | |
139 var tokens = [WebInspector.TimelineUIUtilsImpl._recordTitle(record)]; | |
140 var data = record.data(); | |
141 for (var key in data) | |
142 tokens.push(data[key]) | |
143 return regExp.test(tokens.join("|")); | |
144 }, | |
145 | |
146 /** | |
147 * @param {!Object} total | |
148 * @param {!WebInspector.TimelineModel.Record} record | |
149 */ | |
150 aggregateTimeForRecord: function(total, record) | |
151 { | |
152 WebInspector.TimelineUIUtilsImpl.aggregateTimeForRecord(total, record); | |
153 }, | |
154 | |
155 /** | |
156 * @return {!WebInspector.TimelineModel.Filter} | |
157 */ | |
158 hiddenRecordsFilter: function() | |
159 { | |
160 var recordTypes = WebInspector.TimelineModel.RecordType; | |
161 var hiddenRecords = [ | |
162 recordTypes.ActivateLayerTree, | |
163 recordTypes.BeginFrame, | |
164 recordTypes.DrawFrame, | |
165 recordTypes.GPUTask, | |
166 recordTypes.InvalidateLayout, | |
167 recordTypes.MarkDOMContent, | |
168 recordTypes.MarkFirstPaint, | |
169 recordTypes.MarkLoad, | |
170 recordTypes.RequestMainThreadFrame, | |
171 recordTypes.ScheduleStyleRecalculation, | |
172 recordTypes.UpdateCounters | |
173 ]; | |
174 return new WebInspector.TimelineRecordHiddenTypeFilter(hiddenRecords); | |
175 }, | |
176 | |
177 __proto__: WebInspector.TimelineUIUtils.prototype | |
178 } | |
179 | |
180 | |
181 WebInspector.TimelineUIUtilsImpl._coalescableRecordTypes = {}; | |
182 WebInspector.TimelineUIUtilsImpl._coalescableRecordTypes[WebInspector.TimelineMo
del.RecordType.Layout] = 1; | |
183 WebInspector.TimelineUIUtilsImpl._coalescableRecordTypes[WebInspector.TimelineMo
del.RecordType.Paint] = 1; | |
184 WebInspector.TimelineUIUtilsImpl._coalescableRecordTypes[WebInspector.TimelineMo
del.RecordType.Rasterize] = 1; | |
185 WebInspector.TimelineUIUtilsImpl._coalescableRecordTypes[WebInspector.TimelineMo
del.RecordType.DecodeImage] = 1; | |
186 WebInspector.TimelineUIUtilsImpl._coalescableRecordTypes[WebInspector.TimelineMo
del.RecordType.ResizeImage] = 1; | |
187 | |
188 /** | |
189 * @return {!Object.<string, !{title: string, category: !WebInspector.TimelineCa
tegory}>} | |
190 */ | |
191 WebInspector.TimelineUIUtils._initRecordStyles = function() | |
192 { | |
193 if (WebInspector.TimelineUIUtils._recordStylesMap) | |
194 return WebInspector.TimelineUIUtils._recordStylesMap; | |
195 | |
196 var recordTypes = WebInspector.TimelineModel.RecordType; | |
197 var categories = WebInspector.TimelineUIUtils.categories(); | |
198 | |
199 var recordStyles = {}; | |
200 recordStyles[recordTypes.Root] = { title: "#root", category: categories["loa
ding"] }; | |
201 recordStyles[recordTypes.Program] = { title: WebInspector.UIString("Other"),
category: categories["other"] }; | |
202 recordStyles[recordTypes.EventDispatch] = { title: WebInspector.UIString("Ev
ent"), category: categories["scripting"] }; | |
203 recordStyles[recordTypes.BeginFrame] = { title: WebInspector.UIString("Frame
Start"), category: categories["rendering"] }; | |
204 recordStyles[recordTypes.ScheduleStyleRecalculation] = { title: WebInspector
.UIString("Schedule Style Recalculation"), category: categories["rendering"] }; | |
205 recordStyles[recordTypes.RecalculateStyles] = { title: WebInspector.UIString
("Recalculate Style"), category: categories["rendering"] }; | |
206 recordStyles[recordTypes.InvalidateLayout] = { title: WebInspector.UIString(
"Invalidate Layout"), category: categories["rendering"] }; | |
207 recordStyles[recordTypes.Layout] = { title: WebInspector.UIString("Layout"),
category: categories["rendering"] }; | |
208 recordStyles[recordTypes.UpdateLayerTree] = { title: WebInspector.UIString("
Update Layer Tree"), category: categories["rendering"] }; | |
209 recordStyles[recordTypes.PaintSetup] = { title: WebInspector.UIString("Paint
Setup"), category: categories["painting"] }; | |
210 recordStyles[recordTypes.Paint] = { title: WebInspector.UIString("Paint"), c
ategory: categories["painting"] }; | |
211 recordStyles[recordTypes.Rasterize] = { title: WebInspector.UIString("Paint"
), category: categories["painting"] }; | |
212 recordStyles[recordTypes.ScrollLayer] = { title: WebInspector.UIString("Scro
ll"), category: categories["rendering"] }; | |
213 recordStyles[recordTypes.DecodeImage] = { title: WebInspector.UIString("Imag
e Decode"), category: categories["painting"] }; | |
214 recordStyles[recordTypes.ResizeImage] = { title: WebInspector.UIString("Imag
e Resize"), category: categories["painting"] }; | |
215 recordStyles[recordTypes.CompositeLayers] = { title: WebInspector.UIString("
Composite Layers"), category: categories["painting"] }; | |
216 recordStyles[recordTypes.ParseHTML] = { title: WebInspector.UIString("Parse
HTML"), category: categories["loading"] }; | |
217 recordStyles[recordTypes.TimerInstall] = { title: WebInspector.UIString("Ins
tall Timer"), category: categories["scripting"] }; | |
218 recordStyles[recordTypes.TimerRemove] = { title: WebInspector.UIString("Remo
ve Timer"), category: categories["scripting"] }; | |
219 recordStyles[recordTypes.TimerFire] = { title: WebInspector.UIString("Timer
Fired"), category: categories["scripting"] }; | |
220 recordStyles[recordTypes.XHRReadyStateChange] = { title: WebInspector.UIStri
ng("XHR Ready State Change"), category: categories["scripting"] }; | |
221 recordStyles[recordTypes.XHRLoad] = { title: WebInspector.UIString("XHR Load
"), category: categories["scripting"] }; | |
222 recordStyles[recordTypes.EvaluateScript] = { title: WebInspector.UIString("E
valuate Script"), category: categories["scripting"] }; | |
223 recordStyles[recordTypes.ResourceSendRequest] = { title: WebInspector.UIStri
ng("Send Request"), category: categories["loading"] }; | |
224 recordStyles[recordTypes.ResourceReceiveResponse] = { title: WebInspector.UI
String("Receive Response"), category: categories["loading"] }; | |
225 recordStyles[recordTypes.ResourceFinish] = { title: WebInspector.UIString("F
inish Loading"), category: categories["loading"] }; | |
226 recordStyles[recordTypes.FunctionCall] = { title: WebInspector.UIString("Fun
ction Call"), category: categories["scripting"] }; | |
227 recordStyles[recordTypes.ResourceReceivedData] = { title: WebInspector.UIStr
ing("Receive Data"), category: categories["loading"] }; | |
228 recordStyles[recordTypes.GCEvent] = { title: WebInspector.UIString("GC Event
"), category: categories["scripting"] }; | |
229 recordStyles[recordTypes.MarkDOMContent] = { title: WebInspector.UIString("D
OMContentLoaded event"), category: categories["scripting"] }; | |
230 recordStyles[recordTypes.MarkLoad] = { title: WebInspector.UIString("Load ev
ent"), category: categories["scripting"] }; | |
231 recordStyles[recordTypes.MarkFirstPaint] = { title: WebInspector.UIString("F
irst paint"), category: categories["painting"] }; | |
232 recordStyles[recordTypes.TimeStamp] = { title: WebInspector.UIString("Timest
amp"), category: categories["scripting"] }; | |
233 recordStyles[recordTypes.ConsoleTime] = { title: WebInspector.UIString("Cons
ole Time"), category: categories["scripting"] }; | |
234 recordStyles[recordTypes.RequestAnimationFrame] = { title: WebInspector.UISt
ring("Request Animation Frame"), category: categories["scripting"] }; | |
235 recordStyles[recordTypes.CancelAnimationFrame] = { title: WebInspector.UIStr
ing("Cancel Animation Frame"), category: categories["scripting"] }; | |
236 recordStyles[recordTypes.FireAnimationFrame] = { title: WebInspector.UIStrin
g("Animation Frame Fired"), category: categories["scripting"] }; | |
237 recordStyles[recordTypes.WebSocketCreate] = { title: WebInspector.UIString("
Create WebSocket"), category: categories["scripting"] }; | |
238 recordStyles[recordTypes.WebSocketSendHandshakeRequest] = { title: WebInspec
tor.UIString("Send WebSocket Handshake"), category: categories["scripting"] }; | |
239 recordStyles[recordTypes.WebSocketReceiveHandshakeResponse] = { title: WebIn
spector.UIString("Receive WebSocket Handshake"), category: categories["scripting
"] }; | |
240 recordStyles[recordTypes.WebSocketDestroy] = { title: WebInspector.UIString(
"Destroy WebSocket"), category: categories["scripting"] }; | |
241 recordStyles[recordTypes.EmbedderCallback] = { title: WebInspector.UIString(
"Embedder Callback"), category: categories["scripting"] }; | |
242 | |
243 WebInspector.TimelineUIUtils._recordStylesMap = recordStyles; | |
244 return recordStyles; | |
245 } | |
246 | |
247 /** | |
248 * @param {!WebInspector.TimelineModel.Record} record | |
249 * @return {!{title: string, category: !WebInspector.TimelineCategory}} | |
250 */ | |
251 WebInspector.TimelineUIUtilsImpl.recordStyle = function(record) | |
252 { | |
253 var type = record.type(); | |
254 var recordStyles = WebInspector.TimelineUIUtils._initRecordStyles(); | |
255 var result = recordStyles[type]; | |
256 if (!result) { | |
257 result = { | |
258 title: WebInspector.UIString("Unknown: %s", type), | |
259 category: WebInspector.TimelineUIUtils.categories()["other"] | |
260 }; | |
261 recordStyles[type] = result; | |
262 } | |
263 return result; | |
264 } | |
265 | |
266 /** | |
267 * @param {!WebInspector.TimelineModel.Record} record | |
268 * @return {string} | |
269 */ | |
270 WebInspector.TimelineUIUtilsImpl._recordTitle = function(record) | |
271 { | |
272 var recordData = record.data(); | |
273 var title = WebInspector.TimelineUIUtilsImpl.recordStyle(record).title; | |
274 if (record.type() === WebInspector.TimelineModel.RecordType.TimeStamp || rec
ord.type() === WebInspector.TimelineModel.RecordType.ConsoleTime) | |
275 return WebInspector.UIString("%s: %s", title, recordData["message"]); | |
276 if (WebInspector.TimelineUIUtilsImpl.isEventDivider(record)) { | |
277 var startTime = Number.millisToString(record.startTime() - record._model
.minimumRecordTime()); | |
278 return WebInspector.UIString("%s at %s", title, startTime); | |
279 } | |
280 return title; | |
281 } | |
282 | |
283 /** | |
284 * @param {!WebInspector.TimelineModel.Record} record | |
285 * @return {boolean} | |
286 */ | |
287 WebInspector.TimelineUIUtilsImpl.isEventDivider = function(record) | |
288 { | |
289 var recordTypes = WebInspector.TimelineModel.RecordType; | |
290 if (record.type() === recordTypes.TimeStamp) | |
291 return true; | |
292 if (record.type() === recordTypes.MarkFirstPaint) | |
293 return true; | |
294 if (record.type() === recordTypes.MarkDOMContent || record.type() === record
Types.MarkLoad) | |
295 return record.data()["isMainFrame"]; | |
296 return false; | |
297 } | |
298 | |
299 /** | |
300 * @param {!Object} total | |
301 * @param {!WebInspector.TimelineModel.Record} record | |
302 */ | |
303 WebInspector.TimelineUIUtilsImpl.aggregateTimeForRecord = function(total, record
) | |
304 { | |
305 var children = record.children(); | |
306 for (var i = 0; i < children.length; ++i) | |
307 WebInspector.TimelineUIUtilsImpl.aggregateTimeForRecord(total, children[
i]); | |
308 var categoryName = WebInspector.TimelineUIUtilsImpl.recordStyle(record).cate
gory.name; | |
309 total[categoryName] = (total[categoryName] || 0) + record.selfTime(); | |
310 } | |
311 | |
312 /** | |
313 * @param {!WebInspector.TimelineModel.Record} record | |
314 * @param {!WebInspector.Linkifier} linkifier | |
315 * @return {?Node} | |
316 */ | |
317 WebInspector.TimelineUIUtilsImpl.buildDetailsNode = function(record, linkifier) | |
318 { | |
319 var details; | |
320 var detailsText; | |
321 var recordData = record.data(); | |
322 switch (record.type()) { | |
323 case WebInspector.TimelineModel.RecordType.GCEvent: | |
324 detailsText = WebInspector.UIString("%s collected", Number.bytesToString
(recordData["usedHeapSizeDelta"])); | |
325 break; | |
326 case WebInspector.TimelineModel.RecordType.TimerFire: | |
327 detailsText = recordData["timerId"]; | |
328 break; | |
329 case WebInspector.TimelineModel.RecordType.FunctionCall: | |
330 details = linkifyLocation(recordData["scriptId"], recordData["scriptName
"], recordData["scriptLine"], 0); | |
331 break; | |
332 case WebInspector.TimelineModel.RecordType.FireAnimationFrame: | |
333 detailsText = recordData["id"]; | |
334 break; | |
335 case WebInspector.TimelineModel.RecordType.EventDispatch: | |
336 detailsText = recordData ? recordData["type"] : null; | |
337 break; | |
338 case WebInspector.TimelineModel.RecordType.Paint: | |
339 var width = WebInspector.TimelineUIUtils.quadWidth(recordData.clip); | |
340 var height = WebInspector.TimelineUIUtils.quadHeight(recordData.clip); | |
341 if (width && height) | |
342 detailsText = WebInspector.UIString("%d\u2009\u00d7\u2009%d", width,
height); | |
343 break; | |
344 case WebInspector.TimelineModel.RecordType.TimerInstall: | |
345 case WebInspector.TimelineModel.RecordType.TimerRemove: | |
346 details = linkifyTopCallFrame(); | |
347 detailsText = recordData["timerId"]; | |
348 break; | |
349 case WebInspector.TimelineModel.RecordType.RequestAnimationFrame: | |
350 case WebInspector.TimelineModel.RecordType.CancelAnimationFrame: | |
351 details = linkifyTopCallFrame(); | |
352 detailsText = recordData["id"]; | |
353 break; | |
354 case WebInspector.TimelineModel.RecordType.ParseHTML: | |
355 case WebInspector.TimelineModel.RecordType.RecalculateStyles: | |
356 details = linkifyTopCallFrame(); | |
357 break; | |
358 case WebInspector.TimelineModel.RecordType.EvaluateScript: | |
359 var url = recordData["url"]; | |
360 if (url) | |
361 details = linkifyLocation("", url, recordData["lineNumber"], 0); | |
362 break; | |
363 case WebInspector.TimelineModel.RecordType.XHRReadyStateChange: | |
364 case WebInspector.TimelineModel.RecordType.XHRLoad: | |
365 case WebInspector.TimelineModel.RecordType.ResourceSendRequest: | |
366 case WebInspector.TimelineModel.RecordType.DecodeImage: | |
367 case WebInspector.TimelineModel.RecordType.ResizeImage: | |
368 var url = recordData["url"]; | |
369 if (url) | |
370 detailsText = WebInspector.displayNameForURL(url); | |
371 break; | |
372 case WebInspector.TimelineModel.RecordType.ResourceReceivedData: | |
373 case WebInspector.TimelineModel.RecordType.ResourceReceiveResponse: | |
374 case WebInspector.TimelineModel.RecordType.ResourceFinish: | |
375 var initiator = record.initiator(); | |
376 if (initiator) { | |
377 var url = initiator.data()["url"]; | |
378 if (url) | |
379 detailsText = WebInspector.displayNameForURL(url); | |
380 } | |
381 break; | |
382 case WebInspector.TimelineModel.RecordType.ConsoleTime: | |
383 detailsText = recordData["message"]; | |
384 break; | |
385 case WebInspector.TimelineModel.RecordType.EmbedderCallback: | |
386 detailsText = recordData["callbackName"]; | |
387 break; | |
388 default: | |
389 details = linkifyTopCallFrame(); | |
390 break; | |
391 } | |
392 | |
393 if (!details && detailsText) | |
394 details = createTextNode(detailsText); | |
395 return details; | |
396 | |
397 /** | |
398 * @param {string} scriptId | |
399 * @param {string} url | |
400 * @param {number} lineNumber | |
401 * @param {number=} columnNumber | |
402 */ | |
403 function linkifyLocation(scriptId, url, lineNumber, columnNumber) | |
404 { | |
405 if (!url) | |
406 return null; | |
407 | |
408 // FIXME(62725): stack trace line/column numbers are one-based. | |
409 columnNumber = columnNumber ? columnNumber - 1 : 0; | |
410 return linkifier.linkifyScriptLocation(record.target(), scriptId, url, l
ineNumber - 1, columnNumber, "timeline-details"); | |
411 } | |
412 | |
413 /** | |
414 * @return {?Element} | |
415 */ | |
416 function linkifyTopCallFrame() | |
417 { | |
418 if (record.stackTrace()) | |
419 return linkifier.linkifyConsoleCallFrame(record.target(), record.sta
ckTrace()[0], "timeline-details"); | |
420 if (record.callSiteStackTrace()) | |
421 return linkifier.linkifyConsoleCallFrame(record.target(), record.cal
lSiteStackTrace()[0], "timeline-details"); | |
422 return null; | |
423 } | |
424 } | |
425 | |
426 /** | |
427 * @param {string=} recordType | |
428 * @return {boolean} | |
429 */ | |
430 WebInspector.TimelineUIUtilsImpl._needsPreviewElement = function(recordType) | |
431 { | |
432 if (!recordType) | |
433 return false; | |
434 const recordTypes = WebInspector.TimelineModel.RecordType; | |
435 switch (recordType) { | |
436 case recordTypes.ResourceSendRequest: | |
437 case recordTypes.ResourceReceiveResponse: | |
438 case recordTypes.ResourceReceivedData: | |
439 case recordTypes.ResourceFinish: | |
440 return true; | |
441 default: | |
442 return false; | |
443 } | |
444 } | |
445 | |
446 /** | |
447 * @param {!WebInspector.TimelineModel.Record} record | |
448 * @param {!WebInspector.TimelineModel} model | |
449 * @param {!WebInspector.Linkifier} linkifier | |
450 * @param {function(!DocumentFragment)} callback | |
451 */ | |
452 WebInspector.TimelineUIUtilsImpl.generateDetailsContent = function(record, model
, linkifier, callback) | |
453 { | |
454 var imageElement = /** @type {?Element} */ (record.getUserObject("TimelineUI
Utils::preview-element") || null); | |
455 var relatedNode = null; | |
456 var recordData = record.data(); | |
457 var barrier = new CallbackBarrier(); | |
458 var target = record.target(); | |
459 if (!imageElement && WebInspector.TimelineUIUtilsImpl._needsPreviewElement(r
ecord.type()) && target) | |
460 WebInspector.DOMPresentationUtils.buildImagePreviewContents(target, reco
rdData["url"], false, barrier.createCallback(saveImage)); | |
461 if (recordData["backendNodeId"] && target) | |
462 target.domModel.pushNodesByBackendIdsToFrontend([recordData["backendNode
Id"]], barrier.createCallback(setRelatedNode)); | |
463 barrier.callWhenDone(callbackWrapper); | |
464 | |
465 /** | |
466 * @param {!Element=} element | |
467 */ | |
468 function saveImage(element) | |
469 { | |
470 imageElement = element || null; | |
471 record.setUserObject("TimelineUIUtils::preview-element", element); | |
472 } | |
473 | |
474 /** | |
475 * @param {?Array.<!DOMAgent.NodeId>} nodeIds | |
476 */ | |
477 function setRelatedNode(nodeIds) | |
478 { | |
479 if (nodeIds && target) | |
480 relatedNode = target.domModel.nodeForId(nodeIds[0]); | |
481 } | |
482 | |
483 function callbackWrapper() | |
484 { | |
485 callback(WebInspector.TimelineUIUtilsImpl._generateDetailsContentSynchro
nously(record, model, linkifier, imageElement, relatedNode)); | |
486 } | |
487 } | |
488 | |
489 /** | |
490 * @param {!WebInspector.TimelineModel.Record} record | |
491 * @param {!WebInspector.TimelineModel} model | |
492 * @param {!WebInspector.Linkifier} linkifier | |
493 * @param {?Element} imagePreviewElement | |
494 * @param {?WebInspector.DOMNode} relatedNode | |
495 * @return {!DocumentFragment} | |
496 */ | |
497 WebInspector.TimelineUIUtilsImpl._generateDetailsContentSynchronously = function
(record, model, linkifier, imagePreviewElement, relatedNode) | |
498 { | |
499 var fragment = createDocumentFragment(); | |
500 const recordTypes = WebInspector.TimelineModel.RecordType; | |
501 | |
502 // The messages may vary per record.type(); | |
503 var callSiteStackTraceLabel; | |
504 var callStackLabel; | |
505 var relatedNodeLabel; | |
506 | |
507 var contentHelper = new WebInspector.TimelineDetailsContentHelper(record.tar
get(), linkifier, true); | |
508 contentHelper.appendTextRow(WebInspector.UIString("Self Time"), Number.milli
sToString(record.selfTime(), true)); | |
509 contentHelper.appendTextRow(WebInspector.UIString("Start Time"), Number.mill
isToString(record.startTime() - model.minimumRecordTime())); | |
510 var recordData = record.data(); | |
511 | |
512 switch (record.type()) { | |
513 case recordTypes.GCEvent: | |
514 contentHelper.appendTextRow(WebInspector.UIString("Collected"), Numb
er.bytesToString(recordData["usedHeapSizeDelta"])); | |
515 break; | |
516 case recordTypes.TimerFire: | |
517 callSiteStackTraceLabel = WebInspector.UIString("Timer installed"); | |
518 // Fall-through intended. | |
519 | |
520 case recordTypes.TimerInstall: | |
521 case recordTypes.TimerRemove: | |
522 contentHelper.appendTextRow(WebInspector.UIString("Timer ID"), recor
dData["timerId"]); | |
523 if (record.type() === recordTypes.TimerInstall) { | |
524 contentHelper.appendTextRow(WebInspector.UIString("Timeout"), Nu
mber.millisToString(recordData["timeout"])); | |
525 contentHelper.appendTextRow(WebInspector.UIString("Repeats"), !r
ecordData["singleShot"]); | |
526 } | |
527 break; | |
528 case recordTypes.FireAnimationFrame: | |
529 callSiteStackTraceLabel = WebInspector.UIString("Animation frame req
uested"); | |
530 contentHelper.appendTextRow(WebInspector.UIString("Callback ID"), re
cordData["id"]); | |
531 break; | |
532 case recordTypes.FunctionCall: | |
533 if (recordData["scriptName"]) | |
534 contentHelper.appendLocationRow(WebInspector.UIString("Location"
), recordData["scriptName"], recordData["scriptLine"]); | |
535 break; | |
536 case recordTypes.ResourceSendRequest: | |
537 case recordTypes.ResourceReceiveResponse: | |
538 case recordTypes.ResourceReceivedData: | |
539 case recordTypes.ResourceFinish: | |
540 var url; | |
541 if (record.type() === recordTypes.ResourceSendRequest) | |
542 url = recordData["url"]; | |
543 else if (record.initiator()) | |
544 url = record.initiator().data()["url"]; | |
545 if (url) | |
546 contentHelper.appendElementRow(WebInspector.UIString("Resource")
, WebInspector.linkifyResourceAsNode(url)); | |
547 if (imagePreviewElement) | |
548 contentHelper.appendElementRow(WebInspector.UIString("Preview"),
imagePreviewElement); | |
549 if (recordData["requestMethod"]) | |
550 contentHelper.appendTextRow(WebInspector.UIString("Request Metho
d"), recordData["requestMethod"]); | |
551 if (typeof recordData["statusCode"] === "number") | |
552 contentHelper.appendTextRow(WebInspector.UIString("Status Code")
, recordData["statusCode"]); | |
553 if (recordData["mimeType"]) | |
554 contentHelper.appendTextRow(WebInspector.UIString("MIME Type"),
recordData["mimeType"]); | |
555 if (recordData["encodedDataLength"]) | |
556 contentHelper.appendTextRow(WebInspector.UIString("Encoded Data
Length"), WebInspector.UIString("%d Bytes", recordData["encodedDataLength"])); | |
557 break; | |
558 case recordTypes.EvaluateScript: | |
559 var url = recordData["url"]; | |
560 if (url) | |
561 contentHelper.appendLocationRow(WebInspector.UIString("Script"),
url, recordData["lineNumber"]); | |
562 break; | |
563 case recordTypes.Paint: | |
564 var clip = recordData["clip"]; | |
565 contentHelper.appendTextRow(WebInspector.UIString("Location"), WebIn
spector.UIString("(%d, %d)", clip[0], clip[1])); | |
566 var clipWidth = WebInspector.TimelineUIUtils.quadWidth(clip); | |
567 var clipHeight = WebInspector.TimelineUIUtils.quadHeight(clip); | |
568 contentHelper.appendTextRow(WebInspector.UIString("Dimensions"), Web
Inspector.UIString("%d × %d", clipWidth, clipHeight)); | |
569 // Fall-through intended. | |
570 | |
571 case recordTypes.PaintSetup: | |
572 case recordTypes.Rasterize: | |
573 case recordTypes.ScrollLayer: | |
574 relatedNodeLabel = WebInspector.UIString("Layer root"); | |
575 break; | |
576 case recordTypes.DecodeImage: | |
577 case recordTypes.ResizeImage: | |
578 relatedNodeLabel = WebInspector.UIString("Image element"); | |
579 var url = recordData["url"]; | |
580 if (url) | |
581 contentHelper.appendElementRow(WebInspector.UIString("Image URL"
), WebInspector.linkifyResourceAsNode(url)); | |
582 break; | |
583 case recordTypes.RecalculateStyles: // We don't want to see default deta
ils. | |
584 if (recordData["elementCount"]) | |
585 contentHelper.appendTextRow(WebInspector.UIString("Elements affe
cted"), recordData["elementCount"]); | |
586 callStackLabel = WebInspector.UIString("Styles recalculation forced"
); | |
587 break; | |
588 case recordTypes.Layout: | |
589 if (recordData["dirtyObjects"]) | |
590 contentHelper.appendTextRow(WebInspector.UIString("Nodes that ne
ed layout"), recordData["dirtyObjects"]); | |
591 if (recordData["totalObjects"]) | |
592 contentHelper.appendTextRow(WebInspector.UIString("Layout tree s
ize"), recordData["totalObjects"]); | |
593 if (typeof recordData["partialLayout"] === "boolean") { | |
594 contentHelper.appendTextRow(WebInspector.UIString("Layout scope"
), | |
595 recordData["partialLayout"] ? WebInspector.UIString("Partial"
) : WebInspector.UIString("Whole document")); | |
596 } | |
597 callSiteStackTraceLabel = WebInspector.UIString("Layout invalidated"
); | |
598 callStackLabel = WebInspector.UIString("Layout forced"); | |
599 relatedNodeLabel = WebInspector.UIString("Layout root"); | |
600 break; | |
601 case recordTypes.ConsoleTime: | |
602 contentHelper.appendTextRow(WebInspector.UIString("Message"), record
Data["message"]); | |
603 break; | |
604 case recordTypes.WebSocketCreate: | |
605 case recordTypes.WebSocketSendHandshakeRequest: | |
606 case recordTypes.WebSocketReceiveHandshakeResponse: | |
607 case recordTypes.WebSocketDestroy: | |
608 var initiatorData = record.initiator() ? record.initiator().data() :
recordData; | |
609 if (typeof initiatorData["webSocketURL"] !== "undefined") | |
610 contentHelper.appendTextRow(WebInspector.UIString("URL"), initia
torData["webSocketURL"]); | |
611 if (typeof initiatorData["webSocketProtocol"] !== "undefined") | |
612 contentHelper.appendTextRow(WebInspector.UIString("WebSocket Pro
tocol"), initiatorData["webSocketProtocol"]); | |
613 if (typeof recordData["message"] !== "undefined") | |
614 contentHelper.appendTextRow(WebInspector.UIString("Message"), re
cordData["message"]); | |
615 break; | |
616 case recordTypes.EmbedderCallback: | |
617 contentHelper.appendTextRow(WebInspector.UIString("Callback Function
"), recordData["callbackName"]); | |
618 break; | |
619 default: | |
620 var detailsNode = WebInspector.TimelineUIUtilsImpl.buildDetailsNode(
record, linkifier); | |
621 if (detailsNode) | |
622 contentHelper.appendElementRow(WebInspector.UIString("Details"),
detailsNode); | |
623 break; | |
624 } | |
625 | |
626 if (relatedNode) | |
627 contentHelper.appendElementRow(relatedNodeLabel || WebInspector.UIString
("Related node"), WebInspector.DOMPresentationUtils.linkifyNodeReference(related
Node)); | |
628 | |
629 if (recordData["scriptName"] && record.type() !== recordTypes.FunctionCall) | |
630 contentHelper.appendLocationRow(WebInspector.UIString("Function Call"),
recordData["scriptName"], recordData["scriptLine"]); | |
631 var callSiteStackTrace = record.callSiteStackTrace(); | |
632 if (callSiteStackTrace) | |
633 contentHelper.appendStackTrace(callSiteStackTraceLabel || WebInspector.U
IString("Call Site stack"), callSiteStackTrace); | |
634 var recordStackTrace = record.stackTrace(); | |
635 if (recordStackTrace) | |
636 contentHelper.appendStackTrace(callStackLabel || WebInspector.UIString("
Call Stack"), recordStackTrace); | |
637 | |
638 if (record.warnings()) { | |
639 var ul = createElement("ul"); | |
640 for (var i = 0; i < record.warnings().length; ++i) | |
641 ul.createChild("li").textContent = record.warnings()[i]; | |
642 contentHelper.appendElementRow(WebInspector.UIString("Warning"), ul); | |
643 } | |
644 fragment.appendChild(contentHelper.element); | |
645 | |
646 var aggregatedStats = {}; | |
647 WebInspector.TimelineUIUtilsImpl.aggregateTimeForRecord(aggregatedStats, rec
ord); | |
648 if (record.children().length) | |
649 fragment.appendChild(WebInspector.TimelineUIUtils.generatePieChart(aggre
gatedStats, WebInspector.TimelineUIUtilsImpl.recordStyle(record).category, recor
d.selfTime())); | |
650 else | |
651 fragment.appendChild(WebInspector.TimelineUIUtils.generatePieChart(aggre
gatedStats)); | |
652 | |
653 return fragment; | |
654 } | |
655 | |
656 /** | |
657 * @param {string} recordType | |
658 * @param {string=} title | |
659 * @return {!Element} | |
660 */ | |
661 WebInspector.TimelineUIUtilsImpl._createEventDivider = function(recordType, titl
e) | |
662 { | |
663 var eventDivider = createElement("div"); | |
664 eventDivider.className = "resources-event-divider"; | |
665 var recordTypes = WebInspector.TimelineModel.RecordType; | |
666 | |
667 if (recordType === recordTypes.MarkDOMContent) | |
668 eventDivider.className += " resources-blue-divider"; | |
669 else if (recordType === recordTypes.MarkLoad) | |
670 eventDivider.className += " resources-red-divider"; | |
671 else if (recordType === recordTypes.MarkFirstPaint) | |
672 eventDivider.className += " resources-green-divider"; | |
673 else if (recordType === recordTypes.TimeStamp) | |
674 eventDivider.className += " resources-orange-divider"; | |
675 else if (recordType === recordTypes.BeginFrame) | |
676 eventDivider.className += " timeline-frame-divider"; | |
677 | |
678 if (title) | |
679 eventDivider.title = title; | |
680 | |
681 return eventDivider; | |
682 } | |
OLD | NEW |