var ScrollBar = Class.create( {
tlog: function () {},
initialize: function( config ) {
this.config = Object.extend( {
min: 0,
max: 100,
height: 100,
zIndex: 100,
style: {},
page_size: 1
}, config );
this.set_range( this.config.min, this.config.max );
this.set_page_size( this.config.page_size );
this.set_height( this.config.height );
if ( typeof(this.config.value) == 'undefined' )
this.config.value = this.config.min;
this.set_value( this.config.value );
if ( ScrollBar.ready )
this.render();
else
ScrollBar.to_render.push( this );
if ( this.config.position )
this.move_to( this.config.position );
},
fire_change_event: function () {
this.scrollbar.fire( 'scrollbar:change' );
},
set_styles: function ( style ) {
if ( typeof(style) != 'undefined' )
this.config.style = style;
this.scrollbar.className = this.config.style.scroll_frame;
this.scroll_border.className = this.config.style.scroll_border;
this.scroll_up.className = this.config.style.scroll_up;
this.scrub_frame.className = this.config.style.scrub_frame;
this.scrub.className = this.config.style.scrub;
this.scroll_down.className = this.config.style.scroll_down;
},
set_range: function( min, max ) {
false;
this.min = min;
this.max = max;
},
set_value: function( value ) {
false;
this.value = value;
this.set_scrub();
},
set_page_size: function ( page_size ) {
false;
this.page_size = page_size;
},
increment: function() {
if( this.value < this.max ) {
this.value ++;
this.fire_change_event();
this.set_scrub();
}
},
decrement: function() {
if( this.value > this.min ) {
this.value --;
this.fire_change_event();
this.set_scrub();
}
},
page_up: function () {
false;
var new_value = this.value - this.page_size;
if ( new_value < 0 )
new_value = 0;
if ( this.value != new_value ) {
this.set_value( new_value );
this.fire_change_event();
}
else
this.set_scrub();
},
page_down: function () {
false;
var new_value = this.value + this.page_size;
if ( new_value >= this.max )
new_value = this.max;
if ( this.value != new_value ) {
this.set_value( new_value );
this.fire_change_event();
}
else
this.set_scrub();
},
move_to: function( position ) {
false;
if ( typeof(this.position) == 'undefined' && typeof(position) == 'undefined' )
position = [0,0];
if ( typeof(position) != 'undefined' )
this.position = position;
if ( !this.is_attached() )
return;
false;
this.scrollbar.style.left = this. position[0] + 'px';
this.scrollbar.style.top = this.position[1] + 'px';
if ( this.blocking_iframe )
this.blocking_iframe.update();
},
set_height: function( height ) {
false;
if ( typeof(height) == 'undefined' )
height = this.height;
else
this.height = height;
if ( !this.is_attached() )
return;
this.scrub_frame.style.height = '0px';
var bar_height = Element.getHeight( this.scrollbar );
this.frame_height = height - bar_height;
false;
this.scrub_frame.style.height = this.frame_height + 'px';
this.scroll_up.hide().show();
this.scroll_down.hide().show();
var min_scrub_height = this.config.scrub_height || Element.getHeight( this.scroll_up );
this.scrub_height = this.frame_height / (this.max - this.min + 1);
if ( this.scrub_height < min_scrub_height )
this.scrub_height = min_scrub_height;
this.set_scrub();
},
is_attached: function() {
if ( this.scrollbar && this.scrollbar.parentNode && this.scrollbar.parentNode.nodeType == 1 )
return true;
return false;
},
set_scrub: function () {
false;
if ( !this.is_attached() )
return;
var range = this.frame_height - this.scrub_height;
var top = ((this.value - this.min) / (this.max - this.min)) * range;
this.scrub.style.top = top + 'px';
this.scrub.style.height = this.scrub_height + 'px';
},
insert: function( parent, where ) {
false;
if ( !this.scrollbar )
return;
if ( this.scrollbar.parentNode )
this.remove();
var content = {};
content[where] = this.scrollbar;
Element.insert( parent, content );
this.move_to();
this.set_height();
},
remove: function() {
false;
if ( !this.is_attached() )
return;
Element.remove( this.scrollbar );
this.scroll_stop();
},
render: function() {
this.scrollbar = new Element( 'div' );
this.scrollbar.style.position = 'absolute';
this.scrollbar.style.zIndex = this.config.zIndex;
this.scroll_border = new Element( 'div' );
this.scroll_border.style.position = 'relative';
this.scroll_up = new Element( 'div' );
this.scroll_up.style.position = 'relative';
this.scrub_frame = new Element( 'div' );
this.scrub_frame.style.position = 'relative';
this.scrub = new Element( 'div' );
this.scrub.style.position = 'absolute';
this.scrub.style.zIndex = 1;
this.scroll_down = new Element( 'div' );
this.scroll_down.style.position = 'relative';
this.scrollbar.appendChild( this.scroll_border );
this.scroll_border.appendChild( this.scroll_up );
this.scroll_border.appendChild( this.scrub_frame );
this.scroll_border.appendChild( this.scroll_down );
this.scrub_frame.appendChild( this.scrub );
this.set_styles();
if ( is_IE6 ) {
var iframe = new BlockingIframe( this.scrollbar );
this.blocking_iframe = iframe;
}
Event.observe( this.scroll_up, 'mousedown', this.scroll_up_start.bind( this ) );
Event.observe( this.scroll_up, 'mouseup', this.scroll_stop.bind( this ) );
Event.observe( this.scroll_down, 'mousedown', this.scroll_down_start.bind( this ) );
Event.observe( this.scroll_down, 'mouseup', this.scroll_stop.bind( this ) );
Event.observe( this.scrub, 'mousedown', this.start_scrub_drag.bind( this ) );
Event.observe( this.scrub_frame, 'click', this.page_scrub.bind( this ) );
if ( this.config.insert )
this.insert.apply( this, this.config.insert );
},
page_scrub: function ( event ) {
false;
var frameY = Element.cumulativeOffset( this.scrub_frame )[1];
var frame_height = Element.getHeight( this.scrub_frame );
var scrubY = Element.cumulativeOffset( this.scrub )[1];
var scrub_height = Element.getHeight( this.scrub );
var pointerY = event.pointerY();
false;
if ( frameY <= pointerY && pointerY < scrubY )
this.page_up();
else if ( scrubY + scrub_height <= pointerY && pointerY < frameY + frame_height )
this.page_down();
},
start_scrub_drag: function( event ) {
false;
this.pointerY = event.pointerY();
this.scrubY = this.scrub.offsetTop;
this.drag_function = this.drag_scrub.bind( this );
this.stop_drag_function = this.stop_scrub_drag.bind( this );
Event.observe( document.body, 'mousemove', this.drag_function );
Event.observe( document.body, 'mouseup', this.stop_drag_function );
this.scrub.className = this.config.style.scrub_active;
},
drag_scrub: function ( event ) {
false;
var newY = this.scrubY + event.pointerY() - this.pointerY;
if ( newY < 0 )
newY = 0;
var frame_height = Element.getHeight( this.scrub_frame ) - Element.getHeight( this.scrub );
if ( newY > frame_height )
newY = frame_height;
this.scrub.style.top = newY + 'px';
this.value = this.min + Math.round( (this.max - this.min) * (newY / frame_height ) );
this.fire_change_event();
Event.stop( event );
},
stop_scrub_drag: function( event ) {
false;
Event.stopObserving( document.body, 'mousemove', this.drag_function );
Event.stopObserving( document.body, 'mouseup', this.stop_drag_function );
this.scrub.className = this.config.style.scrub;
},
set_scroll_speed: function() {
false;
if ( !this.speed ) {
this.speed = 1000;
this.scroll_count = 0;
}
this.scroll_count ++;
if ( this.scroll_count == 1 )
this.speed = 200;
if ( !(this.scroll_count % 5) )
this.speed -= 10;
if ( this.speed < 50 )
this.speed = 50;
},
get_dimensions: function() {
return this.scrollbar.getDimensions();
},
scroll_up_start: function( event ) {
this.scroll_up.className = this.config.style.scroll_up_active;
this.decrement();
this.set_scroll_speed();
this.next = window.setTimeout( this.scroll_up_start.bind( this ), this.speed );
},
scroll_stop: function( event ) {
window.clearTimeout( this.next );
this.speed = 0;
this.scroll_up.className = this.config.style.scroll_up;
this.scroll_down.className = this.config.style.scroll_down;
},
scroll_down_start: function( event ) {
this.scroll_down.className = this.config.style.scroll_down_active;
this.increment();
this.set_scroll_speed();
this.next = window.setTimeout( this.scroll_down_start.bind( this ), this.speed );
}
} );
ScrollBar.to_render = [];
Element.observe( window, 'load', function () {
ScrollBar.to_render.each( function( widget ) { widget.render(); } );
ScrollBar.ready = true;
} );
