jscrollpane-rails 2.2.1 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +2 -2
- data/README.md +6 -4
- data/app/assets/javascripts/jquery.jscrollpane.js +1394 -1501
- data/app/assets/stylesheets/jquery.jscrollpane.css +46 -46
- data/lib/jscrollpane-rails/version.rb +1 -1
- metadata +5 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8c44d1282555878230b6462b49367cfccf339d9298b3cded4b10bd14ec8b79a3
|
4
|
+
data.tar.gz: d848d4a686dc5fd061cdd3a0e7a6425bf87d383168392060be1f00850a9d5f24
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8bc8979e62344fc724121581ea4b2c7e6bccba7b3f03babd1bbbe0d75e0f4f7d581907d8a3738b4445c576ece89db6f47532a69d8809a41fb6e6bed89303067e
|
7
|
+
data.tar.gz: 7b37b548289a70c52be1aa7ec0ad7839205221a64ea794738779921976904fda40bfa02267e5c35341abc96078b82471d35d9e9af45defe1cef47989a6aa453c
|
data/LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright (c)
|
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
|
-
[](http://badge.fury.io/rb/jscrollpane-rails)
|
4
4
|
[](https://travis-ci.org/bodrovis/jscrollpane-rails)
|
5
5
|
|
6
|
-
A
|
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
|
-
|
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)
|
87
|
+
Copyright (c) 2020 [Ilya Bodrov-Krukowski](http://bodrovis.tech)
|
@@ -1,16 +1,17 @@
|
|
1
1
|
/*!
|
2
|
-
* jScrollPane - v2.2.1 -
|
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-
|
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-
|
26
|
+
// Copyright (c) 2017-2020 Tuukka Pasanen
|
26
27
|
// Dual licensed under the MIT or GPL Version 2 licenses.
|
27
|
-
//
|
28
|
-
//
|
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
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
}(function($){
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
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
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
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
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
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
|
-
|
232
|
+
pane.css('width', '');
|
233
|
+
elem.width(paneWidth);
|
286
234
|
|
287
|
-
|
288
|
-
|
235
|
+
container.find('>.jspVerticalBar,>.jspHorizontalBar').remove().end();
|
236
|
+
}
|
289
237
|
|
290
|
-
|
291
|
-
|
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
|
-
|
294
|
-
|
273
|
+
initialiseVerticalScroll();
|
274
|
+
initialiseHorizontalScroll();
|
275
|
+
resizeScrollbars();
|
295
276
|
|
296
|
-
|
297
|
-
|
277
|
+
if (settings.stickToBottom || settings.stickToRight) {
|
278
|
+
scrollToX(maintainAtRight ? contentWidth - paneWidth : lastContentX, false);
|
279
|
+
scrollToY(maintainAtBottom ? contentHeight - paneHeight : lastContentY, false);
|
280
|
+
}
|
298
281
|
|
299
|
-
|
300
|
-
|
282
|
+
initFocusHandler();
|
283
|
+
initMousewheel();
|
284
|
+
initTouch();
|
301
285
|
|
302
|
-
|
303
|
-
|
304
|
-
|
286
|
+
if (settings.enableKeyboardNavigation) {
|
287
|
+
initKeyboardNav();
|
288
|
+
}
|
289
|
+
if (settings.clickOnTrack) {
|
290
|
+
initClickOnTrack();
|
291
|
+
}
|
305
292
|
|
306
|
-
|
307
|
-
|
308
|
-
|
293
|
+
observeHash();
|
294
|
+
if (settings.hijackInternalLinks) {
|
295
|
+
hijackInternalLinks();
|
296
|
+
}
|
297
|
+
}
|
309
298
|
|
310
|
-
|
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
|
-
|
307
|
+
if (settings.resizeSensor && !resizeEventsAdded) {
|
308
|
+
// detect size change in content
|
309
|
+
detectSizeChanges(pane, reinitialiseFn);
|
314
310
|
|
315
|
-
|
316
|
-
|
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
|
-
|
324
|
-
|
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
|
-
|
329
|
-
|
317
|
+
// add a reinit on window resize also for safety
|
318
|
+
window.addEventListener('resize', reinitialiseFn);
|
330
319
|
|
331
|
-
|
332
|
-
|
320
|
+
resizeEventsAdded = true;
|
321
|
+
}
|
333
322
|
|
334
|
-
|
335
|
-
|
323
|
+
if (originalScrollTop && elem.scrollTop(0)) {
|
324
|
+
scrollToY(originalScrollTop, false);
|
325
|
+
}
|
336
326
|
|
337
|
-
|
338
|
-
|
327
|
+
if (originalScrollLeft && elem.scrollLeft(0)) {
|
328
|
+
scrollToX(originalScrollLeft, false);
|
329
|
+
}
|
339
330
|
|
340
|
-
|
341
|
-
|
331
|
+
elem.trigger('jsp-initialised', [isScrollableH || isScrollableV]);
|
332
|
+
}
|
342
333
|
|
343
|
-
|
344
|
-
|
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
|
-
|
348
|
-
|
391
|
+
// bind to scroll events
|
392
|
+
resizeGrowElement.addEventListener('scroll', onGrow.bind(this));
|
393
|
+
resizeShrinkElement.addEventListener('scroll', onShrink.bind(this));
|
349
394
|
|
350
|
-
|
351
|
-
|
395
|
+
// nest elements before adding to pane
|
396
|
+
resizeGrowElement.appendChild(resizeGrowChildElement);
|
397
|
+
resizeShrinkElement.appendChild(resizeShrinkChildElement);
|
352
398
|
|
353
|
-
|
354
|
-
|
355
|
-
}
|
356
|
-
// after reinitialising update sizes
|
357
|
-
updateSizes();
|
358
|
-
};
|
399
|
+
resizeElement.appendChild(resizeGrowElement);
|
400
|
+
resizeElement.appendChild(resizeShrinkElement);
|
359
401
|
|
360
|
-
|
361
|
-
var onShrink = function() {
|
402
|
+
element.append(resizeElement);
|
362
403
|
|
363
|
-
|
364
|
-
|
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
|
-
|
367
|
-
|
368
|
-
|
369
|
-
// after reinitialising update sizes
|
370
|
-
updateSizes();
|
371
|
-
};
|
409
|
+
// update sizes initially
|
410
|
+
updateSizes();
|
411
|
+
}
|
372
412
|
|
373
|
-
|
374
|
-
|
375
|
-
|
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
|
-
|
378
|
-
|
379
|
-
resizeShrinkElement.appendChild(resizeShrinkChildElement);
|
442
|
+
appendArrows(verticalTrack, settings.verticalArrowPositions, arrowUp, arrowDown);
|
443
|
+
}
|
380
444
|
|
381
|
-
|
382
|
-
|
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
|
-
|
476
|
+
function sizeVerticalScrollbar() {
|
477
|
+
verticalTrack.height(verticalTrackHeight + 'px');
|
478
|
+
verticalDragPosition = 0;
|
479
|
+
scrollbarWidth = settings.verticalGutter + verticalTrack.outerWidth();
|
385
480
|
|
386
|
-
|
387
|
-
|
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
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
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
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
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
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
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
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
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
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
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
|
-
|
635
|
-
|
636
|
-
|
610
|
+
function appendArrows(ele, p, a1, a2) {
|
611
|
+
var p1 = 'before',
|
612
|
+
p2 = 'after',
|
613
|
+
aTemp;
|
637
614
|
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
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
|
-
|
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
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
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
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
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.
|
653
|
+
scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.arrowRepeatFreq);
|
739
654
|
isFirst = false;
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
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
|
-
|
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
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
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
|
-
|
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
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
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
|
-
|
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
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
778
|
+
if (verticalDrag) {
|
779
|
+
verticalDrag.removeClass('jspActive');
|
780
|
+
}
|
781
|
+
if (horizontalDrag) {
|
782
|
+
horizontalDrag.removeClass('jspActive');
|
783
|
+
}
|
784
|
+
}
|
831
785
|
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
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
|
-
|
844
|
-
|
845
|
-
|
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
|
-
|
848
|
-
|
849
|
-
|
800
|
+
if (willScrollYEvent.isDefaultPrevented()) {
|
801
|
+
return;
|
802
|
+
}
|
850
803
|
|
851
|
-
|
804
|
+
var tmpVerticalDragPosition = destY || 0;
|
852
805
|
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
806
|
+
var isAtTop = tmpVerticalDragPosition === 0,
|
807
|
+
isAtBottom = tmpVerticalDragPosition == dragMaxY,
|
808
|
+
percentScrolled = destY / dragMaxY,
|
809
|
+
destTop = -percentScrolled * (contentHeight - paneHeight);
|
857
810
|
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
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
|
-
|
875
|
-
|
876
|
-
if (destY === undefined) {
|
877
|
-
destY = verticalDrag.position().top;
|
878
|
-
}
|
831
|
+
container.scrollTop(0);
|
832
|
+
verticalDragPosition = destY || 0;
|
879
833
|
|
880
|
-
|
881
|
-
|
834
|
+
var isAtTop = verticalDragPosition === 0,
|
835
|
+
isAtBottom = verticalDragPosition == dragMaxY,
|
836
|
+
percentScrolled = destY / dragMaxY,
|
837
|
+
destTop = -percentScrolled * (contentHeight - paneHeight);
|
882
838
|
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
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
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
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
|
-
|
895
|
-
|
896
|
-
|
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
|
-
|
900
|
-
|
901
|
-
|
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
|
-
|
912
|
-
var willScrollXEvent = new $.Event("jsp-will-scroll-x");
|
913
|
-
elem.trigger(willScrollXEvent, [destX]);
|
868
|
+
var tmpHorizontalDragPosition = destX || 0;
|
914
869
|
|
915
|
-
|
916
|
-
|
917
|
-
|
870
|
+
var isAtLeft = tmpHorizontalDragPosition === 0,
|
871
|
+
isAtRight = tmpHorizontalDragPosition == dragMaxX,
|
872
|
+
percentScrolled = destX / dragMaxX,
|
873
|
+
destLeft = -percentScrolled * (contentWidth - paneWidth);
|
918
874
|
|
919
|
-
|
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
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
889
|
+
function _positionDragX(destX) {
|
890
|
+
if (destX === undefined) {
|
891
|
+
destX = horizontalDrag.position().left;
|
892
|
+
}
|
925
893
|
|
926
|
-
|
927
|
-
|
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
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
}
|
897
|
+
var isAtLeft = horizontalDragPosition === 0,
|
898
|
+
isAtRight = horizontalDragPosition == dragMaxX,
|
899
|
+
percentScrolled = destX / dragMaxX,
|
900
|
+
destLeft = -percentScrolled * (contentWidth - paneWidth);
|
945
901
|
|
946
|
-
|
947
|
-
|
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
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
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
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
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
|
-
|
961
|
-
|
962
|
-
|
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
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
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
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
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
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
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
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
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
|
-
|
1120
|
-
|
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
|
-
|
1124
|
-
pane.on(
|
1125
|
-
'focus.jsp',
|
1126
|
-
function()
|
1127
|
-
{
|
1128
|
-
elem.focus();
|
1018
|
+
return true;
|
1129
1019
|
}
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
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
|
-
|
1167
|
-
|
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
|
-
|
1194
|
-
|
1195
|
-
|
1196
|
-
|
1197
|
-
|
1198
|
-
|
1199
|
-
|
1200
|
-
|
1201
|
-
|
1202
|
-
|
1203
|
-
|
1204
|
-
|
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
|
-
|
1269
|
-
|
1270
|
-
|
1271
|
-
if ($(document.body).data('jspHijack')) {
|
1272
|
-
return;
|
1273
|
-
}
|
1045
|
+
function removeMousewheel() {
|
1046
|
+
container.off(mwEvent);
|
1047
|
+
}
|
1274
1048
|
|
1275
|
-
|
1276
|
-
|
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
|
-
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1336
|
-
|
1337
|
-
|
1338
|
-
|
1339
|
-
|
1340
|
-
|
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
|
-
|
1367
|
-
|
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
|
-
|
1077
|
+
// IE also focuses elements that don't have tabindex set.
|
1078
|
+
pane.on('focus.jsp', function () {
|
1079
|
+
elem.focus();
|
1080
|
+
});
|
1370
1081
|
|
1371
|
-
|
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
|
-
|
1374
|
-
|
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
|
-
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
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
|
-
|
1386
|
-
|
1387
|
-
|
1388
|
-
|
1389
|
-
|
1390
|
-
|
1391
|
-
|
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
|
-
|
1398
|
-
|
1399
|
-
|
1400
|
-
|
1401
|
-
|
1402
|
-
|
1403
|
-
|
1404
|
-
|
1405
|
-
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1409
|
-
|
1410
|
-
|
1411
|
-
|
1412
|
-
|
1413
|
-
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
1417
|
-
|
1418
|
-
|
1419
|
-
|
1420
|
-
|
1421
|
-
|
1422
|
-
|
1423
|
-
|
1424
|
-
|
1425
|
-
|
1426
|
-
|
1427
|
-
|
1428
|
-
|
1429
|
-
|
1430
|
-
|
1431
|
-
|
1432
|
-
|
1433
|
-
|
1434
|
-
|
1435
|
-
|
1436
|
-
|
1437
|
-
|
1438
|
-
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1442
|
-
|
1443
|
-
|
1444
|
-
|
1445
|
-
|
1446
|
-
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1450
|
-
|
1451
|
-
|
1452
|
-
|
1453
|
-
|
1454
|
-
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
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
|
-
|
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
|
-
|
1601
|
-
|
1602
|
-
|
1603
|
-
|
1604
|
-
|
1605
|
-
|
1606
|
-
|
1607
|
-
|
1608
|
-
|
1609
|
-
|
1610
|
-
|
1611
|
-
|
1612
|
-
|
1613
|
-
|
1614
|
-
|
1615
|
-
|
1616
|
-
|
1617
|
-
|
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
|
-
|
1624
|
-
|
1625
|
-
|
1626
|
-
|
1627
|
-
|
1628
|
-
|
1629
|
-
|
1630
|
-
|
1631
|
-
|
1632
|
-
|
1633
|
-
|
1634
|
-
|
1635
|
-
|
1636
|
-
|
1637
|
-
|
1638
|
-
|
1639
|
-
|
1640
|
-
|
1641
|
-
|
1642
|
-
|
1643
|
-
|
1644
|
-
|
1645
|
-
|
1646
|
-
|
1647
|
-
|
1648
|
-
|
1649
|
-
|
1650
|
-
|
1651
|
-
|
1652
|
-
|
1653
|
-
|
1654
|
-
|
1655
|
-
|
1656
|
-
|
1657
|
-
|
1658
|
-
|
1659
|
-
|
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
|
+
});
|