Current File : /home/k/a/r/karenpetzb/www/items/category/7.tar
before.html000060400000011421150714271410006671 0ustar00<!DOCTYPE html>
<html lang="en">
    <head>
		<!-- Thanks to Rob Lifford ( http://www.lifford.org/ ) for the test case -->
        <meta charset="utf-8">
        <title>jScrollPane 2 reinit bug?</title>
        <style type="text/css">
        	body, html {
        		margin: 0;
        		padding: 20px;
        		font-family: Verdana, sans-serif;
        		font-size: 85%;
        		line-height: 1.5;
        	}

        	.float {
        		float: left;
        	}

        	.clear {
        		clear: both;
        	}

        	.scroll-container {
        		width: 400px;
        		height: 200px;
        		overflow: auto;
        		margin: 0 2em 1.5em 0;
        	}

        	.fluid-width {
        		width: 100%;
        	}

        	.padded {
        		padding: 5px;
        	}

        	ul {
        		margin: 0;
        		padding: 0;
        		line-height: 1;
        		list-style: none;
        		border-bottom: solid 1px #ccc;
        	}

        	li {
        		margin: 0;
        		padding: 10px 5px;
        		border-top: solid 1px #ccc;
        	}

        </style>
        <link rel="stylesheet" type="text/css" href="jscrollpane-2b1.css" />

        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>

        <script type="text/javascript" src="jscrollpane-2b2.js"></script>

        <script type="text/javascript">
			$(function()
			{
				var element = $('.scroll-container').jScrollPane();
				var api = element.data('jsp');

				$('#jsp').click(function() {
					elem = $('.scroll-container').jScrollPane();
				});

				$('#api').click(function() {
					api.reinitialise();
				});

			});
        </script>

    </head>
    <body>

	<div class="scroll-container float">
		<ul>
			<li><strong>scrollable list box</strong></li>
			<li>list item</li>

			<li>another list item</li>
			<li>the next list item</li>
			<li>list item</li>
			<li>another list item</li>
			<li>the next list item</li>
			<li>list item</li>

			<li>another list item</li>
			<li>the next list item</li>
			<li>list item</li>
			<li>another list item</li>
			<li>the next list item</li>
			<li>the next list item</li>

			<li>list item</li>
			<li>another list item</li>
			<li>the next list item</li>
			<li>the next list item</li>
			<li>list item</li>
			<li>another list item</li>

			<li>the next list item</li>
		</ul>
	</div>

	<div class="scroll-container float">
		<ul>
			<li><strong>scrollable list box</strong></li>
			<li>list item</li>

			<li>another list item</li>
		</ul>
	</div>

	<div class="scroll-container padded clear">
		<ul>
			<li><strong>scrollable list box</strong></li>
			<li>list item</li>

			<li>another list item</li>
			<li>the next list item</li>
			<li>list item</li>
			<li>another list item</li>
			<li>the next list item</li>
			<li>list item</li>

			<li>another list item</li>
			<li>the next list item</li>
			<li>list item</li>
			<li>another list item</li>
			<li>the next list item</li>
			<li>the next list item</li>

			<li>list item</li>
			<li>another list item</li>
			<li>the next list item</li>
			<li>the next list item</li>
			<li>list item</li>
			<li>another list item</li>

			<li>the next list item</li>
		</ul>
	</div>

	<div class="scroll-container fluid-width clear">
		<ul>
			<li><strong>scrollable list box</strong></li>
			<li>list item</li>

			<li>another list item</li>
			<li>the next list item</li>
			<li>list item</li>
			<li>another list item</li>
			<li>the next list item</li>
			<li>list item</li>

			<li>another list item</li>
			<li>the next list item</li>
			<li>list item</li>
			<li>another list item</li>
			<li>the next list item</li>
			<li>the next list item</li>

			<li>list item</li>
			<li>another list item</li>
			<li>the next list item</li>
			<li>the next list item</li>
			<li>list item</li>
			<li>another list item</li>

			<li>the next list item</li>
		</ul>
	</div>


	<p class="clear"><button id="api">reinit via API</button> <button id="jsp">Reinit by re-calling .jScrollPane</button> </p>

	<p>In the above testcase: reinitialising jScrollPane (either via the api or simply by re-calling .jScrollPane() on the original element) strips out the width of the div.jspPane and causes a rendering issue: the absolutely-positioned div renders only as wide as its text content. The expected behavior is that it'll fill the available width, as it does on page load after the first call to .jScrollPane().</p>


<p><strong>UPDATE:</strong> this is fixed for scrollable content in v2b2, but when the content is not scrollable there's still undesired rendering on first load.</p>

<p>Additionally, padding calculations might need some tweaks. The third list box here is identical to the first two except for an added 5px of padding all the way around: note how the jspVerticalBar is partially pushed out of view.</p>

    </body>
</html>jscrollpane-2b1.css000060400000002617150714271410010160 0ustar00/*
 * CSS Styles that are needed by jScrollPane for it to operate correctly.
 *
 * Include this stylesheet in your site or copy and paste the styles below into your stylesheet - jScrollPane
 * may not operate correctly without them.
 */

.jspContainer
{
	overflow: hidden;
	position: relative;
}

.jspPane
{
	position: absolute;
}

.jspVerticalBar
{
	position: absolute;
	top: 0;
	right: 0;
	width: 16px;
	height: 100%;
	background: red;
}

.jspHorizontalBar
{
	position: absolute;
	bottom: 0;
	left: 0;
	width: 100%;
	height: 16px;
	background: red;
}

.jspVerticalBar *,
.jspHorizontalBar *
{
	margin: 0;
	padding: 0;
}

.jspCap
{
	display: none;
}

.jspHorizontalBar .jspCap
{
	float: left;
}

.jspTrack
{
	background: #dde;
	position: relative;
}

.jspDrag
{
	background: #bbd;
	position: relative;
	top: 0;
	left: 0;
	cursor: pointer;
}

.jspHorizontalBar .jspTrack,
.jspHorizontalBar .jspDrag
{
	float: left;
	height: 100%;
}

.jspArrow
{
	background: #50506d;
	text-indent: -20000px;
	display: block;
	cursor: pointer;
}

.jspArrow.jspDisabled
{
	cursor: default;
	background: #80808d;
}

.jspVerticalBar .jspArrow
{
	height: 16px;
}

.jspHorizontalBar .jspArrow
{
	width: 16px;
	float: left;
	height: 100%;
}

.jspVerticalBar .jspArrow:focus
{
	outline: none;
}

.jspCorner
{
	background: #eeeef4;
	float: left;
	height: 100%;
}

/* Yuk! CSS Hack for IE6 3 pixel bug :( */
* html .jspCorner
{
	margin: 0 -3px 0 0;
}jscrollpane-2b2.js000060400000072635150714271410010014 0ustar00/*!
 * jScrollPane - v2.0.0beta2 - 2010-08-19
 * http://jscrollpane.kelvinluck.com/
 *
 * Copyright (c) 2010 Kelvin Luck
 * Dual licensed under the MIT or GPL licenses.
 */

// Script: jScrollPane - cross browser customisable scrollbars
//
// *Version: 2.0.0beta2, Last updated: 2010-08-19*
//
// Project Home - http://jscrollpane.kelvinluck.com/
// GitHub       - http://github.com/vitch/jScrollPane
// Source       - http://github.com/vitch/jScrollPane/raw/master/script/jquery.jscrollpane.js
// (Minified)   - http://github.com/vitch/jScrollPane/raw/master/script/jquery.jscrollpane.min.js
//
// About: License
//
// Copyright (c) 2010 Kelvin Luck
// Dual licensed under the MIT or GPL Version 2 licenses.
// http://jscrollpane.kelvinluck.com/MIT-LICENSE.txt
// http://jscrollpane.kelvinluck.com/GPL-LICENSE.txt
//
// About: Examples
//
// All examples and demos are available through the jScrollPane example site at:
// http://jscrollpane.kelvinluck.com/
//
// About: Support and Testing
//
// This plugin is tested on the browsers below and has been found to work reliably on them. If you run
// into a problem on one of the supported browsers then please visit the support section on the jScrollPane
// website (http://jscrollpane.kelvinluck.com/) for more information on getting support. You are also
// welcome to fork the project on GitHub if you can contribute a fix for a given issue.
//
// jQuery Versions - 1.4.2
// Browsers Tested - Firefox 3.6.8, Safari 5, Opera 10.6, Chrome 5.0, IE 6, 7, 8
//
// About: Release History
//
// 2.0.0beta2 - (2010-08-19) Bug fixes
// 2.0.0beta1 - (2010-08-17) Rewrite to follow modern best practices and enable horizontal scrolling, initially hidden
//							 elements and dynamically sized elements.
// 1.x - (2006-12-31 - 2010-07-31) Initial version, hosted at googlecode, deprecated

(function($,window,undefined){

	$.fn.jScrollPane = function(settings)
	{
		// JScrollPane "class" - public methods are available through $('selector').data('jsp')
		function JScrollPane(elem, s)
		{

			var settings, jsp = this, pane, paneWidth, paneHeight, container, contentWidth, contentHeight,
				percentInViewH, percentInViewV, isScrollableV, isScrollableH, verticalDrag, dragMaxY,
				verticalDragPosition, horizontalDrag, dragMaxX, horizontalDragPosition,
				verticalBar, verticalTrack, scrollbarWidth, verticalTrackHeight, verticalDragHeight, arrowUp, arrowDown,
				horizontalBar, horizontalTrack, horizontalTrackWidth, horizontalDragWidth, arrowLeft, arrowRight,
				reinitialiseInterval, originalPadding, originalPaddingTotalWidth, previousPaneWidth;

			originalPadding = elem.css('paddingTop') + ' ' +
								elem.css('paddingRight') + ' ' +
								elem.css('paddingBottom') + ' ' +
								elem.css('paddingLeft');
			originalPaddingTotalWidth = (parseInt(elem.css('paddingLeft')) || 0) +
										(parseInt(elem.css('paddingRight')) || 0);

			initialise(s);

			function initialise(s)
			{

				var clonedElem, tempWrapper, /*firstChild, lastChild, */isMaintainingPositon, lastContentX, lastContentY,
						hasContainingSpaceChanged;

				settings = s;

				if (pane == undefined) {

					elem.css(
						{
							'overflow': 'hidden',
							'padding': 0
						}
					);
					// TODO: Deal with where width/ height is 0 as it probably means the element is hidden and we should
					// come back to it later and check once it is unhidden...
					paneWidth = elem.innerWidth() + originalPaddingTotalWidth;
					paneHeight = elem.innerHeight();

					pane = $('<div class="jspPane" />').wrap(
						$('<div class="jspContainer" />')
							.css({
								'width': paneWidth + 'px',
								'height': paneHeight + 'px'
							}
						)
					);

					elem.wrapInner(pane.parent());
					// Need to get the vars after being added to the document, otherwise they reference weird
					// disconnected orphan elements...
					container = elem.find('>.jspContainer');
					pane = container.find('>.jspPane');
					pane.css('padding', originalPadding);

					/*
					// Move any margins from the first and last children up to the container so they can still
					// collapse with neighbouring elements as they would before jScrollPane
					firstChild = pane.find(':first-child');
					lastChild = pane.find(':last-child');
					elem.css(
						{
							'margin-top': firstChild.css('margin-top'),
							'margin-bottom': lastChild.css('margin-bottom')
						}
					);
					firstChild.css('margin-top', 0);
					lastChild.css('margin-bottom', 0);
					*/
				} else {
					hasContainingSpaceChanged = elem.outerWidth() != paneWidth || elem.outerHeight() != paneHeight;

					if (hasContainingSpaceChanged) {
						paneWidth = elem.innerWidth();
						paneHeight = elem.innerHeight();
						container.css({
							'width': paneWidth + 'px',
							'height': paneHeight + 'px'
						});
					}

					previousPaneWidth = pane.innerWidth();
					pane.css('width', null);

					if (!hasContainingSpaceChanged && pane.outerWidth() == contentWidth && pane.outerHeight() == contentHeight) {
						// Nothing has changed since we last initialised
						if (isScrollableH || isScrollableV) { // If we had already set a width then re-set it
							pane.css('width', previousPaneWidth + 'px');
						}
						// Then abort...
						return;
					}

					container.find('>.jspVerticalBar,>.jspHorizontalBar').remove().end();
				}

				// Unfortunately it isn't that easy to find out the width of the element as it will always report the
				// width as allowed by its container, regardless of overflow settings.
				// A cunning workaround is to clone the element, set its position to absolute and place it in a narrow
				// container. Now it will push outwards to its maxium real width...
				clonedElem = pane.clone().css('position', 'absolute');
				tempWrapper = $('<div style="width:1px; position: relative;" />').append(clonedElem);
				$('body').append(tempWrapper);
				contentWidth = Math.max(pane.outerWidth(), clonedElem.outerWidth());
				tempWrapper.remove();

				contentHeight = pane.outerHeight();
				percentInViewH = contentWidth / paneWidth;
				percentInViewV = contentHeight / paneHeight;
				isScrollableV = percentInViewV > 1;

				isScrollableH = percentInViewH > 1;

				//console.log(paneWidth, paneHeight, contentWidth, contentHeight, percentInViewH, percentInViewV, isScrollableH, isScrollableV);

				if (!(isScrollableH || isScrollableV)) {
					elem.removeClass('jspScrollable');
					pane.css('top', 0);
					removeMousewheel();
					removeFocusHandler();
					unhijackInternalLinks();
				} else {
					elem.addClass('jspScrollable');

					isMaintainingPositon = settings.maintainPosition && (verticalDragPosition || horizontalDragPosition);
					if (isMaintainingPositon) {
						lastContentX = contentPositionX();
						lastContentY = contentPositionY();
					}

					initialiseVerticalScroll();
					initialiseHorizontalScroll();
					resizeScrollbars();

					if (isMaintainingPositon) {
						scrollToX(lastContentX);
						scrollToY(lastContentY);
					}

					initFocusHandler();
					observeHash();
					if (settings.hijackInternalLinks) {
						hijackInternalLinks();
					}
				}

				if (settings.autoReinitialise && !reinitialiseInterval) {
					reinitialiseInterval = setInterval(
						function()
						{
							initialise(settings);
						},
						settings.autoReinitialiseDelay
					);
				} else if (!settings.autoReinitialise && reinitialiseInterval) {
					clearInterval(reinitialiseInterval)
				}
			}

			function initialiseVerticalScroll()
			{
				if (isScrollableV) {

					container.append(
						$('<div class="jspVerticalBar" />').append(
							$('<div class="jspCap jspCapTop" />'),
							$('<div class="jspTrack" />').append(
								$('<div class="jspDrag" />').append(
									$('<div class="jspDragTop" />'),
									$('<div class="jspDragBottom" />')
								)
							),
							$('<div class="jspCap jspCapBottom" />')
						)
					);

					verticalBar = container.find('>.jspVerticalBar');
					verticalTrack = verticalBar.find('>.jspTrack');
					verticalDrag = verticalTrack.find('>.jspDrag');

					if (settings.showArrows) {
						arrowUp = $('<a href="#" class="jspArrow jspArrowUp">Scroll up</a>').bind(
							'mousedown.jsp', getArrowScroll(0, -1)
						).bind('click.jsp', nil);
						arrowDown = $('<a href="#" class="jspArrow jspArrowDown">Scroll down</a>').bind(
							'mousedown.jsp', getArrowScroll(0, 1)
						).bind('click.jsp', nil);
						if (settings.arrowScrollOnHover) {
							arrowUp.bind('mouseover.jsp', getArrowScroll(0, -1, arrowUp));
							arrowDown.bind('mouseover.jsp', getArrowScroll(0, 1, arrowDown));
						}

						appendArrows(verticalTrack, settings.verticalArrowPositions, arrowUp, arrowDown);
					}

					verticalTrackHeight = paneHeight;
					container.find('>.jspVerticalBar>.jspCap:visible,>.jspVerticalBar>.jspArrow').each(
						function()
						{
							verticalTrackHeight -= $(this).outerHeight();
						}
					);


					verticalDrag.hover(
						function()
						{
							verticalDrag.addClass('jspHover');
						},
						function()
						{
							verticalDrag.removeClass('jspHover');
						}
					).bind(
						'mousedown.jsp',
						function(e)
						{
							// Stop IE from allowing text selection
							$('html').bind('dragstart.jsp selectstart.jsp', function() { return false; });

							verticalDrag.addClass('jspActive');

							var startY = e.pageY - verticalDrag.position().top;

							$('html').bind(
								'mousemove.jsp',
								function(e)
								{
									positionDragY(e.pageY - startY, false);
								}
							).bind('mouseup.jsp mouseleave.jsp', cancelDrag);
							return false;
						}
					);
					sizeVerticalScrollbar();
					updateVerticalArrows();
					initMousewheel();
				} else {
					// no vertical scroll
					removeMousewheel();
				}
			}

			function sizeVerticalScrollbar()
			{
				verticalTrack.height(verticalTrackHeight + 'px');
				verticalDragPosition = 0;
				scrollbarWidth = settings.verticalGutter + verticalTrack.outerWidth();

				// Make the pane thinner to allow for the vertical scrollbar
				pane.width(paneWidth - scrollbarWidth - originalPaddingTotalWidth);

				// Add margin to the left of the pane if scrollbars are on that side (to position
				// the scrollbar on the left or right set it's left or right property in CSS)
				if (verticalBar.position().left == 0) {
					pane.css('margin-left', scrollbarWidth + 'px');
				}
			}

			function initialiseHorizontalScroll()
			{
				if (isScrollableH) {

					container.append(
						$('<div class="jspHorizontalBar" />').append(
							$('<div class="jspCap jspCapLeft" />'),
							$('<div class="jspTrack" />').append(
								$('<div class="jspDrag" />').append(
									$('<div class="jspDragLeft" />'),
									$('<div class="jspDragRight" />')
								)
							),
							$('<div class="jspCap jspCapRight" />')
						)
					);

					horizontalBar = container.find('>.jspHorizontalBar');
					horizontalTrack = horizontalBar.find('>.jspTrack');
					horizontalDrag = horizontalTrack.find('>.jspDrag');

					if (settings.showArrows) {
						arrowLeft = $('<a href="#" class="jspArrow jspArrowLeft">Scroll left</a>').bind(
							'mousedown.jsp', getArrowScroll(-1, 0)
						).bind('click.jsp', nil);
						arrowRight = $('<a href="#" class="jspArrow jspArrowRight">Scroll right</a>').bind(
							'mousedown.jsp', getArrowScroll(1, 0)
						).bind('click.jsp', nil);
						if (settings.arrowScrollOnHover) {
							arrowLeft.bind('mouseover.jsp', getArrowScroll(-1, 0, arrowLeft));
							arrowRight.bind('mouseover.jsp', getArrowScroll(1, 0, arrowRight));
						}
						appendArrows(horizontalTrack, settings.horizontalArrowPositions, arrowLeft, arrowRight);
					}

					horizontalDrag.hover(
						function()
						{
							horizontalDrag.addClass('jspHover');
						},
						function()
						{
							horizontalDrag.removeClass('jspHover');
						}
					).bind(
						'mousedown.jsp',
						function(e)
						{
							// Stop IE from allowing text selection
							$('html').bind('dragstart.jsp selectstart.jsp', function() { return false; });

							horizontalDrag.addClass('jspActive');

							var startX = e.pageX - horizontalDrag.position().left;

							$('html').bind(
								'mousemove.jsp',
								function(e)
								{
									positionDragX(e.pageX - startX, false);
								}
							).bind('mouseup.jsp mouseleave.jsp', cancelDrag);
							return false;
						}
					);
					horizontalTrackWidth = container.innerWidth();
					sizeHorizontalScrollbar();
					updateHorizontalArrows();
				} else {
					// no horizontal scroll
				}
			}

			function sizeHorizontalScrollbar()
			{

				container.find('>.jspHorizontalBar>.jspCap:visible,>.jspHorizontalBar>.jspArrow').each(
					function()
					{
						horizontalTrackWidth -= $(this).outerWidth();
					}
				);

				horizontalTrack.width(horizontalTrackWidth + 'px');
				horizontalDragPosition = 0;
			}

			function resizeScrollbars()
			{
				if (isScrollableH && isScrollableV) {
					var horizontalTrackHeight = horizontalTrack.outerHeight(),
						verticalTrackWidth = verticalTrack.outerWidth();
					verticalTrackHeight -= horizontalTrackHeight;
					$(horizontalBar).find('>.jspCap:visible,>.jspArrow').each(
						function()
						{
							horizontalTrackWidth += $(this).outerWidth();
						}
					);
					horizontalTrackWidth -= verticalTrackWidth;
					paneHeight -= verticalTrackWidth;
					paneWidth -= horizontalTrackHeight;
					horizontalTrack.parent().append(
						$('<div class="jspCorner" />').css('width', horizontalTrackHeight + 'px')
					);
					sizeVerticalScrollbar();
					sizeHorizontalScrollbar();
				}
				// reflow content
				if (isScrollableH) {
					pane.width((container.outerWidth() - originalPaddingTotalWidth) + 'px');
				}
				contentHeight = pane.outerHeight();
				percentInViewV = contentHeight / paneHeight;

				if (isScrollableH) {
					horizontalDragWidth = 1 / percentInViewH * horizontalTrackWidth;
					if (horizontalDragWidth > settings.horizontalDragMaxWidth) {
						horizontalDragWidth = settings.horizontalDragMaxWidth;
					} else if (horizontalDragWidth < settings.horizontalDragMinWidth) {
						horizontalDragWidth = settings.horizontalDragMinWidth;
					}
					horizontalDrag.width(horizontalDragWidth + 'px');
					dragMaxX = horizontalTrackWidth - horizontalDragWidth;
				}
				if (isScrollableV) {
					verticalDragHeight = 1 / percentInViewV * verticalTrackHeight;
					if (verticalDragHeight > settings.verticalDragMaxHeight) {
						verticalDragHeight = settings.verticalDragMaxHeight;
					} else if (verticalDragHeight < settings.verticalDragMinHeight) {
						verticalDragHeight = settings.verticalDragMinHeight;
					}
					verticalDrag.height(verticalDragHeight + 'px');
					dragMaxY = verticalTrackHeight - verticalDragHeight;
				}
			}

			function appendArrows(ele, p, a1, a2)
			{
				var p1 = "before", p2 = "after", aTemp;

				// Sniff for mac... Is there a better way to determine whether the arrows would naturally appear
				// at the top or the bottom of the bar?
				if (p == "os") {
					p = /Mac/.test(navigator.platform) ? "after" : "split";
				}
				if (p == p1) {
					p2 = p;
				} else if (p == p2) {
					p1 = p;
					aTemp = a1;
					a1 = a2;
					a2 = aTemp;
				}

				ele[p1](a1)[p2](a2);
			}

			function getArrowScroll(dirX, dirY, ele) {
				return function()
				{
					arrowScroll(dirX, dirY, this, ele);
					this.blur();
					return false;
				}
			}

			function arrowScroll(dirX, dirY, arrow, ele)
			{
				arrow = $(arrow).addClass('jspActive');

				var eve, doScroll = function()
					{
						if (dirX != 0) {
							positionDragX(horizontalDragPosition + dirX * settings.arrowButtonSpeed, false);
						}
						if (dirY != 0) {
							positionDragY(verticalDragPosition + dirY * settings.arrowButtonSpeed, false);
						}
					},
					scrollInt = setInterval(doScroll, settings.arrowRepeatFreq);

				doScroll();

				eve = ele == undefined ? 'mouseup.jsp' : 'mouseout.jsp';
				ele = ele || $('html');
				ele.bind(
					eve,
					function()
					{
						arrow.removeClass('jspActive');
						clearInterval(scrollInt);
						ele.unbind(eve);
					}
				);
			}

			function cancelDrag()
			{
				$('html').unbind('dragstart.jsp selectstart.jsp mousemove.jsp mouseup.jsp mouseleave.jsp');

				verticalDrag && verticalDrag.removeClass('jspActive');
				horizontalDrag && horizontalDrag.removeClass('jspActive');
			}

			function positionDragY(destY, animate)
			{
				if (!isScrollableV) {
					return;
				}
				if (destY < 0) {
					destY = 0;
				} else if (destY > dragMaxY) {
					destY = dragMaxY;
				}

				// can't just check if(animate) because false is a valid value that could be passed in...
				if (animate == undefined) {
					animate = settings.animateScroll;
				}
				if (animate) {
					jsp.animate(verticalDrag, 'top', destY,	_positionDragY);
				} else {
					verticalDrag.css('top', destY);
					_positionDragY(destY);
				}

			}

			function _positionDragY(destY)
			{
				if (destY == undefined) {
					destY = verticalDrag.position().top;
				}

				container.scrollTop(0);
				verticalDragPosition = destY;

				var isAtTop = verticalDragPosition == 0,
					isAtBottom = verticalDragPosition == dragMaxY,
					percentScrolled = destY/ dragMaxY,
					destTop = -percentScrolled * (contentHeight - paneHeight);

				updateVerticalArrows(isAtTop, isAtBottom);
				pane.css('top', destTop);
				elem.trigger('jsp-scroll-y', [-destTop, isAtTop, isAtBottom]);
			}

			function positionDragX(destX, animate)
			{
				if (!isScrollableH) {
					return;
				}
				if (destX < 0) {
					destX = 0;
				} else if (destX > dragMaxX) {
					destX = dragMaxX;
				}

				if (animate == undefined) {
					animate = settings.animateScroll;
				}
				if (animate) {
					jsp.animate(horizontalDrag, 'left', destX,	_positionDragX);
				} else {
					horizontalDrag.css('left', destX);
					_positionDragX(destX);
				}
			}

			function _positionDragX(destX)
			{
				if (destX == undefined) {
					destX = horizontalDrag.position().left;
				}

				container.scrollTop(0);
				horizontalDragPosition = destX;

				var isAtLeft = horizontalDragPosition == 0,
					isAtRight = horizontalDragPosition == dragMaxY,
					percentScrolled = destX / dragMaxX,
					destLeft = -percentScrolled * (contentWidth - paneWidth);

				updateHorizontalArrows(isAtLeft, isAtRight);
				pane.css('left', destLeft);
				elem.trigger('jsp-scroll-x', [-destLeft, isAtLeft, isAtRight]);
			}

			function updateVerticalArrows(isAtTop, isAtBottom)
			{
				if (settings.showArrows) {
					arrowUp[isAtTop ? 'addClass' : 'removeClass']('jspDisabled');
					arrowDown[isAtBottom ? 'addClass' : 'removeClass']('jspDisabled');
				}
			}

			function updateHorizontalArrows(isAtLeft, isAtRight)
			{
				if (settings.showArrows) {
					arrowLeft[isAtLeft ? 'addClass' : 'removeClass']('jspDisabled');
					arrowRight[isAtRight ? 'addClass' : 'removeClass']('jspDisabled');
				}
			}

			function scrollToY(destY, animate)
			{
				var percentScrolled = destY / (contentHeight - paneHeight);
				positionDragY(percentScrolled * dragMaxY, animate);
			}

			function scrollToX(destX, animate)
			{
				var percentScrolled = destX / (contentWidth - paneWidth);
				positionDragX(percentScrolled * dragMaxX, animate);
			}

			function scrollToElement(ele, stickToTop, animate)
			{
				var e, eleHeight, eleTop = 0, viewportTop, maxVisibleEleTop, destY;

				// Legal hash values aren't necessarily legal jQuery selectors so we need to catch any
				// errors from the lookup...
				try {
					e = $(ele);
				} catch (err) {
					return;
				}
				eleHeight = e.outerHeight();

				container.scrollTop(0);

				// loop through parents adding the offset top of any elements that are relatively positioned between
				// the focused element and the jspPane so we can get the true distance from the top
				// of the focused element to the top of the scrollpane...
				while (!e.is('.jspPane')) {
					eleTop += e.position().top;
					e = e.offsetParent();
					if (/^body|html$/i.test(e[0].nodeName)) {
						// we ended up too high in the document structure. Quit!
						return;
					}
				}


				viewportTop = contentPositionY();
				maxVisibleEleTop = viewportTop + paneHeight;
				if (eleTop < viewportTop || stickToTop) { // element is above viewport
					destY = eleTop - settings.verticalGutter;
				} else if (eleTop + eleHeight > maxVisibleEleTop) { // element is below viewport
					destY = eleTop - paneHeight + eleHeight + settings.verticalGutter;
				}
				if (destY) {
					scrollToY(destY, animate);
				}
				// TODO: Implement automatic horizontal scrolling?
			}

			function contentPositionX()
			{
				return -pane.position().left;
			}

			function contentPositionY()
			{
				return -pane.position().top;
			}

			function initMousewheel()
			{
				container.unbind('mousewheel.jsp').bind(
					'mousewheel.jsp',
					function (event, delta) {
						var d = verticalDragPosition;
						positionDragY(verticalDragPosition - delta * settings.mouseWheelSpeed, false);
						// return true if there was no movement so rest of screen can scroll
						return d == verticalDragPosition;
					}
				);
			}

			function removeMousewheel()
			{
				container.unbind('mousewheel.jsp');
			}

			function nil()
			{
				return false;
			}

			function initFocusHandler()
			{
				pane.find(':input,a').bind(
					'focus.jsp',
					function()
					{
						scrollToElement(this, false);
					}
				);
			}

			function removeFocusHandler()
			{

				pane.find(':input,a').unbind('focus.jsp')
			}

			function observeHash()
			{
				if (location.hash && location.hash.length > 1) {
					var e, retryInt;
					try {
						e = $(location.hash);
					} catch (err) {
						return;
					}

					if (e.length && pane.find(e)) {
						// nasty workaround but it appears to take a little while before the hash has done its thing
						// to the rendered page so we just wait until the container's scrollTop has been messed up.
						if (container.scrollTop() == 0) {
							retryInt = setInterval(
								function()
								{
									if (container.scrollTop() > 0) {
										scrollToElement(location.hash, true);
										$(document).scrollTop(container.position().top);
										clearInterval(retryInt);
									}
								},
								50
							)
						} else {
							scrollToElement(location.hash, true);
							$(document).scrollTop(container.position().top);
						}
					}
				}
			}

			function unhijackInternalLinks()
			{
				$('a.jspHijack').unbind('click.jsp-hijack').removeClass('jspHijack');
			}

			function hijackInternalLinks()
			{
				unhijackInternalLinks();
				$('a[href^=#]').addClass('jspHijack').bind(
					'click.jsp-hijack',
					function()
					{
						var uriParts = this.href.split('#'), hash;
						if (uriParts.length > 1) {
							hash = uriParts[1];
							if (hash.length > 0 && pane.find('#' + hash).length > 0) {
								scrollToElement('#' + hash, true);
								// Need to return false otherwise things mess up... Would be nice to maybe also scroll
								// the window to the top of the scrollpane?
								return false;
							}
						}
					}
				)
			}

			// Public API
			$.extend(
				jsp,
				{
					// Reinitialises the scroll pane (if it's internal dimensions have changed since the last time it
					// was initialised). The settings object which is passed in will override any settings from the
					// previous time it was initialised - if you don't pass any settings then the ones from the previous
					// initialisation will be used.
					reinitialise: function(s)
					{
						s = $.extend({}, s, settings);
						initialise(s);
					},
					// Scrolls the specified element (a jQuery object, DOM node or jQuery selector string) into view so
					// that it can be seen within the viewport. If stickToTop is true then the element will appear at
					// the top of the viewport, if it is false then the viewport will scroll as little as possible to
					// show the element. You can also specify if you want animation to occur. If you don't provide this
					// argument then the animateScroll value from the settings object is used instead.
					scrollToElement: function(ele, stickToTop, animate)
					{
						scrollToElement(ele, stickToTop, animate);
					},
					// Scrolls the pane so that the specified co-ordinates within the content are at the top left
					// of the viewport. animate is optional and if not passed then the value of animateScroll from
					// the settings object this jScrollPane was initialised with is used.
					scrollTo: function(destX, destY, animate)
					{
						scrollToX(destX, animate);
						scrollToY(destY, animate);
					},
					// Scrolls the pane so that the specified co-ordinate within the content is at the left of the
					// viewport. animate is optional and if not passed then the value of animateScroll from the settings
					// object this jScrollPane was initialised with is used.
					scrollToX: function(destX, animate)
					{
						scrollToX(destX, animate);
					},
					// Scrolls the pane so that the specified co-ordinate within the content is at the top of the
					// viewport. animate is optional and if not passed then the value of animateScroll from the settings
					// object this jScrollPane was initialised with is used.
					scrollToY: function(destY, animate)
					{
						scrollToY(destY, animate);
					},
					// Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then
					// the value of animateScroll from the settings object this jScrollPane was initialised with is used.
					scrollBy: function(deltaX, deltaY, animate)
					{
						jsp.scrollByX(deltaX, animate);
						jsp.scrollByY(deltaY, animate);
					},
					// Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then
					// the value of animateScroll from the settings object this jScrollPane was initialised with is used.
					scrollByX: function(deltaX, animate)
					{
						var destX = contentPositionX() + deltaX,
							percentScrolled = destX / (contentWidth - paneWidth);
						positionDragX(percentScrolled * dragMaxX, animate);
					},
					// Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then
					// the value of animateScroll from the settings object this jScrollPane was initialised with is used.
					scrollByY: function(deltaY, animate)
					{
						var destY = contentPositionY() + deltaY,
							percentScrolled = destY / (contentHeight - paneHeight);
						positionDragY(percentScrolled * dragMaxY, animate);
					},
					// This method is called when jScrollPane is trying to animate to a new position. You can override
					// it if you want to provide advanced animation functionality. It is passed the following arguments:
					//  * ele          - the element whose position is being animated
					//  * prop         - the property that is being animated
					//  * value        - the value it's being animated to
					//  * stepCallback - a function that you must execute each time you update the value of the property
					// You can use the default implementation (below) as a starting point for your own implementation.
					animate: function(ele, prop, value, stepCallback)
					{
						var params = {};
						params[prop] = value;
						ele.animate(
							params,
							{
								'duration'	: settings.animateDuration,
								'ease'		: settings.animateEase,
								'queue'		: false,
								'step'		: stepCallback
							}
						);
					},
					// Returns the current x position of the viewport with regards to the content pane.
					getContentPositionX: function()
					{
						return contentPositionX();
					},
					// Returns the current y position of the viewport with regards to the content pane.
					getContentPositionY: function()
					{
						return contentPositionY();
					},
					// Gets a reference to the content pane. It is important that you use this method if you want to
					// edit the content of your jScrollPane as if you access the element directly then you may have some
					// problems (as your original element has had additional elements for the scrollbars etc added into
					// it).
					getContentPane: function()
					{
						return pane;
					},
					// Scrolls this jScrollPane down as far as it can currently scroll. If animate isn't passed then the
					// animateScroll value from settings is used instead.
					scrollToBottom: function(animate)
					{
						positionDragY(dragMaxY, animate);
					},
					// Hijacks the links on the page which link to content inside the scrollpane. If you have changed
					// the content of your page (e.g. via AJAX) and want to make sure any new anchor links to the
					// contents of your scroll pane will work then call this function.
					hijackInternalLinks: function()
					{
						hijackInternalLinks();
					}
				}
			);
		}

		// Pluginifying code...

		settings = $.extend({}, $.fn.jScrollPane.defaults, settings);

		var ret;
		this.each(
			function()
			{
				var elem = $(this), jspApi = elem.data('jsp');
				if (jspApi) {
					jspApi.reinitialise(settings);
				} else {
					jspApi = new JScrollPane(elem, settings);
					elem.data('jsp', jspApi);
				}
				ret = ret ? ret.add(elem) : elem;
			}
		)
		return ret;
	};

	$.fn.jScrollPane.defaults = {
		'showArrows'				: false,
		'maintainPosition'			: true,
		'autoReinitialise'			: false,
		'autoReinitialiseDelay'		: 500,
		'verticalDragMinHeight'		: 0,
		'verticalDragMaxHeight'		: 99999,
		'horizontalDragMinWidth'	: 0,
		'horizontalDragMaxWidth'	: 99999,
		'animateScroll'				: false,
		'animateDuration'			: 300,
		'animateEase'				: 'linear',
		'hijackInternalLinks'		: false,
		'verticalGutter'			: 4,
		'horizontalGutter'			: 4,
		'mouseWheelSpeed'			: 10,
		'arrowButtonSpeed'			: 10,
		'arrowRepeatFreq'			: 100,
		'arrowScrollOnHover'		: false,
		'verticalArrowPositions'	: 'split',
		'horizontalArrowPositions'	: 'split'
	};

})(jQuery,this);

native.html000060400000010562150714271410006722 0ustar00<!DOCTYPE html>
<html lang="en">
    <head>
		<!-- Thanks to Rob Lifford ( http://www.lifford.org/ ) for the test case -->
        <meta charset="utf-8">
        <title>jScrollPane 2 reinit bug?</title>
        <style type="text/css">
        	body, html {
        		margin: 0;
        		padding: 20px;
        		font-family: Verdana, sans-serif;
        		font-size: 85%;
        		line-height: 1.5;
        	}

        	.float {
        		float: left;
        	}

        	.clear {
        		clear: both;
        	}

        	.scroll-container {
        		width: 400px;
        		height: 200px;
        		overflow: auto;
        		margin: 0 2em 1.5em 0;
        	}

        	.fluid-width {
        		width: 100%;
        	}

        	.padded {
        		padding: 5px;
        	}

        	ul {
        		margin: 0;
        		padding: 0;
        		line-height: 1;
        		list-style: none;
        		border-bottom: solid 1px #ccc;
        	}

        	li {
        		margin: 0;
        		padding: 10px 5px;
        		border-top: solid 1px #ccc;
        	}

        </style>
        <link rel="stylesheet" type="text/css" href="jscrollpane-2b1.css" />

        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>

    </head>
    <body>

	<div class="scroll-container float">
		<ul>
			<li><strong>scrollable list box</strong></li>
			<li>list item</li>

			<li>another list item</li>
			<li>the next list item</li>
			<li>list item</li>
			<li>another list item</li>
			<li>the next list item</li>
			<li>list item</li>

			<li>another list item</li>
			<li>the next list item</li>
			<li>list item</li>
			<li>another list item</li>
			<li>the next list item</li>
			<li>the next list item</li>

			<li>list item</li>
			<li>another list item</li>
			<li>the next list item</li>
			<li>the next list item</li>
			<li>list item</li>
			<li>another list item</li>

			<li>the next list item</li>
		</ul>
	</div>

	<div class="scroll-container float">
		<ul>
			<li><strong>scrollable list box</strong></li>
			<li>list item</li>

			<li>another list item</li>
		</ul>
	</div>

	<div class="scroll-container padded clear">
		<ul>
			<li><strong>scrollable list box</strong></li>
			<li>list item</li>

			<li>another list item</li>
			<li>the next list item</li>
			<li>list item</li>
			<li>another list item</li>
			<li>the next list item</li>
			<li>list item</li>

			<li>another list item</li>
			<li>the next list item</li>
			<li>list item</li>
			<li>another list item</li>
			<li>the next list item</li>
			<li>the next list item</li>

			<li>list item</li>
			<li>another list item</li>
			<li>the next list item</li>
			<li>the next list item</li>
			<li>list item</li>
			<li>another list item</li>

			<li>the next list item</li>
		</ul>
	</div>

	<div class="scroll-container fluid-width clear">
		<ul>
			<li><strong>scrollable list box</strong></li>
			<li>list item</li>

			<li>another list item</li>
			<li>the next list item</li>
			<li>list item</li>
			<li>another list item</li>
			<li>the next list item</li>
			<li>list item</li>

			<li>another list item</li>
			<li>the next list item</li>
			<li>list item</li>
			<li>another list item</li>
			<li>the next list item</li>
			<li>the next list item</li>

			<li>list item</li>
			<li>another list item</li>
			<li>the next list item</li>
			<li>the next list item</li>
			<li>list item</li>
			<li>another list item</li>

			<li>the next list item</li>
		</ul>
	</div>


	<p class="clear"><button id="api">reinit via API</button> <button id="jsp">Reinit by re-calling .jScrollPane</button> </p>

	<p>In the above testcase: reinitialising jScrollPane (either via the api or simply by re-calling .jScrollPane() on the original element) strips out the width of the div.jspPane and causes a rendering issue: the absolutely-positioned div renders only as wide as its text content. The expected behavior is that it'll fill the available width, as it does on page load after the first call to .jScrollPane().</p>


<p><strong>UPDATE:</strong> this is fixed for scrollable content in v2b2, but when the content is not scrollable there's still undesired rendering on first load.</p>

<p>Additionally, padding calculations might need some tweaks. The third list box here is identical to the first two except for an added 5px of padding all the way around: note how the jspVerticalBar is partially pushed out of view.</p>

    </body>
</html>index.html000060400000003723150714271410006544 0ustar00<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
		"http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>

		<title>jScrollPane - issue 7</title>

		<!-- styles specific to demo site -->
		<link type="text/css" href="../../style/demo.css" rel="stylesheet" media="all" />

		<!-- latest jQuery direct from google's CDN -->
		<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
		<!-- scripts specific to this demo site -->
		<script type="text/javascript" src="../../script/demo.js"></script>
	</head>
	<body>
		<div id="top-nav">
			<img src="../../image/logo.png" width="196" height="69" alt="jScrollPane">
			<ul>
				<li><a href="../../index.html">Home</a></li>
				<li><a href="../../index.html#examples">Examples</a></li>
				<li><a href="../../index.html#themes">Themes</a></li>
				<li><a href="../../index.html#usage">How to use</a></li>
				<li><a href="../../faqs.html">FAQs</a></li>
				<li><a href="../../known_issues.html">Known issues</a></li>
				<li><a href="../../index.html#support">Support</a></li>
				<li><a href="../../index.html#download">Download</a></li>
			</ul>
		</div>
		<div id="container">
			<h1>jScrollPane - issue 7</h1>
			<p>
				This page demonstrates the bug described in <a href="http://github.com/vitch/jScrollPane/issues#issue/7">
				issue 7</a> as reported (with nice striped down test cases) by <a href="http://rob.lifford.org/">Rob
				Lifford</a>. 
			</p>
			<ul class="link-list">
				<li>
					<a href="before.html">Before</a> - showing the bug as it appears in the version of jScrollPane which
					was current when it was reported.
				</li>
				<li>
					<a href="native.html">Native</a> - showing how the page looks with native scrollbars (i.e. if
					jScrollPane isn't initialised).
				</li>
				<li>
					<a href="after.html">After</a> - showing the page which was displaying the bug with the latest
					version of jScrollPane.
				</li>
			</ul>
		</div>
	</body>
</html>after.html000060400000011456150714271410006540 0ustar00<!DOCTYPE html>
<html lang="en">
    <head>
		<!-- Thanks to Rob Lifford ( http://www.lifford.org/ ) for the test case -->
        <meta charset="utf-8">
        <title>jScrollPane 2 reinit bug?</title>
        <style type="text/css">
        	body, html {
        		margin: 0;
        		padding: 20px;
        		font-family: Verdana, sans-serif;
        		font-size: 85%;
        		line-height: 1.5;
        	}

        	.float {
        		float: left;
        	}

        	.clear {
        		clear: both;
        	}

        	.scroll-container {
        		width: 400px;
        		height: 200px;
        		overflow: auto;
        		margin: 0 2em 1.5em 0;
        	}

        	.fluid-width {
        		width: 100%;
        	}

        	.padded {
        		padding: 5px;
        	}

        	ul {
        		margin: 0;
        		padding: 0;
        		line-height: 1;
        		list-style: none;
        		border-bottom: solid 1px #ccc;
        	}

        	li {
        		margin: 0;
        		padding: 10px 5px;
        		border-top: solid 1px #ccc;
        	}

        </style>
        <link rel="stylesheet" type="text/css" href="../../style/jquery.jscrollpane.css" />

        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>

        <script type="text/javascript" src="../../script/jquery.jscrollpane.js"></script>

        <script type="text/javascript">
			$(function()
			{
				var element = $('.scroll-container').jScrollPane();
				var api = element.data('jsp');

				$('#jsp').click(function() {
					elem = $('.scroll-container').jScrollPane();
				});

				$('#api').click(function() {
					api.reinitialise();
				});

			});
        </script>

    </head>
    <body>

	<div class="scroll-container float">
		<ul>
			<li><strong>scrollable list box</strong></li>
			<li>list item</li>

			<li>another list item</li>
			<li>the next list item</li>
			<li>list item</li>
			<li>another list item</li>
			<li>the next list item</li>
			<li>list item</li>

			<li>another list item</li>
			<li>the next list item</li>
			<li>list item</li>
			<li>another list item</li>
			<li>the next list item</li>
			<li>the next list item</li>

			<li>list item</li>
			<li>another list item</li>
			<li>the next list item</li>
			<li>the next list item</li>
			<li>list item</li>
			<li>another list item</li>

			<li>the next list item</li>
		</ul>
	</div>

	<div class="scroll-container float">
		<ul>
			<li><strong>scrollable list box</strong></li>
			<li>list item</li>

			<li>another list item</li>
		</ul>
	</div>

	<div class="scroll-container padded clear">
		<ul>
			<li><strong>scrollable list box</strong></li>
			<li>list item</li>

			<li>another list item</li>
			<li>the next list item</li>
			<li>list item</li>
			<li>another list item</li>
			<li>the next list item</li>
			<li>list item</li>

			<li>another list item</li>
			<li>the next list item</li>
			<li>list item</li>
			<li>another list item</li>
			<li>the next list item</li>
			<li>the next list item</li>

			<li>list item</li>
			<li>another list item</li>
			<li>the next list item</li>
			<li>the next list item</li>
			<li>list item</li>
			<li>another list item</li>

			<li>the next list item</li>
		</ul>
	</div>

	<div class="scroll-container fluid-width clear">
		<ul>
			<li><strong>scrollable list box</strong></li>
			<li>list item</li>

			<li>another list item</li>
			<li>the next list item</li>
			<li>list item</li>
			<li>another list item</li>
			<li>the next list item</li>
			<li>list item</li>

			<li>another list item</li>
			<li>the next list item</li>
			<li>list item</li>
			<li>another list item</li>
			<li>the next list item</li>
			<li>the next list item</li>

			<li>list item</li>
			<li>another list item</li>
			<li>the next list item</li>
			<li>the next list item</li>
			<li>list item</li>
			<li>another list item</li>

			<li>the next list item</li>
		</ul>
	</div>


	<p class="clear"><button id="api">reinit via API</button> <button id="jsp">Reinit by re-calling .jScrollPane</button> </p>

	<p>In the above testcase: reinitialising jScrollPane (either via the api or simply by re-calling .jScrollPane() on the original element) strips out the width of the div.jspPane and causes a rendering issue: the absolutely-positioned div renders only as wide as its text content. The expected behavior is that it'll fill the available width, as it does on page load after the first call to .jScrollPane().</p>


<p><strong>UPDATE:</strong> this is fixed for scrollable content in v2b2, but when the content is not scrollable there's still undesired rendering on first load.</p>

<p>Additionally, padding calculations might need some tweaks. The third list box here is identical to the first two except for an added 5px of padding all the way around: note how the jspVerticalBar is partially pushed out of view.</p>

    </body>
</html>