| Index: Source/devtools/front_end/HeapSnapshotDataGrids.js
|
| diff --git a/Source/devtools/front_end/HeapSnapshotDataGrids.js b/Source/devtools/front_end/HeapSnapshotDataGrids.js
|
| index 9c0c39dd3b83a7004c59c2c485668f2647837fe6..8f16d24e02466f330530f967ef61e8351484c20e 100644
|
| --- a/Source/devtools/front_end/HeapSnapshotDataGrids.js
|
| +++ b/Source/devtools/front_end/HeapSnapshotDataGrids.js
|
| @@ -231,7 +231,6 @@ WebInspector.HeapSnapshotSortableDataGrid.prototype = {
|
| if (child.expanded)
|
| child.sort();
|
| }
|
| - this.updateVisibleNodes();
|
| this.recursiveSortingLeave();
|
| },
|
|
|
| @@ -251,8 +250,10 @@ WebInspector.HeapSnapshotSortableDataGrid.prototype = {
|
| {
|
| if (!this._recursiveSortingDepth)
|
| return;
|
| - if (!--this._recursiveSortingDepth)
|
| - this.dispatchEventToListeners("sorting complete");
|
| + if (--this._recursiveSortingDepth)
|
| + return;
|
| + this.updateVisibleNodes();
|
| + this.dispatchEventToListeners("sorting complete");
|
| },
|
|
|
| updateVisibleNodes: function()
|
| @@ -331,68 +332,95 @@ WebInspector.HeapSnapshotViewportDataGrid.prototype = {
|
| // Do nothing here, it will be added in updateVisibleNodes.
|
| },
|
|
|
| - updateVisibleNodes: function()
|
| + /**
|
| + * @param {number=} scrollTop
|
| + */
|
| + updateVisibleNodes: function(scrollTop)
|
| {
|
| - var scrollTop = this.scrollContainer.scrollTop;
|
| - var children = this.topLevelNodes();
|
| + if (scrollTop === undefined)
|
| + scrollTop = this.scrollContainer.scrollTop;
|
| + var viewPortHeight = this.scrollContainer.offsetHeight;
|
| + var selectedNode = this.selectedNode;
|
| + this.rootNode().removeChildren();
|
|
|
| - var topPadding = 0;
|
| - for (var i = 0; i < children.length; ++i) {
|
| - if (children[i].revealed) {
|
| - var newTop = topPadding + children[i].nodeHeight();
|
| - if (newTop > scrollTop)
|
| - break;
|
| - topPadding = newTop;
|
| + this._topPaddingHeight = 0;
|
| + this._bottomPaddingHeight = 0;
|
| +
|
| + this._addVisibleNodes(this.rootNode(), scrollTop, scrollTop + viewPortHeight);
|
| +
|
| + this._topPadding.setHeight(this._topPaddingHeight);
|
| + this._bottomPadding.setHeight(this._bottomPaddingHeight);
|
| +
|
| + if (selectedNode) {
|
| + if (selectedNode.parent) {
|
| + selectedNode.select(true);
|
| + } else {
|
| + // Keep selection even if the node is not in the current viewport.
|
| + this.selectedNode = selectedNode;
|
| }
|
| }
|
| -
|
| - this._addVisibleNodes(this.rootNode(), i, scrollTop - topPadding, topPadding);
|
| },
|
|
|
| /**
|
| * @param {!WebInspector.DataGridNode} parentNode
|
| - * @param {number} firstVisibleNodeIndex
|
| - * @param {number} firstNodeHiddenHeight
|
| - * @param {number} topPadding
|
| + * @param {number} topBound
|
| + * @param {number} bottomBound
|
| + * @return {number}
|
| */
|
| - _addVisibleNodes: function(parentNode, firstVisibleNodeIndex, firstNodeHiddenHeight, topPadding)
|
| + _addVisibleNodes: function(parentNode, topBound, bottomBound)
|
| {
|
| - var viewPortHeight = this.scrollContainer.offsetHeight;
|
| + if (!parentNode.expanded)
|
| + return 0;
|
|
|
| var children = this.allChildren(parentNode);
|
| - var selectedNode = this.selectedNode;
|
| -
|
| - parentNode.removeChildren();
|
| + var topPadding = 0;
|
| + // Iterate over invisible nodes beyond the upper bound of viewport.
|
| + // Do not insert them into the grid, but count their total height.
|
| + for (var i = 0; i < children.length; ++i) {
|
| + var newTop = topPadding + this._nodeHeight(children[i]);
|
| + if (newTop > topBound)
|
| + break;
|
| + topPadding = newTop;
|
| + }
|
|
|
| - // The height of the view port + invisible top part.
|
| - var heightToFill = viewPortHeight + firstNodeHiddenHeight;
|
| - var filledHeight = 0;
|
| - var i = firstVisibleNodeIndex;
|
| - while (i < children.length && filledHeight < heightToFill) {
|
| - if (children[i].revealed) {
|
| - parentNode.appendChild(children[i]);
|
| - filledHeight += children[i].nodeHeight();
|
| - }
|
| - ++i;
|
| + // Put visible nodes into the data grid.
|
| + var position = topPadding;
|
| + for (; i < children.length && position < bottomBound; ++i) {
|
| + var child = children[i];
|
| + var hasChildren = child.hasChildren;
|
| + child.removeChildren();
|
| + child.hasChildren = hasChildren;
|
| + child.revealed = true;
|
| + parentNode.appendChild(child);
|
| + position += child.nodeSelfHeight();
|
| + position += this._addVisibleNodes(child, topBound - position, bottomBound - position);
|
| }
|
|
|
| + // Count the invisible nodes beyond the bottom bound of the viewport.
|
| var bottomPadding = 0;
|
| - while (i < children.length) {
|
| - bottomPadding += children[i].nodeHeight();
|
| - ++i;
|
| - }
|
| + for (; i < children.length; ++i)
|
| + bottomPadding += this._nodeHeight(children[i]);
|
|
|
| - this._topPadding.setHeight(topPadding);
|
| - this._bottomPadding.setHeight(bottomPadding);
|
| + this._topPaddingHeight += topPadding;
|
| + this._bottomPaddingHeight += bottomPadding;
|
| + return position + bottomPadding;
|
| + },
|
|
|
| - if (selectedNode) {
|
| - if (selectedNode.parent) {
|
| - selectedNode.select(true);
|
| - } else {
|
| - // Keep selection even if the node is not in the current viewport.
|
| - this.selectedNode = selectedNode;
|
| - }
|
| - }
|
| + /**
|
| + * @param {!WebInspector.HeapSnapshotGridNode} node
|
| + * @return {number}
|
| + */
|
| + _nodeHeight: function(node)
|
| + {
|
| + if (!node.revealed)
|
| + return 0;
|
| + var result = node.nodeSelfHeight();
|
| + if (!node.expanded)
|
| + return result;
|
| + var children = this.allChildren(node);
|
| + for (var i = 0; i < children.length; i++)
|
| + result += this._nodeHeight(children[i]);
|
| + return result;
|
| },
|
|
|
| /**
|
| @@ -404,26 +432,27 @@ WebInspector.HeapSnapshotViewportDataGrid.prototype = {
|
| return this._bottomPadding.element;
|
| },
|
|
|
| + /**
|
| + * @param {!WebInspector.HeapSnapshotGridNode} nodeToReveal
|
| + */
|
| _revealTopLevelNode: function(nodeToReveal)
|
| {
|
| var children = this.allChildren(this.rootNode());
|
| -
|
| var topPadding = 0;
|
| for (var i = 0; i < children.length; ++i) {
|
| if (children[i] === nodeToReveal)
|
| break;
|
| if (children[i].revealed) {
|
| - var newTop = topPadding + children[i].nodeHeight();
|
| + var newTop = topPadding + this._nodeHeight(children[i]);
|
| topPadding = newTop;
|
| }
|
| }
|
| -
|
| - this._addVisibleNodes(this.rootNode(), i, 0, topPadding);
|
| + this.updateVisibleNodes(topPadding);
|
| },
|
|
|
| /**
|
| * @param {!WebInspector.DataGridNode} parent
|
| - * @return {!Array.<!WebInspector.DataGridNode>}
|
| + * @return {!Array.<!WebInspector.HeapSnapshotGridNode>}
|
| */
|
| allChildren: function(parent)
|
| {
|
|
|