ViewportControl.js [plain text]
WebInspector.ViewportControl = function(provider)
{
this.element = document.createElement("div");
this.element.className = "fill";
this.element.style.overflow = "auto";
this._topGapElement = this.element.createChild("div");
this._contentElement = this.element.createChild("div");
this._bottomGapElement = this.element.createChild("div");
this._provider = provider;
this.element.addEventListener("scroll", this._onScroll.bind(this), false);
this._firstVisibleIndex = 0;
this._lastVisibleIndex = -1;
}
WebInspector.ViewportControl.Provider = function()
{
}
WebInspector.ViewportControl.Provider.prototype = {
itemCount: function() { return 0; },
itemElement: function(index) { return null; }
}
WebInspector.ViewportControl.prototype = {
contentElement: function()
{
return this._contentElement;
},
refresh: function()
{
if (!this.element.clientHeight)
return;
var itemCount = this._provider.itemCount();
if (!itemCount)
return;
if (!this._rowHeight) {
var firstElement = this._provider.itemElement(0);
this._rowHeight = firstElement.measurePreferredSize(this._contentElement).height;
}
var visibleFrom = this.element.scrollTop;
var visibleTo = visibleFrom + this.element.clientHeight;
this._firstVisibleIndex = Math.floor(visibleFrom / this._rowHeight);
this._lastVisibleIndex = Math.min(Math.ceil(visibleTo / this._rowHeight), itemCount) - 1;
this._topGapElement.style.height = (this._rowHeight * this._firstVisibleIndex) + "px";
this._bottomGapElement.style.height = (this._rowHeight * (itemCount - this._lastVisibleIndex - 1)) + "px";
this._contentElement.removeChildren();
for (var i = this._firstVisibleIndex; i <= this._lastVisibleIndex; ++i)
this._contentElement.appendChild(this._provider.itemElement(i));
},
_onScroll: function(event)
{
this.refresh();
},
rowsPerViewport: function()
{
return Math.floor(this.element.clientHeight / this._rowHeight);
},
firstVisibleIndex: function()
{
return this._firstVisibleIndex;
},
lastVisibleIndex: function()
{
return this._lastVisibleIndex;
},
renderedElementAt: function(index)
{
if (index < this._firstVisibleIndex)
return null;
if (index > this._lastVisibleIndex)
return null;
return this._contentElement.childNodes[index - this._firstVisibleIndex];
},
scrollItemIntoView: function(index, makeLast)
{
if (index > this._firstVisibleIndex && index < this._lastVisibleIndex)
return;
if (makeLast)
this.element.scrollTop = this._rowHeight * (index + 1) - this.element.clientHeight;
else
this.element.scrollTop = this._rowHeight * index;
}
}