jscrollpane-rails 2.0.20 → 2.0.21

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: edd9a57c4e871260580e534d6f4ef3fccddd62cb
4
- data.tar.gz: 6d18cd77a426c557bbd7301419834300a2611c02
3
+ metadata.gz: 5494c033221ff075b0a0d67c8db5895d862e9283
4
+ data.tar.gz: 76c20dbe6a52830cce5a76c015e17d9610fc42cb
5
5
  SHA512:
6
- metadata.gz: 7d0499243572596ce789e7487a1c362b877e6b9d3a193ed838ad6a6b74e2c35e54e1af8c48aa104b38fa612b70c92540c15a1d0d1ebd4304a121082f0efbaccd
7
- data.tar.gz: d5a16cdda5c9dae50a79e2852008a65fb6d43cddac3aaa252ba6b050c89df3d5c942468113c9fc5b346e39efca4a4a3a5cb1835022a0b763b201edb19a351428
6
+ metadata.gz: ed0d69f8c165ff6d1bd8369571efaec91bbc271614c8c015733626de6995f1bbab0e0e9d79fd64dd68595493a4539534255239ee0219ae13f08110ce47387c72
7
+ data.tar.gz: 10f3b40d125eb092642984ce1b5fbea3f18a664b80a1c0d96921168bb361c63c7e899cb2823a535455bb81ffee4b64a6acb89d3190b6d9360bc9a98f854824cb
@@ -0,0 +1,1465 @@
1
+ /*!
2
+ * jScrollPane - v2.0.21 - 2015-02-24
3
+ * http://jscrollpane.kelvinluck.com/
4
+ *
5
+ * Copyright (c) 2014 Kelvin Luck
6
+ * Dual licensed under the MIT or GPL licenses.
7
+ */
8
+
9
+ // Script: jScrollPane - cross browser customisable scrollbars
10
+ //
11
+ // *Version: 2.0.21, Last updated: 2015-02-24*
12
+ //
13
+ // Project Home - http://jscrollpane.kelvinluck.com/
14
+ // GitHub - http://github.com/vitch/jScrollPane
15
+ // Source - http://github.com/vitch/jScrollPane/raw/master/script/jquery.jscrollpane.js
16
+ // (Minified) - http://github.com/vitch/jScrollPane/raw/master/script/jquery.jscrollpane.min.js
17
+ //
18
+ // About: License
19
+ //
20
+ // Copyright (c) 2014 Kelvin Luck
21
+ // Dual licensed under the MIT or GPL Version 2 licenses.
22
+ // http://jscrollpane.kelvinluck.com/MIT-LICENSE.txt
23
+ // http://jscrollpane.kelvinluck.com/GPL-LICENSE.txt
24
+ //
25
+ // About: Examples
26
+ //
27
+ // All examples and demos are available through the jScrollPane example site at:
28
+ // http://jscrollpane.kelvinluck.com/
29
+ //
30
+ // About: Support and Testing
31
+ //
32
+ // This plugin is tested on the browsers below and has been found to work reliably on them. If you run
33
+ // into a problem on one of the supported browsers then please visit the support section on the jScrollPane
34
+ // website (http://jscrollpane.kelvinluck.com/) for more information on getting support. You are also
35
+ // welcome to fork the project on GitHub if you can contribute a fix for a given issue.
36
+ //
37
+ // jQuery Versions - tested in 1.4.2+ - reported to work in 1.3.x
38
+ // Browsers Tested - Firefox 3.6.8, Safari 5, Opera 10.6, Chrome 5.0, IE 6, 7, 8
39
+ //
40
+ // About: Release History
41
+ //
42
+ // 2.0.21 - (2015-02-24) Simplify UMD pattern: fixes browserify when loading jQuery outside of bundle
43
+ // 2.0.20 - (2014-10-23) Adds AMD support (thanks @carlosrberto) and support for overflow-x/overflow-y (thanks @darimpulso)
44
+ // 2.0.19 - (2013-11-16) Changes for more reliable scroll amount with latest mousewheel plugin (thanks @brandonaaron)
45
+ // 2.0.18 - (2013-10-23) Fix for issue with gutters and scrollToElement (thanks @Dubiy)
46
+ // 2.0.17 - (2013-08-17) Working correctly when box-sizing is set to border-box (thanks @pieht)
47
+ // 2.0.16 - (2013-07-30) Resetting left position when scroll is removed. Fixes #189
48
+ // 2.0.15 - (2013-07-29) Fixed issue with scrollToElement where the destX and destY are undefined.
49
+ // 2.0.14 - (2013-05-01) Updated to most recent mouse wheel plugin (see #106) and related changes for sensible scroll speed
50
+ // 2.0.13 - (2013-05-01) Switched to semver compatible version name
51
+ // 2.0.0beta12 - (2012-09-27) fix for jQuery 1.8+
52
+ // 2.0.0beta11 - (2012-05-14)
53
+ // 2.0.0beta10 - (2011-04-17) cleaner required size calculation, improved keyboard support, stickToBottom/Left, other small fixes
54
+ // 2.0.0beta9 - (2011-01-31) new API methods, bug fixes and correct keyboard support for FF/OSX
55
+ // 2.0.0beta8 - (2011-01-29) touchscreen support, improved keyboard support
56
+ // 2.0.0beta7 - (2011-01-23) scroll speed consistent (thanks Aivo Paas)
57
+ // 2.0.0beta6 - (2010-12-07) scrollToElement horizontal support
58
+ // 2.0.0beta5 - (2010-10-18) jQuery 1.4.3 support, various bug fixes
59
+ // 2.0.0beta4 - (2010-09-17) clickOnTrack support, bug fixes
60
+ // 2.0.0beta3 - (2010-08-27) Horizontal mousewheel, mwheelIntent, keyboard support, bug fixes
61
+ // 2.0.0beta2 - (2010-08-21) Bug fixes
62
+ // 2.0.0beta1 - (2010-08-17) Rewrite to follow modern best practices and enable horizontal scrolling, initially hidden
63
+ // elements and dynamically sized elements.
64
+ // 1.x - (2006-12-31 - 2010-07-31) Initial version, hosted at googlecode, deprecated
65
+
66
+ (function (factory) {
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(require('jquery'));
73
+ } else {
74
+ // Browser globals
75
+ factory(jQuery);
76
+ }
77
+ }(function($){
78
+
79
+ $.fn.jScrollPane = function(settings)
80
+ {
81
+ // JScrollPane "class" - public methods are available through $('selector').data('jsp')
82
+ function JScrollPane(elem, s)
83
+ {
84
+ var settings, jsp = this, pane, paneWidth, paneHeight, container, contentWidth, contentHeight,
85
+ percentInViewH, percentInViewV, isScrollableV, isScrollableH, verticalDrag, dragMaxY,
86
+ verticalDragPosition, horizontalDrag, dragMaxX, horizontalDragPosition,
87
+ verticalBar, verticalTrack, scrollbarWidth, verticalTrackHeight, verticalDragHeight, arrowUp, arrowDown,
88
+ horizontalBar, horizontalTrack, horizontalTrackWidth, horizontalDragWidth, arrowLeft, arrowRight,
89
+ reinitialiseInterval, originalPadding, originalPaddingTotalWidth, previousContentWidth,
90
+ wasAtTop = true, wasAtLeft = true, wasAtBottom = false, wasAtRight = false,
91
+ originalElement = elem.clone(false, false).empty(),
92
+ mwEvent = $.fn.mwheelIntent ? 'mwheelIntent.jsp' : 'mousewheel.jsp';
93
+
94
+ if (elem.css('box-sizing') === 'border-box') {
95
+ originalPadding = 0;
96
+ originalPaddingTotalWidth = 0;
97
+ } else {
98
+ originalPadding = elem.css('paddingTop') + ' ' +
99
+ elem.css('paddingRight') + ' ' +
100
+ elem.css('paddingBottom') + ' ' +
101
+ elem.css('paddingLeft');
102
+ originalPaddingTotalWidth = (parseInt(elem.css('paddingLeft'), 10) || 0) +
103
+ (parseInt(elem.css('paddingRight'), 10) || 0);
104
+ }
105
+
106
+ function initialise(s)
107
+ {
108
+
109
+ var /*firstChild, lastChild, */isMaintainingPositon, lastContentX, lastContentY,
110
+ hasContainingSpaceChanged, originalScrollTop, originalScrollLeft,
111
+ maintainAtBottom = false, maintainAtRight = false;
112
+
113
+ settings = s;
114
+
115
+ if (pane === undefined) {
116
+ originalScrollTop = elem.scrollTop();
117
+ originalScrollLeft = elem.scrollLeft();
118
+
119
+ elem.css(
120
+ {
121
+ overflow: 'hidden',
122
+ padding: 0
123
+ }
124
+ );
125
+ // TODO: Deal with where width/ height is 0 as it probably means the element is hidden and we should
126
+ // come back to it later and check once it is unhidden...
127
+ paneWidth = elem.innerWidth() + originalPaddingTotalWidth;
128
+ paneHeight = elem.innerHeight();
129
+
130
+ elem.width(paneWidth);
131
+
132
+ pane = $('<div class="jspPane" />').css('padding', originalPadding).append(elem.children());
133
+ container = $('<div class="jspContainer" />')
134
+ .css({
135
+ 'width': paneWidth + 'px',
136
+ 'height': paneHeight + 'px'
137
+ }
138
+ ).append(pane).appendTo(elem);
139
+
140
+ /*
141
+ // Move any margins from the first and last children up to the container so they can still
142
+ // collapse with neighbouring elements as they would before jScrollPane
143
+ firstChild = pane.find(':first-child');
144
+ lastChild = pane.find(':last-child');
145
+ elem.css(
146
+ {
147
+ 'margin-top': firstChild.css('margin-top'),
148
+ 'margin-bottom': lastChild.css('margin-bottom')
149
+ }
150
+ );
151
+ firstChild.css('margin-top', 0);
152
+ lastChild.css('margin-bottom', 0);
153
+ */
154
+ } else {
155
+ elem.css('width', '');
156
+
157
+ maintainAtBottom = settings.stickToBottom && isCloseToBottom();
158
+ maintainAtRight = settings.stickToRight && isCloseToRight();
159
+
160
+ hasContainingSpaceChanged = elem.innerWidth() + originalPaddingTotalWidth != paneWidth || elem.outerHeight() != paneHeight;
161
+
162
+ if (hasContainingSpaceChanged) {
163
+ paneWidth = elem.innerWidth() + originalPaddingTotalWidth;
164
+ paneHeight = elem.innerHeight();
165
+ container.css({
166
+ width: paneWidth + 'px',
167
+ height: paneHeight + 'px'
168
+ });
169
+ }
170
+
171
+ // If nothing changed since last check...
172
+ if (!hasContainingSpaceChanged && previousContentWidth == contentWidth && pane.outerHeight() == contentHeight) {
173
+ elem.width(paneWidth);
174
+ return;
175
+ }
176
+ previousContentWidth = contentWidth;
177
+
178
+ pane.css('width', '');
179
+ elem.width(paneWidth);
180
+
181
+ container.find('>.jspVerticalBar,>.jspHorizontalBar').remove().end();
182
+ }
183
+
184
+ pane.css('overflow', 'auto');
185
+ if (s.contentWidth) {
186
+ contentWidth = s.contentWidth;
187
+ } else {
188
+ contentWidth = pane[0].scrollWidth;
189
+ }
190
+ contentHeight = pane[0].scrollHeight;
191
+ pane.css('overflow', '');
192
+
193
+ percentInViewH = contentWidth / paneWidth;
194
+ percentInViewV = contentHeight / paneHeight;
195
+ isScrollableV = percentInViewV > 1;
196
+
197
+ isScrollableH = percentInViewH > 1;
198
+
199
+ //console.log(paneWidth, paneHeight, contentWidth, contentHeight, percentInViewH, percentInViewV, isScrollableH, isScrollableV);
200
+
201
+ if (!(isScrollableH || isScrollableV)) {
202
+ elem.removeClass('jspScrollable');
203
+ pane.css({
204
+ top: 0,
205
+ left: 0,
206
+ width: container.width() - originalPaddingTotalWidth
207
+ });
208
+ removeMousewheel();
209
+ removeFocusHandler();
210
+ removeKeyboardNav();
211
+ removeClickOnTrack();
212
+ } else {
213
+ elem.addClass('jspScrollable');
214
+
215
+ isMaintainingPositon = settings.maintainPosition && (verticalDragPosition || horizontalDragPosition);
216
+ if (isMaintainingPositon) {
217
+ lastContentX = contentPositionX();
218
+ lastContentY = contentPositionY();
219
+ }
220
+
221
+ initialiseVerticalScroll();
222
+ initialiseHorizontalScroll();
223
+ resizeScrollbars();
224
+
225
+ if (isMaintainingPositon) {
226
+ scrollToX(maintainAtRight ? (contentWidth - paneWidth ) : lastContentX, false);
227
+ scrollToY(maintainAtBottom ? (contentHeight - paneHeight) : lastContentY, false);
228
+ }
229
+
230
+ initFocusHandler();
231
+ initMousewheel();
232
+ initTouch();
233
+
234
+ if (settings.enableKeyboardNavigation) {
235
+ initKeyboardNav();
236
+ }
237
+ if (settings.clickOnTrack) {
238
+ initClickOnTrack();
239
+ }
240
+
241
+ observeHash();
242
+ if (settings.hijackInternalLinks) {
243
+ hijackInternalLinks();
244
+ }
245
+ }
246
+
247
+ if (settings.autoReinitialise && !reinitialiseInterval) {
248
+ reinitialiseInterval = setInterval(
249
+ function()
250
+ {
251
+ initialise(settings);
252
+ },
253
+ settings.autoReinitialiseDelay
254
+ );
255
+ } else if (!settings.autoReinitialise && reinitialiseInterval) {
256
+ clearInterval(reinitialiseInterval);
257
+ }
258
+
259
+ originalScrollTop && elem.scrollTop(0) && scrollToY(originalScrollTop, false);
260
+ originalScrollLeft && elem.scrollLeft(0) && scrollToX(originalScrollLeft, false);
261
+
262
+ elem.trigger('jsp-initialised', [isScrollableH || isScrollableV]);
263
+ }
264
+
265
+ function initialiseVerticalScroll()
266
+ {
267
+ if (isScrollableV) {
268
+
269
+ container.append(
270
+ $('<div class="jspVerticalBar" />').append(
271
+ $('<div class="jspCap jspCapTop" />'),
272
+ $('<div class="jspTrack" />').append(
273
+ $('<div class="jspDrag" />').append(
274
+ $('<div class="jspDragTop" />'),
275
+ $('<div class="jspDragBottom" />')
276
+ )
277
+ ),
278
+ $('<div class="jspCap jspCapBottom" />')
279
+ )
280
+ );
281
+
282
+ verticalBar = container.find('>.jspVerticalBar');
283
+ verticalTrack = verticalBar.find('>.jspTrack');
284
+ verticalDrag = verticalTrack.find('>.jspDrag');
285
+
286
+ if (settings.showArrows) {
287
+ arrowUp = $('<a class="jspArrow jspArrowUp" />').bind(
288
+ 'mousedown.jsp', getArrowScroll(0, -1)
289
+ ).bind('click.jsp', nil);
290
+ arrowDown = $('<a class="jspArrow jspArrowDown" />').bind(
291
+ 'mousedown.jsp', getArrowScroll(0, 1)
292
+ ).bind('click.jsp', nil);
293
+ if (settings.arrowScrollOnHover) {
294
+ arrowUp.bind('mouseover.jsp', getArrowScroll(0, -1, arrowUp));
295
+ arrowDown.bind('mouseover.jsp', getArrowScroll(0, 1, arrowDown));
296
+ }
297
+
298
+ appendArrows(verticalTrack, settings.verticalArrowPositions, arrowUp, arrowDown);
299
+ }
300
+
301
+ verticalTrackHeight = paneHeight;
302
+ container.find('>.jspVerticalBar>.jspCap:visible,>.jspVerticalBar>.jspArrow').each(
303
+ function()
304
+ {
305
+ verticalTrackHeight -= $(this).outerHeight();
306
+ }
307
+ );
308
+
309
+
310
+ verticalDrag.hover(
311
+ function()
312
+ {
313
+ verticalDrag.addClass('jspHover');
314
+ },
315
+ function()
316
+ {
317
+ verticalDrag.removeClass('jspHover');
318
+ }
319
+ ).bind(
320
+ 'mousedown.jsp',
321
+ function(e)
322
+ {
323
+ // Stop IE from allowing text selection
324
+ $('html').bind('dragstart.jsp selectstart.jsp', nil);
325
+
326
+ verticalDrag.addClass('jspActive');
327
+
328
+ var startY = e.pageY - verticalDrag.position().top;
329
+
330
+ $('html').bind(
331
+ 'mousemove.jsp',
332
+ function(e)
333
+ {
334
+ positionDragY(e.pageY - startY, false);
335
+ }
336
+ ).bind('mouseup.jsp mouseleave.jsp', cancelDrag);
337
+ return false;
338
+ }
339
+ );
340
+ sizeVerticalScrollbar();
341
+ }
342
+ }
343
+
344
+ function sizeVerticalScrollbar()
345
+ {
346
+ verticalTrack.height(verticalTrackHeight + 'px');
347
+ verticalDragPosition = 0;
348
+ scrollbarWidth = settings.verticalGutter + verticalTrack.outerWidth();
349
+
350
+ // Make the pane thinner to allow for the vertical scrollbar
351
+ pane.width(paneWidth - scrollbarWidth - originalPaddingTotalWidth);
352
+
353
+ // Add margin to the left of the pane if scrollbars are on that side (to position
354
+ // the scrollbar on the left or right set it's left or right property in CSS)
355
+ try {
356
+ if (verticalBar.position().left === 0) {
357
+ pane.css('margin-left', scrollbarWidth + 'px');
358
+ }
359
+ } catch (err) {
360
+ }
361
+ }
362
+
363
+ function initialiseHorizontalScroll()
364
+ {
365
+ if (isScrollableH) {
366
+
367
+ container.append(
368
+ $('<div class="jspHorizontalBar" />').append(
369
+ $('<div class="jspCap jspCapLeft" />'),
370
+ $('<div class="jspTrack" />').append(
371
+ $('<div class="jspDrag" />').append(
372
+ $('<div class="jspDragLeft" />'),
373
+ $('<div class="jspDragRight" />')
374
+ )
375
+ ),
376
+ $('<div class="jspCap jspCapRight" />')
377
+ )
378
+ );
379
+
380
+ horizontalBar = container.find('>.jspHorizontalBar');
381
+ horizontalTrack = horizontalBar.find('>.jspTrack');
382
+ horizontalDrag = horizontalTrack.find('>.jspDrag');
383
+
384
+ if (settings.showArrows) {
385
+ arrowLeft = $('<a class="jspArrow jspArrowLeft" />').bind(
386
+ 'mousedown.jsp', getArrowScroll(-1, 0)
387
+ ).bind('click.jsp', nil);
388
+ arrowRight = $('<a class="jspArrow jspArrowRight" />').bind(
389
+ 'mousedown.jsp', getArrowScroll(1, 0)
390
+ ).bind('click.jsp', nil);
391
+ if (settings.arrowScrollOnHover) {
392
+ arrowLeft.bind('mouseover.jsp', getArrowScroll(-1, 0, arrowLeft));
393
+ arrowRight.bind('mouseover.jsp', getArrowScroll(1, 0, arrowRight));
394
+ }
395
+ appendArrows(horizontalTrack, settings.horizontalArrowPositions, arrowLeft, arrowRight);
396
+ }
397
+
398
+ horizontalDrag.hover(
399
+ function()
400
+ {
401
+ horizontalDrag.addClass('jspHover');
402
+ },
403
+ function()
404
+ {
405
+ horizontalDrag.removeClass('jspHover');
406
+ }
407
+ ).bind(
408
+ 'mousedown.jsp',
409
+ function(e)
410
+ {
411
+ // Stop IE from allowing text selection
412
+ $('html').bind('dragstart.jsp selectstart.jsp', nil);
413
+
414
+ horizontalDrag.addClass('jspActive');
415
+
416
+ var startX = e.pageX - horizontalDrag.position().left;
417
+
418
+ $('html').bind(
419
+ 'mousemove.jsp',
420
+ function(e)
421
+ {
422
+ positionDragX(e.pageX - startX, false);
423
+ }
424
+ ).bind('mouseup.jsp mouseleave.jsp', cancelDrag);
425
+ return false;
426
+ }
427
+ );
428
+ horizontalTrackWidth = container.innerWidth();
429
+ sizeHorizontalScrollbar();
430
+ }
431
+ }
432
+
433
+ function sizeHorizontalScrollbar()
434
+ {
435
+ container.find('>.jspHorizontalBar>.jspCap:visible,>.jspHorizontalBar>.jspArrow').each(
436
+ function()
437
+ {
438
+ horizontalTrackWidth -= $(this).outerWidth();
439
+ }
440
+ );
441
+
442
+ horizontalTrack.width(horizontalTrackWidth + 'px');
443
+ horizontalDragPosition = 0;
444
+ }
445
+
446
+ function resizeScrollbars()
447
+ {
448
+ if (isScrollableH && isScrollableV) {
449
+ var horizontalTrackHeight = horizontalTrack.outerHeight(),
450
+ verticalTrackWidth = verticalTrack.outerWidth();
451
+ verticalTrackHeight -= horizontalTrackHeight;
452
+ $(horizontalBar).find('>.jspCap:visible,>.jspArrow').each(
453
+ function()
454
+ {
455
+ horizontalTrackWidth += $(this).outerWidth();
456
+ }
457
+ );
458
+ horizontalTrackWidth -= verticalTrackWidth;
459
+ paneHeight -= verticalTrackWidth;
460
+ paneWidth -= horizontalTrackHeight;
461
+ horizontalTrack.parent().append(
462
+ $('<div class="jspCorner" />').css('width', horizontalTrackHeight + 'px')
463
+ );
464
+ sizeVerticalScrollbar();
465
+ sizeHorizontalScrollbar();
466
+ }
467
+ // reflow content
468
+ if (isScrollableH) {
469
+ pane.width((container.outerWidth() - originalPaddingTotalWidth) + 'px');
470
+ }
471
+ contentHeight = pane.outerHeight();
472
+ percentInViewV = contentHeight / paneHeight;
473
+
474
+ if (isScrollableH) {
475
+ horizontalDragWidth = Math.ceil(1 / percentInViewH * horizontalTrackWidth);
476
+ if (horizontalDragWidth > settings.horizontalDragMaxWidth) {
477
+ horizontalDragWidth = settings.horizontalDragMaxWidth;
478
+ } else if (horizontalDragWidth < settings.horizontalDragMinWidth) {
479
+ horizontalDragWidth = settings.horizontalDragMinWidth;
480
+ }
481
+ horizontalDrag.width(horizontalDragWidth + 'px');
482
+ dragMaxX = horizontalTrackWidth - horizontalDragWidth;
483
+ _positionDragX(horizontalDragPosition); // To update the state for the arrow buttons
484
+ }
485
+ if (isScrollableV) {
486
+ verticalDragHeight = Math.ceil(1 / percentInViewV * verticalTrackHeight);
487
+ if (verticalDragHeight > settings.verticalDragMaxHeight) {
488
+ verticalDragHeight = settings.verticalDragMaxHeight;
489
+ } else if (verticalDragHeight < settings.verticalDragMinHeight) {
490
+ verticalDragHeight = settings.verticalDragMinHeight;
491
+ }
492
+ verticalDrag.height(verticalDragHeight + 'px');
493
+ dragMaxY = verticalTrackHeight - verticalDragHeight;
494
+ _positionDragY(verticalDragPosition); // To update the state for the arrow buttons
495
+ }
496
+ }
497
+
498
+ function appendArrows(ele, p, a1, a2)
499
+ {
500
+ var p1 = "before", p2 = "after", aTemp;
501
+
502
+ // Sniff for mac... Is there a better way to determine whether the arrows would naturally appear
503
+ // at the top or the bottom of the bar?
504
+ if (p == "os") {
505
+ p = /Mac/.test(navigator.platform) ? "after" : "split";
506
+ }
507
+ if (p == p1) {
508
+ p2 = p;
509
+ } else if (p == p2) {
510
+ p1 = p;
511
+ aTemp = a1;
512
+ a1 = a2;
513
+ a2 = aTemp;
514
+ }
515
+
516
+ ele[p1](a1)[p2](a2);
517
+ }
518
+
519
+ function getArrowScroll(dirX, dirY, ele)
520
+ {
521
+ return function()
522
+ {
523
+ arrowScroll(dirX, dirY, this, ele);
524
+ this.blur();
525
+ return false;
526
+ };
527
+ }
528
+
529
+ function arrowScroll(dirX, dirY, arrow, ele)
530
+ {
531
+ arrow = $(arrow).addClass('jspActive');
532
+
533
+ var eve,
534
+ scrollTimeout,
535
+ isFirst = true,
536
+ doScroll = function()
537
+ {
538
+ if (dirX !== 0) {
539
+ jsp.scrollByX(dirX * settings.arrowButtonSpeed);
540
+ }
541
+ if (dirY !== 0) {
542
+ jsp.scrollByY(dirY * settings.arrowButtonSpeed);
543
+ }
544
+ scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.arrowRepeatFreq);
545
+ isFirst = false;
546
+ };
547
+
548
+ doScroll();
549
+
550
+ eve = ele ? 'mouseout.jsp' : 'mouseup.jsp';
551
+ ele = ele || $('html');
552
+ ele.bind(
553
+ eve,
554
+ function()
555
+ {
556
+ arrow.removeClass('jspActive');
557
+ scrollTimeout && clearTimeout(scrollTimeout);
558
+ scrollTimeout = null;
559
+ ele.unbind(eve);
560
+ }
561
+ );
562
+ }
563
+
564
+ function initClickOnTrack()
565
+ {
566
+ removeClickOnTrack();
567
+ if (isScrollableV) {
568
+ verticalTrack.bind(
569
+ 'mousedown.jsp',
570
+ function(e)
571
+ {
572
+ if (e.originalTarget === undefined || e.originalTarget == e.currentTarget) {
573
+ var clickedTrack = $(this),
574
+ offset = clickedTrack.offset(),
575
+ direction = e.pageY - offset.top - verticalDragPosition,
576
+ scrollTimeout,
577
+ isFirst = true,
578
+ doScroll = function()
579
+ {
580
+ var offset = clickedTrack.offset(),
581
+ pos = e.pageY - offset.top - verticalDragHeight / 2,
582
+ contentDragY = paneHeight * settings.scrollPagePercent,
583
+ dragY = dragMaxY * contentDragY / (contentHeight - paneHeight);
584
+ if (direction < 0) {
585
+ if (verticalDragPosition - dragY > pos) {
586
+ jsp.scrollByY(-contentDragY);
587
+ } else {
588
+ positionDragY(pos);
589
+ }
590
+ } else if (direction > 0) {
591
+ if (verticalDragPosition + dragY < pos) {
592
+ jsp.scrollByY(contentDragY);
593
+ } else {
594
+ positionDragY(pos);
595
+ }
596
+ } else {
597
+ cancelClick();
598
+ return;
599
+ }
600
+ scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.trackClickRepeatFreq);
601
+ isFirst = false;
602
+ },
603
+ cancelClick = function()
604
+ {
605
+ scrollTimeout && clearTimeout(scrollTimeout);
606
+ scrollTimeout = null;
607
+ $(document).unbind('mouseup.jsp', cancelClick);
608
+ };
609
+ doScroll();
610
+ $(document).bind('mouseup.jsp', cancelClick);
611
+ return false;
612
+ }
613
+ }
614
+ );
615
+ }
616
+
617
+ if (isScrollableH) {
618
+ horizontalTrack.bind(
619
+ 'mousedown.jsp',
620
+ function(e)
621
+ {
622
+ if (e.originalTarget === undefined || e.originalTarget == e.currentTarget) {
623
+ var clickedTrack = $(this),
624
+ offset = clickedTrack.offset(),
625
+ direction = e.pageX - offset.left - horizontalDragPosition,
626
+ scrollTimeout,
627
+ isFirst = true,
628
+ doScroll = function()
629
+ {
630
+ var offset = clickedTrack.offset(),
631
+ pos = e.pageX - offset.left - horizontalDragWidth / 2,
632
+ contentDragX = paneWidth * settings.scrollPagePercent,
633
+ dragX = dragMaxX * contentDragX / (contentWidth - paneWidth);
634
+ if (direction < 0) {
635
+ if (horizontalDragPosition - dragX > pos) {
636
+ jsp.scrollByX(-contentDragX);
637
+ } else {
638
+ positionDragX(pos);
639
+ }
640
+ } else if (direction > 0) {
641
+ if (horizontalDragPosition + dragX < pos) {
642
+ jsp.scrollByX(contentDragX);
643
+ } else {
644
+ positionDragX(pos);
645
+ }
646
+ } else {
647
+ cancelClick();
648
+ return;
649
+ }
650
+ scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.trackClickRepeatFreq);
651
+ isFirst = false;
652
+ },
653
+ cancelClick = function()
654
+ {
655
+ scrollTimeout && clearTimeout(scrollTimeout);
656
+ scrollTimeout = null;
657
+ $(document).unbind('mouseup.jsp', cancelClick);
658
+ };
659
+ doScroll();
660
+ $(document).bind('mouseup.jsp', cancelClick);
661
+ return false;
662
+ }
663
+ }
664
+ );
665
+ }
666
+ }
667
+
668
+ function removeClickOnTrack()
669
+ {
670
+ if (horizontalTrack) {
671
+ horizontalTrack.unbind('mousedown.jsp');
672
+ }
673
+ if (verticalTrack) {
674
+ verticalTrack.unbind('mousedown.jsp');
675
+ }
676
+ }
677
+
678
+ function cancelDrag()
679
+ {
680
+ $('html').unbind('dragstart.jsp selectstart.jsp mousemove.jsp mouseup.jsp mouseleave.jsp');
681
+
682
+ if (verticalDrag) {
683
+ verticalDrag.removeClass('jspActive');
684
+ }
685
+ if (horizontalDrag) {
686
+ horizontalDrag.removeClass('jspActive');
687
+ }
688
+ }
689
+
690
+ function positionDragY(destY, animate)
691
+ {
692
+ if (!isScrollableV) {
693
+ return;
694
+ }
695
+ if (destY < 0) {
696
+ destY = 0;
697
+ } else if (destY > dragMaxY) {
698
+ destY = dragMaxY;
699
+ }
700
+
701
+ // can't just check if(animate) because false is a valid value that could be passed in...
702
+ if (animate === undefined) {
703
+ animate = settings.animateScroll;
704
+ }
705
+ if (animate) {
706
+ jsp.animate(verticalDrag, 'top', destY, _positionDragY);
707
+ } else {
708
+ verticalDrag.css('top', destY);
709
+ _positionDragY(destY);
710
+ }
711
+
712
+ }
713
+
714
+ function _positionDragY(destY)
715
+ {
716
+ if (destY === undefined) {
717
+ destY = verticalDrag.position().top;
718
+ }
719
+
720
+ container.scrollTop(0);
721
+ verticalDragPosition = destY || 0;
722
+
723
+ var isAtTop = verticalDragPosition === 0,
724
+ isAtBottom = verticalDragPosition == dragMaxY,
725
+ percentScrolled = destY/ dragMaxY,
726
+ destTop = -percentScrolled * (contentHeight - paneHeight);
727
+
728
+ if (wasAtTop != isAtTop || wasAtBottom != isAtBottom) {
729
+ wasAtTop = isAtTop;
730
+ wasAtBottom = isAtBottom;
731
+ elem.trigger('jsp-arrow-change', [wasAtTop, wasAtBottom, wasAtLeft, wasAtRight]);
732
+ }
733
+
734
+ updateVerticalArrows(isAtTop, isAtBottom);
735
+ pane.css('top', destTop);
736
+ elem.trigger('jsp-scroll-y', [-destTop, isAtTop, isAtBottom]).trigger('scroll');
737
+ }
738
+
739
+ function positionDragX(destX, animate)
740
+ {
741
+ if (!isScrollableH) {
742
+ return;
743
+ }
744
+ if (destX < 0) {
745
+ destX = 0;
746
+ } else if (destX > dragMaxX) {
747
+ destX = dragMaxX;
748
+ }
749
+
750
+ if (animate === undefined) {
751
+ animate = settings.animateScroll;
752
+ }
753
+ if (animate) {
754
+ jsp.animate(horizontalDrag, 'left', destX, _positionDragX);
755
+ } else {
756
+ horizontalDrag.css('left', destX);
757
+ _positionDragX(destX);
758
+ }
759
+ }
760
+
761
+ function _positionDragX(destX)
762
+ {
763
+ if (destX === undefined) {
764
+ destX = horizontalDrag.position().left;
765
+ }
766
+
767
+ container.scrollTop(0);
768
+ horizontalDragPosition = destX ||0;
769
+
770
+ var isAtLeft = horizontalDragPosition === 0,
771
+ isAtRight = horizontalDragPosition == dragMaxX,
772
+ percentScrolled = destX / dragMaxX,
773
+ destLeft = -percentScrolled * (contentWidth - paneWidth);
774
+
775
+ if (wasAtLeft != isAtLeft || wasAtRight != isAtRight) {
776
+ wasAtLeft = isAtLeft;
777
+ wasAtRight = isAtRight;
778
+ elem.trigger('jsp-arrow-change', [wasAtTop, wasAtBottom, wasAtLeft, wasAtRight]);
779
+ }
780
+
781
+ updateHorizontalArrows(isAtLeft, isAtRight);
782
+ pane.css('left', destLeft);
783
+ elem.trigger('jsp-scroll-x', [-destLeft, isAtLeft, isAtRight]).trigger('scroll');
784
+ }
785
+
786
+ function updateVerticalArrows(isAtTop, isAtBottom)
787
+ {
788
+ if (settings.showArrows) {
789
+ arrowUp[isAtTop ? 'addClass' : 'removeClass']('jspDisabled');
790
+ arrowDown[isAtBottom ? 'addClass' : 'removeClass']('jspDisabled');
791
+ }
792
+ }
793
+
794
+ function updateHorizontalArrows(isAtLeft, isAtRight)
795
+ {
796
+ if (settings.showArrows) {
797
+ arrowLeft[isAtLeft ? 'addClass' : 'removeClass']('jspDisabled');
798
+ arrowRight[isAtRight ? 'addClass' : 'removeClass']('jspDisabled');
799
+ }
800
+ }
801
+
802
+ function scrollToY(destY, animate)
803
+ {
804
+ var percentScrolled = destY / (contentHeight - paneHeight);
805
+ positionDragY(percentScrolled * dragMaxY, animate);
806
+ }
807
+
808
+ function scrollToX(destX, animate)
809
+ {
810
+ var percentScrolled = destX / (contentWidth - paneWidth);
811
+ positionDragX(percentScrolled * dragMaxX, animate);
812
+ }
813
+
814
+ function scrollToElement(ele, stickToTop, animate)
815
+ {
816
+ var e, eleHeight, eleWidth, eleTop = 0, eleLeft = 0, viewportTop, viewportLeft, maxVisibleEleTop, maxVisibleEleLeft, destY, destX;
817
+
818
+ // Legal hash values aren't necessarily legal jQuery selectors so we need to catch any
819
+ // errors from the lookup...
820
+ try {
821
+ e = $(ele);
822
+ } catch (err) {
823
+ return;
824
+ }
825
+ eleHeight = e.outerHeight();
826
+ eleWidth= e.outerWidth();
827
+
828
+ container.scrollTop(0);
829
+ container.scrollLeft(0);
830
+
831
+ // loop through parents adding the offset top of any elements that are relatively positioned between
832
+ // the focused element and the jspPane so we can get the true distance from the top
833
+ // of the focused element to the top of the scrollpane...
834
+ while (!e.is('.jspPane')) {
835
+ eleTop += e.position().top;
836
+ eleLeft += e.position().left;
837
+ e = e.offsetParent();
838
+ if (/^body|html$/i.test(e[0].nodeName)) {
839
+ // we ended up too high in the document structure. Quit!
840
+ return;
841
+ }
842
+ }
843
+
844
+ viewportTop = contentPositionY();
845
+ maxVisibleEleTop = viewportTop + paneHeight;
846
+ if (eleTop < viewportTop || stickToTop) { // element is above viewport
847
+ destY = eleTop - settings.horizontalGutter;
848
+ } else if (eleTop + eleHeight > maxVisibleEleTop) { // element is below viewport
849
+ destY = eleTop - paneHeight + eleHeight + settings.horizontalGutter;
850
+ }
851
+ if (!isNaN(destY)) {
852
+ scrollToY(destY, animate);
853
+ }
854
+
855
+ viewportLeft = contentPositionX();
856
+ maxVisibleEleLeft = viewportLeft + paneWidth;
857
+ if (eleLeft < viewportLeft || stickToTop) { // element is to the left of viewport
858
+ destX = eleLeft - settings.horizontalGutter;
859
+ } else if (eleLeft + eleWidth > maxVisibleEleLeft) { // element is to the right viewport
860
+ destX = eleLeft - paneWidth + eleWidth + settings.horizontalGutter;
861
+ }
862
+ if (!isNaN(destX)) {
863
+ scrollToX(destX, animate);
864
+ }
865
+
866
+ }
867
+
868
+ function contentPositionX()
869
+ {
870
+ return -pane.position().left;
871
+ }
872
+
873
+ function contentPositionY()
874
+ {
875
+ return -pane.position().top;
876
+ }
877
+
878
+ function isCloseToBottom()
879
+ {
880
+ var scrollableHeight = contentHeight - paneHeight;
881
+ return (scrollableHeight > 20) && (scrollableHeight - contentPositionY() < 10);
882
+ }
883
+
884
+ function isCloseToRight()
885
+ {
886
+ var scrollableWidth = contentWidth - paneWidth;
887
+ return (scrollableWidth > 20) && (scrollableWidth - contentPositionX() < 10);
888
+ }
889
+
890
+ function initMousewheel()
891
+ {
892
+ container.unbind(mwEvent).bind(
893
+ mwEvent,
894
+ function (event, delta, deltaX, deltaY) {
895
+
896
+ if (!horizontalDragPosition) horizontalDragPosition = 0;
897
+ if (!verticalDragPosition) verticalDragPosition = 0;
898
+
899
+ var dX = horizontalDragPosition, dY = verticalDragPosition, factor = event.deltaFactor || settings.mouseWheelSpeed;
900
+ jsp.scrollBy(deltaX * factor, -deltaY * factor, false);
901
+ // return true if there was no movement so rest of screen can scroll
902
+ return dX == horizontalDragPosition && dY == verticalDragPosition;
903
+ }
904
+ );
905
+ }
906
+
907
+ function removeMousewheel()
908
+ {
909
+ container.unbind(mwEvent);
910
+ }
911
+
912
+ function nil()
913
+ {
914
+ return false;
915
+ }
916
+
917
+ function initFocusHandler()
918
+ {
919
+ pane.find(':input,a').unbind('focus.jsp').bind(
920
+ 'focus.jsp',
921
+ function(e)
922
+ {
923
+ scrollToElement(e.target, false);
924
+ }
925
+ );
926
+ }
927
+
928
+ function removeFocusHandler()
929
+ {
930
+ pane.find(':input,a').unbind('focus.jsp');
931
+ }
932
+
933
+ function initKeyboardNav()
934
+ {
935
+ var keyDown, elementHasScrolled, validParents = [];
936
+ isScrollableH && validParents.push(horizontalBar[0]);
937
+ isScrollableV && validParents.push(verticalBar[0]);
938
+
939
+ // IE also focuses elements that don't have tabindex set.
940
+ pane.focus(
941
+ function()
942
+ {
943
+ elem.focus();
944
+ }
945
+ );
946
+
947
+ elem.attr('tabindex', 0)
948
+ .unbind('keydown.jsp keypress.jsp')
949
+ .bind(
950
+ 'keydown.jsp',
951
+ function(e)
952
+ {
953
+ if (e.target !== this && !(validParents.length && $(e.target).closest(validParents).length)){
954
+ return;
955
+ }
956
+ var dX = horizontalDragPosition, dY = verticalDragPosition;
957
+ switch(e.keyCode) {
958
+ case 40: // down
959
+ case 38: // up
960
+ case 34: // page down
961
+ case 32: // space
962
+ case 33: // page up
963
+ case 39: // right
964
+ case 37: // left
965
+ keyDown = e.keyCode;
966
+ keyDownHandler();
967
+ break;
968
+ case 35: // end
969
+ scrollToY(contentHeight - paneHeight);
970
+ keyDown = null;
971
+ break;
972
+ case 36: // home
973
+ scrollToY(0);
974
+ keyDown = null;
975
+ break;
976
+ }
977
+
978
+ elementHasScrolled = e.keyCode == keyDown && dX != horizontalDragPosition || dY != verticalDragPosition;
979
+ return !elementHasScrolled;
980
+ }
981
+ ).bind(
982
+ 'keypress.jsp', // For FF/ OSX so that we can cancel the repeat key presses if the JSP scrolls...
983
+ function(e)
984
+ {
985
+ if (e.keyCode == keyDown) {
986
+ keyDownHandler();
987
+ }
988
+ return !elementHasScrolled;
989
+ }
990
+ );
991
+
992
+ if (settings.hideFocus) {
993
+ elem.css('outline', 'none');
994
+ if ('hideFocus' in container[0]){
995
+ elem.attr('hideFocus', true);
996
+ }
997
+ } else {
998
+ elem.css('outline', '');
999
+ if ('hideFocus' in container[0]){
1000
+ elem.attr('hideFocus', false);
1001
+ }
1002
+ }
1003
+
1004
+ function keyDownHandler()
1005
+ {
1006
+ var dX = horizontalDragPosition, dY = verticalDragPosition;
1007
+ switch(keyDown) {
1008
+ case 40: // down
1009
+ jsp.scrollByY(settings.keyboardSpeed, false);
1010
+ break;
1011
+ case 38: // up
1012
+ jsp.scrollByY(-settings.keyboardSpeed, false);
1013
+ break;
1014
+ case 34: // page down
1015
+ case 32: // space
1016
+ jsp.scrollByY(paneHeight * settings.scrollPagePercent, false);
1017
+ break;
1018
+ case 33: // page up
1019
+ jsp.scrollByY(-paneHeight * settings.scrollPagePercent, false);
1020
+ break;
1021
+ case 39: // right
1022
+ jsp.scrollByX(settings.keyboardSpeed, false);
1023
+ break;
1024
+ case 37: // left
1025
+ jsp.scrollByX(-settings.keyboardSpeed, false);
1026
+ break;
1027
+ }
1028
+
1029
+ elementHasScrolled = dX != horizontalDragPosition || dY != verticalDragPosition;
1030
+ return elementHasScrolled;
1031
+ }
1032
+ }
1033
+
1034
+ function removeKeyboardNav()
1035
+ {
1036
+ elem.attr('tabindex', '-1')
1037
+ .removeAttr('tabindex')
1038
+ .unbind('keydown.jsp keypress.jsp');
1039
+ }
1040
+
1041
+ function observeHash()
1042
+ {
1043
+ if (location.hash && location.hash.length > 1) {
1044
+ var e,
1045
+ retryInt,
1046
+ hash = escape(location.hash.substr(1)) // hash must be escaped to prevent XSS
1047
+ ;
1048
+ try {
1049
+ e = $('#' + hash + ', a[name="' + hash + '"]');
1050
+ } catch (err) {
1051
+ return;
1052
+ }
1053
+
1054
+ if (e.length && pane.find(hash)) {
1055
+ // nasty workaround but it appears to take a little while before the hash has done its thing
1056
+ // to the rendered page so we just wait until the container's scrollTop has been messed up.
1057
+ if (container.scrollTop() === 0) {
1058
+ retryInt = setInterval(
1059
+ function()
1060
+ {
1061
+ if (container.scrollTop() > 0) {
1062
+ scrollToElement(e, true);
1063
+ $(document).scrollTop(container.position().top);
1064
+ clearInterval(retryInt);
1065
+ }
1066
+ },
1067
+ 50
1068
+ );
1069
+ } else {
1070
+ scrollToElement(e, true);
1071
+ $(document).scrollTop(container.position().top);
1072
+ }
1073
+ }
1074
+ }
1075
+ }
1076
+
1077
+ function hijackInternalLinks()
1078
+ {
1079
+ // only register the link handler once
1080
+ if ($(document.body).data('jspHijack')) {
1081
+ return;
1082
+ }
1083
+
1084
+ // remember that the handler was bound
1085
+ $(document.body).data('jspHijack', true);
1086
+
1087
+ // use live handler to also capture newly created links
1088
+ $(document.body).delegate('a[href*=#]', 'click', function(event) {
1089
+ // does the link point to the same page?
1090
+ // this also takes care of cases with a <base>-Tag or Links not starting with the hash #
1091
+ // e.g. <a href="index.html#test"> when the current url already is index.html
1092
+ var href = this.href.substr(0, this.href.indexOf('#')),
1093
+ locationHref = location.href,
1094
+ hash,
1095
+ element,
1096
+ container,
1097
+ jsp,
1098
+ scrollTop,
1099
+ elementTop;
1100
+ if (location.href.indexOf('#') !== -1) {
1101
+ locationHref = location.href.substr(0, location.href.indexOf('#'));
1102
+ }
1103
+ if (href !== locationHref) {
1104
+ // the link points to another page
1105
+ return;
1106
+ }
1107
+
1108
+ // check if jScrollPane should handle this click event
1109
+ hash = escape(this.href.substr(this.href.indexOf('#') + 1));
1110
+
1111
+ // find the element on the page
1112
+ element;
1113
+ try {
1114
+ element = $('#' + hash + ', a[name="' + hash + '"]');
1115
+ } catch (e) {
1116
+ // hash is not a valid jQuery identifier
1117
+ return;
1118
+ }
1119
+
1120
+ if (!element.length) {
1121
+ // this link does not point to an element on this page
1122
+ return;
1123
+ }
1124
+
1125
+ container = element.closest('.jspScrollable');
1126
+ jsp = container.data('jsp');
1127
+
1128
+ // jsp might be another jsp instance than the one, that bound this event
1129
+ // remember: this event is only bound once for all instances.
1130
+ jsp.scrollToElement(element, true);
1131
+
1132
+ if (container[0].scrollIntoView) {
1133
+ // also scroll to the top of the container (if it is not visible)
1134
+ scrollTop = $(window).scrollTop();
1135
+ elementTop = element.offset().top;
1136
+ if (elementTop < scrollTop || elementTop > scrollTop + $(window).height()) {
1137
+ container[0].scrollIntoView();
1138
+ }
1139
+ }
1140
+
1141
+ // jsp handled this event, prevent the browser default (scrolling :P)
1142
+ event.preventDefault();
1143
+ });
1144
+ }
1145
+
1146
+ // Init touch on iPad, iPhone, iPod, Android
1147
+ function initTouch()
1148
+ {
1149
+ var startX,
1150
+ startY,
1151
+ touchStartX,
1152
+ touchStartY,
1153
+ moved,
1154
+ moving = false;
1155
+
1156
+ container.unbind('touchstart.jsp touchmove.jsp touchend.jsp click.jsp-touchclick').bind(
1157
+ 'touchstart.jsp',
1158
+ function(e)
1159
+ {
1160
+ var touch = e.originalEvent.touches[0];
1161
+ startX = contentPositionX();
1162
+ startY = contentPositionY();
1163
+ touchStartX = touch.pageX;
1164
+ touchStartY = touch.pageY;
1165
+ moved = false;
1166
+ moving = true;
1167
+ }
1168
+ ).bind(
1169
+ 'touchmove.jsp',
1170
+ function(ev)
1171
+ {
1172
+ if(!moving) {
1173
+ return;
1174
+ }
1175
+
1176
+ var touchPos = ev.originalEvent.touches[0],
1177
+ dX = horizontalDragPosition, dY = verticalDragPosition;
1178
+
1179
+ jsp.scrollTo(startX + touchStartX - touchPos.pageX, startY + touchStartY - touchPos.pageY);
1180
+
1181
+ moved = moved || Math.abs(touchStartX - touchPos.pageX) > 5 || Math.abs(touchStartY - touchPos.pageY) > 5;
1182
+
1183
+ // return true if there was no movement so rest of screen can scroll
1184
+ return dX == horizontalDragPosition && dY == verticalDragPosition;
1185
+ }
1186
+ ).bind(
1187
+ 'touchend.jsp',
1188
+ function(e)
1189
+ {
1190
+ moving = false;
1191
+ /*if(moved) {
1192
+ return false;
1193
+ }*/
1194
+ }
1195
+ ).bind(
1196
+ 'click.jsp-touchclick',
1197
+ function(e)
1198
+ {
1199
+ if(moved) {
1200
+ moved = false;
1201
+ return false;
1202
+ }
1203
+ }
1204
+ );
1205
+ }
1206
+
1207
+ function destroy(){
1208
+ var currentY = contentPositionY(),
1209
+ currentX = contentPositionX();
1210
+ elem.removeClass('jspScrollable').unbind('.jsp');
1211
+ elem.replaceWith(originalElement.append(pane.children()));
1212
+ originalElement.scrollTop(currentY);
1213
+ originalElement.scrollLeft(currentX);
1214
+
1215
+ // clear reinitialize timer if active
1216
+ if (reinitialiseInterval) {
1217
+ clearInterval(reinitialiseInterval);
1218
+ }
1219
+ }
1220
+
1221
+ // Public API
1222
+ $.extend(
1223
+ jsp,
1224
+ {
1225
+ // Reinitialises the scroll pane (if it's internal dimensions have changed since the last time it
1226
+ // was initialised). The settings object which is passed in will override any settings from the
1227
+ // previous time it was initialised - if you don't pass any settings then the ones from the previous
1228
+ // initialisation will be used.
1229
+ reinitialise: function(s)
1230
+ {
1231
+ s = $.extend({}, settings, s);
1232
+ initialise(s);
1233
+ },
1234
+ // Scrolls the specified element (a jQuery object, DOM node or jQuery selector string) into view so
1235
+ // that it can be seen within the viewport. If stickToTop is true then the element will appear at
1236
+ // the top of the viewport, if it is false then the viewport will scroll as little as possible to
1237
+ // show the element. You can also specify if you want animation to occur. If you don't provide this
1238
+ // argument then the animateScroll value from the settings object is used instead.
1239
+ scrollToElement: function(ele, stickToTop, animate)
1240
+ {
1241
+ scrollToElement(ele, stickToTop, animate);
1242
+ },
1243
+ // Scrolls the pane so that the specified co-ordinates within the content are at the top left
1244
+ // of the viewport. animate is optional and if not passed then the value of animateScroll from
1245
+ // the settings object this jScrollPane was initialised with is used.
1246
+ scrollTo: function(destX, destY, animate)
1247
+ {
1248
+ scrollToX(destX, animate);
1249
+ scrollToY(destY, animate);
1250
+ },
1251
+ // Scrolls the pane so that the specified co-ordinate within the content is at the left of the
1252
+ // viewport. animate is optional and if not passed then the value of animateScroll from the settings
1253
+ // object this jScrollPane was initialised with is used.
1254
+ scrollToX: function(destX, animate)
1255
+ {
1256
+ scrollToX(destX, animate);
1257
+ },
1258
+ // Scrolls the pane so that the specified co-ordinate within the content is at the top of the
1259
+ // viewport. animate is optional and if not passed then the value of animateScroll from the settings
1260
+ // object this jScrollPane was initialised with is used.
1261
+ scrollToY: function(destY, animate)
1262
+ {
1263
+ scrollToY(destY, animate);
1264
+ },
1265
+ // Scrolls the pane to the specified percentage of its maximum horizontal scroll position. animate
1266
+ // is optional and if not passed then the value of animateScroll from the settings object this
1267
+ // jScrollPane was initialised with is used.
1268
+ scrollToPercentX: function(destPercentX, animate)
1269
+ {
1270
+ scrollToX(destPercentX * (contentWidth - paneWidth), animate);
1271
+ },
1272
+ // Scrolls the pane to the specified percentage of its maximum vertical scroll position. animate
1273
+ // is optional and if not passed then the value of animateScroll from the settings object this
1274
+ // jScrollPane was initialised with is used.
1275
+ scrollToPercentY: function(destPercentY, animate)
1276
+ {
1277
+ scrollToY(destPercentY * (contentHeight - paneHeight), animate);
1278
+ },
1279
+ // Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then
1280
+ // the value of animateScroll from the settings object this jScrollPane was initialised with is used.
1281
+ scrollBy: function(deltaX, deltaY, animate)
1282
+ {
1283
+ jsp.scrollByX(deltaX, animate);
1284
+ jsp.scrollByY(deltaY, animate);
1285
+ },
1286
+ // Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then
1287
+ // the value of animateScroll from the settings object this jScrollPane was initialised with is used.
1288
+ scrollByX: function(deltaX, animate)
1289
+ {
1290
+ var destX = contentPositionX() + Math[deltaX<0 ? 'floor' : 'ceil'](deltaX),
1291
+ percentScrolled = destX / (contentWidth - paneWidth);
1292
+ positionDragX(percentScrolled * dragMaxX, animate);
1293
+ },
1294
+ // Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then
1295
+ // the value of animateScroll from the settings object this jScrollPane was initialised with is used.
1296
+ scrollByY: function(deltaY, animate)
1297
+ {
1298
+ var destY = contentPositionY() + Math[deltaY<0 ? 'floor' : 'ceil'](deltaY),
1299
+ percentScrolled = destY / (contentHeight - paneHeight);
1300
+ positionDragY(percentScrolled * dragMaxY, animate);
1301
+ },
1302
+ // Positions the horizontal drag at the specified x position (and updates the viewport to reflect
1303
+ // this). animate is optional and if not passed then the value of animateScroll from the settings
1304
+ // object this jScrollPane was initialised with is used.
1305
+ positionDragX: function(x, animate)
1306
+ {
1307
+ positionDragX(x, animate);
1308
+ },
1309
+ // Positions the vertical drag at the specified y position (and updates the viewport to reflect
1310
+ // this). animate is optional and if not passed then the value of animateScroll from the settings
1311
+ // object this jScrollPane was initialised with is used.
1312
+ positionDragY: function(y, animate)
1313
+ {
1314
+ positionDragY(y, animate);
1315
+ },
1316
+ // This method is called when jScrollPane is trying to animate to a new position. You can override
1317
+ // it if you want to provide advanced animation functionality. It is passed the following arguments:
1318
+ // * ele - the element whose position is being animated
1319
+ // * prop - the property that is being animated
1320
+ // * value - the value it's being animated to
1321
+ // * stepCallback - a function that you must execute each time you update the value of the property
1322
+ // You can use the default implementation (below) as a starting point for your own implementation.
1323
+ animate: function(ele, prop, value, stepCallback)
1324
+ {
1325
+ var params = {};
1326
+ params[prop] = value;
1327
+ ele.animate(
1328
+ params,
1329
+ {
1330
+ 'duration' : settings.animateDuration,
1331
+ 'easing' : settings.animateEase,
1332
+ 'queue' : false,
1333
+ 'step' : stepCallback
1334
+ }
1335
+ );
1336
+ },
1337
+ // Returns the current x position of the viewport with regards to the content pane.
1338
+ getContentPositionX: function()
1339
+ {
1340
+ return contentPositionX();
1341
+ },
1342
+ // Returns the current y position of the viewport with regards to the content pane.
1343
+ getContentPositionY: function()
1344
+ {
1345
+ return contentPositionY();
1346
+ },
1347
+ // Returns the width of the content within the scroll pane.
1348
+ getContentWidth: function()
1349
+ {
1350
+ return contentWidth;
1351
+ },
1352
+ // Returns the height of the content within the scroll pane.
1353
+ getContentHeight: function()
1354
+ {
1355
+ return contentHeight;
1356
+ },
1357
+ // Returns the horizontal position of the viewport within the pane content.
1358
+ getPercentScrolledX: function()
1359
+ {
1360
+ return contentPositionX() / (contentWidth - paneWidth);
1361
+ },
1362
+ // Returns the vertical position of the viewport within the pane content.
1363
+ getPercentScrolledY: function()
1364
+ {
1365
+ return contentPositionY() / (contentHeight - paneHeight);
1366
+ },
1367
+ // Returns whether or not this scrollpane has a horizontal scrollbar.
1368
+ getIsScrollableH: function()
1369
+ {
1370
+ return isScrollableH;
1371
+ },
1372
+ // Returns whether or not this scrollpane has a vertical scrollbar.
1373
+ getIsScrollableV: function()
1374
+ {
1375
+ return isScrollableV;
1376
+ },
1377
+ // Gets a reference to the content pane. It is important that you use this method if you want to
1378
+ // edit the content of your jScrollPane as if you access the element directly then you may have some
1379
+ // problems (as your original element has had additional elements for the scrollbars etc added into
1380
+ // it).
1381
+ getContentPane: function()
1382
+ {
1383
+ return pane;
1384
+ },
1385
+ // Scrolls this jScrollPane down as far as it can currently scroll. If animate isn't passed then the
1386
+ // animateScroll value from settings is used instead.
1387
+ scrollToBottom: function(animate)
1388
+ {
1389
+ positionDragY(dragMaxY, animate);
1390
+ },
1391
+ // Hijacks the links on the page which link to content inside the scrollpane. If you have changed
1392
+ // the content of your page (e.g. via AJAX) and want to make sure any new anchor links to the
1393
+ // contents of your scroll pane will work then call this function.
1394
+ hijackInternalLinks: $.noop,
1395
+ // Removes the jScrollPane and returns the page to the state it was in before jScrollPane was
1396
+ // initialised.
1397
+ destroy: function()
1398
+ {
1399
+ destroy();
1400
+ }
1401
+ }
1402
+ );
1403
+
1404
+ initialise(s);
1405
+ }
1406
+
1407
+ // Pluginifying code...
1408
+ settings = $.extend({}, $.fn.jScrollPane.defaults, settings);
1409
+
1410
+ // Apply default speed
1411
+ $.each(['arrowButtonSpeed', 'trackClickSpeed', 'keyboardSpeed'], function() {
1412
+ settings[this] = settings[this] || settings.speed;
1413
+ });
1414
+
1415
+ return this.each(
1416
+ function()
1417
+ {
1418
+ var elem = $(this), jspApi = elem.data('jsp');
1419
+ if (jspApi) {
1420
+ jspApi.reinitialise(settings);
1421
+ } else {
1422
+ $("script",elem).filter('[type="text/javascript"],:not([type])').remove();
1423
+ jspApi = new JScrollPane(elem, settings);
1424
+ elem.data('jsp', jspApi);
1425
+ }
1426
+ }
1427
+ );
1428
+ };
1429
+
1430
+ $.fn.jScrollPane.defaults = {
1431
+ showArrows : false,
1432
+ maintainPosition : true,
1433
+ stickToBottom : false,
1434
+ stickToRight : false,
1435
+ clickOnTrack : true,
1436
+ autoReinitialise : false,
1437
+ autoReinitialiseDelay : 500,
1438
+ verticalDragMinHeight : 0,
1439
+ verticalDragMaxHeight : 99999,
1440
+ horizontalDragMinWidth : 0,
1441
+ horizontalDragMaxWidth : 99999,
1442
+ contentWidth : undefined,
1443
+ animateScroll : false,
1444
+ animateDuration : 300,
1445
+ animateEase : 'linear',
1446
+ hijackInternalLinks : false,
1447
+ verticalGutter : 4,
1448
+ horizontalGutter : 4,
1449
+ mouseWheelSpeed : 3,
1450
+ arrowButtonSpeed : 0,
1451
+ arrowRepeatFreq : 50,
1452
+ arrowScrollOnHover : false,
1453
+ trackClickSpeed : 0,
1454
+ trackClickRepeatFreq : 70,
1455
+ verticalArrowPositions : 'split',
1456
+ horizontalArrowPositions : 'split',
1457
+ enableKeyboardNavigation : true,
1458
+ hideFocus : false,
1459
+ keyboardSpeed : 0,
1460
+ initialDelay : 300, // Delay before starting repeating
1461
+ speed : 30, // Default speed when others falsey
1462
+ scrollPagePercent : .8 // Percent of visible area scrolled when pageUp/Down or track area pressed
1463
+ };
1464
+
1465
+ }));