--- /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-Scroller'>/**
+</span> * @class Ext.grid.Scroller
+ * @extends Ext.Component
+ *
+ * Docked in an Ext.grid.Panel, controls virtualized scrolling and synchronization
+ * across different sections.
+ *
+ * @private
+ */
+Ext.define('Ext.grid.Scroller', {
+ extend: 'Ext.Component',
+ alias: 'widget.gridscroller',
+ weight: 110,
+ cls: Ext.baseCSSPrefix + 'scroller',
+ focusable: false,
+
+ renderTpl: ['<div class="' + Ext.baseCSSPrefix + 'stretcher"></div>'],
+
+ initComponent: function() {
+ var me = this,
+ dock = me.dock,
+ cls = Ext.baseCSSPrefix + 'scroller-vertical',
+ sizeProp = 'width',
+ // Subtracting 2px would give us a perfect fit of the scroller
+ // however, some browsers wont allow us to scroll content thats not
+ // visible, therefore we use 1px.
+ // Note: This 1px offset matches code in Ext.grid.ColumnLayout when
+ // reserving room for the scrollbar
+ scrollbarWidth = Ext.getScrollBarWidth() + (Ext.isIE ? 1 : -1);
+
+ me.offsets = {bottom: 0};
+
+ if (dock === 'top' || dock === 'bottom') {
+ cls = Ext.baseCSSPrefix + 'scroller-horizontal';
+ sizeProp = 'height';
+ }
+ me[sizeProp] = scrollbarWidth;
+
+ me.cls += (' ' + cls);
+
+ Ext.applyIf(me.renderSelectors, {
+ stretchEl: '.' + Ext.baseCSSPrefix + 'stretcher'
+ });
+ me.callParent();
+ },
+
+
+ afterRender: function() {
+ var me = this;
+ me.callParent();
+ me.ownerCt.on('afterlayout', me.onOwnerAfterLayout, me);
+ me.mon(me.el, 'scroll', me.onElScroll, me);
+ Ext.cache[me.el.id].skipGarbageCollection = true;
+ },
+
+ getSizeCalculation: function() {
+ var owner = this.getPanel(),
+ dock = this.dock,
+ elDom = this.el.dom,
+ width = 1,
+ height = 1,
+ view, tbl;
+
+ if (dock === 'top' || dock === 'bottom') {
+ // TODO: Must gravitate to a single region..
+ // Horizontal scrolling only scrolls virtualized region
+ var items = owner.query('tableview'),
+ center = items[1] || items[0];
+
+ if (!center) {
+ return false;
+ }
+ // center is not guaranteed to have content, such as when there
+ // are zero rows in the grid/tree. We read the width from the
+ // headerCt instead.
+ width = center.headerCt.getFullWidth();
+
+ if (Ext.isIEQuirks) {
+ width--;
+ }
+ // Account for the 1px removed in Scroller.
+ width--;
+ } else {
+ view = owner.down('tableview:not([lockableInjected])');
+ if (!view) {
+ return false;
+ }
+ tbl = view.el;
+ if (!tbl) {
+ return false;
+ }
+
+ // needs to also account for header and scroller (if still in picture)
+ // should calculate from headerCt.
+ height = tbl.dom.scrollHeight;
+ }
+ if (isNaN(width)) {
+ width = 1;
+ }
+ if (isNaN(height)) {
+ height = 1;
+ }
+ return {
+ width: width,
+ height: height
+ };
+ },
+
+ invalidate: function(firstPass) {
+ if (!this.stretchEl || !this.ownerCt) {
+ return;
+ }
+ var size = this.getSizeCalculation(),
+ elDom = this.el.dom;
+ if (size) {
+ this.stretchEl.setSize(size);
+
+ // BrowserBug: IE7
+ // This makes the scroller enabled, when initially rendering.
+ elDom.scrollTop = elDom.scrollTop;
+ }
+ },
+
+ onOwnerAfterLayout: function(owner, layout) {
+ this.invalidate();
+ },
+
+<span id='Ext-grid-Scroller-method-setScrollTop'> /**
+</span> * Sets the scrollTop and constrains the value between 0 and max.
+ * @param {Number} scrollTop
+ * @return {Number} The resulting scrollTop value after being constrained
+ */
+ setScrollTop: function(scrollTop) {
+ if (this.el) {
+ var elDom = this.el.dom;
+ return elDom.scrollTop = Ext.Number.constrain(scrollTop, 0, elDom.scrollHeight - elDom.clientHeight);
+ }
+ },
+
+<span id='Ext-grid-Scroller-method-setScrollLeft'> /**
+</span> * Sets the scrollLeft and constrains the value between 0 and max.
+ * @param {Number} scrollLeft
+ * @return {Number} The resulting scrollLeft value after being constrained
+ */
+ setScrollLeft: function(scrollLeft) {
+ if (this.el) {
+ var elDom = this.el.dom;
+ return elDom.scrollLeft = Ext.Number.constrain(scrollLeft, 0, elDom.scrollWidth - elDom.clientWidth);
+ }
+ },
+
+<span id='Ext-grid-Scroller-method-scrollByDeltaY'> /**
+</span> * Scroll by deltaY
+ * @param {Number} delta
+ * @return {Number} The resulting scrollTop value
+ */
+ scrollByDeltaY: function(delta) {
+ if (this.el) {
+ var elDom = this.el.dom;
+ return this.setScrollTop(elDom.scrollTop + delta);
+ }
+ },
+
+<span id='Ext-grid-Scroller-method-scrollByDeltaX'> /**
+</span> * Scroll by deltaX
+ * @param {Number} delta
+ * @return {Number} The resulting scrollLeft value
+ */
+ scrollByDeltaX: function(delta) {
+ if (this.el) {
+ var elDom = this.el.dom;
+ return this.setScrollLeft(elDom.scrollLeft + delta);
+ }
+ },
+
+
+<span id='Ext-grid-Scroller-method-scrollToTop'> /**
+</span> * Scroll to the top.
+ */
+ scrollToTop : function(){
+ this.setScrollTop(0);
+ },
+
+ // synchronize the scroller with the bound gridviews
+ onElScroll: function(event, target) {
+ this.fireEvent('bodyscroll', event, target);
+ },
+
+ getPanel: function() {
+ var me = this;
+ if (!me.panel) {
+ me.panel = this.up('[scrollerOwner]');
+ }
+ return me.panel;
+ }
+});
+
+</pre>
+</body>
+</html>