OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. | 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 this.viewSelectElement.addEventListener("change", this._changeView.bind(this
), false); | 49 this.viewSelectElement.addEventListener("change", this._changeView.bind(this
), false); |
50 this.view = "Heavy"; | 50 this.view = "Heavy"; |
51 | 51 |
52 var heavyViewOption = document.createElement("option"); | 52 var heavyViewOption = document.createElement("option"); |
53 heavyViewOption.label = WebInspector.UIString("Heavy (Bottom Up)"); | 53 heavyViewOption.label = WebInspector.UIString("Heavy (Bottom Up)"); |
54 var treeViewOption = document.createElement("option"); | 54 var treeViewOption = document.createElement("option"); |
55 treeViewOption.label = WebInspector.UIString("Tree (Top Down)"); | 55 treeViewOption.label = WebInspector.UIString("Tree (Top Down)"); |
56 this.viewSelectElement.appendChild(heavyViewOption); | 56 this.viewSelectElement.appendChild(heavyViewOption); |
57 this.viewSelectElement.appendChild(treeViewOption); | 57 this.viewSelectElement.appendChild(treeViewOption); |
58 | 58 |
59 this.percentButton = document.createElement("button"); | 59 this.percentButton = new WebInspector.StatusBarButton("", "percent-time-stat
us-bar-item"); |
60 this.percentButton.className = "percent-time-status-bar-item status-bar-item
"; | |
61 this.percentButton.addEventListener("click", this._percentClicked.bind(this)
, false); | 60 this.percentButton.addEventListener("click", this._percentClicked.bind(this)
, false); |
62 | 61 |
63 this.focusButton = document.createElement("button"); | 62 this.focusButton = new WebInspector.StatusBarButton(WebInspector.UIString("F
ocus selected function."), "focus-profile-node-status-bar-item"); |
64 this.focusButton.title = WebInspector.UIString("Focus selected function."); | |
65 this.focusButton.className = "focus-profile-node-status-bar-item status-bar-
item"; | |
66 this.focusButton.disabled = true; | 63 this.focusButton.disabled = true; |
67 this.focusButton.addEventListener("click", this._focusClicked.bind(this), fa
lse); | 64 this.focusButton.addEventListener("click", this._focusClicked.bind(this), fa
lse); |
68 | 65 |
69 this.excludeButton = document.createElement("button"); | 66 this.excludeButton = new WebInspector.StatusBarButton(WebInspector.UIString(
"Exclude selected function."), "exclude-profile-node-status-bar-item"); |
70 this.excludeButton.title = WebInspector.UIString("Exclude selected function.
"); | |
71 this.excludeButton.className = "exclude-profile-node-status-bar-item status-
bar-item"; | |
72 this.excludeButton.disabled = true; | 67 this.excludeButton.disabled = true; |
73 this.excludeButton.addEventListener("click", this._excludeClicked.bind(this)
, false); | 68 this.excludeButton.addEventListener("click", this._excludeClicked.bind(this)
, false); |
74 | 69 |
75 this.resetButton = document.createElement("button"); | 70 this.resetButton = new WebInspector.StatusBarButton(WebInspector.UIString("R
estore all functions."), "reset-profile-status-bar-item"); |
76 this.resetButton.title = WebInspector.UIString("Restore all functions."); | 71 this.resetButton.visible = false; |
77 this.resetButton.className = "reset-profile-status-bar-item status-bar-item
hidden"; | |
78 this.resetButton.addEventListener("click", this._resetClicked.bind(this), fa
lse); | 72 this.resetButton.addEventListener("click", this._resetClicked.bind(this), fa
lse); |
79 | 73 |
80 this.profile = profile; | 74 this.profile = profile; |
81 | 75 |
82 this.profileDataGridTree = this.bottomUpProfileDataGridTree; | 76 this.profileDataGridTree = this.bottomUpProfileDataGridTree; |
83 this.profileDataGridTree.sort(WebInspector.ProfileDataGridTree.propertyCompa
rator("selfTime", false)); | 77 this.profileDataGridTree.sort(WebInspector.ProfileDataGridTree.propertyCompa
rator("selfTime", false)); |
84 | 78 |
85 this.refresh(); | 79 this.refresh(); |
86 | 80 |
87 this._updatePercentButton(); | 81 this._updatePercentButton(); |
88 } | 82 } |
89 | 83 |
90 WebInspector.ProfileView.prototype = { | 84 WebInspector.ProfileView.prototype = { |
91 get statusBarItems() | 85 get statusBarItems() |
92 { | 86 { |
93 return [this.viewSelectElement, this.percentButton, this.focusButton, th
is.excludeButton, this.resetButton]; | 87 return [this.viewSelectElement, this.percentButton.element, this.focusBu
tton.element, this.excludeButton.element, this.resetButton.element]; |
94 }, | 88 }, |
95 | 89 |
96 get profile() | 90 get profile() |
97 { | 91 { |
98 return this._profile; | 92 return this._profile; |
99 }, | 93 }, |
100 | 94 |
101 set profile(profile) | 95 set profile(profile) |
102 { | 96 { |
103 this._profile = profile; | 97 this._profile = profile; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 get bottomUpTree() | 135 get bottomUpTree() |
142 { | 136 { |
143 if (!this._bottomUpTree) { | 137 if (!this._bottomUpTree) { |
144 this._bottomUpTree = WebInspector.BottomUpTreeFactory.create(this.pr
ofile.head); | 138 this._bottomUpTree = WebInspector.BottomUpTreeFactory.create(this.pr
ofile.head); |
145 this._sortProfile(this._bottomUpTree); | 139 this._sortProfile(this._bottomUpTree); |
146 } | 140 } |
147 | 141 |
148 return this._bottomUpTree; | 142 return this._bottomUpTree; |
149 }, | 143 }, |
150 | 144 |
| 145 show: function(parentElement) |
| 146 { |
| 147 WebInspector.View.prototype.show.call(this, parentElement); |
| 148 this.dataGrid.updateWidths(); |
| 149 }, |
| 150 |
151 hide: function() | 151 hide: function() |
152 { | 152 { |
153 WebInspector.View.prototype.hide.call(this); | 153 WebInspector.View.prototype.hide.call(this); |
154 this._currentSearchResultIndex = -1; | 154 this._currentSearchResultIndex = -1; |
155 }, | 155 }, |
| 156 |
| 157 resize: function() |
| 158 { |
| 159 if (this.dataGrid) |
| 160 this.dataGrid.updateWidths(); |
| 161 }, |
156 | 162 |
157 refresh: function() | 163 refresh: function() |
158 { | 164 { |
159 var selectedProfileNode = this.dataGrid.selectedNode ? this.dataGrid.sel
ectedNode.profileNode : null; | 165 var selectedProfileNode = this.dataGrid.selectedNode ? this.dataGrid.sel
ectedNode.profileNode : null; |
160 | 166 |
161 this.dataGrid.removeChildren(); | 167 this.dataGrid.removeChildren(); |
162 | 168 |
163 var children = this.profileDataGridTree.children; | 169 var children = this.profileDataGridTree.children; |
164 var count = children.length; | 170 var count = children.length; |
165 | 171 |
166 for (var index = 0; index < count; ++index) | 172 for (var index = 0; index < count; ++index) |
167 this.dataGrid.appendChild(children[index]); | 173 this.dataGrid.appendChild(children[index]); |
168 | 174 |
169 if (selectedProfileNode && selectedProfileNode._dataGridNode) | 175 if (selectedProfileNode) |
170 selectedProfileNode._dataGridNode.selected = true; | 176 selectedProfileNode.selected = true; |
171 }, | 177 }, |
172 | 178 |
173 refreshVisibleData: function() | 179 refreshVisibleData: function() |
174 { | 180 { |
175 var child = this.dataGrid.children[0]; | 181 var child = this.dataGrid.children[0]; |
176 while (child) { | 182 while (child) { |
177 child.refresh(); | 183 child.refresh(); |
178 child = child.traverseNextNode(false, null, true); | 184 child = child.traverseNextNode(false, null, true); |
179 } | 185 } |
180 }, | 186 }, |
181 | 187 |
182 refreshShowAsPercents: function() | 188 refreshShowAsPercents: function() |
183 { | 189 { |
184 this._updatePercentButton(); | 190 this._updatePercentButton(); |
185 this.refreshVisibleData(); | 191 this.refreshVisibleData(); |
186 }, | 192 }, |
187 | 193 |
188 searchCanceled: function() | 194 searchCanceled: function() |
189 { | 195 { |
190 if (this._searchResults) { | 196 if (this._searchResults) { |
191 for (var i = 0; i < this._searchResults.length; ++i) { | 197 for (var i = 0; i < this._searchResults.length; ++i) { |
192 var profileNode = this._searchResults[i].profileNode; | 198 var profileNode = this._searchResults[i].profileNode; |
193 | 199 |
194 delete profileNode._searchMatchedSelfColumn; | 200 delete profileNode._searchMatchedSelfColumn; |
195 delete profileNode._searchMatchedTotalColumn; | 201 delete profileNode._searchMatchedTotalColumn; |
196 delete profileNode._searchMatchedCallsColumn; | 202 delete profileNode._searchMatchedCallsColumn; |
197 delete profileNode._searchMatchedFunctionColumn; | 203 delete profileNode._searchMatchedFunctionColumn; |
198 | 204 |
199 if (profileNode._dataGridNode) | 205 profileNode.refresh(); |
200 profileNode._dataGridNode.refresh(); | |
201 } | 206 } |
202 } | 207 } |
203 | 208 |
204 delete this._searchFinishedCallback; | 209 delete this._searchFinishedCallback; |
205 this._currentSearchResultIndex = -1; | 210 this._currentSearchResultIndex = -1; |
206 this._searchResults = []; | 211 this._searchResults = []; |
207 }, | 212 }, |
208 | 213 |
209 performSearch: function(query, finishedCallback) | 214 performSearch: function(query, finishedCallback) |
210 { | 215 { |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 profileDataGridNode._searchMatchedCallsColumn = true; | 311 profileDataGridNode._searchMatchedCallsColumn = true; |
307 } | 312 } |
308 | 313 |
309 if (profileDataGridNode.functionName.hasSubstring(query, true) || pr
ofileDataGridNode.url.hasSubstring(query, true)) | 314 if (profileDataGridNode.functionName.hasSubstring(query, true) || pr
ofileDataGridNode.url.hasSubstring(query, true)) |
310 profileDataGridNode._searchMatchedFunctionColumn = true; | 315 profileDataGridNode._searchMatchedFunctionColumn = true; |
311 | 316 |
312 if (profileDataGridNode._searchMatchedSelfColumn || | 317 if (profileDataGridNode._searchMatchedSelfColumn || |
313 profileDataGridNode._searchMatchedTotalColumn || | 318 profileDataGridNode._searchMatchedTotalColumn || |
314 profileDataGridNode._searchMatchedAverageColumn || | 319 profileDataGridNode._searchMatchedAverageColumn || |
315 profileDataGridNode._searchMatchedCallsColumn || | 320 profileDataGridNode._searchMatchedCallsColumn || |
316 profileDataGridNode._searchMatchedFunctionColumn); | 321 profileDataGridNode._searchMatchedFunctionColumn) |
317 { | 322 { |
318 profileDataGridNode.refresh(); | 323 profileDataGridNode.refresh(); |
319 return true; | 324 return true; |
320 } | 325 } |
321 | 326 |
322 return false; | 327 return false; |
323 } | 328 } |
324 | 329 |
325 var current = this.dataGrid; | 330 var current = this.profileDataGridTree.children[0]; |
326 var ancestors = []; | |
327 var nextIndexes = []; | |
328 var startIndex = 0; | |
329 | 331 |
330 while (current) { | 332 while (current) { |
331 var children = current.children; | 333 if (matchesQuery(current)) { |
332 var childrenLength = children.length; | 334 this._searchResults.push({ profileNode: current }); |
333 | |
334 if (startIndex >= childrenLength) { | |
335 current = ancestors.pop(); | |
336 startIndex = nextIndexes.pop(); | |
337 continue; | |
338 } | 335 } |
339 | 336 |
340 for (var i = startIndex; i < childrenLength; ++i) { | 337 current = current.traverseNextNode(false, null, false); |
341 var child = children[i]; | |
342 | |
343 if (matchesQuery(child)) { | |
344 if (child._dataGridNode) { | |
345 // The child has a data grid node already, no need to re
member the ancestors. | |
346 this._searchResults.push({ profileNode: child }); | |
347 } else { | |
348 var ancestorsCopy = [].concat(ancestors); | |
349 ancestorsCopy.push(current); | |
350 this._searchResults.push({ profileNode: child, ancestors
: ancestorsCopy }); | |
351 } | |
352 } | |
353 | |
354 if (child.children.length) { | |
355 ancestors.push(current); | |
356 nextIndexes.push(i + 1); | |
357 current = child; | |
358 startIndex = 0; | |
359 break; | |
360 } | |
361 | |
362 if (i === (childrenLength - 1)) { | |
363 current = ancestors.pop(); | |
364 startIndex = nextIndexes.pop(); | |
365 } | |
366 } | |
367 } | 338 } |
368 | 339 |
369 finishedCallback(this, this._searchResults.length); | 340 finishedCallback(this, this._searchResults.length); |
370 }, | 341 }, |
371 | 342 |
372 jumpToFirstSearchResult: function() | 343 jumpToFirstSearchResult: function() |
373 { | 344 { |
374 if (!this._searchResults || !this._searchResults.length) | 345 if (!this._searchResults || !this._searchResults.length) |
375 return; | 346 return; |
376 this._currentSearchResultIndex = 0; | 347 this._currentSearchResultIndex = 0; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 { | 383 { |
413 return (this._searchResults && this._currentSearchResultIndex === (this.
_searchResults.length - 1)); | 384 return (this._searchResults && this._currentSearchResultIndex === (this.
_searchResults.length - 1)); |
414 }, | 385 }, |
415 | 386 |
416 _jumpToSearchResult: function(index) | 387 _jumpToSearchResult: function(index) |
417 { | 388 { |
418 var searchResult = this._searchResults[index]; | 389 var searchResult = this._searchResults[index]; |
419 if (!searchResult) | 390 if (!searchResult) |
420 return; | 391 return; |
421 | 392 |
422 var profileNode = this._searchResults[index].profileNode; | 393 var profileNode = searchResult.profileNode; |
423 if (!profileNode._dataGridNode && searchResult.ancestors) { | 394 profileNode.reveal(); |
424 var ancestors = searchResult.ancestors; | 395 profileNode.select(); |
425 for (var i = 0; i < ancestors.length; ++i) { | |
426 var ancestorProfileNode = ancestors[i]; | |
427 var gridNode = ancestorProfileNode._dataGridNode; | |
428 if (gridNode) | |
429 gridNode.expand(); | |
430 } | |
431 | |
432 // No need to keep the ancestors around. | |
433 delete searchResult.ancestors; | |
434 } | |
435 | |
436 gridNode = profileNode._dataGridNode; | |
437 if (!gridNode) | |
438 return; | |
439 | |
440 gridNode.reveal(); | |
441 gridNode.select(); | |
442 }, | 396 }, |
443 | 397 |
444 _changeView: function(event) | 398 _changeView: function(event) |
445 { | 399 { |
446 if (!event || !this.profile) | 400 if (!event || !this.profile) |
447 return; | 401 return; |
448 | 402 |
449 if (event.target.selectedIndex == 1 && this.view == "Heavy") { | 403 if (event.target.selectedIndex == 1 && this.view == "Heavy") { |
450 this.profileDataGridTree = this.topDownProfileDataGridTree; | 404 this.profileDataGridTree = this.topDownProfileDataGridTree; |
451 this._sortProfile(); | 405 this._sortProfile(); |
(...skipping 20 matching lines...) Expand all Loading... |
472 this.showSelfTimeAsPercent = !currentState; | 426 this.showSelfTimeAsPercent = !currentState; |
473 this.showTotalTimeAsPercent = !currentState; | 427 this.showTotalTimeAsPercent = !currentState; |
474 this.showAverageTimeAsPercent = !currentState; | 428 this.showAverageTimeAsPercent = !currentState; |
475 this.refreshShowAsPercents(); | 429 this.refreshShowAsPercents(); |
476 }, | 430 }, |
477 | 431 |
478 _updatePercentButton: function() | 432 _updatePercentButton: function() |
479 { | 433 { |
480 if (this.showSelfTimeAsPercent && this.showTotalTimeAsPercent && this.sh
owAverageTimeAsPercent) { | 434 if (this.showSelfTimeAsPercent && this.showTotalTimeAsPercent && this.sh
owAverageTimeAsPercent) { |
481 this.percentButton.title = WebInspector.UIString("Show absolute tota
l and self times."); | 435 this.percentButton.title = WebInspector.UIString("Show absolute tota
l and self times."); |
482 this.percentButton.addStyleClass("toggled-on"); | 436 this.percentButton.toggled = true; |
483 } else { | 437 } else { |
484 this.percentButton.title = WebInspector.UIString("Show total and sel
f times as percentages."); | 438 this.percentButton.title = WebInspector.UIString("Show total and sel
f times as percentages."); |
485 this.percentButton.removeStyleClass("toggled-on"); | 439 this.percentButton.toggled = false; |
486 } | 440 } |
487 }, | 441 }, |
488 | 442 |
489 _focusClicked: function(event) | 443 _focusClicked: function(event) |
490 { | 444 { |
491 if (!this.dataGrid.selectedNode) | 445 if (!this.dataGrid.selectedNode) |
492 return; | 446 return; |
493 | 447 |
494 this.resetButton.removeStyleClass("hidden"); | 448 this.resetButton.visible = true; |
495 this.profileDataGridTree.focus(this.dataGrid.selectedNode); | 449 this.profileDataGridTree.focus(this.dataGrid.selectedNode); |
496 this.refresh(); | 450 this.refresh(); |
497 this.refreshVisibleData(); | 451 this.refreshVisibleData(); |
498 }, | 452 }, |
499 | 453 |
500 _excludeClicked: function(event) | 454 _excludeClicked: function(event) |
501 { | 455 { |
502 var selectedNode = this.dataGrid.selectedNode | 456 var selectedNode = this.dataGrid.selectedNode |
503 | 457 |
504 if (!selectedNode) | 458 if (!selectedNode) |
505 return; | 459 return; |
506 | 460 |
507 selectedNode.deselect(); | 461 selectedNode.deselect(); |
508 | 462 |
509 this.resetButton.removeStyleClass("hidden"); | 463 this.resetButton.visible = true; |
510 this.profileDataGridTree.exclude(selectedNode); | 464 this.profileDataGridTree.exclude(selectedNode); |
511 this.refresh(); | 465 this.refresh(); |
512 this.refreshVisibleData(); | 466 this.refreshVisibleData(); |
513 }, | 467 }, |
514 | 468 |
515 _resetClicked: function(event) | 469 _resetClicked: function(event) |
516 { | 470 { |
517 this.resetButton.addStyleClass("hidden"); | 471 this.resetButton.visible = false; |
518 this.profileDataGridTree.restore(); | 472 this.profileDataGridTree.restore(); |
519 this.refresh(); | 473 this.refresh(); |
520 this.refreshVisibleData(); | 474 this.refreshVisibleData(); |
521 }, | 475 }, |
522 | 476 |
523 _dataGridNodeSelected: function(node) | 477 _dataGridNodeSelected: function(node) |
524 { | 478 { |
525 this.focusButton.disabled = false; | 479 this.focusButton.disabled = false; |
526 this.excludeButton.disabled = false; | 480 this.excludeButton.disabled = false; |
527 }, | 481 }, |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
571 this.showAverageTimeAsPercent = !this.showAverageTimeAsPercent; | 525 this.showAverageTimeAsPercent = !this.showAverageTimeAsPercent; |
572 | 526 |
573 this.refreshShowAsPercents(); | 527 this.refreshShowAsPercents(); |
574 | 528 |
575 event.preventDefault(); | 529 event.preventDefault(); |
576 event.stopPropagation(); | 530 event.stopPropagation(); |
577 } | 531 } |
578 } | 532 } |
579 | 533 |
580 WebInspector.ProfileView.prototype.__proto__ = WebInspector.View.prototype; | 534 WebInspector.ProfileView.prototype.__proto__ = WebInspector.View.prototype; |
OLD | NEW |