From b7806c12ce397f0daf766d13ff2f74528cd4b3f5 Mon Sep 17 00:00:00 2001 From: Jacques Distler Date: Sat, 9 Oct 2010 21:54:38 -0500 Subject: [PATCH] Update Scriptaculous to 1.8.3. Perhaps this will fix Marco's bug (which I cannot reproduce). --- public/javascripts/builder.js | 136 +++++++++++ public/javascripts/controls.js | 8 +- public/javascripts/dragdrop.js | 13 +- public/javascripts/effects.js | 21 +- public/javascripts/scriptaculous.js | 67 +++-- public/javascripts/slider.js | 367 +++++++++++++++------------- 6 files changed, 392 insertions(+), 220 deletions(-) create mode 100644 public/javascripts/builder.js diff --git a/public/javascripts/builder.js b/public/javascripts/builder.js new file mode 100644 index 00000000..f1f42b9a --- /dev/null +++ b/public/javascripts/builder.js @@ -0,0 +1,136 @@ +// script.aculo.us builder.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009 + +// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// +// 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/ + +var Builder = { + NODEMAP: { + AREA: 'map', + CAPTION: 'table', + COL: 'table', + COLGROUP: 'table', + LEGEND: 'fieldset', + OPTGROUP: 'select', + OPTION: 'select', + PARAM: 'object', + TBODY: 'table', + TD: 'table', + TFOOT: 'table', + TH: 'table', + THEAD: 'table', + TR: 'table' + }, + // note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken, + // due to a Firefox bug + node: function(elementName) { + elementName = elementName.toUpperCase(); + + // try innerHTML approach + var parentTag = this.NODEMAP[elementName] || 'div'; + var parentElement = document.createElement(parentTag); + try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707 + parentElement.innerHTML = "<" + elementName + ">"; + } catch(e) {} + var element = parentElement.firstChild || null; + + // see if browser added wrapping tags + if(element && (element.tagName.toUpperCase() != elementName)) + element = element.getElementsByTagName(elementName)[0]; + + // fallback to createElement approach + if(!element) element = document.createElement(elementName); + + // abort if nothing could be created + if(!element) return; + + // attributes (or text) + if(arguments[1]) + if(this._isStringOrNumber(arguments[1]) || + (arguments[1] instanceof Array) || + arguments[1].tagName) { + this._children(element, arguments[1]); + } else { + var attrs = this._attributes(arguments[1]); + if(attrs.length) { + try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707 + parentElement.innerHTML = "<" +elementName + " " + + attrs + ">"; + } catch(e) {} + element = parentElement.firstChild || null; + // workaround firefox 1.0.X bug + if(!element) { + element = document.createElement(elementName); + for(attr in arguments[1]) + element[attr == 'class' ? 'className' : attr] = arguments[1][attr]; + } + if(element.tagName.toUpperCase() != elementName) + element = parentElement.getElementsByTagName(elementName)[0]; + } + } + + // text, or array of children + if(arguments[2]) + this._children(element, arguments[2]); + + return $(element); + }, + _text: function(text) { + return document.createTextNode(text); + }, + + ATTR_MAP: { + 'className': 'class', + 'htmlFor': 'for' + }, + + _attributes: function(attributes) { + var attrs = []; + for(attribute in attributes) + attrs.push((attribute in this.ATTR_MAP ? this.ATTR_MAP[attribute] : attribute) + + '="' + attributes[attribute].toString().escapeHTML().gsub(/"/,'"') + '"'); + return attrs.join(" "); + }, + _children: function(element, children) { + if(children.tagName) { + element.appendChild(children); + return; + } + if(typeof children=='object') { // array can hold nodes and text + children.flatten().each( function(e) { + if(typeof e=='object') + element.appendChild(e); + else + if(Builder._isStringOrNumber(e)) + element.appendChild(Builder._text(e)); + }); + } else + if(Builder._isStringOrNumber(children)) + element.appendChild(Builder._text(children)); + }, + _isStringOrNumber: function(param) { + return(typeof param=='string' || typeof param=='number'); + }, + build: function(html) { + var element = this.node('div'); + $(element).update(html.strip()); + return element.down(); + }, + dump: function(scope) { + if(typeof scope != 'object' && typeof scope != 'function') scope = window; //global scope + + var tags = ("A ABBR ACRONYM ADDRESS APPLET AREA B BASE BASEFONT BDO BIG BLOCKQUOTE BODY " + + "BR BUTTON CAPTION CENTER CITE CODE COL COLGROUP DD DEL DFN DIR DIV DL DT EM FIELDSET " + + "FONT FORM FRAME FRAMESET H1 H2 H3 H4 H5 H6 HEAD HR HTML I IFRAME IMG INPUT INS ISINDEX "+ + "KBD LABEL LEGEND LI LINK MAP MENU META NOFRAMES NOSCRIPT OBJECT OL OPTGROUP OPTION P "+ + "PARAM PRE Q S SAMP SCRIPT SELECT SMALL SPAN STRIKE STRONG STYLE SUB SUP TABLE TBODY TD "+ + "TEXTAREA TFOOT TH THEAD TITLE TR TT U UL VAR").split(/\s+/); + + tags.each( function(tag){ + scope[tag] = function() { + return Builder.node.apply(Builder, [tag].concat($A(arguments))); + }; + }); + } +}; \ No newline at end of file diff --git a/public/javascripts/controls.js b/public/javascripts/controls.js index ca29aefd..7392fb66 100644 --- a/public/javascripts/controls.js +++ b/public/javascripts/controls.js @@ -1,6 +1,8 @@ -// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// (c) 2005-2008 Ivan Krstic (http://blogs.law.harvard.edu/ivan) -// (c) 2005-2008 Jon Tirsen (http://www.tirsen.com) +// script.aculo.us controls.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009 + +// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// (c) 2005-2009 Ivan Krstic (http://blogs.law.harvard.edu/ivan) +// (c) 2005-2009 Jon Tirsen (http://www.tirsen.com) // Contributors: // Richard Livsey // Rahul Bhargava diff --git a/public/javascripts/dragdrop.js b/public/javascripts/dragdrop.js index 07229f98..15c6dbca 100644 --- a/public/javascripts/dragdrop.js +++ b/public/javascripts/dragdrop.js @@ -1,5 +1,6 @@ -// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// (c) 2005-2008 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz) +// script.aculo.us dragdrop.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009 + +// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) // // 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/ @@ -311,7 +312,7 @@ var Draggable = Class.create({ tag_name=='TEXTAREA')) return; var pointer = [Event.pointerX(event), Event.pointerY(event)]; - var pos = Position.cumulativeOffset(this.element); + var pos = this.element.cumulativeOffset(); this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) }); Draggables.activate(this); @@ -454,7 +455,7 @@ var Draggable = Class.create({ }, draw: function(point) { - var pos = Position.cumulativeOffset(this.element); + var pos = this.element.cumulativeOffset(); if(this.options.ghosting) { var r = Position.realOffset(this.element); pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY; @@ -730,7 +731,7 @@ var Sortable = { } // keep reference - this.sortables[element.id] = options; + this.sortables[element.identify()] = options; // for onupdate Draggables.addObserver(new SortableObserver(element, options.onUpdate)); @@ -825,7 +826,7 @@ var Sortable = { hide().addClassName('dropmarker').setStyle({position:'absolute'}); document.getElementsByTagName("body").item(0).appendChild(Sortable._marker); } - var offsets = Position.cumulativeOffset(dropon); + var offsets = dropon.cumulativeOffset(); Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'}); if(position=='after') diff --git a/public/javascripts/effects.js b/public/javascripts/effects.js index 5a639d2d..066ee590 100644 --- a/public/javascripts/effects.js +++ b/public/javascripts/effects.js @@ -1,4 +1,6 @@ -// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// script.aculo.us effects.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009 + +// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) // Contributors: // Justin Palmer (http://encytemedia.com/) // Mark Pilgrim (http://diveintomark.org/) @@ -145,14 +147,13 @@ var Effect = { 'blind': ['BlindDown','BlindUp'], 'appear': ['Appear','Fade'] }, - toggle: function(element, effect) { + toggle: function(element, effect, options) { element = $(element); - effect = (effect || 'appear').toLowerCase(); - var options = Object.extend({ + effect = (effect || 'appear').toLowerCase(); + + return Effect[ Effect.PAIRS[ effect ][ element.visible() ? 1 : 0 ] ](element, Object.extend({ queue: { position:'end', scope:(element.id || 'global'), limit: 1 } - }, arguments[2] || { }); - Effect[element.visible() ? - Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options); + }, options || {})); } }; @@ -228,12 +229,6 @@ Effect.Queue = Effect.Queues.get('global'); Effect.Base = Class.create({ position: null, start: function(options) { - function codeForEvent(options,eventName){ - return ( - (options[eventName+'Internal'] ? 'this.options.'+eventName+'Internal(this);' : '') + - (options[eventName] ? 'this.options.'+eventName+'(this);' : '') - ); - } if (options && options.transition === false) options.transition = Effect.Transitions.linear; this.options = Object.extend(Object.extend({ },Effect.DefaultOptions), options || { }); this.currentFrame = 0; diff --git a/public/javascripts/scriptaculous.js b/public/javascripts/scriptaculous.js index cd0e3417..6bf437ac 100644 --- a/public/javascripts/scriptaculous.js +++ b/public/javascripts/scriptaculous.js @@ -1,5 +1,7 @@ -// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// +// script.aculo.us scriptaculous.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009 + +// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including @@ -7,7 +9,7 @@ // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: -// +// // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // @@ -18,30 +20,49 @@ // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// For details, see the script.aculo.us web site: http://script.aculo.us/ var Scriptaculous = { - Version: '1.5_rc3', + Version: '1.8.3', require: function(libraryName) { - // inserting via DOM fails in Safari 2.0, so brute force approach - document.write(''); - }, - load: function() { - if((typeof Prototype=='undefined') || - parseFloat(Prototype.Version.split(".")[0] + "." + - Prototype.Version.split(".")[1]) < 1.4) - throw("script.aculo.us requires the Prototype JavaScript framework >= 1.4.0"); - var scriptTags = document.getElementsByTagName("script"); - for(var i=0;i<\/script>'); + } catch(e) { + // for xhtml+xml served content, fall back to DOM methods + var script = document.createElement('script'); + script.type = 'text/javascript'; + script.src = libraryName; + document.getElementsByTagName('head')[0].appendChild(script); } + }, + REQUIRED_PROTOTYPE: '1.6.0.3', + load: function() { + function convertVersionString(versionString) { + var v = versionString.replace(/_.*|\./g, ''); + v = parseInt(v + '0'.times(4-v.length)); + return versionString.indexOf('_') > -1 ? v-1 : v; + } + + if((typeof Prototype=='undefined') || + (typeof Element == 'undefined') || + (typeof Element.Methods=='undefined') || + (convertVersionString(Prototype.Version) < + convertVersionString(Scriptaculous.REQUIRED_PROTOTYPE))) + throw("script.aculo.us requires the Prototype JavaScript framework >= " + + Scriptaculous.REQUIRED_PROTOTYPE); + + var js = /scriptaculous\.js(\?.*)?$/; + $$('head script[src]').findAll(function(s) { + return s.src.match(js); + }).each(function(s) { + var path = s.src.replace(js, ''), + includes = s.src.match(/\?.*load=([a-z,]*)/); + (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider,sound').split(',').each( + function(include) { Scriptaculous.require(path+include+'.js') }); + }); } -} +}; Scriptaculous.load(); \ No newline at end of file diff --git a/public/javascripts/slider.js b/public/javascripts/slider.js index 1712b989..eb830558 100644 --- a/public/javascripts/slider.js +++ b/public/javascripts/slider.js @@ -1,258 +1,275 @@ -// Copyright (c) 2005 Marty Haught -// -// See scriptaculous.js for full license. +// script.aculo.us slider.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009 -if(!Control) var Control = {}; -Control.Slider = Class.create(); +// Copyright (c) 2005-2009 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) -// increment: (default: 1) -// step: (default: 1) // // callbacks: // onChange(value) // onSlide(value) -Control.Slider.prototype = { +Control.Slider = Class.create({ initialize: function(handle, track, options) { - this.handle = $(handle); - this.track = $(track); + var slider = this; - this.options = options || {}; + 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.value = 0; + this.step = parseInt(this.options.step || '1'); + this.range = this.options.range || $R(0,1); - var defaultMaximum = Math.round(this.track.offsetWidth / this.increment); - if(this.isVertical()) defaultMaximum = Math.round(this.track.offsetHeight / this.increment); - - this.maximum = this.options.maximum || defaultMaximum; - this.minimum = this.options.minimum || 0; + 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.alignX = parseInt(this.options.alignX || '0'); + this.alignY = parseInt(this.options.alignY || '0'); - // Zero out the slider position - this.setCurrentLeft(Position.cumulativeOffset(this.track)[0] - Position.cumulativeOffset(this.handle)[0] + this.alignX); - this.setCurrentTop(this.trackTop() - Position.cumulativeOffset(this.handle)[1] + this.alignY); + this.trackLength = this.maximumOffset() - this.minimumOffset(); - this.offsetX = 0; - this.offsetY = 0; - - this.originalLeft = this.currentLeft(); - this.originalTop = this.currentTop(); - this.originalZ = parseInt(this.handle.style.zIndex || "0"); - - // Prepopulate Slider value - this.setSliderValue(parseInt(this.options.sliderValue) || 0); + 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; - // FIXME: use css - this.handleImage = $(this.options.handleImage) || false; - this.handleDisabled = this.options.handleDisabled || false; - this.handleEnabled = false; - if(this.handleImage) - this.handleEnabled = this.handleImage.src || false; + if (this.options.disabled) this.setDisabled(); - if(this.options.disabled) - this.setDisabled(); - - // Value Array - this.values = this.options.values || false; // Add method to validate and sort?? - - Element.makePositioned(this.handle); // fix IE + // 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); - this.eventKeypress = this.keyPress.bindAsEventListener(this); - Event.observe(this.handle, "mousedown", this.eventMouseDown); - Event.observe(document, "mouseup", this.eventMouseUp); - Event.observe(document, "mousemove", this.eventMouseMove); - Event.observe(document, "keypress", this.eventKeypress); + // 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() { - Event.stopObserving(this.handle, "mousedown", this.eventMouseDown); + var slider = this; + Event.stopObserving(this.track, "mousedown", this.eventMouseDown); Event.stopObserving(document, "mouseup", this.eventMouseUp); Event.stopObserving(document, "mousemove", this.eventMouseMove); - Event.stopObserving(document, "keypress", this.eventKeypress); + this.handles.each( function(h) { + Event.stopObserving(h, "mousedown", slider.eventMouseDown); + }); }, setDisabled: function(){ this.disabled = true; - if(this.handleDisabled) - this.handleImage.src = this.handleDisabled; }, setEnabled: function(){ this.disabled = false; - if(this.handleEnabled) - this.handleImage.src = this.handleEnabled; - }, - currentLeft: function() { - return parseInt(this.handle.style.left || '0'); }, - currentTop: function() { - return parseInt(this.handle.style.top || '0'); - }, - setCurrentLeft: function(left) { - this.handle.style.left = left +"px"; - }, - setCurrentTop: function(top) { - this.handle.style.top = top +"px"; - }, - trackLeft: function(){ - return Position.cumulativeOffset(this.track)[0]; - }, - trackTop: function(){ - return Position.cumulativeOffset(this.track)[1]; - }, getNearestValue: function(value){ - if(this.values){ - var i = 0; - var offset = Math.abs(this.values[0] - value); - var newValue = this.values[0]; + if (this.allowedValues){ + if (value >= this.allowedValues.max()) return(this.allowedValues.max()); + if (value <= this.allowedValues.min()) return(this.allowedValues.min()); - for(i=0; i < this.values.length; i++){ - var currentOffset = Math.abs(this.values[i] - value); - if(currentOffset < offset){ - newValue = this.values[i]; + 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; }, - setSliderValue: function(sliderValue){ - // First check our max and minimum and nearest values - sliderValue = this.getNearestValue(sliderValue); - if(sliderValue > this.maximum) sliderValue = this.maximum; - if(sliderValue < this.minimum) sliderValue = this.minimum; - var offsetDiff = (sliderValue - (this.value||this.minimum)) * this.increment; - - if(this.isVertical()){ - this.setCurrentTop(offsetDiff + this.currentTop()); - } else { - this.setCurrentLeft(offsetDiff + this.currentLeft()); + setValue: function(sliderValue, handleIdx){ + if (!this.active) { + this.activeHandleIdx = handleIdx || 0; + this.activeHandle = this.handles[this.activeHandleIdx]; + this.updateStyles(); } - this.value = sliderValue; - this.updateFinished(); - }, + 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.trackTop() + this.alignY : - this.trackLeft() + this.alignX); + return(this.isVertical() ? this.alignY : this.alignX); }, maximumOffset: function(){ return(this.isVertical() ? - this.trackTop() + this.alignY + (this.maximum - this.minimum) * this.increment : - this.trackLeft() + this.alignX + (this.maximum - this.minimum) * this.increment); - }, + (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){ + if (Event.isLeftClick(event)) { + if (!this.disabled){ this.active = true; - var pointer = [Event.pointerX(event), Event.pointerY(event)]; - var offsets = Position.cumulativeOffset(this.handle); - this.offsetX = (pointer[0] - offsets[0]); - this.offsetY = (pointer[1] - offsets[1]); - this.originalLeft = this.currentLeft(); - this.originalTop = this.currentTop(); + + var handle = Event.element(event); + var pointer = [Event.pointerX(event), Event.pointerY(event)]; + var track = handle; + if (track==this.track) { + var offsets = this.track.cumulativeOffset(); + this.event = event; + this.setValue(this.translateToValue( + (this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2) + )); + var offsets = this.activeHandle.cumulativeOffset(); + 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 = this.activeHandle.cumulativeOffset(); + this.offsetX = (pointer[0] - offsets[0]); + this.offsetY = (pointer[1] - offsets[1]); + } + } } Event.stop(event); } }, update: function(event) { - if(this.active) { - if(!this.dragging) { - var style = this.handle.style; - this.dragging = true; - if(style.position=="") style.position = "relative"; - style.zIndex = this.options.zindex; - } + if (this.active) { + if (!this.dragging) this.dragging = true; this.draw(event); - // fix AppleWebKit rendering - if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); + 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.handle); - - offsets[0] -= this.currentLeft(); - offsets[1] -= this.currentTop(); - - // Adjust for the pointer's position on the handle - pointer[0] -= this.offsetX; - pointer[1] -= this.offsetY; - var style = this.handle.style; - - if(this.isVertical()){ - if(pointer[1] > this.maximumOffset()) - pointer[1] = this.maximumOffset(); - if(pointer[1] < this.minimumOffset()) - pointer[1] = this.minimumOffset(); - - // Increment by values - if(this.values){ - this.value = this.getNearestValue(Math.round((pointer[1] - this.minimumOffset()) / this.increment) + this.minimum); - pointer[1] = this.trackTop() + this.alignY + (this.value - this.minimum) * this.increment; - } else { - this.value = Math.round((pointer[1] - this.minimumOffset()) / this.increment) + this.minimum; - } - style.top = pointer[1] - offsets[1] + "px"; - } else { - if(pointer[0] > this.maximumOffset()) pointer[0] = this.maximumOffset(); - if(pointer[0] < this.minimumOffset()) pointer[0] = this.minimumOffset(); - // Increment by values - if(this.values){ - this.value = this.getNearestValue(Math.round((pointer[0] - this.minimumOffset()) / this.increment) + this.minimum); - pointer[0] = this.trackLeft() + this.alignX + (this.value - this.minimum) * this.increment; - } else { - this.value = Math.round((pointer[0] - this.minimumOffset()) / this.increment) + this.minimum; - } - style.left = (pointer[0] - offsets[0]) + "px"; - } - if(this.options.onSlide) this.options.onSlide(this.value); + var offsets = this.track.cumulativeOffset(); + 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) { + 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.handle.style.zIndex = this.originalZ; - this.originalLeft = this.currentLeft(); - this.originalTop = this.currentTop(); this.updateFinished(); }, updateFinished: function() { - if(this.options.onChange) this.options.onChange(this.value); - }, - keyPress: function(event) { - if(this.active && !this.disabled) { - switch(event.keyCode) { - case Event.KEY_ESC: - this.finishDrag(event, false); - Event.stop(event); - break; - } - if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event); - } + if (this.initialized && this.options.onChange) + this.options.onChange(this.values.length>1 ? this.values : this.value, this); + this.event = null; } -} +}); \ No newline at end of file