Show:

File: platform/plugins/Q/web/js/fn/scrollbarsAutoHide.js

(function (Q, $, window, document, undefined) {

/**
 * Q Tools
 * @module Q-tools
 */

/**
 * jQuery plugin for automatically hiding scrollbars
 * on 'overflow: scroll' or 'overflow: auto' elements when
 * mouse cursor is not over them.
 * Usable on desktop browsers for not overloading interface
 * with unneeded visual elements (such as scrollbars)
 * if there are lot of scrollable areas.
 * @class Q scrollbarsAutoHide
 * @constructor
 * @param {Mixed} [Object_or_String] function could have String or Object parameter
 * @param {Object} [Object_or_String.Object] If an object then it's a hash of options, that can include:
 *   @param {Boolean} [Object_or_String.Object.scrollbarPadding] Boolean which indicates whether to preserve padding in a container based on scrollbar
 *   width. Padding preserved on the right side (for vertical scrolling) or on the bottom side (for horizontal scrolling).
 *	 @default true
 *	 @param {Q.Event} [Object_or_String.Object.showHandler] callback which is called when scrollbar is just shown.
 *	 @param {Q.Event} [Object_or_String.Object.hideHandler] callback which is called when scrollbar is just hidden.
 * @param {String} [Object_or_String.String]
 *	 If a string then it's a command and it can have following values:
 *	 "remove": Removes the plugin functionality so the container won't hide its scrollbars automatically anymore.
 */

    Q.Tool.jQuery('Q/scrollbarsAutoHide',

        function (o) {

            var $this = this;
			var element = this[0];
            if (element.scrollHeight <= element.offsetHeight
                && element.scrollWidth <= element.offsetWidth) {
                return;
            }
            var scrollbarWidth = Q.Browser.getScrollbarWidth();
            var oldOverflow = $this.css('overflow');
            var oldPaddingRight = parseInt($this.css('padding-right'));
            var oldPaddingBottom = parseInt($this.css('padding-bottom'));
            $this.data('Q/scrollbarsAutoHide old_overflow', oldOverflow);
            $this.data('Q/scrollbarsAutoHide old_padding_right', oldPaddingRight);
            $this.data('Q/scrollbarsAutoHide old_padding_bottom', oldPaddingBottom);
            var scrollbarRight = element.scrollHeight > element.offsetHeight;
            var scrollbarBottom = element.scrollWidth > element.offsetWidth;
            if (scrollbarRight) {
				var newPaddingRight = Math.max(oldPaddingRight, scrollbarWidth);
				var paddingDiffRight = Math.max(0, newPaddingRight - scrollbarWidth);
                $this.css('overflow', 'hidden' );
                if (o.scrollbarPadding) {
                    $this.css('padding-right', newPaddingRight + 'px');
                } else {
                    $this.css('padding-right', paddingDiffRight + 'px');
                }
                $this.on({
                    'mouseenter.Q_scrollbar_autohide': function() {
                        $this.css({ 'overflow': 'auto' });
                        if (o.scrollbarPadding) {
                            $this.css({ 'padding-right': paddingDiffRight + 'px' });
                        }
                        if (Q.Browser.detect().OS == 'mac') {
                            var scrollTop = $this.scrollTop();
                            $this.scrollTop(0);
                            $this.scrollTop(scrollTop);
                        }
                        Q.handle(o.showHandler);
                    },
                    'mouseleave.Q_scrollbar_autohide': function() {
                        $this.css({ 'overflow': 'hidden' });
                        if (o.scrollbarPadding) {
                            $this.css({ 'padding-right': newPaddingRight + 'px' });
                        }
                        Q.handle(o.hideHandler);
                    }
                });
            } else if (scrollbarBottom) {
				var newPaddingBottom = Math.max(oldPaddingBottom, scrollbarWidth);
				var paddingDiffBottom = Math.max(0, newPaddingRight - scrollbarWidth);
                $this.css({ 'overflow': 'hidden' });
                if (o.scrollbarPadding) {
                    $this.css('padding-bottom', newPaddingBottom + 'px');
                } else {
                    $this.css('padding-bottom', paddingDiffBottom + 'px');
                }
                $this.on({
                    'mouseenter.Q_scrollbar_autohide': function() {
                        $this.css({ 'overflow': 'auto' });
                        if (o.scrollbarPadding) {
                            $this.css({ 'padding-right': paddingDiffBottom + 'px' });
                        }
                        if (Q.Browser.detect().OS == 'mac') {
                            var scrollLeft = $this.scrollLeft();
                            $this.scrollLeft(0);
                            $this.scrollLeft(scrollLeft);
                        }
                        Q.handle(o.showHandler);
                    },
                    'mouseleave.Q_scrollbar_autohide': function() {
                        $this.css({ 'overflow': 'hidden' });
		                if (o.scrollbarPadding) {
		                    $this.css('padding-bottom', newPaddingBottom + 'px');
		                }
                        Q.handle(o.hideHandler);
                    }
                });
            }

            $this.on('mousemove.Q_scrollbar_autohide', function() {
                $this.off('mousemove.Q_scrollbar_autohide').trigger('mouseenter');
            });
        },

        {
            'scrollbarPadding': true,
            'showHandler': new Q.Event(function() {}),
            'hideHandler': new Q.Event(function() {})
        },

        {
			/**
			 * Removes the scrollbarsAutoHide functionality from the element
			 * @method remove
			 */
            remove: function () {
                var $this = this;
                if ($this.data('Q/scrollbarsAutoHide old_overflow') !== undefined)
                {
                    $this.off('mouseenter.Q_scrollbar_autohide mouseleave.Q_scrollbar_autohide mousemove.Q_scrollbar_autohide');
                    $this.css({
                        'overflow': $this.data('Q/scrollbarsAutoHide old_overflow'),
                        'padding-right': $this.data('Q/scrollbarsAutoHide old_padding_right') + 'px',
                        'padding-bottom': $this.data('Q/scrollbarsAutoHide old_padding_bottom') + 'px'
                    });
                    $this.removeData(['Q/scrollbarsAutoHide old_overflow', 'Q/scrollbarsAutoHide old_padding_right', 'Q/scrollbarsAutoHide old_padding_bottom']);
                }
            }
        }

    );

})(Q, jQuery, window, document);