OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. | |
3 * | |
4 * Redistribution and use in source and binary forms, with or without | |
5 * modification, are permitted provided that the following conditions | |
6 * are met: | |
7 * 1. Redistributions of source code must retain the above copyright | |
8 * notice, this list of conditions and the following disclaimer. | |
9 * 2. Redistributions in binary form must reproduce the above copyright | |
10 * notice, this list of conditions and the following disclaimer in the | |
11 * documentation and/or other materials provided with the distribution. | |
12 * | |
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY | |
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR | |
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | |
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
24 */ | |
25 | |
26 // FIXME: Rename the file. | |
27 | |
28 WebInspector.CPUProfileView = function(profile) | |
29 { | |
30 WebInspector.View.call(this); | |
31 | |
32 this.element.addStyleClass("profile-view"); | |
33 | |
34 this.showSelfTimeAsPercent = true; | |
35 this.showTotalTimeAsPercent = true; | |
36 this.showAverageTimeAsPercent = true; | |
37 | |
38 var columns = { "self": { title: WebInspector.UIString("Self"), width: "72px
", sort: "descending", sortable: true }, | |
39 "total": { title: WebInspector.UIString("Total"), width: "72
px", sortable: true }, | |
40 "average": { title: WebInspector.UIString("Average"), width:
"72px", sortable: true }, | |
41 "calls": { title: WebInspector.UIString("Calls"), width: "54
px", sortable: true }, | |
42 "function": { title: WebInspector.UIString("Function"), disc
losure: true, sortable: true } }; | |
43 | |
44 if (Preferences.samplingCPUProfiler) { | |
45 delete columns.average; | |
46 delete columns.calls; | |
47 } | |
48 | |
49 this.dataGrid = new WebInspector.DataGrid(columns); | |
50 this.dataGrid.addEventListener("sorting changed", this._sortData, this); | |
51 this.dataGrid.element.addEventListener("mousedown", this._mouseDownInDataGri
d.bind(this), true); | |
52 this.element.appendChild(this.dataGrid.element); | |
53 | |
54 this.viewSelectElement = document.createElement("select"); | |
55 this.viewSelectElement.className = "status-bar-item"; | |
56 this.viewSelectElement.addEventListener("change", this._changeView.bind(this
), false); | |
57 this.view = "Heavy"; | |
58 | |
59 var heavyViewOption = document.createElement("option"); | |
60 heavyViewOption.label = WebInspector.UIString("Heavy (Bottom Up)"); | |
61 var treeViewOption = document.createElement("option"); | |
62 treeViewOption.label = WebInspector.UIString("Tree (Top Down)"); | |
63 this.viewSelectElement.appendChild(heavyViewOption); | |
64 this.viewSelectElement.appendChild(treeViewOption); | |
65 | |
66 this.percentButton = new WebInspector.StatusBarButton("", "percent-time-stat
us-bar-item"); | |
67 this.percentButton.addEventListener("click", this._percentClicked.bind(this)
, false); | |
68 | |
69 this.focusButton = new WebInspector.StatusBarButton(WebInspector.UIString("F
ocus selected function."), "focus-profile-node-status-bar-item"); | |
70 this.focusButton.disabled = true; | |
71 this.focusButton.addEventListener("click", this._focusClicked.bind(this), fa
lse); | |
72 | |
73 this.excludeButton = new WebInspector.StatusBarButton(WebInspector.UIString(
"Exclude selected function."), "exclude-profile-node-status-bar-item"); | |
74 this.excludeButton.disabled = true; | |
75 this.excludeButton.addEventListener("click", this._excludeClicked.bind(this)
, false); | |
76 | |
77 this.resetButton = new WebInspector.StatusBarButton(WebInspector.UIString("R
estore all functions."), "reset-profile-status-bar-item"); | |
78 this.resetButton.visible = false; | |
79 this.resetButton.addEventListener("click", this._resetClicked.bind(this), fa
lse); | |
80 | |
81 this.profile = profile; | |
82 | |
83 var self = this; | |
84 function profileCallback(profile) | |
85 { | |
86 self.profile.representedObject = profile; | |
87 self._assignParentsInProfile(); | |
88 | |
89 self.profileDataGridTree = self.bottomUpProfileDataGridTree; | |
90 self.profileDataGridTree.sort(WebInspector.ProfileDataGridTree.propertyC
omparator("selfTime", false)); | |
91 | |
92 self.refresh(); | |
93 | |
94 self._updatePercentButton(); | |
95 } | |
96 | |
97 var callId = WebInspector.Callback.wrap(profileCallback); | |
98 InspectorController.getProfile(callId, this.profile.uid); | |
99 } | |
100 | |
101 WebInspector.CPUProfileView.prototype = { | |
102 get statusBarItems() | |
103 { | |
104 return [this.viewSelectElement, this.percentButton.element, this.focusBu
tton.element, this.excludeButton.element, this.resetButton.element]; | |
105 }, | |
106 | |
107 get profile() | |
108 { | |
109 return this._profile; | |
110 }, | |
111 | |
112 set profile(profile) | |
113 { | |
114 this._profile = profile; | |
115 }, | |
116 | |
117 get bottomUpProfileDataGridTree() | |
118 { | |
119 if (!this._bottomUpProfileDataGridTree) | |
120 this._bottomUpProfileDataGridTree = new WebInspector.BottomUpProfile
DataGridTree(this, this.profile.head); | |
121 return this._bottomUpProfileDataGridTree; | |
122 }, | |
123 | |
124 get topDownProfileDataGridTree() | |
125 { | |
126 if (!this._topDownProfileDataGridTree) | |
127 this._topDownProfileDataGridTree = new WebInspector.TopDownProfileDa
taGridTree(this, this.profile.head); | |
128 return this._topDownProfileDataGridTree; | |
129 }, | |
130 | |
131 get currentTree() | |
132 { | |
133 return this._currentTree; | |
134 }, | |
135 | |
136 set currentTree(tree) | |
137 { | |
138 this._currentTree = tree; | |
139 this.refresh(); | |
140 }, | |
141 | |
142 get topDownTree() | |
143 { | |
144 if (!this._topDownTree) { | |
145 this._topDownTree = WebInspector.TopDownTreeFactory.create(this.prof
ile.head); | |
146 this._sortProfile(this._topDownTree); | |
147 } | |
148 | |
149 return this._topDownTree; | |
150 }, | |
151 | |
152 get bottomUpTree() | |
153 { | |
154 if (!this._bottomUpTree) { | |
155 this._bottomUpTree = WebInspector.BottomUpTreeFactory.create(this.pr
ofile.head); | |
156 this._sortProfile(this._bottomUpTree); | |
157 } | |
158 | |
159 return this._bottomUpTree; | |
160 }, | |
161 | |
162 show: function(parentElement) | |
163 { | |
164 WebInspector.View.prototype.show.call(this, parentElement); | |
165 this.dataGrid.updateWidths(); | |
166 }, | |
167 | |
168 hide: function() | |
169 { | |
170 WebInspector.View.prototype.hide.call(this); | |
171 this._currentSearchResultIndex = -1; | |
172 }, | |
173 | |
174 resize: function() | |
175 { | |
176 if (this.dataGrid) | |
177 this.dataGrid.updateWidths(); | |
178 }, | |
179 | |
180 refresh: function() | |
181 { | |
182 var selectedProfileNode = this.dataGrid.selectedNode ? this.dataGrid.sel
ectedNode.profileNode : null; | |
183 | |
184 this.dataGrid.removeChildren(); | |
185 | |
186 var children = this.profileDataGridTree.children; | |
187 var count = children.length; | |
188 | |
189 for (var index = 0; index < count; ++index) | |
190 this.dataGrid.appendChild(children[index]); | |
191 | |
192 if (selectedProfileNode) | |
193 selectedProfileNode.selected = true; | |
194 }, | |
195 | |
196 refreshVisibleData: function() | |
197 { | |
198 var child = this.dataGrid.children[0]; | |
199 while (child) { | |
200 child.refresh(); | |
201 child = child.traverseNextNode(false, null, true); | |
202 } | |
203 }, | |
204 | |
205 refreshShowAsPercents: function() | |
206 { | |
207 this._updatePercentButton(); | |
208 this.refreshVisibleData(); | |
209 }, | |
210 | |
211 searchCanceled: function() | |
212 { | |
213 if (this._searchResults) { | |
214 for (var i = 0; i < this._searchResults.length; ++i) { | |
215 var profileNode = this._searchResults[i].profileNode; | |
216 | |
217 delete profileNode._searchMatchedSelfColumn; | |
218 delete profileNode._searchMatchedTotalColumn; | |
219 delete profileNode._searchMatchedCallsColumn; | |
220 delete profileNode._searchMatchedFunctionColumn; | |
221 | |
222 profileNode.refresh(); | |
223 } | |
224 } | |
225 | |
226 delete this._searchFinishedCallback; | |
227 this._currentSearchResultIndex = -1; | |
228 this._searchResults = []; | |
229 }, | |
230 | |
231 performSearch: function(query, finishedCallback) | |
232 { | |
233 // Call searchCanceled since it will reset everything we need before doi
ng a new search. | |
234 this.searchCanceled(); | |
235 | |
236 query = query.trimWhitespace(); | |
237 | |
238 if (!query.length) | |
239 return; | |
240 | |
241 this._searchFinishedCallback = finishedCallback; | |
242 | |
243 var greaterThan = (query.indexOf(">") === 0); | |
244 var lessThan = (query.indexOf("<") === 0); | |
245 var equalTo = (query.indexOf("=") === 0 || ((greaterThan || lessThan) &&
query.indexOf("=") === 1)); | |
246 var percentUnits = (query.lastIndexOf("%") === (query.length - 1)); | |
247 var millisecondsUnits = (query.length > 2 && query.lastIndexOf("ms") ===
(query.length - 2)); | |
248 var secondsUnits = (!millisecondsUnits && query.lastIndexOf("s") === (qu
ery.length - 1)); | |
249 | |
250 var queryNumber = parseFloat(query); | |
251 if (greaterThan || lessThan || equalTo) { | |
252 if (equalTo && (greaterThan || lessThan)) | |
253 queryNumber = parseFloat(query.substring(2)); | |
254 else | |
255 queryNumber = parseFloat(query.substring(1)); | |
256 } | |
257 | |
258 var queryNumberMilliseconds = (secondsUnits ? (queryNumber * 1000) : que
ryNumber); | |
259 | |
260 // Make equalTo implicitly true if it wasn't specified there is no other
operator. | |
261 if (!isNaN(queryNumber) && !(greaterThan || lessThan)) | |
262 equalTo = true; | |
263 | |
264 function matchesQuery(/*ProfileDataGridNode*/ profileDataGridNode) | |
265 { | |
266 delete profileDataGridNode._searchMatchedSelfColumn; | |
267 delete profileDataGridNode._searchMatchedTotalColumn; | |
268 delete profileDataGridNode._searchMatchedAverageColumn; | |
269 delete profileDataGridNode._searchMatchedCallsColumn; | |
270 delete profileDataGridNode._searchMatchedFunctionColumn; | |
271 | |
272 if (percentUnits) { | |
273 if (lessThan) { | |
274 if (profileDataGridNode.selfPercent < queryNumber) | |
275 profileDataGridNode._searchMatchedSelfColumn = true; | |
276 if (profileDataGridNode.totalPercent < queryNumber) | |
277 profileDataGridNode._searchMatchedTotalColumn = true; | |
278 if (profileDataGridNode.averagePercent < queryNumberMillisec
onds) | |
279 profileDataGridNode._searchMatchedAverageColumn = true; | |
280 } else if (greaterThan) { | |
281 if (profileDataGridNode.selfPercent > queryNumber) | |
282 profileDataGridNode._searchMatchedSelfColumn = true; | |
283 if (profileDataGridNode.totalPercent > queryNumber) | |
284 profileDataGridNode._searchMatchedTotalColumn = true; | |
285 if (profileDataGridNode.averagePercent < queryNumberMillisec
onds) | |
286 profileDataGridNode._searchMatchedAverageColumn = true; | |
287 } | |
288 | |
289 if (equalTo) { | |
290 if (profileDataGridNode.selfPercent == queryNumber) | |
291 profileDataGridNode._searchMatchedSelfColumn = true; | |
292 if (profileDataGridNode.totalPercent == queryNumber) | |
293 profileDataGridNode._searchMatchedTotalColumn = true; | |
294 if (profileDataGridNode.averagePercent < queryNumberMillisec
onds) | |
295 profileDataGridNode._searchMatchedAverageColumn = true; | |
296 } | |
297 } else if (millisecondsUnits || secondsUnits) { | |
298 if (lessThan) { | |
299 if (profileDataGridNode.selfTime < queryNumberMilliseconds) | |
300 profileDataGridNode._searchMatchedSelfColumn = true; | |
301 if (profileDataGridNode.totalTime < queryNumberMilliseconds) | |
302 profileDataGridNode._searchMatchedTotalColumn = true; | |
303 if (profileDataGridNode.averageTime < queryNumberMillisecond
s) | |
304 profileDataGridNode._searchMatchedAverageColumn = true; | |
305 } else if (greaterThan) { | |
306 if (profileDataGridNode.selfTime > queryNumberMilliseconds) | |
307 profileDataGridNode._searchMatchedSelfColumn = true; | |
308 if (profileDataGridNode.totalTime > queryNumberMilliseconds) | |
309 profileDataGridNode._searchMatchedTotalColumn = true; | |
310 if (profileDataGridNode.averageTime > queryNumberMillisecond
s) | |
311 profileDataGridNode._searchMatchedAverageColumn = true; | |
312 } | |
313 | |
314 if (equalTo) { | |
315 if (profileDataGridNode.selfTime == queryNumberMilliseconds) | |
316 profileDataGridNode._searchMatchedSelfColumn = true; | |
317 if (profileDataGridNode.totalTime == queryNumberMilliseconds
) | |
318 profileDataGridNode._searchMatchedTotalColumn = true; | |
319 if (profileDataGridNode.averageTime == queryNumberMillisecon
ds) | |
320 profileDataGridNode._searchMatchedAverageColumn = true; | |
321 } | |
322 } else { | |
323 if (equalTo && profileDataGridNode.numberOfCalls == queryNumber) | |
324 profileDataGridNode._searchMatchedCallsColumn = true; | |
325 if (greaterThan && profileDataGridNode.numberOfCalls > queryNumb
er) | |
326 profileDataGridNode._searchMatchedCallsColumn = true; | |
327 if (lessThan && profileDataGridNode.numberOfCalls < queryNumber) | |
328 profileDataGridNode._searchMatchedCallsColumn = true; | |
329 } | |
330 | |
331 if (profileDataGridNode.functionName.hasSubstring(query, true) || pr
ofileDataGridNode.url.hasSubstring(query, true)) | |
332 profileDataGridNode._searchMatchedFunctionColumn = true; | |
333 | |
334 if (profileDataGridNode._searchMatchedSelfColumn || | |
335 profileDataGridNode._searchMatchedTotalColumn || | |
336 profileDataGridNode._searchMatchedAverageColumn || | |
337 profileDataGridNode._searchMatchedCallsColumn || | |
338 profileDataGridNode._searchMatchedFunctionColumn) | |
339 { | |
340 profileDataGridNode.refresh(); | |
341 return true; | |
342 } | |
343 | |
344 return false; | |
345 } | |
346 | |
347 var current = this.profileDataGridTree.children[0]; | |
348 | |
349 while (current) { | |
350 if (matchesQuery(current)) { | |
351 this._searchResults.push({ profileNode: current }); | |
352 } | |
353 | |
354 current = current.traverseNextNode(false, null, false); | |
355 } | |
356 | |
357 finishedCallback(this, this._searchResults.length); | |
358 }, | |
359 | |
360 jumpToFirstSearchResult: function() | |
361 { | |
362 if (!this._searchResults || !this._searchResults.length) | |
363 return; | |
364 this._currentSearchResultIndex = 0; | |
365 this._jumpToSearchResult(this._currentSearchResultIndex); | |
366 }, | |
367 | |
368 jumpToLastSearchResult: function() | |
369 { | |
370 if (!this._searchResults || !this._searchResults.length) | |
371 return; | |
372 this._currentSearchResultIndex = (this._searchResults.length - 1); | |
373 this._jumpToSearchResult(this._currentSearchResultIndex); | |
374 }, | |
375 | |
376 jumpToNextSearchResult: function() | |
377 { | |
378 if (!this._searchResults || !this._searchResults.length) | |
379 return; | |
380 if (++this._currentSearchResultIndex >= this._searchResults.length) | |
381 this._currentSearchResultIndex = 0; | |
382 this._jumpToSearchResult(this._currentSearchResultIndex); | |
383 }, | |
384 | |
385 jumpToPreviousSearchResult: function() | |
386 { | |
387 if (!this._searchResults || !this._searchResults.length) | |
388 return; | |
389 if (--this._currentSearchResultIndex < 0) | |
390 this._currentSearchResultIndex = (this._searchResults.length - 1); | |
391 this._jumpToSearchResult(this._currentSearchResultIndex); | |
392 }, | |
393 | |
394 showingFirstSearchResult: function() | |
395 { | |
396 return (this._currentSearchResultIndex === 0); | |
397 }, | |
398 | |
399 showingLastSearchResult: function() | |
400 { | |
401 return (this._searchResults && this._currentSearchResultIndex === (this.
_searchResults.length - 1)); | |
402 }, | |
403 | |
404 _jumpToSearchResult: function(index) | |
405 { | |
406 var searchResult = this._searchResults[index]; | |
407 if (!searchResult) | |
408 return; | |
409 | |
410 var profileNode = searchResult.profileNode; | |
411 profileNode.reveal(); | |
412 profileNode.select(); | |
413 }, | |
414 | |
415 _changeView: function(event) | |
416 { | |
417 if (!event || !this.profile) | |
418 return; | |
419 | |
420 if (event.target.selectedIndex == 1 && this.view == "Heavy") { | |
421 this.profileDataGridTree = this.topDownProfileDataGridTree; | |
422 this._sortProfile(); | |
423 this.view = "Tree"; | |
424 } else if (event.target.selectedIndex == 0 && this.view == "Tree") { | |
425 this.profileDataGridTree = this.bottomUpProfileDataGridTree; | |
426 this._sortProfile(); | |
427 this.view = "Heavy"; | |
428 } | |
429 | |
430 if (!this.currentQuery || !this._searchFinishedCallback || !this._search
Results) | |
431 return; | |
432 | |
433 // The current search needs to be performed again. First negate out prev
ious match | |
434 // count by calling the search finished callback with a negative number
of matches. | |
435 // Then perform the search again the with same query and callback. | |
436 this._searchFinishedCallback(this, -this._searchResults.length); | |
437 this.performSearch(this.currentQuery, this._searchFinishedCallback); | |
438 }, | |
439 | |
440 _percentClicked: function(event) | |
441 { | |
442 var currentState = this.showSelfTimeAsPercent && this.showTotalTimeAsPer
cent && this.showAverageTimeAsPercent; | |
443 this.showSelfTimeAsPercent = !currentState; | |
444 this.showTotalTimeAsPercent = !currentState; | |
445 this.showAverageTimeAsPercent = !currentState; | |
446 this.refreshShowAsPercents(); | |
447 }, | |
448 | |
449 _updatePercentButton: function() | |
450 { | |
451 if (this.showSelfTimeAsPercent && this.showTotalTimeAsPercent && this.sh
owAverageTimeAsPercent) { | |
452 this.percentButton.title = WebInspector.UIString("Show absolute tota
l and self times."); | |
453 this.percentButton.toggled = true; | |
454 } else { | |
455 this.percentButton.title = WebInspector.UIString("Show total and sel
f times as percentages."); | |
456 this.percentButton.toggled = false; | |
457 } | |
458 }, | |
459 | |
460 _focusClicked: function(event) | |
461 { | |
462 if (!this.dataGrid.selectedNode) | |
463 return; | |
464 | |
465 this.resetButton.visible = true; | |
466 this.profileDataGridTree.focus(this.dataGrid.selectedNode); | |
467 this.refresh(); | |
468 this.refreshVisibleData(); | |
469 }, | |
470 | |
471 _excludeClicked: function(event) | |
472 { | |
473 var selectedNode = this.dataGrid.selectedNode | |
474 | |
475 if (!selectedNode) | |
476 return; | |
477 | |
478 selectedNode.deselect(); | |
479 | |
480 this.resetButton.visible = true; | |
481 this.profileDataGridTree.exclude(selectedNode); | |
482 this.refresh(); | |
483 this.refreshVisibleData(); | |
484 }, | |
485 | |
486 _resetClicked: function(event) | |
487 { | |
488 this.resetButton.visible = false; | |
489 this.profileDataGridTree.restore(); | |
490 this.refresh(); | |
491 this.refreshVisibleData(); | |
492 }, | |
493 | |
494 _dataGridNodeSelected: function(node) | |
495 { | |
496 this.focusButton.disabled = false; | |
497 this.excludeButton.disabled = false; | |
498 }, | |
499 | |
500 _dataGridNodeDeselected: function(node) | |
501 { | |
502 this.focusButton.disabled = true; | |
503 this.excludeButton.disabled = true; | |
504 }, | |
505 | |
506 _sortData: function(event) | |
507 { | |
508 this._sortProfile(this.profile.representedObject); | |
509 }, | |
510 | |
511 _sortProfile: function() | |
512 { | |
513 var sortAscending = this.dataGrid.sortOrder === "ascending"; | |
514 var sortColumnIdentifier = this.dataGrid.sortColumnIdentifier; | |
515 var sortProperty = { | |
516 "average": "averageTime", | |
517 "self": "selfTime", | |
518 "total": "totalTime", | |
519 "calls": "numberOfCalls", | |
520 "function": "functionName" | |
521 }[sortColumnIdentifier]; | |
522 | |
523 this.profileDataGridTree.sort(WebInspector.ProfileDataGridTree.propertyC
omparator(sortProperty, sortAscending)); | |
524 | |
525 this.refresh(); | |
526 }, | |
527 | |
528 _mouseDownInDataGrid: function(event) | |
529 { | |
530 if (event.detail < 2) | |
531 return; | |
532 | |
533 var cell = event.target.enclosingNodeOrSelfWithNodeName("td"); | |
534 if (!cell || (!cell.hasStyleClass("total-column") && !cell.hasStyleClass
("self-column") && !cell.hasStyleClass("average-column"))) | |
535 return; | |
536 | |
537 if (cell.hasStyleClass("total-column")) | |
538 this.showTotalTimeAsPercent = !this.showTotalTimeAsPercent; | |
539 else if (cell.hasStyleClass("self-column")) | |
540 this.showSelfTimeAsPercent = !this.showSelfTimeAsPercent; | |
541 else if (cell.hasStyleClass("average-column")) | |
542 this.showAverageTimeAsPercent = !this.showAverageTimeAsPercent; | |
543 | |
544 this.refreshShowAsPercents(); | |
545 | |
546 event.preventDefault(); | |
547 event.stopPropagation(); | |
548 }, | |
549 | |
550 _assignParentsInProfile: function() | |
551 { | |
552 var head = this.profile.head; | |
553 head.parent = null; | |
554 head.head = null; | |
555 var nodesToTraverse = [ { parent: head, children: head.children } ]; | |
556 while (nodesToTraverse.length > 0) { | |
557 var pair = nodesToTraverse.shift(); | |
558 var parent = pair.parent; | |
559 var children = pair.children; | |
560 var length = children.length; | |
561 for (var i = 0; i < length; ++i) { | |
562 children[i].head = head; | |
563 children[i].parent = parent; | |
564 if (children[i].children.length > 0) | |
565 nodesToTraverse.push({ parent: children[i], children: childr
en[i].children }); | |
566 } | |
567 } | |
568 } | |
569 } | |
570 | |
571 WebInspector.CPUProfileView.prototype.__proto__ = WebInspector.View.prototype; | |
572 | |
573 WebInspector.CPUProfileType = function() | |
574 { | |
575 WebInspector.ProfileType.call(this, WebInspector.CPUProfileType.TypeId, WebI
nspector.UIString("CPU PROFILES")); | |
576 this._recording = false; | |
577 } | |
578 | |
579 WebInspector.CPUProfileType.TypeId = "CPU"; | |
580 | |
581 WebInspector.CPUProfileType.prototype = { | |
582 get buttonTooltip() | |
583 { | |
584 return this._recording ? WebInspector.UIString("Stop profiling.") : WebI
nspector.UIString("Start profiling."); | |
585 }, | |
586 | |
587 get buttonStyle() | |
588 { | |
589 return this._recording ? "record-profile-status-bar-item status-bar-item
toggled-on" : "record-profile-status-bar-item status-bar-item"; | |
590 }, | |
591 | |
592 buttonClicked: function() | |
593 { | |
594 this._recording = !this._recording; | |
595 | |
596 if (this._recording) | |
597 InspectorController.startProfiling(); | |
598 else | |
599 InspectorController.stopProfiling(); | |
600 }, | |
601 | |
602 setRecordingProfile: function(isProfiling) | |
603 { | |
604 this._recording = isProfiling; | |
605 }, | |
606 | |
607 createSidebarTreeElementForProfile: function(profile) | |
608 { | |
609 return new WebInspector.ProfileSidebarTreeElement(profile); | |
610 }, | |
611 | |
612 createView: function(profile) | |
613 { | |
614 return new WebInspector.CPUProfileView(profile); | |
615 } | |
616 } | |
617 | |
618 WebInspector.CPUProfileType.prototype.__proto__ = WebInspector.ProfileType.proto
type; | |
619 | |
620 WebInspector.CPUProfile = function(profile) | |
621 { | |
622 this.representedObject = profile; | |
623 this.typeId = WebInspector.CPUProfileType.TypeId; | |
624 } | |
625 | |
626 WebInspector.CPUProfile.prototype = { | |
627 get title() | |
628 { | |
629 return this.representedObject.title; | |
630 }, | |
631 | |
632 get uid() | |
633 { | |
634 return this.representedObject.uid; | |
635 }, | |
636 | |
637 get head() | |
638 { | |
639 return this.representedObject.head; | |
640 } | |
641 } | |
OLD | NEW |