Index: third_party/WebKit/Source/devtools/front_end/ui/ViewportControl.js |
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/ViewportControl.js b/third_party/WebKit/Source/devtools/front_end/ui/ViewportControl.js |
index 4774a14ae7dce4b0afb8b21e4199ece8f6738f12..854b451ca45ae73fcc4e17c1980623e784b362f8 100644 |
--- a/third_party/WebKit/Source/devtools/front_end/ui/ViewportControl.js |
+++ b/third_party/WebKit/Source/devtools/front_end/ui/ViewportControl.js |
@@ -59,9 +59,11 @@ WebInspector.ViewportControl = function(provider) |
this._renderedItems = []; |
this._anchorSelection = null; |
this._headSelection = null; |
- this._stickToBottom = false; |
- this._scrolledToBottom = true; |
this._itemCount = 0; |
+ this._observer = new MutationObserver(this.refresh.bind(this)); |
+ this._observerConfig = { childList: true, subtree: true }; |
+ |
+ this.setStickToBottom(true); |
} |
/** |
@@ -145,9 +147,9 @@ WebInspector.ViewportControl.prototype = { |
/** |
* @return {boolean} |
*/ |
- scrolledToBottom: function() |
+ stickToBottom: function() |
{ |
- return this._scrolledToBottom; |
+ return this._stickToBottom; |
}, |
/** |
@@ -156,6 +158,10 @@ WebInspector.ViewportControl.prototype = { |
setStickToBottom: function(value) |
{ |
this._stickToBottom = value; |
+ if (this._stickToBottom) |
+ this._observer.observe(this._contentElement, this._observerConfig); |
+ else |
+ this._observer.disconnect(); |
}, |
/** |
@@ -376,6 +382,14 @@ WebInspector.ViewportControl.prototype = { |
refresh: function() |
{ |
+ this._observer.disconnect(); |
+ this._innerRefresh(); |
+ if (this._stickToBottom) |
+ this._observer.observe(this._contentElement, this._observerConfig); |
+ }, |
+ |
+ _innerRefresh: function() |
+ { |
if (!this._visibleHeight()) |
return; // Do nothing for invisible controls. |
@@ -396,7 +410,6 @@ WebInspector.ViewportControl.prototype = { |
var visibleFrom = this.element.scrollTop; |
var visibleHeight = this._visibleHeight(); |
- this._scrolledToBottom = this.element.isScrolledToBottom(); |
var isInvalidating = !this._cumulativeHeights; |
for (var i = 0; i < this._renderedItems.length; ++i) { |
@@ -408,17 +421,11 @@ WebInspector.ViewportControl.prototype = { |
var oldFirstVisibleIndex = this._firstVisibleIndex; |
var oldLastVisibleIndex = this._lastVisibleIndex; |
- var shouldStickToBottom = this._stickToBottom && this._scrolledToBottom; |
+ this._firstVisibleIndex = Math.max(Array.prototype.lowerBound.call(this._cumulativeHeights, visibleFrom + 1), 0); |
+ // Proactively render more rows in case some of them will be collapsed without triggering refresh. @see crbug.com/390169 |
+ this._lastVisibleIndex = this._firstVisibleIndex + Math.ceil(visibleHeight / this._provider.minimumRowHeight()) - 1; |
+ this._lastVisibleIndex = Math.min(this._lastVisibleIndex, this._itemCount - 1); |
- if (shouldStickToBottom) { |
- this._lastVisibleIndex = this._itemCount - 1; |
- this._firstVisibleIndex = Math.max(this._itemCount - Math.ceil(visibleHeight / this._provider.minimumRowHeight()), 0); |
- } else { |
- this._firstVisibleIndex = Math.max(Array.prototype.lowerBound.call(this._cumulativeHeights, visibleFrom + 1), 0); |
- // Proactively render more rows in case some of them will be collapsed without triggering refresh. @see crbug.com/390169 |
- this._lastVisibleIndex = this._firstVisibleIndex + Math.ceil(visibleHeight / this._provider.minimumRowHeight()) - 1; |
- this._lastVisibleIndex = Math.min(this._lastVisibleIndex, this._itemCount - 1); |
- } |
var topGapHeight = this._cumulativeHeights[this._firstVisibleIndex - 1] || 0; |
var bottomGapHeight = this._cumulativeHeights[this._cumulativeHeights.length - 1] - this._cumulativeHeights[this._lastVisibleIndex]; |
@@ -442,7 +449,7 @@ WebInspector.ViewportControl.prototype = { |
// Should be the last call in the method as it might force layout. |
if (shouldRestoreSelection) |
this._restoreSelection(selection); |
- if (shouldStickToBottom) |
+ if (this._stickToBottom) |
this.element.scrollTop = 10000000; |
}, |
@@ -612,8 +619,11 @@ WebInspector.ViewportControl.prototype = { |
*/ |
forceScrollItemToBeFirst: function(index) |
{ |
+ this.setStickToBottom(false); |
this._rebuildCumulativeHeightsIfNeeded(); |
this.element.scrollTop = index > 0 ? this._cumulativeHeights[index - 1] : 0; |
+ if (this.element.isScrolledToBottom()) |
+ this.setStickToBottom(true); |
this.refresh(); |
}, |
@@ -622,8 +632,11 @@ WebInspector.ViewportControl.prototype = { |
*/ |
forceScrollItemToBeLast: function(index) |
{ |
+ this.setStickToBottom(false); |
this._rebuildCumulativeHeightsIfNeeded(); |
this.element.scrollTop = this._cumulativeHeights[index] - this._visibleHeight(); |
+ if (this.element.isScrolledToBottom()) |
+ this.setStickToBottom(true); |
this.refresh(); |
}, |