Skip to content
Browse files

- add ender support!

- create example page
- set proper version
- make note in README on Ender support
  • Loading branch information...
1 parent 8ccfc24 commit 20666ca2d5fba79206818c73539c5de7050efccd @ded ded committed Sep 13, 2011
Showing with 1,828 additions and 0 deletions.
  1. +1 −0 .gitignore
  2. +11 −0 README.md
  3. +1,602 −0 examples/ender/ender.js
  4. +27 −0 examples/ender/ender.min.js
  5. +166 −0 examples/ender/index.html
  6. +14 −0 package.json
  7. +7 −0 src/ender.js
View
1 .gitignore
@@ -1,2 +1,3 @@
.DS_Store
dist/*.js
+node_modules
View
11 README.md
@@ -3,6 +3,17 @@ iScroll v4.1.9 - 2011-08-03
The overflow:scroll for mobile webkit. Project started because webkit for iPhone does not provide a native way to scroll content inside a fixed size (width/height) div. So basically it was impossible to have a fixed header/footer and a scrolling central area. Until now. Read more at [cubiq.org](http://cubiq.org).
+## Ender support
+Using [Ender](http://ender.no.de), add it to your existing build
+
+ $ ender add iscroll
+
+Use it like this:
+
+``` js
+var myScroll = $('#doc').iScroll(options)
+```
+
## Credits and Special thanks
iScroll is evolving thank to the help of all those who sent suggestions, bug reports and ideas on [github](https://github.com/cubiq/iscroll), my [blog](http://cubiq.org) and [googlecode](http://code.google.com/p/iscroll-js/). This is by no means the work of a sole man.
View
1,602 examples/ender/ender.js
@@ -0,0 +1,1602 @@
+/*!
+ * =============================================================
+ * Ender: open module JavaScript framework (https://ender.no.de)
+ * Build: ender build qwery domready ../../
+ * =============================================================
+ */
+
+/*!
+ * Ender-JS: open module JavaScript framework (client-lib)
+ * copyright Dustin Diaz & Jacob Thornton 2011 (@ded @fat)
+ * https://ender.no.de
+ * License MIT
+ */
+!function (context) {
+
+ // a global object for node.js module compatiblity
+ // ============================================
+
+ context['global'] = context;
+
+ // Implements simple module system
+ // losely based on CommonJS Modules spec v1.1.1
+ // ============================================
+
+ var modules = {};
+
+ function require (identifier) {
+ var module = modules[identifier] || window[identifier];
+ if (!module) throw new Error("Requested module '" + identifier + "' has not been defined.");
+ return module;
+ }
+
+ function provide (name, what) {
+ return modules[name] = what;
+ }
+
+ context['provide'] = provide;
+ context['require'] = require;
+
+ // Implements Ender's $ global access object
+ // =========================================
+
+ function aug(o, o2) {
+ for (var k in o2) {
+ k != 'noConflict' && k != '_VERSION' && (o[k] = o2[k]);
+ }
+ return o;
+ }
+
+ function boosh(s, r, els) {
+ // string || node || nodelist || window
+ if (ender._select && (typeof s == 'string' || s.nodeName || s.length && 'item' in s || s == window)) {
+ els = ender._select(s, r);
+ els.selector = s;
+ } else {
+ els = isFinite(s.length) ? s : [s];
+ }
+ return aug(els, boosh);
+ }
+
+ function ender(s, r) {
+ return boosh(s, r);
+ }
+
+ aug(ender, {
+ _VERSION: '0.2.5',
+ ender: function (o, chain) {
+ aug(chain ? boosh : ender, o);
+ },
+ fn: context.$ && context.$.fn || {} // for easy compat to jQuery plugins
+ });
+
+ aug(boosh, {
+ forEach: function (fn, scope, i) {
+ // opt out of native forEach so we can intentionally call our own scope
+ // defaulting to the current item and be able to return self
+ for (i = 0, l = this.length; i < l; ++i) {
+ i in this && fn.call(scope || this[i], this[i], i, this);
+ }
+ // return self for chaining
+ return this;
+ },
+ $: ender // handy reference to self
+ });
+
+ var old = context.$;
+ ender.noConflict = function () {
+ context.$ = old;
+ return this;
+ };
+
+ (typeof module !== 'undefined') && module.exports && (module.exports = ender);
+ // use subscript notation as extern for Closure compilation
+ context['ender'] = context['$'] = context['ender'] || ender;
+
+}(this);
+
+!function () {
+
+ var module = { exports: {} }, exports = module.exports;
+
+ /*!
+ * Qwery - A Blazing Fast query selector engine
+ * https://github.com/ded/qwery
+ * copyright Dustin Diaz & Jacob Thornton 2011
+ * MIT License
+ */
+
+ !function (name, definition) {
+ if (typeof define == 'function') define(definition)
+ else if (typeof module != 'undefined') module.exports = definition()
+ else this[name] = definition()
+ }('qwery', function () {
+ var context = this
+ , doc = document
+ , c, i, j, k, l, m, o, p, r, v
+ , el, node, found, classes, item, items, token
+ , html = doc.documentElement
+ , id = /#([\w\-]+)/
+ , clas = /\.[\w\-]+/g
+ , idOnly = /^#([\w\-]+$)/
+ , classOnly = /^\.([\w\-]+)$/
+ , tagOnly = /^([\w\-]+)$/
+ , tagAndOrClass = /^([\w]+)?\.([\w\-]+)$/
+ , normalizr = /\s*([\s\+\~>])\s*/g
+ , splitters = /[\s\>\+\~]/
+ , splittersMore = /(?![\s\w\-\/\?\&\=\:\.\(\)\!,@#%<>\{\}\$\*\^'"]*\]|[\s\w\+\-]*\))/
+ , specialChars = /([.*+?\^=!:${}()|\[\]\/\\])/g
+ , simple = /^([a-z0-9]+)?(?:([\.\#]+[\w\-\.#]+)?)/
+ , attr = /\[([\w\-]+)(?:([\|\^\$\*\~]?\=)['"]?([ \w\-\/\?\&\=\:\.\(\)\!,@#%<>\{\}\$\*\^]+)["']?)?\]/
+ , pseudo = /:([\w\-]+)(\(['"]?([\s\w\+\-]+)['"]?\))?/
+ , dividers = new RegExp('(' + splitters.source + ')' + splittersMore.source, 'g')
+ , tokenizr = new RegExp(splitters.source + splittersMore.source)
+ , chunker = new RegExp(simple.source + '(' + attr.source + ')?' + '(' + pseudo.source + ')?')
+ , walker = {
+ ' ': function (node) {
+ return node && node !== html && node.parentNode
+ }
+ , '>': function (node, contestant) {
+ return node && node.parentNode == contestant.parentNode && node.parentNode;
+ }
+ , '~': function (node) {
+ return node && node.previousSibling;
+ }
+ , '+': function (node, contestant, p1, p2) {
+ if (!node) {
+ return false;
+ }
+ p1 = previous(node);
+ p2 = previous(contestant);
+ return p1 && p2 && p1 == p2 && p1;
+ }
+ }
+ function cache() {
+ this.c = {}
+ }
+ cache.prototype = {
+ g: function (k) {
+ return this.c[k] || undefined
+ }
+ , s: function (k, v) {
+ this.c[k] = v
+ return v
+ }
+ }
+
+ var classCache = new cache()
+ , cleanCache = new cache()
+ , attrCache = new cache()
+ , tokenCache = new cache()
+
+ function flatten(ar) {
+ r = []
+ for (i = 0, l = ar.length; i < l; i++) {
+ if (arrayLike(ar[i])) {
+ r = r.concat(ar[i])
+ } else {
+ r.push(ar[i])
+ }
+ }
+ return r
+ }
+
+ function previous(n) {
+ while (n = n.previousSibling) {
+ if (n.nodeType == 1) {
+ break;
+ }
+ }
+ return n
+ }
+
+ function q(query) {
+ return query.match(chunker)
+ }
+
+ // this next method expect at most these args
+ // given => div.hello[title="world"]:foo('bar')
+
+ // div.hello[title="world"]:foo('bar'), div, .hello, [title="world"], title, =, world, :foo('bar'), foo, ('bar'), bar]
+
+ function interpret(whole, tag, idsAndClasses, wholeAttribute, attribute, qualifier, value, wholePseudo, pseudo, wholePseudoVal, pseudoVal) {
+ var m, c, k;
+ if (tag && this.tagName.toLowerCase() !== tag) {
+ return false
+ }
+ if (idsAndClasses && (m = idsAndClasses.match(id)) && m[1] !== this.id) {
+ return false
+ }
+ if (idsAndClasses && (classes = idsAndClasses.match(clas))) {
+ for (i = classes.length; i--;) {
+ c = classes[i].slice(1)
+ if (!(classCache.g(c) || classCache.s(c, new RegExp('(^|\\s+)' + c + '(\\s+|$)'))).test(this.className)) {
+ return false
+ }
+ }
+ }
+ if (pseudo && qwery.pseudos[pseudo] && !qwery.pseudos[pseudo](this, pseudoVal)) {
+ return false
+ }
+ if (wholeAttribute && !value) {
+ o = this.attributes
+ for (k in o) {
+ if (Object.prototype.hasOwnProperty.call(o, k) && (o[k].name || k) == attribute) {
+ return this
+ }
+ }
+ }
+ if (wholeAttribute && !checkAttr(qualifier, this.getAttribute(attribute) || '', value)) {
+ return false
+ }
+ return this
+ }
+
+ function clean(s) {
+ return cleanCache.g(s) || cleanCache.s(s, s.replace(specialChars, '\\$1'))
+ }
+
+ function checkAttr(qualify, actual, val) {
+ switch (qualify) {
+ case '=':
+ return actual == val
+ case '^=':
+ return actual.match(attrCache.g('^=' + val) || attrCache.s('^=' + val, new RegExp('^' + clean(val))))
+ case '$=':
+ return actual.match(attrCache.g('$=' + val) || attrCache.s('$=' + val, new RegExp(clean(val) + '$')))
+ case '*=':
+ return actual.match(attrCache.g(val) || attrCache.s(val, new RegExp(clean(val))))
+ case '~=':
+ return actual.match(attrCache.g('~=' + val) || attrCache.s('~=' + val, new RegExp('(?:^|\\s+)' + clean(val) + '(?:\\s+|$)')))
+ case '|=':
+ return actual.match(attrCache.g('|=' + val) || attrCache.s('|=' + val, new RegExp('^' + clean(val) + '(-|$)')))
+ }
+ return 0
+ }
+
+ function _qwery(selector) {
+ var r = [], ret = [], i, j = 0, k, l, m, p, token, tag, els, root, intr, item, children
+ , tokens = tokenCache.g(selector) || tokenCache.s(selector, selector.split(tokenizr))
+ , dividedTokens = selector.match(dividers), dividedToken
+ tokens = tokens.slice(0) // this makes a copy of the array so the cached original is not effected
+
+ if (!tokens.length) return r
+
+ token = tokens.pop()
+ root = tokens.length && (m = tokens[tokens.length - 1].match(idOnly)) ? doc.getElementById(m[1]) : doc
+
+ if (!root) return r
+
+ intr = q(token)
+ els = dividedTokens && /^[+~]$/.test(dividedTokens[dividedTokens.length - 1]) ? function (r) {
+ while (root = root.nextSibling) {
+ root.nodeType == 1 && (intr[1] ? intr[1] == root.tagName.toLowerCase() : 1) && r.push(root)
+ }
+ return r
+ }([]) :
+ root.getElementsByTagName(intr[1] || '*')
+ for (i = 0, l = els.length; i < l; i++) if (item = interpret.apply(els[i], intr)) r[j++] = item
+ if (!tokens.length) return r
+
+ // loop through all descendent tokens
+ for (j = 0, l = r.length, k = 0; j < l; j++) {
+ p = r[j]
+ // loop through each token backwards crawling up tree
+ for (i = tokens.length; i--;) {
+ // loop through parent nodes
+ while (p = walker[dividedTokens[i]](p, r[j])) {
+ if (found = interpret.apply(p, q(tokens[i]))) break;
+ }
+ }
+ found && (ret[k++] = r[j])
+ }
+ return ret
+ }
+
+ function isNode(el) {
+ return (el && el.nodeType && (el.nodeType == 1 || el.nodeType == 9))
+ }
+
+ function uniq(ar) {
+ var a = [], i, j;
+ label:
+ for (i = 0; i < ar.length; i++) {
+ for (j = 0; j < a.length; j++) {
+ if (a[j] == ar[i]) {
+ continue label;
+ }
+ }
+ a[a.length] = ar[i]
+ }
+ return a
+ }
+
+ function arrayLike(o) {
+ return (typeof o === 'object' && isFinite(o.length))
+ }
+
+ function normalizeRoot(root) {
+ if (!root) return doc
+ if (typeof root == 'string') return qwery(root)[0]
+ if (arrayLike(root)) return root[0]
+ return root
+ }
+
+ function qwery(selector, _root) {
+ var root = normalizeRoot(_root)
+
+ if (!root || !selector) return []
+ if (selector === window || isNode(selector)) {
+ return !_root || (selector !== window && isNode(root) && isAncestor(selector, root)) ? [selector] : []
+ }
+ if (selector && arrayLike(selector)) return flatten(selector)
+ if (m = selector.match(idOnly)) return (el = doc.getElementById(m[1])) ? [el] : []
+ if (m = selector.match(tagOnly)) return flatten(root.getElementsByTagName(m[1]))
+ return select(selector, root)
+ }
+
+ var isAncestor = 'compareDocumentPosition' in html ?
+ function (element, container) {
+ return (container.compareDocumentPosition(element) & 16) == 16;
+ } : 'contains' in html ?
+ function (element, container) {
+ container = container == doc || container == window ? html : container
+ return container !== element && container.contains(element)
+ } :
+ function (element, container) {
+ while (element = element.parentNode) if (element === container) return 1
+ return 0
+ },
+
+ supportsCSS3 = function () {
+ if (!doc.querySelector || !doc.querySelectorAll) return false
+
+ try { return (doc.querySelectorAll(':nth-of-type(1)').length > 0) }
+ catch (e) { return false }
+ }(),
+
+ select = supportsCSS3 ?
+ function (selector, root) {
+ if (doc.getElementsByClassName && (m = selector.match(classOnly))) {
+ return flatten((root).getElementsByClassName(m[1]));
+ }
+ return flatten((root).querySelectorAll(selector))
+ } :
+ function (selector, root) {
+ selector = selector.replace(normalizr, '$1')
+ var result = [], element, collection, collections = [], i
+ if (m = selector.match(tagAndOrClass)) {
+ items = root.getElementsByTagName(m[1] || '*');
+ r = classCache.g(m[2]) || classCache.s(m[2], new RegExp('(^|\\s+)' + m[2] + '(\\s+|$)'));
+ for (i = 0, l = items.length, j = 0; i < l; i++) {
+ r.test(items[i].className) && (result[j++] = items[i]);
+ }
+ return result
+ }
+ for (i = 0, items = selector.split(','), l = items.length; i < l; i++) {
+ collections[i] = _qwery(items[i])
+ }
+ for (i = 0, l = collections.length; i < l && (collection = collections[i]); i++) {
+ var ret = collection
+ if (root !== doc) {
+ ret = []
+ for (j = 0, m = collection.length; j < m && (element = collection[j]); j++) {
+ // make sure element is a descendent of root
+ isAncestor(element, root) && ret.push(element)
+ }
+ }
+ result = result.concat(ret)
+ }
+ return uniq(result)
+ }
+
+ qwery.uniq = uniq
+ qwery.pseudos = {}
+
+ var old = context.qwery
+ qwery.noConflict = function () {
+ context.qwery = old
+ return this
+ }
+
+ return qwery
+ })
+
+ provide("qwery", module.exports);
+
+ !function (doc, $) {
+ var q = require('qwery')
+ , table = 'table'
+ , nodeMap = {
+ thead: table
+ , tbody: table
+ , tfoot: table
+ , tr: 'tbody'
+ , th: 'tr'
+ , td: 'tr'
+ , fieldset: 'form'
+ , option: 'select'
+ }
+ function create(node, root) {
+ var tag = /^<([^\s>]+)/.exec(node)[1]
+ , el = (root || doc).createElement(nodeMap[tag] || 'div'), els = []
+ el.innerHTML = node
+ var nodes = el.childNodes
+ el = el.firstChild
+ els.push(el)
+ while (el = el.nextSibling) (el.nodeType == 1) && els.push(el)
+ return els
+ }
+
+ $._select = function (s, r) {
+ return /^\s*</.test(s) ? create(s, r) : q(s, r)
+ }
+
+ $.pseudos = q.pseudos
+
+ $.ender({
+ find: function (s) {
+ var r = [], i, l, j, k, els
+ for (i = 0, l = this.length; i < l; i++) {
+ els = q(s, this[i])
+ for (j = 0, k = els.length; j < k; j++) r.push(els[j])
+ }
+ return $(q.uniq(r))
+ }
+ , and: function (s) {
+ var plus = $(s)
+ for (var i = this.length, j = 0, l = this.length + plus.length; i < l; i++, j++) {
+ this[i] = plus[j]
+ }
+ return this
+ }
+ }, true)
+ }(document, ender);
+
+
+}();
+
+!function () {
+
+ var module = { exports: {} }, exports = module.exports;
+
+ !function (context, doc) {
+ var fns = [], ready, ol, fn, f = false,
+ testEl = doc.documentElement,
+ hack = testEl.doScroll,
+ domContentLoaded = 'DOMContentLoaded',
+ addEventListener = 'addEventListener',
+ onreadystatechange = 'onreadystatechange',
+ loaded = /^loade|c/.test(doc.readyState);
+
+ function flush(i) {
+ loaded = 1;
+ while (i = fns.shift()) { i() }
+ }
+ doc[addEventListener] && doc[addEventListener](domContentLoaded, fn = function () {
+ doc.removeEventListener(domContentLoaded, fn, f);
+ flush();
+ }, f);
+
+
+ hack && doc.attachEvent(onreadystatechange, (ol = function () {
+ if (/^c/.test(doc.readyState)) {
+ doc.detachEvent(onreadystatechange, ol);
+ flush();
+ }
+ }));
+
+ ready = hack ?
+ function (fn) {
+ self != top ?
+ loaded ? fn() : fns.push(fn) :
+ function () {
+ try {
+ testEl.doScroll('left');
+ } catch (e) {
+ return setTimeout(function() { ready(fn) }, 50);
+ }
+ fn();
+ }()
+ } :
+ function (fn) {
+ loaded ? fn() : fns.push(fn);
+ };
+
+ (typeof module !== 'undefined') ?
+ (module.exports = ready) :
+ (context['domReady'] = ready);
+
+ }(this, document);
+
+
+ provide("domready", module.exports);
+
+ !function ($) {
+ var ready = require('domready')
+ $.ender({domReady: ready})
+ $.ender({
+ ready: function (f) {
+ ready(f)
+ return this
+ }
+ }, true)
+ }(ender);
+
+}();
+
+!function () {
+
+ var module = { exports: {} }, exports = module.exports;
+
+ /*!
+ * iScroll v4.1.9 ~ Copyright (c) 2011 Matteo Spinelli, http://cubiq.org
+ * Released under MIT license, http://cubiq.org/license
+ */
+
+ (function(){
+ var m = Math,
+ vendor = (/webkit/i).test(navigator.appVersion) ? 'webkit' :
+ (/firefox/i).test(navigator.userAgent) ? 'Moz' :
+ 'opera' in window ? 'O' : '',
+
+ // Browser capabilities
+ has3d = 'WebKitCSSMatrix' in window && 'm11' in new WebKitCSSMatrix(),
+ hasTouch = 'ontouchstart' in window,
+ hasTransform = vendor + 'Transform' in document.documentElement.style,
+ isAndroid = (/android/gi).test(navigator.appVersion),
+ isIDevice = (/iphone|ipad/gi).test(navigator.appVersion),
+ isPlaybook = (/playbook/gi).test(navigator.appVersion),
+ hasTransitionEnd = isIDevice || isPlaybook,
+ nextFrame = (function() {
+ return window.requestAnimationFrame
+ || window.webkitRequestAnimationFrame
+ || window.mozRequestAnimationFrame
+ || window.oRequestAnimationFrame
+ || window.msRequestAnimationFrame
+ || function(callback) { return setTimeout(callback, 1); }
+ })(),
+ cancelFrame = (function () {
+ return window.cancelRequestAnimationFrame
+ || window.webkitCancelRequestAnimationFrame
+ || window.mozCancelRequestAnimationFrame
+ || window.oCancelRequestAnimationFrame
+ || window.msCancelRequestAnimationFrame
+ || clearTimeout
+ })(),
+
+ // Events
+ RESIZE_EV = 'onorientationchange' in window ? 'orientationchange' : 'resize',
+ START_EV = hasTouch ? 'touchstart' : 'mousedown',
+ MOVE_EV = hasTouch ? 'touchmove' : 'mousemove',
+ END_EV = hasTouch ? 'touchend' : 'mouseup',
+ CANCEL_EV = hasTouch ? 'touchcancel' : 'mouseup',
+ WHEEL_EV = vendor == 'Moz' ? 'DOMMouseScroll' : 'mousewheel',
+
+ // Helpers
+ trnOpen = 'translate' + (has3d ? '3d(' : '('),
+ trnClose = has3d ? ',0)' : ')',
+
+ // Constructor
+ iScroll = function (el, options) {
+ var that = this,
+ doc = document,
+ i;
+
+ that.wrapper = typeof el == 'object' ? el : doc.getElementById(el);
+ that.wrapper.style.overflow = 'hidden';
+ that.scroller = that.wrapper.children[0];
+
+ // Default options
+ that.options = {
+ hScroll: true,
+ vScroll: true,
+ x: 0,
+ y: 0,
+ bounce: true,
+ bounceLock: false,
+ momentum: true,
+ lockDirection: true,
+ useTransform: true,
+ useTransition: false,
+ topOffset: 0,
+ checkDOMChanges: false, // Experimental
+
+ // Scrollbar
+ hScrollbar: true,
+ vScrollbar: true,
+ fixedScrollbar: isAndroid,
+ hideScrollbar: isIDevice,
+ fadeScrollbar: isIDevice && has3d,
+ scrollbarClass: '',
+
+ // Zoom
+ zoom: false,
+ zoomMin: 1,
+ zoomMax: 4,
+ doubleTapZoom: 2,
+ wheelAction: 'scroll',
+
+ // Snap
+ snap: false,
+ snapThreshold: 1,
+
+ // Events
+ onRefresh: null,
+ onBeforeScrollStart: function (e) { e.preventDefault(); },
+ onScrollStart: null,
+ onBeforeScrollMove: null,
+ onScrollMove: null,
+ onBeforeScrollEnd: null,
+ onScrollEnd: null,
+ onTouchEnd: null,
+ onDestroy: null,
+ onZoomStart: null,
+ onZoom: null,
+ onZoomEnd: null
+ };
+
+ // User defined options
+ for (i in options) that.options[i] = options[i];
+
+ // Set starting position
+ that.x = that.options.x;
+ that.y = that.options.y;
+
+ // Normalize options
+ that.options.useTransform = hasTransform ? that.options.useTransform : false;
+ that.options.hScrollbar = that.options.hScroll && that.options.hScrollbar;
+ that.options.vScrollbar = that.options.vScroll && that.options.vScrollbar;
+ that.options.zoom = that.options.useTransform && that.options.zoom;
+ that.options.useTransition = hasTransitionEnd && that.options.useTransition;
+
+ // Set some default styles
+ that.scroller.style[vendor + 'TransitionProperty'] = that.options.useTransform ? '-' + vendor.toLowerCase() + '-transform' : 'top left';
+ that.scroller.style[vendor + 'TransitionDuration'] = '0';
+ that.scroller.style[vendor + 'TransformOrigin'] = '0 0';
+ if (that.options.useTransition) that.scroller.style[vendor + 'TransitionTimingFunction'] = 'cubic-bezier(0.33,0.66,0.66,1)';
+
+ if (that.options.useTransform) that.scroller.style[vendor + 'Transform'] = trnOpen + that.x + 'px,' + that.y + 'px' + trnClose;
+ else that.scroller.style.cssText += ';position:absolute;top:' + that.y + 'px;left:' + that.x + 'px';
+
+ if (that.options.useTransition) that.options.fixedScrollbar = true;
+
+ that.refresh();
+
+ that._bind(RESIZE_EV, window);
+ that._bind(START_EV);
+ if (!hasTouch) {
+ that._bind('mouseout', that.wrapper);
+ that._bind(WHEEL_EV);
+ }
+
+ if (that.options.checkDOMChanges) that.checkDOMTime = setInterval(function () {
+ that._checkDOMChanges();
+ }, 500);
+ };
+
+ // Prototype
+ iScroll.prototype = {
+ enabled: true,
+ x: 0,
+ y: 0,
+ steps: [],
+ scale: 1,
+ currPageX: 0, currPageY: 0,
+ pagesX: [], pagesY: [],
+ aniTime: null,
+ wheelZoomCount: 0,
+
+ handleEvent: function (e) {
+ var that = this;
+ switch(e.type) {
+ case START_EV:
+ if (!hasTouch && e.button !== 0) return;
+ that._start(e);
+ break;
+ case MOVE_EV: that._move(e); break;
+ case END_EV:
+ case CANCEL_EV: that._end(e); break;
+ case RESIZE_EV: that._resize(); break;
+ case WHEEL_EV: that._wheel(e); break;
+ case 'mouseout': that._mouseout(e); break;
+ case 'webkitTransitionEnd': that._transitionEnd(e); break;
+ }
+ },
+
+ _checkDOMChanges: function () {
+ if (this.moved || this.zoomed || this.animating ||
+ (this.scrollerW == this.scroller.offsetWidth * this.scale && this.scrollerH == this.scroller.offsetHeight * this.scale)) return;
+
+ this.refresh();
+ },
+
+ _scrollbar: function (dir) {
+ var that = this,
+ doc = document,
+ bar;
+
+ if (!that[dir + 'Scrollbar']) {
+ if (that[dir + 'ScrollbarWrapper']) {
+ if (hasTransform) that[dir + 'ScrollbarIndicator'].style[vendor + 'Transform'] = '';
+ that[dir + 'ScrollbarWrapper'].parentNode.removeChild(that[dir + 'ScrollbarWrapper']);
+ that[dir + 'ScrollbarWrapper'] = null;
+ that[dir + 'ScrollbarIndicator'] = null;
+ }
+
+ return;
+ }
+
+ if (!that[dir + 'ScrollbarWrapper']) {
+ // Create the scrollbar wrapper
+ bar = doc.createElement('div');
+
+ if (that.options.scrollbarClass) bar.className = that.options.scrollbarClass + dir.toUpperCase();
+ else bar.style.cssText = 'position:absolute;z-index:100;' + (dir == 'h' ? 'height:7px;bottom:1px;left:2px;right:' + (that.vScrollbar ? '7' : '2') + 'px' : 'width:7px;bottom:' + (that.hScrollbar ? '7' : '2') + 'px;top:2px;right:1px');
+
+ bar.style.cssText += ';pointer-events:none;-' + vendor + '-transition-property:opacity;-' + vendor + '-transition-duration:' + (that.options.fadeScrollbar ? '350ms' : '0') + ';overflow:hidden;opacity:' + (that.options.hideScrollbar ? '0' : '1');
+
+ that.wrapper.appendChild(bar);
+ that[dir + 'ScrollbarWrapper'] = bar;
+
+ // Create the scrollbar indicator
+ bar = doc.createElement('div');
+ if (!that.options.scrollbarClass) {
+ bar.style.cssText = 'position:absolute;z-index:100;background:rgba(0,0,0,0.5);border:1px solid rgba(255,255,255,0.9);-' + vendor + '-background-clip:padding-box;-' + vendor + '-box-sizing:border-box;' + (dir == 'h' ? 'height:100%' : 'width:100%') + ';-' + vendor + '-border-radius:3px;border-radius:3px';
+ }
+ bar.style.cssText += ';pointer-events:none;-' + vendor + '-transition-property:-' + vendor + '-transform;-' + vendor + '-transition-timing-function:cubic-bezier(0.33,0.66,0.66,1);-' + vendor + '-transition-duration:0;-' + vendor + '-transform:' + trnOpen + '0,0' + trnClose;
+ if (that.options.useTransition) bar.style.cssText += ';-' + vendor + '-transition-timing-function:cubic-bezier(0.33,0.66,0.66,1)';
+
+ that[dir + 'ScrollbarWrapper'].appendChild(bar);
+ that[dir + 'ScrollbarIndicator'] = bar;
+ }
+
+ if (dir == 'h') {
+ that.hScrollbarSize = that.hScrollbarWrapper.clientWidth;
+ that.hScrollbarIndicatorSize = m.max(m.round(that.hScrollbarSize * that.hScrollbarSize / that.scrollerW), 8);
+ that.hScrollbarIndicator.style.width = that.hScrollbarIndicatorSize + 'px';
+ that.hScrollbarMaxScroll = that.hScrollbarSize - that.hScrollbarIndicatorSize;
+ that.hScrollbarProp = that.hScrollbarMaxScroll / that.maxScrollX;
+ } else {
+ that.vScrollbarSize = that.vScrollbarWrapper.clientHeight;
+ that.vScrollbarIndicatorSize = m.max(m.round(that.vScrollbarSize * that.vScrollbarSize / that.scrollerH), 8);
+ that.vScrollbarIndicator.style.height = that.vScrollbarIndicatorSize + 'px';
+ that.vScrollbarMaxScroll = that.vScrollbarSize - that.vScrollbarIndicatorSize;
+ that.vScrollbarProp = that.vScrollbarMaxScroll / that.maxScrollY;
+ }
+
+ // Reset position
+ that._scrollbarPos(dir, true);
+ },
+
+ _resize: function () {
+ var that = this;
+ setTimeout(function () { that.refresh(); }, isAndroid ? 200 : 0);
+ },
+
+ _pos: function (x, y) {
+ x = this.hScroll ? x : 0;
+ y = this.vScroll ? y : 0;
+
+ if (this.options.useTransform) {
+ this.scroller.style[vendor + 'Transform'] = trnOpen + x + 'px,' + y + 'px' + trnClose + ' scale(' + this.scale + ')';
+ } else {
+ x = m.round(x);
+ y = m.round(y);
+ this.scroller.style.left = x + 'px';
+ this.scroller.style.top = y + 'px';
+ }
+
+ this.x = x;
+ this.y = y;
+
+ this._scrollbarPos('h');
+ this._scrollbarPos('v');
+ },
+
+ _scrollbarPos: function (dir, hidden) {
+ var that = this,
+ pos = dir == 'h' ? that.x : that.y,
+ size;
+
+ if (!that[dir + 'Scrollbar']) return;
+
+ pos = that[dir + 'ScrollbarProp'] * pos;
+
+ if (pos < 0) {
+ if (!that.options.fixedScrollbar) {
+ size = that[dir + 'ScrollbarIndicatorSize'] + m.round(pos * 3);
+ if (size < 8) size = 8;
+ that[dir + 'ScrollbarIndicator'].style[dir == 'h' ? 'width' : 'height'] = size + 'px';
+ }
+ pos = 0;
+ } else if (pos > that[dir + 'ScrollbarMaxScroll']) {
+ if (!that.options.fixedScrollbar) {
+ size = that[dir + 'ScrollbarIndicatorSize'] - m.round((pos - that[dir + 'ScrollbarMaxScroll']) * 3);
+ if (size < 8) size = 8;
+ that[dir + 'ScrollbarIndicator'].style[dir == 'h' ? 'width' : 'height'] = size + 'px';
+ pos = that[dir + 'ScrollbarMaxScroll'] + (that[dir + 'ScrollbarIndicatorSize'] - size);
+ } else {
+ pos = that[dir + 'ScrollbarMaxScroll'];
+ }
+ }
+
+ that[dir + 'ScrollbarWrapper'].style[vendor + 'TransitionDelay'] = '0';
+ that[dir + 'ScrollbarWrapper'].style.opacity = hidden && that.options.hideScrollbar ? '0' : '1';
+ that[dir + 'ScrollbarIndicator'].style[vendor + 'Transform'] = trnOpen + (dir == 'h' ? pos + 'px,0' : '0,' + pos + 'px') + trnClose;
+ },
+
+ _start: function (e) {
+ var that = this,
+ point = hasTouch ? e.touches[0] : e,
+ matrix, x, y,
+ c1, c2;
+
+ if (!that.enabled) return;
+
+ if (that.options.onBeforeScrollStart) that.options.onBeforeScrollStart.call(that, e);
+
+ if (that.options.useTransition || that.options.zoom) that._transitionTime(0);
+
+ that.moved = false;
+ that.animating = false;
+ that.zoomed = false;
+ that.distX = 0;
+ that.distY = 0;
+ that.absDistX = 0;
+ that.absDistY = 0;
+ that.dirX = 0;
+ that.dirY = 0;
+
+ // Gesture start
+ if (that.options.zoom && hasTouch && e.touches.length > 1) {
+ c1 = m.abs(e.touches[0].pageX-e.touches[1].pageX);
+ c2 = m.abs(e.touches[0].pageY-e.touches[1].pageY);
+ that.touchesDistStart = m.sqrt(c1 * c1 + c2 * c2);
+
+ that.originX = m.abs(e.touches[0].pageX + e.touches[1].pageX - that.wrapperOffsetLeft * 2) / 2 - that.x;
+ that.originY = m.abs(e.touches[0].pageY + e.touches[1].pageY - that.wrapperOffsetTop * 2) / 2 - that.y;
+
+ if (that.options.onZoomStart) that.options.onZoomStart.call(that, e);
+ }
+
+ if (that.options.momentum) {
+ if (that.options.useTransform) {
+ // Very lame general purpose alternative to CSSMatrix
+ matrix = getComputedStyle(that.scroller, null)[vendor + 'Transform'].replace(/[^0-9-.,]/g, '').split(',');
+ x = matrix[4] * 1;
+ y = matrix[5] * 1;
+ } else {
+ x = getComputedStyle(that.scroller, null).left.replace(/[^0-9-]/g, '') * 1;
+ y = getComputedStyle(that.scroller, null).top.replace(/[^0-9-]/g, '') * 1;
+ }
+
+ if (x != that.x || y != that.y) {
+ if (that.options.useTransition) that._unbind('webkitTransitionEnd');
+ else cancelFrame(that.aniTime);
+ that.steps = [];
+ that._pos(x, y);
+ }
+ }
+
+ that.absStartX = that.x; // Needed by snap threshold
+ that.absStartY = that.y;
+
+ that.startX = that.x;
+ that.startY = that.y;
+ that.pointX = point.pageX;
+ that.pointY = point.pageY;
+
+ that.startTime = e.timeStamp || Date.now();
+
+ if (that.options.onScrollStart) that.options.onScrollStart.call(that, e);
+
+ that._bind(MOVE_EV);
+ that._bind(END_EV);
+ that._bind(CANCEL_EV);
+ },
+
+ _move: function (e) {
+ var that = this,
+ point = hasTouch ? e.touches[0] : e,
+ deltaX = point.pageX - that.pointX,
+ deltaY = point.pageY - that.pointY,
+ newX = that.x + deltaX,
+ newY = that.y + deltaY,
+ c1, c2, scale,
+ timestamp = e.timeStamp || Date.now();
+
+ if (that.options.onBeforeScrollMove) that.options.onBeforeScrollMove.call(that, e);
+
+ // Zoom
+ if (that.options.zoom && hasTouch && e.touches.length > 1) {
+ c1 = m.abs(e.touches[0].pageX - e.touches[1].pageX);
+ c2 = m.abs(e.touches[0].pageY - e.touches[1].pageY);
+ that.touchesDist = m.sqrt(c1*c1+c2*c2);
+
+ that.zoomed = true;
+
+ scale = 1 / that.touchesDistStart * that.touchesDist * this.scale;
+
+ if (scale < that.options.zoomMin) scale = 0.5 * that.options.zoomMin * Math.pow(2.0, scale / that.options.zoomMin);
+ else if (scale > that.options.zoomMax) scale = 2.0 * that.options.zoomMax * Math.pow(0.5, that.options.zoomMax / scale);
+
+ that.lastScale = scale / this.scale;
+
+ newX = this.originX - this.originX * that.lastScale + this.x,
+ newY = this.originY - this.originY * that.lastScale + this.y;
+
+ this.scroller.style[vendor + 'Transform'] = trnOpen + newX + 'px,' + newY + 'px' + trnClose + ' scale(' + scale + ')';
+
+ if (that.options.onZoom) that.options.onZoom.call(that, e);
+ return;
+ }
+
+ that.pointX = point.pageX;
+ that.pointY = point.pageY;
+
+ // Slow down if outside of the boundaries
+ if (newX > 0 || newX < that.maxScrollX) {
+ newX = that.options.bounce ? that.x + (deltaX / 2) : newX >= 0 || that.maxScrollX >= 0 ? 0 : that.maxScrollX;
+ }
+ if (newY > that.minScrollY || newY < that.maxScrollY) {
+ newY = that.options.bounce ? that.y + (deltaY / 2) : newY >= that.minScrollY || that.maxScrollY >= 0 ? that.minScrollY : that.maxScrollY;
+ }
+
+ if (that.absDistX < 6 && that.absDistY < 6) {
+ that.distX += deltaX;
+ that.distY += deltaY;
+ that.absDistX = m.abs(that.distX);
+ that.absDistY = m.abs(that.distY);
+
+ return;
+ }
+
+ // Lock direction
+ if (that.options.lockDirection) {
+ if (that.absDistX > that.absDistY + 5) {
+ newY = that.y;
+ deltaY = 0;
+ } else if (that.absDistY > that.absDistX + 5) {
+ newX = that.x;
+ deltaX = 0;
+ }
+ }
+
+ that.moved = true;
+ that._pos(newX, newY);
+ that.dirX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0;
+ that.dirY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0;
+
+ if (timestamp - that.startTime > 300) {
+ that.startTime = timestamp;
+ that.startX = that.x;
+ that.startY = that.y;
+ }
+
+ if (that.options.onScrollMove) that.options.onScrollMove.call(that, e);
+ },
+
+ _end: function (e) {
+ if (hasTouch && e.touches.length != 0) return;
+
+ var that = this,
+ point = hasTouch ? e.changedTouches[0] : e,
+ target, ev,
+ momentumX = { dist:0, time:0 },
+ momentumY = { dist:0, time:0 },
+ duration = (e.timeStamp || Date.now()) - that.startTime,
+ newPosX = that.x,
+ newPosY = that.y,
+ distX, distY,
+ newDuration,
+ snap,
+ scale;
+
+ that._unbind(MOVE_EV);
+ that._unbind(END_EV);
+ that._unbind(CANCEL_EV);
+
+ if (that.options.onBeforeScrollEnd) that.options.onBeforeScrollEnd.call(that, e);
+
+ if (that.zoomed) {
+ scale = that.scale * that.lastScale;
+ scale = Math.max(that.options.zoomMin, scale);
+ scale = Math.min(that.options.zoomMax, scale);
+ that.lastScale = scale / that.scale;
+ that.scale = scale;
+
+ that.x = that.originX - that.originX * that.lastScale + that.x;
+ that.y = that.originY - that.originY * that.lastScale + that.y;
+
+ that.scroller.style[vendor + 'TransitionDuration'] = '200ms';
+ that.scroller.style[vendor + 'Transform'] = trnOpen + that.x + 'px,' + that.y + 'px' + trnClose + ' scale(' + that.scale + ')';
+
+ that.zoomed = false;
+ that.refresh();
+
+ if (that.options.onZoomEnd) that.options.onZoomEnd.call(that, e);
+ return;
+ }
+
+ if (!that.moved) {
+ if (hasTouch) {
+ if (that.doubleTapTimer && that.options.zoom) {
+ // Double tapped
+ clearTimeout(that.doubleTapTimer);
+ that.doubleTapTimer = null;
+ if (that.options.onZoomStart) that.options.onZoomStart.call(that, e);
+ that.zoom(that.pointX, that.pointY, that.scale == 1 ? that.options.doubleTapZoom : 1);
+ if (that.options.onZoomEnd) {
+ setTimeout(function() {
+ that.options.onZoomEnd.call(that, e);
+ }, 200); // 200 is default zoom duration
+ }
+ } else {
+ that.doubleTapTimer = setTimeout(function () {
+ that.doubleTapTimer = null;
+
+ // Find the last touched element
+ target = point.target;
+ while (target.nodeType != 1) target = target.parentNode;
+
+ if (target.tagName != 'SELECT' && target.tagName != 'INPUT' && target.tagName != 'TEXTAREA') {
+ ev = document.createEvent('MouseEvents');
+ ev.initMouseEvent('click', true, true, e.view, 1,
+ point.screenX, point.screenY, point.clientX, point.clientY,
+ e.ctrlKey, e.altKey, e.shiftKey, e.metaKey,
+ 0, null);
+ ev._fake = true;
+ target.dispatchEvent(ev);
+ }
+ }, that.options.zoom ? 250 : 0);
+ }
+ }
+
+ that._resetPos(200);
+
+ if (that.options.onTouchEnd) that.options.onTouchEnd.call(that, e);
+ return;
+ }
+
+ if (duration < 300 && that.options.momentum) {
+ momentumX = newPosX ? that._momentum(newPosX - that.startX, duration, -that.x, that.scrollerW - that.wrapperW + that.x, that.options.bounce ? that.wrapperW : 0) : momentumX;
+ momentumY = newPosY ? that._momentum(newPosY - that.startY, duration, -that.y, (that.maxScrollY < 0 ? that.scrollerH - that.wrapperH + that.y - that.minScrollY : 0), that.options.bounce ? that.wrapperH : 0) : momentumY;
+
+ newPosX = that.x + momentumX.dist;
+ newPosY = that.y + momentumY.dist;
+
+ if ((that.x > 0 && newPosX > 0) || (that.x < that.maxScrollX && newPosX < that.maxScrollX)) momentumX = { dist:0, time:0 };
+ if ((that.y > that.minScrollY && newPosY > that.minScrollY) || (that.y < that.maxScrollY && newPosY < that.maxScrollY)) momentumY = { dist:0, time:0 };
+ }
+
+ if (momentumX.dist || momentumY.dist) {
+ newDuration = m.max(m.max(momentumX.time, momentumY.time), 10);
+
+ // Do we need to snap?
+ if (that.options.snap) {
+ distX = newPosX - that.absStartX;
+ distY = newPosY - that.absStartY;
+ if (m.abs(distX) < that.options.snapThreshold && m.abs(distY) < that.options.snapThreshold) { that.scrollTo(that.absStartX, that.absStartY, 200); }
+ else {
+ snap = that._snap(newPosX, newPosY);
+ newPosX = snap.x;
+ newPosY = snap.y;
+ newDuration = m.max(snap.time, newDuration);
+ }
+ }
+
+ that.scrollTo(m.round(newPosX), m.round(newPosY), newDuration);
+
+ if (that.options.onTouchEnd) that.options.onTouchEnd.call(that, e);
+ return;
+ }
+
+ // Do we need to snap?
+ if (that.options.snap) {
+ distX = newPosX - that.absStartX;
+ distY = newPosY - that.absStartY;
+ if (m.abs(distX) < that.options.snapThreshold && m.abs(distY) < that.options.snapThreshold) that.scrollTo(that.absStartX, that.absStartY, 200);
+ else {
+ snap = that._snap(that.x, that.y);
+ if (snap.x != that.x || snap.y != that.y) that.scrollTo(snap.x, snap.y, snap.time);
+ }
+
+ if (that.options.onTouchEnd) that.options.onTouchEnd.call(that, e);
+ return;
+ }
+
+ that._resetPos(200);
+ if (that.options.onTouchEnd) that.options.onTouchEnd.call(that, e);
+ },
+
+ _resetPos: function (time) {
+ var that = this,
+ resetX = that.x >= 0 ? 0 : that.x < that.maxScrollX ? that.maxScrollX : that.x,
+ resetY = that.y >= that.minScrollY || that.maxScrollY > 0 ? that.minScrollY : that.y < that.maxScrollY ? that.maxScrollY : that.y;
+
+ if (resetX == that.x && resetY == that.y) {
+ if (that.moved) {
+ that.moved = false;
+ if (that.options.onScrollEnd) that.options.onScrollEnd.call(that); // Execute custom code on scroll end
+ }
+
+ if (that.hScrollbar && that.options.hideScrollbar) {
+ if (vendor == 'webkit') that.hScrollbarWrapper.style[vendor + 'TransitionDelay'] = '300ms';
+ that.hScrollbarWrapper.style.opacity = '0';
+ }
+ if (that.vScrollbar && that.options.hideScrollbar) {
+ if (vendor == 'webkit') that.vScrollbarWrapper.style[vendor + 'TransitionDelay'] = '300ms';
+ that.vScrollbarWrapper.style.opacity = '0';
+ }
+
+ return;
+ }
+
+ that.scrollTo(resetX, resetY, time || 0);
+ },
+
+ _wheel: function (e) {
+ var that = this,
+ wheelDeltaX, wheelDeltaY,
+ deltaX, deltaY,
+ deltaScale;
+
+ if ('wheelDeltaX' in e) {
+ wheelDeltaX = e.wheelDeltaX / 12;
+ wheelDeltaY = e.wheelDeltaY / 12;
+ } else if ('detail' in e) {
+ wheelDeltaX = wheelDeltaY = -e.detail * 3;
+ } else {
+ wheelDeltaX = wheelDeltaY = -e.wheelDelta;
+ }
+
+ if (that.options.wheelAction == 'zoom') {
+ deltaScale = that.scale * Math.pow(2, 1/3 * (wheelDeltaY ? wheelDeltaY / Math.abs(wheelDeltaY) : 0));
+ if (deltaScale < that.options.zoomMin) deltaScale = that.options.zoomMin;
+ if (deltaScale > that.options.zoomMax) deltaScale = that.options.zoomMax;
+
+ if (deltaScale != that.scale) {
+ if (!that.wheelZoomCount && that.options.onZoomStart) that.options.onZoomStart.call(that, e);
+ that.wheelZoomCount++;
+
+ that.zoom(e.pageX, e.pageY, deltaScale, 400);
+
+ setTimeout(function() {
+ that.wheelZoomCount--;
+ if (!that.wheelZoomCount && that.options.onZoomEnd) that.options.onZoomEnd.call(that, e);
+ }, 400);
+ }
+
+ return;
+ }
+
+ deltaX = that.x + wheelDeltaX;
+ deltaY = that.y + wheelDeltaY;
+
+ if (deltaX > 0) deltaX = 0;
+ else if (deltaX < that.maxScrollX) deltaX = that.maxScrollX;
+
+ if (deltaY > that.minScrollY) deltaY = that.minScrollY;
+ else if (deltaY < that.maxScrollY) deltaY = that.maxScrollY;
+
+ that.scrollTo(deltaX, deltaY, 0);
+ },
+
+ _mouseout: function (e) {
+ var t = e.relatedTarget;
+
+ if (!t) {
+ this._end(e);
+ return;
+ }
+
+ while (t = t.parentNode) if (t == this.wrapper) return;
+
+ this._end(e);
+ },
+
+ _transitionEnd: function (e) {
+ var that = this;
+
+ if (e.target != that.scroller) return;
+
+ that._unbind('webkitTransitionEnd');
+
+ that._startAni();
+ },
+
+
+ /**
+ *
+ * Utilities
+ *
+ */
+ _startAni: function () {
+ var that = this,
+ startX = that.x, startY = that.y,
+ startTime = Date.now(),
+ step, easeOut,
+ animate;
+
+ if (that.animating) return;
+
+ if (!that.steps.length) {
+ that._resetPos(400);
+ return;
+ }
+
+ step = that.steps.shift();
+
+ if (step.x == startX && step.y == startY) step.time = 0;
+
+ that.animating = true;
+ that.moved = true;
+
+ if (that.options.useTransition) {
+ that._transitionTime(step.time);
+ that._pos(step.x, step.y);
+ that.animating = false;
+ if (step.time) that._bind('webkitTransitionEnd');
+ else that._resetPos(0);
+ return;
+ }
+
+ animate = function () {
+ var now = Date.now(),
+ newX, newY;
+
+ if (now >= startTime + step.time) {
+ that._pos(step.x, step.y);
+ that.animating = false;
+ if (that.options.onAnimationEnd) that.options.onAnimationEnd.call(that); // Execute custom code on animation end
+ that._startAni();
+ return;
+ }
+
+ now = (now - startTime) / step.time - 1;
+ easeOut = m.sqrt(1 - now * now);
+ newX = (step.x - startX) * easeOut + startX;
+ newY = (step.y - startY) * easeOut + startY;
+ that._pos(newX, newY);
+ if (that.animating) that.aniTime = nextFrame(animate);
+ };
+
+ animate();
+ },
+
+ _transitionTime: function (time) {
+ time += 'ms';
+ this.scroller.style[vendor + 'TransitionDuration'] = time;
+ if (this.hScrollbar) this.hScrollbarIndicator.style[vendor + 'TransitionDuration'] = time;
+ if (this.vScrollbar) this.vScrollbarIndicator.style[vendor + 'TransitionDuration'] = time;
+ },
+
+ _momentum: function (dist, time, maxDistUpper, maxDistLower, size) {
+ var deceleration = 0.0006,
+ speed = m.abs(dist) / time,
+ newDist = (speed * speed) / (2 * deceleration),
+ newTime = 0, outsideDist = 0;
+
+ // Proportinally reduce speed if we are outside of the boundaries
+ if (dist > 0 && newDist > maxDistUpper) {
+ outsideDist = size / (6 / (newDist / speed * deceleration));
+ maxDistUpper = maxDistUpper + outsideDist;
+ speed = speed * maxDistUpper / newDist;
+ newDist = maxDistUpper;
+ } else if (dist < 0 && newDist > maxDistLower) {
+ outsideDist = size / (6 / (newDist / speed * deceleration));
+ maxDistLower = maxDistLower + outsideDist;
+ speed = speed * maxDistLower / newDist;
+ newDist = maxDistLower;
+ }
+
+ newDist = newDist * (dist < 0 ? -1 : 1);
+ newTime = speed / deceleration;
+
+ return { dist: newDist, time: m.round(newTime) };
+ },
+
+ _offset: function (el) {
+ var left = -el.offsetLeft,
+ top = -el.offsetTop;
+
+ while (el = el.offsetParent) {
+ left -= el.offsetLeft;
+ top -= el.offsetTop;
+ }
+
+ if (el != this.wrapper) {
+ left *= this.scale;
+ top *= this.scale;
+ }
+
+ return { left: left, top: top };
+ },
+
+ _snap: function (x, y) {
+ var that = this,
+ i, l,
+ page, time,
+ sizeX, sizeY;
+
+ // Check page X
+ page = that.pagesX.length - 1;
+ for (i=0, l=that.pagesX.length; i<l; i++) {
+ if (x >= that.pagesX[i]) {
+ page = i;
+ break;
+ }
+ }
+ if (page == that.currPageX && page > 0 && that.dirX < 0) page--;
+ x = that.pagesX[page];
+ sizeX = m.abs(x - that.pagesX[that.currPageX]);
+ sizeX = sizeX ? m.abs(that.x - x) / sizeX * 500 : 0;
+ that.currPageX = page;
+
+ // Check page Y
+ page = that.pagesY.length-1;
+ for (i=0; i<page; i++) {
+ if (y >= that.pagesY[i]) {
+ page = i;
+ break;
+ }
+ }
+ if (page == that.currPageY && page > 0 && that.dirY < 0) page--;
+ y = that.pagesY[page];
+ sizeY = m.abs(y - that.pagesY[that.currPageY]);
+ sizeY = sizeY ? m.abs(that.y - y) / sizeY * 500 : 0;
+ that.currPageY = page;
+
+ // Snap with constant speed (proportional duration)
+ time = m.round(m.max(sizeX, sizeY)) || 200;
+
+ return { x: x, y: y, time: time };
+ },
+
+ _bind: function (type, el, bubble) {
+ (el || this.scroller).addEventListener(type, this, !!bubble);
+ },
+
+ _unbind: function (type, el, bubble) {
+ (el || this.scroller).removeEventListener(type, this, !!bubble);
+ },
+
+
+ /**
+ *
+ * Public methods
+ *
+ */
+ destroy: function () {
+ var that = this;
+
+ that.scroller.style[vendor + 'Transform'] = '';
+
+ // Remove the scrollbars
+ that.hScrollbar = false;
+ that.vScrollbar = false;
+ that._scrollbar('h');
+ that._scrollbar('v');
+
+ // Remove the event listeners
+ that._unbind(RESIZE_EV, window);
+ that._unbind(START_EV);
+ that._unbind(MOVE_EV);
+ that._unbind(END_EV);
+ that._unbind(CANCEL_EV);
+
+ if (that.options.hasTouch) {
+ that._unbind('mouseout', that.wrapper);
+ that._unbind(WHEEL_EV);
+ }
+
+ if (that.options.useTransition) that._unbind('webkitTransitionEnd');
+
+ if (that.options.checkDOMChanges) clearInterval(that.checkDOMTime);
+
+ if (that.options.onDestroy) that.options.onDestroy.call(that);
+ },
+
+ refresh: function () {
+ var that = this,
+ offset,
+ i, l,
+ els,
+ pos = 0,
+ page = 0;
+
+ if (that.scale < that.options.zoomMin) that.scale = that.options.zoomMin;
+ that.wrapperW = that.wrapper.clientWidth || 1;
+ that.wrapperH = that.wrapper.clientHeight || 1;
+
+ that.minScrollY = -that.options.topOffset || 0;
+ that.scrollerW = m.round(that.scroller.offsetWidth * that.scale);
+ that.scrollerH = m.round((that.scroller.offsetHeight + that.minScrollY) * that.scale);
+ that.maxScrollX = that.wrapperW - that.scrollerW;
+ that.maxScrollY = that.wrapperH - that.scrollerH + that.minScrollY;
+ that.dirX = 0;
+ that.dirY = 0;
+
+ if (that.options.onRefresh) that.options.onRefresh.call(that);
+
+ that.hScroll = that.options.hScroll && that.maxScrollX < 0;
+ that.vScroll = that.options.vScroll && (!that.options.bounceLock && !that.hScroll || that.scrollerH > that.wrapperH);
+
+ that.hScrollbar = that.hScroll && that.options.hScrollbar;
+ that.vScrollbar = that.vScroll && that.options.vScrollbar && that.scrollerH > that.wrapperH;
+
+ offset = that._offset(that.wrapper);
+ that.wrapperOffsetLeft = -offset.left;
+ that.wrapperOffsetTop = -offset.top;
+
+ // Prepare snap
+ if (typeof that.options.snap == 'string') {
+ that.pagesX = [];
+ that.pagesY = [];
+ els = that.scroller.querySelectorAll(that.options.snap);
+ for (i=0, l=els.length; i<l; i++) {
+ pos = that._offset(els[i]);
+ pos.left += that.wrapperOffsetLeft;
+ pos.top += that.wrapperOffsetTop;
+ that.pagesX[i] = pos.left < that.maxScrollX ? that.maxScrollX : pos.left * that.scale;
+ that.pagesY[i] = pos.top < that.maxScrollY ? that.maxScrollY : pos.top * that.scale;
+ }
+ } else if (that.options.snap) {
+ that.pagesX = [];
+ while (pos >= that.maxScrollX) {
+ that.pagesX[page] = pos;
+ pos = pos - that.wrapperW;
+ page++;
+ }
+ if (that.maxScrollX%that.wrapperW) that.pagesX[that.pagesX.length] = that.maxScrollX - that.pagesX[that.pagesX.length-1] + that.pagesX[that.pagesX.length-1];
+
+ pos = 0;
+ page = 0;
+ that.pagesY = [];
+ while (pos >= that.maxScrollY) {
+ that.pagesY[page] = pos;
+ pos = pos - that.wrapperH;
+ page++;
+ }
+ if (that.maxScrollY%that.wrapperH) that.pagesY[that.pagesY.length] = that.maxScrollY - that.pagesY[that.pagesY.length-1] + that.pagesY[that.pagesY.length-1];
+ }
+
+ // Prepare the scrollbars
+ that._scrollbar('h');
+ that._scrollbar('v');
+
+ if (!that.zoomed) {
+ that.scroller.style[vendor + 'TransitionDuration'] = '0';
+ that._resetPos(200);
+ }
+ },
+
+ scrollTo: function (x, y, time, relative) {
+ var that = this,
+ step = x,
+ i, l;
+
+ that.stop();
+
+ if (!step.length) step = [{ x: x, y: y, time: time, relative: relative }];
+
+ for (i=0, l=step.length; i<l; i++) {
+ if (step[i].relative) { step[i].x = that.x - step[i].x; step[i].y = that.y - step[i].y; }
+ that.steps.push({ x: step[i].x, y: step[i].y, time: step[i].time || 0 });
+ }
+
+ that._startAni();
+ },
+
+ scrollToElement: function (el, time) {
+ var that = this, pos;
+ el = el.nodeType ? el : that.scroller.querySelector(el);
+ if (!el) return;
+
+ pos = that._offset(el);
+ pos.left += that.wrapperOffsetLeft;
+ pos.top += that.wrapperOffsetTop;
+
+ pos.left = pos.left > 0 ? 0 : pos.left < that.maxScrollX ? that.maxScrollX : pos.left;
+ pos.top = pos.top > that.minScrollY ? that.minScrollY : pos.top < that.maxScrollY ? that.maxScrollY : pos.top;
+ time = time === undefined ? m.max(m.abs(pos.left)*2, m.abs(pos.top)*2) : time;
+
+ that.scrollTo(pos.left, pos.top, time);
+ },
+
+ scrollToPage: function (pageX, pageY, time) {
+ var that = this, x, y;
+
+ if (that.options.onScrollStart) that.options.onScrollStart.call(that);
+
+ if (that.options.snap) {
+ pageX = pageX == 'next' ? that.currPageX+1 : pageX == 'prev' ? that.currPageX-1 : pageX;
+ pageY = pageY == 'next' ? that.currPageY+1 : pageY == 'prev' ? that.currPageY-1 : pageY;
+
+ pageX = pageX < 0 ? 0 : pageX > that.pagesX.length-1 ? that.pagesX.length-1 : pageX;
+ pageY = pageY < 0 ? 0 : pageY > that.pagesY.length-1 ? that.pagesY.length-1 : pageY;
+
+ that.currPageX = pageX;
+ that.currPageY = pageY;
+ x = that.pagesX[pageX];
+ y = that.pagesY[pageY];
+ } else {
+ x = -that.wrapperW * pageX;
+ y = -that.wrapperH * pageY;
+ if (x < that.maxScrollX) x = that.maxScrollX;
+ if (y < that.maxScrollY) y = that.maxScrollY;
+ }
+
+ that.scrollTo(x, y, time || 400);
+ },
+
+ disable: function () {
+ this.stop();
+ this._resetPos(0);
+ this.enabled = false;
+
+ // If disabled after touchstart we make sure that there are no left over events
+ this._unbind(MOVE_EV);
+ this._unbind(END_EV);
+ this._unbind(CANCEL_EV);
+ },
+
+ enable: function () {
+ this.enabled = true;
+ },
+
+ stop: function () {
+ if (this.options.useTransition) this._unbind('webkitTransitionEnd');
+ else cancelFrame(this.aniTime);
+ this.steps = [];
+ this.moved = false;
+ this.animating = false;
+ },
+
+ zoom: function (x, y, scale, time) {
+ var that = this,
+ relScale = scale / that.scale;
+
+ if (!that.options.useTransform) return;
+
+ that.zoomed = true;
+ time = time === undefined ? 200 : time;
+ x = x - that.wrapperOffsetLeft - that.x;
+ y = y - that.wrapperOffsetTop - that.y;
+ that.x = x - x * relScale + that.x;
+ that.y = y - y * relScale + that.y;
+
+ that.scale = scale;
+ that.refresh();
+
+ that.x = that.x > 0 ? 0 : that.x < that.maxScrollX ? that.maxScrollX : that.x;
+ that.y = that.y > that.minScrollY ? that.minScrollY : that.y < that.maxScrollY ? that.maxScrollY : that.y;
+
+ that.scroller.style[vendor + 'TransitionDuration'] = time + 'ms';
+ that.scroller.style[vendor + 'Transform'] = trnOpen + that.x + 'px,' + that.y + 'px' + trnClose + ' scale(' + scale + ')';
+ that.zoomed = false;
+ },
+
+ isReady: function () {
+ return !this.moved && !this.zoomed && !this.animating;
+ }
+ };
+
+ if (typeof exports !== 'undefined') exports.iScroll = iScroll;
+ else window.iScroll = iScroll;
+
+ })();
+
+
+ provide("iscroll", module.exports);
+
+ !function ($, iScroll) {
+ $.ender({
+ iScroll: function (options) {
+ return new iScroll(this[0], options)
+ }
+ }, true)
+ }(ender, require('iscroll').iScroll)
+
+}();
View
27 examples/ender/ender.min.js
@@ -0,0 +1,27 @@
+/*!
+ * =============================================================
+ * Ender: open module JavaScript framework (https://ender.no.de)
+ * Build: ender build qwery domready ../../
+ * =============================================================
+ */
+
+
+/*!
+ * Ender-JS: open module JavaScript framework (client-lib)
+ * copyright Dustin Diaz & Jacob Thornton 2011 (@ded @fat)
+ * https://ender.no.de
+ * License MIT
+ */
+!function(a){function c(a){var c=b[a]||window[a];if(!c)throw new Error("Requested module '"+a+"' has not been defined.");return c}function d(a,c){return b[a]=c}function e(a,b){for(var c in b)c!="noConflict"&&c!="_VERSION"&&(a[c]=b[c]);return a}function f(a,b,c){return g._select&&(typeof a=="string"||a.nodeName||a.length&&"item"in a||a==window)?(c=g._select(a,b),c.selector=a):c=isFinite(a.length)?a:[a],e(c,f)}function g(a,b){return f(a,b)}a.global=a;var b={};a.provide=d,a.require=c,e(g,{_VERSION:"0.2.5",ender:function(a,b){e(b?f:g,a)},fn:a.$&&a.$.fn||{}}),e(f,{forEach:function(a,b,c){for(c=0,l=this.length;c<l;++c)c in this&&a.call(b||this[c],this[c],c,this);return this},$:g});var h=a.$;g.noConflict=function(){return a.$=h,this},typeof module!="undefined"&&module.exports&&(module.exports=g),a.ender=a.$=a.ender||g}(this),!function(){var a={exports:{}},b=a.exports;
+/*!
+ * Qwery - A Blazing Fast query selector engine
+ * https://github.com/ded/qwery
+ * copyright Dustin Diaz & Jacob Thornton 2011
+ * MIT License
+ */
+!function(b,c){typeof define=="function"?define(c):typeof a!="undefined"?a.exports=c():this[b]=c()}("qwery",function(){function L(){this.c={}}function Q(a){k=[];for(d=0,g=a.length;d<g;d++)Z(a[d])?k=k.concat(a[d]):k.push(a[d]);return k}function R(a){while(a=a.previousSibling)if(a.nodeType==1)break;return a}function S(a){return a.match(J)}function T(a,b,c,e,f,g,h,j,k,l,m){var n,o,q;if(b&&this.tagName.toLowerCase()!==b)return!1;if(c&&(n=c.match(u))&&n[1]!==this.id)return!1;if(c&&(p=c.match(v)))for(d=p.length;d--;){o=p[d].slice(1);if(!(M.g(o)||M.s(o,new RegExp("(^|\\s+)"+o+"(\\s+|$)"))).test(this.className))return!1}if(k&&_.pseudos[k]&&!_.pseudos[k](this,m))return!1;if(e&&!h){i=this.attributes;for(q in i)if(Object.prototype.hasOwnProperty.call(i,q)&&(i[q].name||q)==f)return this}return e&&!V(g,this.getAttribute(f)||"",h)?!1:this}function U(a){return N.g(a)||N.s(a,a.replace(D,"\\$1"))}function V(a,b,c){switch(a){case"=":return b==c;case"^=":return b.match(O.g("^="+c)||O.s("^="+c,new RegExp("^"+U(c))));case"$=":return b.match(O.g("$="+c)||O.s("$="+c,new RegExp(U(c)+"$")));case"*=":return b.match(O.g(c)||O.s(c,new RegExp(U(c))));case"~=":return b.match(O.g("~="+c)||O.s("~="+c,new RegExp("(?:^|\\s+)"+U(c)+"(?:\\s+|$)")));case"|=":return b.match(O.g("|="+c)||O.s("|="+c,new RegExp("^"+U(c)+"(-|$)")))}return 0}function W(a){var c=[],d=[],e,f=0,g,h,i,j,k,l,m,n,p,q,r,s=P.g(a)||P.s(a,a.split(I)),t=a.match(H),u;s=s.slice(0);if(!s.length)return c;k=s.pop(),n=s.length&&(i=s[s.length-1].match(w))?b.getElementById(i[1]):b;if(!n)return c;p=S(k),m=t&&/^[+~]$/.test(t[t.length-1])?function(a){while(n=n.nextSibling)n.nodeType==1&&(p[1]?p[1]==n.tagName.toLowerCase():1)&&a.push(n);return a}([]):n.getElementsByTagName(p[1]||"*");for(e=0,h=m.length;e<h;e++)if(q=T.apply(m[e],p))c[f++]=q;if(!s.length)return c;for(f=0,h=c.length,g=0;f<h;f++){j=c[f];for(e=s.length;e--;)while(j=K[t[e]](j,c[f]))if(o=T.apply(j,S(s[e])))break;o&&(d[g++]=c[f])}return d}function X(a){return a&&a.nodeType&&(a.nodeType==1||a.nodeType==9)}function Y(a){var b=[],c,d;e:for(c=0;c<a.length;c++){for(d=0;d<b.length;d++)if(b[d]==a[c])continue e;b[b.length]=a[c]}return b}function Z(a){return typeof a=="object"&&isFinite(a.length)}function $(a){return a?typeof a=="string"?_(a)[0]:Z(a)?a[0]:a:b}function _(a,c){var d=$(c);return!d||!a?[]:a===window||X(a)?!c||a!==window&&X(d)&&ba(a,d)?[a]:[]:a&&Z(a)?Q(a):(h=a.match(w))?(m=b.getElementById(h[1]))?[m]:[]:(h=a.match(y))?Q(d.getElementsByTagName(h[1])):bc(a,d)}var a=this,b=document,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t=b.documentElement,u=/#([\w\-]+)/,v=/\.[\w\-]+/g,w=/^#([\w\-]+$)/,x=/^\.([\w\-]+)$/,y=/^([\w\-]+)$/,z=/^([\w]+)?\.([\w\-]+)$/,A=/\s*([\s\+\~>])\s*/g,B=/[\s\>\+\~]/,C=/(?![\s\w\-\/\?\&\=\:\.\(\)\!,@#%<>\{\}\$\*\^'"]*\]|[\s\w\+\-]*\))/,D=/([.*+?\^=!:${}()|\[\]\/\\])/g,E=/^([a-z0-9]+)?(?:([\.\#]+[\w\-\.#]+)?)/,F=/\[([\w\-]+)(?:([\|\^\$\*\~]?\=)['"]?([ \w\-\/\?\&\=\:\.\(\)\!,@#%<>\{\}\$\*\^]+)["']?)?\]/,G=/:([\w\-]+)(\(['"]?([\s\w\+\-]+)['"]?\))?/,H=new RegExp("("+B.source+")"+C.source,"g"),I=new RegExp(B.source+C.source),J=new RegExp(E.source+"("+F.source+")?"+"("+G.source+")?"),K={" ":function(a){return a&&a!==t&&a.parentNode},">":function(a,b){return a&&a.parentNode==b.parentNode&&a.parentNode},"~":function(a){return a&&a.previousSibling},"+":function(a,b,c,d){return a?(c=R(a),d=R(b),c&&d&&c==d&&c):!1}};L.prototype={g:function(a){return this.c[a]||undefined},s:function(a,b){return this.c[a]=b,b}};var M=new L,N=new L,O=new L,P=new L,ba="compareDocumentPosition"in t?function(a,b){return(b.compareDocumentPosition(a)&16)==16}:"contains"in t?function(a,c){return c=c==b||c==window?t:c,c!==a&&c.contains(a)}:function(a,b){while(a=a.parentNode)if(a===b)return 1;return 0},bb=function(){if(!b.querySelector||!b.querySelectorAll)return!1;try{return b.querySelectorAll(":nth-of-type(1)").length>0}catch(a){return!1}}(),bc=bb?function(a,c){return b.getElementsByClassName&&(h=a.match(x))?Q(c.getElementsByClassName(h[1])):Q(c.querySelectorAll(a))}:function(a,c){a=a.replace(A,"$1");var d=[],f,i,j=[],l;if(h=a.match(z)){r=c.getElementsByTagName(h[1]||"*"),k=M.g(h[2])||M.s(h[2],new RegExp("(^|\\s+)"+h[2]+"(\\s+|$)"));for(l=0,g=r.length,e=0;l<g;l++)k.test(r[l].className)&&(d[e++]=r[l]);return d}for(l=0,r=a.split(","),g=r.length;l<g;l++)j[l]=W(r[l]);for(l=0,g=j.length;l<g&&(i=j[l]);l++){var m=i;if(c!==b){m=[];for(e=0,h=i.length;e<h&&(f=i[e]);e++)ba(f,c)&&m.push(f)}d=d.concat(m)}return Y(d)};_.uniq=Y,_.pseudos={};var bd=a.qwery;return _.noConflict=function(){return a.qwery=bd,this},_}),provide("qwery",a.exports),!function(a,b){function f(b,c){var d=/^<([^\s>]+)/.exec(b)[1],f=(c||a).createElement(e[d]||"div"),g=[];f.innerHTML=b;var h=f.childNodes;f=f.firstChild,g.push(f);while(f=f.nextSibling)f.nodeType==1&&g.push(f);return g}var c=require("qwery"),d="table",e={thead:d,tbody:d,tfoot:d,tr:"tbody",th:"tr",td:"tr",fieldset:"form",option:"select"};b._select=function(a,b){return/^\s*</.test(a)?f(a,b):c(a,b)},b.pseudos=c.pseudos,b.ender({find:function(a){var d=[],e,f,g,h,i;for(e=0,f=this.length;e<f;e++){i=c(a,this[e]);for(g=0,h=i.length;g<h;g++)d.push(i[g])}return b(c.uniq(d))},and:function(a){var c=b(a);for(var d=this.length,e=0,f=this.length+c.length;d<f;d++,e++)this[d]=c[e];return this}},!0)}(document,ender)}(),!function(){var a={exports:{}},b=a.exports;!function(b,c){function o(a){n=1;while(a=d.shift())a()}var d=[],e,f,g,h=!1,i=c.documentElement,j=i.doScroll,k="DOMContentLoaded",l="addEventListener",m="onreadystatechange",n=/^loade|c/.test(c.readyState);c[l]&&c[l](k,g=function(){c.removeEventListener(k,g,h),o()},h),j&&c.attachEvent(m,f=function(){/^c/.test(c.readyState)&&(c.detachEvent(m,f),o())}),e=j?function(a){self!=top?n?a():d.push(a):function(){try{i.doScroll("left")}catch(b){return setTimeout(function(){e(a)},50)}a()}()}:function(a){n?a():d.push(a)},typeof a!="undefined"?a.exports=e:b.domReady=e}(this,document),provide("domready",a.exports),!function(a){var b=require("domready");a.ender({domReady:b}),a.ender({ready:function(a){return b(a),this}},!0)}(ender)}(),!function(){var a={exports:{}},b=a.exports;
+/*!
+ * iScroll v4.1.9 ~ Copyright (c) 2011 Matteo Spinelli, http://cubiq.org
+ * Released under MIT license, http://cubiq.org/license
+ */
+function(){var a=Math,c=/webkit/i.test(navigator.appVersion)?"webkit":/firefox/i.test(navigator.userAgent)?"Moz":"opera"in window?"O":"",d="WebKitCSSMatrix"in window&&"m11"in new WebKitCSSMatrix,e="ontouchstart"in window,f=c+"Transform"in document.documentElement.style,g=/android/gi.test(navigator.appVersion),h=/iphone|ipad/gi.test(navigator.appVersion),i=/playbook/gi.test(navigator.appVersion),j=h||i,k=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a){return setTimeout(a,1)}}(),l=function(){return window.cancelRequestAnimationFrame||window.webkitCancelRequestAnimationFrame||window.mozCancelRequestAnimationFrame||window.oCancelRequestAnimationFrame||window.msCancelRequestAnimationFrame||clearTimeout}(),m="onorientationchange"in window?"orientationchange":"resize",n=e?"touchstart":"mousedown",o=e?"touchmove":"mousemove",p=e?"touchend":"mouseup",q=e?"touchcancel":"mouseup",r=c=="Moz"?"DOMMouseScroll":"mousewheel",s="translate"+(d?"3d(":"("),t=d?",0)":")",u=function(a,b){var i=this,k=document,l;i.wrapper=typeof a=="object"?a:k.getElementById(a),i.wrapper.style.overflow="hidden",i.scroller=i.wrapper.children[0],i.options={hScroll:!0,vScroll:!0,x:0,y:0,bounce:!0,bounceLock:!1,momentum:!0,lockDirection:!0,useTransform:!0,useTransition:!1,topOffset:0,checkDOMChanges:!1,hScrollbar:!0,vScrollbar:!0,fixedScrollbar:g,hideScrollbar:h,fadeScrollbar:h&&d,scrollbarClass:"",zoom:!1,zoomMin:1,zoomMax:4,doubleTapZoom:2,wheelAction:"scroll",snap:!1,snapThreshold:1,onRefresh:null,onBeforeScrollStart:function(a){a.preventDefault()},onScrollStart:null,onBeforeScrollMove:null,onScrollMove:null,onBeforeScrollEnd:null,onScrollEnd:null,onTouchEnd:null,onDestroy:null,onZoomStart:null,onZoom:null,onZoomEnd:null};for(l in b)i.options[l]=b[l];i.x=i.options.x,i.y=i.options.y,i.options.useTransform=f?i.options.useTransform:!1,i.options.hScrollbar=i.options.hScroll&&i.options.hScrollbar,i.options.vScrollbar=i.options.vScroll&&i.options.vScrollbar,i.options.zoom=i.options.useTransform&&i.options.zoom,i.options.useTransition=j&&i.options.useTransition,i.scroller.style[c+"TransitionProperty"]=i.options.useTransform?"-"+c.toLowerCase()+"-transform":"top left",i.scroller.style[c+"TransitionDuration"]="0",i.scroller.style[c+"TransformOrigin"]="0 0",i.options.useTransition&&(i.scroller.style[c+"TransitionTimingFunction"]="cubic-bezier(0.33,0.66,0.66,1)"),i.options.useTransform?i.scroller.style[c+"Transform"]=s+i.x+"px,"+i.y+"px"+t:i.scroller.style.cssText+=";position:absolute;top:"+i.y+"px;left:"+i.x+"px",i.options.useTransition&&(i.options.fixedScrollbar=!0),i.refresh(),i._bind(m,window),i._bind(n),e||(i._bind("mouseout",i.wrapper),i._bind(r)),i.options.checkDOMChanges&&(i.checkDOMTime=setInterval(function(){i._checkDOMChanges()},500))};u.prototype={enabled:!0,x:0,y:0,steps:[],scale:1,currPageX:0,currPageY:0,pagesX:[],pagesY:[],aniTime:null,wheelZoomCount:0,handleEvent:function(a){var b=this;switch(a.type){case n:if(!e&&a.button!==0)return;b._start(a);break;case o:b._move(a);break;case p:case q:b._end(a);break;case m:b._resize();break;case r:b._wheel(a);break;case"mouseout":b._mouseout(a);break;case"webkitTransitionEnd":b._transitionEnd(a)}},_checkDOMChanges:function(){if(this.moved||this.zoomed||this.animating||this.scrollerW==this.scroller.offsetWidth*this.scale&&this.scrollerH==this.scroller.offsetHeight*this.scale)return;this.refresh()},_scrollbar:function(b){var d=this,e=document,g;if(!d[b+"Scrollbar"]){d[b+"ScrollbarWrapper"]&&(f&&(d[b+"ScrollbarIndicator"].style[c+"Transform"]=""),d[b+"ScrollbarWrapper"].parentNode.removeChild(d[b+"ScrollbarWrapper"]),d[b+"ScrollbarWrapper"]=null,d[b+"ScrollbarIndicator"]=null);return}d[b+"ScrollbarWrapper"]||(g=e.createElement("div"),d.options.scrollbarClass?g.className=d.options.scrollbarClass+b.toUpperCase():g.style.cssText="position:absolute;z-index:100;"+(b=="h"?"height:7px;bottom:1px;left:2px;right:"+(d.vScrollbar?"7":"2")+"px":"width:7px;bottom:"+(d.hScrollbar?"7":"2")+"px;top:2px;right:1px"),g.style.cssText+=";pointer-events:none;-"+c+"-transition-property:opacity;-"+c+"-transition-duration:"+(d.options.fadeScrollbar?"350ms":"0")+";overflow:hidden;opacity:"+(d.options.hideScrollbar?"0":"1"),d.wrapper.appendChild(g),d[b+"ScrollbarWrapper"]=g,g=e.createElement("div"),d.options.scrollbarClass||(g.style.cssText="position:absolute;z-index:100;background:rgba(0,0,0,0.5);border:1px solid rgba(255,255,255,0.9);-"+c+"-background-clip:padding-box;-"+c+"-box-sizing:border-box;"+(b=="h"?"height:100%":"width:100%")+";-"+c+"-border-radius:3px;border-radius:3px"),g.style.cssText+=";pointer-events:none;-"+c+"-transition-property:-"+c+"-transform;-"+c+"-transition-timing-function:cubic-bezier(0.33,0.66,0.66,1);-"+c+"-transition-duration:0;-"+c+"-transform:"+s+"0,0"+t,d.options.useTransition&&(g.style.cssText+=";-"+c+"-transition-timing-function:cubic-bezier(0.33,0.66,0.66,1)"),d[b+"ScrollbarWrapper"].appendChild(g),d[b+"ScrollbarIndicator"]=g),b=="h"?(d.hScrollbarSize=d.hScrollbarWrapper.clientWidth,d.hScrollbarIndicatorSize=a.max(a.round(d.hScrollbarSize*d.hScrollbarSize/d.scrollerW),8),d.hScrollbarIndicator.style.width=d.hScrollbarIndicatorSize+"px",d.hScrollbarMaxScroll=d.hScrollbarSize-d.hScrollbarIndicatorSize,d.hScrollbarProp=d.hScrollbarMaxScroll/d.maxScrollX):(d.vScrollbarSize=d.vScrollbarWrapper.clientHeight,d.vScrollbarIndicatorSize=a.max(a.round(d.vScrollbarSize*d.vScrollbarSize/d.scrollerH),8),d.vScrollbarIndicator.style.height=d.vScrollbarIndicatorSize+"px",d.vScrollbarMaxScroll=d.vScrollbarSize-d.vScrollbarIndicatorSize,d.vScrollbarProp=d.vScrollbarMaxScroll/d.maxScrollY),d._scrollbarPos(b,!0)},_resize:function(){var a=this;setTimeout(function(){a.refresh()},g?200:0)},_pos:function(b,d){b=this.hScroll?b:0,d=this.vScroll?d:0,this.options.useTransform?this.scroller.style[c+"Transform"]=s+b+"px,"+d+"px"+t+" scale("+this.scale+")":(b=a.round(b),d=a.round(d),this.scroller.style.left=b+"px",this.scroller.style.top=d+"px"),this.x=b,this.y=d,this._scrollbarPos("h"),this._scrollbarPos("v")},_scrollbarPos:function(b,d){var e=this,f=b=="h"?e.x:e.y,g;if(!e[b+"Scrollbar"])return;f=e[b+"ScrollbarProp"]*f,f<0?(e.options.fixedScrollbar||(g=e[b+"ScrollbarIndicatorSize"]+a.round(f*3),g<8&&(g=8),e[b+"ScrollbarIndicator"].style[b=="h"?"width":"height"]=g+"px"),f=0):f>e[b+"ScrollbarMaxScroll"]&&(e.options.fixedScrollbar?f=e[b+"ScrollbarMaxScroll"]:(g=e[b+"ScrollbarIndicatorSize"]-a.round((f-e[b+"ScrollbarMaxScroll"])*3),g<8&&(g=8),e[b+"ScrollbarIndicator"].style[b=="h"?"width":"height"]=g+"px",f=e[b+"ScrollbarMaxScroll"]+(e[b+"ScrollbarIndicatorSize"]-g))),e[b+"ScrollbarWrapper"].style[c+"TransitionDelay"]="0",e[b+"ScrollbarWrapper"].style.opacity=d&&e.options.hideScrollbar?"0":"1",e[b+"ScrollbarIndicator"].style[c+"Transform"]=s+(b=="h"?f+"px,0":"0,"+f+"px")+t},_start:function(b){var d=this,f=e?b.touches[0]:b,g,h,i,j,k;if(!d.enabled)return;d.options.onBeforeScrollStart&&d.options.onBeforeScrollStart.call(d,b),(d.options.useTransition||d.options.zoom)&&d._transitionTime(0),d.moved=!1,d.animating=!1,d.zoomed=!1,d.distX=0,d.distY=0,d.absDistX=0,d.absDistY=0,d.dirX=0,d.dirY=0,d.options.zoom&&e&&b.touches.length>1&&(j=a.abs(b.touches[0].pageX-b.touches[1].pageX),k=a.abs(b.touches[0].pageY-b.touches[1].pageY),d.touchesDistStart=a.sqrt(j*j+k*k),d.originX=a.abs(b.touches[0].pageX+b.touches[1].pageX-d.wrapperOffsetLeft*2)/2-d.x,d.originY=a.abs(b.touches[0].pageY+b.touches[1].pageY-d.wrapperOffsetTop*2)/2-d.y,d.options.onZoomStart&&d.options.onZoomStart.call(d,b));if(d.options.momentum){d.options.useTransform?(g=getComputedStyle(d.scroller,null)[c+"Transform"].replace(/[^0-9-.,]/g,"").split(","),h=g[4]*1,i=g[5]*1):(h=getComputedStyle(d.scroller,null).left.replace(/[^0-9-]/g,"")*1,i=getComputedStyle(d.scroller,null).top.replace(/[^0-9-]/g,"")*1);if(h!=d.x||i!=d.y)d.options.useTransition?d._unbind("webkitTransitionEnd"):l(d.aniTime),d.steps=[],d._pos(h,i)}d.absStartX=d.x,d.absStartY=d.y,d.startX=d.x,d.startY=d.y,d.pointX=f.pageX,d.pointY=f.pageY,d.startTime=b.timeStamp||Date.now(),d.options.onScrollStart&&d.options.onScrollStart.call(d,b),d._bind(o),d._bind(p),d._bind(q)},_move:function(b){var d=this,f=e?b.touches[0]:b,g=f.pageX-d.pointX,h=f.pageY-d.pointY,i=d.x+g,j=d.y+h,k,l,m,n=b.timeStamp||Date.now();d.options.onBeforeScrollMove&&d.options.onBeforeScrollMove.call(d,b);if(d.options.zoom&&e&&b.touches.length>1){k=a.abs(b.touches[0].pageX-b.touches[1].pageX),l=a.abs(b.touches[0].pageY-b.touches[1].pageY),d.touchesDist=a.sqrt(k*k+l*l),d.zoomed=!0,m=1/d.touchesDistStart*d.touchesDist*this.scale,m<d.options.zoomMin?m=.5*d.options.zoomMin*Math.pow(2,m/d.options.zoomMin):m>d.options.zoomMax&&(m=2*d.options.zoomMax*Math.pow(.5,d.options.zoomMax/m)),d.lastScale=m/this.scale,i=this.originX-this.originX*d.lastScale+this.x,j=this.originY-this.originY*d.lastScale+this.y,this.scroller.style[c+"Transform"]=s+i+"px,"+j+"px"+t+" scale("+m+")",d.options.onZoom&&d.options.onZoom.call(d,b);return}d.pointX=f.pageX,d.pointY=f.pageY;if(i>0||i<d.maxScrollX)i=d.options.bounce?d.x+g/2:i>=0||d.maxScrollX>=0?0:d.maxScrollX;if(j>d.minScrollY||j<d.maxScrollY)j=d.options.bounce?d.y+h/2:j>=d.minScrollY||d.maxScrollY>=0?d.minScrollY:d.maxScrollY;if(d.absDistX<6&&d.absDistY<6){d.distX+=g,d.distY+=h,d.absDistX=a.abs(d.distX),d.absDistY=a.abs(d.distY);return}d.options.lockDirection&&(d.absDistX>d.absDistY+5?(j=d.y,h=0):d.absDistY>d.absDistX+5&&(i=d.x,g=0)),d.moved=!0,d._pos(i,j),d.dirX=g>0?-1:g<0?1:0,d.dirY=h>0?-1:h<0?1:0,n-d.startTime>300&&(d.startTime=n,d.startX=d.x,d.startY=d.y),d.options.onScrollMove&&d.options.onScrollMove.call(d,b)},_end:function(b){if(e&&b.touches.length!=0)return;var d=this,f=e?b.changedTouches[0]:b,g,h,i={dist:0,time:0},j={dist:0,time:0},k=(b.timeStamp||Date.now())-d.startTime,l=d.x,m=d.y,n,r,u,v,w;d._unbind(o),d._unbind(p),d._unbind(q),d.options.onBeforeScrollEnd&&d.options.onBeforeScrollEnd.call(d,b);if(d.zoomed){w=d.scale*d.lastScale,w=Math.max(d.options.zoomMin,w),w=Math.min(d.options.zoomMax,w),d.lastScale=w/d.scale,d.scale=w,d.x=d.originX-d.originX*d.lastScale+d.x,d.y=d.originY-d.originY*d.lastScale+d.y,d.scroller.style[c+"TransitionDuration"]="200ms",d.scroller.style[c+"Transform"]=s+d.x+"px,"+d.y+"px"+t+" scale("+d.scale+")",d.zoomed=!1,d.refresh(),d.options.onZoomEnd&&d.options.onZoomEnd.call(d,b);return}if(!d.moved){e&&(d.doubleTapTimer&&d.options.zoom?(clearTimeout(d.doubleTapTimer),d.doubleTapTimer=null,d.options.onZoomStart&&d.options.onZoomStart.call(d,b),d.zoom(d.pointX,d.pointY,d.scale==1?d.options.doubleTapZoom:1),d.options.onZoomEnd&&setTimeout(function(){d.options.onZoomEnd.call(d,b)},200)):d.doubleTapTimer=setTimeout(function(){d.doubleTapTimer=null,g=f.target;while(g.nodeType!=1)g=g.parentNode;g.tagName!="SELECT"&&g.tagName!="INPUT"&&g.tagName!="TEXTAREA"&&(h=document.createEvent("MouseEvents"),h.initMouseEvent("click",!0,!0,b.view,1,f.screenX,f.screenY,f.clientX,f.clientY,b.ctrlKey,b.altKey,b.shiftKey,b.metaKey,0,null),h._fake=!0,g.dispatchEvent(h))},d.options.zoom?250:0)),d._resetPos(200),d.options.onTouchEnd&&d.options.onTouchEnd.call(d,b);return}if(k<300&&d.options.momentum){i=l?d._momentum(l-d.startX,k,-d.x,d.scrollerW-d.wrapperW+d.x,d.options.bounce?d.wrapperW:0):i,j=m?d._momentum(m-d.startY,k,-d.y,d.maxScrollY<0?d.scrollerH-d.wrapperH+d.y-d.minScrollY:0,d.options.bounce?d.wrapperH:0):j,l=d.x+i.dist,m=d.y+j.dist;if(d.x>0&&l>0||d.x<d.maxScrollX&&l<d.maxScrollX)i={dist:0,time:0};if(d.y>d.minScrollY&&m>d.minScrollY||d.y<d.maxScrollY&&m<d.maxScrollY)j={dist:0,time:0}}if(i.dist||j.dist){u=a.max(a.max(i.time,j.time),10),d.options.snap&&(n=l-d.absStartX,r=m-d.absStartY,a.abs(n)<d.options.snapThreshold&&a.abs(r)<d.options.snapThreshold?d.scrollTo(d.absStartX,d.absStartY,200):(v=d._snap(l,m),l=v.x,m=v.y,u=a.max(v.time,u))),d.scrollTo(a.round(l),a.round(m),u),d.options.onTouchEnd&&d.options.onTouchEnd.call(d,b);return}if(d.options.snap){n=l-d.absStartX,r=m-d.absStartY,a.abs(n)<d.options.snapThreshold&&a.abs(r)<d.options.snapThreshold?d.scrollTo(d.absStartX,d.absStartY,200):(v=d._snap(d.x,d.y),(v.x!=d.x||v.y!=d.y)&&d.scrollTo(v.x,v.y,v.time)),d.options.onTouchEnd&&d.options.onTouchEnd.call(d,b);return}d._resetPos(200),d.options.onTouchEnd&&d.options.onTouchEnd.call(d,b)},_resetPos:function(a){var b=this,d=b.x>=0?0:b.x<b.maxScrollX?b.maxScrollX:b.x,e=b.y>=b.minScrollY||b.maxScrollY>0?b.minScrollY:b.y<b.maxScrollY?b.maxScrollY:b.y;if(d==b.x&&e==b.y){b.moved&&(b.moved=!1,b.options.onScrollEnd&&b.options.onScrollEnd.call(b)),b.hScrollbar&&b.options.hideScrollbar&&(c=="webkit"&&(b.hScrollbarWrapper.style[c+"TransitionDelay"]="300ms"),b.hScrollbarWrapper.style.opacity="0"),b.vScrollbar&&b.options.hideScrollbar&&(c=="webkit"&&(b.vScrollbarWrapper.style[c+"TransitionDelay"]="300ms"),b.vScrollbarWrapper.style.opacity="0");return}b.scrollTo(d,e,a||0)},_wheel:function(a){var b=this,c,d,e,f,g;"wheelDeltaX"in a?(c=a.wheelDeltaX/12,d=a.wheelDeltaY/12):"detail"in a?c=d=-a.detail*3:c=d=-a.wheelDelta;if(b.options.wheelAction=="zoom"){g=b.scale*Math.pow(2,1/3*(d?d/Math.abs(d):0)),g<b.options.zoomMin&&(g=b.options.zoomMin),g>b.options.zoomMax&&(g=b.options.zoomMax),g!=b.scale&&(!b.wheelZoomCount&&b.options.onZoomStart&&b.options.onZoomStart.call(b,a),b.wheelZoomCount++,b.zoom(a.pageX,a.pageY,g,400),setTimeout(function(){b.wheelZoomCount--,!b.wheelZoomCount&&b.options.onZoomEnd&&b.options.onZoomEnd.call(b,a)},400));return}e=b.x+c,f=b.y+d,e>0?e=0:e<b.maxScrollX&&(e=b.maxScrollX),f>b.minScrollY?f=b.minScrollY:f<b.maxScrollY&&(f=b.maxScrollY),b.scrollTo(e,f,0)},_mouseout:function(a){var b=a.relatedTarget;if(!b){this._end(a);return}while(b=b.parentNode)if(b==this.wrapper)return;this._end(a)},_transitionEnd:function(a){var b=this;if(a.target!=b.scroller)return;b._unbind("webkitTransitionEnd"),b._startAni()},_startAni:function(){var b=this,c=b.x,d=b.y,e=Date.now(),f,g,h;if(b.animating)return;if(!b.steps.length){b._resetPos(400);return}f=b.steps.shift(),f.x==c&&f.y==d&&(f.time=0),b.animating=!0,b.moved=!0;if(b.options.useTransition){b._transitionTime(f.time),b._pos(f.x,f.y),b.animating=!1,f.time?b._bind("webkitTransitionEnd"):b._resetPos(0);return}h=function(){var i=Date.now(),j,l;if(i>=e+f.time){b._pos(f.x,f.y),b.animating=!1,b.options.onAnimationEnd&&b.options.onAnimationEnd.call(b),b._startAni();return}i=(i-e)/f.time-1,g=a.sqrt(1-i*i),j=(f.x-c)*g+c,l=(f.y-d)*g+d,b._pos(j,l),b.animating&&(b.aniTime=k(h))},h()},_transitionTime:function(a){a+="ms",this.scroller.style[c+"TransitionDuration"]=a,this.hScrollbar&&(this.hScrollbarIndicator.style[c+"TransitionDuration"]=a),this.vScrollbar&&(this.vScrollbarIndicator.style[c+"TransitionDuration"]=a)},_momentum:function(b,c,d,e,f){var g=6e-4,h=a.abs(b)/c,i=h*h/(2*g),j=0,k=0;return b>0&&i>d?(k=f/(6/(i/h*g)),d=d+k,h=h*d/i,i=d):b<0&&i>e&&(k=f/(6/(i/h*g)),e=e+k,h=h*e/i,i=e),i=i*(b<0?-1:1),j=h/g,{dist:i,time:a.round(j)}},_offset:function(a){var b=-a.offsetLeft,c=-a.offsetTop;while(a=a.offsetParent)b-=a.offsetLeft,c-=a.offsetTop;return a!=this.wrapper&&(b*=this.scale,c*=this.scale),{left:b,top:c}},_snap:function(b,c){var d=this,e,f,g,h,i,j;g=d.pagesX.length-1;for(e=0,f=d.pagesX.length;e<f;e++)if(b>=d.pagesX[e]){g=e;break}g==d.currPageX&&g>0&&d.dirX<0&&g--,b=d.pagesX[g],i=a.abs(b-d.pagesX[d.currPageX]),i=i?a.abs(d.x-b)/i*500:0,d.currPageX=g,g=d.pagesY.length-1;for(e=0;e<g;e++)if(c>=d.pagesY[e]){g=e;break}return g==d.currPageY&&g>0&&d.dirY<0&&g--,c=d.pagesY[g],j=a.abs(c-d.pagesY[d.currPageY]),j=j?a.abs(d.y-c)/j*500:0,d.currPageY=g,h=a.round(a.max(i,j))||200,{x:b,y:c,time:h}},_bind:function(a,b,c){(b||this.scroller).addEventListener(a,this,!!c)},_unbind:function(a,b,c){(b||this.scroller).removeEventListener(a,this,!!c)},destroy:function(){var a=this;a.scroller.style[c+"Transform"]="",a.hScrollbar=!1,a.vScrollbar=!1,a._scrollbar("h"),a._scrollbar("v"),a._unbind(m,window),a._unbind(n),a._unbind(o),a._unbind(p),a._unbind(q),a.options.hasTouch&&(a._unbind("mouseout",a.wrapper),a._unbind(r)),a.options.useTransition&&a._unbind("webkitTransitionEnd"),a.options.checkDOMChanges&&clearInterval(a.checkDOMTime),a.options.onDestroy&&a.options.onDestroy.call(a)},refresh:function(){var b=this,d,e,f,g,h=0,i=0;b.scale<b.options.zoomMin&&(b.scale=b.options.zoomMin),b.wrapperW=b.wrapper.clientWidth||1,b.wrapperH=b.wrapper.clientHeight||1,b.minScrollY=-b.options.topOffset||0,b.scrollerW=a.round(b.scroller.offsetWidth*b.scale),b.scrollerH=a.round((b.scroller.offsetHeight+b.minScrollY)*b.scale),b.maxScrollX=b.wrapperW-b.scrollerW,b.maxScrollY=b.wrapperH-b.scrollerH+b.minScrollY,b.dirX=0,b.dirY=0,b.options.onRefresh&&b.options.onRefresh.call(b),b.hScroll=b.options.hScroll&&b.maxScrollX<0,b.vScroll=b.options.vScroll&&(!b.options.bounceLock&&!b.hScroll||b.scrollerH>b.wrapperH),b.hScrollbar=b.hScroll&&b.options.hScrollbar,b.vScrollbar=b.vScroll&&b.options.vScrollbar&&b.scrollerH>b.wrapperH,d=b._offset(b.wrapper),b.wrapperOffsetLeft=-d.left,b.wrapperOffsetTop=-d.top;if(typeof b.options.snap=="string"){b.pagesX=[],b.pagesY=[],g=b.scroller.querySelectorAll(b.options.snap);for(e=0,f=g.length;e<f;e++)h=b._offset(g[e]),h.left+=b.wrapperOffsetLeft,h.top+=b.wrapperOffsetTop,b.pagesX[e]=h.left<b.maxScrollX?b.maxScrollX:h.left*b.scale,b.pagesY[e]=h.top<b.maxScrollY?b.maxScrollY:h.top*b.scale}else if(b.options.snap){b.pagesX=[];while(h>=b.maxScrollX)b.pagesX[i]=h,h=h-b.wrapperW,i++;b.maxScrollX%b.wrapperW&&(b.pagesX[b.pagesX.length]=b.maxScrollX-b.pagesX[b.pagesX.length-1]+b.pagesX[b.pagesX.length-1]),h=0,i=0,b.pagesY=[];while(h>=b.maxScrollY)b.pagesY[i]=h,h=h-b.wrapperH,i++;b.maxScrollY%b.wrapperH&&(b.pagesY[b.pagesY.length]=b.maxScrollY-b.pagesY[b.pagesY.length-1]+b.pagesY[b.pagesY.length-1])}b._scrollbar("h"),b._scrollbar("v"),b.zoomed||(b.scroller.style[c+"TransitionDuration"]="0",b._resetPos(200))},scrollTo:function(a,b,c,d){var e=this,f=a,g,h;e.stop(),f.length||(f=[{x:a,y:b,time:c,relative:d}]);for(g=0,h=f.length;g<h;g++)f[g].relative&&(f[g].x=e.x-f[g].x,f[g].y=e.y-f[g].y),e.steps.push({x:f[g].x,y:f[g].y,time:f[g].time||0});e._startAni()},scrollToElement:function(b,c){var d=this,e;b=b.nodeType?b:d.scroller.querySelector(b);if(!b)return;e=d._offset(b),e.left+=d.wrapperOffsetLeft,e.top+=d.wrapperOffsetTop,e.left=e.left>0?0:e.left<d.maxScrollX?d.maxScrollX:e.left,e.top=e.top>d.minScrollY?d.minScrollY:e.top<d.maxScrollY?d.maxScrollY:e.top,c=c===undefined?a.max(a.abs(e.left)*2,a.abs(e.top)*2):c,d.scrollTo(e.left,e.top,c)},scrollToPage:function(a,b,c){var d=this,e,f;d.options.onScrollStart&&d.options.onScrollStart.call(d),d.options.snap?(a=a=="next"?d.currPageX+1:a=="prev"?d.currPageX-1:a,b=b=="next"?d.currPageY+1:b=="prev"?d.currPageY-1:b,a=a<0?0:a>d.pagesX.length-1?d.pagesX.length-1:a,b=b<0?0:b>d.pagesY.length-1?d.pagesY.length-1:b,d.currPageX=a,d.currPageY=b,e=d.pagesX[a],f=d.pagesY[b]):(e=-d.wrapperW*a,f=-d.wrapperH*b,e<d.maxScrollX&&(e=d.maxScrollX),f<d.maxScrollY&&(f=d.maxScrollY)),d.scrollTo(e,f,c||400)},disable:function(){this.stop(),this._resetPos(0),this.enabled=!1,this._unbind(o),this._unbind(p),this._unbind(q)},enable:function(){this.enabled=!0},stop:function(){this.options.useTransition?this._unbind("webkitTransitionEnd"):l(this.aniTime),this.steps=[],this.moved=!1,this.animating=!1},zoom:function(a,b,d,e){var f=this,g=d/f.scale;if(!f.options.useTransform)return;f.zoomed=!0,e=e===undefined?200:e,a=a-f.wrapperOffsetLeft-f.x,b=b-f.wrapperOffsetTop-f.y,f.x=a-a*g+f.x,f.y=b-b*g+f.y,f.scale=d,f.refresh(),f.x=f.x>0?0:f.x<f.maxScrollX?f.maxScrollX:f.x,f.y=f.y>f.minScrollY?f.minScrollY:f.y<f.maxScrollY?f.maxScrollY:f.y,f.scroller.style[c+"TransitionDuration"]=e+"ms",f.scroller.style[c+"Transform"]=s+f.x+"px,"+f.y+"px"+t+" scale("+d+")",f.zoomed=!1},isReady:function(){return!this.moved&&!this.zoomed&&!this.animating}},typeof b!="undefined"?b.iScroll=u:window.iScroll=u}(),provide("iscroll",a.exports),!function(a,b){a.ender({iScroll:function(a){return new b(this[0],a)}},!0)}(ender,require("iscroll").iScroll)}()
View
166 examples/ender/index.html
@@ -0,0 +1,166 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
+<meta name="apple-mobile-web-app-capable" content="yes">
+<meta name="apple-mobile-web-app-status-bar-style" content="black">
+<title>iScroll demo: Carousel</title>
+
+<script src="ender.js"></script>
+<script type="text/javascript">
+$(document).ready(function () {
+ this.myScroll = $('#wrapper').iScroll({
+ snap: true,
+ momentum: false,
+ hScrollbar: false,
+ onScrollEnd: function () {
+ document.querySelector('#indicator > li.active').className = '';
+ document.querySelector('#indicator > li:nth-child(' + (this.currPageX+1) + ')').className = 'active';
+ }
+ })
+})
+
+</script>
+
+<style type="text/css" media="all">
+body,ul,li {
+ padding:10px;
+ margin:0;
+}
+
+body {
+ font-size:12px;
+ -webkit-user-select:none;
+ -webkit-text-size-adjust:none;
+ font-family:helvetica;
+}
+
+#wrapper {
+ width:300px;
+ height:160px;
+
+ float:left;
+ position:relative;
+ z-index:1;
+ overflow:hidden;
+
+ background:#aaa;
+ -webkit-border-radius:10px;
+ -moz-border-radius:10px;
+ -o-border-radius:10px;
+ border-radius:10px;
+ background:#e3e3e3;
+}
+
+#scroller {
+ width:2100px;
+ height:100%;
+ float:left;
+ padding:0;
+}
+
+#scroller ul {
+ list-style:none;
+ display:block;
+ float:left;
+ width:100%;
+ height:100%;
+ padding:0;
+ margin:0;
+ text-align:left;
+}
+
+#scroller li {
+ -webkit-box-sizing:border-box;
+ -moz-box-sizing:border-box;
+ -o-box-sizing:border-box;
+ box-sizing:border-box;
+ display:block; float:left;
+ width:300px; height:160px;
+ text-align:center;
+ font-family:georgia;
+ font-size:18px;
+ line-height:140%;
+}
+
+#nav {
+ width:300px;
+ float:left;
+}
+
+#prev, #next {
+ float:left;
+ font-weight:bold;
+ font-size:14px;
+ padding:5px 0;
+ width:80px;
+}
+
+#next {
+ float:right;
+ text-align:right;
+}
+
+#indicator, #indicator > li {
+ display:block; float:left;
+ list-style:none;
+ padding:0; margin:0;
+}
+
+#indicator {
+ width:110px;
+ padding:12px 0 0 30px;
+}
+
+#indicator > li {
+ text-indent:-9999em;
+ width:8px; height:8px;
+ -webkit-border-radius:4px;
+ -moz-border-radius:4px;
+ -o-border-radius:4px;
+ border-radius:4px;
+ background:#ddd;
+ overflow:hidden;
+ margin-right:4px;
+}
+
+#indicator > li.active {
+ background:#888;
+}
+
+#indicator > li:last-child {
+ margin:0;
+}
+
+</style>
+</head>
+<body>
+<div id="wrapper">
+ <div id="scroller">
+ <ul id="thelist">
+ <li><strong>1.</strong> <em>A robot may not injure a human being or, through inaction, allow a human being to come to harm.</em></li>
+ <li><strong>2.</strong> <em>A robot must obey any orders given to it by human beings, except where such orders would conflict with the First Law.</em></li>
+ <li><strong>3.</strong> <em>A robot must protect its own existence as long as such protection does not conflict with the First or Second Law.</em></li>
+ <li><strong>Zeroth Law:</strong> <em>A robot may not harm humanity, or, by inaction, allow humanity to come to harm.</em></li>
+ <li><strong>Lyuben Dilov's Forth law:</strong> <em>A robot must establish its identity as a robot in all cases.</em></li>
+ <li><strong>Harry Harrison's Forth law:</strong> <em>A robot must reproduce. As long as such reproduction does not interfere with the First or Second or Third Law.</em></li>
+ <li><strong>Nikola Kesarovski's Fifth law:</strong> <em>A robot must know it is a robot.</em></li>
+ </ul>
+ </div>
+</div>
+<div id="nav">
+ <div id="prev" onclick="myScroll.scrollToPage('prev', 0);return false">&larr; prev</div>
+ <ul id="indicator">
+ <li class="active">1</li>
+ <li>2</li>
+ <li>3</li>
+ <li>4</li>
+ <li>5</li>
+ <li>6</li>
+ <li>7</li>
+ </ul>
+ <div id="next" onclick="myScroll.scrollToPage('next', 0);return false">next &rarr;</div>
+</div>
+</body>
+</html>
View
14 package.json
@@ -0,0 +1,14 @@
+{
+ "name": "iscroll"
+ , "description": "smooth scrolling for mobile webkit"
+ , "version": "4.1.9"
+ , "homepage": "http://cubiq.org/iscroll-4"
+ , "author": "Matteo Spinelli <> (http://cubiq.org)"
+ , "keywords": ["ender", "iscroll", "scrolling", "webkit", "iphone", "android"]
+ , "main": "./src/iscroll.js"
+ , "ender": "./src/ender.js"
+ , "repository": {
+ "type": "git"
+ , "url": "https://github.com/cubiq/iscroll.git"
+ }
+}
View
7 src/ender.js
@@ -0,0 +1,7 @@
+!function ($, iScroll) {
+ $.ender({
+ iScroll: function (options) {
+ return new iScroll(this[0], options)
+ }
+ }, true)
+}(ender, require('iscroll').iScroll)

0 comments on commit 20666ca

Please sign in to comment.
Something went wrong with that request. Please try again.