| /* |
| * Copyright (C) 2011 Google 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: |
| * |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * 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. |
| * * Neither the name of Google Inc. nor the names of its |
| * contributors may be used to endorse or promote products derived from |
| * this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "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 THE COPYRIGHT |
| * OWNER 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.HeapSnapshotGridNode = function(tree, hasChildren) |
| { |
| WebInspector.DataGridNode.call(this, null, hasChildren); |
| this._defaultPopulateCount = tree._defaultPopulateCount; |
| this._provider = null; |
| this.addEventListener("populate", this._populate, this); |
| } |
| |
| WebInspector.HeapSnapshotGridNode.prototype = { |
| createCell: function(columnIdentifier) |
| { |
| var cell = WebInspector.DataGridNode.prototype.createCell.call(this, columnIdentifier); |
| if (this._searchMatched) |
| cell.addStyleClass("highlight"); |
| return cell; |
| }, |
| |
| _populate: function(event) |
| { |
| WebInspector.PleaseWaitMessage.prototype.startAction(this.dataGrid.element, doPopulate.bind(this)); |
| |
| function doPopulate() |
| { |
| this.removeEventListener("populate", this._populate, this); |
| function sorted(ignored) |
| { |
| this.populateChildren(); |
| } |
| this._provider.sortAndRewind(this.comparator(), sorted.bind(this)); |
| } |
| }, |
| |
| populateChildren: function(provider, howMany, atIndex, afterPopulate, suppressNotifyAboutCompletion) |
| { |
| if (!howMany && provider) { |
| howMany = provider.instanceCount; |
| provider.instanceCount = 0; |
| } |
| provider = provider || this._provider; |
| if (!("instanceCount" in provider)) |
| provider.instanceCount = 0; |
| howMany = howMany || this._defaultPopulateCount; |
| atIndex = atIndex || this.children.length; |
| var haveSavedChildren = !!this._savedChildren; |
| if (haveSavedChildren) { |
| haveSavedChildren = false; |
| for (var c in this._savedChildren) { |
| haveSavedChildren = true; |
| break; |
| } |
| } |
| |
| function childrenRetrieved(items, hasNext, length) |
| { |
| for (var i = 0, l = items.length; i < l; ++i) { |
| var item = items[i]; |
| if (haveSavedChildren) { |
| var hash = this._childHashForEntity(item); |
| if (hash in this._savedChildren) { |
| this.insertChild(this._savedChildren[hash], atIndex++); |
| continue; |
| } |
| } |
| this.insertChild(this._createChildNode(item, provider), atIndex++); |
| } |
| provider.instanceCount += items.length; |
| |
| if (hasNext) |
| this.insertChild(new WebInspector.ShowMoreDataGridNode(this.populateChildren.bind(this, provider), this._defaultPopulateCount, length), atIndex++); |
| if (afterPopulate) |
| afterPopulate(); |
| if (!suppressNotifyAboutCompletion) { |
| function notify() |
| { |
| this.dispatchEventToListeners("populate complete"); |
| } |
| setTimeout(notify.bind(this), 0); |
| } |
| } |
| provider.getNextItems(howMany, childrenRetrieved.bind(this)); |
| }, |
| |
| _saveChildren: function() |
| { |
| this._savedChildren = {}; |
| for (var i = 0, childrenCount = this.children.length; i < childrenCount; ++i) { |
| var child = this.children[i]; |
| if (child.expanded) |
| this._savedChildren[this._childHashForNode(child)] = child; |
| } |
| }, |
| |
| sort: function() |
| { |
| function doSort() |
| { |
| function afterSort(sorted) |
| { |
| if (!sorted) |
| return; |
| this._saveChildren(); |
| this.removeChildren(); |
| |
| function afterPopulate() |
| { |
| for (var i = 0, l = this.children.length; i < l; ++i) { |
| var child = this.children[i]; |
| if (child.expanded) |
| child.sort(); |
| } |
| this.dataGrid.dispatchEventToListeners("sorting complete"); |
| } |
| this.populateChildren(this._provider, null, null, afterPopulate.bind(this)); |
| } |
| this._provider.sortAndRewind(this.comparator(), afterSort.bind(this)); |
| } |
| this.dataGrid.dispatchEventToListeners("start sorting"); |
| WebInspector.PleaseWaitMessage.prototype.startAction(this.dataGrid.element, doSort.bind(this)); |
| } |
| }; |
| |
| WebInspector.HeapSnapshotGridNode.prototype.__proto__ = WebInspector.DataGridNode.prototype; |
| |
| WebInspector.HeapSnapshotGenericObjectNode = function(tree, node) |
| { |
| WebInspector.HeapSnapshotGridNode.call(this, tree, false); |
| this._name = node.name; |
| this._type = node.type; |
| this._shallowSize = node.selfSize; |
| this._retainedSize = node.retainedSize; |
| this.snapshotNodeId = node.id; |
| this.snapshotNodeIndex = node.nodeIndex; |
| }; |
| |
| WebInspector.HeapSnapshotGenericObjectNode.prototype = { |
| createCell: function(columnIdentifier) |
| { |
| var cell = columnIdentifier !== "object" ? WebInspector.DataGridNode.prototype.createCell.call(this, columnIdentifier) : this._createObjectCell(); |
| if (this._searchMatched) |
| cell.addStyleClass("highlight"); |
| return cell; |
| }, |
| |
| _createObjectCell: function() |
| { |
| var cell = document.createElement("td"); |
| cell.className = "object-column"; |
| var div = document.createElement("div"); |
| div.className = "source-code event-properties"; |
| div.style.overflow = "hidden"; |
| var data = this.data["object"]; |
| if (this._prefixObjectCell) |
| this._prefixObjectCell(div, data); |
| var valueSpan = document.createElement("span"); |
| valueSpan.className = "value console-formatted-" + data.valueStyle; |
| valueSpan.textContent = data.value; |
| div.appendChild(valueSpan); |
| cell.appendChild(div); |
| cell.addStyleClass("disclosure"); |
| if (this.depth) |
| cell.style.setProperty("padding-left", (this.depth * this.dataGrid.indentWidth) + "px"); |
| return cell; |
| }, |
| |
| get _countPercent() |
| { |
| return this._count / this.dataGrid.snapshot.nodeCount * 100.0; |
| }, |
| |
| get data() |
| { |
| var data = this._emptyData(); |
| |
| var value = this._name; |
| var valueStyle = "object"; |
| switch (this._type) { |
| case "string": |
| value = "\"" + value + "\""; |
| valueStyle = "string"; |
| break; |
| case "regexp": |
| value = "/" + value + "/"; |
| valueStyle = "string"; |
| break; |
| case "closure": |
| value = "function " + value + "()"; |
| valueStyle = "function"; |
| break; |
| case "number": |
| valueStyle = "number"; |
| break; |
| case "hidden": |
| valueStyle = "null"; |
| break; |
| case "array": |
| value += "[]"; |
| break; |
| }; |
| data["object"] = { valueStyle: valueStyle, value: value + " @" + this.snapshotNodeId }; |
| |
| var view = this.dataGrid.snapshotView; |
| data["shallowSize"] = view.showShallowSizeAsPercent ? WebInspector.UIString("%.2f%%", this._shallowSizePercent) : Number.bytesToString(this._shallowSize); |
| data["retainedSize"] = view.showRetainedSizeAsPercent ? WebInspector.UIString("%.2f%%", this._retainedSizePercent) : Number.bytesToString(this._retainedSize); |
| |
| return this._enhanceData ? this._enhanceData(data) : data; |
| }, |
| |
| get _retainedSizePercent() |
| { |
| return this._retainedSize / this.dataGrid.snapshot.totalSize * 100.0; |
| }, |
| |
| get _shallowSizePercent() |
| { |
| return this._shallowSize / this.dataGrid.snapshot.totalSize * 100.0; |
| }, |
| |
| _updateHasChildren: function() |
| { |
| function isEmptyCallback(isEmpty) |
| { |
| this.hasChildren = !isEmpty; |
| } |
| this._provider.isEmpty(isEmptyCallback.bind(this)); |
| } |
| } |
| |
| WebInspector.HeapSnapshotGenericObjectNode.prototype.__proto__ = WebInspector.HeapSnapshotGridNode.prototype; |
| |
| WebInspector.HeapSnapshotObjectNode = function(tree, edge) |
| { |
| WebInspector.HeapSnapshotGenericObjectNode.call(this, tree, edge.node); |
| this._referenceName = edge.name; |
| this._referenceType = edge.type; |
| this._provider = this._createProvider(tree.snapshot, edge.nodeIndex); |
| this._updateHasChildren(); |
| } |
| |
| WebInspector.HeapSnapshotObjectNode.prototype = { |
| _createChildNode: function(item) |
| { |
| return new WebInspector.HeapSnapshotObjectNode(this.dataGrid, item); |
| }, |
| |
| _createProvider: function(snapshot, nodeIndex) |
| { |
| var showHiddenData = WebInspector.DetailedHeapshotView.prototype.showHiddenData; |
| return snapshot.createEdgesProvider( |
| nodeIndex, |
| function(edge) { |
| return !edge.isInvisible |
| && (showHiddenData || (!edge.isHidden && !edge.node.isHidden)); |
| }); |
| }, |
| |
| _childHashForEntity: function(edge) |
| { |
| return edge.type + "#" + edge.name; |
| }, |
| |
| _childHashForNode: function(childNode) |
| { |
| return childNode._referenceType + "#" + childNode._referenceName; |
| }, |
| |
| comparator: function() |
| { |
| var sortAscending = this.dataGrid.sortOrder === "ascending"; |
| var sortColumnIdentifier = this.dataGrid.sortColumnIdentifier; |
| var sortFields = { |
| object: ["!edgeName", sortAscending, "retainedSize", false], |
| count: ["!edgeName", true, "retainedSize", false], |
| shallowSize: ["selfSize", sortAscending, "!edgeName", true], |
| retainedSize: ["retainedSize", sortAscending, "!edgeName", true] |
| }[sortColumnIdentifier] || ["!edgeName", true, "retainedSize", false]; |
| return WebInspector.HeapSnapshotFilteredOrderedIterator.prototype.createComparator(sortFields); |
| }, |
| |
| _emptyData: function() |
| { |
| return {count:"", addedCount: "", removedCount: "", countDelta:"", addedSize: "", removedSize: "", sizeDelta: ""}; |
| }, |
| |
| _enhanceData: function(data) |
| { |
| var name = this._referenceName; |
| if (name === "") name = "(empty)"; |
| var nameClass = "name"; |
| switch (this._referenceType) { |
| case "context": |
| nameClass = "console-formatted-number"; |
| break; |
| case "internal": |
| case "hidden": |
| nameClass = "console-formatted-null"; |
| break; |
| } |
| data["object"].nameClass = nameClass; |
| data["object"].name = name; |
| return data; |
| }, |
| |
| _prefixObjectCell: function(div, data) |
| { |
| var nameSpan = document.createElement("span"); |
| nameSpan.className = data.nameClass; |
| nameSpan.textContent = data.name; |
| var separatorSpan = document.createElement("span"); |
| separatorSpan.className = "separator"; |
| separatorSpan.textContent = ": "; |
| div.appendChild(nameSpan); |
| div.appendChild(separatorSpan); |
| } |
| } |
| |
| WebInspector.HeapSnapshotObjectNode.prototype.__proto__ = WebInspector.HeapSnapshotGenericObjectNode.prototype; |
| |
| WebInspector.HeapSnapshotInstanceNode = function(tree, baseSnapshot, snapshot, node) |
| { |
| WebInspector.HeapSnapshotGenericObjectNode.call(this, tree, node); |
| this._isDeletedNode = !!baseSnapshot; |
| this._provider = this._createProvider(baseSnapshot || snapshot, node.nodeIndex); |
| this._updateHasChildren(); |
| }; |
| |
| WebInspector.HeapSnapshotInstanceNode.prototype = { |
| _createChildNode: function(item) |
| { |
| return new WebInspector.HeapSnapshotObjectNode(this.dataGrid, item); |
| }, |
| |
| _createProvider: function(snapshot, nodeIndex) |
| { |
| var showHiddenData = WebInspector.DetailedHeapshotView.prototype.showHiddenData; |
| return snapshot.createEdgesProvider( |
| nodeIndex, |
| function(edge) { |
| return !edge.isInvisible |
| && (showHiddenData || (!edge.isHidden && !edge.node.isHidden)); |
| }); |
| }, |
| |
| _childHashForEntity: function(edge) |
| { |
| return edge.type + "#" + edge.name; |
| }, |
| |
| _childHashForNode: function(childNode) |
| { |
| return childNode._referenceType + "#" + childNode._referenceName; |
| }, |
| |
| comparator: function() |
| { |
| var sortAscending = this.dataGrid.sortOrder === "ascending"; |
| var sortColumnIdentifier = this.dataGrid.sortColumnIdentifier; |
| var sortFields = { |
| object: ["!edgeName", sortAscending, "retainedSize", false], |
| count: ["!edgeName", true, "retainedSize", false], |
| addedSize: ["selfSize", sortAscending, "!edgeName", true], |
| removedSize: ["selfSize", sortAscending, "!edgeName", true], |
| shallowSize: ["selfSize", sortAscending, "!edgeName", true], |
| retainedSize: ["retainedSize", sortAscending, "!edgeName", true] |
| }[sortColumnIdentifier] || ["!edgeName", true, "retainedSize", false]; |
| return WebInspector.HeapSnapshotFilteredOrderedIterator.prototype.createComparator(sortFields); |
| }, |
| |
| _emptyData: function() |
| { |
| return {count:"", countDelta:"", sizeDelta: ""}; |
| }, |
| |
| _enhanceData: function(data) |
| { |
| if (this._isDeletedNode) { |
| data["addedCount"] = ""; |
| data["addedSize"] = ""; |
| data["removedCount"] = "\u2022"; |
| data["removedSize"] = Number.bytesToString(this._shallowSize); |
| } else { |
| data["addedCount"] = "\u2022"; |
| data["addedSize"] = Number.bytesToString(this._shallowSize); |
| data["removedCount"] = ""; |
| data["removedSize"] = ""; |
| } |
| return data; |
| } |
| } |
| |
| WebInspector.HeapSnapshotInstanceNode.prototype.__proto__ = WebInspector.HeapSnapshotGenericObjectNode.prototype; |
| |
| WebInspector.HeapSnapshotConstructorNode = function(tree, className, aggregate) |
| { |
| WebInspector.HeapSnapshotGridNode.call(this, tree, aggregate.count > 0); |
| this._name = className; |
| this._count = aggregate.count; |
| this._shallowSize = aggregate.self; |
| this._retainedSize = aggregate.maxRet; |
| this._provider = this._createNodesProvider(tree.snapshot, aggregate.type, className); |
| } |
| |
| WebInspector.HeapSnapshotConstructorNode.prototype = { |
| _createChildNode: function(item) |
| { |
| return new WebInspector.HeapSnapshotInstanceNode(this.dataGrid, null, this.dataGrid.snapshot, item); |
| }, |
| |
| _createNodesProvider: function(snapshot, nodeType, nodeClassName) |
| { |
| return snapshot.createNodesProvider( |
| function (node) { |
| return node.type === nodeType |
| && (nodeClassName === null || node.className === nodeClassName); |
| }); |
| }, |
| |
| comparator: function() |
| { |
| var sortAscending = this.dataGrid.sortOrder === "ascending"; |
| var sortColumnIdentifier = this.dataGrid.sortColumnIdentifier; |
| var sortFields = { |
| object: ["id", sortAscending, "retainedSize", false], |
| count: ["id", true, "retainedSize", false], |
| shallowSize: ["selfSize", sortAscending, "id", true], |
| retainedSize: ["retainedSize", sortAscending, "id", true] |
| }[sortColumnIdentifier]; |
| return WebInspector.HeapSnapshotFilteredOrderedIterator.prototype.createComparator(sortFields); |
| }, |
| |
| _childHashForEntity: function(node) |
| { |
| return node.id; |
| }, |
| |
| _childHashForNode: function(childNode) |
| { |
| return childNode.snapshotNodeId; |
| }, |
| |
| get data() |
| { |
| var data = {object: this._name, count: this._count}; |
| var view = this.dataGrid.snapshotView; |
| data["count"] = view.showCountAsPercent ? WebInspector.UIString("%.2f%%", this._countPercent) : this._count; |
| data["shallowSize"] = view.showShallowSizeAsPercent ? WebInspector.UIString("%.2f%%", this._shallowSizePercent) : Number.bytesToString(this._shallowSize); |
| data["retainedSize"] = "> " + (view.showRetainedSizeAsPercent ? WebInspector.UIString("%.2f%%", this._retainedSizePercent) : Number.bytesToString(this._retainedSize)); |
| return data; |
| }, |
| |
| get _countPercent() |
| { |
| return this._count / this.dataGrid.snapshot.nodeCount * 100.0; |
| }, |
| |
| get _retainedSizePercent() |
| { |
| return this._retainedSize / this.dataGrid.snapshot.totalSize * 100.0; |
| }, |
| |
| get _shallowSizePercent() |
| { |
| return this._shallowSize / this.dataGrid.snapshot.totalSize * 100.0; |
| } |
| }; |
| |
| WebInspector.HeapSnapshotConstructorNode.prototype.__proto__ = WebInspector.HeapSnapshotGridNode.prototype; |
| |
| WebInspector.HeapSnapshotIteratorsTuple = function(it1, it2) |
| { |
| this._it1 = it1; |
| this._it2 = it2; |
| } |
| |
| WebInspector.HeapSnapshotIteratorsTuple.prototype = { |
| sortAndRewind: function(comparator, callback) |
| { |
| function afterSort(ignored) |
| { |
| this._it2.sortAndRewind(comparator, callback); |
| } |
| this._it1.sortAndRewind(comparator, afterSort.bind(this)); |
| } |
| }; |
| |
| WebInspector.HeapSnapshotDiffNode = function(tree, className, baseAggregate, aggregate) |
| { |
| WebInspector.HeapSnapshotGridNode.call(this, tree, true); |
| this._name = className; |
| this._baseIndexes = baseAggregate ? baseAggregate.idxs : []; |
| this._indexes = aggregate ? aggregate.idxs : []; |
| this._provider = this._createNodesProvider(tree.baseSnapshot, tree.snapshot, aggregate ? aggregate.type : baseAggregate.type, className); |
| } |
| |
| WebInspector.HeapSnapshotDiffNode.prototype = { |
| calculateDiff: function(dataGrid, callback) |
| { |
| var diff = dataGrid.snapshot.createDiff(this._name); |
| |
| function diffCalculated(diffResult) |
| { |
| this._diff = diffResult; |
| this._baseIndexes = null; |
| this._indexes = null; |
| callback(this._diff.addedSize === 0 && this._diff.removedSize === 0); |
| } |
| function baseSelfSizesReceived(baseSelfSizes) |
| { |
| diff.pushBaseSelfSizes(baseSelfSizes); |
| diff.calculate(diffCalculated.bind(this)); |
| } |
| function baseIdsReceived(baseIds) |
| { |
| diff.pushBaseIds(dataGrid.baseSnapshot.uid, baseIds); |
| dataGrid.snapshot.pushBaseIds(dataGrid.baseSnapshot.uid, this._name, baseIds); |
| dataGrid.baseSnapshot.nodeFieldValuesByIndex("selfSize", this._baseIndexes, baseSelfSizesReceived.bind(this)); |
| } |
| function idsReceived(ids) |
| { |
| dataGrid.baseSnapshot.pushBaseIds(dataGrid.snapshot.uid, this._name, ids); |
| } |
| dataGrid.baseSnapshot.nodeFieldValuesByIndex("id", this._baseIndexes, baseIdsReceived.bind(this)); |
| dataGrid.snapshot.nodeFieldValuesByIndex("id", this._indexes, idsReceived.bind(this)); |
| }, |
| |
| _createChildNode: function(item, provider) |
| { |
| if (provider === this._provider._it1) |
| return new WebInspector.HeapSnapshotInstanceNode(this.dataGrid, null, provider.snapshot, item); |
| else |
| return new WebInspector.HeapSnapshotInstanceNode(this.dataGrid, provider.snapshot, null, item); |
| }, |
| |
| _createNodesProvider: function(baseSnapshot, snapshot, nodeType, nodeClassName) |
| { |
| var className = this._name; |
| return new WebInspector.HeapSnapshotIteratorsTuple( |
| createProvider(snapshot, baseSnapshot), createProvider(baseSnapshot, snapshot)); |
| |
| function createProvider(snapshot, otherSnapshot) |
| { |
| var otherSnapshotId = otherSnapshot.uid; |
| var provider = snapshot.createNodesProvider( |
| function (node) { |
| return node.type === nodeType |
| && (nodeClassName === null || node.className === nodeClassName) |
| && !this.baseSnapshotHasNode(otherSnapshotId, className, node.id); |
| }); |
| provider.snapshot = snapshot; |
| return provider; |
| } |
| }, |
| |
| _childHashForEntity: function(node) |
| { |
| return node.id; |
| }, |
| |
| _childHashForNode: function(childNode) |
| { |
| return childNode.snapshotNodeId; |
| }, |
| |
| comparator: function() |
| { |
| var sortAscending = this.dataGrid.sortOrder === "ascending"; |
| var sortColumnIdentifier = this.dataGrid.sortColumnIdentifier; |
| var sortFields = { |
| object: ["id", sortAscending, "selfSize", false], |
| addedCount: ["selfSize", sortAscending, "id", true], |
| removedCount: ["selfSize", sortAscending, "id", true], |
| countDelta: ["selfSize", sortAscending, "id", true], |
| addedSize: ["selfSize", sortAscending, "id", true], |
| removedSize: ["selfSize", sortAscending, "id", true], |
| sizeDelta: ["selfSize", sortAscending, "id", true] |
| }[sortColumnIdentifier]; |
| return WebInspector.HeapSnapshotFilteredOrderedIterator.prototype.createComparator(sortFields); |
| }, |
| |
| populateChildren: function(provider, howMany, atIndex, afterPopulate) |
| { |
| if (!provider && !howMany) { |
| var firstProviderPopulated = function() |
| { |
| WebInspector.HeapSnapshotGridNode.prototype.populateChildren.call(this, this._provider._it2, this._defaultPopulateCount, atIndex, afterPopulate); |
| }; |
| WebInspector.HeapSnapshotGridNode.prototype.populateChildren.call(this, this._provider._it1, this._defaultPopulateCount, atIndex, firstProviderPopulated.bind(this), true); |
| } else if (!howMany) { |
| var firstProviderPopulated = function() |
| { |
| WebInspector.HeapSnapshotGridNode.prototype.populateChildren.call(this, this._provider._it2, null, atIndex, afterPopulate); |
| }; |
| WebInspector.HeapSnapshotGridNode.prototype.populateChildren.call(this, this._provider._it1, null, atIndex, firstProviderPopulated.bind(this), true); |
| } else |
| WebInspector.HeapSnapshotGridNode.prototype.populateChildren.call(this, provider, howMany, atIndex, afterPopulate); |
| }, |
| |
| _signForDelta: function(delta) |
| { |
| if (delta === 0) |
| return ""; |
| if (delta > 0) |
| return "+"; |
| else |
| return "\u2212"; // Math minus sign, same width as plus. |
| }, |
| |
| get data() |
| { |
| var data = {object: this._name}; |
| |
| data["addedCount"] = this._diff.addedCount; |
| data["removedCount"] = this._diff.removedCount; |
| var countDelta = this._diff.countDelta; |
| data["countDelta"] = WebInspector.UIString("%s%d", this._signForDelta(countDelta), Math.abs(countDelta)); |
| data["addedSize"] = Number.bytesToString(this._diff.addedSize); |
| data["removedSize"] = Number.bytesToString(this._diff.removedSize); |
| var sizeDelta = this._diff.sizeDelta; |
| data["sizeDelta"] = WebInspector.UIString("%s%s", this._signForDelta(sizeDelta), Number.bytesToString(Math.abs(sizeDelta))); |
| |
| return data; |
| } |
| }; |
| |
| WebInspector.HeapSnapshotDiffNode.prototype.__proto__ = WebInspector.HeapSnapshotGridNode.prototype; |
| |
| WebInspector.HeapSnapshotDominatorObjectNode = function(tree, node) |
| { |
| WebInspector.HeapSnapshotGenericObjectNode.call(this, tree, node); |
| this._provider = this._createProvider(tree.snapshot, node.nodeIndex); |
| this._updateHasChildren(); |
| }; |
| |
| WebInspector.HeapSnapshotDominatorObjectNode.prototype = { |
| _createChildNode: function(item) |
| { |
| return new WebInspector.HeapSnapshotDominatorObjectNode(this.dataGrid, item); |
| }, |
| |
| _createProvider: function(snapshot, nodeIndex) |
| { |
| var showHiddenData = WebInspector.DetailedHeapshotView.prototype.showHiddenData; |
| return snapshot.createNodesProvider( |
| function (node) { |
| var dominatorIndex = node.dominatorIndex; |
| return dominatorIndex === nodeIndex |
| && dominatorIndex !== node.nodeIndex |
| && (showHiddenData || !node.isHidden); |
| }); |
| }, |
| |
| _childHashForEntity: function(node) |
| { |
| return node.id; |
| }, |
| |
| _childHashForNode: function(childNode) |
| { |
| return childNode.snapshotNodeId; |
| }, |
| |
| comparator: function() |
| { |
| var sortAscending = this.dataGrid.sortOrder === "ascending"; |
| var sortColumnIdentifier = this.dataGrid.sortColumnIdentifier; |
| var sortFields = { |
| object: ["id", sortAscending, "retainedSize", false], |
| shallowSize: ["selfSize", sortAscending, "id", true], |
| retainedSize: ["retainedSize", sortAscending, "id", true] |
| }[sortColumnIdentifier]; |
| return WebInspector.HeapSnapshotFilteredOrderedIterator.prototype.createComparator(sortFields); |
| }, |
| |
| _emptyData: function() |
| { |
| return {}; |
| } |
| }; |
| |
| WebInspector.HeapSnapshotDominatorObjectNode.prototype.__proto__ = WebInspector.HeapSnapshotGenericObjectNode.prototype; |
| |
| function MixInSnapshotNodeFunctions(sourcePrototype, targetPrototype) |
| { |
| targetPrototype._childHashForEntity = sourcePrototype._childHashForEntity; |
| targetPrototype._childHashForNode = sourcePrototype._childHashForNode; |
| targetPrototype.comparator = sourcePrototype.comparator; |
| targetPrototype._createChildNode = sourcePrototype._createChildNode; |
| targetPrototype._createProvider = sourcePrototype._createProvider; |
| targetPrototype.populateChildren = sourcePrototype.populateChildren; |
| targetPrototype._saveChildren = sourcePrototype._saveChildren; |
| targetPrototype.sort = sourcePrototype.sort; |
| } |