--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>The source code</title>
+ <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
+ <script type="text/javascript" src="../prettify/prettify.js"></script>
+ <style type="text/css">
+ .highlight { display: block; background-color: #ddd; }
+ </style>
+ <script type="text/javascript">
+ function highlight() {
+ document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
+ }
+ </script>
+</head>
+<body onload="prettyPrint(); highlight();">
+ <pre class="prettyprint lang-js"><span id='Ext-grid-PagingScroller'>/**
+</span> * @class Ext.grid.PagingScroller
+ * @extends Ext.grid.Scroller
+ *
+ * @private
+ */
+Ext.define('Ext.grid.PagingScroller', {
+ extend: 'Ext.grid.Scroller',
+ alias: 'widget.paginggridscroller',
+ //renderTpl: null,
+ //tpl: [
+ // '<tpl for="pages">',
+ // '<div class="' + Ext.baseCSSPrefix + 'stretcher" style="width: {width}px;height: {height}px;"></div>',
+ // '</tpl>'
+ //],
+<span id='Ext-grid-PagingScroller-cfg-percentageFromEdge'> /**
+</span> * @cfg {Number} percentageFromEdge This is a number above 0 and less than 1 which specifies
+ * at what percentage to begin fetching the next page. For example if the pageSize is 100
+ * and the percentageFromEdge is the default of 0.35, the paging scroller will prefetch pages
+ * when scrolling up between records 0 and 34 and when scrolling down between records 65 and 99.
+ */
+ percentageFromEdge: 0.35,
+
+<span id='Ext-grid-PagingScroller-cfg-scrollToLoadBuffer'> /**
+</span> * @cfg {Number} scrollToLoadBuffer This is the time in milliseconds to buffer load requests
+ * when scrolling the PagingScrollbar.
+ */
+ scrollToLoadBuffer: 200,
+
+ activePrefetch: true,
+
+ chunkSize: 50,
+ snapIncrement: 25,
+
+ syncScroll: true,
+
+ initComponent: function() {
+ var me = this,
+ ds = me.store;
+
+ ds.on('guaranteedrange', this.onGuaranteedRange, this);
+ this.callParent(arguments);
+ },
+
+
+ onGuaranteedRange: function(range, start, end) {
+ var me = this,
+ ds = me.store,
+ rs;
+ // this should never happen
+ if (range.length && me.visibleStart < range[0].index) {
+ return;
+ }
+
+ ds.loadRecords(range);
+
+ if (!me.firstLoad) {
+ if (me.rendered) {
+ me.invalidate();
+ } else {
+ me.on('afterrender', this.invalidate, this, {single: true});
+ }
+ me.firstLoad = true;
+ } else {
+ // adjust to visible
+ me.syncTo();
+ }
+ },
+
+ syncTo: function() {
+ var me = this,
+ pnl = me.getPanel(),
+ store = pnl.store,
+ scrollerElDom = this.el.dom,
+ rowOffset = me.visibleStart - store.guaranteedStart,
+ scrollBy = rowOffset * me.rowHeight,
+ scrollHeight = scrollerElDom.scrollHeight,
+ clientHeight = scrollerElDom.clientHeight,
+ scrollTop = scrollerElDom.scrollTop,
+ useMaximum;
+
+ // BrowserBug: clientHeight reports 0 in IE9 StrictMode
+ // Instead we are using offsetHeight and hardcoding borders
+ if (Ext.isIE9 && Ext.isStrict) {
+ clientHeight = scrollerElDom.offsetHeight + 2;
+ }
+
+ // This should always be zero or greater than zero but staying
+ // safe and less than 0 we'll scroll to the bottom.
+ useMaximum = (scrollHeight - clientHeight - scrollTop <= 0);
+ this.setViewScrollTop(scrollBy, useMaximum);
+ },
+
+ getPageData : function(){
+ var panel = this.getPanel(),
+ store = panel.store,
+ totalCount = store.getTotalCount();
+
+ return {
+ total : totalCount,
+ currentPage : store.currentPage,
+ pageCount: Math.ceil(totalCount / store.pageSize),
+ fromRecord: ((store.currentPage - 1) * store.pageSize) + 1,
+ toRecord: Math.min(store.currentPage * store.pageSize, totalCount)
+ };
+ },
+
+ onElScroll: function(e, t) {
+ var me = this,
+ panel = me.getPanel(),
+ store = panel.store,
+ pageSize = store.pageSize,
+ guaranteedStart = store.guaranteedStart,
+ guaranteedEnd = store.guaranteedEnd,
+ totalCount = store.getTotalCount(),
+ numFromEdge = Math.ceil(me.percentageFromEdge * store.pageSize),
+ position = t.scrollTop,
+ visibleStart = Math.floor(position / me.rowHeight),
+ view = panel.down('tableview'),
+ viewEl = view.el,
+ visibleHeight = viewEl.getHeight(),
+ visibleAhead = Math.ceil(visibleHeight / me.rowHeight),
+ visibleEnd = visibleStart + visibleAhead,
+ prevPage = Math.floor(visibleStart / store.pageSize),
+ nextPage = Math.floor(visibleEnd / store.pageSize) + 2,
+ lastPage = Math.ceil(totalCount / store.pageSize),
+ //requestStart = visibleStart,
+ requestStart = Math.floor(visibleStart / me.snapIncrement) * me.snapIncrement,
+ requestEnd = requestStart + pageSize - 1,
+ activePrefetch = me.activePrefetch;
+
+ me.visibleStart = visibleStart;
+ me.visibleEnd = visibleEnd;
+
+
+ me.syncScroll = true;
+ if (totalCount >= pageSize) {
+ // end of request was past what the total is, grab from the end back a pageSize
+ if (requestEnd > totalCount - 1) {
+ this.cancelLoad();
+ if (store.rangeSatisfied(totalCount - pageSize, totalCount - 1)) {
+ me.syncScroll = true;
+ }
+ store.guaranteeRange(totalCount - pageSize, totalCount - 1);
+ // Out of range, need to reset the current data set
+ } else if (visibleStart < guaranteedStart || visibleEnd > guaranteedEnd) {
+ if (store.rangeSatisfied(requestStart, requestEnd)) {
+ this.cancelLoad();
+ store.guaranteeRange(requestStart, requestEnd);
+ } else {
+ store.mask();
+ me.attemptLoad(requestStart, requestEnd);
+ }
+ // dont sync the scroll view immediately, sync after the range has been guaranteed
+ me.syncScroll = false;
+ } else if (activePrefetch && visibleStart < (guaranteedStart + numFromEdge) && prevPage > 0) {
+ me.syncScroll = true;
+ store.prefetchPage(prevPage);
+ } else if (activePrefetch && visibleEnd > (guaranteedEnd - numFromEdge) && nextPage < lastPage) {
+ me.syncScroll = true;
+ store.prefetchPage(nextPage);
+ }
+ }
+
+
+ if (me.syncScroll) {
+ me.syncTo();
+ }
+ },
+
+ getSizeCalculation: function() {
+ // Use the direct ownerCt here rather than the scrollerOwner
+ // because we are calculating widths/heights.
+ var owner = this.ownerCt,
+ view = owner.getView(),
+ store = this.store,
+ dock = this.dock,
+ elDom = this.el.dom,
+ width = 1,
+ height = 1;
+
+ if (!this.rowHeight) {
+ this.rowHeight = view.el.down(view.getItemSelector()).getHeight(false, true);
+ }
+
+ height = store.getTotalCount() * this.rowHeight;
+
+ if (isNaN(width)) {
+ width = 1;
+ }
+ if (isNaN(height)) {
+ height = 1;
+ }
+ return {
+ width: width,
+ height: height
+ };
+ },
+
+ attemptLoad: function(start, end) {
+ var me = this;
+ if (!me.loadTask) {
+ me.loadTask = Ext.create('Ext.util.DelayedTask', me.doAttemptLoad, me, []);
+ }
+ me.loadTask.delay(me.scrollToLoadBuffer, me.doAttemptLoad, me, [start, end]);
+ },
+
+ cancelLoad: function() {
+ if (this.loadTask) {
+ this.loadTask.cancel();
+ }
+ },
+
+ doAttemptLoad: function(start, end) {
+ var store = this.getPanel().store;
+ store.guaranteeRange(start, end);
+ },
+
+ setViewScrollTop: function(scrollTop, useMax) {
+ var owner = this.getPanel(),
+ items = owner.query('tableview'),
+ i = 0,
+ len = items.length,
+ center,
+ centerEl,
+ calcScrollTop,
+ maxScrollTop,
+ scrollerElDom = this.el.dom;
+
+ owner.virtualScrollTop = scrollTop;
+
+ center = items[1] || items[0];
+ centerEl = center.el.dom;
+
+ maxScrollTop = ((owner.store.pageSize * this.rowHeight) - centerEl.clientHeight);
+ calcScrollTop = (scrollTop % ((owner.store.pageSize * this.rowHeight) + 1));
+ if (useMax) {
+ calcScrollTop = maxScrollTop;
+ }
+ if (calcScrollTop > maxScrollTop) {
+ //Ext.Error.raise("Calculated scrollTop was larger than maxScrollTop");
+ return;
+ // calcScrollTop = maxScrollTop;
+ }
+ for (; i < len; i++) {
+ items[i].el.dom.scrollTop = calcScrollTop;
+ }
+ }
+});
+
+</pre>
+</body>
+</html>