AutorÃa | Ultima modificación | Ver Log |
YUI.add('scrollview-scrollbars', function (Y, NAME) {/*** Provides a plugin, which adds support for a scroll indicator to ScrollView instances** @module scrollview* @submodule scrollview-scrollbars*/var getClassName = Y.ClassNameManager.getClassName,_classNames,Transition = Y.Transition,NATIVE_TRANSITIONS = Transition.useNative,SCROLLBAR = 'scrollbar',SCROLLVIEW = 'scrollview',VERTICAL_NODE = "verticalNode",HORIZONTAL_NODE = "horizontalNode",CHILD_CACHE = "childCache",TOP = "top",LEFT = "left",WIDTH = "width",HEIGHT = "height",HORIZ_CACHE = "_sbh",VERT_CACHE = "_sbv",TRANSITION_PROPERTY = Y.ScrollView._TRANSITION.PROPERTY,TRANSFORM = "transform",TRANSLATE_X = "translateX(",TRANSLATE_Y = "translateY(",SCALE_X = "scaleX(",SCALE_Y = "scaleY(",SCROLL_X = "scrollX",SCROLL_Y = "scrollY",PX = "px",CLOSE = ")",PX_CLOSE = PX + CLOSE;/*** ScrollView plugin that adds scroll indicators to ScrollView instances** @class ScrollViewScrollbars* @namespace Plugin* @extends Plugin.Base* @constructor*/function ScrollbarsPlugin() {ScrollbarsPlugin.superclass.constructor.apply(this, arguments);}ScrollbarsPlugin.CLASS_NAMES = {showing: getClassName(SCROLLVIEW, SCROLLBAR, 'showing'),scrollbar: getClassName(SCROLLVIEW, SCROLLBAR),scrollbarV: getClassName(SCROLLVIEW, SCROLLBAR, 'vert'),scrollbarH: getClassName(SCROLLVIEW, SCROLLBAR, 'horiz'),scrollbarVB: getClassName(SCROLLVIEW, SCROLLBAR, 'vert', 'basic'),scrollbarHB: getClassName(SCROLLVIEW, SCROLLBAR, 'horiz', 'basic'),child: getClassName(SCROLLVIEW, 'child'),first: getClassName(SCROLLVIEW, 'first'),middle: getClassName(SCROLLVIEW, 'middle'),last: getClassName(SCROLLVIEW, 'last')};_classNames = ScrollbarsPlugin.CLASS_NAMES;/*** The identity of the plugin** @property NAME* @type String* @default 'pluginScrollViewScrollbars'* @static*/ScrollbarsPlugin.NAME = 'pluginScrollViewScrollbars';/*** The namespace on which the plugin will reside.** @property NS* @type String* @default 'scrollbars'* @static*/ScrollbarsPlugin.NS = 'scrollbars';/*** HTML template for the scrollbar** @property SCROLLBAR_TEMPLATE* @type Object* @static*/ScrollbarsPlugin.SCROLLBAR_TEMPLATE = ['<div>','<span class="' + _classNames.child + ' ' + _classNames.first + '"></span>','<span class="' + _classNames.child + ' ' + _classNames.middle + '"></span>','<span class="' + _classNames.child + ' ' + _classNames.last + '"></span>','</div>'].join('');/*** The default attribute configuration for the plugin** @property ATTRS* @type Object* @static*/ScrollbarsPlugin.ATTRS = {/*** Vertical scrollbar node** @attribute verticalNode* @type Y.Node*/verticalNode: {setter: '_setNode',valueFn: '_defaultNode'},/*** Horizontal scrollbar node** @attribute horizontalNode* @type Y.Node*/horizontalNode: {setter: '_setNode',valueFn: '_defaultNode'}};Y.namespace("Plugin").ScrollViewScrollbars = Y.extend(ScrollbarsPlugin, Y.Plugin.Base, {/*** Designated initializer** @method initializer*/initializer: function() {this._host = this.get("host");this.afterHostEvent('scrollEnd', this._hostScrollEnd);this.afterHostMethod('scrollTo', this._update);this.afterHostMethod('_uiDimensionsChange', this._hostDimensionsChange);},/*** Set up the DOM nodes for the scrollbars. This method is invoked whenever the* host's _uiDimensionsChange fires, giving us the opportunity to remove un-needed* scrollbars, as well as add one if necessary.** @method _hostDimensionsChange* @protected*/_hostDimensionsChange: function() {var host = this._host,axis = host._cAxis,scrollX = host.get(SCROLL_X),scrollY = host.get(SCROLL_Y);this._dims = host._getScrollDims();if (axis && axis.y) {this._renderBar(this.get(VERTICAL_NODE), true, 'vert');}if (axis && axis.x) {this._renderBar(this.get(HORIZONTAL_NODE), true, 'horiz');}this._update(scrollX, scrollY);Y.later(500, this, 'flash', true);},/*** Handler for the scrollEnd event fired by the host. Default implementation flashes the scrollbar** @method _hostScrollEnd* @param {EventFacade} e The event facade.* @protected*/_hostScrollEnd : function() {var host = this._host,scrollX = host.get(SCROLL_X),scrollY = host.get(SCROLL_Y);this.flash();this._update(scrollX, scrollY);},/*** Adds or removes a scrollbar node from the document.** @method _renderBar* @private* @param {Node} bar The scrollbar node* @param {boolean} add true, to add the node, false to remove it*/_renderBar: function(bar, add) {var inDoc = bar.inDoc(),bb = this._host._bb,className = bar.getData("isHoriz") ? _classNames.scrollbarHB : _classNames.scrollbarVB;if (add && !inDoc) {bb.append(bar);bar.toggleClass(className, this._basic);this._setChildCache(bar);} else if(!add && inDoc) {bar.remove();this._clearChildCache(bar);}},/*** Caches scrollbar child element information,* to optimize _update implementation** @method _setChildCache* @private* @param {Node} node*/_setChildCache : function(node) {var c = node.get("children"),fc = c.item(0),mc = c.item(1),lc = c.item(2),size = node.getData("isHoriz") ? "offsetWidth" : "offsetHeight";node.setStyle(TRANSITION_PROPERTY, TRANSFORM);mc.setStyle(TRANSITION_PROPERTY, TRANSFORM);lc.setStyle(TRANSITION_PROPERTY, TRANSFORM);node.setData(CHILD_CACHE, {fc : fc,lc : lc,mc : mc,fcSize : fc && fc.get(size),lcSize : lc && lc.get(size)});},/*** Clears child cache** @method _clearChildCache* @private* @param {Node} node*/_clearChildCache : function(node) {node.clearData(CHILD_CACHE);},/*** Utility method, to move/resize either vertical or horizontal scrollbars** @method _updateBar* @private** @param {Node} scrollbar The scrollbar node.* @param {Number} current The current scroll position.* @param {Number} duration The transition duration.* @param {boolean} horiz true if horizontal, false if vertical.*/_updateBar : function(scrollbar, current, duration, horiz) {var host = this._host,basic = this._basic,scrollbarSize = 0,scrollbarPos = 1,childCache = scrollbar.getData(CHILD_CACHE),lastChild = childCache.lc,middleChild = childCache.mc,firstChildSize = childCache.fcSize,lastChildSize = childCache.lcSize,middleChildSize,lastChildPosition,transition,translate,scale,dim,dimOffset,dimCache,widgetSize,contentSize;if (horiz) {dim = WIDTH;dimOffset = LEFT;dimCache = HORIZ_CACHE;widgetSize = this._dims.offsetWidth;contentSize = this._dims.scrollWidth;translate = TRANSLATE_X;scale = SCALE_X;current = (current !== undefined) ? current : host.get(SCROLL_X);} else {dim = HEIGHT;dimOffset = TOP;dimCache = VERT_CACHE;widgetSize = this._dims.offsetHeight;contentSize = this._dims.scrollHeight;translate = TRANSLATE_Y;scale = SCALE_Y;current = (current !== undefined) ? current : host.get(SCROLL_Y);}scrollbarSize = Math.floor(widgetSize * (widgetSize/contentSize));scrollbarPos = Math.floor((current/(contentSize - widgetSize)) * (widgetSize - scrollbarSize));if (scrollbarSize > widgetSize) {scrollbarSize = 1;}if (scrollbarPos > (widgetSize - scrollbarSize)) {scrollbarSize = scrollbarSize - (scrollbarPos - (widgetSize - scrollbarSize));} else if (scrollbarPos < 0) {scrollbarSize = scrollbarPos + scrollbarSize;scrollbarPos = 0;} else if (isNaN(scrollbarPos)) {scrollbarPos = 0;}middleChildSize = (scrollbarSize - (firstChildSize + lastChildSize));if (middleChildSize < 0) {middleChildSize = 0;}if (middleChildSize === 0 && scrollbarPos !== 0) {scrollbarPos = widgetSize - (firstChildSize + lastChildSize) - 1;}if (duration !== 0) {// Position Scrollbartransition = {duration : duration};if (NATIVE_TRANSITIONS) {transition.transform = translate + scrollbarPos + PX_CLOSE;} else {transition[dimOffset] = scrollbarPos + PX;}scrollbar.transition(transition);} else {if (NATIVE_TRANSITIONS) {scrollbar.setStyle(TRANSFORM, translate + scrollbarPos + PX_CLOSE);} else {scrollbar.setStyle(dimOffset, scrollbarPos + PX);}}// Resize Scrollbar Middle Childif (this[dimCache] !== middleChildSize) {this[dimCache] = middleChildSize;if (middleChildSize > 0) {if (duration !== 0) {transition = {duration : duration};if(NATIVE_TRANSITIONS) {transition.transform = scale + middleChildSize + CLOSE;} else {transition[dim] = middleChildSize + PX;}middleChild.transition(transition);} else {if (NATIVE_TRANSITIONS) {middleChild.setStyle(TRANSFORM, scale + middleChildSize + CLOSE);} else {middleChild.setStyle(dim, middleChildSize + PX);}}// Position Last Childif (!horiz || !basic) {lastChildPosition = scrollbarSize - lastChildSize;if(duration !== 0) {transition = {duration : duration};if (NATIVE_TRANSITIONS) {transition.transform = translate + lastChildPosition + PX_CLOSE;} else {transition[dimOffset] = lastChildPosition;}lastChild.transition(transition);} else {if (NATIVE_TRANSITIONS) {lastChild.setStyle(TRANSFORM, translate + lastChildPosition + PX_CLOSE);} else {lastChild.setStyle(dimOffset, lastChildPosition + PX);}}}}}},/*** AOP method, invoked after the host's _uiScrollTo method,* to position and resize the scroll bars** @method _update* @param x {Number} The current scrollX value* @param y {Number} The current scrollY value* @param duration {Number} Number of ms of animation (optional) - used when snapping to bounds* @param easing {String} Optional easing equation to use during the animation, if duration is set* @protected*/_update: function(x, y, duration) {var vNode = this.get(VERTICAL_NODE),hNode = this.get(HORIZONTAL_NODE),host = this._host,axis = host._cAxis;duration = (duration || 0)/1000;if (!this._showing) {this.show();}if (axis && axis.y && vNode && y !== null) {this._updateBar(vNode, y, duration, false);}if (axis && axis.x && hNode && x !== null) {this._updateBar(hNode, x, duration, true);}},/*** Show the scroll bar indicators** @method show* @param animated {Boolean} Whether or not to animate the showing*/show: function(animated) {this._show(true, animated);},/*** Hide the scroll bar indicators** @method hide* @param animated {Boolean} Whether or not to animate the hiding*/hide: function(animated) {this._show(false, animated);},/*** Internal hide/show implementation utility method** @method _show* @param {boolean} show Whether to show or hide the scrollbar* @param {bolean} animated Whether or not to animate while showing/hide* @protected*/_show : function(show, animated) {var verticalNode = this.get(VERTICAL_NODE),horizontalNode = this.get(HORIZONTAL_NODE),duration = (animated) ? 0.6 : 0,opacity = (show) ? 1 : 0,transition;this._showing = show;if (this._flashTimer) {this._flashTimer.cancel();}transition = {duration : duration,opacity : opacity};if (verticalNode && verticalNode._node) {verticalNode.transition(transition);}if (horizontalNode && horizontalNode._node) {horizontalNode.transition(transition);}},/*** Momentarily flash the scroll bars to indicate current scroll position** @method flash*/flash: function() {this.show(true);this._flashTimer = Y.later(800, this, 'hide', true);},/*** Setter for the verticalNode and horizontalNode attributes** @method _setNode* @param node {Node} The Y.Node instance for the scrollbar* @param name {String} The attribute name* @return {Node} The Y.Node instance for the scrollbar** @protected*/_setNode: function(node, name) {var horiz = (name === HORIZONTAL_NODE);node = Y.one(node);if (node) {node.addClass(_classNames.scrollbar);node.addClass( (horiz) ? _classNames.scrollbarH : _classNames.scrollbarV );node.setData("isHoriz", horiz);}return node;},/*** Creates default node instances for scrollbars** @method _defaultNode* @return {Node} The Y.Node instance for the scrollbar** @protected*/_defaultNode: function() {return Y.Node.create(ScrollbarsPlugin.SCROLLBAR_TEMPLATE);},_basic: Y.UA.ie && Y.UA.ie <= 8});}, '3.18.1', {"requires": ["classnamemanager", "transition", "plugin"], "skinnable": true});