Index: resources/inspector/ProfileDataGridTree.js |
=================================================================== |
--- resources/inspector/ProfileDataGridTree.js (revision 33840) |
+++ resources/inspector/ProfileDataGridTree.js (working copy) |
@@ -1,407 +0,0 @@ |
-/* |
- * Copyright (C) 2009 280 North Inc. All Rights Reserved. |
- * |
- * Redistribution and use in source and binary forms, with or without |
- * modification, are permitted provided that the following conditions |
- * are met: |
- * 1. Redistributions of source code must retain the above copyright |
- * notice, this list of conditions and the following disclaimer. |
- * 2. Redistributions in binary form must reproduce the above copyright |
- * notice, this list of conditions and the following disclaimer in the |
- * documentation and/or other materials provided with the distribution. |
- * |
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
- */ |
- |
-WebInspector.ProfileDataGridNode = function(profileView, profileNode, owningTree, hasChildren) |
-{ |
- this.profileView = profileView; |
- this.profileNode = profileNode; |
- |
- WebInspector.DataGridNode.call(this, null, hasChildren); |
- |
- this.addEventListener("populate", this._populate, this); |
- |
- this.tree = owningTree; |
- |
- this.childrenByCallUID = {}; |
- this.lastComparator = null; |
- |
- this.callUID = profileNode.callUID; |
- this.selfTime = profileNode.selfTime; |
- this.totalTime = profileNode.totalTime; |
- this.functionName = profileNode.functionName; |
- this.numberOfCalls = profileNode.numberOfCalls; |
- this.url = profileNode.url; |
-} |
- |
-WebInspector.ProfileDataGridNode.prototype = { |
- get data() |
- { |
- function formatMilliseconds(time) |
- { |
- return Number.secondsToString(time / 1000, WebInspector.UIString.bind(WebInspector), !Preferences.samplingCPUProfiler); |
- } |
- |
- var data = {}; |
- |
- data["function"] = this.functionName; |
- data["calls"] = this.numberOfCalls; |
- |
- if (this.profileView.showSelfTimeAsPercent) |
- data["self"] = WebInspector.UIString("%.2f%%", this.selfPercent); |
- else |
- data["self"] = formatMilliseconds(this.selfTime); |
- |
- if (this.profileView.showTotalTimeAsPercent) |
- data["total"] = WebInspector.UIString("%.2f%%", this.totalPercent); |
- else |
- data["total"] = formatMilliseconds(this.totalTime); |
- |
- if (this.profileView.showAverageTimeAsPercent) |
- data["average"] = WebInspector.UIString("%.2f%%", this.averagePercent); |
- else |
- data["average"] = formatMilliseconds(this.averageTime); |
- |
- return data; |
- }, |
- |
- createCell: function(columnIdentifier) |
- { |
- var cell = WebInspector.DataGridNode.prototype.createCell.call(this, columnIdentifier); |
- |
- if (columnIdentifier === "self" && this._searchMatchedSelfColumn) |
- cell.addStyleClass("highlight"); |
- else if (columnIdentifier === "total" && this._searchMatchedTotalColumn) |
- cell.addStyleClass("highlight"); |
- else if (columnIdentifier === "average" && this._searchMatchedAverageColumn) |
- cell.addStyleClass("highlight"); |
- else if (columnIdentifier === "calls" && this._searchMatchedCallsColumn) |
- cell.addStyleClass("highlight"); |
- |
- if (columnIdentifier !== "function") |
- return cell; |
- |
- if (this.profileNode._searchMatchedFunctionColumn) |
- cell.addStyleClass("highlight"); |
- |
- if (this.profileNode.url) { |
- var fileName = WebInspector.displayNameForURL(this.profileNode.url); |
- |
- var urlElement = document.createElement("a"); |
- urlElement.className = "profile-node-file webkit-html-resource-link"; |
- urlElement.href = this.profileNode.url; |
- urlElement.lineNumber = this.profileNode.lineNumber; |
- |
- if (this.profileNode.lineNumber > 0) |
- urlElement.textContent = fileName + ":" + this.profileNode.lineNumber; |
- else |
- urlElement.textContent = fileName; |
- |
- cell.insertBefore(urlElement, cell.firstChild); |
- } |
- |
- return cell; |
- }, |
- |
- select: function(supressSelectedEvent) |
- { |
- WebInspector.DataGridNode.prototype.select.call(this, supressSelectedEvent); |
- this.profileView._dataGridNodeSelected(this); |
- }, |
- |
- deselect: function(supressDeselectedEvent) |
- { |
- WebInspector.DataGridNode.prototype.deselect.call(this, supressDeselectedEvent); |
- this.profileView._dataGridNodeDeselected(this); |
- }, |
- |
- sort: function(/*Function*/ comparator, /*Boolean*/ force) |
- { |
- var gridNodeGroups = [[this]]; |
- |
- for (var gridNodeGroupIndex = 0; gridNodeGroupIndex < gridNodeGroups.length; ++gridNodeGroupIndex) { |
- var gridNodes = gridNodeGroups[gridNodeGroupIndex]; |
- var count = gridNodes.length; |
- |
- for (var index = 0; index < count; ++index) { |
- var gridNode = gridNodes[index]; |
- |
- // If the grid node is collapsed, then don't sort children (save operation for later). |
- // If the grid node has the same sorting as previously, then there is no point in sorting it again. |
- if (!force && (!gridNode.expanded || gridNode.lastComparator === comparator)) { |
- if (gridNode.children.length) |
- gridNode.shouldRefreshChildren = true; |
- continue; |
- } |
- |
- gridNode.lastComparator = comparator; |
- |
- var children = gridNode.children; |
- var childCount = children.length; |
- |
- if (childCount) { |
- children.sort(comparator); |
- |
- for (var childIndex = 0; childIndex < childCount; ++childIndex) |
- children[childIndex]._recalculateSiblings(childIndex); |
- |
- gridNodeGroups.push(children); |
- } |
- } |
- } |
- }, |
- |
- insertChild: function(/*ProfileDataGridNode*/ profileDataGridNode, index) |
- { |
- WebInspector.DataGridNode.prototype.insertChild.call(this, profileDataGridNode, index); |
- |
- this.childrenByCallUID[profileDataGridNode.callUID] = profileDataGridNode; |
- }, |
- |
- removeChild: function(/*ProfileDataGridNode*/ profileDataGridNode) |
- { |
- WebInspector.DataGridNode.prototype.removeChild.call(this, profileDataGridNode); |
- |
- delete this.childrenByCallUID[profileDataGridNode.callUID]; |
- }, |
- |
- removeChildren: function(/*ProfileDataGridNode*/ profileDataGridNode) |
- { |
- WebInspector.DataGridNode.prototype.removeChildren.call(this); |
- |
- this.childrenByCallUID = {}; |
- }, |
- |
- findChild: function(/*Node*/ node) |
- { |
- if (!node) |
- return null; |
- return this.childrenByCallUID[node.callUID]; |
- }, |
- |
- get averageTime() |
- { |
- return this.selfTime / Math.max(1, this.numberOfCalls); |
- }, |
- |
- get averagePercent() |
- { |
- return this.averageTime / this.tree.totalTime * 100.0; |
- }, |
- |
- get selfPercent() |
- { |
- return this.selfTime / this.tree.totalTime * 100.0; |
- }, |
- |
- get totalPercent() |
- { |
- return this.totalTime / this.tree.totalTime * 100.0; |
- }, |
- |
- get _parent() |
- { |
- return this.parent !== this.dataGrid ? this.parent : this.tree; |
- }, |
- |
- _populate: function(event) |
- { |
- this._sharedPopulate(); |
- |
- if (this._parent) { |
- var currentComparator = this._parent.lastComparator; |
- |
- if (currentComparator) |
- this.sort(currentComparator, true); |
- } |
- |
- if (this.removeEventListener) |
- this.removeEventListener("populate", this._populate, this); |
- }, |
- |
- // When focusing and collapsing we modify lots of nodes in the tree. |
- // This allows us to restore them all to their original state when we revert. |
- _save: function() |
- { |
- if (this._savedChildren) |
- return; |
- |
- this._savedSelfTime = this.selfTime; |
- this._savedTotalTime = this.totalTime; |
- this._savedNumberOfCalls = this.numberOfCalls; |
- |
- this._savedChildren = this.children.slice(); |
- }, |
- |
- // When focusing and collapsing we modify lots of nodes in the tree. |
- // This allows us to restore them all to their original state when we revert. |
- _restore: function() |
- { |
- if (!this._savedChildren) |
- return; |
- |
- this.selfTime = this._savedSelfTime; |
- this.totalTime = this._savedTotalTime; |
- this.numberOfCalls = this._savedNumberOfCalls; |
- |
- this.removeChildren(); |
- |
- var children = this._savedChildren; |
- var count = children.length; |
- |
- for (var index = 0; index < count; ++index) { |
- children[index]._restore(); |
- this.appendChild(children[index]); |
- } |
- }, |
- |
- _merge: function(child, shouldAbsorb) |
- { |
- this.selfTime += child.selfTime; |
- |
- if (!shouldAbsorb) { |
- this.totalTime += child.totalTime; |
- this.numberOfCalls += child.numberOfCalls; |
- } |
- |
- var children = this.children.slice(); |
- |
- this.removeChildren(); |
- |
- var count = children.length; |
- |
- for (var index = 0; index < count; ++index) { |
- if (!shouldAbsorb || children[index] !== child) |
- this.appendChild(children[index]); |
- } |
- |
- children = child.children.slice(); |
- count = children.length; |
- |
- for (var index = 0; index < count; ++index) { |
- var orphanedChild = children[index], |
- existingChild = this.childrenByCallUID[orphanedChild.callUID]; |
- |
- if (existingChild) |
- existingChild._merge(orphanedChild, false); |
- else |
- this.appendChild(orphanedChild); |
- } |
- } |
-} |
- |
-WebInspector.ProfileDataGridNode.prototype.__proto__ = WebInspector.DataGridNode.prototype; |
- |
-WebInspector.ProfileDataGridTree = function(profileView, profileNode) |
-{ |
- this.tree = this; |
- this.children = []; |
- |
- this.profileView = profileView; |
- |
- this.totalTime = profileNode.totalTime; |
- this.lastComparator = null; |
- |
- this.childrenByCallUID = {}; |
-} |
- |
-WebInspector.ProfileDataGridTree.prototype = { |
- get expanded() |
- { |
- return true; |
- }, |
- |
- appendChild: function(child) |
- { |
- this.insertChild(child, this.children.length); |
- }, |
- |
- insertChild: function(child, index) |
- { |
- this.children.splice(index, 0, child); |
- this.childrenByCallUID[child.callUID] = child; |
- }, |
- |
- removeChildren: function() |
- { |
- this.children = []; |
- this.childrenByCallUID = {}; |
- }, |
- |
- findChild: WebInspector.ProfileDataGridNode.prototype.findChild, |
- sort: WebInspector.ProfileDataGridNode.prototype.sort, |
- |
- _save: function() |
- { |
- if (this._savedChildren) |
- return; |
- |
- this._savedTotalTime = this.totalTime; |
- this._savedChildren = this.children.slice(); |
- }, |
- |
- restore: function() |
- { |
- if (!this._savedChildren) |
- return; |
- |
- this.children = this._savedChildren; |
- this.totalTime = this._savedTotalTime; |
- |
- var children = this.children; |
- var count = children.length; |
- |
- for (var index = 0; index < count; ++index) |
- children[index]._restore(); |
- |
- this._savedChildren = null; |
- } |
-} |
- |
-WebInspector.ProfileDataGridTree.propertyComparators = [{}, {}]; |
- |
-WebInspector.ProfileDataGridTree.propertyComparator = function(/*String*/ property, /*Boolean*/ isAscending) |
-{ |
- var comparator = this.propertyComparators[(isAscending ? 1 : 0)][property]; |
- |
- if (!comparator) { |
- if (isAscending) { |
- comparator = function(lhs, rhs) |
- { |
- if (lhs[property] < rhs[property]) |
- return -1; |
- |
- if (lhs[property] > rhs[property]) |
- return 1; |
- |
- return 0; |
- } |
- } else { |
- comparator = function(lhs, rhs) |
- { |
- if (lhs[property] > rhs[property]) |
- return -1; |
- |
- if (lhs[property] < rhs[property]) |
- return 1; |
- |
- return 0; |
- } |
- } |
- |
- this.propertyComparators[(isAscending ? 1 : 0)][property] = comparator; |
- } |
- |
- return comparator; |
-} |