| Index: chrome_frame/tools/test/reference_build/chrome/resources/inspector/ProfileDataGridTree.js
|
| ===================================================================
|
| --- chrome_frame/tools/test/reference_build/chrome/resources/inspector/ProfileDataGridTree.js (revision 0)
|
| +++ chrome_frame/tools/test/reference_build/chrome/resources/inspector/ProfileDataGridTree.js (revision 0)
|
| @@ -0,0 +1,398 @@
|
| +/*
|
| + * 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);
|
| + },
|
| +
|
| + expand: function()
|
| + {
|
| + if (!this.parent) {
|
| + var currentComparator = this.parent.lastComparator;
|
| +
|
| + if (!currentComparator || (currentComparator === this.lastComparator))
|
| + return;
|
| +
|
| + this.sort(currentComparator);
|
| + }
|
| +
|
| + WebInspector.DataGridNode.prototype.expand.call(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)
|
| + 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;
|
| + },
|
| +
|
| + // 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;
|
| +}
|
|
|