

var Scroller = Class.create();
Scroller.ids = new Object();
Scroller.i = 0;
Scroller.prototype = {
/*
constructor: initialize 
Wrap the passed div in a scrollpane.
parameters: 
el - the div to add a scrollbar to.
*/
initialize: function(el) {
this.outerBox = el;
this.decorate();
},
/*
function: decorate 
create the necessary elements to implement the scrollbar and wire up events.
*/
decorate: function() {
$(this.outerBox).makePositioned(); // Fix IE
// Seed a unique ID
Scroller.i = Scroller.i + 1;
this.myIndex = Scroller.i;
//wrap the existing content in an intermediate inner box
this.innerBox = document.createElement("DIV");
this.innerBox.className="scroll-innerBox";
$(this.innerBox).makePositioned(); // Fix IE
this.innerBox.style.cssFloat=this.innerBox.style.styleFloat='left'; // Need the scrollbar to appear next to the scrollpane
this.innerBox.id="scroll-innerBox-"+Scroller.i;
this.innerBox.style.top = "0px";
//Transfer the contents of Outer Box to Inner Box
while (this.outerBox.hasChildNodes()) {
this.innerBox.appendChild(this.outerBox.firstChild);
}
this.innerBox.style.overflow="hidden";
//turn off scrolling on the outer div
this.outerBox.style.overflow="hidden";
// create a track
this.track=document.createElement('div');
this.track.className="scroll-track";
$(this.track).makePositioned();
this.track.style.cssFloat=this.track.style.styleFloat='left';
this.track.id="scroll-track-"+Scroller.i;
// Fix IE line-height bug. Sigh.
this.track.appendChild(document.createComment(''));
// Create the top button
this.tracktop=document.createElement('div');
this.tracktop.className="scroll-track-top";
$(this.tracktop).makePositioned();
this.tracktop.style.cssFloat=this.tracktop.style.styleFloat='left';
this.tracktop.id="scroll-track-top-"+Scroller.i;
// Fix IE line-height bug. Sigh.
this.tracktop.appendChild(document.createComment(''));
// Create the bottom button
this.trackbot=document.createElement('div');
this.trackbot.className="scroll-track-bot";
$(this.trackbot).makePositioned();
this.trackbot.style.cssFloat=this.trackbot.style.styleFloat='left';
this.trackbot.id="scroll-track-bot-"+Scroller.i;
// Fix IE line-height bug. Sigh.
this.trackbot.appendChild(document.createComment(''));
// Create the handle
this.handle=document.createElement('div');
this.handle.className="scroll-handle-container";
this.handle.id="scroll-handle-container"+Scroller.i;
// Create the handle middle
this.handle_middle=document.createElement('div');
this.handle_middle.className="scroll-handle";
$(this.handle_middle).makePositioned();
this.handle_middle.id="scroll-handle-"+Scroller.i;
// Fix IE line-height bug. Sigh.
this.handle_middle.appendChild(document.createComment(''));
// Create the handle top cap
this.handletop=document.createElement('div');
this.handletop.className="scroll-handle-top";
$(this.handletop).makePositioned();
this.handletop.id="scroll-handle-top-"+Scroller.i;
// Fix IE line-height bug. Sigh.
this.handletop.appendChild(document.createComment(''));
// Create the handle bottom cap
this.handlebot=document.createElement('div');
this.handlebot.className="scroll-handle-bot";
$(this.handlebot).makePositioned();
this.handlebot.id="scroll-handle-bot-"+Scroller.i;
// Fix IE line-height bug. Sigh.
this.handlebot.appendChild(document.createComment(''));
this.track.hide();
this.tracktop.hide();
this.trackbot.hide();
this.outerBox.appendChild(this.innerBox);
this.outerBox.appendChild(this.tracktop);
this.handle.appendChild(this.handletop);
this.handle.appendChild(this.handle_middle);
this.handle.appendChild(this.handlebot);
this.track.appendChild(this.handle);
this.outerBox.appendChild(this.track);
this.outerBox.appendChild(this.trackbot);
this.slider = new Control.Slider($(this.handle).id, $(this.track).id, {axis:'vertical',
minimum: 0,
maximum: $(this.outerBox).clientHeight});
this.slider.options.onSlide = this.slider.options.onChange = this.onChange.bind(this);
setTimeout(this.resetScrollbar.bind(this, false), 10);
/* Mouse-Event-Handler verschoben */
},
release: function() {
$(this.outerBox).stopObserving('DOMMouseScroll', this.domMouseCB);
$(this.outerBox).stopObserving('mousewheel', this.mouseWheelCB);// IE/Opera
$(this.tracktop).stopObserving('mousedown', this.trackTopCB);
$(this.trackbot).stopObserving('mousedown', this.trackBotCB);
},
/*
function: resetScrollbar 
Re-calculate the geometry of the scrollbar. Typically called from an event handler.
args: 
repeat - if true, set timer to re-calculate to fix IE bug on resize window.
*/
resetScrollbar: function(repeat) {
this.track.hide();
this.tracktop.hide();
this.trackbot.hide();
this.enableScroll = false;
this.innerHeight = $(this.outerBox).clientHeight;
this.innerBox.style.height = this.innerHeight + "px";
var newWidth = $(this.outerBox).clientWidth;
var tth = Element.getStyle(this.tracktop,"height");
if (tth)
tth = tth.replace("px","");
else
tth = 0;
var hth = Element.getStyle(this.handletop,"height");
if (hth)
hth = hth.replace("px","");
else
hth = 0;
if (this.innerHeight < this.innerBox.scrollHeight) {
this.viewportHeight = this.innerHeight - tth*2;
this.slider.trackLength = this.viewportHeight;
this.track.style.height = this.viewportHeight + "px"; 
this.handleHeight = Math.round(this.viewportHeight * this.innerHeight / this.innerBox.scrollHeight); 
if(this.handleHeight < (hth*2))
this.handleHeight = (hth*2);
if (this.handleHeight < 10)
this.handleHeight = 10;
this.handle.style.height = this.handleHeight + "px";
this.handle_middle.style.height = this.handleHeight - hth*2 + "px";
this.handletop.style.height = hth + "px";
this.slider.handleLength = this.handleHeight;
this.track.style.display = 'inline';
this.tracktop.style.display = 'inline';
this.trackbot.style.display = 'inline';
this.ieDecreaseBy = 1; // Firefox seems to have an off-by one error, so allow for it.
if (this.outerBox.currentStyle) {
var borderWidth = this.outerBox.currentStyle["borderWidth"].replace("px","");
if(!isNaN(borderWidth)) {
this.ieDecreaseBy = (borderWidth) * 2;
}
}
newWidth = ($(this.outerBox).clientWidth - $(this.track).clientWidth - this.ieDecreaseBy);
this.enableScroll = true;
/* Verschoben von Z. 151ff */
this.domMouseCB = this.MouseWheelEvent.bindAsEventListener(this, this.slider);
this.mouseWheelCB = this.MouseWheelEvent.bindAsEventListener(this, this.slider);
this.trackTopCB = this.tracktopEvent.bindAsEventListener(this, this.slider);
this.trackBotCB = this.trackbotEvent.bindAsEventListener(this, this.slider);
//Events control
$(this.outerBox).observe('DOMMouseScroll', this.domMouseCB); // Mozilla
$(this.outerBox).observe('mousewheel', this.mouseWheelCB);// IE/Opera
$(this.tracktop).observe('mousedown', this.trackTopCB);
$(this.trackbot).observe('mousedown', this.trackBotCB);
}
//Set the width of of the scrollpane (aka innerBox).
this.innerBox.style.width = newWidth + "px";
//Fix IE resize event Bug 
if(repeat) {
setTimeout(this.resetScrollbar.bind(this, false), 10);
}
},
//Mouse wheel code from http://adomas.org/javascript-mouse-wheel/
MouseWheelEvent: function(event, slider) {
var delta = 0;
if (!event) //For IE.
event = window.event;
if (event.wheelDelta) { //IE/Opera.
delta = event.wheelDelta / 120;
/*if (window.opera) //In Opera 9, delta differs in sign as compared to IE
delta = -delta; But it isn't necessary with Opera v9.51*/
} else if (event.detail) { //Mozilla case
delta = -event.detail / 3;
}
if (delta)
slider.setValueBy(-delta / 10);
Event.stop(event);
},
trackbotEvent: function(event, slider) {
if (Event.isLeftClick(event)) { 
slider.setValueBy(0.2);
Event.stop(event);
}
},
tracktopEvent: function(event, slider) {
if (Event.isLeftClick(event)) {
slider.setValueBy(-0.2);
Event.stop(event);
}
},
/*
function: onChange 
Called when the script.aculo.us slider has changed (i.e. when it has been dragged). Scroll the inner box.
args: 
val - not used.
*/
onChange: function(val) {
if(this.enableScroll)
this.innerBox.scrollTop = Math.round (val * (this.innerBox.scrollHeight-this.innerBox.offsetHeight));
}
}
Scroller.setAll = function () {
$$('.makeScroll').each(function(item) {
Scroller.ids[item.id] = new Scroller(item);
});
}
Scroller.reset = function (body_id) {
if ($(body_id).className.match(new RegExp("(^|\\s)makeScroll(\\s|$)"))) {
if (Scroller.ids[body_id])
Scroller.ids[body_id].release();
Scroller.ids[body_id] = new Scroller($(body_id));
}
}
Scroller.updateAll = function () {
$H(Scroller.ids).each(function(pair) {
Scroller.ids[pair.key].resetScrollbar(true);
});
}
Event.observe(window, "load", Scroller.setAll);
Event.observe(window, "resize", Scroller.updateAll);
