/** * @class Ext.core.Element */ Ext.override(Ext.core.Element, { /** * Returns true if this element is scrollable. * @return {Boolean} */ isScrollable : function(){ var dom = this.dom; return dom.scrollHeight > dom.clientHeight || dom.scrollWidth > dom.clientWidth; }, /** * Returns the current scroll position of the element. * @return {Object} An object containing the scroll position in the format {left: (scrollLeft), top: (scrollTop)} */ getScroll : function() { var d = this.dom, doc = document, body = doc.body, docElement = doc.documentElement, l, t, ret; if (d == doc || d == body) { if (Ext.isIE && Ext.isStrict) { l = docElement.scrollLeft; t = docElement.scrollTop; } else { l = window.pageXOffset; t = window.pageYOffset; } ret = { left: l || (body ? body.scrollLeft : 0), top : t || (body ? body.scrollTop : 0) }; } else { ret = { left: d.scrollLeft, top : d.scrollTop }; } return ret; }, /** * Scrolls this element the specified scroll point. It does NOT do bounds checking so if you scroll to a weird value it will try to do it. For auto bounds checking, use scroll(). * @param {String} side Either "left" for scrollLeft values or "top" for scrollTop values. * @param {Number} value The new scroll value * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object * @return {Element} this */ scrollTo : function(side, value, animate) { //check if we're scrolling top or left var top = /top/i.test(side), me = this, dom = me.dom, obj = {}, prop; if (!animate || !me.anim) { // just setting the value, so grab the direction prop = 'scroll' + (top ? 'Top' : 'Left'); dom[prop] = value; } else { if (!Ext.isObject(animate)) { animate = {}; } obj['scroll' + (top ? 'Top' : 'Left')] = value; me.animate(Ext.applyIf({ to: obj }, animate)); } return me; }, /** * Scrolls this element into view within the passed container. * @param {Mixed} container (optional) The container element to scroll (defaults to document.body). Should be a * string (id), dom node, or Ext.core.Element. * @param {Boolean} hscroll (optional) False to disable horizontal scroll (defaults to true) * @return {Ext.core.Element} this */ scrollIntoView : function(container, hscroll) { container = Ext.getDom(container) || Ext.getBody().dom; var el = this.dom, offsets = this.getOffsetsTo(container), // el's box left = offsets[0] + container.scrollLeft, top = offsets[1] + container.scrollTop, bottom = top + el.offsetHeight, right = left + el.offsetWidth, // ct's box ctClientHeight = container.clientHeight, ctScrollTop = parseInt(container.scrollTop, 10), ctScrollLeft = parseInt(container.scrollLeft, 10), ctBottom = ctScrollTop + ctClientHeight, ctRight = ctScrollLeft + container.clientWidth; if (el.offsetHeight > ctClientHeight || top < ctScrollTop) { container.scrollTop = top; } else if (bottom > ctBottom) { container.scrollTop = bottom - ctClientHeight; } // corrects IE, other browsers will ignore container.scrollTop = container.scrollTop; if (hscroll !== false) { if (el.offsetWidth > container.clientWidth || left < ctScrollLeft) { container.scrollLeft = left; } else if (right > ctRight) { container.scrollLeft = right - container.clientWidth; } container.scrollLeft = container.scrollLeft; } return this; }, // private scrollChildIntoView : function(child, hscroll) { Ext.fly(child, '_scrollChildIntoView').scrollIntoView(this, hscroll); }, /** * Scrolls this element the specified direction. Does bounds checking to make sure the scroll is * within this element's scrollable range. * @param {String} direction Possible values are: "l" (or "left"), "r" (or "right"), "t" (or "top", or "up"), "b" (or "bottom", or "down"). * @param {Number} distance How far to scroll the element in pixels * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object * @return {Boolean} Returns true if a scroll was triggered or false if the element * was scrolled as far as it could go. */ scroll : function(direction, distance, animate) { if (!this.isScrollable()) { return false; } var el = this.dom, l = el.scrollLeft, t = el.scrollTop, w = el.scrollWidth, h = el.scrollHeight, cw = el.clientWidth, ch = el.clientHeight, scrolled = false, v, hash = { l: Math.min(l + distance, w-cw), r: v = Math.max(l - distance, 0), t: Math.max(t - distance, 0), b: Math.min(t + distance, h-ch) }; hash.d = hash.b; hash.u = hash.t; direction = direction.substr(0, 1); if ((v = hash[direction]) > -1) { scrolled = true; this.scrollTo(direction == 'l' || direction == 'r' ? 'left' : 'top', v, this.anim(animate)); } return scrolled; } });