iugu-ux 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (163) hide show
  1. data/Rakefile +14 -0
  2. data/lib/iugu-ux.rb +41 -0
  3. data/lib/iugu-ux/railtie.rb +13 -0
  4. data/lib/iugu-ux/version.rb +3 -0
  5. data/sandbox/Rakefile +7 -0
  6. data/sandbox/app/assets/images/assets-hd-s827ab39c93.png +0 -0
  7. data/sandbox/app/assets/images/assets-sf5326dcc8f.png +0 -0
  8. data/sandbox/app/assets/images/iux-default-hd-sc9d2356e0b.png +0 -0
  9. data/sandbox/app/assets/images/iux-default-s80f46e65ce.png +0 -0
  10. data/sandbox/app/assets/images/rails.png +0 -0
  11. data/sandbox/app/assets/javascripts/application.js +0 -0
  12. data/sandbox/app/assets/javascripts/web-app/config.js.erb +9 -0
  13. data/sandbox/app/assets/javascripts/web-app/i18n-languages.js.erb +12 -0
  14. data/sandbox/app/assets/javascripts/web-app/locale/en.json +11 -0
  15. data/sandbox/app/assets/javascripts/web-app/locale/pt-BR.json +11 -0
  16. data/sandbox/app/assets/javascripts/web-app/models.js +1 -0
  17. data/sandbox/app/assets/javascripts/web-app/presenters.js +1 -0
  18. data/sandbox/app/assets/javascripts/web-app/presenters/main-view.jst.eco +50 -0
  19. data/sandbox/app/assets/javascripts/web-app/usecode.js +1 -0
  20. data/sandbox/app/assets/javascripts/web-app/usecode/root-view.coffee +13 -0
  21. data/sandbox/app/assets/javascripts/web-app/usecode/router.coffee +19 -0
  22. data/sandbox/app/assets/sprites/a/assets-hd/arrow-down.png +0 -0
  23. data/sandbox/app/assets/sprites/a/assets-hd/arrow-up.png +0 -0
  24. data/sandbox/app/assets/sprites/a/assets-hd/btn-dashboard.png +0 -0
  25. data/sandbox/app/assets/sprites/a/assets-hd/btn-yell.png +0 -0
  26. data/sandbox/app/assets/sprites/a/assets-hd/clock.png +0 -0
  27. data/sandbox/app/assets/sprites/a/assets-hd/dashboard-places.png +0 -0
  28. data/sandbox/app/assets/sprites/a/assets-hd/dashboard-products.png +0 -0
  29. data/sandbox/app/assets/sprites/a/assets-hd/dashboard-spaces.png +0 -0
  30. data/sandbox/app/assets/sprites/a/assets-hd/dashboard-user.png +0 -0
  31. data/sandbox/app/assets/sprites/a/assets-hd/header-letsyell-logo.png +0 -0
  32. data/sandbox/app/assets/sprites/a/assets-hd/icon-facebook.png +0 -0
  33. data/sandbox/app/assets/sprites/a/assets-hd/icon-google.png +0 -0
  34. data/sandbox/app/assets/sprites/a/assets-hd/icon-linkedin.png +0 -0
  35. data/sandbox/app/assets/sprites/a/assets-hd/icon-twitter.png +0 -0
  36. data/sandbox/app/assets/sprites/a/assets-hd/icon-windows.png +0 -0
  37. data/sandbox/app/assets/sprites/a/assets-hd/icon-yahoo.png +0 -0
  38. data/sandbox/app/assets/sprites/a/assets-hd/place-coffee.png +0 -0
  39. data/sandbox/app/assets/sprites/a/assets-hd/right-arrow.png +0 -0
  40. data/sandbox/app/assets/sprites/a/assets-hd/stars-five.png +0 -0
  41. data/sandbox/app/assets/sprites/a/assets-hd/stars-four-half.png +0 -0
  42. data/sandbox/app/assets/sprites/a/assets-hd/stars-four.png +0 -0
  43. data/sandbox/app/assets/sprites/a/assets-hd/stars-half.png +0 -0
  44. data/sandbox/app/assets/sprites/a/assets-hd/stars-one-half.png +0 -0
  45. data/sandbox/app/assets/sprites/a/assets-hd/stars-one.png +0 -0
  46. data/sandbox/app/assets/sprites/a/assets-hd/stars-three-half.png +0 -0
  47. data/sandbox/app/assets/sprites/a/assets-hd/stars-three.png +0 -0
  48. data/sandbox/app/assets/sprites/a/assets-hd/stars-two-half.png +0 -0
  49. data/sandbox/app/assets/sprites/a/assets-hd/stars-two.png +0 -0
  50. data/sandbox/app/assets/sprites/a/assets-hd/stars-zero.png +0 -0
  51. data/sandbox/app/assets/sprites/a/assets/arrow-down.png +0 -0
  52. data/sandbox/app/assets/sprites/a/assets/arrow-up.png +0 -0
  53. data/sandbox/app/assets/sprites/a/assets/btn-dashboard.png +0 -0
  54. data/sandbox/app/assets/sprites/a/assets/btn-yell.png +0 -0
  55. data/sandbox/app/assets/sprites/a/assets/clock.png +0 -0
  56. data/sandbox/app/assets/sprites/a/assets/dashboard-places.png +0 -0
  57. data/sandbox/app/assets/sprites/a/assets/dashboard-products.png +0 -0
  58. data/sandbox/app/assets/sprites/a/assets/dashboard-spaces.png +0 -0
  59. data/sandbox/app/assets/sprites/a/assets/dashboard-user.png +0 -0
  60. data/sandbox/app/assets/sprites/a/assets/header-letsyell-logo.png +0 -0
  61. data/sandbox/app/assets/sprites/a/assets/icon-facebook.png +0 -0
  62. data/sandbox/app/assets/sprites/a/assets/icon-google.png +0 -0
  63. data/sandbox/app/assets/sprites/a/assets/icon-linkedin.png +0 -0
  64. data/sandbox/app/assets/sprites/a/assets/icon-twitter.png +0 -0
  65. data/sandbox/app/assets/sprites/a/assets/icon-windows.png +0 -0
  66. data/sandbox/app/assets/sprites/a/assets/icon-yahoo.png +0 -0
  67. data/sandbox/app/assets/sprites/a/assets/place-coffee.png +0 -0
  68. data/sandbox/app/assets/sprites/a/assets/right-arrow.png +0 -0
  69. data/sandbox/app/assets/sprites/a/assets/stars-five.png +0 -0
  70. data/sandbox/app/assets/sprites/a/assets/stars-four-half.png +0 -0
  71. data/sandbox/app/assets/sprites/a/assets/stars-four.png +0 -0
  72. data/sandbox/app/assets/sprites/a/assets/stars-half.png +0 -0
  73. data/sandbox/app/assets/sprites/a/assets/stars-one-half.png +0 -0
  74. data/sandbox/app/assets/sprites/a/assets/stars-one.png +0 -0
  75. data/sandbox/app/assets/sprites/a/assets/stars-three-half.png +0 -0
  76. data/sandbox/app/assets/sprites/a/assets/stars-three.png +0 -0
  77. data/sandbox/app/assets/sprites/a/assets/stars-two-half.png +0 -0
  78. data/sandbox/app/assets/sprites/a/assets/stars-two.png +0 -0
  79. data/sandbox/app/assets/sprites/a/assets/stars-zero.png +0 -0
  80. data/sandbox/app/assets/sprites/assets-hd/arrow-down.png +0 -0
  81. data/sandbox/app/assets/sprites/assets-hd/arrow-up.png +0 -0
  82. data/sandbox/app/assets/sprites/assets/arrow-down.png +0 -0
  83. data/sandbox/app/assets/sprites/assets/arrow-up.png +0 -0
  84. data/sandbox/app/assets/stylesheets/application.css +3 -0
  85. data/sandbox/app/assets/stylesheets/default-sprites.sass +8 -0
  86. data/sandbox/app/assets/stylesheets/experiment.sass +178 -0
  87. data/sandbox/app/assets/stylesheets/sandbox-sprites.css +6 -0
  88. data/sandbox/app/controllers/application_controller.rb +3 -0
  89. data/sandbox/app/controllers/ui_library_controller.rb +15 -0
  90. data/sandbox/app/views/layouts/ui.html.haml +18 -0
  91. data/sandbox/app/views/ui_library/boiler.html.haml +32 -0
  92. data/sandbox/app/views/ui_library/components.html.haml +189 -0
  93. data/sandbox/app/views/ui_library/index.html.haml +300 -0
  94. data/sandbox/config.ru +4 -0
  95. data/sandbox/config/application.rb +55 -0
  96. data/sandbox/config/boot.rb +10 -0
  97. data/sandbox/config/environment.rb +5 -0
  98. data/sandbox/config/environments/development.rb +35 -0
  99. data/sandbox/config/environments/production.rb +67 -0
  100. data/sandbox/config/environments/test.rb +39 -0
  101. data/sandbox/config/initializers/backtrace_silencers.rb +7 -0
  102. data/sandbox/config/initializers/inflections.rb +10 -0
  103. data/sandbox/config/initializers/mime_types.rb +5 -0
  104. data/sandbox/config/initializers/secret_token.rb +7 -0
  105. data/sandbox/config/initializers/session_store.rb +8 -0
  106. data/sandbox/config/initializers/wrap_parameters.rb +10 -0
  107. data/sandbox/config/locales/en.yml +5 -0
  108. data/sandbox/config/routes.rb +5 -0
  109. data/sandbox/doc/README_FOR_APP +2 -0
  110. data/sandbox/lib/sass/sprite_relative.rb +7 -0
  111. data/sandbox/public/404.html +26 -0
  112. data/sandbox/public/422.html +26 -0
  113. data/sandbox/public/500.html +26 -0
  114. data/sandbox/public/favicon.ico +0 -0
  115. data/sandbox/public/robots.txt +5 -0
  116. data/sandbox/script/rails +6 -0
  117. data/vendor/assets/javascripts/iugu-ux.js +7 -0
  118. data/vendor/assets/javascripts/iugu-ux/capabilities.js +209 -0
  119. data/vendor/assets/javascripts/iugu-ux/enable-prettify.js +3 -0
  120. data/vendor/assets/javascripts/iugu-ux/google-code-prettify/prettify.js +28 -0
  121. data/vendor/assets/javascripts/iugu-ux/iugu-ux.js +11 -0
  122. data/vendor/assets/javascripts/iugu-ux/twitter-bootstrap/bootstrap.js +7 -0
  123. data/vendor/assets/javascripts/iugu-ux/twitter-bootstrap/notice.js +90 -0
  124. data/vendor/assets/javascripts/iugu-ux/web-app.js +24 -0
  125. data/vendor/assets/javascripts/vendor.js +15 -0
  126. data/vendor/assets/javascripts/vendor/backbone.js +1479 -0
  127. data/vendor/assets/javascripts/vendor/gmaps.js +1058 -0
  128. data/vendor/assets/javascripts/vendor/iscroll.js +1080 -0
  129. data/vendor/assets/javascripts/vendor/jquery.base64.js +190 -0
  130. data/vendor/assets/javascripts/vendor/jquery.checkboxes.js +284 -0
  131. data/vendor/assets/javascripts/vendor/jquery.cookie.js +47 -0
  132. data/vendor/assets/javascripts/vendor/jquery.js +9267 -0
  133. data/vendor/assets/javascripts/vendor/jquery.ui.js +11363 -0
  134. data/vendor/assets/javascripts/vendor/jquery.ui.touch-punch.js +160 -0
  135. data/vendor/assets/javascripts/vendor/jquery.web-storage.js +489 -0
  136. data/vendor/assets/javascripts/vendor/underscore.js +1204 -0
  137. data/vendor/assets/javascripts/web-app/comm.coffee +1 -0
  138. data/vendor/assets/javascripts/web-app/config.js.erb +3 -0
  139. data/vendor/assets/javascripts/web-app/controllers.js +0 -0
  140. data/vendor/assets/javascripts/web-app/environment.js.coffee +8 -0
  141. data/vendor/assets/javascripts/web-app/helpers.coffee +86 -0
  142. data/vendor/assets/javascripts/web-app/i18n-languages.js +0 -0
  143. data/vendor/assets/javascripts/web-app/i18n.coffee +37 -0
  144. data/vendor/assets/javascripts/web-app/models.js +0 -0
  145. data/vendor/assets/javascripts/web-app/sound.coffee +67 -0
  146. data/vendor/assets/javascripts/web-app/views.js +0 -0
  147. data/vendor/assets/sprites/iux-default-hd/menu-icon.png +0 -0
  148. data/vendor/assets/sprites/iux-default/menu-icon.png +0 -0
  149. data/vendor/assets/stylesheets/iugu-ux.css +8 -0
  150. data/vendor/assets/stylesheets/iugu-ux/adaptative-mixins.sass +50 -0
  151. data/vendor/assets/stylesheets/iugu-ux/components.sass +185 -0
  152. data/vendor/assets/stylesheets/iugu-ux/core.sass +10 -0
  153. data/vendor/assets/stylesheets/iugu-ux/google-code-prettify/prettify.css +48 -0
  154. data/vendor/assets/stylesheets/iugu-ux/iugu-ux.sass +16 -0
  155. data/vendor/assets/stylesheets/iugu-ux/iux-sprites.sass +8 -0
  156. data/vendor/assets/stylesheets/iugu-ux/mixins.sass +32 -0
  157. data/vendor/assets/stylesheets/iugu-ux/no-js.sass +15 -0
  158. data/vendor/assets/stylesheets/iugu-ux/reset.sass +229 -0
  159. data/vendor/assets/stylesheets/iugu-ux/sprite-mixins.sass +49 -0
  160. data/vendor/assets/stylesheets/iugu-ux/typography.sass +268 -0
  161. data/vendor/assets/stylesheets/iugu-ux/utilities.sass +51 -0
  162. data/vendor/assets/stylesheets/iugu-ux/variables.sass +46 -0
  163. metadata +485 -0
@@ -0,0 +1,1080 @@
1
+ /*!
2
+ * iScroll v4.1.9 ~ Copyright (c) 2011 Matteo Spinelli, http://cubiq.org
3
+ * Released under MIT license, http://cubiq.org/license
4
+ */
5
+ (function(){
6
+ var m = Math,
7
+ mround = function (r) { return r >> 0; },
8
+ vendor = (/webkit/i).test(navigator.appVersion) ? 'webkit' :
9
+ (/firefox/i).test(navigator.userAgent) ? 'Moz' :
10
+ (/trident/i).test(navigator.userAgent) ? 'ms' :
11
+ 'opera' in window ? 'O' : '',
12
+
13
+ // Browser capabilities44
14
+ isAndroid = (/android/gi).test(navigator.appVersion),
15
+ isIDevice = (/iphone|ipad/gi).test(navigator.appVersion),
16
+ isPlaybook = (/playbook/gi).test(navigator.appVersion),
17
+ isTouchPad = (/hp-tablet/gi).test(navigator.appVersion),
18
+
19
+ has3d = 'WebKitCSSMatrix' in window && 'm11' in new WebKitCSSMatrix(),
20
+ hasTouch = 'ontouchstart' in window && !isTouchPad,
21
+ hasTransform = vendor + 'Transform' in document.documentElement.style,
22
+ hasTransitionEnd = isIDevice || isPlaybook,
23
+
24
+ nextFrame = (function() {
25
+ return window.requestAnimationFrame
26
+ || window.webkitRequestAnimationFrame
27
+ || window.mozRequestAnimationFrame
28
+ || window.oRequestAnimationFrame
29
+ || window.msRequestAnimationFrame
30
+ || function(callback) { return setTimeout(callback, 1); }
31
+ })(),
32
+ cancelFrame = (function () {
33
+ return window.cancelRequestAnimationFrame
34
+ || window.webkitCancelAnimationFrame
35
+ || window.webkitCancelRequestAnimationFrame
36
+ || window.mozCancelRequestAnimationFrame
37
+ || window.oCancelRequestAnimationFrame
38
+ || window.msCancelRequestAnimationFrame
39
+ || clearTimeout
40
+ })(),
41
+
42
+ // Events
43
+ RESIZE_EV = 'onorientationchange' in window ? 'orientationchange' : 'resize',
44
+ START_EV = hasTouch ? 'touchstart' : 'mousedown',
45
+ MOVE_EV = hasTouch ? 'touchmove' : 'mousemove',
46
+ END_EV = hasTouch ? 'touchend' : 'mouseup',
47
+ CANCEL_EV = hasTouch ? 'touchcancel' : 'mouseup',
48
+ WHEEL_EV = vendor == 'Moz' ? 'DOMMouseScroll' : 'mousewheel',
49
+
50
+ // Helpers
51
+ trnOpen = 'translate' + (has3d ? '3d(' : '('),
52
+ trnClose = has3d ? ',0)' : ')',
53
+
54
+ // Constructor
55
+ iScroll = function (el, options) {
56
+ var that = this,
57
+ doc = document,
58
+ i;
59
+
60
+ that.wrapper = typeof el == 'object' ? el : doc.getElementById(el);
61
+ that.wrapper.style.overflow = 'hidden';
62
+ that.scroller = that.wrapper.children[0];
63
+
64
+ // Default options
65
+ that.options = {
66
+ hScroll: true,
67
+ vScroll: true,
68
+ x: 0,
69
+ y: 0,
70
+ bounce: true,
71
+ bounceLock: false,
72
+ momentum: true,
73
+ lockDirection: true,
74
+ useTransform: true,
75
+ useTransition: false,
76
+ topOffset: 0,
77
+ checkDOMChanges: false, // Experimental
78
+
79
+ // Scrollbar
80
+ hScrollbar: true,
81
+ vScrollbar: true,
82
+ fixedScrollbar: isAndroid,
83
+ hideScrollbar: isIDevice,
84
+ fadeScrollbar: isIDevice && has3d,
85
+ scrollbarClass: '',
86
+
87
+ // Zoom
88
+ zoom: false,
89
+ zoomMin: 1,
90
+ zoomMax: 4,
91
+ doubleTapZoom: 2,
92
+ wheelAction: 'scroll',
93
+
94
+ // Snap
95
+ snap: false,
96
+ snapThreshold: 1,
97
+
98
+ // Events
99
+ onRefresh: null,
100
+ onBeforeScrollStart: function (e) { e.preventDefault(); },
101
+ onScrollStart: null,
102
+ onBeforeScrollMove: null,
103
+ onScrollMove: null,
104
+ onBeforeScrollEnd: null,
105
+ onScrollEnd: null,
106
+ onTouchEnd: null,
107
+ onDestroy: null,
108
+ onZoomStart: null,
109
+ onZoom: null,
110
+ onZoomEnd: null
111
+ };
112
+
113
+ // User defined options
114
+ for (i in options) that.options[i] = options[i];
115
+
116
+ // Set starting position
117
+ that.x = that.options.x;
118
+ that.y = that.options.y;
119
+
120
+ // Normalize options
121
+ that.options.useTransform = hasTransform ? that.options.useTransform : false;
122
+ that.options.hScrollbar = that.options.hScroll && that.options.hScrollbar;
123
+ that.options.vScrollbar = that.options.vScroll && that.options.vScrollbar;
124
+ that.options.zoom = that.options.useTransform && that.options.zoom;
125
+ that.options.useTransition = hasTransitionEnd && that.options.useTransition;
126
+
127
+ // Helpers FIX ANDROID BUG!
128
+ // translate3d and scale doesn't work together!
129
+ // Ignoring 3d ONLY WHEN YOU SET that.options.zoom
130
+ if ( that.options.zoom && isAndroid ){
131
+ trnOpen = 'translate(';
132
+ trnClose = ')';
133
+ }
134
+
135
+ // Set some default styles
136
+ that.scroller.style[vendor + 'TransitionProperty'] = that.options.useTransform ? '-' + vendor.toLowerCase() + '-transform' : 'top left';
137
+ that.scroller.style[vendor + 'TransitionDuration'] = '0';
138
+ that.scroller.style[vendor + 'TransformOrigin'] = '0 0';
139
+ if (that.options.useTransition) that.scroller.style[vendor + 'TransitionTimingFunction'] = 'cubic-bezier(0.33,0.66,0.66,1)';
140
+
141
+ if (that.options.useTransform) that.scroller.style[vendor + 'Transform'] = trnOpen + that.x + 'px,' + that.y + 'px' + trnClose;
142
+ else that.scroller.style.cssText += ';position:absolute;top:' + that.y + 'px;left:' + that.x + 'px';
143
+
144
+ if (that.options.useTransition) that.options.fixedScrollbar = true;
145
+
146
+ that.refresh();
147
+
148
+ that._bind(RESIZE_EV, window);
149
+ that._bind(START_EV);
150
+ if (!hasTouch) {
151
+ that._bind('mouseout', that.wrapper);
152
+ if (that.options.wheelAction != 'none')
153
+ that._bind(WHEEL_EV);
154
+ }
155
+
156
+ if (that.options.checkDOMChanges) that.checkDOMTime = setInterval(function () {
157
+ that._checkDOMChanges();
158
+ }, 500);
159
+ };
160
+
161
+ // Prototype
162
+ iScroll.prototype = {
163
+ enabled: true,
164
+ x: 0,
165
+ y: 0,
166
+ steps: [],
167
+ scale: 1,
168
+ currPageX: 0, currPageY: 0,
169
+ pagesX: [], pagesY: [],
170
+ aniTime: null,
171
+ wheelZoomCount: 0,
172
+
173
+ handleEvent: function (e) {
174
+ var that = this;
175
+ switch(e.type) {
176
+ case START_EV:
177
+ if (!hasTouch && e.button !== 0) return;
178
+ that._start(e);
179
+ break;
180
+ case MOVE_EV: that._move(e); break;
181
+ case END_EV:
182
+ case CANCEL_EV: that._end(e); break;
183
+ case RESIZE_EV: that._resize(); break;
184
+ case WHEEL_EV: that._wheel(e); break;
185
+ case 'mouseout': that._mouseout(e); break;
186
+ case 'webkitTransitionEnd': that._transitionEnd(e); break;
187
+ }
188
+ },
189
+
190
+ _checkDOMChanges: function () {
191
+ if (this.moved || this.zoomed || this.animating ||
192
+ (this.scrollerW == this.scroller.offsetWidth * this.scale && this.scrollerH == this.scroller.offsetHeight * this.scale)) return;
193
+
194
+ this.refresh();
195
+ },
196
+
197
+ _scrollbar: function (dir) {
198
+ var that = this,
199
+ doc = document,
200
+ bar;
201
+
202
+ if (!that[dir + 'Scrollbar']) {
203
+ if (that[dir + 'ScrollbarWrapper']) {
204
+ if (hasTransform) that[dir + 'ScrollbarIndicator'].style[vendor + 'Transform'] = '';
205
+ that[dir + 'ScrollbarWrapper'].parentNode.removeChild(that[dir + 'ScrollbarWrapper']);
206
+ that[dir + 'ScrollbarWrapper'] = null;
207
+ that[dir + 'ScrollbarIndicator'] = null;
208
+ }
209
+
210
+ return;
211
+ }
212
+
213
+ if (!that[dir + 'ScrollbarWrapper']) {
214
+ // Create the scrollbar wrapper
215
+ bar = doc.createElement('div');
216
+
217
+ if (that.options.scrollbarClass) bar.className = that.options.scrollbarClass + dir.toUpperCase();
218
+ 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');
219
+
220
+ 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');
221
+
222
+ that.wrapper.appendChild(bar);
223
+ that[dir + 'ScrollbarWrapper'] = bar;
224
+
225
+ // Create the scrollbar indicator
226
+ bar = doc.createElement('div');
227
+ if (!that.options.scrollbarClass) {
228
+ 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';
229
+ }
230
+ 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;
231
+ if (that.options.useTransition) bar.style.cssText += ';-' + vendor + '-transition-timing-function:cubic-bezier(0.33,0.66,0.66,1)';
232
+
233
+ that[dir + 'ScrollbarWrapper'].appendChild(bar);
234
+ that[dir + 'ScrollbarIndicator'] = bar;
235
+ }
236
+
237
+ if (dir == 'h') {
238
+ that.hScrollbarSize = that.hScrollbarWrapper.clientWidth;
239
+ that.hScrollbarIndicatorSize = m.max(mround(that.hScrollbarSize * that.hScrollbarSize / that.scrollerW), 8);
240
+ that.hScrollbarIndicator.style.width = that.hScrollbarIndicatorSize + 'px';
241
+ that.hScrollbarMaxScroll = that.hScrollbarSize - that.hScrollbarIndicatorSize;
242
+ that.hScrollbarProp = that.hScrollbarMaxScroll / that.maxScrollX;
243
+ } else {
244
+ that.vScrollbarSize = that.vScrollbarWrapper.clientHeight;
245
+ that.vScrollbarIndicatorSize = m.max(mround(that.vScrollbarSize * that.vScrollbarSize / that.scrollerH), 8);
246
+ that.vScrollbarIndicator.style.height = that.vScrollbarIndicatorSize + 'px';
247
+ that.vScrollbarMaxScroll = that.vScrollbarSize - that.vScrollbarIndicatorSize;
248
+ that.vScrollbarProp = that.vScrollbarMaxScroll / that.maxScrollY;
249
+ }
250
+
251
+ // Reset position
252
+ that._scrollbarPos(dir, true);
253
+ },
254
+
255
+ _resize: function () {
256
+ var that = this;
257
+ setTimeout(function () { that.refresh(); }, isAndroid ? 200 : 0);
258
+ },
259
+
260
+ _pos: function (x, y) {
261
+ x = this.hScroll ? x : 0;
262
+ y = this.vScroll ? y : 0;
263
+
264
+ if (this.options.useTransform) {
265
+ this.scroller.style[vendor + 'Transform'] = trnOpen + x + 'px,' + y + 'px' + trnClose + ' scale(' + this.scale + ')';
266
+ } else {
267
+ x = mround(x);
268
+ y = mround(y);
269
+ this.scroller.style.left = x + 'px';
270
+ this.scroller.style.top = y + 'px';
271
+ }
272
+
273
+ this.x = x;
274
+ this.y = y;
275
+
276
+ this._scrollbarPos('h');
277
+ this._scrollbarPos('v');
278
+ },
279
+
280
+ _scrollbarPos: function (dir, hidden) {
281
+ var that = this,
282
+ pos = dir == 'h' ? that.x : that.y,
283
+ size;
284
+
285
+ if (!that[dir + 'Scrollbar']) return;
286
+
287
+ pos = that[dir + 'ScrollbarProp'] * pos;
288
+
289
+ if (pos < 0) {
290
+ if (!that.options.fixedScrollbar) {
291
+ size = that[dir + 'ScrollbarIndicatorSize'] + mround(pos * 3);
292
+ if (size < 8) size = 8;
293
+ that[dir + 'ScrollbarIndicator'].style[dir == 'h' ? 'width' : 'height'] = size + 'px';
294
+ }
295
+ pos = 0;
296
+ } else if (pos > that[dir + 'ScrollbarMaxScroll']) {
297
+ if (!that.options.fixedScrollbar) {
298
+ size = that[dir + 'ScrollbarIndicatorSize'] - mround((pos - that[dir + 'ScrollbarMaxScroll']) * 3);
299
+ if (size < 8) size = 8;
300
+ that[dir + 'ScrollbarIndicator'].style[dir == 'h' ? 'width' : 'height'] = size + 'px';
301
+ pos = that[dir + 'ScrollbarMaxScroll'] + (that[dir + 'ScrollbarIndicatorSize'] - size);
302
+ } else {
303
+ pos = that[dir + 'ScrollbarMaxScroll'];
304
+ }
305
+ }
306
+
307
+ that[dir + 'ScrollbarWrapper'].style[vendor + 'TransitionDelay'] = '0';
308
+ that[dir + 'ScrollbarWrapper'].style.opacity = hidden && that.options.hideScrollbar ? '0' : '1';
309
+ that[dir + 'ScrollbarIndicator'].style[vendor + 'Transform'] = trnOpen + (dir == 'h' ? pos + 'px,0' : '0,' + pos + 'px') + trnClose;
310
+ },
311
+
312
+ _start: function (e) {
313
+ var that = this,
314
+ point = hasTouch ? e.touches[0] : e,
315
+ matrix, x, y,
316
+ c1, c2;
317
+
318
+ if (!that.enabled) return;
319
+
320
+ if (that.options.onBeforeScrollStart) that.options.onBeforeScrollStart.call(that, e);
321
+
322
+ if (that.options.useTransition || that.options.zoom) that._transitionTime(0);
323
+
324
+ that.moved = false;
325
+ that.animating = false;
326
+ that.zoomed = false;
327
+ that.distX = 0;
328
+ that.distY = 0;
329
+ that.absDistX = 0;
330
+ that.absDistY = 0;
331
+ that.dirX = 0;
332
+ that.dirY = 0;
333
+
334
+ // Gesture start
335
+ if (that.options.zoom && hasTouch && e.touches.length > 1) {
336
+ c1 = m.abs(e.touches[0].pageX-e.touches[1].pageX);
337
+ c2 = m.abs(e.touches[0].pageY-e.touches[1].pageY);
338
+ that.touchesDistStart = m.sqrt(c1 * c1 + c2 * c2);
339
+
340
+ that.originX = m.abs(e.touches[0].pageX + e.touches[1].pageX - that.wrapperOffsetLeft * 2) / 2 - that.x;
341
+ that.originY = m.abs(e.touches[0].pageY + e.touches[1].pageY - that.wrapperOffsetTop * 2) / 2 - that.y;
342
+
343
+ if (that.options.onZoomStart) that.options.onZoomStart.call(that, e);
344
+ }
345
+
346
+ if (that.options.momentum) {
347
+ if (that.options.useTransform) {
348
+ // Very lame general purpose alternative to CSSMatrix
349
+ matrix = getComputedStyle(that.scroller, null)[vendor + 'Transform'].replace(/[^0-9-.,]/g, '').split(',');
350
+ x = matrix[4] * 1;
351
+ y = matrix[5] * 1;
352
+ } else {
353
+ x = getComputedStyle(that.scroller, null).left.replace(/[^0-9-]/g, '') * 1;
354
+ y = getComputedStyle(that.scroller, null).top.replace(/[^0-9-]/g, '') * 1;
355
+ }
356
+
357
+ if (x != that.x || y != that.y) {
358
+ if (that.options.useTransition) that._unbind('webkitTransitionEnd');
359
+ else cancelFrame(that.aniTime);
360
+ that.steps = [];
361
+ that._pos(x, y);
362
+ }
363
+ }
364
+
365
+ that.absStartX = that.x; // Needed by snap threshold
366
+ that.absStartY = that.y;
367
+
368
+ that.startX = that.x;
369
+ that.startY = that.y;
370
+ that.pointX = point.pageX;
371
+ that.pointY = point.pageY;
372
+
373
+ that.startTime = e.timeStamp || Date.now();
374
+
375
+ if (that.options.onScrollStart) that.options.onScrollStart.call(that, e);
376
+
377
+ that._bind(MOVE_EV);
378
+ that._bind(END_EV);
379
+ that._bind(CANCEL_EV);
380
+ },
381
+
382
+ _move: function (e) {
383
+ var that = this,
384
+ point = hasTouch ? e.touches[0] : e,
385
+ deltaX = point.pageX - that.pointX,
386
+ deltaY = point.pageY - that.pointY,
387
+ newX = that.x + deltaX,
388
+ newY = that.y + deltaY,
389
+ c1, c2, scale,
390
+ timestamp = e.timeStamp || Date.now();
391
+
392
+ if (that.options.onBeforeScrollMove) that.options.onBeforeScrollMove.call(that, e);
393
+
394
+ // Zoom
395
+ if (that.options.zoom && hasTouch && e.touches.length > 1) {
396
+ c1 = m.abs(e.touches[0].pageX - e.touches[1].pageX);
397
+ c2 = m.abs(e.touches[0].pageY - e.touches[1].pageY);
398
+ that.touchesDist = m.sqrt(c1*c1+c2*c2);
399
+
400
+ that.zoomed = true;
401
+
402
+ scale = 1 / that.touchesDistStart * that.touchesDist * this.scale;
403
+
404
+ if (scale < that.options.zoomMin) scale = 0.5 * that.options.zoomMin * Math.pow(2.0, scale / that.options.zoomMin);
405
+ else if (scale > that.options.zoomMax) scale = 2.0 * that.options.zoomMax * Math.pow(0.5, that.options.zoomMax / scale);
406
+
407
+ that.lastScale = scale / this.scale;
408
+
409
+ newX = this.originX - this.originX * that.lastScale + this.x,
410
+ newY = this.originY - this.originY * that.lastScale + this.y;
411
+
412
+ this.scroller.style[vendor + 'Transform'] = trnOpen + newX + 'px,' + newY + 'px' + trnClose + ' scale(' + scale + ')';
413
+
414
+ if (that.options.onZoom) that.options.onZoom.call(that, e);
415
+ return;
416
+ }
417
+
418
+ that.pointX = point.pageX;
419
+ that.pointY = point.pageY;
420
+
421
+ // Slow down if outside of the boundaries
422
+ if (newX > 0 || newX < that.maxScrollX) {
423
+ newX = that.options.bounce ? that.x + (deltaX / 2) : newX >= 0 || that.maxScrollX >= 0 ? 0 : that.maxScrollX;
424
+ }
425
+ if (newY > that.minScrollY || newY < that.maxScrollY) {
426
+ newY = that.options.bounce ? that.y + (deltaY / 2) : newY >= that.minScrollY || that.maxScrollY >= 0 ? that.minScrollY : that.maxScrollY;
427
+ }
428
+
429
+ that.distX += deltaX;
430
+ that.distY += deltaY;
431
+ that.absDistX = m.abs(that.distX);
432
+ that.absDistY = m.abs(that.distY);
433
+
434
+ if (that.absDistX < 6 && that.absDistY < 6) {
435
+ return;
436
+ }
437
+
438
+ // Lock direction
439
+ if (that.options.lockDirection) {
440
+ if (that.absDistX > that.absDistY + 5) {
441
+ newY = that.y;
442
+ deltaY = 0;
443
+ } else if (that.absDistY > that.absDistX + 5) {
444
+ newX = that.x;
445
+ deltaX = 0;
446
+ }
447
+ }
448
+
449
+ that.moved = true;
450
+ that._pos(newX, newY);
451
+ that.dirX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0;
452
+ that.dirY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0;
453
+
454
+ if (timestamp - that.startTime > 300) {
455
+ that.startTime = timestamp;
456
+ that.startX = that.x;
457
+ that.startY = that.y;
458
+ }
459
+
460
+ if (that.options.onScrollMove) that.options.onScrollMove.call(that, e);
461
+ },
462
+
463
+ _end: function (e) {
464
+ if (hasTouch && e.touches.length != 0) return;
465
+
466
+ var that = this,
467
+ point = hasTouch ? e.changedTouches[0] : e,
468
+ target, ev,
469
+ momentumX = { dist:0, time:0 },
470
+ momentumY = { dist:0, time:0 },
471
+ duration = (e.timeStamp || Date.now()) - that.startTime,
472
+ newPosX = that.x,
473
+ newPosY = that.y,
474
+ distX, distY,
475
+ newDuration,
476
+ snap,
477
+ scale;
478
+
479
+ that._unbind(MOVE_EV);
480
+ that._unbind(END_EV);
481
+ that._unbind(CANCEL_EV);
482
+
483
+ if (that.options.onBeforeScrollEnd) that.options.onBeforeScrollEnd.call(that, e);
484
+
485
+ if (that.zoomed) {
486
+ scale = that.scale * that.lastScale;
487
+ scale = Math.max(that.options.zoomMin, scale);
488
+ scale = Math.min(that.options.zoomMax, scale);
489
+ that.lastScale = scale / that.scale;
490
+ that.scale = scale;
491
+
492
+ that.x = that.originX - that.originX * that.lastScale + that.x;
493
+ that.y = that.originY - that.originY * that.lastScale + that.y;
494
+
495
+ that.scroller.style[vendor + 'TransitionDuration'] = '200ms';
496
+ that.scroller.style[vendor + 'Transform'] = trnOpen + that.x + 'px,' + that.y + 'px' + trnClose + ' scale(' + that.scale + ')';
497
+
498
+ that.zoomed = false;
499
+ that.refresh();
500
+
501
+ if (that.options.onZoomEnd) that.options.onZoomEnd.call(that, e);
502
+ return;
503
+ }
504
+
505
+ if (!that.moved) {
506
+ if (hasTouch) {
507
+ if (that.doubleTapTimer && that.options.zoom) {
508
+ // Double tapped
509
+ clearTimeout(that.doubleTapTimer);
510
+ that.doubleTapTimer = null;
511
+ if (that.options.onZoomStart) that.options.onZoomStart.call(that, e);
512
+ that.zoom(that.pointX, that.pointY, that.scale == 1 ? that.options.doubleTapZoom : 1);
513
+ if (that.options.onZoomEnd) {
514
+ setTimeout(function() {
515
+ that.options.onZoomEnd.call(that, e);
516
+ }, 200); // 200 is default zoom duration
517
+ }
518
+ } else {
519
+ that.doubleTapTimer = setTimeout(function () {
520
+ that.doubleTapTimer = null;
521
+
522
+ // Find the last touched element
523
+ target = point.target;
524
+ while (target.nodeType != 1) target = target.parentNode;
525
+
526
+ if (target.tagName != 'SELECT' && target.tagName != 'INPUT' && target.tagName != 'TEXTAREA') {
527
+ ev = document.createEvent('MouseEvents');
528
+ ev.initMouseEvent('click', true, true, e.view, 1,
529
+ point.screenX, point.screenY, point.clientX, point.clientY,
530
+ e.ctrlKey, e.altKey, e.shiftKey, e.metaKey,
531
+ 0, null);
532
+ ev._fake = true;
533
+ target.dispatchEvent(ev);
534
+ }
535
+ }, that.options.zoom ? 250 : 0);
536
+ }
537
+ }
538
+
539
+ that._resetPos(200);
540
+
541
+ if (that.options.onTouchEnd) that.options.onTouchEnd.call(that, e);
542
+ return;
543
+ }
544
+
545
+ if (duration < 300 && that.options.momentum) {
546
+ momentumX = newPosX ? that._momentum(newPosX - that.startX, duration, -that.x, that.scrollerW - that.wrapperW + that.x, that.options.bounce ? that.wrapperW : 0) : momentumX;
547
+ 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;
548
+
549
+ newPosX = that.x + momentumX.dist;
550
+ newPosY = that.y + momentumY.dist;
551
+
552
+ if ((that.x > 0 && newPosX > 0) || (that.x < that.maxScrollX && newPosX < that.maxScrollX)) momentumX = { dist:0, time:0 };
553
+ if ((that.y > that.minScrollY && newPosY > that.minScrollY) || (that.y < that.maxScrollY && newPosY < that.maxScrollY)) momentumY = { dist:0, time:0 };
554
+ }
555
+
556
+ if (momentumX.dist || momentumY.dist) {
557
+ newDuration = m.max(m.max(momentumX.time, momentumY.time), 10);
558
+
559
+ // Do we need to snap?
560
+ if (that.options.snap) {
561
+ distX = newPosX - that.absStartX;
562
+ distY = newPosY - that.absStartY;
563
+ if (m.abs(distX) < that.options.snapThreshold && m.abs(distY) < that.options.snapThreshold) { that.scrollTo(that.absStartX, that.absStartY, 200); }
564
+ else {
565
+ snap = that._snap(newPosX, newPosY);
566
+ newPosX = snap.x;
567
+ newPosY = snap.y;
568
+ newDuration = m.max(snap.time, newDuration);
569
+ }
570
+ }
571
+
572
+ that.scrollTo(mround(newPosX), mround(newPosY), newDuration);
573
+
574
+ if (that.options.onTouchEnd) that.options.onTouchEnd.call(that, e);
575
+ return;
576
+ }
577
+
578
+ // Do we need to snap?
579
+ if (that.options.snap) {
580
+ distX = newPosX - that.absStartX;
581
+ distY = newPosY - that.absStartY;
582
+ if (m.abs(distX) < that.options.snapThreshold && m.abs(distY) < that.options.snapThreshold) that.scrollTo(that.absStartX, that.absStartY, 200);
583
+ else {
584
+ snap = that._snap(that.x, that.y);
585
+ if (snap.x != that.x || snap.y != that.y) that.scrollTo(snap.x, snap.y, snap.time);
586
+ }
587
+
588
+ if (that.options.onTouchEnd) that.options.onTouchEnd.call(that, e);
589
+ return;
590
+ }
591
+
592
+ that._resetPos(200);
593
+ if (that.options.onTouchEnd) that.options.onTouchEnd.call(that, e);
594
+ },
595
+
596
+ _resetPos: function (time) {
597
+ var that = this,
598
+ resetX = that.x >= 0 ? 0 : that.x < that.maxScrollX ? that.maxScrollX : that.x,
599
+ resetY = that.y >= that.minScrollY || that.maxScrollY > 0 ? that.minScrollY : that.y < that.maxScrollY ? that.maxScrollY : that.y;
600
+
601
+ if (resetX == that.x && resetY == that.y) {
602
+ if (that.moved) {
603
+ that.moved = false;
604
+ if (that.options.onScrollEnd) that.options.onScrollEnd.call(that); // Execute custom code on scroll end
605
+ }
606
+
607
+ if (that.hScrollbar && that.options.hideScrollbar) {
608
+ if (vendor == 'webkit') that.hScrollbarWrapper.style[vendor + 'TransitionDelay'] = '300ms';
609
+ that.hScrollbarWrapper.style.opacity = '0';
610
+ }
611
+ if (that.vScrollbar && that.options.hideScrollbar) {
612
+ if (vendor == 'webkit') that.vScrollbarWrapper.style[vendor + 'TransitionDelay'] = '300ms';
613
+ that.vScrollbarWrapper.style.opacity = '0';
614
+ }
615
+
616
+ return;
617
+ }
618
+
619
+ that.scrollTo(resetX, resetY, time || 0);
620
+ },
621
+
622
+ _wheel: function (e) {
623
+ var that = this,
624
+ wheelDeltaX, wheelDeltaY,
625
+ deltaX, deltaY,
626
+ deltaScale;
627
+
628
+ if ('wheelDeltaX' in e) {
629
+ wheelDeltaX = e.wheelDeltaX / 12;
630
+ wheelDeltaY = e.wheelDeltaY / 12;
631
+ } else if('wheelDelta' in e) {
632
+ wheelDeltaX = wheelDeltaY = e.wheelDelta / 12;
633
+ } else if ('detail' in e) {
634
+ wheelDeltaX = wheelDeltaY = -e.detail * 3;
635
+ } else {
636
+ return;
637
+ }
638
+
639
+ if (that.options.wheelAction == 'zoom') {
640
+ deltaScale = that.scale * Math.pow(2, 1/3 * (wheelDeltaY ? wheelDeltaY / Math.abs(wheelDeltaY) : 0));
641
+ if (deltaScale < that.options.zoomMin) deltaScale = that.options.zoomMin;
642
+ if (deltaScale > that.options.zoomMax) deltaScale = that.options.zoomMax;
643
+
644
+ if (deltaScale != that.scale) {
645
+ if (!that.wheelZoomCount && that.options.onZoomStart) that.options.onZoomStart.call(that, e);
646
+ that.wheelZoomCount++;
647
+
648
+ that.zoom(e.pageX, e.pageY, deltaScale, 400);
649
+
650
+ setTimeout(function() {
651
+ that.wheelZoomCount--;
652
+ if (!that.wheelZoomCount && that.options.onZoomEnd) that.options.onZoomEnd.call(that, e);
653
+ }, 400);
654
+ }
655
+
656
+ return;
657
+ }
658
+
659
+ deltaX = that.x + wheelDeltaX;
660
+ deltaY = that.y + wheelDeltaY;
661
+
662
+ if (deltaX > 0) deltaX = 0;
663
+ else if (deltaX < that.maxScrollX) deltaX = that.maxScrollX;
664
+
665
+ if (deltaY > that.minScrollY) deltaY = that.minScrollY;
666
+ else if (deltaY < that.maxScrollY) deltaY = that.maxScrollY;
667
+
668
+ that.scrollTo(deltaX, deltaY, 0);
669
+ },
670
+
671
+ _mouseout: function (e) {
672
+ var t = e.relatedTarget;
673
+
674
+ if (!t) {
675
+ this._end(e);
676
+ return;
677
+ }
678
+
679
+ while (t = t.parentNode) if (t == this.wrapper) return;
680
+
681
+ this._end(e);
682
+ },
683
+
684
+ _transitionEnd: function (e) {
685
+ var that = this;
686
+
687
+ if (e.target != that.scroller) return;
688
+
689
+ that._unbind('webkitTransitionEnd');
690
+
691
+ that._startAni();
692
+ },
693
+
694
+
695
+ /**
696
+ *
697
+ * Utilities
698
+ *
699
+ */
700
+ _startAni: function () {
701
+ var that = this,
702
+ startX = that.x, startY = that.y,
703
+ startTime = Date.now(),
704
+ step, easeOut,
705
+ animate;
706
+
707
+ if (that.animating) return;
708
+
709
+ if (!that.steps.length) {
710
+ that._resetPos(400);
711
+ return;
712
+ }
713
+
714
+ step = that.steps.shift();
715
+
716
+ if (step.x == startX && step.y == startY) step.time = 0;
717
+
718
+ that.animating = true;
719
+ that.moved = true;
720
+
721
+ if (that.options.useTransition) {
722
+ that._transitionTime(step.time);
723
+ that._pos(step.x, step.y);
724
+ that.animating = false;
725
+ if (step.time) that._bind('webkitTransitionEnd');
726
+ else that._resetPos(0);
727
+ return;
728
+ }
729
+
730
+ animate = function () {
731
+ var now = Date.now(),
732
+ newX, newY;
733
+
734
+ if (now >= startTime + step.time) {
735
+ that._pos(step.x, step.y);
736
+ that.animating = false;
737
+ if (that.options.onAnimationEnd) that.options.onAnimationEnd.call(that); // Execute custom code on animation end
738
+ that._startAni();
739
+ return;
740
+ }
741
+
742
+ now = (now - startTime) / step.time - 1;
743
+ easeOut = m.sqrt(1 - now * now);
744
+ newX = (step.x - startX) * easeOut + startX;
745
+ newY = (step.y - startY) * easeOut + startY;
746
+ that._pos(newX, newY);
747
+ if (that.animating) that.aniTime = nextFrame(animate);
748
+ };
749
+
750
+ animate();
751
+ },
752
+
753
+ _transitionTime: function (time) {
754
+ time += 'ms';
755
+ this.scroller.style[vendor + 'TransitionDuration'] = time;
756
+ if (this.hScrollbar) this.hScrollbarIndicator.style[vendor + 'TransitionDuration'] = time;
757
+ if (this.vScrollbar) this.vScrollbarIndicator.style[vendor + 'TransitionDuration'] = time;
758
+ },
759
+
760
+ _momentum: function (dist, time, maxDistUpper, maxDistLower, size) {
761
+ var deceleration = 0.0006,
762
+ speed = m.abs(dist) / time,
763
+ newDist = (speed * speed) / (2 * deceleration),
764
+ newTime = 0, outsideDist = 0;
765
+
766
+ // Proportinally reduce speed if we are outside of the boundaries
767
+ if (dist > 0 && newDist > maxDistUpper) {
768
+ outsideDist = size / (6 / (newDist / speed * deceleration));
769
+ maxDistUpper = maxDistUpper + outsideDist;
770
+ speed = speed * maxDistUpper / newDist;
771
+ newDist = maxDistUpper;
772
+ } else if (dist < 0 && newDist > maxDistLower) {
773
+ outsideDist = size / (6 / (newDist / speed * deceleration));
774
+ maxDistLower = maxDistLower + outsideDist;
775
+ speed = speed * maxDistLower / newDist;
776
+ newDist = maxDistLower;
777
+ }
778
+
779
+ newDist = newDist * (dist < 0 ? -1 : 1);
780
+ newTime = speed / deceleration;
781
+
782
+ return { dist: newDist, time: mround(newTime) };
783
+ },
784
+
785
+ _offset: function (el) {
786
+ var left = -el.offsetLeft,
787
+ top = -el.offsetTop;
788
+
789
+ while (el = el.offsetParent) {
790
+ left -= el.offsetLeft;
791
+ top -= el.offsetTop;
792
+ }
793
+
794
+ if (el != this.wrapper) {
795
+ left *= this.scale;
796
+ top *= this.scale;
797
+ }
798
+
799
+ return { left: left, top: top };
800
+ },
801
+
802
+ _snap: function (x, y) {
803
+ var that = this,
804
+ i, l,
805
+ page, time,
806
+ sizeX, sizeY;
807
+
808
+ // Check page X
809
+ page = that.pagesX.length - 1;
810
+ for (i=0, l=that.pagesX.length; i<l; i++) {
811
+ if (x >= that.pagesX[i]) {
812
+ page = i;
813
+ break;
814
+ }
815
+ }
816
+ if (page == that.currPageX && page > 0 && that.dirX < 0) page--;
817
+ x = that.pagesX[page];
818
+ sizeX = m.abs(x - that.pagesX[that.currPageX]);
819
+ sizeX = sizeX ? m.abs(that.x - x) / sizeX * 500 : 0;
820
+ that.currPageX = page;
821
+
822
+ // Check page Y
823
+ page = that.pagesY.length-1;
824
+ for (i=0; i<page; i++) {
825
+ if (y >= that.pagesY[i]) {
826
+ page = i;
827
+ break;
828
+ }
829
+ }
830
+ if (page == that.currPageY && page > 0 && that.dirY < 0) page--;
831
+ y = that.pagesY[page];
832
+ sizeY = m.abs(y - that.pagesY[that.currPageY]);
833
+ sizeY = sizeY ? m.abs(that.y - y) / sizeY * 500 : 0;
834
+ that.currPageY = page;
835
+
836
+ // Snap with constant speed (proportional duration)
837
+ time = mround(m.max(sizeX, sizeY)) || 200;
838
+
839
+ return { x: x, y: y, time: time };
840
+ },
841
+
842
+ _bind: function (type, el, bubble) {
843
+ (el || this.scroller).addEventListener(type, this, !!bubble);
844
+ },
845
+
846
+ _unbind: function (type, el, bubble) {
847
+ (el || this.scroller).removeEventListener(type, this, !!bubble);
848
+ },
849
+
850
+
851
+ /**
852
+ *
853
+ * Public methods
854
+ *
855
+ */
856
+ destroy: function () {
857
+ var that = this;
858
+
859
+ that.scroller.style[vendor + 'Transform'] = '';
860
+
861
+ // Remove the scrollbars
862
+ that.hScrollbar = false;
863
+ that.vScrollbar = false;
864
+ that._scrollbar('h');
865
+ that._scrollbar('v');
866
+
867
+ // Remove the event listeners
868
+ that._unbind(RESIZE_EV, window);
869
+ that._unbind(START_EV);
870
+ that._unbind(MOVE_EV);
871
+ that._unbind(END_EV);
872
+ that._unbind(CANCEL_EV);
873
+
874
+ if (!that.options.hasTouch) {
875
+ that._unbind('mouseout', that.wrapper);
876
+ that._unbind(WHEEL_EV);
877
+ }
878
+
879
+ if (that.options.useTransition) that._unbind('webkitTransitionEnd');
880
+
881
+ if (that.options.checkDOMChanges) clearInterval(that.checkDOMTime);
882
+
883
+ if (that.options.onDestroy) that.options.onDestroy.call(that);
884
+ },
885
+
886
+ refresh: function () {
887
+ var that = this,
888
+ offset,
889
+ i, l,
890
+ els,
891
+ pos = 0,
892
+ page = 0;
893
+
894
+ if (that.scale < that.options.zoomMin) that.scale = that.options.zoomMin;
895
+ that.wrapperW = that.wrapper.clientWidth || 1;
896
+ that.wrapperH = that.wrapper.clientHeight || 1;
897
+
898
+ that.minScrollY = -that.options.topOffset || 0;
899
+ that.scrollerW = mround(that.scroller.offsetWidth * that.scale);
900
+ that.scrollerH = mround((that.scroller.offsetHeight + that.minScrollY) * that.scale);
901
+ that.maxScrollX = that.wrapperW - that.scrollerW;
902
+ that.maxScrollY = that.wrapperH - that.scrollerH + that.minScrollY;
903
+ that.dirX = 0;
904
+ that.dirY = 0;
905
+
906
+ if (that.options.onRefresh) that.options.onRefresh.call(that);
907
+
908
+ that.hScroll = that.options.hScroll && that.maxScrollX < 0;
909
+ that.vScroll = that.options.vScroll && (!that.options.bounceLock && !that.hScroll || that.scrollerH > that.wrapperH);
910
+
911
+ that.hScrollbar = that.hScroll && that.options.hScrollbar;
912
+ that.vScrollbar = that.vScroll && that.options.vScrollbar && that.scrollerH > that.wrapperH;
913
+
914
+ offset = that._offset(that.wrapper);
915
+ that.wrapperOffsetLeft = -offset.left;
916
+ that.wrapperOffsetTop = -offset.top;
917
+
918
+ // Prepare snap
919
+ if (typeof that.options.snap == 'string') {
920
+ that.pagesX = [];
921
+ that.pagesY = [];
922
+ els = that.scroller.querySelectorAll(that.options.snap);
923
+ for (i=0, l=els.length; i<l; i++) {
924
+ pos = that._offset(els[i]);
925
+ pos.left += that.wrapperOffsetLeft;
926
+ pos.top += that.wrapperOffsetTop;
927
+ that.pagesX[i] = pos.left < that.maxScrollX ? that.maxScrollX : pos.left * that.scale;
928
+ that.pagesY[i] = pos.top < that.maxScrollY ? that.maxScrollY : pos.top * that.scale;
929
+ }
930
+ } else if (that.options.snap) {
931
+ that.pagesX = [];
932
+ while (pos >= that.maxScrollX) {
933
+ that.pagesX[page] = pos;
934
+ pos = pos - that.wrapperW;
935
+ page++;
936
+ }
937
+ if (that.maxScrollX%that.wrapperW) that.pagesX[that.pagesX.length] = that.maxScrollX - that.pagesX[that.pagesX.length-1] + that.pagesX[that.pagesX.length-1];
938
+
939
+ pos = 0;
940
+ page = 0;
941
+ that.pagesY = [];
942
+ while (pos >= that.maxScrollY) {
943
+ that.pagesY[page] = pos;
944
+ pos = pos - that.wrapperH;
945
+ page++;
946
+ }
947
+ if (that.maxScrollY%that.wrapperH) that.pagesY[that.pagesY.length] = that.maxScrollY - that.pagesY[that.pagesY.length-1] + that.pagesY[that.pagesY.length-1];
948
+ }
949
+
950
+ // Prepare the scrollbars
951
+ that._scrollbar('h');
952
+ that._scrollbar('v');
953
+
954
+ if (!that.zoomed) {
955
+ that.scroller.style[vendor + 'TransitionDuration'] = '0';
956
+ //that._resetPos(200);
957
+ that._resetPos(0);
958
+ }
959
+ },
960
+
961
+ scrollTo: function (x, y, time, relative) {
962
+ var that = this,
963
+ step = x,
964
+ i, l;
965
+
966
+ that.stop();
967
+
968
+ if (!step.length) step = [{ x: x, y: y, time: time, relative: relative }];
969
+
970
+ for (i=0, l=step.length; i<l; i++) {
971
+ if (step[i].relative) { step[i].x = that.x - step[i].x; step[i].y = that.y - step[i].y; }
972
+ that.steps.push({ x: step[i].x, y: step[i].y, time: step[i].time || 0 });
973
+ }
974
+
975
+ that._startAni();
976
+ },
977
+
978
+ scrollToElement: function (el, time) {
979
+ var that = this, pos;
980
+ el = el.nodeType ? el : that.scroller.querySelector(el);
981
+ if (!el) return;
982
+
983
+ pos = that._offset(el);
984
+ pos.left += that.wrapperOffsetLeft;
985
+ pos.top += that.wrapperOffsetTop;
986
+
987
+ pos.left = pos.left > 0 ? 0 : pos.left < that.maxScrollX ? that.maxScrollX : pos.left;
988
+ pos.top = pos.top > that.minScrollY ? that.minScrollY : pos.top < that.maxScrollY ? that.maxScrollY : pos.top;
989
+ time = time === undefined ? m.max(m.abs(pos.left)*2, m.abs(pos.top)*2) : time;
990
+
991
+ that.scrollTo(pos.left, pos.top, time);
992
+ },
993
+
994
+ scrollToPage: function (pageX, pageY, time) {
995
+ var that = this, x, y;
996
+
997
+ time = time === undefined ? 400 : time;
998
+
999
+ if (that.options.onScrollStart) that.options.onScrollStart.call(that);
1000
+
1001
+ if (that.options.snap) {
1002
+ pageX = pageX == 'next' ? that.currPageX+1 : pageX == 'prev' ? that.currPageX-1 : pageX;
1003
+ pageY = pageY == 'next' ? that.currPageY+1 : pageY == 'prev' ? that.currPageY-1 : pageY;
1004
+
1005
+ pageX = pageX < 0 ? 0 : pageX > that.pagesX.length-1 ? that.pagesX.length-1 : pageX;
1006
+ pageY = pageY < 0 ? 0 : pageY > that.pagesY.length-1 ? that.pagesY.length-1 : pageY;
1007
+
1008
+ that.currPageX = pageX;
1009
+ that.currPageY = pageY;
1010
+ x = that.pagesX[pageX];
1011
+ y = that.pagesY[pageY];
1012
+ } else {
1013
+ x = -that.wrapperW * pageX;
1014
+ y = -that.wrapperH * pageY;
1015
+ if (x < that.maxScrollX) x = that.maxScrollX;
1016
+ if (y < that.maxScrollY) y = that.maxScrollY;
1017
+ }
1018
+
1019
+ that.scrollTo(x, y, time);
1020
+ },
1021
+
1022
+ disable: function () {
1023
+ this.stop();
1024
+ this._resetPos(0);
1025
+ this.enabled = false;
1026
+
1027
+ // If disabled after touchstart we make sure that there are no left over events
1028
+ this._unbind(MOVE_EV);
1029
+ this._unbind(END_EV);
1030
+ this._unbind(CANCEL_EV);
1031
+ },
1032
+
1033
+ enable: function () {
1034
+ this.enabled = true;
1035
+ },
1036
+
1037
+ stop: function () {
1038
+ if (this.options.useTransition) this._unbind('webkitTransitionEnd');
1039
+ else cancelFrame(this.aniTime);
1040
+ this.steps = [];
1041
+ this.moved = false;
1042
+ this.animating = false;
1043
+ },
1044
+
1045
+ zoom: function (x, y, scale, time) {
1046
+ var that = this,
1047
+ relScale = scale / that.scale;
1048
+
1049
+ if (!that.options.useTransform) return;
1050
+
1051
+ that.zoomed = true;
1052
+ time = time === undefined ? 200 : time;
1053
+ x = x - that.wrapperOffsetLeft - that.x;
1054
+ y = y - that.wrapperOffsetTop - that.y;
1055
+ that.x = x - x * relScale + that.x;
1056
+ that.y = y - y * relScale + that.y;
1057
+
1058
+ that.scale = scale;
1059
+ that.refresh();
1060
+
1061
+ that.x = that.x > 0 ? 0 : that.x < that.maxScrollX ? that.maxScrollX : that.x;
1062
+ that.y = that.y > that.minScrollY ? that.minScrollY : that.y < that.maxScrollY ? that.maxScrollY : that.y;
1063
+
1064
+ that.scroller.style[vendor + 'TransitionDuration'] = time + 'ms';
1065
+ that.scroller.style[vendor + 'Transform'] = trnOpen + that.x + 'px,' + that.y + 'px' + trnClose + ' scale(' + scale + ')';
1066
+ that.zoomed = false;
1067
+ },
1068
+
1069
+ isReady: function () {
1070
+ return !this.moved && !this.zoomed && !this.animating;
1071
+ }
1072
+ };
1073
+
1074
+ if (typeof exports !== 'undefined') exports.iScroll = iScroll;
1075
+ else window.iScroll = iScroll;
1076
+
1077
+ })();
1078
+
1079
+ document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
1080
+