// script.aculo.us slider.js v1.8.2, Tue Nov 18 18:30:58 +0100 2008 // Copyright (c) 2005-2008 Marty Haught, Thomas Fuchs // // script.aculo.us is freely distributable under the terms of an MIT-style license. // For details, see the script.aculo.us web site: http://script.aculo.us/ if (!Control) var Control = { }; // options: // axis: 'vertical', or 'horizontal' (default) // // callbacks: // onChange(value) // onSlide(value) Control.Slider = Class.create({ initialize: function(handle, track, options) { var slider = this; if (Object.isArray(handle)) { this.handles = handle.collect( function(e) { return $(e) }); } else { this.handles = [$(handle)]; } this.track = $(track); this.options = options || { }; this.axis = this.options.axis || 'horizontal'; this.increment = this.options.increment || 1; this.step = parseInt(this.options.step || '1'); this.range = this.options.range || $R(0,1); this.value = 0; // assure backwards compat this.values = this.handles.map( function() { return 0 }); this.spans = this.options.spans ? this.options.spans.map(function(s){ return $(s) }) : false; this.options.startSpan = $(this.options.startSpan || null); this.options.endSpan = $(this.options.endSpan || null); this.restricted = this.options.restricted || false; this.maximum = this.options.maximum || this.range.end; this.minimum = this.options.minimum || this.range.start; // Will be used to align the handle onto the track, if necessary this.alignX = parseInt(this.options.alignX || '0'); this.alignY = parseInt(this.options.alignY || '0'); this.trackLength = this.maximumOffset() - this.minimumOffset(); this.handleLength = this.isVertical() ? (this.handles[0].offsetHeight != 0 ? this.handles[0].offsetHeight : this.handles[0].style.height.replace(/px$/,"")) : (this.handles[0].offsetWidth != 0 ? this.handles[0].offsetWidth : this.handles[0].style.width.replace(/px$/,"")); this.active = false; this.dragging = false; this.disabled = false; if (this.options.disabled) this.setDisabled(); // Allowed values array this.allowedValues = this.options.values ? this.options.values.sortBy(Prototype.K) : false; if (this.allowedValues) { this.minimum = this.allowedValues.min(); this.maximum = this.allowedValues.max(); } this.eventMouseDown = this.startDrag.bindAsEventListener(this); this.eventMouseUp = this.endDrag.bindAsEventListener(this); this.eventMouseMove = this.update.bindAsEventListener(this); // Initialize handles in reverse (make sure first handle is active) this.handles.each( function(h,i) { i = slider.handles.length-1-i; slider.setValue(parseFloat( (Object.isArray(slider.options.sliderValue) ? slider.options.sliderValue[i] : slider.options.sliderValue) || slider.range.start), i); h.makePositioned().observe("mousedown", slider.eventMouseDown); }); this.track.observe("mousedown", this.eventMouseDown); document.observe("mouseup", this.eventMouseUp); document.observe("mousemove", this.eventMouseMove); this.initialized = true; }, dispose: function() { var slider = this; Event.stopObserving(this.track, "mousedown", this.eventMouseDown); Event.stopObserving(document, "mouseup", this.eventMouseUp); Event.stopObserving(document, "mousemove", this.eventMouseMove); this.handles.each( function(h) { Event.stopObserving(h, "mousedown", slider.eventMouseDown); }); }, setDisabled: function(){ this.disabled = true; }, setEnabled: function(){ this.disabled = false; }, getNearestValue: function(value){ if (this.allowedValues){ if (value >= this.allowedValues.max()) return(this.allowedValues.max()); if (value <= this.allowedValues.min()) return(this.allowedValues.min()); var offset = Math.abs(this.allowedValues[0] - value); var newValue = this.allowedValues[0]; this.allowedValues.each( function(v) { var currentOffset = Math.abs(v - value); if (currentOffset <= offset){ newValue = v; offset = currentOffset; } }); return newValue; } if (value > this.range.end) return this.range.end; if (value < this.range.start) return this.range.start; return value; }, setValue: function(sliderValue, handleIdx){ if (!this.active) { this.activeHandleIdx = handleIdx || 0; this.activeHandle = this.handles[this.activeHandleIdx]; this.updateStyles(); } handleIdx = handleIdx || this.activeHandleIdx || 0; if (this.initialized && this.restricted) { if ((handleIdx>0) && (sliderValuethis.values[handleIdx+1])) sliderValue = this.values[handleIdx+1]; } sliderValue = this.getNearestValue(sliderValue); this.values[handleIdx] = sliderValue; this.value = this.values[0]; // assure backwards compat this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] = this.translateToPx(sliderValue); this.drawSpans(); if (!this.dragging || !this.event) this.updateFinished(); }, setValueBy: function(delta, handleIdx) { this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta, handleIdx || this.activeHandleIdx || 0); }, translateToPx: function(value) { return Math.round( ((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) * (value - this.range.start)) + "px"; }, translateToValue: function(offset) { return ((offset/(this.trackLength-this.handleLength) * (this.range.end-this.range.start)) + this.range.start); }, getRange: function(range) { var v = this.values.sortBy(Prototype.K); range = range || 0; return $R(v[range],v[range+1]); }, minimumOffset: function(){ return(this.isVertical() ? this.alignY : this.alignX); }, maximumOffset: function(){ return(this.isVertical() ? (this.track.offsetHeight != 0 ? this.track.offsetHeight : this.track.style.height.replace(/px$/,"")) - this.alignY : (this.track.offsetWidth != 0 ? this.track.offsetWidth : this.track.style.width.replace(/px$/,"")) - this.alignX); }, isVertical: function(){ return (this.axis == 'vertical'); }, drawSpans: function() { var slider = this; if (this.spans) $R(0, this.spans.length-1).each(function(r) { slider.setSpan(slider.spans[r], slider.getRange(r)) }); if (this.options.startSpan) this.setSpan(this.options.startSpan, $R(0, this.values.length>1 ? this.getRange(0).min() : this.value )); if (this.options.endSpan) this.setSpan(this.options.endSpan, $R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum)); }, setSpan: function(span, range) { if (this.isVertical()) { span.style.top = this.translateToPx(range.start); span.style.height = this.translateToPx(range.end - range.start + this.range.start); } else { span.style.left = this.translateToPx(range.start); span.style.width = this.translateToPx(range.end - range.start + this.range.start); } }, updateStyles: function() { this.handles.each( function(h){ Element.removeClassName(h, 'selected') }); Element.addClassName(this.activeHandle, 'selected'); }, startDrag: function(event) { if (Event.isLeftClick(event)) { if (!this.disabled){ this.active = true; var handle = Event.element(event); var pointer = [Event.pointerX(event), Event.pointerY(event)]; var track = handle; if (track==this.track) { var offsets = Position.cumulativeOffset(this.track); this.event = event; this.setValue(this.translateToValue( (this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2) )); var offsets = Position.cumulativeOffset(this.activeHandle); this.offsetX = (pointer[0] - offsets[0]); this.offsetY = (pointer[1] - offsets[1]); } else { // find the handle (prevents issues with Safari) while((this.handles.indexOf(handle) == -1) && handle.parentNode) handle = handle.parentNode; if (this.handles.indexOf(handle)!=-1) { this.activeHandle = handle; this.activeHandleIdx = this.handles.indexOf(this.activeHandle); this.updateStyles(); var offsets = Position.cumulativeOffset(this.activeHandle); this.offsetX = (pointer[0] - offsets[0]); this.offsetY = (pointer[1] - offsets[1]); } } } Event.stop(event); } }, update: function(event) { if (this.active) { if (!this.dragging) this.dragging = true; this.draw(event); if (Prototype.Browser.WebKit) window.scrollBy(0,0); Event.stop(event); } }, draw: function(event) { var pointer = [Event.pointerX(event), Event.pointerY(event)]; var offsets = Position.cumulativeOffset(this.track); pointer[0] -= this.offsetX + offsets[0]; pointer[1] -= this.offsetY + offsets[1]; this.event = event; this.setValue(this.translateToValue( this.isVertical() ? pointer[1] : pointer[0] )); if (this.initialized && this.options.onSlide) this.options.onSlide(this.values.length>1 ? this.values : this.value, this); }, endDrag: function(event) { if (this.active && this.dragging) { this.finishDrag(event, true); Event.stop(event); } this.active = false; this.dragging = false; }, finishDrag: function(event, success) { this.active = false; this.dragging = false; this.updateFinished(); }, updateFinished: function() { if (this.initialized && this.options.onChange) this.options.onChange(this.values.length>1 ? this.values : this.value, this); this.event = null; } }); /** * @author Ryan Johnson * @copyright 2008 PersonalGrid Corporation * @package LivePipe UI * @license MIT * @url http://livepipe.net/core * @require prototype.js */ if(typeof(Control) == 'undefined') Control = {}; var $proc = function(proc){ return typeof(proc) == 'function' ? proc : function(){return proc}; }; var $value = function(value){ return typeof(value) == 'function' ? value() : value; }; Object.Event = { extend: function(object){ object._objectEventSetup = function(event_name){ this._observers = this._observers || {}; this._observers[event_name] = this._observers[event_name] || []; }; object.observe = function(event_name,observer){ if(typeof(event_name) == 'string' && typeof(observer) != 'undefined'){ this._objectEventSetup(event_name); if(!this._observers[event_name].include(observer)) this._observers[event_name].push(observer); }else for(var e in event_name) this.observe(e,event_name[e]); }; object.stopObserving = function(event_name,observer){ this._objectEventSetup(event_name); if(event_name && observer) this._observers[event_name] = this._observers[event_name].without(observer); else if(event_name) this._observers[event_name] = []; else this._observers = {}; }; object.observeOnce = function(event_name,outer_observer){ var inner_observer = function(){ outer_observer.apply(this,arguments); this.stopObserving(event_name,inner_observer); }.bind(this); this._objectEventSetup(event_name); this._observers[event_name].push(inner_observer); }; object.notify = function(event_name){ this._objectEventSetup(event_name); var collected_return_values = []; var args = $A(arguments).slice(1); try{ for(var i = 0; i < this._observers[event_name].length; ++i) collected_return_values.push(this._observers[event_name][i].apply(this._observers[event_name][i],args) || null); }catch(e){ if(e == $break) return false; else throw e; } return collected_return_values; }; if(object.prototype){ object.prototype._objectEventSetup = object._objectEventSetup; object.prototype.observe = object.observe; object.prototype.stopObserving = object.stopObserving; object.prototype.observeOnce = object.observeOnce; object.prototype.notify = function(event_name){ if(object.notify){ var args = $A(arguments).slice(1); args.unshift(this); args.unshift(event_name); object.notify.apply(object,args); } this._objectEventSetup(event_name); var args = $A(arguments).slice(1); var collected_return_values = []; try{ if(this.options && this.options[event_name] && typeof(this.options[event_name]) == 'function') collected_return_values.push(this.options[event_name].apply(this,args) || null); for(var i = 0; i < this._observers[event_name].length; ++i) collected_return_values.push(this._observers[event_name][i].apply(this._observers[event_name][i],args) || null); }catch(e){ if(e == $break) return false; else throw e; } return collected_return_values; }; } } }; /* Begin Core Extensions */ //Element.observeOnce Element.addMethods({ observeOnce: function(element,event_name,outer_callback){ var inner_callback = function(){ outer_callback.apply(this,arguments); Element.stopObserving(element,event_name,inner_callback); }; Element.observe(element,event_name,inner_callback); } }); //mouseenter, mouseleave //from http://dev.rubyonrails.org/attachment/ticket/8354/event_mouseenter_106rc1.patch Object.extend(Event, (function() { var cache = Event.cache; function getEventID(element) { if (element._prototypeEventID) return element._prototypeEventID[0]; arguments.callee.id = arguments.callee.id || 1; return element._prototypeEventID = [++arguments.callee.id]; } function getDOMEventName(eventName) { if (eventName && eventName.include(':')) return "dataavailable"; //begin extension if(!Prototype.Browser.IE){ eventName = { mouseenter: 'mouseover', mouseleave: 'mouseout' }[eventName] || eventName; } //end extension return eventName; } function getCacheForID(id) { return cache[id] = cache[id] || { }; } function getWrappersForEventName(id, eventName) { var c = getCacheForID(id); return c[eventName] = c[eventName] || []; } function createWrapper(element, eventName, handler) { var id = getEventID(element); var c = getWrappersForEventName(id, eventName); if (c.pluck("handler").include(handler)) return false; var wrapper = function(event) { if (!Event || !Event.extend || (event.eventName && event.eventName != eventName)) return false; Event.extend(event); handler.call(element, event); }; //begin extension if(!(Prototype.Browser.IE) && ['mouseenter','mouseleave'].include(eventName)){ wrapper = wrapper.wrap(function(proceed,event) { var rel = event.relatedTarget; var cur = event.currentTarget; if(rel && rel.nodeType == Node.TEXT_NODE) rel = rel.parentNode; if(rel && rel != cur && !rel.descendantOf(cur)) return proceed(event); }); } //end extension wrapper.handler = handler; c.push(wrapper); return wrapper; } function findWrapper(id, eventName, handler) { var c = getWrappersForEventName(id, eventName); return c.find(function(wrapper) { return wrapper.handler == handler }); } function destroyWrapper(id, eventName, handler) { var c = getCacheForID(id); if (!c[eventName]) return false; c[eventName] = c[eventName].without(findWrapper(id, eventName, handler)); } function destroyCache() { for (var id in cache) for (var eventName in cache[id]) cache[id][eventName] = null; } if (window.attachEvent) { window.attachEvent("onunload", destroyCache); } return { observe: function(element, eventName, handler) { element = $(element); var name = getDOMEventName(eventName); var wrapper = createWrapper(element, eventName, handler); if (!wrapper) return element; if (element.addEventListener) { element.addEventListener(name, wrapper, false); } else { element.attachEvent("on" + name, wrapper); } return element; }, stopObserving: function(element, eventName, handler) { element = $(element); var id = getEventID(element), name = getDOMEventName(eventName); if (!handler && eventName) { getWrappersForEventName(id, eventName).each(function(wrapper) { element.stopObserving(eventName, wrapper.handler); }); return element; } else if (!eventName) { Object.keys(getCacheForID(id)).each(function(eventName) { element.stopObserving(eventName); }); return element; } var wrapper = findWrapper(id, eventName, handler); if (!wrapper) return element; if (element.removeEventListener) { element.removeEventListener(name, wrapper, false); } else { element.detachEvent("on" + name, wrapper); } destroyWrapper(id, eventName, handler); return element; }, fire: function(element, eventName, memo) { element = $(element); if (element == document && document.createEvent && !element.dispatchEvent) element = document.documentElement; var event; if (document.createEvent) { event = document.createEvent("HTMLEvents"); event.initEvent("dataavailable", true, true); } else { event = document.createEventObject(); event.eventType = "ondataavailable"; } event.eventName = eventName; event.memo = memo || { }; if (document.createEvent) { element.dispatchEvent(event); } else { element.fireEvent(event.eventType, event); } return Event.extend(event); } }; })()); Object.extend(Event, Event.Methods); Element.addMethods({ fire: Event.fire, observe: Event.observe, stopObserving: Event.stopObserving }); Object.extend(document, { fire: Element.Methods.fire.methodize(), observe: Element.Methods.observe.methodize(), stopObserving: Element.Methods.stopObserving.methodize() }); //mouse:wheel (function(){ function wheel(event){ var delta; // normalize the delta if(event.wheelDelta) // IE & Opera delta = event.wheelDelta / 120; else if (event.detail) // W3C delta =- event.detail / 3; if(!delta) return; var custom_event = Event.element(event).fire('mouse:wheel',{ delta: delta }); if(custom_event.stopped){ Event.stop(event); return false; } } document.observe('mousewheel',wheel); document.observe('DOMMouseScroll',wheel); })(); /* End Core Extensions */ //from PrototypeUI var IframeShim = Class.create({ initialize: function() { this.element = new Element('iframe',{ style: 'position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);display:none', src: 'javascript:void(0);', frameborder: 0 }); $(document.body).insert(this.element); }, hide: function() { this.element.hide(); return this; }, show: function() { this.element.show(); return this; }, positionUnder: function(element) { var element = $(element); var offset = element.cumulativeOffset(); var dimensions = element.getDimensions(); this.element.setStyle({ left: offset[0] + 'px', top: offset[1] + 'px', width: dimensions.width + 'px', height: dimensions.height + 'px', zIndex: element.getStyle('zIndex') - 1 }).show(); return this; }, setBounds: function(bounds) { for(prop in bounds) bounds[prop] += 'px'; this.element.setStyle(bounds); return this; }, destroy: function() { if(this.element) this.element.remove(); return this; } }); /** * @author Ryan Johnson * @copyright 2008 PersonalGrid Corporation * @package LivePipe UI * @license MIT * @url http://livepipe.net/control/scrollbar * @require prototype.js, slider.js, livepipe.js */ if(typeof(Prototype) == "undefined") throw "Control.ScrollBar requires Prototype to be loaded."; if(typeof(Control.Slider) == "undefined") throw "Control.ScrollBar requires Control.Slider to be loaded."; if(typeof(Object.Event) == "undefined") throw "Control.ScrollBar requires Object.Event to be loaded."; Control.ScrollBar = Class.create({ initialize: function(container,track,options){ this.enabled = false; this.notificationTimeout = true; this.container = $(container); this.boundMouseWheelEvent = this.onMouseWheel.bindAsEventListener(this); this.boundResizeObserver = this.onWindowResize.bind(this); this.track = $(track); this.handle = this.track.firstDescendant(); this.options = Object.extend({ active_class_name: 'scrolling', apply_active_class_name_to: this.container, notification_timeout_length: 125, handle_minimum_height: 25, scroll_to_smoothing: 0.01, scroll_to_steps: 15, proportional: true, slider_options: {} },options || {}); this.slider = new Control.Slider(this.handle,this.track,Object.extend({ axis: 'vertical', onSlide: this.onChange.bind(this), onChange: this.onChange.bind(this) },this.options.slider_options)); this.recalculateLayout(); Event.observe(window,'resize',this.boundResizeObserver); this.handle.observe('mousedown',function(){ if(this.auto_sliding_executer) this.auto_sliding_executer.stop(); }.bind(this)); }, destroy: function(){ Event.stopObserving(window,'resize',this.boundResizeObserver); }, enable: function(){ this.enabled = true; this.container.observe('mouse:wheel',this.boundMouseWheelEvent); this.slider.setEnabled(); this.track.show(); if(this.options.active_class_name) $(this.options.apply_active_class_name_to).addClassName(this.options.active_class_name); this.notify('enabled'); }, disable: function(){ this.enabled = false; this.container.stopObserving('mouse:wheel',this.boundMouseWheelEvent); this.slider.setDisabled(); this.track.hide(); if(this.options.active_class_name) $(this.options.apply_active_class_name_to).removeClassName(this.options.active_class_name); this.notify('disabled'); this.reset(); }, reset: function(){ this.slider.setValue(0); }, recalculateLayout: function(){ if(this.container.scrollHeight <= this.container.offsetHeight) this.disable(); else{ this.slider.trackLength = this.slider.maximumOffset() - this.slider.minimumOffset(); if(this.options.proportional){ this.handle.style.height = Math.max(this.container.offsetHeight * (this.container.offsetHeight / this.container.scrollHeight),this.options.handle_minimum_height) + 'px'; this.slider.handleLength = this.handle.style.height.replace(/px/,''); } this.enable(); } }, onWindowResize: function(){ this.recalculateLayout(); this.scrollBy(0); }, onMouseWheel: function(event){ if(this.auto_sliding_executer) this.auto_sliding_executer.stop(); this.slider.setValueBy(-(event.memo.delta / 20)); //put in math to account for the window height event.stop(); return false; }, onChange: function(value){ this.container.scrollTop = Math.round(value / this.slider.maximum * (this.container.scrollHeight - this.container.offsetHeight)); if(this.notification_timeout) window.clearTimeout(this.notificationTimeout); this.notificationTimeout = window.setTimeout(function(){ this.notify('change',value); }.bind(this),this.options.notification_timeout_length); }, getCurrentMaximumDelta: function(){ return this.slider.maximum * (this.container.scrollHeight - this.container.offsetHeight); }, getDeltaToElement: function(element){ return this.slider.maximum * ((element.positionedOffset().top + (element.getHeight() / 2)) - (this.container.getHeight() / 2)); }, scrollTo: function(y,animate){ var current_maximum_delta = this.getCurrentMaximumDelta(); if(y == 'top') y = 0; else if(y == 'bottom') { y = current_maximum_delta; } else if(typeof(y) != "number") y = this.getDeltaToElement($(y)); if(this.enabled){ y = Math.max(0,Math.min(y,current_maximum_delta)); if(this.auto_sliding_executer) this.auto_sliding_executer.stop(); var target_value = y / current_maximum_delta; var original_slider_value = this.slider.value; var delta = (target_value - original_slider_value) * current_maximum_delta; if(animate){ this.auto_sliding_executer = new PeriodicalExecuter(function(){ if(Math.round(this.slider.value * 100) / 100 < Math.round(target_value * 100) / 100 || Math.round(this.slider.value * 100) / 100 > Math.round(target_value * 100) / 100){ this.scrollBy(delta / this.options.scroll_to_steps); }else{ this.auto_sliding_executer.stop(); this.auto_sliding_executer = null; if(typeof(animate) == "function") animate(); } }.bind(this),this.options.scroll_to_smoothing); }else this.scrollBy(delta); }else if(typeof(animate) == "function") animate(); }, scrollBy: function(y){ if(!this.enabled) return false; this.slider.setValueBy(y / this.getCurrentMaximumDelta()); } }); Object.Event.extend(Control.ScrollBar); function terms_scroll() { document.observe('dom:loaded',function(){ var scrollbar = new Control.ScrollBar('scrollbar_content','scrollbar_track'); scrollbar.observe('change', function(value) { if(value == 1) { $('continue').disabled = false; scrollbar.stopObserving('change'); } }); /* $('scroll_down_50').observe('click',function(event){ scrollbar.scrollBy(-50); event.stop(); }); $('scroll_up_50').observe('click',function(event){ scrollbar.scrollBy(50); event.stop(); }); $('scroll_top').observe('click',function(event){ scrollbar.scrollTo('top'); event.stop(); }); $('scroll_bottom').observe('click',function(event){ //to animate a scroll operation you can pass true //or a callback that will be called when scrolling is complete scrollbar.scrollTo('bottom',function(){ if(typeof(console) != "undefined") console.log('Finished scrolling to bottom.'); }); event.stop(); }); $('scroll_second').observe('click',function(event){ //you can pass a number or element to scroll to //if you pass an element, it will be centered, unless it is //near the bottom of the container scrollbar.scrollTo($('second_subhead')); event.stop(); }); $('scroll_third').observe('click',function(event){ //passing true will animate the scroll scrollbar.scrollTo($('third_subhead'),true); event.stop(); }); $('scroll_insert').observe('click',function(event){ $('scrollbar_content').insert('<p>Inserted: ' + $('repeat').innerHTML + '</p>'); //you only need to call this if ajax or dom operations modify the layout //this is automatically called when the window resizes scrollbar.recalculateLayout(); event.stop(); }); */ }); }