pushpop-rails 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. data/README.md +42 -0
  2. data/Rakefile +29 -0
  3. data/lib/generators/pushpop/install/install_generator.rb +17 -0
  4. data/lib/pushpop-rails.rb +4 -0
  5. data/lib/pushpop/rails.rb +8 -0
  6. data/lib/pushpop/rails/engine.rb +7 -0
  7. data/lib/pushpop/rails/version.rb +5 -0
  8. data/vendor/assets/Pushpop/background.png +0 -0
  9. data/vendor/assets/Pushpop/background@2x.png +0 -0
  10. data/vendor/assets/Pushpop/externals/scrollkit/background.png +0 -0
  11. data/vendor/assets/Pushpop/externals/scrollkit/scrollkit.css +202 -0
  12. data/vendor/assets/Pushpop/externals/scrollkit/scrollkit.js +924 -0
  13. data/vendor/assets/Pushpop/font/pushpop-glyphs-webfont.eot +0 -0
  14. data/vendor/assets/Pushpop/font/pushpop-glyphs-webfont.svg +57 -0
  15. data/vendor/assets/Pushpop/font/pushpop-glyphs-webfont.ttf +0 -0
  16. data/vendor/assets/Pushpop/font/pushpop-glyphs-webfont.woff +0 -0
  17. data/vendor/assets/Pushpop/pushpop-modal-view-stack/pushpop-modal-view-stack.css +148 -0
  18. data/vendor/assets/Pushpop/pushpop-modal-view-stack/pushpop-modal-view-stack.js +306 -0
  19. data/vendor/assets/Pushpop/pushpop-popover-view-stack/pushpop-popover-view-stack.css +170 -0
  20. data/vendor/assets/Pushpop/pushpop-popover-view-stack/pushpop-popover-view-stack.js +278 -0
  21. data/vendor/assets/Pushpop/pushpop-split-view/pushpop-split-view.css +38 -0
  22. data/vendor/assets/Pushpop/pushpop-split-view/pushpop-split-view.js +33 -0
  23. data/vendor/assets/Pushpop/pushpop-tab-view/pushpop-tab-view.css +130 -0
  24. data/vendor/assets/Pushpop/pushpop-tab-view/pushpop-tab-view.js +298 -0
  25. data/vendor/assets/Pushpop/pushpop-table-view/pushpop-table-view.css +1273 -0
  26. data/vendor/assets/Pushpop/pushpop-table-view/pushpop-table-view.js +2275 -0
  27. data/vendor/assets/Pushpop/pushpop.css +2243 -0
  28. data/vendor/assets/Pushpop/pushpop.js +1554 -0
  29. data/vendor/assets/javascripts/pushpop_rails.js +7 -0
  30. data/vendor/assets/stylesheets/pushpop_rails.css +9 -0
  31. metadata +92 -0
@@ -0,0 +1,42 @@
1
+ pushpop-rails
2
+ =============
3
+
4
+ pushpop-rails integrates Entropi's Pushpop HTML5 Web Development Framework in to the Rails Asset Pipeline. For more information on the Pushpop framework, please [view the Pushpop project page](https://github.com/entropillc/Pushpop) on GitHub
5
+
6
+ Installation
7
+ -------------
8
+
9
+ Add the following to your Gemfile
10
+
11
+ gem "pushpop-rails", :git => "git://github.com/entropillc/pushpop-rails.git"
12
+
13
+ Then install the bundle
14
+
15
+ bundle install
16
+
17
+ Finally, run the install generator
18
+
19
+ rails g pushpop:install
20
+
21
+ Understanding pushpop-rails
22
+ -------------
23
+
24
+ pushpop-rails provides a way for easy integration between PushPop and the Rails asset pipeline. If you are using the source of this gem, the Pushpop project is stored under vendor/assets/Pushpop. When working with the source, make sure to initialize all git submodules
25
+
26
+ git submodule update --init --recurisve
27
+
28
+ This should pull all dependent submodules in to the project for use.
29
+
30
+ There are two manifest files: vendor/assets/javascripts/pushpop_rails.js and vendor/assets/stylesheets/pushpop_rails.css. These manifest files include various javascript and css dependencies in to one file, to make it easier to require in the main manifest file of your rails application. These are also put in place by the installer
31
+
32
+ You can also make these includes manually if you wish. For javascript the includes would be
33
+
34
+ //= require externals/scrollkit/scrollkit
35
+ //= require pushpop
36
+ //= require pushpop-tableview/pushpop-tableview
37
+
38
+ And for CSS the includes would be
39
+
40
+ *= require externals/scrollkit/scrollkit
41
+ *= require pushpop.css
42
+ *= require pushpop-tableview/pushpop-tableview.css
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'pushpop-rails'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
24
+ load 'rails/tasks/engine.rake'
25
+
26
+
27
+
28
+ Bundler::GemHelper.install_tasks
29
+
@@ -0,0 +1,17 @@
1
+ require 'rails/generators/base'
2
+
3
+ module Pushpop
4
+ module Generators
5
+ class InstallGenerator < ::Rails::Generators::Base
6
+
7
+ def add_javascript
8
+ insert_into_file "app/assets/javascripts/application.js","//= require pushpop_rails\n", :before => "//= require_tree ."
9
+ end
10
+
11
+ def add_css
12
+ insert_into_file "app/assets/stylesheets/application.css", " *= require pushpop_rails\n", :after => "*= require_tree .\n"
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,4 @@
1
+ require "pushpop/rails"
2
+
3
+ module Pushpop
4
+ end
@@ -0,0 +1,8 @@
1
+ module Pushpop
2
+ module Rails
3
+
4
+ end
5
+ end
6
+
7
+ require 'pushpop/rails/engine'
8
+ require 'pushpop/rails/version'
@@ -0,0 +1,7 @@
1
+ module Pushpop
2
+ module Rails
3
+ class Engine < ::Rails::Engine
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ module Pushpop
2
+ module Rails
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
@@ -0,0 +1,202 @@
1
+ * {
2
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
3
+ -webkit-text-size-adjust: none;
4
+ -webkit-touch-callout: none;
5
+ -webkit-user-drag: none;
6
+ }
7
+
8
+ html {
9
+ background: #000;
10
+ width: 100%;
11
+ height: 100%;
12
+ margin: 0;
13
+ padding: 0;
14
+ overflow: hidden;
15
+ -webkit-text-size-adjust: 100%;
16
+ -moz-text-size-adjust: 100%;
17
+ -ms-text-size-adjust: 100%;
18
+ -o-text-size-adjust: 100%;
19
+ text-size-adjust: 100%;
20
+ }
21
+
22
+ body {
23
+ background: #000;
24
+ position: absolute;
25
+ width: 100%;
26
+ height: 100%;
27
+ margin: 0;
28
+ padding: 0;
29
+ overflow: hidden;
30
+ }
31
+
32
+ .sk-scroll-view {
33
+ background: #333 url('background.png');
34
+ background-size: 256px 256px;
35
+ position: absolute;
36
+ width: 100%;
37
+ height: 100%;
38
+ top: 0;
39
+ left: 0;
40
+ margin: 0;
41
+ padding: 0;
42
+ overflow: hidden;
43
+ -webkit-user-select: none;
44
+ -moz-user-select: none;
45
+ -ms-user-select: none;
46
+ -o-user-select: none;
47
+ user-select: none;
48
+ -webkit-backface-visibility: hidden;
49
+ -moz-backface-visibility: hidden;
50
+ -ms-backface-visibility: hidden;
51
+ -o-backface-visibility: hidden;
52
+ backface-visibility: hidden;
53
+ -webkit-transform: translate3d(0, 0, 0);
54
+ -moz-transform: translate(0, 0);
55
+ -ms-transform: translate(0, 0);
56
+ -o-transform: translate(0, 0);
57
+ transform: translate(0, 0);
58
+ }
59
+
60
+ @media only screen and (-webkit-min-device-pixel-ratio: 2) {
61
+ .sk-scroll-view {
62
+ background: #333 url('background@2x.png');
63
+ }
64
+ }
65
+
66
+ .sk-scroll-view.sk-scroll-view-plain, .sk-scroll-view.sk-scroll-view-plain > .sk-scroll-content {
67
+ background: none;
68
+ }
69
+
70
+ .sk-scroll-view.sk-no-touch {
71
+ overflow: auto;
72
+ -webkit-transform: none;
73
+ -moz-transform: none;
74
+ -ms-transform: none;
75
+ -o-transform: none;
76
+ transform: none;
77
+ }
78
+
79
+ .sk-no-touch::-webkit-scrollbar {
80
+ background: #ddd;
81
+ width: 12px;
82
+ height: 12px;
83
+ }
84
+
85
+ .sk-no-touch::-webkit-scrollbar-thumb {
86
+ background: rgba(0, 0, 0, 0.5);
87
+ -webkit-border-radius: 10px;
88
+ border-radius: 10px;
89
+ }
90
+
91
+ .sk-no-touch::-webkit-scrollbar-track {
92
+ -webkit-box-shadow: inset 0 0 6px 0 rgba(0, 0, 0, 0.3);
93
+ box-shadow: inset 0 0 6px 0 rgba(0, 0, 0, 0.3);
94
+ -webkit-border-radius: 10px;
95
+ border-radius: 10px;
96
+ }
97
+
98
+ .sk-scroll-content {
99
+ background: #ddd;
100
+ position: absolute;
101
+ min-width: 100%;
102
+ width: auto;
103
+ min-height: 100%;
104
+ height: auto;
105
+ top: 0;
106
+ left: 0;
107
+ margin: 0;
108
+ padding: 0;
109
+ overflow: visible;
110
+ -webkit-backface-visibility: hidden;
111
+ -moz-backface-visibility: hidden;
112
+ -ms-backface-visibility: hidden;
113
+ -o-backface-visibility: hidden;
114
+ backface-visibility: hidden;
115
+ -webkit-transform: translate3d(0, 0, 0);
116
+ -moz-transform: translate(0, 0);
117
+ -ms-transform: translate(0, 0);
118
+ -o-transform: translate(0, 0);
119
+ transform: translate(0, 0);
120
+ -webkit-transition: -webkit-transform 0s ease;
121
+ -moz-transition: -moz-transform 0s ease;
122
+ -ms-transition: -ms-transform 0s ease;
123
+ -o-transition: -o-transform 0s ease;
124
+ transition: transform 0s ease;
125
+ }
126
+
127
+ .sk-no-touch > .sk-scroll-content {
128
+ -webkit-transform: none;
129
+ -moz-transform: none;
130
+ -ms-transform: none;
131
+ -o-transform: none;
132
+ transform: none;
133
+ -webkit-transition: none;
134
+ -moz-transition: none;
135
+ -ms-transition: none;
136
+ -o-transition: none;
137
+ transition: none;
138
+ }
139
+
140
+ .sk-scroll-indicator {
141
+ background: rgba(0, 0, 0, 1);
142
+ border: 1px solid rgba(255, 255, 255, 0.8);
143
+ position: absolute;
144
+ width: 5px;
145
+ height: 5px;
146
+ margin: 2px;
147
+ opacity: 0.5;
148
+ -webkit-border-radius: 5px;
149
+ -moz-border-radius: 5px;
150
+ border-radius: 5px;
151
+ -webkit-backface-visibility: hidden;
152
+ -moz-backface-visibility: hidden;
153
+ -ms-backface-visibility: hidden;
154
+ -o-backface-visibility: hidden;
155
+ backface-visibility: hidden;
156
+ -webkit-transform: translate3d(0, 0, 0);
157
+ -moz-transform: translate(0, 0);
158
+ -ms-transform: translate(0, 0);
159
+ -o-transform: translate(0, 0);
160
+ transform: translate(0, 0);
161
+ -webkit-transition: opacity 0.1s ease 0s, -webkit-transform 0s ease;
162
+ -moz-transition: opacity 0.1s ease 0s, -moz-transform 0s ease;
163
+ -ms-transition: opacity 0.1s ease 0s, -ms-transform 0s ease;
164
+ -o-transition: opacity 0.1s ease 0s, -o-transform 0s ease;
165
+ transition: opacity 0.1s ease 0s, transform 0s ease;
166
+ }
167
+
168
+ .sk-scroll-indicator.sk-hidden {
169
+ opacity: 0;
170
+ -webkit-transition: opacity 0.3s ease 0.3s, -webkit-transform 0s ease;
171
+ -moz-transition: opacity 0.3s ease 0.3s, -moz-transform 0s ease;
172
+ -ms-transition: opacity 0.3s ease 0.3s, -ms-transform 0s ease;
173
+ -o-transition: opacity 0.3s ease 0.3s, -o-transform 0s ease;
174
+ transition: opacity 0.3s ease 0.3s, transform 0s ease;
175
+ }
176
+
177
+ .sk-page-container-horizontal {
178
+ display: inline-block;
179
+ float: left;
180
+ list-style: none;
181
+ margin: 0;
182
+ padding: 0;
183
+ white-space: nowrap;
184
+ min-width: 100%;
185
+ width: auto;
186
+ height: 100%;
187
+ overflow: hidden;
188
+ overflow-x: auto;
189
+ position: relative;
190
+ }
191
+
192
+ .sk-page-container-horizontal > li {
193
+ display: inline-block;
194
+ float: left;
195
+ list-style-type: none;
196
+ margin: 0;
197
+ padding: 0;
198
+ white-space: normal;
199
+ width: 100%;
200
+ height: 100%;
201
+ position: relative;
202
+ }
@@ -0,0 +1,924 @@
1
+ ;'use strict';
2
+
3
+ // Polyfill for window.requestAnimationFrame and window.cancelAnimationFrame.
4
+ (function(){var a=0;var b=['webkit','moz','ms','o'];for(var c=0;c<b.length&&!window.requestAnimationFrame;c++){window.requestAnimationFrame=window[b[c]+'RequestAnimationFrame'];window.cancelAnimationFrame=window[b[c]+'CancelAnimationFrame']||window[b[c]+'RequestCancelAnimationFrame'];}if(!window.requestAnimationFrame){window.requestAnimationFrame=function(b,c){var d=Date['now']?Date.now():+(new Date());var e=Math.max(0,16-(d-a));var f=window.setTimeout(function(){b(d+e);},e);a=d+e;return f;};}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=function(a){window.clearTimeout(a);};}})();
5
+
6
+ // The base ScrollKit object.
7
+ var ScrollKit = window['ScrollKit'] || {};
8
+
9
+ ScrollKit.Params = {
10
+ bounceTransitionDuration: 0.3,
11
+ accelerationTimeout: 250,
12
+ acceleration: 20,
13
+ elasticDeceleration: 0.03,
14
+ elasticAcceleration: 0.18,
15
+ minimumDecelerationVelocity: 1,
16
+ decelerationFactor: 0.85,
17
+ minimumVelocity: 0.01,
18
+ minimumDeltaForScrollEvent: 0.5,
19
+ minimumPageTurnVelocity: 5
20
+ };
21
+
22
+ /**
23
+
24
+ */
25
+ ScrollKit.Util = {
26
+
27
+ /**
28
+
29
+ */
30
+ getCoordinatesForEvent: function(evt, identifier) {
31
+ if (evt.type.indexOf('mouse') !== -1) return { x: evt.pageX, y: evt.pageY };
32
+
33
+ evt = evt.originalEvent;
34
+
35
+ var touch = (identifier) ? this.getTouchWithIdentifier(evt.touches, identifier) : this.getTouchWithIdentifier(evt.targetTouches);
36
+ return { x: touch.pageX, y: touch.pageY };
37
+ },
38
+
39
+ /**
40
+
41
+ */
42
+ getTouchWithIdentifier: function(touches, identifier) {
43
+ if (touches.length === 0) return null;
44
+ if (!identifier) return touches[0];
45
+
46
+ for (var i = 0, length = touches.length, touch; i < length; i++) {
47
+ if ((touch = touches[i]).identifier === identifier) return touch;
48
+ }
49
+
50
+ return null;
51
+ },
52
+
53
+ /**
54
+
55
+ */
56
+ getDeltaForCoordinates: function(coordA, coordB) {
57
+ return { x: coordA.x - coordB.x, y: coordA.y - coordB.y };
58
+ },
59
+
60
+ /**
61
+
62
+ */
63
+ getVendorPrefix: function() {
64
+ if ('result' in arguments.callee) return arguments.callee.result;
65
+
66
+ var regExp = /^(Moz|Webkit|Khtml|O|ms|Icab)(?=[A-Z])/;
67
+ var script = document.createElement('script');
68
+
69
+ for (var prop in script.style) {
70
+ if (regExp.test(prop)) return arguments.callee.result = prop.match(regExp)[0];
71
+ }
72
+
73
+ if ('WebkitOpacity' in script.style) return arguments.callee.result = 'Webkit';
74
+ if ('KhtmlOpacity' in script.style) return arguments.callee.result = 'Khtml';
75
+
76
+ return arguments.callee.result = '';
77
+ }
78
+ };
79
+
80
+ /**
81
+
82
+ */
83
+ ScrollKit.ScrollView = function ScrollView(element) {
84
+ if (!element) return;
85
+
86
+ var $element = this.$element = $(element);
87
+ element = this.element = $element[0];
88
+
89
+ var scrollView = element.scrollView;
90
+ if (scrollView) return scrollView;
91
+
92
+ var self = element.scrollView = this;
93
+
94
+ var Params = ScrollKit.Params;
95
+ var Util = ScrollKit.Util;
96
+
97
+ var $window = $(window['addEventListener'] ? window : document.body);
98
+
99
+ var $content = this.$content = $('<div class="sk-scroll-content"/>').append($element.contents()).appendTo($element);
100
+ var $horizontalScrollIndicator = this.$horizontalScrollIndicator = $('<div class="sk-scroll-indicator sk-hidden" style="bottom: 0; left: 0;"/>').appendTo($element);
101
+ var $verticalScrollIndicator = this.$verticalScrollIndicator = $('<div class="sk-scroll-indicator sk-hidden" style="top: 0; right: 0;"/>').appendTo($element);
102
+
103
+ var alwaysBounceHorizontal = $element.attr('data-always-bounce-horizontal') || 'false';
104
+ alwaysBounceHorizontal = this._alwaysBounceHorizontal = alwaysBounceHorizontal !== 'false';
105
+
106
+ var alwaysBounceVertical = $element.attr('data-always-bounce-vertical') || 'false';
107
+ alwaysBounceVertical = this._alwaysBounceVertical = alwaysBounceVertical !== 'false';
108
+
109
+ var alwaysHideHorizontalScrollIndicator = this._alwaysHideHorizontalScrollIndicator = $element.attr('data-always-hide-horizontal-scroll-indicator') || 'false';
110
+ alwaysHideHorizontalScrollIndicator = this._alwaysHideHorizontalScrollIndicator = alwaysHideHorizontalScrollIndicator !== 'false';
111
+
112
+ var alwaysHideVerticalScrollIndicator = this._alwaysHideVerticalScrollIndicator = $element.attr('data-always-hide-vertical-scroll-indicator') || 'false';
113
+ alwaysHideVerticalScrollIndicator = this._alwaysHideVerticalScrollIndicator = alwaysHideVerticalScrollIndicator !== 'false';
114
+
115
+ var pagingEnabled = $element.attr('data-paging-enabled') || 'false';
116
+ pagingEnabled = this._pagingEnabled = pagingEnabled !== 'false';
117
+
118
+ var useMouseDragScrolling = $element.attr('data-use-mouse-drag-scrolling') || 'false';
119
+ useMouseDragScrolling = this._useMouseDragScrolling = useMouseDragScrolling !== 'false';
120
+
121
+ var size = this._size = { width: 0, height: 0 };
122
+ var contentSize = this._contentSize = { width: 0, height: 0 };
123
+ var margin = this._margin = { top: 0, right: 0, bottom: 0, left: 0 };
124
+ var scrollPosition = this._scrollPosition = { x: 0, y: 0 };
125
+ var maximumScrollPosition = this._maximumScrollPosition = { x: 0, y: 0 };
126
+ var pageIndexes = this._pageIndexes = { horizontal: 0, vertical: 0 };
127
+
128
+ window.setTimeout(function() { self.recalculateDimensions(); }, 1);
129
+
130
+ var isTouchSupported = !!('ontouchstart' in window);
131
+ if (!isTouchSupported && !useMouseDragScrolling) {
132
+ $element.addClass('sk-no-touch');
133
+ $element.bind('scroll', function(evt) {
134
+ scrollPosition.x = this.scrollLeft;
135
+ scrollPosition.y = this.scrollTop;
136
+ });
137
+
138
+ return this;
139
+ }
140
+
141
+ else if (isTouchSupported) {
142
+ useMouseDragScrolling = this._useMouseDragScrolling = true;
143
+ }
144
+
145
+ var isDragging = false;
146
+ var lastTouchPosition = null;
147
+ var lastTouchIdentifier = null;
148
+
149
+ var startAccelerateTimeStamp = null;
150
+ var startAccelerateScrollPosition = null;
151
+ var isDecelerating = false;
152
+ var decelerationAnimationInterval = null;
153
+
154
+ var resetStartAccelerate = function(timeStamp) {
155
+ startAccelerateTimeStamp = timeStamp;
156
+ startAccelerateScrollPosition = {
157
+ x: scrollPosition.x,
158
+ y: scrollPosition.y
159
+ };
160
+ };
161
+
162
+ var startDeceleration = function(startTimeStamp) {
163
+ var shouldScrollHorizontal = self.getShouldScrollHorizontal();
164
+ var shouldScrollVertical = self.getShouldScrollVertical();
165
+ var acceleration = (startAccelerateTimeStamp - startTimeStamp) / Params.acceleration;
166
+ var accelerateDelta = Util.getDeltaForCoordinates(scrollPosition, startAccelerateScrollPosition);
167
+ var velocity = {
168
+ x: accelerateDelta.x / acceleration,
169
+ y: accelerateDelta.y / acceleration
170
+ };
171
+
172
+ var stepAnimation = function (currentFrameTimeStamp) {
173
+ if (!isDecelerating) return;
174
+
175
+ var animationDelta = {
176
+ x: (shouldScrollHorizontal ? velocity.x : 0),
177
+ y: (shouldScrollVertical ? velocity.y : 0)
178
+ };
179
+
180
+ velocity.x *= Params.decelerationFactor;
181
+ velocity.y *= Params.decelerationFactor;
182
+
183
+ if (Math.abs(velocity.x) <= Params.minimumVelocity && Math.abs(velocity.y) <= Params.minimumVelocity) {
184
+ stopDeceleration();
185
+ stopScroll();
186
+ return;
187
+ }
188
+
189
+ self.setScrollPosition(scrollPosition.x - velocity.x, scrollPosition.y - velocity.y);
190
+
191
+ decelerationAnimationInterval = window.requestAnimationFrame(stepAnimation);
192
+
193
+ if (self.getIsScrollPositionInBounds()) return;
194
+
195
+ var elastic = {
196
+ x: (scrollPosition.x < 0) ? scrollPosition.x : (scrollPosition.x > maximumScrollPosition.x) ? scrollPosition.x - maximumScrollPosition.x : 0,
197
+ y: (scrollPosition.y < 0) ? scrollPosition.y : (scrollPosition.y > maximumScrollPosition.y) ? scrollPosition.y - maximumScrollPosition.y : 0
198
+ };
199
+
200
+ if (elastic.x) velocity.x = (elastic.x * velocity.x <= 0) ? velocity.x + (elastic.x * Params.elasticDeceleration) : elastic.x * Params.elasticAcceleration;
201
+ if (elastic.y) velocity.y = (elastic.y * velocity.y <= 0) ? velocity.y + (elastic.y * Params.elasticDeceleration) : elastic.y * Params.elasticAcceleration;
202
+ };
203
+
204
+ if (Math.abs(velocity.x) > Params.minimumDecelerationVelocity || Math.abs(velocity.y) > Params.minimumDecelerationVelocity) {
205
+ isDecelerating = true;
206
+ decelerationAnimationInterval = window.requestAnimationFrame(stepAnimation);
207
+ } else {
208
+ self.bounceScrollPositionInBounds();
209
+ stopScroll();
210
+ }
211
+ };
212
+
213
+ var stopDeceleration = function() {
214
+ if (!isDecelerating) return;
215
+
216
+ isDecelerating = false;
217
+ window.cancelAnimationFrame(decelerationAnimationInterval);
218
+ };
219
+
220
+ var snapToPage = function(startTimeStamp) {
221
+ var acceleration = (startAccelerateTimeStamp - startTimeStamp) / Params.acceleration;
222
+ var accelerateDelta = Util.getDeltaForCoordinates(scrollPosition, startAccelerateScrollPosition);
223
+ var velocity = {
224
+ x: accelerateDelta.x / acceleration,
225
+ y: accelerateDelta.y / acceleration
226
+ };
227
+
228
+ var pageCounts = self.getPageCounts();
229
+ var currentPageIndexes = {
230
+ horizontal: Math.round(scrollPosition.x / size.width),
231
+ vertical: Math.round(scrollPosition.y / size.height)
232
+ };
233
+
234
+ if (currentPageIndexes.horizontal === pageIndexes.horizontal && Math.abs(velocity.x) > Params.minimumPageTurnVelocity) currentPageIndexes.horizontal += (velocity.x > 0) ? -1 : 1;
235
+ if (currentPageIndexes.vertical === pageIndexes.vertical && Math.abs(velocity.y) > Params.minimumPageTurnVelocity) currentPageIndexes.vertical += (velocity.y > 0) ? -1 : 1;
236
+
237
+ currentPageIndexes.horizontal = Math.min(Math.max(0, currentPageIndexes.horizontal), pageCounts.horizontal - 1);
238
+ currentPageIndexes.vertical = Math.min(Math.max(0, currentPageIndexes.vertical), pageCounts.vertical - 1);
239
+
240
+ self.setPageIndexes(currentPageIndexes.horizontal, currentPageIndexes.vertical);
241
+ };
242
+
243
+ var startScroll = function() {
244
+ if (self._scrolling) return;
245
+ self._scrolling = true;
246
+
247
+ self.setHorizontalScrollIndicatorHidden(false);
248
+ self.setVerticalScrollIndicatorHidden(false);
249
+ $element.trigger(ScrollKit.ScrollView.EventType.ScrollStart);
250
+ };
251
+
252
+ var stopScroll = function() {
253
+ if (!self._scrolling) return;
254
+ self._scrolling = false;
255
+
256
+ var roundedScrollPosition = {
257
+ x: Math.round(scrollPosition.x),
258
+ y: Math.round(scrollPosition.y)
259
+ };
260
+
261
+ self.setHorizontalScrollIndicatorHidden(true);
262
+ self.setVerticalScrollIndicatorHidden(true);
263
+
264
+ if (scrollPosition.x !== roundedScrollPosition.x || scrollPosition.y !== roundedScrollPosition.y) {
265
+ self.setScrollPosition(Math.round(scrollPosition.x), Math.round(scrollPosition.y));
266
+ }
267
+
268
+ $element.trigger(ScrollKit.ScrollView.EventType.ScrollStop);
269
+ };
270
+
271
+ $element.bind(isTouchSupported ? 'touchstart' : 'mousedown', function(evt) {
272
+ if (isDragging) return;
273
+
274
+ isDragging = true;
275
+ lastTouchPosition = Util.getCoordinatesForEvent(evt);
276
+ lastTouchIdentifier = (isTouchSupported) ? evt.originalEvent.targetTouches[0].identifier : null;
277
+
278
+ stopDeceleration();
279
+ resetStartAccelerate(evt.timeStamp);
280
+
281
+ self.recalculateDimensions();
282
+
283
+ $window.bind(isTouchSupported ? 'touchmove' : 'mousemove', touchMoveHandler);
284
+ $window.bind(isTouchSupported ? 'touchend' : 'mouseup', touchEndHandler);
285
+ });
286
+
287
+ var touchMoveHandler = function(evt) {
288
+ evt.preventDefault();
289
+
290
+ if (!isDragging) return;
291
+
292
+ if (!self._scrolling) startScroll();
293
+
294
+ var touchPosition = Util.getCoordinatesForEvent(evt, lastTouchIdentifier);
295
+ var touchDelta = Util.getDeltaForCoordinates(touchPosition, lastTouchPosition);
296
+
297
+ if (!self.getIsScrollPositionInBounds()) {
298
+ touchDelta.x /= 2;
299
+ touchDelta.y /= 2;
300
+ }
301
+
302
+ self.setScrollPosition(scrollPosition.x - touchDelta.x, scrollPosition.y - touchDelta.y);
303
+
304
+ var timeStamp = evt.timeStamp;
305
+ var accelerationTime = timeStamp - startAccelerateTimeStamp;
306
+ if (accelerationTime > Params.accelerationTimeout) resetStartAccelerate(timeStamp);
307
+
308
+ lastTouchPosition = touchPosition;
309
+ };
310
+
311
+ var touchEndHandler = function(evt) {
312
+ if (!isDragging) return;
313
+
314
+ isDragging = false;
315
+ lastTouchIdentifier = null;
316
+
317
+ $window.unbind(isTouchSupported ? 'touchmove' : 'mousemove', touchMoveHandler);
318
+ $window.unbind(isTouchSupported ? 'touchend' : 'mouseup', touchEndHandler);
319
+
320
+ var timeStamp = evt.timeStamp;
321
+ var accelerationTime = timeStamp - startAccelerateTimeStamp;
322
+
323
+ if (self._pagingEnabled) {
324
+ snapToPage(timeStamp);
325
+ stopScroll();
326
+ }
327
+
328
+ else if (accelerationTime < Params.accelerationTimeout) {
329
+ startDeceleration(timeStamp);
330
+ }
331
+
332
+ else if (!self.getIsScrollPositionInBounds()) {
333
+ self.bounceScrollPositionInBounds();
334
+ stopScroll();
335
+ }
336
+
337
+ else {
338
+ stopScroll();
339
+ }
340
+ };
341
+ };
342
+
343
+ /**
344
+ Event types for ScrollKit.ScrollView.
345
+ */
346
+ ScrollKit.ScrollView.EventType = {
347
+ ScrollStart: 'ScrollKit:ScrollView:ScrollStart',
348
+ ScrollStop: 'ScrollKit:ScrollView:ScrollStop',
349
+ WillScrollToTop: 'ScrollKit:ScrollView:WillScrollToTop',
350
+ DidScrollToTop: 'ScrollKit:ScrollView:DidScrollToTop',
351
+ PageChanged: 'ScrollKit:ScrollView:PageChanged',
352
+ DidPullToRefresh: 'ScrollKit:ScrollView:DidPullToRefresh'
353
+ };
354
+
355
+ ScrollKit.ScrollView.prototype = {
356
+ constructor: ScrollKit.ScrollView,
357
+
358
+ element: null,
359
+ $element: null,
360
+ $content: null,
361
+ $horizontalScrollIndicator: null,
362
+ $verticalScrollIndicator: null,
363
+
364
+ _useMouseDragScrolling: false,
365
+ _vendorPrefix: ScrollKit.Util.getVendorPrefix().toLowerCase(),
366
+
367
+ _scrolling: false,
368
+
369
+ /**
370
+
371
+ */
372
+ getScrolling: function() { return this._scrolling; },
373
+
374
+ _alwaysBounceHorizontal: false,
375
+
376
+ /**
377
+
378
+ */
379
+ getAlwaysBounceHorizontal: function() { return this._alwaysBounceHorizontal; },
380
+
381
+ /**
382
+
383
+ */
384
+ setAlwaysBounceHorizontal: function(alwaysBounceHorizontal) { this._alwaysBounceHorizontal = alwaysBounceHorizontal; },
385
+
386
+ /**
387
+
388
+ */
389
+ getShouldScrollHorizontal: function() { return this._alwaysBounceHorizontal || this._contentSize.width > this._size.width; },
390
+
391
+ _alwaysBounceVertical: false,
392
+
393
+ /**
394
+
395
+ */
396
+ getAlwaysBounceVertical: function() { return this._alwaysBounceVertical; },
397
+
398
+ /**
399
+
400
+ */
401
+ setAlwaysBounceVertical: function(alwaysBounceVertical) { this._alwaysBounceVertical = alwaysBounceVertical; },
402
+
403
+ /**
404
+
405
+ */
406
+ getShouldScrollVertical: function() { return this._alwaysBounceVertical || this._contentSize.height > this._size.height; },
407
+
408
+ _alwaysHideHorizontalScrollIndicator: false,
409
+
410
+ /**
411
+
412
+ */
413
+ getAlwaysHideHorizontalScrollIndicator: function() { return this._alwaysHideHorizontalScrollIndicator; },
414
+
415
+ /**
416
+
417
+ */
418
+ setAlwaysHideHorizontalScrollIndicator: function(alwaysHideHorizontalScrollIndicator) { this._alwaysHideHorizontalScrollIndicator = alwaysHideHorizontalScrollIndicator; },
419
+
420
+ _alwaysHideVerticalScrollIndicator: false,
421
+
422
+ /**
423
+
424
+ */
425
+ getAlwaysHideVerticalScrollIndicator: function() { return this._alwaysHideVerticalScrollIndicator; },
426
+
427
+ /**
428
+
429
+ */
430
+ setAlwaysHideVerticalScrollIndicator: function(alwaysHideVerticalScrollIndicator) { this._alwaysHideVerticalScrollIndicator = alwaysHideVerticalScrollIndicator; },
431
+
432
+ _pagingEnabled: false,
433
+
434
+ /**
435
+
436
+ */
437
+ getPagingEnabled: function() { return this._pagingEnabled; },
438
+
439
+ /**
440
+
441
+ */
442
+ setPagingEnabled: function(pagingEnabled) { this._pagingEnabled = pagingEnabled; },
443
+
444
+ _pageIndexes: null, // { horizontal: 0, vertical: 0 }
445
+
446
+ /**
447
+
448
+ */
449
+ getPageIndexes: function() { return this._pageIndexes; },
450
+
451
+ /**
452
+
453
+ */
454
+ setPageIndexes: function(horizontalPageIndex, verticalPageIndex) {
455
+ var pageIndexes = this._pageIndexes;
456
+ var size = this._size;
457
+
458
+ var previousIndexes = {
459
+ horizontal: pageIndexes.horizontal,
460
+ vertical: pageIndexes.vertical
461
+ };
462
+
463
+ pageIndexes.horizontal = horizontalPageIndex;
464
+ pageIndexes.vertical = verticalPageIndex;
465
+
466
+ this.setScrollPosition(horizontalPageIndex * size.width, verticalPageIndex * size.height, ScrollKit.Params.bounceTransitionDuration);
467
+
468
+ if (horizontalPageIndex !== previousIndexes.horizontal || verticalPageIndex !== previousIndexes.vertical) {
469
+ this.$element.trigger($.Event(ScrollKit.ScrollView.EventType.PageChanged, {
470
+ previousIndexes: previousIndexes,
471
+ currentIndexes: {
472
+ horizontal: horizontalPageIndex,
473
+ vertical: verticalPageIndex
474
+ }
475
+ }));
476
+ }
477
+ },
478
+
479
+ /**
480
+
481
+ */
482
+ getPageCounts: function() {
483
+ var contentSize = this._contentSize;
484
+ var size = this._size;
485
+ var pageCounts = {
486
+ horizontal: Math.floor(contentSize.width / size.width),
487
+ vertical: Math.floor(contentSize.height / size.height)
488
+ };
489
+
490
+ return pageCounts;
491
+ },
492
+
493
+ _minimumHorizontalScrollIndicatorLength: 12,
494
+
495
+ /**
496
+
497
+ */
498
+ getMinimumHorizontalScrollIndicatorLength: function() { return this._minimumHorizontalScrollIndicatorLength; },
499
+
500
+ /**
501
+
502
+ */
503
+ setMinimumHorizontalScrollIndicatorLength: function(minimumHorizontalScrollIndicatorLength) {
504
+ this._minimumHorizontalScrollIndicatorLength = minimumHorizontalScrollIndicatorLength;
505
+ this.updateHorizontalScrollIndicator();
506
+ },
507
+
508
+ _horizontalScrollIndicatorThickness: 7,
509
+
510
+ /**
511
+
512
+ */
513
+ getHorizontalScrollIndicatorThickness: function() { return this._horizontalScrollIndicatorThickness; },
514
+
515
+ /**
516
+
517
+ */
518
+ setHorizontalScrollIndicatorThickness: function(horizontalScrollIndicatorThickness) {
519
+ this._horizontalScrollIndicatorThickness = horizontalScrollIndicatorThickness;
520
+ this.updateHorizontalScrollIndicator();
521
+ },
522
+
523
+ _horizontalScrollIndicatorHidden: true,
524
+
525
+ /**
526
+
527
+ */
528
+ getHorizontalScrollIndicatorHidden: function() { return this._horizontalScrollIndicatorHidden; },
529
+
530
+ /**
531
+
532
+ */
533
+ setHorizontalScrollIndicatorHidden: function(horizontalScrollIndicatorHidden) {
534
+ this._horizontalScrollIndicatorHidden = horizontalScrollIndicatorHidden;
535
+
536
+ if (horizontalScrollIndicatorHidden || this._alwaysHideHorizontalScrollIndicator || !this.getShouldScrollHorizontal()) {
537
+ this.$horizontalScrollIndicator.addClass('sk-hidden');
538
+ } else {
539
+ this.$horizontalScrollIndicator.removeClass('sk-hidden');
540
+ }
541
+ },
542
+
543
+ /**
544
+
545
+ */
546
+ updateHorizontalScrollIndicator: function() {
547
+ if (this._horizontalScrollIndicatorHidden) return;
548
+
549
+ var scrollPosition = this._scrollPosition.x;
550
+ var size = this._size.width;
551
+ var contentSize = this._contentSize.width;
552
+ var maximumScrollPosition = this._maximumScrollPosition.x;
553
+ var minimumScrollIndicatorLength = this._minimumHorizontalScrollIndicatorLength;
554
+ var scrollIndicatorThickness = this._horizontalScrollIndicatorThickness;
555
+ var scrollIndicatorMargin = this.getShouldScrollVertical() ? scrollIndicatorThickness * 2 : scrollIndicatorThickness - 2;
556
+ var scrollIndicatorLength = Math.max(minimumScrollIndicatorLength, (size / contentSize) * (size - scrollIndicatorMargin));
557
+ var scrollIndicatorPosition = (scrollPosition / maximumScrollPosition) * (size - scrollIndicatorMargin - scrollIndicatorLength);
558
+
559
+ if (scrollPosition <= 0) {
560
+ scrollIndicatorLength = Math.max(scrollIndicatorThickness - 2, scrollPosition + scrollIndicatorLength);
561
+ scrollIndicatorPosition = 0;
562
+ }
563
+
564
+ else if (scrollPosition >= maximumScrollPosition) {
565
+ scrollIndicatorLength = Math.max(scrollIndicatorThickness - 2, (maximumScrollPosition - scrollPosition) + scrollIndicatorLength);
566
+ scrollIndicatorPosition = size - scrollIndicatorLength - scrollIndicatorMargin;
567
+ }
568
+
569
+ var translation = scrollIndicatorPosition + 'px, 0';
570
+ var vendorPrefix = this._vendorPrefix;
571
+ var styles = this._horizontalScrollIndicatorStyles = this._horizontalScrollIndicatorStyles || {};
572
+
573
+ styles['width'] = scrollIndicatorLength + 'px';
574
+
575
+ // TODO: Change this test to look for 3D transform capability instead of Webkit only.
576
+ if (vendorPrefix === 'webkit') {
577
+ styles['-webkit-transform'] = styles['transform'] = 'translate3d(' + translation + ', 0)';
578
+ }
579
+
580
+ else {
581
+ styles['-' + vendorPrefix + '-transform'] = styles['transform'] = 'translate(' + translation + ')';
582
+ }
583
+
584
+ this.$horizontalScrollIndicator.css(styles);
585
+ },
586
+
587
+ _minimumVerticalScrollIndicatorLength: 12,
588
+
589
+ /**
590
+
591
+ */
592
+ getMinimumVerticalScrollIndicatorLength: function() { return this._minimumVerticalScrollIndicatorLength; },
593
+
594
+ /**
595
+
596
+ */
597
+ setMinimumVerticalScrollIndicatorLength: function(minimumVerticalScrollIndicatorLength) {
598
+ this._minimumVerticalScrollIndicatorLength = minimumVerticalScrollIndicatorLength;
599
+ this.updateVerticalScrollIndicator();
600
+ },
601
+
602
+ _verticalScrollIndicatorThickness: 7,
603
+
604
+ /**
605
+
606
+ */
607
+ getVerticalScrollIndicatorThickness: function() { return this._verticalScrollIndicatorThickness; },
608
+
609
+ /**
610
+
611
+ */
612
+ setVerticalScrollIndicatorThickness: function(verticalScrollIndicatorThickness) {
613
+ this._verticalScrollIndicatorThickness = verticalScrollIndicatorThickness;
614
+ this.updateVerticalScrollIndicator();
615
+ },
616
+
617
+ _verticalScrollIndicatorHidden: true,
618
+
619
+ /**
620
+
621
+ */
622
+ getVerticalScrollIndicatorHidden: function() { return this._verticalScrollIndicatorHidden; },
623
+
624
+ /**
625
+
626
+ */
627
+ setVerticalScrollIndicatorHidden: function(verticalScrollIndicatorHidden) {
628
+ this._verticalScrollIndicatorHidden = verticalScrollIndicatorHidden;
629
+
630
+ if (verticalScrollIndicatorHidden || this._alwaysHideVerticalScrollIndicator || !this.getShouldScrollVertical()) {
631
+ this.$verticalScrollIndicator.addClass('sk-hidden');
632
+ } else {
633
+ this.$verticalScrollIndicator.removeClass('sk-hidden');
634
+ }
635
+ },
636
+
637
+ /**
638
+
639
+ */
640
+ updateVerticalScrollIndicator: function() {
641
+ if (this._verticalScrollIndicatorHidden) return;
642
+
643
+ var scrollPosition = this._scrollPosition.y;
644
+ var size = this._size.height;
645
+ var contentSize = this._contentSize.height;
646
+ var maximumScrollPosition = this._maximumScrollPosition.y;
647
+ var minimumScrollIndicatorLength = this._minimumVerticalScrollIndicatorLength;
648
+ var scrollIndicatorThickness = this._verticalScrollIndicatorThickness;
649
+ var scrollIndicatorMargin = this.getShouldScrollHorizontal() ? scrollIndicatorThickness * 2 : scrollIndicatorThickness - 2;
650
+ var scrollIndicatorLength = Math.max(minimumScrollIndicatorLength, (size / contentSize) * (size - scrollIndicatorMargin));
651
+ var scrollIndicatorPosition = (scrollPosition / maximumScrollPosition) * (size - scrollIndicatorMargin - scrollIndicatorLength);
652
+
653
+ if (scrollPosition <= 0) {
654
+ scrollIndicatorLength = Math.max(scrollIndicatorThickness - 2, scrollPosition + scrollIndicatorLength);
655
+ scrollIndicatorPosition = 0;
656
+ }
657
+
658
+ else if (scrollPosition >= maximumScrollPosition) {
659
+ scrollIndicatorLength = Math.max(scrollIndicatorThickness - 2, (maximumScrollPosition - scrollPosition) + scrollIndicatorLength);
660
+ scrollIndicatorPosition = size - scrollIndicatorLength - scrollIndicatorMargin;
661
+ }
662
+
663
+ var translation = '0, ' + scrollIndicatorPosition + 'px';
664
+ var vendorPrefix = this._vendorPrefix;
665
+ var styles = this._verticalScrollIndicatorStyles = this._verticalScrollIndicatorStyles || {};
666
+
667
+ styles['height'] = scrollIndicatorLength + 'px';
668
+
669
+ // TODO: Change this test to look for 3D transform capability instead of Webkit only.
670
+ if (vendorPrefix === 'webkit') {
671
+ styles['-webkit-transform'] = styles['transform'] = 'translate3d(' + translation + ', 0)';
672
+ }
673
+
674
+ else {
675
+ styles['-' + vendorPrefix + '-transform'] = styles['transform'] = 'translate(' + translation + ')';
676
+ }
677
+
678
+ this.$verticalScrollIndicator.css(styles);
679
+ },
680
+
681
+ _size: null, // { width: 0, height: 0 }
682
+
683
+ /**
684
+
685
+ */
686
+ getSize: function() { return this._size; },
687
+
688
+ _contentSize: null, // { width: 0, height: 0 }
689
+
690
+ /**
691
+
692
+ */
693
+ getContentSize: function() { return this._contentSize; },
694
+
695
+ _margin: null, // { top: 0, right: 0, bottom: 0, left: 0 }
696
+
697
+ /**
698
+
699
+ */
700
+ getMargin: function() { return this._margin; },
701
+
702
+ /**
703
+
704
+ */
705
+ setMargin: function(marginTop, marginRight, marginBottom, marginLeft) {
706
+ var scrollPosition = this._scrollPosition;
707
+ var margin = this._margin;
708
+ margin.top = (marginTop !== 0) ? (marginTop || margin.top) : 0;
709
+ margin.right = (marginRight !== 0) ? (marginRight || margin.right) : 0;
710
+ margin.bottom = (marginBottom !== 0) ? (marginBottom || margin.bottom) : 0;
711
+ margin.left = (marginLeft !== 0) ? (marginLeft || margin.left) : 0;
712
+
713
+ if (this._useMouseDragScrolling) {
714
+ this.translate(scrollPosition.x, scrollPosition.y);
715
+ } else {
716
+ this.$content.css('padding', margin.top + 'px ' + margin.right + 'px ' + margin.bottom + 'px ' + margin.left + 'px');
717
+ }
718
+
719
+ this.recalculateDimensions();
720
+ },
721
+
722
+ _scrollPosition: null, // { x: 0, y: 0 }
723
+
724
+ /**
725
+
726
+ */
727
+ getScrollPosition: function() { return this._scrollPosition; },
728
+
729
+ /**
730
+
731
+ */
732
+ setScrollPosition: function(x, y, animationDuration) {
733
+ var $element = this.$element;
734
+ var scrollPosition = this._scrollPosition;
735
+ var minimumDeltaForScrollEvent = ScrollKit.Params.minimumDeltaForScrollEvent;
736
+ var shouldTriggerScrollEvent = (Math.abs(scrollPosition.x - x) > minimumDeltaForScrollEvent || Math.abs(scrollPosition.y - y) > minimumDeltaForScrollEvent);
737
+
738
+ x = scrollPosition.x = (this.getShouldScrollHorizontal()) ? x : 0;
739
+ y = scrollPosition.y = (this.getShouldScrollVertical()) ? y : 0;
740
+
741
+ if (!this._useMouseDragScrolling) {
742
+ $element.scrollLeft(x);
743
+ $element.scrollTop(y);
744
+ return;
745
+ }
746
+
747
+ this.translate(x, y, animationDuration);
748
+
749
+ if (!shouldTriggerScrollEvent) return;
750
+
751
+ this.updateHorizontalScrollIndicator();
752
+ this.updateVerticalScrollIndicator();
753
+
754
+ $element.trigger('scroll');
755
+ },
756
+
757
+ /**
758
+
759
+ */
760
+ scrollToTop: function() {
761
+ if (this._scrolling) return;
762
+
763
+ var $element = this.$element;
764
+ $element.trigger(ScrollKit.ScrollView.EventType.WillScrollToTop);
765
+
766
+ var margin = this._margin;
767
+ margin.bottom += margin.top;
768
+ margin.top = 0;
769
+
770
+ var bounceTransitionDuration = ScrollKit.Params.bounceTransitionDuration;
771
+
772
+ if (!this._useMouseDragScrolling) {
773
+ this.$content.css('padding', margin.top + 'px ' + margin.right + 'px ' + margin.bottom + 'px ' + margin.left + 'px');
774
+
775
+ $element.animate({
776
+ scrollTop: 0
777
+ }, bounceTransitionDuration * 500, function() {
778
+ $element.trigger(ScrollKit.ScrollView.EventType.DidScrollToTop);
779
+ });
780
+
781
+ return;
782
+ }
783
+
784
+ var scrollPosition = this._scrollPosition;
785
+ scrollPosition.x = 0;
786
+ scrollPosition.y = 0;
787
+
788
+ this.setHorizontalScrollIndicatorHidden(false);
789
+ this.setVerticalScrollIndicatorHidden(false);
790
+
791
+ this.updateHorizontalScrollIndicator();
792
+ this.updateVerticalScrollIndicator();
793
+
794
+ this.setScrollPosition(0, 0, bounceTransitionDuration);
795
+
796
+ var self = this;
797
+ window.setTimeout(function() {
798
+ self.setHorizontalScrollIndicatorHidden(true);
799
+ self.setVerticalScrollIndicatorHidden(true);
800
+
801
+ $element.trigger(ScrollKit.ScrollView.EventType.DidScrollToTop);
802
+ }, bounceTransitionDuration * 250);
803
+ },
804
+
805
+ _maximumScrollPosition: null, // { x: 0, y: 0 }
806
+
807
+ /**
808
+
809
+ */
810
+ getMaximumScrollPosition: function() { return this._maximumScrollPosition; },
811
+
812
+ /**
813
+
814
+ */
815
+ getIsScrollPositionInBounds: function() {
816
+ var scrollPosition = this._scrollPosition;
817
+ var maximumScrollPosition = this._maximumScrollPosition;
818
+ var clampedX = Math.min(Math.max(0, scrollPosition.x), maximumScrollPosition.x);
819
+ var clampedY = Math.min(Math.max(0, scrollPosition.y), maximumScrollPosition.y);
820
+
821
+ return (scrollPosition.x === clampedX && scrollPosition.y === clampedY);
822
+ },
823
+
824
+ /**
825
+
826
+ */
827
+ bounceScrollPositionInBounds: function() {
828
+ var scrollPosition = this._scrollPosition;
829
+ var maximumScrollPosition = this._maximumScrollPosition;
830
+ var clampedX = Math.min(Math.max(0, scrollPosition.x), maximumScrollPosition.x);
831
+ var clampedY = Math.min(Math.max(0, scrollPosition.y), maximumScrollPosition.y);
832
+
833
+ this.setScrollPosition(clampedX, clampedY, ScrollKit.Params.bounceTransitionDuration);
834
+ },
835
+
836
+ _lastTransitionDuration: '0s',
837
+
838
+ /**
839
+
840
+ */
841
+ translate: function(x, y, animationDuration) {
842
+ var margin = this._margin;
843
+ var translation = (margin.left - x) + 'px, ' + (margin.top - y) + 'px';
844
+ var duration = (animationDuration || '0') + 's';
845
+ var vendorPrefix = this._vendorPrefix;
846
+ var styles = this._contentStyles = this._contentStyles || {};
847
+
848
+ // TODO: Change this test to look for 3D transform capability instead of Webkit only.
849
+ if (vendorPrefix === 'webkit') {
850
+ if (duration !== this._lastTransitionDuration) this._lastTransitionDuration = styles['-webkit-transition-duration'] = styles['transition-duration'] = duration;
851
+ styles['-webkit-transform'] = styles['transform'] = 'translate3d(' + translation + ', 0)';
852
+ }
853
+
854
+ else {
855
+ if (duration !== this._lastTransitionDuration) this._lastTransitionDuration = styles['-' + vendorPrefix + '-transition-duration'] = styles['transition-duration'] = duration;
856
+ styles['-' + vendorPrefix + '-transform'] = styles['transform'] = 'translate(' + translation + ')';
857
+ }
858
+
859
+ this.$content.css(styles);
860
+ },
861
+
862
+ /**
863
+
864
+ */
865
+ recalculateDimensions: function() {
866
+ var $element = this.$element;
867
+ var $content = this.$content;
868
+ var size = this._size;
869
+ var contentSize = this._contentSize;
870
+ var margin = this._margin;
871
+ var maximumScrollPosition = this._maximumScrollPosition;
872
+
873
+ size.width = $element.width();
874
+ size.height = $element.height();
875
+
876
+ contentSize.width = Math.max($content.width(), size.width) + margin.left + margin.right;
877
+ contentSize.height = Math.max($content.height(), size.height) + margin.top + margin.bottom;
878
+
879
+ maximumScrollPosition.x = contentSize.width - size.width;
880
+ maximumScrollPosition.y = contentSize.height - size.height;
881
+
882
+ $element.trigger('scroll');
883
+ },
884
+
885
+ /**
886
+ Convenience accessor for jQuery's .bind() method.
887
+ */
888
+ $bind: function() { this.$element.bind.apply(this.$element, arguments); },
889
+
890
+ /**
891
+ Convenience accessor for jQuery's .unbind() method.
892
+ */
893
+ $unbind: function() { this.$element.unbind.apply(this.$element, arguments); },
894
+
895
+ /**
896
+ Convenience accessor for jQuery's .delegate() method.
897
+ */
898
+ $delegate: function() { this.$element.delegate.apply(this.$element, arguments); },
899
+
900
+ /**
901
+ Convenience accessor for jQuery's .undelegate() method.
902
+ */
903
+ $undelegate: function() { this.$element.undelegate.apply(this.$element, arguments); },
904
+
905
+ /**
906
+ Convenience accessor for jQuery's .trigger() method.
907
+ */
908
+ $trigger: function() { this.$element.trigger.apply(this.$element, arguments); }
909
+ };
910
+
911
+ $(function() {
912
+ $('.sk-scroll-view').each(function(index, element) { new ScrollKit.ScrollView(element); });
913
+
914
+ // Set up horizontal page containers to automatically adjust their size when the window resizes.
915
+ var $window = $(window['addEventListener'] ? window : document.body).bind('resize', function(evt) {
916
+ resizePageContainers();
917
+ });
918
+ var $style = $('<style/>').appendTo($(document.head));
919
+ var resizePageContainers = function() {
920
+ $style.html('.sk-page-container-horizontal > li { width: ' + $window.width() + 'px !important; }');
921
+ };
922
+
923
+ resizePageContainers();
924
+ });