jscrollpane-rails 2.2.1 → 2.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bd6a603883bd23cc7d09a3a94a6b6f2b433e571d4a44f256244fbb5f4e80ed66
4
- data.tar.gz: 2ad16320b795bc7a3618bd2d10c43d5d09127cd6febc0a37199747e961e7531c
3
+ metadata.gz: 8c44d1282555878230b6462b49367cfccf339d9298b3cded4b10bd14ec8b79a3
4
+ data.tar.gz: d848d4a686dc5fd061cdd3a0e7a6425bf87d383168392060be1f00850a9d5f24
5
5
  SHA512:
6
- metadata.gz: 84e2c98f713d57bc65c75cdc7247b876fd3920d3f64ab36060c3c3551d384bf0eef95ae6c1892db9c98b5ba5a6316330754b593d0bdc2024b5f093b22c6078cf
7
- data.tar.gz: '0330538e6d802cb84f13eb914652c421b6a8222bfc942306212f22160ae0d1c950cde54b6c53f9d0fb5ee9c177d2a8fa9113770c44eb2da3c7d513fe6c4baabd'
6
+ metadata.gz: 8bc8979e62344fc724121581ea4b2c7e6bccba7b3f03babd1bbbe0d75e0f4f7d581907d8a3738b4445c576ece89db6f47532a69d8809a41fb6e6bed89303067e
7
+ data.tar.gz: 7b37b548289a70c52be1aa7ec0ad7839205221a64ea794738779921976904fda40bfa02267e5c35341abc96078b82471d35d9e9af45defe1cef47989a6aa453c
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2018 Ilya Bodrov
1
+ Copyright (c) 2020 Ilya Bodrov-Krukowski
2
2
 
3
3
  MIT License
4
4
 
@@ -19,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
19
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
20
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
21
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # jScrollPane plugin for Rails
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/jscrollpane-rails.png)](http://badge.fury.io/rb/jscrollpane-rails)
3
+ [![Gem Version](https://badge.fury.io/rb/jscrollpane-rails.svg)](http://badge.fury.io/rb/jscrollpane-rails)
4
4
  [![Build Status](https://travis-ci.org/bodrovis/jscrollpane-rails.svg?branch=master)](https://travis-ci.org/bodrovis/jscrollpane-rails)
5
5
 
6
- A ruby gem that uses the Rails asset pipeline to include the jScrollPane plugin by Kelvin Luck and Tuukka Pasanen:
6
+ A Ruby gem that uses the Rails asset pipeline to include the jScrollPane plugin by Kelvin Luck and Tuukka Pasanen:
7
7
 
8
8
  * [Library's homepage](http://jscrollpane.kelvinluck.com/)
9
9
  * [Source code](https://github.com/vitch/jScrollPane)
@@ -12,7 +12,9 @@ A ruby gem that uses the Rails asset pipeline to include the jScrollPane plugin
12
12
 
13
13
  Add this line to your application's Gemfile:
14
14
 
15
- gem 'jscrollpane-rails'
15
+ ```ruby
16
+ gem 'jscrollpane-rails'
17
+ ```
16
18
 
17
19
  And then execute:
18
20
 
@@ -82,4 +84,4 @@ $ rake test
82
84
 
83
85
  This plugin is licensed under the [MIT license](https://github.com/bodrovis/jscrollpane-rails/blob/master/LICENSE). The jScrollPane itself is dual-licensed under the [GPL 2 license](https://github.com/vitch/jScrollPane/blob/master/GPL-LICENSE.txt) and the MIT license.
84
86
 
85
- Copyright (c) 2018 [Ilya Bodrov](http://bodrovis.tech)
87
+ Copyright (c) 2020 [Ilya Bodrov-Krukowski](http://bodrovis.tech)
@@ -1,16 +1,17 @@
1
1
  /*!
2
- * jScrollPane - v2.2.1 - 2018-09-27
2
+ * jScrollPane - v2.2.3-rc.1 - 2020-06-26
3
3
  * http://jscrollpane.kelvinluck.com/
4
4
  *
5
5
  * Copyright (c) 2014 Kelvin Luck
6
- * Copyright (c) 2017-2018 Tuukka Pasanen
6
+ * Copyright (c) 2017-2020 Tuukka Pasanen
7
7
  * Dual licensed under the MIT or GPL licenses.
8
+ *
9
+ * SPDX-License-Identifier: MIT
10
+ * SPDX-License-Identifier: GPL-2.0-or-later
8
11
  */
9
12
 
10
13
  // Script: jScrollPane - cross browser customisable scrollbars
11
14
  //
12
- // *Version: 2.2.1, Last updated: 2018-09-27*
13
- //
14
15
  // Project Home - http://jscrollpane.kelvinluck.com/
15
16
  // GitHub - http://github.com/vitch/jScrollPane
16
17
  // CND - https://cdnjs.com/libraries/jScrollPane
@@ -22,10 +23,10 @@
22
23
  // About: License
23
24
  //
24
25
  // Copyright (c) 2017 Kelvin Luck
25
- // Copyright (c) 2017-2018 Tuukka Pasanen
26
+ // Copyright (c) 2017-2020 Tuukka Pasanen
26
27
  // Dual licensed under the MIT or GPL Version 2 licenses.
27
- // http://jscrollpane.kelvinluck.com/MIT-LICENSE.txt
28
- // http://jscrollpane.kelvinluck.com/GPL-LICENSE.txt
28
+ // https://github.com/vitch/jScrollPane/blob/master/MIT-LICENSE.txt
29
+ // https://github.com/vitch/jScrollPane/blob/master/GPL-LICENSE.txt
29
30
  //
30
31
  // About: Examples
31
32
  //
@@ -45,6 +46,10 @@
45
46
  //
46
47
  // About: Release History
47
48
  //
49
+ // 2.2.3-rc.1 - (2020-06-26) Fix Github Issue #376 and #377 with jQuery 3.5 and upcoming jQuery 4.0
50
+ // Small change with setting stickToBottom. Updated other scripts to
51
+ // jQuery 3.x.
52
+ // 2.2.2 - (2020-05-06) Just update NPM dependecies to remove vunerbilities
48
53
  // 2.2.1 - (2018-09-27) No changed applied to release so same as RC1/2
49
54
  // 2.2.1-rc.2 - (2018-06-14) Sucked NPM release have to make new Release.. this is 2018!
50
55
  // 2.2.1-rc.1 - (2018-06-14) Fixed CSSLint warnings which can lead CSS problems in
@@ -57,1606 +62,1494 @@
57
62
  // * Merged:
58
63
  // - #361 Event based reinitialising - Resize Sensor
59
64
  // - #359 Use npm scripts and local dev dependencies to build the project
60
- // 2.1.3 - (2018-04-04) No changes from Release Candidate 2 so making release
61
- // 2.1.3-rc.2 - (2018-03-13) Now using 'script/jquery.jscrollpane.min.js' main
62
- // in package.json rather than 'Gruntfile.js'
63
- // 2.1.3-rc.1 - (2018-03-05) Moving Gruntfile.js to root and example HTML
64
- // to subdirectory examples
65
- // 2.1.2 - (2018-02-16) Just on console.log remove and Release!
66
- // This version should play nicely with NPM
67
- // 2.1.2-rc.2 - (2018-02-03) Update package.json main-tag
68
- // 2.1.2-rc.1 - (2018-01-18) Release on NPM.
69
- // 2.1.1 - (2018-01-12) As everyone stays silent then we just release! No changes from RC.1
70
- // 2.1.1-rc.1 - (2017-12-23) Started to slowly merge stuff (HO HO HO Merry Christmas!)
71
- // * Merged
72
- // - #349 - ScrollPane reinitialization should adapt to changed container size
73
- // - #335 Set drag bar width/height with .css instead of .width/.height
74
- // - #297 added two settings: always show HScroll and VScroll
75
- // * Bugs
76
- // - #8 Make it possible to tell a scrollbar to be "always on"
77
- // 2.1.0 - (2017-12-16) Update jQuery to version 3.x
78
65
 
79
66
  (function (factory) {
80
- if ( typeof define === 'function' && define.amd ) {
81
- // AMD. Register as an anonymous module.
82
- define(['jquery'], factory);
83
- } else if (typeof exports === 'object') {
84
- // Node/CommonJS style for Browserify
85
- module.exports = factory(jQuery || require('jquery'));
86
- } else {
87
- // Browser globals
88
- factory(jQuery);
89
- }
90
- }(function($){
91
-
92
- $.fn.jScrollPane = function(settings)
93
- {
94
- // JScrollPane "class" - public methods are available through $('selector').data('jsp')
95
- function JScrollPane(elem, s)
96
- {
97
- var settings, jsp = this, pane, paneWidth, paneHeight, container, contentWidth, contentHeight,
98
- percentInViewH, percentInViewV, isScrollableV, isScrollableH, verticalDrag, dragMaxY,
99
- verticalDragPosition, horizontalDrag, dragMaxX, horizontalDragPosition,
100
- verticalBar, verticalTrack, scrollbarWidth, verticalTrackHeight, verticalDragHeight, arrowUp, arrowDown,
101
- horizontalBar, horizontalTrack, horizontalTrackWidth, horizontalDragWidth, arrowLeft, arrowRight,
102
- reinitialiseInterval, originalPadding, originalPaddingTotalWidth, previousContentWidth,
103
- wasAtTop = true, wasAtLeft = true, wasAtBottom = false, wasAtRight = false,
104
- originalElement = elem.clone(false, false).empty(), resizeEventsAdded = false,
105
- mwEvent = $.fn.mwheelIntent ? 'mwheelIntent.jsp' : 'mousewheel.jsp';
106
-
107
- var reinitialiseFn = function() {
108
- // if size has changed then reinitialise
109
- if (settings.resizeSensorDelay > 0) {
110
- setTimeout(function() {
111
- initialise(settings);
112
- }, settings.resizeSensorDelay);
113
- }
114
- else {
115
- initialise(settings);
116
- }
117
- };
118
-
119
- if (elem.css('box-sizing') === 'border-box') {
120
- originalPadding = 0;
121
- originalPaddingTotalWidth = 0;
122
- } else {
123
- originalPadding = elem.css('paddingTop') + ' ' +
124
- elem.css('paddingRight') + ' ' +
125
- elem.css('paddingBottom') + ' ' +
126
- elem.css('paddingLeft');
127
- originalPaddingTotalWidth = (parseInt(elem.css('paddingLeft'), 10) || 0) +
128
- (parseInt(elem.css('paddingRight'), 10) || 0);
129
- }
130
-
131
- function initialise(s)
132
- {
133
-
134
- var /*firstChild, lastChild, */isMaintainingPositon, lastContentX, lastContentY,
135
- hasContainingSpaceChanged, originalScrollTop, originalScrollLeft,
136
- newPaneWidth, newPaneHeight, maintainAtBottom = false, maintainAtRight = false;
137
-
138
- settings = s;
139
-
140
- if (pane === undefined) {
141
- originalScrollTop = elem.scrollTop();
142
- originalScrollLeft = elem.scrollLeft();
143
-
144
- elem.css(
145
- {
146
- overflow: 'hidden',
147
- padding: 0
148
- }
149
- );
150
- // TODO: Deal with where width/ height is 0 as it probably means the element is hidden and we should
151
- // come back to it later and check once it is unhidden...
152
- paneWidth = elem.innerWidth() + originalPaddingTotalWidth;
153
- paneHeight = elem.innerHeight();
154
-
155
- elem.width(paneWidth);
156
-
157
- pane = $('<div class="jspPane" />').css('padding', originalPadding).append(elem.children());
158
- container = $('<div class="jspContainer" />')
159
- .css({
160
- 'width': paneWidth + 'px',
161
- 'height': paneHeight + 'px'
162
- }
163
- ).append(pane).appendTo(elem);
164
-
165
- /*
166
- // Move any margins from the first and last children up to the container so they can still
167
- // collapse with neighbouring elements as they would before jScrollPane
168
- firstChild = pane.find(':first-child');
169
- lastChild = pane.find(':last-child');
170
- elem.css(
171
- {
172
- 'margin-top': firstChild.css('margin-top'),
173
- 'margin-bottom': lastChild.css('margin-bottom')
174
- }
175
- );
176
- firstChild.css('margin-top', 0);
177
- lastChild.css('margin-bottom', 0);
178
- */
179
- } else {
180
- elem.css('width', '');
181
-
182
- // To measure the required dimensions accurately, temporarily override the CSS positioning
183
- // of the container and pane.
184
- container.css({width: 'auto', height: 'auto'});
185
- pane.css('position', 'static');
186
-
187
- newPaneWidth = elem.innerWidth() + originalPaddingTotalWidth;
188
- newPaneHeight = elem.innerHeight();
189
- pane.css('position', 'absolute');
190
-
191
- maintainAtBottom = settings.stickToBottom && isCloseToBottom();
192
- maintainAtRight = settings.stickToRight && isCloseToRight();
193
-
194
- hasContainingSpaceChanged = newPaneWidth !== paneWidth || newPaneHeight !== paneHeight;
195
-
196
- paneWidth = newPaneWidth;
197
- paneHeight = newPaneHeight;
198
- container.css({width: paneWidth, height: paneHeight});
199
-
200
- // If nothing changed since last check...
201
- if (!hasContainingSpaceChanged && previousContentWidth == contentWidth && pane.outerHeight() == contentHeight) {
202
- elem.width(paneWidth);
203
- return;
204
- }
205
- previousContentWidth = contentWidth;
206
-
207
- pane.css('width', '');
208
- elem.width(paneWidth);
209
-
210
- container.find('>.jspVerticalBar,>.jspHorizontalBar').remove().end();
211
- }
67
+ if (typeof define === 'function' && define.amd) {
68
+ // AMD. Register as an anonymous module.
69
+ define(['jquery'], factory);
70
+ } else if (typeof exports === 'object') {
71
+ // Node/CommonJS style for Browserify
72
+ module.exports = factory(jQuery || require('jquery'));
73
+ } else {
74
+ // Browser globals
75
+ factory(jQuery);
76
+ }
77
+ })(function ($) {
78
+ $.fn.jScrollPane = function (settings) {
79
+ // JScrollPane "class" - public methods are available through $('selector').data('jsp')
80
+ function JScrollPane(elem, s) {
81
+ var settings,
82
+ jsp = this,
83
+ pane,
84
+ paneWidth,
85
+ paneHeight,
86
+ container,
87
+ contentWidth,
88
+ contentHeight,
89
+ percentInViewH,
90
+ percentInViewV,
91
+ isScrollableV,
92
+ isScrollableH,
93
+ verticalDrag,
94
+ dragMaxY,
95
+ verticalDragPosition,
96
+ horizontalDrag,
97
+ dragMaxX,
98
+ horizontalDragPosition,
99
+ verticalBar,
100
+ verticalTrack,
101
+ scrollbarWidth,
102
+ verticalTrackHeight,
103
+ verticalDragHeight,
104
+ arrowUp,
105
+ arrowDown,
106
+ horizontalBar,
107
+ horizontalTrack,
108
+ horizontalTrackWidth,
109
+ horizontalDragWidth,
110
+ arrowLeft,
111
+ arrowRight,
112
+ reinitialiseInterval,
113
+ originalPadding,
114
+ originalPaddingTotalWidth,
115
+ previousContentWidth,
116
+ wasAtTop = true,
117
+ wasAtLeft = true,
118
+ wasAtBottom = false,
119
+ wasAtRight = false,
120
+ originalElement = elem.clone(false, false).empty(),
121
+ resizeEventsAdded = false,
122
+ mwEvent = $.fn.mwheelIntent ? 'mwheelIntent.jsp' : 'mousewheel.jsp';
123
+
124
+ var reinitialiseFn = function () {
125
+ // if size has changed then reinitialise
126
+ if (settings.resizeSensorDelay > 0) {
127
+ setTimeout(function () {
128
+ initialise(settings);
129
+ }, settings.resizeSensorDelay);
130
+ } else {
131
+ initialise(settings);
132
+ }
133
+ };
212
134
 
213
- pane.css('overflow', 'auto');
214
- if (s.contentWidth) {
215
- contentWidth = s.contentWidth;
216
- } else {
217
- contentWidth = pane[0].scrollWidth;
218
- }
219
- contentHeight = pane[0].scrollHeight;
220
- pane.css('overflow', '');
221
-
222
- percentInViewH = contentWidth / paneWidth;
223
- percentInViewV = contentHeight / paneHeight;
224
- isScrollableV = percentInViewV > 1 || settings.alwaysShowVScroll;
225
- isScrollableH = percentInViewH > 1 || settings.alwaysShowHScroll;
226
-
227
- if (!(isScrollableH || isScrollableV)) {
228
- elem.removeClass('jspScrollable');
229
- pane.css({
230
- top: 0,
231
- left: 0,
232
- width: container.width() - originalPaddingTotalWidth
233
- });
234
- removeMousewheel();
235
- removeFocusHandler();
236
- removeKeyboardNav();
237
- removeClickOnTrack();
238
- } else {
239
- elem.addClass('jspScrollable');
240
-
241
- isMaintainingPositon = settings.maintainPosition && (verticalDragPosition || horizontalDragPosition);
242
- if (isMaintainingPositon) {
243
- lastContentX = contentPositionX();
244
- lastContentY = contentPositionY();
245
- }
246
-
247
- initialiseVerticalScroll();
248
- initialiseHorizontalScroll();
249
- resizeScrollbars();
250
-
251
- if (isMaintainingPositon) {
252
- scrollToX(maintainAtRight ? (contentWidth - paneWidth ) : lastContentX, false);
253
- scrollToY(maintainAtBottom ? (contentHeight - paneHeight) : lastContentY, false);
254
- }
255
-
256
- initFocusHandler();
257
- initMousewheel();
258
- initTouch();
259
-
260
- if (settings.enableKeyboardNavigation) {
261
- initKeyboardNav();
262
- }
263
- if (settings.clickOnTrack) {
264
- initClickOnTrack();
265
- }
266
-
267
- observeHash();
268
- if (settings.hijackInternalLinks) {
269
- hijackInternalLinks();
270
- }
271
- }
135
+ if (elem.css('box-sizing') === 'border-box') {
136
+ originalPadding = 0;
137
+ originalPaddingTotalWidth = 0;
138
+ } else {
139
+ originalPadding =
140
+ elem.css('paddingTop') +
141
+ ' ' +
142
+ elem.css('paddingRight') +
143
+ ' ' +
144
+ elem.css('paddingBottom') +
145
+ ' ' +
146
+ elem.css('paddingLeft');
147
+ originalPaddingTotalWidth = (parseInt(elem.css('paddingLeft'), 10) || 0) + (parseInt(elem.css('paddingRight'), 10) || 0);
148
+ }
272
149
 
273
- if (!settings.resizeSensor && settings.autoReinitialise && !reinitialiseInterval) {
274
- reinitialiseInterval = setInterval(
275
- function()
276
- {
277
- initialise(settings);
278
- },
279
- settings.autoReinitialiseDelay
280
- );
281
- } else if (!settings.resizeSensor && !settings.autoReinitialise && reinitialiseInterval) {
282
- clearInterval(reinitialiseInterval);
283
- }
150
+ function initialise(s) {
151
+ var /*firstChild, lastChild, */ isMaintainingPositon,
152
+ lastContentX,
153
+ lastContentY,
154
+ hasContainingSpaceChanged,
155
+ originalScrollTop,
156
+ originalScrollLeft,
157
+ newPaneWidth,
158
+ newPaneHeight,
159
+ maintainAtBottom = false,
160
+ maintainAtRight = false;
161
+
162
+ settings = s;
163
+ lastContentX = 0;
164
+ lastContentY = 0;
165
+
166
+ if (pane === undefined) {
167
+ originalScrollTop = elem.scrollTop();
168
+ originalScrollLeft = elem.scrollLeft();
169
+
170
+ elem.css({
171
+ overflow: 'hidden',
172
+ padding: '0',
173
+ });
174
+ // TODO: Deal with where width/ height is 0 as it probably means the element is hidden and we should
175
+ // come back to it later and check once it is unhidden...
176
+ paneWidth = elem.innerWidth() + originalPaddingTotalWidth;
177
+ paneHeight = elem.innerHeight();
178
+
179
+ elem.width(paneWidth);
180
+
181
+ pane = $('<div class="jspPane"></div>').css('padding', originalPadding).append(elem.children());
182
+ container = $('<div class="jspContainer"></div>')
183
+ .css({
184
+ width: paneWidth + 'px',
185
+ height: paneHeight + 'px',
186
+ })
187
+ .append(pane)
188
+ .appendTo(elem);
189
+
190
+ /*
191
+ // Move any margins from the first and last children up to the container so they can still
192
+ // collapse with neighbouring elements as they would before jScrollPane
193
+ firstChild = pane.find(':first-child');
194
+ lastChild = pane.find(':last-child');
195
+ elem.css(
196
+ {
197
+ 'margin-top': firstChild.css('margin-top'),
198
+ 'margin-bottom': lastChild.css('margin-bottom')
199
+ }
200
+ );
201
+ firstChild.css('margin-top', 0);
202
+ lastChild.css('margin-bottom', 0);
203
+ */
204
+ } else {
205
+ elem.css('width', '');
206
+
207
+ // To measure the required dimensions accurately, temporarily override the CSS positioning
208
+ // of the container and pane.
209
+ container.css({ width: 'auto', height: 'auto' });
210
+ pane.css('position', 'static');
211
+
212
+ newPaneWidth = elem.innerWidth() + originalPaddingTotalWidth;
213
+ newPaneHeight = elem.innerHeight();
214
+ pane.css('position', 'absolute');
215
+
216
+ maintainAtBottom = settings.stickToBottom && isCloseToBottom();
217
+ maintainAtRight = settings.stickToRight && isCloseToRight();
218
+
219
+ hasContainingSpaceChanged = newPaneWidth !== paneWidth || newPaneHeight !== paneHeight;
220
+
221
+ paneWidth = newPaneWidth;
222
+ paneHeight = newPaneHeight;
223
+ container.css({ width: paneWidth + 'px', height: paneHeight + 'px' });
224
+
225
+ // If nothing changed since last check...
226
+ if (!hasContainingSpaceChanged && previousContentWidth == contentWidth && pane.outerHeight() == contentHeight) {
227
+ elem.width(paneWidth);
228
+ return;
229
+ }
230
+ previousContentWidth = contentWidth;
284
231
 
285
- if(settings.resizeSensor && !resizeEventsAdded) {
232
+ pane.css('width', '');
233
+ elem.width(paneWidth);
286
234
 
287
- // detect size change in content
288
- detectSizeChanges(pane, reinitialiseFn);
235
+ container.find('>.jspVerticalBar,>.jspHorizontalBar').remove().end();
236
+ }
289
237
 
290
- // detect size changes of scroll element
291
- detectSizeChanges(elem, reinitialiseFn);
238
+ pane.css('overflow', 'auto');
239
+ if (s.contentWidth) {
240
+ contentWidth = s.contentWidth;
241
+ } else {
242
+ contentWidth = pane[0].scrollWidth;
243
+ }
244
+ contentHeight = pane[0].scrollHeight;
245
+ pane.css('overflow', '');
246
+
247
+ percentInViewH = contentWidth / paneWidth;
248
+ percentInViewV = contentHeight / paneHeight;
249
+ isScrollableV = percentInViewV > 1 || settings.alwaysShowVScroll;
250
+ isScrollableH = percentInViewH > 1 || settings.alwaysShowHScroll;
251
+
252
+ if (!(isScrollableH || isScrollableV)) {
253
+ elem.removeClass('jspScrollable');
254
+ pane.css({
255
+ top: '0',
256
+ left: '0',
257
+ width: container.width() - originalPaddingTotalWidth,
258
+ });
259
+ removeMousewheel();
260
+ removeFocusHandler();
261
+ removeKeyboardNav();
262
+ removeClickOnTrack();
263
+ } else {
264
+ elem.addClass('jspScrollable');
265
+
266
+ isMaintainingPositon = settings.maintainPosition && (verticalDragPosition || horizontalDragPosition);
267
+
268
+ if (isMaintainingPositon) {
269
+ lastContentX = contentPositionX();
270
+ lastContentY = contentPositionY();
271
+ }
292
272
 
293
- // detect size changes of container
294
- detectSizeChanges(elem.parent(), reinitialiseFn);
273
+ initialiseVerticalScroll();
274
+ initialiseHorizontalScroll();
275
+ resizeScrollbars();
295
276
 
296
- // add a reinit on window resize also for safety
297
- window.addEventListener('resize', reinitialiseFn);
277
+ if (settings.stickToBottom || settings.stickToRight) {
278
+ scrollToX(maintainAtRight ? contentWidth - paneWidth : lastContentX, false);
279
+ scrollToY(maintainAtBottom ? contentHeight - paneHeight : lastContentY, false);
280
+ }
298
281
 
299
- resizeEventsAdded = true;
300
- }
282
+ initFocusHandler();
283
+ initMousewheel();
284
+ initTouch();
301
285
 
302
- if(originalScrollTop && elem.scrollTop(0)) {
303
- scrollToY(originalScrollTop, false);
304
- }
286
+ if (settings.enableKeyboardNavigation) {
287
+ initKeyboardNav();
288
+ }
289
+ if (settings.clickOnTrack) {
290
+ initClickOnTrack();
291
+ }
305
292
 
306
- if(originalScrollLeft && elem.scrollLeft(0)) {
307
- scrollToX(originalScrollLeft, false);
308
- }
293
+ observeHash();
294
+ if (settings.hijackInternalLinks) {
295
+ hijackInternalLinks();
296
+ }
297
+ }
309
298
 
310
- elem.trigger('jsp-initialised', [isScrollableH || isScrollableV]);
311
- }
299
+ if (!settings.resizeSensor && settings.autoReinitialise && !reinitialiseInterval) {
300
+ reinitialiseInterval = setInterval(function () {
301
+ initialise(settings);
302
+ }, settings.autoReinitialiseDelay);
303
+ } else if (!settings.resizeSensor && !settings.autoReinitialise && reinitialiseInterval) {
304
+ clearInterval(reinitialiseInterval);
305
+ }
312
306
 
313
- function detectSizeChanges(element, callback) {
307
+ if (settings.resizeSensor && !resizeEventsAdded) {
308
+ // detect size change in content
309
+ detectSizeChanges(pane, reinitialiseFn);
314
310
 
315
- // create resize event elements - based on resize sensor: https://github.com/flowkey/resize-sensor/
316
- var resizeWidth, resizeHeight;
317
- var resizeElement = document.createElement('div');
318
- var resizeGrowElement = document.createElement('div');
319
- var resizeGrowChildElement = document.createElement('div');
320
- var resizeShrinkElement = document.createElement('div');
321
- var resizeShrinkChildElement = document.createElement('div');
311
+ // detect size changes of scroll element
312
+ detectSizeChanges(elem, reinitialiseFn);
322
313
 
323
- // add necessary styling
324
- resizeElement.style.cssText = 'position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;';
325
- resizeGrowElement.style.cssText = 'position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;';
326
- resizeShrinkElement.style.cssText = 'position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;';
314
+ // detect size changes of container
315
+ detectSizeChanges(elem.parent(), reinitialiseFn);
327
316
 
328
- resizeGrowChildElement.style.cssText = 'position: absolute; left: 0; top: 0;';
329
- resizeShrinkChildElement.style.cssText = 'position: absolute; left: 0; top: 0; width: 200%; height: 200%;';
317
+ // add a reinit on window resize also for safety
318
+ window.addEventListener('resize', reinitialiseFn);
330
319
 
331
- // Create a function to programmatically update sizes
332
- var updateSizes = function() {
320
+ resizeEventsAdded = true;
321
+ }
333
322
 
334
- resizeGrowChildElement.style.width = resizeGrowElement.offsetWidth + 10 + 'px';
335
- resizeGrowChildElement.style.height = resizeGrowElement.offsetHeight + 10 + 'px';
323
+ if (originalScrollTop && elem.scrollTop(0)) {
324
+ scrollToY(originalScrollTop, false);
325
+ }
336
326
 
337
- resizeGrowElement.scrollLeft = resizeGrowElement.scrollWidth;
338
- resizeGrowElement.scrollTop = resizeGrowElement.scrollHeight;
327
+ if (originalScrollLeft && elem.scrollLeft(0)) {
328
+ scrollToX(originalScrollLeft, false);
329
+ }
339
330
 
340
- resizeShrinkElement.scrollLeft = resizeShrinkElement.scrollWidth;
341
- resizeShrinkElement.scrollTop = resizeShrinkElement.scrollHeight;
331
+ elem.trigger('jsp-initialised', [isScrollableH || isScrollableV]);
332
+ }
342
333
 
343
- resizeWidth = element.width();
344
- resizeHeight = element.height();
345
- };
334
+ function detectSizeChanges(element, callback) {
335
+ // create resize event elements - based on resize sensor: https://github.com/flowkey/resize-sensor/
336
+ var resizeWidth, resizeHeight;
337
+ var resizeElement = document.createElement('div');
338
+ var resizeGrowElement = document.createElement('div');
339
+ var resizeGrowChildElement = document.createElement('div');
340
+ var resizeShrinkElement = document.createElement('div');
341
+ var resizeShrinkChildElement = document.createElement('div');
342
+
343
+ // add necessary styling
344
+ resizeElement.style.cssText =
345
+ 'position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;';
346
+ resizeGrowElement.style.cssText =
347
+ 'position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;';
348
+ resizeShrinkElement.style.cssText =
349
+ 'position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;';
350
+
351
+ resizeGrowChildElement.style.cssText = 'position: absolute; left: 0; top: 0;';
352
+ resizeShrinkChildElement.style.cssText = 'position: absolute; left: 0; top: 0; width: 200%; height: 200%;';
353
+
354
+ // Create a function to programmatically update sizes
355
+ var updateSizes = function () {
356
+ resizeGrowChildElement.style.width = resizeGrowElement.offsetWidth + 10 + 'px';
357
+ resizeGrowChildElement.style.height = resizeGrowElement.offsetHeight + 10 + 'px';
358
+
359
+ resizeGrowElement.scrollLeft = resizeGrowElement.scrollWidth;
360
+ resizeGrowElement.scrollTop = resizeGrowElement.scrollHeight;
361
+
362
+ resizeShrinkElement.scrollLeft = resizeShrinkElement.scrollWidth;
363
+ resizeShrinkElement.scrollTop = resizeShrinkElement.scrollHeight;
364
+
365
+ resizeWidth = element.width();
366
+ resizeHeight = element.height();
367
+ };
368
+
369
+ // create functions to call when content grows
370
+ var onGrow = function () {
371
+ // check to see if the content has change size
372
+ if (element.width() > resizeWidth || element.height() > resizeHeight) {
373
+ // if size has changed then reinitialise
374
+ callback.apply(this, []);
375
+ }
376
+ // after reinitialising update sizes
377
+ updateSizes();
378
+ };
379
+
380
+ // create functions to call when content shrinks
381
+ var onShrink = function () {
382
+ // check to see if the content has change size
383
+ if (element.width() < resizeWidth || element.height() < resizeHeight) {
384
+ // if size has changed then reinitialise
385
+ callback.apply(this, []);
386
+ }
387
+ // after reinitialising update sizes
388
+ updateSizes();
389
+ };
346
390
 
347
- // create functions to call when content grows
348
- var onGrow = function() {
391
+ // bind to scroll events
392
+ resizeGrowElement.addEventListener('scroll', onGrow.bind(this));
393
+ resizeShrinkElement.addEventListener('scroll', onShrink.bind(this));
349
394
 
350
- // check to see if the content has change size
351
- if (element.width() > resizeWidth || element.height() > resizeHeight) {
395
+ // nest elements before adding to pane
396
+ resizeGrowElement.appendChild(resizeGrowChildElement);
397
+ resizeShrinkElement.appendChild(resizeShrinkChildElement);
352
398
 
353
- // if size has changed then reinitialise
354
- callback.apply(this, []);
355
- }
356
- // after reinitialising update sizes
357
- updateSizes();
358
- };
399
+ resizeElement.appendChild(resizeGrowElement);
400
+ resizeElement.appendChild(resizeShrinkElement);
359
401
 
360
- // create functions to call when content shrinks
361
- var onShrink = function() {
402
+ element.append(resizeElement);
362
403
 
363
- // check to see if the content has change size
364
- if (element.width() < resizeWidth || element.height() < resizeHeight) {
404
+ // ensure parent element is not statically positioned
405
+ if (window.getComputedStyle(element[0], null).getPropertyValue('position') === 'static') {
406
+ element[0].style.position = 'relative';
407
+ }
365
408
 
366
- // if size has changed then reinitialise
367
- callback.apply(this, []);
368
- }
369
- // after reinitialising update sizes
370
- updateSizes();
371
- };
409
+ // update sizes initially
410
+ updateSizes();
411
+ }
372
412
 
373
- // bind to scroll events
374
- resizeGrowElement.addEventListener('scroll', onGrow.bind(this));
375
- resizeShrinkElement.addEventListener('scroll', onShrink.bind(this));
413
+ function initialiseVerticalScroll() {
414
+ if (isScrollableV) {
415
+ container.append(
416
+ $('<div class="jspVerticalBar"></div>').append(
417
+ $('<div class="jspCap jspCapTop"></div>'),
418
+ $('<div class="jspTrack"></div>').append(
419
+ $('<div class="jspDrag"></div>').append(
420
+ $('<div class="jspDragTop"></div>'),
421
+ $('<div class="jspDragBottom"></div>'),
422
+ ),
423
+ ),
424
+ $('<div class="jspCap jspCapBottom"></div>'),
425
+ ),
426
+ );
427
+
428
+ verticalBar = container.find('>.jspVerticalBar');
429
+ verticalTrack = verticalBar.find('>.jspTrack');
430
+ verticalDrag = verticalTrack.find('>.jspDrag');
431
+
432
+ if (settings.showArrows) {
433
+ arrowUp = $('<a class="jspArrow jspArrowUp"></a>').on('mousedown.jsp', getArrowScroll(0, -1)).on('click.jsp', nil);
434
+ arrowDown = $('<a class="jspArrow jspArrowDown"></a>')
435
+ .on('mousedown.jsp', getArrowScroll(0, 1))
436
+ .on('click.jsp', nil);
437
+ if (settings.arrowScrollOnHover) {
438
+ arrowUp.on('mouseover.jsp', getArrowScroll(0, -1, arrowUp));
439
+ arrowDown.on('mouseover.jsp', getArrowScroll(0, 1, arrowDown));
440
+ }
376
441
 
377
- // nest elements before adding to pane
378
- resizeGrowElement.appendChild(resizeGrowChildElement);
379
- resizeShrinkElement.appendChild(resizeShrinkChildElement);
442
+ appendArrows(verticalTrack, settings.verticalArrowPositions, arrowUp, arrowDown);
443
+ }
380
444
 
381
- resizeElement.appendChild(resizeGrowElement);
382
- resizeElement.appendChild(resizeShrinkElement);
445
+ verticalTrackHeight = paneHeight;
446
+ container.find('>.jspVerticalBar>.jspCap:visible,>.jspVerticalBar>.jspArrow').each(function () {
447
+ verticalTrackHeight -= $(this).outerHeight();
448
+ });
449
+
450
+ verticalDrag
451
+ .on('mouseenter', function () {
452
+ verticalDrag.addClass('jspHover');
453
+ })
454
+ .on('mouseleave', function () {
455
+ verticalDrag.removeClass('jspHover');
456
+ })
457
+ .on('mousedown.jsp', function (e) {
458
+ // Stop IE from allowing text selection
459
+ $('html').on('dragstart.jsp selectstart.jsp', nil);
460
+
461
+ verticalDrag.addClass('jspActive');
462
+
463
+ var startY = e.pageY - verticalDrag.position().top;
464
+
465
+ $('html')
466
+ .on('mousemove.jsp', function (e) {
467
+ positionDragY(e.pageY - startY, false);
468
+ })
469
+ .on('mouseup.jsp mouseleave.jsp', cancelDrag);
470
+ return false;
471
+ });
472
+ sizeVerticalScrollbar();
473
+ }
474
+ }
383
475
 
384
- element.append(resizeElement);
476
+ function sizeVerticalScrollbar() {
477
+ verticalTrack.height(verticalTrackHeight + 'px');
478
+ verticalDragPosition = 0;
479
+ scrollbarWidth = settings.verticalGutter + verticalTrack.outerWidth();
385
480
 
386
- // ensure parent element is not statically positioned
387
- if(window.getComputedStyle(element[0], null).getPropertyValue('position') === 'static') {
388
- element[0].style.position = 'relative';
389
- }
481
+ // Make the pane thinner to allow for the vertical scrollbar
482
+ pane.width(paneWidth - scrollbarWidth - originalPaddingTotalWidth);
390
483
 
391
- // update sizes initially
392
- updateSizes();
393
- }
394
-
395
- function initialiseVerticalScroll()
396
- {
397
- if (isScrollableV) {
398
-
399
- container.append(
400
- $('<div class="jspVerticalBar" />').append(
401
- $('<div class="jspCap jspCapTop" />'),
402
- $('<div class="jspTrack" />').append(
403
- $('<div class="jspDrag" />').append(
404
- $('<div class="jspDragTop" />'),
405
- $('<div class="jspDragBottom" />')
406
- )
407
- ),
408
- $('<div class="jspCap jspCapBottom" />')
409
- )
410
- );
411
-
412
- verticalBar = container.find('>.jspVerticalBar');
413
- verticalTrack = verticalBar.find('>.jspTrack');
414
- verticalDrag = verticalTrack.find('>.jspDrag');
415
-
416
- if (settings.showArrows) {
417
- arrowUp = $('<a class="jspArrow jspArrowUp" />').on(
418
- 'mousedown.jsp', getArrowScroll(0, -1)
419
- ).on('click.jsp', nil);
420
- arrowDown = $('<a class="jspArrow jspArrowDown" />').on(
421
- 'mousedown.jsp', getArrowScroll(0, 1)
422
- ).on('click.jsp', nil);
423
- if (settings.arrowScrollOnHover) {
424
- arrowUp.on('mouseover.jsp', getArrowScroll(0, -1, arrowUp));
425
- arrowDown.on('mouseover.jsp', getArrowScroll(0, 1, arrowDown));
484
+ // Add margin to the left of the pane if scrollbars are on that side (to position
485
+ // the scrollbar on the left or right set it's left or right property in CSS)
486
+ try {
487
+ if (verticalBar.position().left === 0) {
488
+ pane.css('margin-left', scrollbarWidth + 'px');
489
+ }
490
+ } catch (err) {}
426
491
  }
427
492
 
428
- appendArrows(verticalTrack, settings.verticalArrowPositions, arrowUp, arrowDown);
429
- }
430
-
431
- verticalTrackHeight = paneHeight;
432
- container.find('>.jspVerticalBar>.jspCap:visible,>.jspVerticalBar>.jspArrow').each(
433
- function()
434
- {
435
- verticalTrackHeight -= $(this).outerHeight();
436
- }
437
- );
438
-
439
-
440
- verticalDrag.on(
441
- "mouseenter",
442
- function()
443
- {
444
- verticalDrag.addClass('jspHover');
445
- }
446
- ).on(
447
- "mouseleave",
448
- function()
449
- {
450
- verticalDrag.removeClass('jspHover');
451
- }
452
- ).on(
453
- 'mousedown.jsp',
454
- function(e)
455
- {
456
- // Stop IE from allowing text selection
457
- $('html').on('dragstart.jsp selectstart.jsp', nil);
458
-
459
- verticalDrag.addClass('jspActive');
460
-
461
- var startY = e.pageY - verticalDrag.position().top;
462
-
463
- $('html').on(
464
- 'mousemove.jsp',
465
- function(e)
466
- {
467
- positionDragY(e.pageY - startY, false);
493
+ function initialiseHorizontalScroll() {
494
+ if (isScrollableH) {
495
+ container.append(
496
+ $('<div class="jspHorizontalBar"></div>').append(
497
+ $('<div class="jspCap jspCapLeft"></div>'),
498
+ $('<div class="jspTrack"></div>').append(
499
+ $('<div class="jspDrag"></div>').append(
500
+ $('<div class="jspDragLeft"></div>'),
501
+ $('<div class="jspDragRight"></div>'),
502
+ ),
503
+ ),
504
+ $('<div class="jspCap jspCapRight"></div>'),
505
+ ),
506
+ );
507
+
508
+ horizontalBar = container.find('>.jspHorizontalBar');
509
+ horizontalTrack = horizontalBar.find('>.jspTrack');
510
+ horizontalDrag = horizontalTrack.find('>.jspDrag');
511
+
512
+ if (settings.showArrows) {
513
+ arrowLeft = $('<a class="jspArrow jspArrowLeft"></a>')
514
+ .on('mousedown.jsp', getArrowScroll(-1, 0))
515
+ .on('click.jsp', nil);
516
+ arrowRight = $('<a class="jspArrow jspArrowRight"></a>')
517
+ .on('mousedown.jsp', getArrowScroll(1, 0))
518
+ .on('click.jsp', nil);
519
+ if (settings.arrowScrollOnHover) {
520
+ arrowLeft.on('mouseover.jsp', getArrowScroll(-1, 0, arrowLeft));
521
+ arrowRight.on('mouseover.jsp', getArrowScroll(1, 0, arrowRight));
522
+ }
523
+ appendArrows(horizontalTrack, settings.horizontalArrowPositions, arrowLeft, arrowRight);
468
524
  }
469
- ).on('mouseup.jsp mouseleave.jsp', cancelDrag);
470
- return false;
471
- }
472
- );
473
- sizeVerticalScrollbar();
474
- }
475
- }
476
-
477
- function sizeVerticalScrollbar()
478
- {
479
- verticalTrack.height(verticalTrackHeight + 'px');
480
- verticalDragPosition = 0;
481
- scrollbarWidth = settings.verticalGutter + verticalTrack.outerWidth();
482
-
483
- // Make the pane thinner to allow for the vertical scrollbar
484
- pane.width(paneWidth - scrollbarWidth - originalPaddingTotalWidth);
485
-
486
- // Add margin to the left of the pane if scrollbars are on that side (to position
487
- // the scrollbar on the left or right set it's left or right property in CSS)
488
- try {
489
- if (verticalBar.position().left === 0) {
490
- pane.css('margin-left', scrollbarWidth + 'px');
491
- }
492
- } catch (err) {
493
- }
494
- }
495
-
496
- function initialiseHorizontalScroll()
497
- {
498
- if (isScrollableH) {
499
-
500
- container.append(
501
- $('<div class="jspHorizontalBar" />').append(
502
- $('<div class="jspCap jspCapLeft" />'),
503
- $('<div class="jspTrack" />').append(
504
- $('<div class="jspDrag" />').append(
505
- $('<div class="jspDragLeft" />'),
506
- $('<div class="jspDragRight" />')
507
- )
508
- ),
509
- $('<div class="jspCap jspCapRight" />')
510
- )
511
- );
512
-
513
- horizontalBar = container.find('>.jspHorizontalBar');
514
- horizontalTrack = horizontalBar.find('>.jspTrack');
515
- horizontalDrag = horizontalTrack.find('>.jspDrag');
516
-
517
- if (settings.showArrows) {
518
- arrowLeft = $('<a class="jspArrow jspArrowLeft" />').on(
519
- 'mousedown.jsp', getArrowScroll(-1, 0)
520
- ).on('click.jsp', nil);
521
- arrowRight = $('<a class="jspArrow jspArrowRight" />').on(
522
- 'mousedown.jsp', getArrowScroll(1, 0)
523
- ).on('click.jsp', nil);
524
- if (settings.arrowScrollOnHover) {
525
- arrowLeft.on('mouseover.jsp', getArrowScroll(-1, 0, arrowLeft));
526
- arrowRight.on('mouseover.jsp', getArrowScroll(1, 0, arrowRight));
525
+
526
+ horizontalDrag
527
+ .on('mouseenter', function () {
528
+ horizontalDrag.addClass('jspHover');
529
+ })
530
+ .on('mouseleave', function () {
531
+ horizontalDrag.removeClass('jspHover');
532
+ })
533
+ .on('mousedown.jsp', function (e) {
534
+ // Stop IE from allowing text selection
535
+ $('html').on('dragstart.jsp selectstart.jsp', nil);
536
+
537
+ horizontalDrag.addClass('jspActive');
538
+
539
+ var startX = e.pageX - horizontalDrag.position().left;
540
+
541
+ $('html')
542
+ .on('mousemove.jsp', function (e) {
543
+ positionDragX(e.pageX - startX, false);
544
+ })
545
+ .on('mouseup.jsp mouseleave.jsp', cancelDrag);
546
+ return false;
547
+ });
548
+ horizontalTrackWidth = container.innerWidth();
549
+ sizeHorizontalScrollbar();
550
+ }
527
551
  }
528
- appendArrows(horizontalTrack, settings.horizontalArrowPositions, arrowLeft, arrowRight);
529
- }
530
-
531
- horizontalDrag.on(
532
- "mouseenter",
533
- function()
534
- {
535
- horizontalDrag.addClass('jspHover');
536
- }
537
- ).on(
538
- "mouseleave",
539
- function()
540
- {
541
- horizontalDrag.removeClass('jspHover');
542
- }
543
- ).on(
544
- 'mousedown.jsp',
545
- function(e)
546
- {
547
- // Stop IE from allowing text selection
548
- $('html').on('dragstart.jsp selectstart.jsp', nil);
549
-
550
- horizontalDrag.addClass('jspActive');
551
-
552
- var startX = e.pageX - horizontalDrag.position().left;
553
-
554
- $('html').on(
555
- 'mousemove.jsp',
556
- function(e)
557
- {
558
- positionDragX(e.pageX - startX, false);
552
+
553
+ function sizeHorizontalScrollbar() {
554
+ container.find('>.jspHorizontalBar>.jspCap:visible,>.jspHorizontalBar>.jspArrow').each(function () {
555
+ horizontalTrackWidth -= $(this).outerWidth();
556
+ });
557
+
558
+ horizontalTrack.width(horizontalTrackWidth + 'px');
559
+ horizontalDragPosition = 0;
560
+ }
561
+
562
+ function resizeScrollbars() {
563
+ if (isScrollableH && isScrollableV) {
564
+ var horizontalTrackHeight = horizontalTrack.outerHeight(),
565
+ verticalTrackWidth = verticalTrack.outerWidth();
566
+ verticalTrackHeight -= horizontalTrackHeight;
567
+ $(horizontalBar)
568
+ .find('>.jspCap:visible,>.jspArrow')
569
+ .each(function () {
570
+ horizontalTrackWidth += $(this).outerWidth();
571
+ });
572
+ horizontalTrackWidth -= verticalTrackWidth;
573
+ paneHeight -= verticalTrackWidth;
574
+ paneWidth -= horizontalTrackHeight;
575
+ horizontalTrack.parent().append($('<div class="jspCorner"></div>').css('width', horizontalTrackHeight + 'px'));
576
+ sizeVerticalScrollbar();
577
+ sizeHorizontalScrollbar();
578
+ }
579
+ // reflow content
580
+ if (isScrollableH) {
581
+ pane.width(container.outerWidth() - originalPaddingTotalWidth + 'px');
582
+ }
583
+ contentHeight = pane.outerHeight();
584
+ percentInViewV = contentHeight / paneHeight;
585
+
586
+ if (isScrollableH) {
587
+ horizontalDragWidth = Math.ceil((1 / percentInViewH) * horizontalTrackWidth);
588
+ if (horizontalDragWidth > settings.horizontalDragMaxWidth) {
589
+ horizontalDragWidth = settings.horizontalDragMaxWidth;
590
+ } else if (horizontalDragWidth < settings.horizontalDragMinWidth) {
591
+ horizontalDragWidth = settings.horizontalDragMinWidth;
559
592
  }
560
- ).on('mouseup.jsp mouseleave.jsp', cancelDrag);
561
- return false;
562
- }
563
- );
564
- horizontalTrackWidth = container.innerWidth();
565
- sizeHorizontalScrollbar();
566
- }
567
- }
568
-
569
- function sizeHorizontalScrollbar()
570
- {
571
- container.find('>.jspHorizontalBar>.jspCap:visible,>.jspHorizontalBar>.jspArrow').each(
572
- function()
573
- {
574
- horizontalTrackWidth -= $(this).outerWidth();
593
+ horizontalDrag.css('width', horizontalDragWidth + 'px');
594
+ dragMaxX = horizontalTrackWidth - horizontalDragWidth;
595
+ _positionDragX(horizontalDragPosition); // To update the state for the arrow buttons
596
+ }
597
+ if (isScrollableV) {
598
+ verticalDragHeight = Math.ceil((1 / percentInViewV) * verticalTrackHeight);
599
+ if (verticalDragHeight > settings.verticalDragMaxHeight) {
600
+ verticalDragHeight = settings.verticalDragMaxHeight;
601
+ } else if (verticalDragHeight < settings.verticalDragMinHeight) {
602
+ verticalDragHeight = settings.verticalDragMinHeight;
603
+ }
604
+ verticalDrag.css('height', verticalDragHeight + 'px');
605
+ dragMaxY = verticalTrackHeight - verticalDragHeight;
606
+ _positionDragY(verticalDragPosition); // To update the state for the arrow buttons
607
+ }
575
608
  }
576
- );
577
-
578
- horizontalTrack.width(horizontalTrackWidth + 'px');
579
- horizontalDragPosition = 0;
580
- }
581
-
582
- function resizeScrollbars()
583
- {
584
- if (isScrollableH && isScrollableV) {
585
- var horizontalTrackHeight = horizontalTrack.outerHeight(),
586
- verticalTrackWidth = verticalTrack.outerWidth();
587
- verticalTrackHeight -= horizontalTrackHeight;
588
- $(horizontalBar).find('>.jspCap:visible,>.jspArrow').each(
589
- function()
590
- {
591
- horizontalTrackWidth += $(this).outerWidth();
592
- }
593
- );
594
- horizontalTrackWidth -= verticalTrackWidth;
595
- paneHeight -= verticalTrackWidth;
596
- paneWidth -= horizontalTrackHeight;
597
- horizontalTrack.parent().append(
598
- $('<div class="jspCorner" />').css('width', horizontalTrackHeight + 'px')
599
- );
600
- sizeVerticalScrollbar();
601
- sizeHorizontalScrollbar();
602
- }
603
- // reflow content
604
- if (isScrollableH) {
605
- pane.width((container.outerWidth() - originalPaddingTotalWidth) + 'px');
606
- }
607
- contentHeight = pane.outerHeight();
608
- percentInViewV = contentHeight / paneHeight;
609
-
610
- if (isScrollableH) {
611
- horizontalDragWidth = Math.ceil(1 / percentInViewH * horizontalTrackWidth);
612
- if (horizontalDragWidth > settings.horizontalDragMaxWidth) {
613
- horizontalDragWidth = settings.horizontalDragMaxWidth;
614
- } else if (horizontalDragWidth < settings.horizontalDragMinWidth) {
615
- horizontalDragWidth = settings.horizontalDragMinWidth;
616
- }
617
- horizontalDrag.css('width', horizontalDragWidth + 'px');
618
- dragMaxX = horizontalTrackWidth - horizontalDragWidth;
619
- _positionDragX(horizontalDragPosition); // To update the state for the arrow buttons
620
- }
621
- if (isScrollableV) {
622
- verticalDragHeight = Math.ceil(1 / percentInViewV * verticalTrackHeight);
623
- if (verticalDragHeight > settings.verticalDragMaxHeight) {
624
- verticalDragHeight = settings.verticalDragMaxHeight;
625
- } else if (verticalDragHeight < settings.verticalDragMinHeight) {
626
- verticalDragHeight = settings.verticalDragMinHeight;
627
- }
628
- verticalDrag.css('height', verticalDragHeight + 'px');
629
- dragMaxY = verticalTrackHeight - verticalDragHeight;
630
- _positionDragY(verticalDragPosition); // To update the state for the arrow buttons
631
- }
632
- }
633
609
 
634
- function appendArrows(ele, p, a1, a2)
635
- {
636
- var p1 = "before", p2 = "after", aTemp;
610
+ function appendArrows(ele, p, a1, a2) {
611
+ var p1 = 'before',
612
+ p2 = 'after',
613
+ aTemp;
637
614
 
638
- // Sniff for mac... Is there a better way to determine whether the arrows would naturally appear
639
- // at the top or the bottom of the bar?
640
- if (p == "os") {
641
- p = /Mac/.test(navigator.platform) ? "after" : "split";
642
- }
643
- if (p == p1) {
644
- p2 = p;
645
- } else if (p == p2) {
646
- p1 = p;
647
- aTemp = a1;
648
- a1 = a2;
649
- a2 = aTemp;
650
- }
615
+ // Sniff for mac... Is there a better way to determine whether the arrows would naturally appear
616
+ // at the top or the bottom of the bar?
617
+ if (p == 'os') {
618
+ p = /Mac/.test(navigator.platform) ? 'after' : 'split';
619
+ }
620
+ if (p == p1) {
621
+ p2 = p;
622
+ } else if (p == p2) {
623
+ p1 = p;
624
+ aTemp = a1;
625
+ a1 = a2;
626
+ a2 = aTemp;
627
+ }
651
628
 
652
- ele[p1](a1)[p2](a2);
653
- }
654
-
655
- function getArrowScroll(dirX, dirY, ele)
656
- {
657
- return function()
658
- {
659
- arrowScroll(dirX, dirY, this, ele);
660
- this.blur();
661
- return false;
662
- };
663
- }
664
-
665
- function arrowScroll(dirX, dirY, arrow, ele)
666
- {
667
- arrow = $(arrow).addClass('jspActive');
668
-
669
- var eve,
670
- scrollTimeout,
671
- isFirst = true,
672
- doScroll = function()
673
- {
674
- if (dirX !== 0) {
675
- jsp.scrollByX(dirX * settings.arrowButtonSpeed);
676
- }
677
- if (dirY !== 0) {
678
- jsp.scrollByY(dirY * settings.arrowButtonSpeed);
679
- }
680
- scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.arrowRepeatFreq);
681
- isFirst = false;
682
- };
629
+ ele[p1](a1)[p2](a2);
630
+ }
683
631
 
684
- doScroll();
685
-
686
- eve = ele ? 'mouseout.jsp' : 'mouseup.jsp';
687
- ele = ele || $('html');
688
- ele.on(
689
- eve,
690
- function()
691
- {
692
- arrow.removeClass('jspActive');
693
- if(scrollTimeout) {
694
- clearTimeout(scrollTimeout);
695
- }
696
- scrollTimeout = null;
697
- ele.off(eve);
632
+ function getArrowScroll(dirX, dirY, ele) {
633
+ return function () {
634
+ arrowScroll(dirX, dirY, this, ele);
635
+ this.blur();
636
+ return false;
637
+ };
698
638
  }
699
- );
700
- }
701
-
702
- function initClickOnTrack()
703
- {
704
- removeClickOnTrack();
705
- if (isScrollableV) {
706
- verticalTrack.on(
707
- 'mousedown.jsp',
708
- function(e)
709
- {
710
- if (e.originalTarget === undefined || e.originalTarget == e.currentTarget) {
711
- var clickedTrack = $(this),
712
- offset = clickedTrack.offset(),
713
- direction = e.pageY - offset.top - verticalDragPosition,
714
- scrollTimeout,
715
- isFirst = true,
716
- doScroll = function()
717
- {
718
- var offset = clickedTrack.offset(),
719
- pos = e.pageY - offset.top - verticalDragHeight / 2,
720
- contentDragY = paneHeight * settings.scrollPagePercent,
721
- dragY = dragMaxY * contentDragY / (contentHeight - paneHeight);
722
- if (direction < 0) {
723
- if (verticalDragPosition - dragY > pos) {
724
- jsp.scrollByY(-contentDragY);
725
- } else {
726
- positionDragY(pos);
727
- }
728
- } else if (direction > 0) {
729
- if (verticalDragPosition + dragY < pos) {
730
- jsp.scrollByY(contentDragY);
731
- } else {
732
- positionDragY(pos);
733
- }
734
- } else {
735
- cancelClick();
736
- return;
639
+
640
+ function arrowScroll(dirX, dirY, arrow, ele) {
641
+ arrow = $(arrow).addClass('jspActive');
642
+
643
+ var eve,
644
+ scrollTimeout,
645
+ isFirst = true,
646
+ doScroll = function () {
647
+ if (dirX !== 0) {
648
+ jsp.scrollByX(dirX * settings.arrowButtonSpeed);
649
+ }
650
+ if (dirY !== 0) {
651
+ jsp.scrollByY(dirY * settings.arrowButtonSpeed);
737
652
  }
738
- scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.trackClickRepeatFreq);
653
+ scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.arrowRepeatFreq);
739
654
  isFirst = false;
740
- },
741
- cancelClick = function()
742
- {
743
- if(scrollTimeout) {
744
- clearTimeout(scrollTimeout);
655
+ };
656
+
657
+ doScroll();
658
+
659
+ eve = ele ? 'mouseout.jsp' : 'mouseup.jsp';
660
+ ele = ele || $('html');
661
+ ele.on(eve, function () {
662
+ arrow.removeClass('jspActive');
663
+ if (scrollTimeout) {
664
+ clearTimeout(scrollTimeout);
665
+ }
666
+ scrollTimeout = null;
667
+ ele.off(eve);
668
+ });
669
+ }
670
+
671
+ function initClickOnTrack() {
672
+ removeClickOnTrack();
673
+ if (isScrollableV) {
674
+ verticalTrack.on('mousedown.jsp', function (e) {
675
+ if (e.originalTarget === undefined || e.originalTarget == e.currentTarget) {
676
+ var clickedTrack = $(this),
677
+ offset = clickedTrack.offset(),
678
+ direction = e.pageY - offset.top - verticalDragPosition,
679
+ scrollTimeout,
680
+ isFirst = true,
681
+ doScroll = function () {
682
+ var offset = clickedTrack.offset(),
683
+ pos = e.pageY - offset.top - verticalDragHeight / 2,
684
+ contentDragY = paneHeight * settings.scrollPagePercent,
685
+ dragY = (dragMaxY * contentDragY) / (contentHeight - paneHeight);
686
+ if (direction < 0) {
687
+ if (verticalDragPosition - dragY > pos) {
688
+ jsp.scrollByY(-contentDragY);
689
+ } else {
690
+ positionDragY(pos);
691
+ }
692
+ } else if (direction > 0) {
693
+ if (verticalDragPosition + dragY < pos) {
694
+ jsp.scrollByY(contentDragY);
695
+ } else {
696
+ positionDragY(pos);
697
+ }
698
+ } else {
699
+ cancelClick();
700
+ return;
701
+ }
702
+ scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.trackClickRepeatFreq);
703
+ isFirst = false;
704
+ },
705
+ cancelClick = function () {
706
+ if (scrollTimeout) {
707
+ clearTimeout(scrollTimeout);
708
+ }
709
+ scrollTimeout = null;
710
+ $(document).off('mouseup.jsp', cancelClick);
711
+ };
712
+ doScroll();
713
+ $(document).on('mouseup.jsp', cancelClick);
714
+ return false;
745
715
  }
746
- scrollTimeout = null;
747
- $(document).off('mouseup.jsp', cancelClick);
748
- };
749
- doScroll();
750
- $(document).on('mouseup.jsp', cancelClick);
751
- return false;
716
+ });
752
717
  }
753
- }
754
- );
755
- }
756
718
 
757
- if (isScrollableH) {
758
- horizontalTrack.on(
759
- 'mousedown.jsp',
760
- function(e)
761
- {
762
- if (e.originalTarget === undefined || e.originalTarget == e.currentTarget) {
763
- var clickedTrack = $(this),
764
- offset = clickedTrack.offset(),
765
- direction = e.pageX - offset.left - horizontalDragPosition,
766
- scrollTimeout,
767
- isFirst = true,
768
- doScroll = function()
769
- {
770
- var offset = clickedTrack.offset(),
771
- pos = e.pageX - offset.left - horizontalDragWidth / 2,
772
- contentDragX = paneWidth * settings.scrollPagePercent,
773
- dragX = dragMaxX * contentDragX / (contentWidth - paneWidth);
774
- if (direction < 0) {
775
- if (horizontalDragPosition - dragX > pos) {
776
- jsp.scrollByX(-contentDragX);
777
- } else {
778
- positionDragX(pos);
779
- }
780
- } else if (direction > 0) {
781
- if (horizontalDragPosition + dragX < pos) {
782
- jsp.scrollByX(contentDragX);
783
- } else {
784
- positionDragX(pos);
785
- }
786
- } else {
787
- cancelClick();
788
- return;
789
- }
790
- scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.trackClickRepeatFreq);
791
- isFirst = false;
792
- },
793
- cancelClick = function()
794
- {
795
- if(scrollTimeout) {
796
- clearTimeout(scrollTimeout);
719
+ if (isScrollableH) {
720
+ horizontalTrack.on('mousedown.jsp', function (e) {
721
+ if (e.originalTarget === undefined || e.originalTarget == e.currentTarget) {
722
+ var clickedTrack = $(this),
723
+ offset = clickedTrack.offset(),
724
+ direction = e.pageX - offset.left - horizontalDragPosition,
725
+ scrollTimeout,
726
+ isFirst = true,
727
+ doScroll = function () {
728
+ var offset = clickedTrack.offset(),
729
+ pos = e.pageX - offset.left - horizontalDragWidth / 2,
730
+ contentDragX = paneWidth * settings.scrollPagePercent,
731
+ dragX = (dragMaxX * contentDragX) / (contentWidth - paneWidth);
732
+ if (direction < 0) {
733
+ if (horizontalDragPosition - dragX > pos) {
734
+ jsp.scrollByX(-contentDragX);
735
+ } else {
736
+ positionDragX(pos);
737
+ }
738
+ } else if (direction > 0) {
739
+ if (horizontalDragPosition + dragX < pos) {
740
+ jsp.scrollByX(contentDragX);
741
+ } else {
742
+ positionDragX(pos);
743
+ }
744
+ } else {
745
+ cancelClick();
746
+ return;
747
+ }
748
+ scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.trackClickRepeatFreq);
749
+ isFirst = false;
750
+ },
751
+ cancelClick = function () {
752
+ if (scrollTimeout) {
753
+ clearTimeout(scrollTimeout);
754
+ }
755
+ scrollTimeout = null;
756
+ $(document).off('mouseup.jsp', cancelClick);
757
+ };
758
+ doScroll();
759
+ $(document).on('mouseup.jsp', cancelClick);
760
+ return false;
797
761
  }
798
- scrollTimeout = null;
799
- $(document).off('mouseup.jsp', cancelClick);
800
- };
801
- doScroll();
802
- $(document).on('mouseup.jsp', cancelClick);
803
- return false;
762
+ });
804
763
  }
805
- }
806
- );
807
- }
808
- }
764
+ }
809
765
 
810
- function removeClickOnTrack()
811
- {
812
- if (horizontalTrack) {
813
- horizontalTrack.off('mousedown.jsp');
814
- }
815
- if (verticalTrack) {
816
- verticalTrack.off('mousedown.jsp');
817
- }
818
- }
766
+ function removeClickOnTrack() {
767
+ if (horizontalTrack) {
768
+ horizontalTrack.off('mousedown.jsp');
769
+ }
770
+ if (verticalTrack) {
771
+ verticalTrack.off('mousedown.jsp');
772
+ }
773
+ }
819
774
 
820
- function cancelDrag()
821
- {
822
- $('html').off('dragstart.jsp selectstart.jsp mousemove.jsp mouseup.jsp mouseleave.jsp');
775
+ function cancelDrag() {
776
+ $('html').off('dragstart.jsp selectstart.jsp mousemove.jsp mouseup.jsp mouseleave.jsp');
823
777
 
824
- if (verticalDrag) {
825
- verticalDrag.removeClass('jspActive');
826
- }
827
- if (horizontalDrag) {
828
- horizontalDrag.removeClass('jspActive');
829
- }
830
- }
778
+ if (verticalDrag) {
779
+ verticalDrag.removeClass('jspActive');
780
+ }
781
+ if (horizontalDrag) {
782
+ horizontalDrag.removeClass('jspActive');
783
+ }
784
+ }
831
785
 
832
- function positionDragY(destY, animate)
833
- {
834
- if (!isScrollableV) {
835
- return;
836
- }
837
- if (destY < 0) {
838
- destY = 0;
839
- } else if (destY > dragMaxY) {
840
- destY = dragMaxY;
841
- }
786
+ function positionDragY(destY, animate) {
787
+ if (!isScrollableV) {
788
+ return;
789
+ }
790
+ if (destY < 0) {
791
+ destY = 0;
792
+ } else if (destY > dragMaxY) {
793
+ destY = dragMaxY;
794
+ }
842
795
 
843
- // allow for devs to prevent the JSP from being scrolled
844
- var willScrollYEvent = new $.Event("jsp-will-scroll-y");
845
- elem.trigger(willScrollYEvent, [destY]);
796
+ // allow for devs to prevent the JSP from being scrolled
797
+ var willScrollYEvent = new $.Event('jsp-will-scroll-y');
798
+ elem.trigger(willScrollYEvent, [destY]);
846
799
 
847
- if (willScrollYEvent.isDefaultPrevented()) {
848
- return;
849
- }
800
+ if (willScrollYEvent.isDefaultPrevented()) {
801
+ return;
802
+ }
850
803
 
851
- var tmpVerticalDragPosition = destY || 0;
804
+ var tmpVerticalDragPosition = destY || 0;
852
805
 
853
- var isAtTop = tmpVerticalDragPosition === 0,
854
- isAtBottom = tmpVerticalDragPosition == dragMaxY,
855
- percentScrolled = destY/ dragMaxY,
856
- destTop = -percentScrolled * (contentHeight - paneHeight);
806
+ var isAtTop = tmpVerticalDragPosition === 0,
807
+ isAtBottom = tmpVerticalDragPosition == dragMaxY,
808
+ percentScrolled = destY / dragMaxY,
809
+ destTop = -percentScrolled * (contentHeight - paneHeight);
857
810
 
858
- // can't just check if(animate) because false is a valid value that could be passed in...
859
- if (animate === undefined) {
860
- animate = settings.animateScroll;
861
- }
862
- if (animate) {
863
- jsp.animate(verticalDrag, 'top', destY, _positionDragY, function() {
864
- elem.trigger('jsp-user-scroll-y', [-destTop, isAtTop, isAtBottom]);
865
- });
866
- } else {
867
- verticalDrag.css('top', destY);
868
- _positionDragY(destY);
869
- elem.trigger('jsp-user-scroll-y', [-destTop, isAtTop, isAtBottom]);
870
- }
811
+ // can't just check if(animate) because false is a valid value that could be passed in...
812
+ if (animate === undefined) {
813
+ animate = settings.animateScroll;
814
+ }
815
+ if (animate) {
816
+ jsp.animate(verticalDrag, 'top', destY, _positionDragY, function () {
817
+ elem.trigger('jsp-user-scroll-y', [-destTop, isAtTop, isAtBottom]);
818
+ });
819
+ } else {
820
+ verticalDrag.css('top', destY + 'px');
821
+ _positionDragY(destY);
822
+ elem.trigger('jsp-user-scroll-y', [-destTop, isAtTop, isAtBottom]);
823
+ }
824
+ }
871
825
 
872
- }
826
+ function _positionDragY(destY) {
827
+ if (destY === undefined) {
828
+ destY = verticalDrag.position().top;
829
+ }
873
830
 
874
- function _positionDragY(destY)
875
- {
876
- if (destY === undefined) {
877
- destY = verticalDrag.position().top;
878
- }
831
+ container.scrollTop(0);
832
+ verticalDragPosition = destY || 0;
879
833
 
880
- container.scrollTop(0);
881
- verticalDragPosition = destY || 0;
834
+ var isAtTop = verticalDragPosition === 0,
835
+ isAtBottom = verticalDragPosition == dragMaxY,
836
+ percentScrolled = destY / dragMaxY,
837
+ destTop = -percentScrolled * (contentHeight - paneHeight);
882
838
 
883
- var isAtTop = verticalDragPosition === 0,
884
- isAtBottom = verticalDragPosition == dragMaxY,
885
- percentScrolled = destY/ dragMaxY,
886
- destTop = -percentScrolled * (contentHeight - paneHeight);
839
+ if (wasAtTop != isAtTop || wasAtBottom != isAtBottom) {
840
+ wasAtTop = isAtTop;
841
+ wasAtBottom = isAtBottom;
842
+ elem.trigger('jsp-arrow-change', [wasAtTop, wasAtBottom, wasAtLeft, wasAtRight]);
843
+ }
887
844
 
888
- if (wasAtTop != isAtTop || wasAtBottom != isAtBottom) {
889
- wasAtTop = isAtTop;
890
- wasAtBottom = isAtBottom;
891
- elem.trigger('jsp-arrow-change', [wasAtTop, wasAtBottom, wasAtLeft, wasAtRight]);
892
- }
845
+ updateVerticalArrows(isAtTop, isAtBottom);
846
+ pane.css('top', destTop + 'px');
847
+ elem.trigger('jsp-scroll-y', [-destTop, isAtTop, isAtBottom]).trigger('scroll');
848
+ }
893
849
 
894
- updateVerticalArrows(isAtTop, isAtBottom);
895
- pane.css('top', destTop);
896
- elem.trigger('jsp-scroll-y', [-destTop, isAtTop, isAtBottom]).trigger('scroll');
897
- }
850
+ function positionDragX(destX, animate) {
851
+ if (!isScrollableH) {
852
+ return;
853
+ }
854
+ if (destX < 0) {
855
+ destX = 0;
856
+ } else if (destX > dragMaxX) {
857
+ destX = dragMaxX;
858
+ }
898
859
 
899
- function positionDragX(destX, animate)
900
- {
901
- if (!isScrollableH) {
902
- return;
903
- }
904
- if (destX < 0) {
905
- destX = 0;
906
- } else if (destX > dragMaxX) {
907
- destX = dragMaxX;
908
- }
860
+ // allow for devs to prevent the JSP from being scrolled
861
+ var willScrollXEvent = new $.Event('jsp-will-scroll-x');
862
+ elem.trigger(willScrollXEvent, [destX]);
909
863
 
864
+ if (willScrollXEvent.isDefaultPrevented()) {
865
+ return;
866
+ }
910
867
 
911
- // allow for devs to prevent the JSP from being scrolled
912
- var willScrollXEvent = new $.Event("jsp-will-scroll-x");
913
- elem.trigger(willScrollXEvent, [destX]);
868
+ var tmpHorizontalDragPosition = destX || 0;
914
869
 
915
- if (willScrollXEvent.isDefaultPrevented()) {
916
- return;
917
- }
870
+ var isAtLeft = tmpHorizontalDragPosition === 0,
871
+ isAtRight = tmpHorizontalDragPosition == dragMaxX,
872
+ percentScrolled = destX / dragMaxX,
873
+ destLeft = -percentScrolled * (contentWidth - paneWidth);
918
874
 
919
- var tmpHorizontalDragPosition = destX ||0;
875
+ if (animate === undefined) {
876
+ animate = settings.animateScroll;
877
+ }
878
+ if (animate) {
879
+ jsp.animate(horizontalDrag, 'left', destX, _positionDragX, function () {
880
+ elem.trigger('jsp-user-scroll-x', [-destLeft, isAtLeft, isAtRight]);
881
+ });
882
+ } else {
883
+ horizontalDrag.css('left', destX + 'px');
884
+ _positionDragX(destX);
885
+ elem.trigger('jsp-user-scroll-x', [-destLeft, isAtLeft, isAtRight]);
886
+ }
887
+ }
920
888
 
921
- var isAtLeft = tmpHorizontalDragPosition === 0,
922
- isAtRight = tmpHorizontalDragPosition == dragMaxX,
923
- percentScrolled = destX / dragMaxX,
924
- destLeft = -percentScrolled * (contentWidth - paneWidth);
889
+ function _positionDragX(destX) {
890
+ if (destX === undefined) {
891
+ destX = horizontalDrag.position().left;
892
+ }
925
893
 
926
- if (animate === undefined) {
927
- animate = settings.animateScroll;
928
- }
929
- if (animate) {
930
- jsp.animate(horizontalDrag, 'left', destX, _positionDragX, function() {
931
- elem.trigger('jsp-user-scroll-x', [-destLeft, isAtLeft, isAtRight]);
932
- });
933
- } else {
934
- horizontalDrag.css('left', destX);
935
- _positionDragX(destX);
936
- elem.trigger('jsp-user-scroll-x', [-destLeft, isAtLeft, isAtRight]);
937
- }
938
- }
894
+ container.scrollTop(0);
895
+ horizontalDragPosition = destX || 0;
939
896
 
940
- function _positionDragX(destX)
941
- {
942
- if (destX === undefined) {
943
- destX = horizontalDrag.position().left;
944
- }
897
+ var isAtLeft = horizontalDragPosition === 0,
898
+ isAtRight = horizontalDragPosition == dragMaxX,
899
+ percentScrolled = destX / dragMaxX,
900
+ destLeft = -percentScrolled * (contentWidth - paneWidth);
945
901
 
946
- container.scrollTop(0);
947
- horizontalDragPosition = destX ||0;
902
+ if (wasAtLeft != isAtLeft || wasAtRight != isAtRight) {
903
+ wasAtLeft = isAtLeft;
904
+ wasAtRight = isAtRight;
905
+ elem.trigger('jsp-arrow-change', [wasAtTop, wasAtBottom, wasAtLeft, wasAtRight]);
906
+ }
948
907
 
949
- var isAtLeft = horizontalDragPosition === 0,
950
- isAtRight = horizontalDragPosition == dragMaxX,
951
- percentScrolled = destX / dragMaxX,
952
- destLeft = -percentScrolled * (contentWidth - paneWidth);
908
+ updateHorizontalArrows(isAtLeft, isAtRight);
909
+ pane.css('left', destLeft + 'px');
910
+ elem.trigger('jsp-scroll-x', [-destLeft, isAtLeft, isAtRight]).trigger('scroll');
911
+ }
953
912
 
954
- if (wasAtLeft != isAtLeft || wasAtRight != isAtRight) {
955
- wasAtLeft = isAtLeft;
956
- wasAtRight = isAtRight;
957
- elem.trigger('jsp-arrow-change', [wasAtTop, wasAtBottom, wasAtLeft, wasAtRight]);
958
- }
913
+ function updateVerticalArrows(isAtTop, isAtBottom) {
914
+ if (settings.showArrows) {
915
+ arrowUp[isAtTop ? 'addClass' : 'removeClass']('jspDisabled');
916
+ arrowDown[isAtBottom ? 'addClass' : 'removeClass']('jspDisabled');
917
+ }
918
+ }
959
919
 
960
- updateHorizontalArrows(isAtLeft, isAtRight);
961
- pane.css('left', destLeft);
962
- elem.trigger('jsp-scroll-x', [-destLeft, isAtLeft, isAtRight]).trigger('scroll');
963
- }
920
+ function updateHorizontalArrows(isAtLeft, isAtRight) {
921
+ if (settings.showArrows) {
922
+ arrowLeft[isAtLeft ? 'addClass' : 'removeClass']('jspDisabled');
923
+ arrowRight[isAtRight ? 'addClass' : 'removeClass']('jspDisabled');
924
+ }
925
+ }
964
926
 
965
- function updateVerticalArrows(isAtTop, isAtBottom)
966
- {
967
- if (settings.showArrows) {
968
- arrowUp[isAtTop ? 'addClass' : 'removeClass']('jspDisabled');
969
- arrowDown[isAtBottom ? 'addClass' : 'removeClass']('jspDisabled');
970
- }
971
- }
927
+ function scrollToY(destY, animate) {
928
+ var percentScrolled = destY / (contentHeight - paneHeight);
929
+ positionDragY(percentScrolled * dragMaxY, animate);
930
+ }
972
931
 
973
- function updateHorizontalArrows(isAtLeft, isAtRight)
974
- {
975
- if (settings.showArrows) {
976
- arrowLeft[isAtLeft ? 'addClass' : 'removeClass']('jspDisabled');
977
- arrowRight[isAtRight ? 'addClass' : 'removeClass']('jspDisabled');
978
- }
979
- }
980
-
981
- function scrollToY(destY, animate)
982
- {
983
- var percentScrolled = destY / (contentHeight - paneHeight);
984
- positionDragY(percentScrolled * dragMaxY, animate);
985
- }
986
-
987
- function scrollToX(destX, animate)
988
- {
989
- var percentScrolled = destX / (contentWidth - paneWidth);
990
- positionDragX(percentScrolled * dragMaxX, animate);
991
- }
992
-
993
- function scrollToElement(ele, stickToTop, animate)
994
- {
995
- var e, eleHeight, eleWidth, eleTop = 0, eleLeft = 0, viewportTop, viewportLeft, maxVisibleEleTop, maxVisibleEleLeft, destY, destX;
996
-
997
- // Legal hash values aren't necessarily legal jQuery selectors so we need to catch any
998
- // errors from the lookup...
999
- try {
1000
- e = $(ele);
1001
- } catch (err) {
1002
- return;
1003
- }
1004
- eleHeight = e.outerHeight();
1005
- eleWidth= e.outerWidth();
1006
-
1007
- container.scrollTop(0);
1008
- container.scrollLeft(0);
1009
-
1010
- // loop through parents adding the offset top of any elements that are relatively positioned between
1011
- // the focused element and the jspPane so we can get the true distance from the top
1012
- // of the focused element to the top of the scrollpane...
1013
- while (!e.is('.jspPane')) {
1014
- eleTop += e.position().top;
1015
- eleLeft += e.position().left;
1016
- e = e.offsetParent();
1017
- if (/^body|html$/i.test(e[0].nodeName)) {
1018
- // we ended up too high in the document structure. Quit!
1019
- return;
1020
- }
1021
- }
932
+ function scrollToX(destX, animate) {
933
+ var percentScrolled = destX / (contentWidth - paneWidth);
934
+ positionDragX(percentScrolled * dragMaxX, animate);
935
+ }
1022
936
 
1023
- viewportTop = contentPositionY();
1024
- maxVisibleEleTop = viewportTop + paneHeight;
1025
- if (eleTop < viewportTop || stickToTop) { // element is above viewport
1026
- destY = eleTop - settings.horizontalGutter;
1027
- } else if (eleTop + eleHeight > maxVisibleEleTop) { // element is below viewport
1028
- destY = eleTop - paneHeight + eleHeight + settings.horizontalGutter;
1029
- }
1030
- if (!isNaN(destY)) {
1031
- scrollToY(destY, animate);
1032
- }
937
+ function scrollToElement(ele, stickToTop, animate) {
938
+ var e,
939
+ eleHeight,
940
+ eleWidth,
941
+ eleTop = 0,
942
+ eleLeft = 0,
943
+ viewportTop,
944
+ viewportLeft,
945
+ maxVisibleEleTop,
946
+ maxVisibleEleLeft,
947
+ destY,
948
+ destX;
949
+
950
+ // Legal hash values aren't necessarily legal jQuery selectors so we need to catch any
951
+ // errors from the lookup...
952
+ try {
953
+ e = $(ele);
954
+ } catch (err) {
955
+ return;
956
+ }
957
+ eleHeight = e.outerHeight();
958
+ eleWidth = e.outerWidth();
959
+
960
+ container.scrollTop(0);
961
+ container.scrollLeft(0);
962
+
963
+ // loop through parents adding the offset top of any elements that are relatively positioned between
964
+ // the focused element and the jspPane so we can get the true distance from the top
965
+ // of the focused element to the top of the scrollpane...
966
+ while (!e.is('.jspPane')) {
967
+ eleTop += e.position().top;
968
+ eleLeft += e.position().left;
969
+ e = e.offsetParent();
970
+ if (/^body|html$/i.test(e[0].nodeName)) {
971
+ // we ended up too high in the document structure. Quit!
972
+ return;
973
+ }
974
+ }
1033
975
 
1034
- viewportLeft = contentPositionX();
1035
- maxVisibleEleLeft = viewportLeft + paneWidth;
1036
- if (eleLeft < viewportLeft || stickToTop) { // element is to the left of viewport
1037
- destX = eleLeft - settings.horizontalGutter;
1038
- } else if (eleLeft + eleWidth > maxVisibleEleLeft) { // element is to the right viewport
1039
- destX = eleLeft - paneWidth + eleWidth + settings.horizontalGutter;
1040
- }
1041
- if (!isNaN(destX)) {
1042
- scrollToX(destX, animate);
1043
- }
976
+ viewportTop = contentPositionY();
977
+ maxVisibleEleTop = viewportTop + paneHeight;
978
+ if (eleTop < viewportTop || stickToTop) {
979
+ // element is above viewport
980
+ destY = eleTop - settings.horizontalGutter;
981
+ } else if (eleTop + eleHeight > maxVisibleEleTop) {
982
+ // element is below viewport
983
+ destY = eleTop - paneHeight + eleHeight + settings.horizontalGutter;
984
+ }
985
+ if (!isNaN(destY)) {
986
+ scrollToY(destY, animate);
987
+ }
988
+
989
+ viewportLeft = contentPositionX();
990
+ maxVisibleEleLeft = viewportLeft + paneWidth;
991
+ if (eleLeft < viewportLeft || stickToTop) {
992
+ // element is to the left of viewport
993
+ destX = eleLeft - settings.horizontalGutter;
994
+ } else if (eleLeft + eleWidth > maxVisibleEleLeft) {
995
+ // element is to the right viewport
996
+ destX = eleLeft - paneWidth + eleWidth + settings.horizontalGutter;
997
+ }
998
+ if (!isNaN(destX)) {
999
+ scrollToX(destX, animate);
1000
+ }
1001
+ }
1044
1002
 
1045
- }
1046
-
1047
- function contentPositionX()
1048
- {
1049
- return -pane.position().left;
1050
- }
1051
-
1052
- function contentPositionY()
1053
- {
1054
- return -pane.position().top;
1055
- }
1056
-
1057
- function isCloseToBottom()
1058
- {
1059
- var scrollableHeight = contentHeight - paneHeight;
1060
- return (scrollableHeight > 20) && (scrollableHeight - contentPositionY() < 10);
1061
- }
1062
-
1063
- function isCloseToRight()
1064
- {
1065
- var scrollableWidth = contentWidth - paneWidth;
1066
- return (scrollableWidth > 20) && (scrollableWidth - contentPositionX() < 10);
1067
- }
1068
-
1069
- function initMousewheel()
1070
- {
1071
- container.off(mwEvent).on(
1072
- mwEvent,
1073
- function (event, delta, deltaX, deltaY) {
1074
-
1075
- if (!horizontalDragPosition) horizontalDragPosition = 0;
1076
- if (!verticalDragPosition) verticalDragPosition = 0;
1077
-
1078
- var dX = horizontalDragPosition, dY = verticalDragPosition, factor = event.deltaFactor || settings.mouseWheelSpeed;
1079
- jsp.scrollBy(deltaX * factor, -deltaY * factor, false);
1080
- // return true if there was no movement so rest of screen can scroll
1081
- return dX == horizontalDragPosition && dY == verticalDragPosition;
1003
+ function contentPositionX() {
1004
+ return -pane.position().left;
1082
1005
  }
1083
- );
1084
- }
1085
-
1086
- function removeMousewheel()
1087
- {
1088
- container.off(mwEvent);
1089
- }
1090
-
1091
- function nil()
1092
- {
1093
- return false;
1094
- }
1095
-
1096
- function initFocusHandler()
1097
- {
1098
- pane.find(':input,a').off('focus.jsp').on(
1099
- 'focus.jsp',
1100
- function(e)
1101
- {
1102
- scrollToElement(e.target, false);
1006
+
1007
+ function contentPositionY() {
1008
+ return -pane.position().top;
1103
1009
  }
1104
- );
1105
- }
1106
-
1107
- function removeFocusHandler()
1108
- {
1109
- pane.find(':input,a').off('focus.jsp');
1110
- }
1111
-
1112
- function initKeyboardNav()
1113
- {
1114
- var keyDown, elementHasScrolled, validParents = [];
1115
- if(isScrollableH) {
1116
- validParents.push(horizontalBar[0]);
1117
- }
1118
1010
 
1119
- if(isScrollableV) {
1120
- validParents.push(verticalBar[0]);
1121
- }
1011
+ function isCloseToBottom() {
1012
+ var scrollableHeight = contentHeight - paneHeight;
1013
+
1014
+ if (settings.maintainPosition == true) {
1015
+ return scrollableHeight >= 20 && scrollableHeight - contentPositionY() < 10;
1016
+ }
1122
1017
 
1123
- // IE also focuses elements that don't have tabindex set.
1124
- pane.on(
1125
- 'focus.jsp',
1126
- function()
1127
- {
1128
- elem.focus();
1018
+ return true;
1129
1019
  }
1130
- );
1131
-
1132
- elem.attr('tabindex', 0)
1133
- .off('keydown.jsp keypress.jsp')
1134
- .on(
1135
- 'keydown.jsp',
1136
- function(e)
1137
- {
1138
- if (e.target !== this && !(validParents.length && $(e.target).closest(validParents).length)){
1139
- return;
1140
- }
1141
- var dX = horizontalDragPosition, dY = verticalDragPosition;
1142
- switch(e.keyCode) {
1143
- case 40: // down
1144
- case 38: // up
1145
- case 34: // page down
1146
- case 32: // space
1147
- case 33: // page up
1148
- case 39: // right
1149
- case 37: // left
1150
- keyDown = e.keyCode;
1151
- keyDownHandler();
1152
- break;
1153
- case 35: // end
1154
- scrollToY(contentHeight - paneHeight);
1155
- keyDown = null;
1156
- break;
1157
- case 36: // home
1158
- scrollToY(0);
1159
- keyDown = null;
1160
- break;
1161
- }
1162
-
1163
- elementHasScrolled = e.keyCode == keyDown && dX != horizontalDragPosition || dY != verticalDragPosition;
1164
- return !elementHasScrolled;
1020
+
1021
+ function isCloseToRight() {
1022
+ var scrollableWidth = contentWidth - paneWidth;
1023
+
1024
+ if (settings.maintainPosition == true) {
1025
+ return scrollableWidth >= 20 && scrollableWidth - contentPositionX() < 10;
1165
1026
  }
1166
- ).on(
1167
- 'keypress.jsp', // For FF/ OSX so that we can cancel the repeat key presses if the JSP scrolls...
1168
- function(e)
1169
- {
1170
- if (e.keyCode == keyDown) {
1171
- keyDownHandler();
1172
- }
1173
- // If the keypress is not related to the area, ignore it. Fixes problem with inputs inside scrolled area. Copied from line 955.
1174
- if (e.target !== this && !(validParents.length && $(e.target).closest(validParents).length)){
1175
- return;
1176
- }
1177
- return !elementHasScrolled;
1027
+
1028
+ return true;
1178
1029
  }
1179
- );
1180
-
1181
- if (settings.hideFocus) {
1182
- elem.css('outline', 'none');
1183
- if ('hideFocus' in container[0]){
1184
- elem.attr('hideFocus', true);
1185
- }
1186
- } else {
1187
- elem.css('outline', '');
1188
- if ('hideFocus' in container[0]){
1189
- elem.attr('hideFocus', false);
1190
- }
1191
- }
1192
1030
 
1193
- function keyDownHandler()
1194
- {
1195
- var dX = horizontalDragPosition, dY = verticalDragPosition;
1196
- switch(keyDown) {
1197
- case 40: // down
1198
- jsp.scrollByY(settings.keyboardSpeed, false);
1199
- break;
1200
- case 38: // up
1201
- jsp.scrollByY(-settings.keyboardSpeed, false);
1202
- break;
1203
- case 34: // page down
1204
- case 32: // space
1205
- jsp.scrollByY(paneHeight * settings.scrollPagePercent, false);
1206
- break;
1207
- case 33: // page up
1208
- jsp.scrollByY(-paneHeight * settings.scrollPagePercent, false);
1209
- break;
1210
- case 39: // right
1211
- jsp.scrollByX(settings.keyboardSpeed, false);
1212
- break;
1213
- case 37: // left
1214
- jsp.scrollByX(-settings.keyboardSpeed, false);
1215
- break;
1216
- }
1217
-
1218
- elementHasScrolled = dX != horizontalDragPosition || dY != verticalDragPosition;
1219
- return elementHasScrolled;
1220
- }
1221
- }
1222
-
1223
- function removeKeyboardNav()
1224
- {
1225
- elem.attr('tabindex', '-1')
1226
- .removeAttr('tabindex')
1227
- .off('keydown.jsp keypress.jsp');
1228
-
1229
- pane.off('.jsp');
1230
- }
1231
-
1232
- function observeHash()
1233
- {
1234
- if (location.hash && location.hash.length > 1) {
1235
- var e,
1236
- retryInt,
1237
- hash = escape(location.hash.substr(1)) // hash must be escaped to prevent XSS
1238
- ;
1239
- try {
1240
- e = $('#' + hash + ', a[name="' + hash + '"]');
1241
- } catch (err) {
1242
- return;
1243
- }
1244
-
1245
- if (e.length && pane.find(hash)) {
1246
- // nasty workaround but it appears to take a little while before the hash has done its thing
1247
- // to the rendered page so we just wait until the container's scrollTop has been messed up.
1248
- if (container.scrollTop() === 0) {
1249
- retryInt = setInterval(
1250
- function()
1251
- {
1252
- if (container.scrollTop() > 0) {
1253
- scrollToElement(e, true);
1254
- $(document).scrollTop(container.position().top);
1255
- clearInterval(retryInt);
1256
- }
1257
- },
1258
- 50
1259
- );
1260
- } else {
1261
- scrollToElement(e, true);
1262
- $(document).scrollTop(container.position().top);
1031
+ function initMousewheel() {
1032
+ container.off(mwEvent).on(mwEvent, function (event, delta, deltaX, deltaY) {
1033
+ if (!horizontalDragPosition) horizontalDragPosition = 0;
1034
+ if (!verticalDragPosition) verticalDragPosition = 0;
1035
+
1036
+ var dX = horizontalDragPosition,
1037
+ dY = verticalDragPosition,
1038
+ factor = event.deltaFactor || settings.mouseWheelSpeed;
1039
+ jsp.scrollBy(deltaX * factor, -deltaY * factor, false);
1040
+ // return true if there was no movement so rest of screen can scroll
1041
+ return dX == horizontalDragPosition && dY == verticalDragPosition;
1042
+ });
1263
1043
  }
1264
- }
1265
- }
1266
- }
1267
1044
 
1268
- function hijackInternalLinks()
1269
- {
1270
- // only register the link handler once
1271
- if ($(document.body).data('jspHijack')) {
1272
- return;
1273
- }
1045
+ function removeMousewheel() {
1046
+ container.off(mwEvent);
1047
+ }
1274
1048
 
1275
- // remember that the handler was bound
1276
- $(document.body).data('jspHijack', true);
1277
-
1278
- // use live handler to also capture newly created links
1279
- $(document.body).delegate('a[href*="#"]', 'click', function(event) {
1280
- // does the link point to the same page?
1281
- // this also takes care of cases with a <base>-Tag or Links not starting with the hash #
1282
- // e.g. <a href="index.html#test"> when the current url already is index.html
1283
- var href = this.href.substr(0, this.href.indexOf('#')),
1284
- locationHref = location.href,
1285
- hash,
1286
- element,
1287
- container,
1288
- jsp,
1289
- scrollTop,
1290
- elementTop;
1291
- if (location.href.indexOf('#') !== -1) {
1292
- locationHref = location.href.substr(0, location.href.indexOf('#'));
1293
- }
1294
- if (href !== locationHref) {
1295
- // the link points to another page
1296
- return;
1297
- }
1298
-
1299
- // check if jScrollPane should handle this click event
1300
- hash = escape(this.href.substr(this.href.indexOf('#') + 1));
1301
-
1302
- // find the element on the page
1303
- try {
1304
- element = $('#' + hash + ', a[name="' + hash + '"]');
1305
- } catch (e) {
1306
- // hash is not a valid jQuery identifier
1307
- return;
1308
- }
1309
-
1310
- if (!element.length) {
1311
- // this link does not point to an element on this page
1312
- return;
1313
- }
1314
-
1315
- container = element.closest('.jspScrollable');
1316
- jsp = container.data('jsp');
1317
-
1318
- // jsp might be another jsp instance than the one, that bound this event
1319
- // remember: this event is only bound once for all instances.
1320
- jsp.scrollToElement(element, true);
1321
-
1322
- if (container[0].scrollIntoView) {
1323
- // also scroll to the top of the container (if it is not visible)
1324
- scrollTop = $(window).scrollTop();
1325
- elementTop = element.offset().top;
1326
- if (elementTop < scrollTop || elementTop > scrollTop + $(window).height()) {
1327
- container[0].scrollIntoView();
1049
+ function nil() {
1050
+ return false;
1328
1051
  }
1329
- }
1330
1052
 
1331
- // jsp handled this event, prevent the browser default (scrolling :P)
1332
- event.preventDefault();
1333
- });
1334
- }
1335
-
1336
- // Init touch on iPad, iPhone, iPod, Android
1337
- function initTouch()
1338
- {
1339
- var startX,
1340
- startY,
1341
- touchStartX,
1342
- touchStartY,
1343
- moved,
1344
- moving = false;
1345
-
1346
- container.off('touchstart.jsp touchmove.jsp touchend.jsp click.jsp-touchclick').on(
1347
- 'touchstart.jsp',
1348
- function(e)
1349
- {
1350
- var touch = e.originalEvent.touches[0];
1351
- startX = contentPositionX();
1352
- startY = contentPositionY();
1353
- touchStartX = touch.pageX;
1354
- touchStartY = touch.pageY;
1355
- moved = false;
1356
- moving = true;
1053
+ function initFocusHandler() {
1054
+ pane.find(':input,a')
1055
+ .off('focus.jsp')
1056
+ .on('focus.jsp', function (e) {
1057
+ scrollToElement(e.target, false);
1058
+ });
1059
+ }
1060
+
1061
+ function removeFocusHandler() {
1062
+ pane.find(':input,a').off('focus.jsp');
1357
1063
  }
1358
- ).on(
1359
- 'touchmove.jsp',
1360
- function(ev)
1361
- {
1362
- if(!moving) {
1363
- return;
1364
- }
1365
1064
 
1366
- var touchPos = ev.originalEvent.touches[0],
1367
- dX = horizontalDragPosition, dY = verticalDragPosition;
1065
+ function initKeyboardNav() {
1066
+ var keyDown,
1067
+ elementHasScrolled,
1068
+ validParents = [];
1069
+ if (isScrollableH) {
1070
+ validParents.push(horizontalBar[0]);
1071
+ }
1072
+
1073
+ if (isScrollableV) {
1074
+ validParents.push(verticalBar[0]);
1075
+ }
1368
1076
 
1369
- jsp.scrollTo(startX + touchStartX - touchPos.pageX, startY + touchStartY - touchPos.pageY);
1077
+ // IE also focuses elements that don't have tabindex set.
1078
+ pane.on('focus.jsp', function () {
1079
+ elem.focus();
1080
+ });
1370
1081
 
1371
- moved = moved || Math.abs(touchStartX - touchPos.pageX) > 5 || Math.abs(touchStartY - touchPos.pageY) > 5;
1082
+ elem.attr('tabindex', 0)
1083
+ .off('keydown.jsp keypress.jsp')
1084
+ .on('keydown.jsp', function (e) {
1085
+ if (e.target !== this && !(validParents.length && $(e.target).closest(validParents).length)) {
1086
+ return;
1087
+ }
1088
+ var dX = horizontalDragPosition,
1089
+ dY = verticalDragPosition;
1090
+ switch (e.keyCode) {
1091
+ case 40: // down
1092
+ case 38: // up
1093
+ case 34: // page down
1094
+ case 32: // space
1095
+ case 33: // page up
1096
+ case 39: // right
1097
+ case 37: // left
1098
+ keyDown = e.keyCode;
1099
+ keyDownHandler();
1100
+ break;
1101
+ case 35: // end
1102
+ scrollToY(contentHeight - paneHeight);
1103
+ keyDown = null;
1104
+ break;
1105
+ case 36: // home
1106
+ scrollToY(0);
1107
+ keyDown = null;
1108
+ break;
1109
+ }
1372
1110
 
1373
- // return true if there was no movement so rest of screen can scroll
1374
- return dX == horizontalDragPosition && dY == verticalDragPosition;
1111
+ elementHasScrolled = (e.keyCode == keyDown && dX != horizontalDragPosition) || dY != verticalDragPosition;
1112
+ return !elementHasScrolled;
1113
+ })
1114
+ .on(
1115
+ 'keypress.jsp', // For FF/ OSX so that we can cancel the repeat key presses if the JSP scrolls...
1116
+ function (e) {
1117
+ if (e.keyCode == keyDown) {
1118
+ keyDownHandler();
1119
+ }
1120
+ // If the keypress is not related to the area, ignore it. Fixes problem with inputs inside scrolled area. Copied from line 955.
1121
+ if (e.target !== this && !(validParents.length && $(e.target).closest(validParents).length)) {
1122
+ return;
1123
+ }
1124
+ return !elementHasScrolled;
1125
+ },
1126
+ );
1127
+
1128
+ if (settings.hideFocus) {
1129
+ elem.css('outline', 'none');
1130
+ if ('hideFocus' in container[0]) {
1131
+ elem.attr('hideFocus', true);
1132
+ }
1133
+ } else {
1134
+ elem.css('outline', '');
1135
+ if ('hideFocus' in container[0]) {
1136
+ elem.attr('hideFocus', false);
1137
+ }
1138
+ }
1139
+
1140
+ function keyDownHandler() {
1141
+ var dX = horizontalDragPosition,
1142
+ dY = verticalDragPosition;
1143
+ switch (keyDown) {
1144
+ case 40: // down
1145
+ jsp.scrollByY(settings.keyboardSpeed, false);
1146
+ break;
1147
+ case 38: // up
1148
+ jsp.scrollByY(-settings.keyboardSpeed, false);
1149
+ break;
1150
+ case 34: // page down
1151
+ case 32: // space
1152
+ jsp.scrollByY(paneHeight * settings.scrollPagePercent, false);
1153
+ break;
1154
+ case 33: // page up
1155
+ jsp.scrollByY(-paneHeight * settings.scrollPagePercent, false);
1156
+ break;
1157
+ case 39: // right
1158
+ jsp.scrollByX(settings.keyboardSpeed, false);
1159
+ break;
1160
+ case 37: // left
1161
+ jsp.scrollByX(-settings.keyboardSpeed, false);
1162
+ break;
1163
+ }
1164
+
1165
+ elementHasScrolled = dX != horizontalDragPosition || dY != verticalDragPosition;
1166
+ return elementHasScrolled;
1167
+ }
1375
1168
  }
1376
- ).on(
1377
- 'touchend.jsp',
1378
- function(e)
1379
- {
1380
- moving = false;
1381
- /*if(moved) {
1382
- return false;
1383
- }*/
1169
+
1170
+ function removeKeyboardNav() {
1171
+ elem.attr('tabindex', '-1').removeAttr('tabindex').off('keydown.jsp keypress.jsp');
1172
+
1173
+ pane.off('.jsp');
1384
1174
  }
1385
- ).on(
1386
- 'click.jsp-touchclick',
1387
- function(e)
1388
- {
1389
- if(moved) {
1390
- moved = false;
1391
- return false;
1392
- }
1175
+
1176
+ function observeHash() {
1177
+ if (location.hash && location.hash.length > 1) {
1178
+ var e,
1179
+ retryInt,
1180
+ hash = escape(location.hash.substr(1)); // hash must be escaped to prevent XSS
1181
+ try {
1182
+ e = $('#' + hash + ', a[name="' + hash + '"]');
1183
+ } catch (err) {
1184
+ return;
1185
+ }
1186
+
1187
+ if (e.length && pane.find(hash)) {
1188
+ // nasty workaround but it appears to take a little while before the hash has done its thing
1189
+ // to the rendered page so we just wait until the container's scrollTop has been messed up.
1190
+ if (container.scrollTop() === 0) {
1191
+ retryInt = setInterval(function () {
1192
+ if (container.scrollTop() > 0) {
1193
+ scrollToElement(e, true);
1194
+ $(document).scrollTop(container.position().top);
1195
+ clearInterval(retryInt);
1196
+ }
1197
+ }, 50);
1198
+ } else {
1199
+ scrollToElement(e, true);
1200
+ $(document).scrollTop(container.position().top);
1201
+ }
1202
+ }
1203
+ }
1393
1204
  }
1394
- );
1395
- }
1396
-
1397
- function destroy(){
1398
- var currentY = contentPositionY(),
1399
- currentX = contentPositionX();
1400
- elem.removeClass('jspScrollable').off('.jsp');
1401
- pane.off('.jsp');
1402
- elem.replaceWith(originalElement.append(pane.children()));
1403
- originalElement.scrollTop(currentY);
1404
- originalElement.scrollLeft(currentX);
1405
-
1406
- // clear reinitialize timer if active
1407
- if (reinitialiseInterval) {
1408
- clearInterval(reinitialiseInterval);
1409
- }
1410
- }
1411
-
1412
- // Public API
1413
- $.extend(
1414
- jsp,
1415
- {
1416
- // Reinitialises the scroll pane (if it's internal dimensions have changed since the last time it
1417
- // was initialised). The settings object which is passed in will override any settings from the
1418
- // previous time it was initialised - if you don't pass any settings then the ones from the previous
1419
- // initialisation will be used.
1420
- reinitialise: function(s)
1421
- {
1422
- s = $.extend({}, settings, s);
1423
- initialise(s);
1424
- },
1425
- // Scrolls the specified element (a jQuery object, DOM node or jQuery selector string) into view so
1426
- // that it can be seen within the viewport. If stickToTop is true then the element will appear at
1427
- // the top of the viewport, if it is false then the viewport will scroll as little as possible to
1428
- // show the element. You can also specify if you want animation to occur. If you don't provide this
1429
- // argument then the animateScroll value from the settings object is used instead.
1430
- scrollToElement: function(ele, stickToTop, animate)
1431
- {
1432
- scrollToElement(ele, stickToTop, animate);
1433
- },
1434
- // Scrolls the pane so that the specified co-ordinates within the content are at the top left
1435
- // of the viewport. animate is optional and if not passed then the value of animateScroll from
1436
- // the settings object this jScrollPane was initialised with is used.
1437
- scrollTo: function(destX, destY, animate)
1438
- {
1439
- scrollToX(destX, animate);
1440
- scrollToY(destY, animate);
1441
- },
1442
- // Scrolls the pane so that the specified co-ordinate within the content is at the left of the
1443
- // viewport. animate is optional and if not passed then the value of animateScroll from the settings
1444
- // object this jScrollPane was initialised with is used.
1445
- scrollToX: function(destX, animate)
1446
- {
1447
- scrollToX(destX, animate);
1448
- },
1449
- // Scrolls the pane so that the specified co-ordinate within the content is at the top of the
1450
- // viewport. animate is optional and if not passed then the value of animateScroll from the settings
1451
- // object this jScrollPane was initialised with is used.
1452
- scrollToY: function(destY, animate)
1453
- {
1454
- scrollToY(destY, animate);
1455
- },
1456
- // Scrolls the pane to the specified percentage of its maximum horizontal scroll position. animate
1457
- // is optional and if not passed then the value of animateScroll from the settings object this
1458
- // jScrollPane was initialised with is used.
1459
- scrollToPercentX: function(destPercentX, animate)
1460
- {
1461
- scrollToX(destPercentX * (contentWidth - paneWidth), animate);
1462
- },
1463
- // Scrolls the pane to the specified percentage of its maximum vertical scroll position. animate
1464
- // is optional and if not passed then the value of animateScroll from the settings object this
1465
- // jScrollPane was initialised with is used.
1466
- scrollToPercentY: function(destPercentY, animate)
1467
- {
1468
- scrollToY(destPercentY * (contentHeight - paneHeight), animate);
1469
- },
1470
- // Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then
1471
- // the value of animateScroll from the settings object this jScrollPane was initialised with is used.
1472
- scrollBy: function(deltaX, deltaY, animate)
1473
- {
1474
- jsp.scrollByX(deltaX, animate);
1475
- jsp.scrollByY(deltaY, animate);
1476
- },
1477
- // Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then
1478
- // the value of animateScroll from the settings object this jScrollPane was initialised with is used.
1479
- scrollByX: function(deltaX, animate)
1480
- {
1481
- var destX = contentPositionX() + Math[deltaX<0 ? 'floor' : 'ceil'](deltaX),
1482
- percentScrolled = destX / (contentWidth - paneWidth);
1483
- positionDragX(percentScrolled * dragMaxX, animate);
1484
- },
1485
- // Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then
1486
- // the value of animateScroll from the settings object this jScrollPane was initialised with is used.
1487
- scrollByY: function(deltaY, animate)
1488
- {
1489
- var destY = contentPositionY() + Math[deltaY<0 ? 'floor' : 'ceil'](deltaY),
1490
- percentScrolled = destY / (contentHeight - paneHeight);
1491
- positionDragY(percentScrolled * dragMaxY, animate);
1492
- },
1493
- // Positions the horizontal drag at the specified x position (and updates the viewport to reflect
1494
- // this). animate is optional and if not passed then the value of animateScroll from the settings
1495
- // object this jScrollPane was initialised with is used.
1496
- positionDragX: function(x, animate)
1497
- {
1498
- positionDragX(x, animate);
1499
- },
1500
- // Positions the vertical drag at the specified y position (and updates the viewport to reflect
1501
- // this). animate is optional and if not passed then the value of animateScroll from the settings
1502
- // object this jScrollPane was initialised with is used.
1503
- positionDragY: function(y, animate)
1504
- {
1505
- positionDragY(y, animate);
1506
- },
1507
- // This method is called when jScrollPane is trying to animate to a new position. You can override
1508
- // it if you want to provide advanced animation functionality. It is passed the following arguments:
1509
- // * ele - the element whose position is being animated
1510
- // * prop - the property that is being animated
1511
- // * value - the value it's being animated to
1512
- // * stepCallback - a function that you must execute each time you update the value of the property
1513
- // * completeCallback - a function that will be executed after the animation had finished
1514
- // You can use the default implementation (below) as a starting point for your own implementation.
1515
- animate: function(ele, prop, value, stepCallback, completeCallback)
1516
- {
1517
- var params = {};
1518
- params[prop] = value;
1519
- ele.animate(
1520
- params,
1521
- {
1522
- 'duration' : settings.animateDuration,
1523
- 'easing' : settings.animateEase,
1524
- 'queue' : false,
1525
- 'step' : stepCallback,
1526
- 'complete' : completeCallback
1527
- }
1528
- );
1529
- },
1530
- // Returns the current x position of the viewport with regards to the content pane.
1531
- getContentPositionX: function()
1532
- {
1533
- return contentPositionX();
1534
- },
1535
- // Returns the current y position of the viewport with regards to the content pane.
1536
- getContentPositionY: function()
1537
- {
1538
- return contentPositionY();
1539
- },
1540
- // Returns the width of the content within the scroll pane.
1541
- getContentWidth: function()
1542
- {
1543
- return contentWidth;
1544
- },
1545
- // Returns the height of the content within the scroll pane.
1546
- getContentHeight: function()
1547
- {
1548
- return contentHeight;
1549
- },
1550
- // Returns the horizontal position of the viewport within the pane content.
1551
- getPercentScrolledX: function()
1552
- {
1553
- return contentPositionX() / (contentWidth - paneWidth);
1554
- },
1555
- // Returns the vertical position of the viewport within the pane content.
1556
- getPercentScrolledY: function()
1557
- {
1558
- return contentPositionY() / (contentHeight - paneHeight);
1559
- },
1560
- // Returns whether or not this scrollpane has a horizontal scrollbar.
1561
- getIsScrollableH: function()
1562
- {
1563
- return isScrollableH;
1564
- },
1565
- // Returns whether or not this scrollpane has a vertical scrollbar.
1566
- getIsScrollableV: function()
1567
- {
1568
- return isScrollableV;
1569
- },
1570
- // Gets a reference to the content pane. It is important that you use this method if you want to
1571
- // edit the content of your jScrollPane as if you access the element directly then you may have some
1572
- // problems (as your original element has had additional elements for the scrollbars etc added into
1573
- // it).
1574
- getContentPane: function()
1575
- {
1576
- return pane;
1577
- },
1578
- // Scrolls this jScrollPane down as far as it can currently scroll. If animate isn't passed then the
1579
- // animateScroll value from settings is used instead.
1580
- scrollToBottom: function(animate)
1581
- {
1582
- positionDragY(dragMaxY, animate);
1583
- },
1584
- // Hijacks the links on the page which link to content inside the scrollpane. If you have changed
1585
- // the content of your page (e.g. via AJAX) and want to make sure any new anchor links to the
1586
- // contents of your scroll pane will work then call this function.
1587
- hijackInternalLinks: $.noop,
1588
- // Removes the jScrollPane and returns the page to the state it was in before jScrollPane was
1589
- // initialised.
1590
- destroy: function()
1591
- {
1592
- destroy();
1205
+
1206
+ function hijackInternalLinks() {
1207
+ // only register the link handler once
1208
+ if ($(document.body).data('jspHijack')) {
1209
+ return;
1210
+ }
1211
+
1212
+ // remember that the handler was bound
1213
+ $(document.body).data('jspHijack', true);
1214
+
1215
+ // use live handler to also capture newly created links
1216
+ $(document.body).delegate('a[href*="#"]', 'click', function (event) {
1217
+ // does the link point to the same page?
1218
+ // this also takes care of cases with a <base>-Tag or Links not starting with the hash #
1219
+ // e.g. <a href="index.html#test"> when the current url already is index.html
1220
+ var href = this.href.substr(0, this.href.indexOf('#')),
1221
+ locationHref = location.href,
1222
+ hash,
1223
+ element,
1224
+ container,
1225
+ jsp,
1226
+ scrollTop,
1227
+ elementTop;
1228
+ if (location.href.indexOf('#') !== -1) {
1229
+ locationHref = location.href.substr(0, location.href.indexOf('#'));
1230
+ }
1231
+ if (href !== locationHref) {
1232
+ // the link points to another page
1233
+ return;
1234
+ }
1235
+
1236
+ // check if jScrollPane should handle this click event
1237
+ hash = escape(this.href.substr(this.href.indexOf('#') + 1));
1238
+
1239
+ // find the element on the page
1240
+ try {
1241
+ element = $('#' + hash + ', a[name="' + hash + '"]');
1242
+ } catch (e) {
1243
+ // hash is not a valid jQuery identifier
1244
+ return;
1245
+ }
1246
+
1247
+ if (!element.length) {
1248
+ // this link does not point to an element on this page
1249
+ return;
1250
+ }
1251
+
1252
+ container = element.closest('.jspScrollable');
1253
+ jsp = container.data('jsp');
1254
+
1255
+ // jsp might be another jsp instance than the one, that bound this event
1256
+ // remember: this event is only bound once for all instances.
1257
+ jsp.scrollToElement(element, true);
1258
+
1259
+ if (container[0].scrollIntoView) {
1260
+ // also scroll to the top of the container (if it is not visible)
1261
+ scrollTop = $(window).scrollTop();
1262
+ elementTop = element.offset().top;
1263
+ if (elementTop < scrollTop || elementTop > scrollTop + $(window).height()) {
1264
+ container[0].scrollIntoView();
1265
+ }
1266
+ }
1267
+
1268
+ // jsp handled this event, prevent the browser default (scrolling :P)
1269
+ event.preventDefault();
1270
+ });
1593
1271
  }
1594
- }
1595
- );
1596
1272
 
1597
- initialise(s);
1598
- }
1273
+ // Init touch on iPad, iPhone, iPod, Android
1274
+ function initTouch() {
1275
+ var startX,
1276
+ startY,
1277
+ touchStartX,
1278
+ touchStartY,
1279
+ moved,
1280
+ moving = false;
1281
+
1282
+ container
1283
+ .off('touchstart.jsp touchmove.jsp touchend.jsp click.jsp-touchclick')
1284
+ .on('touchstart.jsp', function (e) {
1285
+ var touch = e.originalEvent.touches[0];
1286
+ startX = contentPositionX();
1287
+ startY = contentPositionY();
1288
+ touchStartX = touch.pageX;
1289
+ touchStartY = touch.pageY;
1290
+ moved = false;
1291
+ moving = true;
1292
+ })
1293
+ .on('touchmove.jsp', function (ev) {
1294
+ if (!moving) {
1295
+ return;
1296
+ }
1297
+
1298
+ var touchPos = ev.originalEvent.touches[0],
1299
+ dX = horizontalDragPosition,
1300
+ dY = verticalDragPosition;
1301
+
1302
+ jsp.scrollTo(startX + touchStartX - touchPos.pageX, startY + touchStartY - touchPos.pageY);
1303
+
1304
+ moved = moved || Math.abs(touchStartX - touchPos.pageX) > 5 || Math.abs(touchStartY - touchPos.pageY) > 5;
1305
+
1306
+ // return true if there was no movement so rest of screen can scroll
1307
+ return dX == horizontalDragPosition && dY == verticalDragPosition;
1308
+ })
1309
+ .on('touchend.jsp', function (e) {
1310
+ moving = false;
1311
+ /*if(moved) {
1312
+ return false;
1313
+ }*/
1314
+ })
1315
+ .on('click.jsp-touchclick', function (e) {
1316
+ if (moved) {
1317
+ moved = false;
1318
+ return false;
1319
+ }
1320
+ });
1321
+ }
1322
+
1323
+ function destroy() {
1324
+ var currentY = contentPositionY(),
1325
+ currentX = contentPositionX();
1326
+ elem.removeClass('jspScrollable').off('.jsp');
1327
+ pane.off('.jsp');
1328
+ elem.replaceWith(originalElement.append(pane.children()));
1329
+ originalElement.scrollTop(currentY);
1330
+ originalElement.scrollLeft(currentX);
1331
+
1332
+ // clear reinitialize timer if active
1333
+ if (reinitialiseInterval) {
1334
+ clearInterval(reinitialiseInterval);
1335
+ }
1336
+ }
1599
1337
 
1600
- // Pluginifying code...
1601
- settings = $.extend({}, $.fn.jScrollPane.defaults, settings);
1602
-
1603
- // Apply default speed
1604
- $.each(['arrowButtonSpeed', 'trackClickSpeed', 'keyboardSpeed'], function() {
1605
- settings[this] = settings[this] || settings.speed;
1606
- });
1607
-
1608
- return this.each(
1609
- function()
1610
- {
1611
- var elem = $(this), jspApi = elem.data('jsp');
1612
- if (jspApi) {
1613
- jspApi.reinitialise(settings);
1614
- } else {
1615
- $("script",elem).filter('[type="text/javascript"],:not([type])').remove();
1616
- jspApi = new JScrollPane(elem, settings);
1617
- elem.data('jsp', jspApi);
1618
- }
1338
+ // Public API
1339
+ $.extend(jsp, {
1340
+ // Reinitialises the scroll pane (if it's internal dimensions have changed since the last time it
1341
+ // was initialised). The settings object which is passed in will override any settings from the
1342
+ // previous time it was initialised - if you don't pass any settings then the ones from the previous
1343
+ // initialisation will be used.
1344
+ reinitialise: function (s) {
1345
+ s = $.extend({}, settings, s);
1346
+ initialise(s);
1347
+ },
1348
+ // Scrolls the specified element (a jQuery object, DOM node or jQuery selector string) into view so
1349
+ // that it can be seen within the viewport. If stickToTop is true then the element will appear at
1350
+ // the top of the viewport, if it is false then the viewport will scroll as little as possible to
1351
+ // show the element. You can also specify if you want animation to occur. If you don't provide this
1352
+ // argument then the animateScroll value from the settings object is used instead.
1353
+ scrollToElement: function (ele, stickToTop, animate) {
1354
+ scrollToElement(ele, stickToTop, animate);
1355
+ },
1356
+ // Scrolls the pane so that the specified co-ordinates within the content are at the top left
1357
+ // of the viewport. animate is optional and if not passed then the value of animateScroll from
1358
+ // the settings object this jScrollPane was initialised with is used.
1359
+ scrollTo: function (destX, destY, animate) {
1360
+ scrollToX(destX, animate);
1361
+ scrollToY(destY, animate);
1362
+ },
1363
+ // Scrolls the pane so that the specified co-ordinate within the content is at the left of the
1364
+ // viewport. animate is optional and if not passed then the value of animateScroll from the settings
1365
+ // object this jScrollPane was initialised with is used.
1366
+ scrollToX: function (destX, animate) {
1367
+ scrollToX(destX, animate);
1368
+ },
1369
+ // Scrolls the pane so that the specified co-ordinate within the content is at the top of the
1370
+ // viewport. animate is optional and if not passed then the value of animateScroll from the settings
1371
+ // object this jScrollPane was initialised with is used.
1372
+ scrollToY: function (destY, animate) {
1373
+ scrollToY(destY, animate);
1374
+ },
1375
+ // Scrolls the pane to the specified percentage of its maximum horizontal scroll position. animate
1376
+ // is optional and if not passed then the value of animateScroll from the settings object this
1377
+ // jScrollPane was initialised with is used.
1378
+ scrollToPercentX: function (destPercentX, animate) {
1379
+ scrollToX(destPercentX * (contentWidth - paneWidth), animate);
1380
+ },
1381
+ // Scrolls the pane to the specified percentage of its maximum vertical scroll position. animate
1382
+ // is optional and if not passed then the value of animateScroll from the settings object this
1383
+ // jScrollPane was initialised with is used.
1384
+ scrollToPercentY: function (destPercentY, animate) {
1385
+ scrollToY(destPercentY * (contentHeight - paneHeight), animate);
1386
+ },
1387
+ // Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then
1388
+ // the value of animateScroll from the settings object this jScrollPane was initialised with is used.
1389
+ scrollBy: function (deltaX, deltaY, animate) {
1390
+ jsp.scrollByX(deltaX, animate);
1391
+ jsp.scrollByY(deltaY, animate);
1392
+ },
1393
+ // Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then
1394
+ // the value of animateScroll from the settings object this jScrollPane was initialised with is used.
1395
+ scrollByX: function (deltaX, animate) {
1396
+ var destX = contentPositionX() + Math[deltaX < 0 ? 'floor' : 'ceil'](deltaX),
1397
+ percentScrolled = destX / (contentWidth - paneWidth);
1398
+ positionDragX(percentScrolled * dragMaxX, animate);
1399
+ },
1400
+ // Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then
1401
+ // the value of animateScroll from the settings object this jScrollPane was initialised with is used.
1402
+ scrollByY: function (deltaY, animate) {
1403
+ var destY = contentPositionY() + Math[deltaY < 0 ? 'floor' : 'ceil'](deltaY),
1404
+ percentScrolled = destY / (contentHeight - paneHeight);
1405
+ positionDragY(percentScrolled * dragMaxY, animate);
1406
+ },
1407
+ // Positions the horizontal drag at the specified x position (and updates the viewport to reflect
1408
+ // this). animate is optional and if not passed then the value of animateScroll from the settings
1409
+ // object this jScrollPane was initialised with is used.
1410
+ positionDragX: function (x, animate) {
1411
+ positionDragX(x, animate);
1412
+ },
1413
+ // Positions the vertical drag at the specified y position (and updates the viewport to reflect
1414
+ // this). animate is optional and if not passed then the value of animateScroll from the settings
1415
+ // object this jScrollPane was initialised with is used.
1416
+ positionDragY: function (y, animate) {
1417
+ positionDragY(y, animate);
1418
+ },
1419
+ // This method is called when jScrollPane is trying to animate to a new position. You can override
1420
+ // it if you want to provide advanced animation functionality. It is passed the following arguments:
1421
+ // * ele - the element whose position is being animated
1422
+ // * prop - the property that is being animated
1423
+ // * value - the value it's being animated to
1424
+ // * stepCallback - a function that you must execute each time you update the value of the property
1425
+ // * completeCallback - a function that will be executed after the animation had finished
1426
+ // You can use the default implementation (below) as a starting point for your own implementation.
1427
+ animate: function (ele, prop, value, stepCallback, completeCallback) {
1428
+ var params = {};
1429
+ params[prop] = value;
1430
+ ele.animate(params, {
1431
+ duration: settings.animateDuration,
1432
+ easing: settings.animateEase,
1433
+ queue: false,
1434
+ step: stepCallback,
1435
+ complete: completeCallback,
1436
+ });
1437
+ },
1438
+ // Returns the current x position of the viewport with regards to the content pane.
1439
+ getContentPositionX: function () {
1440
+ return contentPositionX();
1441
+ },
1442
+ // Returns the current y position of the viewport with regards to the content pane.
1443
+ getContentPositionY: function () {
1444
+ return contentPositionY();
1445
+ },
1446
+ // Returns the width of the content within the scroll pane.
1447
+ getContentWidth: function () {
1448
+ return contentWidth;
1449
+ },
1450
+ // Returns the height of the content within the scroll pane.
1451
+ getContentHeight: function () {
1452
+ return contentHeight;
1453
+ },
1454
+ // Returns the horizontal position of the viewport within the pane content.
1455
+ getPercentScrolledX: function () {
1456
+ return contentPositionX() / (contentWidth - paneWidth);
1457
+ },
1458
+ // Returns the vertical position of the viewport within the pane content.
1459
+ getPercentScrolledY: function () {
1460
+ return contentPositionY() / (contentHeight - paneHeight);
1461
+ },
1462
+ // Returns whether or not this scrollpane has a horizontal scrollbar.
1463
+ getIsScrollableH: function () {
1464
+ return isScrollableH;
1465
+ },
1466
+ // Returns whether or not this scrollpane has a vertical scrollbar.
1467
+ getIsScrollableV: function () {
1468
+ return isScrollableV;
1469
+ },
1470
+ // Gets a reference to the content pane. It is important that you use this method if you want to
1471
+ // edit the content of your jScrollPane as if you access the element directly then you may have some
1472
+ // problems (as your original element has had additional elements for the scrollbars etc added into
1473
+ // it).
1474
+ getContentPane: function () {
1475
+ return pane;
1476
+ },
1477
+ // Scrolls this jScrollPane down as far as it can currently scroll. If animate isn't passed then the
1478
+ // animateScroll value from settings is used instead.
1479
+ scrollToBottom: function (animate) {
1480
+ positionDragY(dragMaxY, animate);
1481
+ },
1482
+ // Hijacks the links on the page which link to content inside the scrollpane. If you have changed
1483
+ // the content of your page (e.g. via AJAX) and want to make sure any new anchor links to the
1484
+ // contents of your scroll pane will work then call this function.
1485
+ hijackInternalLinks: $.noop,
1486
+ // Removes the jScrollPane and returns the page to the state it was in before jScrollPane was
1487
+ // initialised.
1488
+ destroy: function () {
1489
+ destroy();
1490
+ },
1491
+ });
1492
+
1493
+ initialise(s);
1619
1494
  }
1620
- );
1621
- };
1622
-
1623
- $.fn.jScrollPane.defaults = {
1624
- showArrows : false,
1625
- maintainPosition : true,
1626
- stickToBottom : false,
1627
- stickToRight : false,
1628
- clickOnTrack : true,
1629
- autoReinitialise : false,
1630
- autoReinitialiseDelay : 500,
1631
- verticalDragMinHeight : 0,
1632
- verticalDragMaxHeight : 99999,
1633
- horizontalDragMinWidth : 0,
1634
- horizontalDragMaxWidth : 99999,
1635
- contentWidth : undefined,
1636
- animateScroll : false,
1637
- animateDuration : 300,
1638
- animateEase : 'linear',
1639
- hijackInternalLinks : false,
1640
- verticalGutter : 4,
1641
- horizontalGutter : 4,
1642
- mouseWheelSpeed : 3,
1643
- arrowButtonSpeed : 0,
1644
- arrowRepeatFreq : 50,
1645
- arrowScrollOnHover : false,
1646
- trackClickSpeed : 0,
1647
- trackClickRepeatFreq : 70,
1648
- verticalArrowPositions : 'split',
1649
- horizontalArrowPositions : 'split',
1650
- enableKeyboardNavigation : true,
1651
- hideFocus : false,
1652
- keyboardSpeed : 0,
1653
- initialDelay : 300, // Delay before starting repeating
1654
- speed : 30, // Default speed when others falsey
1655
- scrollPagePercent : 0.8, // Percent of visible area scrolled when pageUp/Down or track area pressed
1656
- alwaysShowVScroll : false,
1657
- alwaysShowHScroll : false,
1658
- resizeSensor : false,
1659
- resizeSensorDelay : 0,
1660
- };
1661
-
1662
- }));
1495
+
1496
+ // Pluginifying code...
1497
+ settings = $.extend({}, $.fn.jScrollPane.defaults, settings);
1498
+
1499
+ // Apply default speed
1500
+ $.each(['arrowButtonSpeed', 'trackClickSpeed', 'keyboardSpeed'], function () {
1501
+ settings[this] = settings[this] || settings.speed;
1502
+ });
1503
+
1504
+ return this.each(function () {
1505
+ var elem = $(this),
1506
+ jspApi = elem.data('jsp');
1507
+ if (jspApi) {
1508
+ jspApi.reinitialise(settings);
1509
+ } else {
1510
+ $('script', elem).filter('[type="text/javascript"],:not([type])').remove();
1511
+ jspApi = new JScrollPane(elem, settings);
1512
+ elem.data('jsp', jspApi);
1513
+ }
1514
+ });
1515
+ };
1516
+
1517
+ $.fn.jScrollPane.defaults = {
1518
+ showArrows: false,
1519
+ maintainPosition: true,
1520
+ stickToBottom: false,
1521
+ stickToRight: false,
1522
+ clickOnTrack: true,
1523
+ autoReinitialise: false,
1524
+ autoReinitialiseDelay: 500,
1525
+ verticalDragMinHeight: 0,
1526
+ verticalDragMaxHeight: 99999,
1527
+ horizontalDragMinWidth: 0,
1528
+ horizontalDragMaxWidth: 99999,
1529
+ contentWidth: undefined,
1530
+ animateScroll: false,
1531
+ animateDuration: 300,
1532
+ animateEase: 'linear',
1533
+ hijackInternalLinks: false,
1534
+ verticalGutter: 4,
1535
+ horizontalGutter: 4,
1536
+ mouseWheelSpeed: 3,
1537
+ arrowButtonSpeed: 0,
1538
+ arrowRepeatFreq: 50,
1539
+ arrowScrollOnHover: false,
1540
+ trackClickSpeed: 0,
1541
+ trackClickRepeatFreq: 70,
1542
+ verticalArrowPositions: 'split',
1543
+ horizontalArrowPositions: 'split',
1544
+ enableKeyboardNavigation: true,
1545
+ hideFocus: false,
1546
+ keyboardSpeed: 0,
1547
+ initialDelay: 300, // Delay before starting repeating
1548
+ speed: 30, // Default speed when others falsey
1549
+ scrollPagePercent: 0.8, // Percent of visible area scrolled when pageUp/Down or track area pressed
1550
+ alwaysShowVScroll: false,
1551
+ alwaysShowHScroll: false,
1552
+ resizeSensor: false,
1553
+ resizeSensorDelay: 0,
1554
+ };
1555
+ });