diff --git a/Gruntfile.js b/Gruntfile.js index a7fe6ea928..2858ee8bac 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -539,11 +539,10 @@ var _ = require('lodash'), 'bower_components/ember-simple-auth/simple-auth.js', 'bower_components/ember-simple-auth/simple-auth-oauth2.js', 'bower_components/google-caja/html-css-sanitizer-bundle.js', + 'bower_components/nanoscroller/bin/javascripts/jquery.nanoscroller.js', 'core/shared/lib/showdown/extensions/ghostimagepreview.js', - 'core/shared/lib/showdown/extensions/ghostgfm.js', - - 'core/shared/lib/nanoscroller/nanoscroller.js' + 'core/shared/lib/showdown/extensions/ghostgfm.js' ] }, @@ -576,11 +575,10 @@ var _ = require('lodash'), 'bower_components/ember-simple-auth/simple-auth.js', 'bower_components/ember-simple-auth/simple-auth-oauth2.js', 'bower_components/google-caja/html-css-sanitizer-bundle.js', + 'bower_components/nanoscroller/bin/javascripts/jquery.nanoscroller.js', 'core/shared/lib/showdown/extensions/ghostimagepreview.js', - 'core/shared/lib/showdown/extensions/ghostgfm.js', - - 'core/shared/lib/nanoscroller/nanoscroller.js' + 'core/shared/lib/showdown/extensions/ghostgfm.js' ] } }, diff --git a/bower.json b/bower.json index 3eea6b865f..b827fe199a 100644 --- a/bower.json +++ b/bower.json @@ -20,6 +20,7 @@ "loader.js": "git://github.com/stefanpenner/loader.js#1.0.0", "lodash": "2.4.1", "moment": "2.4.0", + "nanoscroller": "0.8.4", "normalize-scss": "~3.0.1", "nprogress": "0.1.2", "showdown": "git://github.com/ErisDS/showdown.git#v0.3.2-ghost", diff --git a/core/shared/lib/nanoscroller/nanoscroller.js b/core/shared/lib/nanoscroller/nanoscroller.js deleted file mode 100644 index 178ae5f260..0000000000 --- a/core/shared/lib/nanoscroller/nanoscroller.js +++ /dev/null @@ -1,964 +0,0 @@ -/*! nanoScrollerJS - v0.8.4 - 2014 -* http://jamesflorentino.github.com/nanoScrollerJS/ -* Copyright (c) 2014 James Florentino; Licensed MIT */ -(function($, window, document) { - "use strict"; - var BROWSER_IS_IE7, BROWSER_SCROLLBAR_WIDTH, DOMSCROLL, DOWN, DRAG, ENTER, KEYDOWN, KEYUP, MOUSEDOWN, MOUSEENTER, MOUSEMOVE, MOUSEUP, MOUSEWHEEL, NanoScroll, PANEDOWN, RESIZE, SCROLL, SCROLLBAR, TOUCHMOVE, UP, WHEEL, cAF, defaults, getBrowserScrollbarWidth, hasTransform, isFFWithBuggyScrollbar, rAF, transform, _elementStyle, _prefixStyle, _vendor; - defaults = { - - /** - a classname for the pane element. - @property paneClass - @type String - @default 'nano-pane' - */ - paneClass: 'nano-pane', - - /** - a classname for the slider element. - @property sliderClass - @type String - @default 'nano-slider' - */ - sliderClass: 'nano-slider', - - /** - a classname for the content element. - @property contentClass - @type String - @default 'nano-content' - */ - contentClass: 'nano-content', - - /** - a setting to enable native scrolling in iOS devices. - @property iOSNativeScrolling - @type Boolean - @default false - */ - iOSNativeScrolling: false, - - /** - a setting to prevent the rest of the page being - scrolled when user scrolls the `.content` element. - @property preventPageScrolling - @type Boolean - @default false - */ - preventPageScrolling: false, - - /** - a setting to disable binding to the resize event. - @property disableResize - @type Boolean - @default false - */ - disableResize: false, - - /** - a setting to make the scrollbar always visible. - @property alwaysVisible - @type Boolean - @default false - */ - alwaysVisible: false, - - /** - a default timeout for the `flash()` method. - @property flashDelay - @type Number - @default 1500 - */ - flashDelay: 1500, - - /** - a minimum height for the `.slider` element. - @property sliderMinHeight - @type Number - @default 20 - */ - sliderMinHeight: 20, - - /** - a maximum height for the `.slider` element. - @property sliderMaxHeight - @type Number - @default null - */ - sliderMaxHeight: null, - - /** - an alternate document context. - @property documentContext - @type Document - @default null - */ - documentContext: null, - - /** - an alternate window context. - @property windowContext - @type Window - @default null - */ - windowContext: null - }; - - /** - @property SCROLLBAR - @type String - @static - @final - @private - */ - SCROLLBAR = 'scrollbar'; - - /** - @property SCROLL - @type String - @static - @final - @private - */ - SCROLL = 'scroll'; - - /** - @property MOUSEDOWN - @type String - @final - @private - */ - MOUSEDOWN = 'mousedown'; - - /** - @property MOUSEENTER - @type String - @final - @private - */ - MOUSEENTER = 'mouseenter'; - - /** - @property MOUSEMOVE - @type String - @static - @final - @private - */ - MOUSEMOVE = 'mousemove'; - - /** - @property MOUSEWHEEL - @type String - @final - @private - */ - MOUSEWHEEL = 'mousewheel'; - - /** - @property MOUSEUP - @type String - @static - @final - @private - */ - MOUSEUP = 'mouseup'; - - /** - @property RESIZE - @type String - @final - @private - */ - RESIZE = 'resize'; - - /** - @property DRAG - @type String - @static - @final - @private - */ - DRAG = 'drag'; - - /** - @property ENTER - @type String - @static - @final - @private - */ - ENTER = 'enter'; - - /** - @property UP - @type String - @static - @final - @private - */ - UP = 'up'; - - /** - @property PANEDOWN - @type String - @static - @final - @private - */ - PANEDOWN = 'panedown'; - - /** - @property DOMSCROLL - @type String - @static - @final - @private - */ - DOMSCROLL = 'DOMMouseScroll'; - - /** - @property DOWN - @type String - @static - @final - @private - */ - DOWN = 'down'; - - /** - @property WHEEL - @type String - @static - @final - @private - */ - WHEEL = 'wheel'; - - /** - @property KEYDOWN - @type String - @static - @final - @private - */ - KEYDOWN = 'keydown'; - - /** - @property KEYUP - @type String - @static - @final - @private - */ - KEYUP = 'keyup'; - - /** - @property TOUCHMOVE - @type String - @static - @final - @private - */ - TOUCHMOVE = 'touchmove'; - - /** - @property BROWSER_IS_IE7 - @type Boolean - @static - @final - @private - */ - BROWSER_IS_IE7 = window.navigator.appName === 'Microsoft Internet Explorer' && /msie 7./i.test(window.navigator.appVersion) && window.ActiveXObject; - - /** - @property BROWSER_SCROLLBAR_WIDTH - @type Number - @static - @default null - @private - */ - BROWSER_SCROLLBAR_WIDTH = null; - rAF = window.requestAnimationFrame; - cAF = window.cancelAnimationFrame; - _elementStyle = document.createElement('div').style; - _vendor = (function() { - var i, transform, vendor, vendors, _i, _len; - vendors = ['t', 'webkitT', 'MozT', 'msT', 'OT']; - for (i = _i = 0, _len = vendors.length; _i < _len; i = ++_i) { - vendor = vendors[i]; - transform = vendors[i] + 'ransform'; - if (transform in _elementStyle) { - return vendors[i].substr(0, vendors[i].length - 1); - } - } - return false; - })(); - _prefixStyle = function(style) { - if (_vendor === false) { - return false; - } - if (_vendor === '') { - return style; - } - return _vendor + style.charAt(0).toUpperCase() + style.substr(1); - }; - transform = _prefixStyle('transform'); - hasTransform = transform !== false; - - /** - Returns browser's native scrollbar width - @method getBrowserScrollbarWidth - @return {Number} the scrollbar width in pixels - @static - @private - */ - getBrowserScrollbarWidth = function() { - var outer, outerStyle, scrollbarWidth; - outer = document.createElement('div'); - outerStyle = outer.style; - outerStyle.position = 'absolute'; - outerStyle.width = '100px'; - outerStyle.height = '100px'; - outerStyle.overflow = SCROLL; - outerStyle.top = '-9999px'; - document.body.appendChild(outer); - scrollbarWidth = outer.offsetWidth - outer.clientWidth; - document.body.removeChild(outer); - return scrollbarWidth; - }; - isFFWithBuggyScrollbar = function() { - var isOSXFF, ua, version; - ua = window.navigator.userAgent; - isOSXFF = /(?=.+Mac OS X)(?=.+Firefox)/.test(ua); - if (!isOSXFF) { - return false; - } - version = /Firefox\/\d{2}\./.exec(ua); - if (version) { - version = version[0].replace(/\D+/g, ''); - } - return isOSXFF && +version > 23; - }; - - /** - @class NanoScroll - @param element {HTMLElement|Node} the main element - @param options {Object} nanoScroller's options - @constructor - */ - NanoScroll = (function() { - function NanoScroll(el, options) { - this.el = el; - this.options = options; - BROWSER_SCROLLBAR_WIDTH || (BROWSER_SCROLLBAR_WIDTH = getBrowserScrollbarWidth()); - this.$el = $(this.el); - this.doc = $(this.options.documentContext || document); - this.win = $(this.options.windowContext || window); - this.body = this.doc.find('body'); - this.$content = this.$el.children("." + options.contentClass); - this.$content.attr('tabindex', this.options.tabIndex || 0); - this.content = this.$content[0]; - this.previousPosition = 0; - if (this.options.iOSNativeScrolling && (this.el.style.WebkitOverflowScrolling != null)) { - this.nativeScrolling(); - } else { - this.generate(); - } - this.createEvents(); - this.addEvents(); - this.reset(); - } - - - /** - Prevents the rest of the page being scrolled - when user scrolls the `.nano-content` element. - @method preventScrolling - @param event {Event} - @param direction {String} Scroll direction (up or down) - @private - */ - - NanoScroll.prototype.preventScrolling = function(e, direction) { - if (!this.isActive) { - return; - } - if (e.type === DOMSCROLL) { - if (direction === DOWN && e.originalEvent.detail > 0 || direction === UP && e.originalEvent.detail < 0) { - e.preventDefault(); - } - } else if (e.type === MOUSEWHEEL) { - if (!e.originalEvent || !e.originalEvent.wheelDelta) { - return; - } - if (direction === DOWN && e.originalEvent.wheelDelta < 0 || direction === UP && e.originalEvent.wheelDelta > 0) { - e.preventDefault(); - } - } - }; - - - /** - Enable iOS native scrolling - @method nativeScrolling - @private - */ - - NanoScroll.prototype.nativeScrolling = function() { - this.$content.css({ - WebkitOverflowScrolling: 'touch' - }); - this.iOSNativeScrolling = true; - this.isActive = true; - }; - - - /** - Updates those nanoScroller properties that - are related to current scrollbar position. - @method updateScrollValues - @private - */ - - NanoScroll.prototype.updateScrollValues = function() { - var content, direction; - content = this.content; - this.maxScrollTop = content.scrollHeight - content.clientHeight; - this.prevScrollTop = this.contentScrollTop || 0; - this.contentScrollTop = content.scrollTop; - direction = this.contentScrollTop > this.previousPosition ? "down" : this.contentScrollTop < this.previousPosition ? "up" : "same"; - this.previousPosition = this.contentScrollTop; - if (direction !== "same") { - this.$el.trigger('update', { - position: this.contentScrollTop, - maximum: this.maxScrollTop, - direction: direction - }); - } - if (!this.iOSNativeScrolling) { - this.maxSliderTop = this.paneHeight - this.sliderHeight; - this.sliderTop = this.maxScrollTop === 0 ? 0 : this.contentScrollTop * this.maxSliderTop / this.maxScrollTop; - } - }; - - - /** - Updates CSS styles for current scroll position. - Uses CSS 2d transfroms and `window.requestAnimationFrame` if available. - @method setOnScrollStyles - @private - */ - - NanoScroll.prototype.setOnScrollStyles = function() { - var cssValue; - if (hasTransform) { - cssValue = {}; - cssValue[transform] = "translate(0, " + this.sliderTop + "px)"; - } else { - cssValue = { - top: this.sliderTop - }; - } - if (rAF) { - if (cAF && this.scrollRAF) { - cAF(this.scrollRAF); - } - this.scrollRAF = rAF((function(_this) { - return function() { - _this.scrollRAF = null; - return _this.slider.css(cssValue); - }; - })(this)); - } else { - this.slider.css(cssValue); - } - }; - - - /** - Creates event related methods - @method createEvents - @private - */ - - NanoScroll.prototype.createEvents = function() { - this.events = { - down: (function(_this) { - return function(e) { - _this.isBeingDragged = true; - _this.offsetY = e.pageY - _this.slider.offset().top; - if (!_this.slider.is(e.target)) { - _this.offsetY = 0; - } - _this.pane.addClass('active'); - _this.doc.bind(MOUSEMOVE, _this.events[DRAG]).bind(MOUSEUP, _this.events[UP]); - _this.body.bind(MOUSEENTER, _this.events[ENTER]); - return false; - }; - })(this), - drag: (function(_this) { - return function(e) { - _this.sliderY = e.pageY - _this.$el.offset().top - _this.paneTop - (_this.offsetY || _this.sliderHeight * 0.5); - _this.scroll(); - if (_this.contentScrollTop >= _this.maxScrollTop && _this.prevScrollTop !== _this.maxScrollTop) { - _this.$el.trigger('scrollend'); - } else if (_this.contentScrollTop === 0 && _this.prevScrollTop !== 0) { - _this.$el.trigger('scrolltop'); - } - return false; - }; - })(this), - up: (function(_this) { - return function(e) { - _this.isBeingDragged = false; - _this.pane.removeClass('active'); - _this.doc.unbind(MOUSEMOVE, _this.events[DRAG]).unbind(MOUSEUP, _this.events[UP]); - _this.body.unbind(MOUSEENTER, _this.events[ENTER]); - return false; - }; - })(this), - resize: (function(_this) { - return function(e) { - _this.reset(); - }; - })(this), - panedown: (function(_this) { - return function(e) { - _this.sliderY = (e.offsetY || e.originalEvent.layerY) - (_this.sliderHeight * 0.5); - _this.scroll(); - _this.events.down(e); - return false; - }; - })(this), - scroll: (function(_this) { - return function(e) { - _this.updateScrollValues(); - if (_this.isBeingDragged) { - return; - } - if (!_this.iOSNativeScrolling) { - _this.sliderY = _this.sliderTop; - _this.setOnScrollStyles(); - } - if (e == null) { - return; - } - if (_this.contentScrollTop >= _this.maxScrollTop) { - if (_this.options.preventPageScrolling) { - _this.preventScrolling(e, DOWN); - } - if (_this.prevScrollTop !== _this.maxScrollTop) { - _this.$el.trigger('scrollend'); - } - } else if (_this.contentScrollTop === 0) { - if (_this.options.preventPageScrolling) { - _this.preventScrolling(e, UP); - } - if (_this.prevScrollTop !== 0) { - _this.$el.trigger('scrolltop'); - } - } - }; - })(this), - wheel: (function(_this) { - return function(e) { - var delta; - if (e == null) { - return; - } - delta = e.delta || e.wheelDelta || (e.originalEvent && e.originalEvent.wheelDelta) || -e.detail || (e.originalEvent && -e.originalEvent.detail); - if (delta) { - _this.sliderY += -delta / 3; - } - _this.scroll(); - return false; - }; - })(this), - enter: (function(_this) { - return function(e) { - var _ref; - if (!_this.isBeingDragged) { - return; - } - if ((e.buttons || e.which) !== 1) { - return (_ref = _this.events)[UP].apply(_ref, arguments); - } - }; - })(this) - }; - }; - - - /** - Adds event listeners with jQuery. - @method addEvents - @private - */ - - NanoScroll.prototype.addEvents = function() { - var events; - this.removeEvents(); - events = this.events; - if (!this.options.disableResize) { - this.win.bind(RESIZE, events[RESIZE]); - } - if (!this.iOSNativeScrolling) { - this.slider.bind(MOUSEDOWN, events[DOWN]); - this.pane.bind(MOUSEDOWN, events[PANEDOWN]).bind("" + MOUSEWHEEL + " " + DOMSCROLL, events[WHEEL]); - } - this.$content.bind("" + SCROLL + " " + MOUSEWHEEL + " " + DOMSCROLL + " " + TOUCHMOVE, events[SCROLL]); - }; - - - /** - Removes event listeners with jQuery. - @method removeEvents - @private - */ - - NanoScroll.prototype.removeEvents = function() { - var events; - events = this.events; - this.win.unbind(RESIZE, events[RESIZE]); - if (!this.iOSNativeScrolling) { - this.slider.unbind(); - this.pane.unbind(); - } - this.$content.unbind("" + SCROLL + " " + MOUSEWHEEL + " " + DOMSCROLL + " " + TOUCHMOVE, events[SCROLL]); - }; - - - /** - Generates nanoScroller's scrollbar and elements for it. - @method generate - @chainable - @private - */ - - NanoScroll.prototype.generate = function() { - var contentClass, cssRule, currentPadding, options, pane, paneClass, sliderClass; - options = this.options; - paneClass = options.paneClass, sliderClass = options.sliderClass, contentClass = options.contentClass; - if (!(pane = this.$el.children("." + paneClass)).length && !pane.children("." + sliderClass).length) { - this.$el.append("