Commit c57909ef authored by alph@chromium.org's avatar alph@chromium.org

DevTools: Implement recursive viewport for the Heap Summary view

BUG=255363

Review URL: https://codereview.chromium.org/187823003

git-svn-id: svn://svn.chromium.org/blink/trunk@168584 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 2408dde5
...@@ -689,6 +689,8 @@ InspectorTest.switchToView = function(title, callback) ...@@ -689,6 +689,8 @@ InspectorTest.switchToView = function(title, callback)
callback = InspectorTest.safeWrap(callback); callback = InspectorTest.safeWrap(callback);
var view = WebInspector.panels.profiles.visibleView; var view = WebInspector.panels.profiles.visibleView;
view.changeView(title, callback); view.changeView(title, callback);
// Increase the grid container height so the viewport don't limit the number of nodes.
InspectorTest._currentGrid().scrollContainer.style.height = "10000px";
}; };
InspectorTest.takeAndOpenSnapshot = function(generator, callback) InspectorTest.takeAndOpenSnapshot = function(generator, callback)
......
...@@ -1168,8 +1168,6 @@ WebInspector.DataGridNode = function(data, hasChildren) ...@@ -1168,8 +1168,6 @@ WebInspector.DataGridNode = function(data, hasChildren)
this.disclosureToggleWidth = 10; this.disclosureToggleWidth = 10;
} }
WebInspector.DataGridNode.NodeShallowHeight = 16;
WebInspector.DataGridNode.prototype = { WebInspector.DataGridNode.prototype = {
/** @type {boolean} */ /** @type {boolean} */
selectable: true, selectable: true,
...@@ -1394,17 +1392,9 @@ WebInspector.DataGridNode.prototype = { ...@@ -1394,17 +1392,9 @@ WebInspector.DataGridNode.prototype = {
/** /**
* @return {number} * @return {number}
*/ */
nodeHeight: function() nodeSelfHeight: function()
{ {
var rowHeight = WebInspector.DataGridNode.NodeShallowHeight; return 16;
if (!this.revealed)
return 0;
if (!this.expanded)
return rowHeight;
var result = rowHeight;
for (var i = 0; i < this.children.length; i++)
result += this.children[i].nodeHeight();
return result;
}, },
/** /**
......
...@@ -231,7 +231,6 @@ WebInspector.HeapSnapshotSortableDataGrid.prototype = { ...@@ -231,7 +231,6 @@ WebInspector.HeapSnapshotSortableDataGrid.prototype = {
if (child.expanded) if (child.expanded)
child.sort(); child.sort();
} }
this.updateVisibleNodes();
this.recursiveSortingLeave(); this.recursiveSortingLeave();
}, },
...@@ -251,8 +250,10 @@ WebInspector.HeapSnapshotSortableDataGrid.prototype = { ...@@ -251,8 +250,10 @@ WebInspector.HeapSnapshotSortableDataGrid.prototype = {
{ {
if (!this._recursiveSortingDepth) if (!this._recursiveSortingDepth)
return; return;
if (!--this._recursiveSortingDepth) if (--this._recursiveSortingDepth)
this.dispatchEventToListeners("sorting complete"); return;
this.updateVisibleNodes();
this.dispatchEventToListeners("sorting complete");
}, },
updateVisibleNodes: function() updateVisibleNodes: function()
...@@ -331,68 +332,95 @@ WebInspector.HeapSnapshotViewportDataGrid.prototype = { ...@@ -331,68 +332,95 @@ WebInspector.HeapSnapshotViewportDataGrid.prototype = {
// Do nothing here, it will be added in updateVisibleNodes. // Do nothing here, it will be added in updateVisibleNodes.
}, },
updateVisibleNodes: function() /**
* @param {number=} scrollTop
*/
updateVisibleNodes: function(scrollTop)
{ {
var scrollTop = this.scrollContainer.scrollTop; if (scrollTop === undefined)
var children = this.topLevelNodes(); scrollTop = this.scrollContainer.scrollTop;
var viewPortHeight = this.scrollContainer.offsetHeight;
var selectedNode = this.selectedNode;
this.rootNode().removeChildren();
var topPadding = 0; this._topPaddingHeight = 0;
for (var i = 0; i < children.length; ++i) { this._bottomPaddingHeight = 0;
if (children[i].revealed) {
var newTop = topPadding + children[i].nodeHeight(); this._addVisibleNodes(this.rootNode(), scrollTop, scrollTop + viewPortHeight);
if (newTop > scrollTop)
break; this._topPadding.setHeight(this._topPaddingHeight);
topPadding = newTop; 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 {!WebInspector.DataGridNode} parentNode
* @param {number} firstVisibleNodeIndex * @param {number} topBound
* @param {number} firstNodeHiddenHeight * @param {number} bottomBound
* @param {number} topPadding * @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 children = this.allChildren(parentNode);
var selectedNode = this.selectedNode; var topPadding = 0;
// Iterate over invisible nodes beyond the upper bound of viewport.
parentNode.removeChildren(); // 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. // Put visible nodes into the data grid.
var heightToFill = viewPortHeight + firstNodeHiddenHeight; var position = topPadding;
var filledHeight = 0; for (; i < children.length && position < bottomBound; ++i) {
var i = firstVisibleNodeIndex; var child = children[i];
while (i < children.length && filledHeight < heightToFill) { var hasChildren = child.hasChildren;
if (children[i].revealed) { child.removeChildren();
parentNode.appendChild(children[i]); child.hasChildren = hasChildren;
filledHeight += children[i].nodeHeight(); child.revealed = true;
} parentNode.appendChild(child);
++i; 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; var bottomPadding = 0;
while (i < children.length) { for (; i < children.length; ++i)
bottomPadding += children[i].nodeHeight(); bottomPadding += this._nodeHeight(children[i]);
++i;
}
this._topPadding.setHeight(topPadding); this._topPaddingHeight += topPadding;
this._bottomPadding.setHeight(bottomPadding); this._bottomPaddingHeight += bottomPadding;
return position + bottomPadding;
},
if (selectedNode) { /**
if (selectedNode.parent) { * @param {!WebInspector.HeapSnapshotGridNode} node
selectedNode.select(true); * @return {number}
} else { */
// Keep selection even if the node is not in the current viewport. _nodeHeight: function(node)
this.selectedNode = selectedNode; {
} 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 = { ...@@ -404,26 +432,27 @@ WebInspector.HeapSnapshotViewportDataGrid.prototype = {
return this._bottomPadding.element; return this._bottomPadding.element;
}, },
/**
* @param {!WebInspector.HeapSnapshotGridNode} nodeToReveal
*/
_revealTopLevelNode: function(nodeToReveal) _revealTopLevelNode: function(nodeToReveal)
{ {
var children = this.allChildren(this.rootNode()); var children = this.allChildren(this.rootNode());
var topPadding = 0; var topPadding = 0;
for (var i = 0; i < children.length; ++i) { for (var i = 0; i < children.length; ++i) {
if (children[i] === nodeToReveal) if (children[i] === nodeToReveal)
break; break;
if (children[i].revealed) { if (children[i].revealed) {
var newTop = topPadding + children[i].nodeHeight(); var newTop = topPadding + this._nodeHeight(children[i]);
topPadding = newTop; topPadding = newTop;
} }
} }
this.updateVisibleNodes(topPadding);
this._addVisibleNodes(this.rootNode(), i, 0, topPadding);
}, },
/** /**
* @param {!WebInspector.DataGridNode} parent * @param {!WebInspector.DataGridNode} parent
* @return {!Array.<!WebInspector.DataGridNode>} * @return {!Array.<!WebInspector.HeapSnapshotGridNode>}
*/ */
allChildren: function(parent) allChildren: function(parent)
{ {
......
...@@ -101,6 +101,15 @@ WebInspector.HeapSnapshotGridNode.prototype = { ...@@ -101,6 +101,15 @@ WebInspector.HeapSnapshotGridNode.prototype = {
this._dataGrid.updateVisibleNodes(); this._dataGrid.updateVisibleNodes();
}, },
/**
* @override
*/
expand: function()
{
WebInspector.DataGridNode.prototype.expand.call(this);
this._dataGrid.updateVisibleNodes();
},
/** /**
* @override * @override
*/ */
...@@ -137,7 +146,7 @@ WebInspector.HeapSnapshotGridNode.prototype = { ...@@ -137,7 +146,7 @@ WebInspector.HeapSnapshotGridNode.prototype = {
*/ */
allChildren: function() allChildren: function()
{ {
return this.children; return this._dataGrid.allChildren(this);
}, },
/** /**
...@@ -145,7 +154,7 @@ WebInspector.HeapSnapshotGridNode.prototype = { ...@@ -145,7 +154,7 @@ WebInspector.HeapSnapshotGridNode.prototype = {
*/ */
removeChildByIndex: function(index) removeChildByIndex: function(index)
{ {
this.removeChild(this.children[index]); this._dataGrid.removeChildByIndex(this, index);
}, },
/** /**
...@@ -247,11 +256,11 @@ WebInspector.HeapSnapshotGridNode.prototype = { ...@@ -247,11 +256,11 @@ WebInspector.HeapSnapshotGridNode.prototype = {
if (this._savedChildren) { if (this._savedChildren) {
var hash = this._childHashForEntity(item); var hash = this._childHashForEntity(item);
if (hash in this._savedChildren) { if (hash in this._savedChildren) {
this.insertChild(this._savedChildren[hash], insertionIndex); this._dataGrid.insertChild(this, this._savedChildren[hash], insertionIndex);
return; return;
} }
} }
this.insertChild(this._createChildNode(item), insertionIndex); this._dataGrid.insertChild(this, this._createChildNode(item), insertionIndex);
} }
/** /**
...@@ -260,7 +269,7 @@ WebInspector.HeapSnapshotGridNode.prototype = { ...@@ -260,7 +269,7 @@ WebInspector.HeapSnapshotGridNode.prototype = {
function insertShowMoreButton(from, to, insertionIndex) function insertShowMoreButton(from, to, insertionIndex)
{ {
var button = new WebInspector.ShowMoreDataGridNode(this._populateChildren.bind(this), from, to, this._dataGrid.defaultPopulateCount()); var button = new WebInspector.ShowMoreDataGridNode(this._populateChildren.bind(this), from, to, this._dataGrid.defaultPopulateCount());
this.insertChild(button, insertionIndex); this._dataGrid.insertChild(this, button, insertionIndex);
} }
/** /**
...@@ -356,6 +365,7 @@ WebInspector.HeapSnapshotGridNode.prototype = { ...@@ -356,6 +365,7 @@ WebInspector.HeapSnapshotGridNode.prototype = {
return; return;
} }
this._dataGrid.updateVisibleNodes();
if (afterPopulate) if (afterPopulate)
afterPopulate(); afterPopulate();
this.dispatchEventToListeners(WebInspector.HeapSnapshotGridNode.Events.PopulateComplete); this.dispatchEventToListeners(WebInspector.HeapSnapshotGridNode.Events.PopulateComplete);
...@@ -387,7 +397,7 @@ WebInspector.HeapSnapshotGridNode.prototype = { ...@@ -387,7 +397,7 @@ WebInspector.HeapSnapshotGridNode.prototype = {
function afterSort() function afterSort()
{ {
this._saveChildren(); this._saveChildren();
this.removeChildren(); this._dataGrid.removeAllChildren(this);
this._retrievedChildrenRanges = []; this._retrievedChildrenRanges = [];
/** /**
......
...@@ -133,7 +133,7 @@ WebInspector.ShowMoreDataGridNode.prototype = { ...@@ -133,7 +133,7 @@ WebInspector.ShowMoreDataGridNode.prototype = {
* @override * @override
* @return {number} * @return {number}
*/ */
nodeHeight: function() nodeSelfHeight: function()
{ {
return 32; return 32;
}, },
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment