PageRenderTime 64ms CodeModel.GetById 5ms RepoModel.GetById 0ms app.codeStats 0ms

/ajax/libs/jScrollPane/2.0.0beta11/script/jquery.jscrollpane.js

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