diff options
author | David Heinemeier Hansson <david@loudthinking.com> | 2005-06-26 12:03:43 +0000 |
---|---|---|
committer | David Heinemeier Hansson <david@loudthinking.com> | 2005-06-26 12:03:43 +0000 |
commit | 7da736f929e88f4730f160d28afc90667c26b966 (patch) | |
tree | 48e46a9dfe62728de3443bc43cdd14db30ef68ce /actionpack/lib/action_view/helpers/javascripts/prototype.js | |
parent | 66d99c913e1ad549b1880bbceb6f7561040d47b4 (diff) | |
download | rails-7da736f929e88f4730f160d28afc90667c26b966.tar.gz rails-7da736f929e88f4730f160d28afc90667c26b966.tar.bz2 rails-7da736f929e88f4730f160d28afc90667c26b966.zip |
Added script.aculo.us Javascripts (controls.js, dragdrop.js, effects.js) (NEEDS MORE DESCRIPTION) #1509 [Thomas Fuchs]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1522 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'actionpack/lib/action_view/helpers/javascripts/prototype.js')
-rw-r--r-- | actionpack/lib/action_view/helpers/javascripts/prototype.js | 438 |
1 files changed, 256 insertions, 182 deletions
diff --git a/actionpack/lib/action_view/helpers/javascripts/prototype.js b/actionpack/lib/action_view/helpers/javascripts/prototype.js index ca772aa8fa..1ebb2a46b7 100644 --- a/actionpack/lib/action_view/helpers/javascripts/prototype.js +++ b/actionpack/lib/action_view/helpers/javascripts/prototype.js @@ -559,205 +559,279 @@ Insertion.After.prototype = (new Abstract.Insertion('afterEnd')).extend({ } }); -/*--------------------------------------------------------------------------*/ - -var Effect = new Object(); -Effect.Highlight = Class.create(); -Effect.Highlight.prototype = { - initialize: function(element) { - this.element = $(element); - this.start = 153; - this.finish = 255; - this.current = this.start; - this.fade(); - }, - - fade: function() { - if (this.isFinished()) return; - if (this.timer) clearTimeout(this.timer); - this.highlight(this.element, this.current); - this.current += 17; - this.timer = setTimeout(this.fade.bind(this), 250); - }, - - isFinished: function() { - return this.current > this.finish; - }, - - highlight: function(element, current) { - element.style.backgroundColor = "#ffff" + current.toColorPart(); +// === Prototype Extension ==================================================== + +// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// +// Element.Class part Copyright (c) 2005 by Rick Olson +// +// 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 +// without limitation the rights to use, copy, modify, merge, publish, +// 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. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// 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. + +var Event = { + KEY_BACKSPACE: 8, + KEY_TAB: 9, + KEY_RETURN: 13, + KEY_ESC: 27, + KEY_LEFT: 37, + KEY_UP: 38, + KEY_RIGHT: 39, + KEY_DOWN: 40, + KEY_DELETE: 46, + + element: function(event) { + return event.srcElement || event.currentTarget; + }, + + isLeftClick: function(event) { + return (((event.which) && (event.which == 1)) || + ((event.button) && (event.button == 1))); + }, + + pointerX: function(event) { + return event.pageX || (event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft)); + }, + + pointerY: function(event) { + return event.pageY || (event.clientY + (document.documentElement.scrollTop || document.body.scrollTop)); + }, + + stop: function(event) { + if(event.preventDefault) + { event.preventDefault(); event.stopPropagation(); } + else + event.returnValue = false; + }, + + // find the first node with the given tagName, starting from the + // node the event was triggered on, traverses the DOM upwards + findElement: function(event, tagName) { + element = Event.element(event); + while(element.tagName.toUpperCase() != tagName.toUpperCase() && element.parentNode) + element = element.parentNode; + return element; + }, + + observe: function(element, name, observer) { + if(name=='keypress') { + if(navigator.appVersion.indexOf('AppleWebKit')>0) + { $(element).addEventListener("keydown",observer,false); return; } + if($(element).addEventListener) $(element).addEventListener("keypress",observer,false) + else if($(element).attachEvent) $(element).attachEvent("onkeydown",observer); + } else { + if($(element).addEventListener) $(element).addEventListener(name,observer,false) + else if($(element).attachEvent) $(element).attachEvent("on" + name,observer); + } } } +/*--------------------------------------------------------------------------*/ -Effect.Fade = Class.create(); -Effect.Fade.prototype = { - initialize: function(element) { - this.element = $(element); - this.start = 100; - this.finish = 0; - this.current = this.start; - this.fade(); - }, - - fade: function() { - if (this.isFinished()) { this.element.style.display = 'none'; return; } - if (this.timer) clearTimeout(this.timer); - this.setOpacity(this.element, this.current); - this.current -= 10; - this.timer = setTimeout(this.fade.bind(this), 50); - }, - - isFinished: function() { - return this.current <= this.finish; - }, - - setOpacity: function(element, opacity) { - opacity = (opacity == 100) ? 99.999 : opacity; - element.style.filter = "alpha(opacity:"+opacity+")"; - element.style.opacity = opacity/100 /*//*/; +// removes whitespace-only text node children +// needed to make Gecko-based browsers happy +Element.cleanWhitespace = function(element) { + var element = $(element); + for(var i=0;i<element.childNodes.length;i++) { + var node = element.childNodes[i]; + if(node.nodeType==3 && !/\S/.test(node.nodeValue)) + Element.remove(node); } } -Effect.Scale = Class.create(); -Effect.Scale.prototype = { - initialize: function(element, percent) { - this.element = $(element); - this.startScale = 1.0; - this.startHeight = this.element.offsetHeight; - this.startWidth = this.element.offsetWidth; - this.currentHeight = this.startHeight; - this.currentWidth = this.startWidth; - this.finishScale = (percent/100) /*//*/; - if (this.element.style.fontSize=="") this.sizeEm = 1.0; - if (this.element.style.fontSize.indexOf("em")>0) - this.sizeEm = parseFloat(this.element.style.fontSize); - if(this.element.effect_scale) { - clearTimeout(this.element.effect_scale.timer); - this.startScale = this.element.effect_scale.currentScale; - this.startHeight = this.element.effect_scale.startHeight; - this.startWidth = this.element.effect_scale.startWidth; - if(this.element.effect_scale.sizeEm) - this.sizeEm = this.element.effect_scale.sizeEm; - } - this.element.effect_scale = this; - this.currentScale = this.startScale; - this.factor = this.finishScale - this.startScale; - this.options = arguments[2] || {}; - this.scale(); - }, - - scale: function() { - if (this.isFinished()) { - this.setDimensions(this.element, this.startWidth*this.finishScale, this.startHeight*this.finishScale); - if(this.sizeEm) this.element.style.fontSize = this.sizeEm*this.finishScale + "em"; - if(this.options.complete) this.options.complete(this); - return; - } - if (this.timer) clearTimeout(this.timer); - if (this.options.step) this.options.step(this); - this.setDimensions(this.element, this.currentWidth, this.currentHeight); - if(this.sizeEm) this.element.style.fontSize = this.sizeEm*this.currentScale + "em"; - this.currentScale += (this.factor/10) /*//*/; - this.currentWidth = this.startWidth * this.currentScale; - this.currentHeight = this.startHeight * this.currentScale; - this.timer = setTimeout(this.scale.bind(this), 50); - }, - - isFinished: function() { - return (this.factor < 0) ? - this.currentScale <= this.finishScale : this.currentScale >= this.finishScale; - }, +Element.collectTextNodesIgnoreClass = function(element, ignoreclass) { + var children = $(element).childNodes; + var text = ""; + var classtest = new RegExp("^([^ ]+ )*" + ignoreclass+ "( [^ ]+)*$","i"); - setDimensions: function(element, width, height) { - element.style.width = width + 'px'; - element.style.height = height + 'px'; + for (var i = 0; i < children.length; i++) { + if(children[i].nodeType==3) { + text+=children[i].nodeValue; + } else { + if((!children[i].className.match(classtest)) && children[i].hasChildNodes()) + text += Element.collectTextNodesIgnoreClass(children[i], ignoreclass); + } } + + return text; } -Effect.Squish = Class.create(); -Effect.Squish.prototype = { - initialize: function(element) { - this.element = $(element); - new Effect.Scale(this.element, 1, { complete: this.hide.bind(this) } ); - }, - hide: function() { - this.element.style.display = 'none'; - } -} +/*--------------------------------------------------------------------------*/ -Effect.Puff = Class.create(); -Effect.Puff.prototype = { - initialize: function(element) { - this.element = $(element); - this.opacity = 100; - this.startTop = this.element.top || this.element.offsetTop; - this.startLeft = this.element.left || this.element.offsetLeft; - new Effect.Scale(this.element, 200, { step: this.fade.bind(this), complete: this.hide.bind(this) } ); - }, - fade: function(effect) { - topd = (((effect.currentScale)*effect.startHeight) - effect.startHeight)/2; - leftd = (((effect.currentScale)*effect.startWidth) - effect.startWidth)/2; - this.element.style.position='absolute'; - this.element.style.top = this.startTop-topd + "px"; - this.element.style.left = this.startLeft-leftd + "px"; - this.opacity -= 10; - this.setOpacity(this.element, this.opacity); - if(navigator.appVersion.indexOf('AppleWebKit')>0) this.element.innerHTML += ''; //force redraw on safari - }, - hide: function() { - this.element.style.display = 'none'; +Text = { + stripTags: function(htmlstr) { + return htmlstr.replace(/<\/?[^>]+>/gi,""); }, - setOpacity: function(element, opacity) { - opacity = (opacity == 100) ? 99.999 : opacity; - element.style.filter = "alpha(opacity:"+opacity+")"; - element.style.opacity = opacity/100 /*//*/; + decodeHTML: function(htmlstr) { + return htmlstr.replace(/</gi,"<").replace(/>/gi,">").replace(/"/gi,'"').replace(/'/gi,"'").replace(/&/gi,"&").replace(/[\n\r]/gi,""); } } -Effect.Appear = Class.create(); -Effect.Appear.prototype = { - initialize: function(element) { - this.element = $(element); - this.start = 0; - this.finish = 100; - this.current = this.start; - this.fade(); - }, - - fade: function() { - if (this.isFinished()) return; - if (this.timer) clearTimeout(this.timer); - this.setOpacity(this.element, this.current); - this.current += 10; - this.timer = setTimeout(this.fade.bind(this), 50); - }, - - isFinished: function() { - return this.current > this.finish; - }, - - setOpacity: function(element, opacity) { - opacity = (opacity == 100) ? 99.999 : opacity; - element.style.filter = "alpha(opacity:"+opacity+")"; - element.style.opacity = opacity/100 /*//*/; - element.style.display = ''; - } -} +/*--------------------------------------------------------------------------*/ -Effect.ContentZoom = Class.create(); -Effect.ContentZoom.prototype = { - initialize: function(element, percent) { - this.element = $(element); - if (this.element.style.fontSize=="") this.sizeEm = 1.0; - if (this.element.style.fontSize.indexOf("em")>0) - this.sizeEm = parseFloat(this.element.style.fontSize); - if(this.element.effect_contentzoom) { - this.sizeEm = this.element.effect_contentzoom.sizeEm; +Element.Class = { + // Element.toggleClass(element, className) toggles the class being on/off + // Element.toggleClass(element, className1, className2) toggles between both classes, + // defaulting to className1 if neither exist + toggle: function(element, className) { + if(Element.Class.has(element, className)) { + Element.Class.remove(element, className); + if(arguments.length == 3) Element.Class.add(element, arguments[2]); + } else { + Element.Class.add(element, className); + if(arguments.length == 3) Element.Class.remove(element, arguments[2]); + } + }, + + // gets space-delimited classnames of an element as an array + get: function(element) { + element = $(element); + return element.className.split(' '); + }, + + // functions adapted from original functions by Gavin Kistner + remove: function(element) { + element = $(element); + var regEx; + for(var i = 1; i < arguments.length; i++) { + regEx = new RegExp("^" + arguments[i] + "\\b\\s*|\\s*\\b" + arguments[i] + "\\b", 'g'); + element.className = element.className.replace(regEx, '') + } + }, + + add: function(element) { + element = $(element); + for(var i = 1; i < arguments.length; i++) { + Element.Class.remove(element, arguments[i]); + element.className += (element.className.length > 0 ? ' ' : '') + arguments[i]; + } + }, + + // returns true if all given classes exist in said element + has: function(element) { + element = $(element); + if(!element || !element.className) return false; + var regEx; + for(var i = 1; i < arguments.length; i++) { + regEx = new RegExp("\\b" + arguments[i] + "\\b"); + if(!regEx.test(element.className)) return false; + } + return true; + }, + + // expects arrays of strings and/or strings as optional paramters + // Element.Class.has_any(element, ['classA','classB','classC'], 'classD') + has_any: function(element) { + element = $(element); + if(!element || !element.className) return false; + var regEx; + for(var i = 1; i < arguments.length; i++) { + if((typeof arguments[i] == 'object') && + (arguments[i].constructor == Array)) { + for(var j = 0; j < arguments[i].length; j++) { + regEx = new RegExp("\\b" + arguments[i][j] + "\\b"); + if(regEx.test(element.className)) return true; + } + } else { + regEx = new RegExp("\\b" + arguments[i] + "\\b"); + if(regEx.test(element.className)) return true; + } + } + return false; + }, + + childrenWith: function(element, className) { + var children = $(element).getElementsByTagName('*'); + var elements = new Array(); + + for (var i = 0; i < children.length; i++) { + if (Element.Class.has(children[i], className)) { + elements.push(children[i]); + break; + } + } + + return elements; } - this.element.effect_contentzoom = this; - this.element.style.fontSize = this.sizeEm*(percent/100) + "em" /*//*/; - if(navigator.appVersion.indexOf('AppleWebKit')>0) { this.element.scrollTop -= 1; }; - } } + +/*--------------------------------------------------------------------------*/ + +var Position = { + // must be called before calling within_including_scrolloffset, every time the page is scrolled + prepare: function() { + this.deltaX = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0; + this.deltaY = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; + this.include_scroll_offsets = true; + }, + + real_offset: function(element) { + var valueT = 0; var valueL = 0; + do { + valueT += element.scrollTop || 0; + valueL += element.scrollLeft || 0; + element = element.parentNode; + } while(element); + return [valueL, valueT]; + }, + + // caches x/y coordinate pair to use with overlap + within: function(element, x, y) { + if(this.include_scroll_offsets) + return within_including_scrolloffsets(element, x, y); + this.xcomp = x; + this.ycomp = y; + var offsettop = element.offsetTop; + var offsetleft = element.offsetLeft; + return (y>=offsettop && + y<offsettop+element.offsetHeight && + x>=offsetleft && + x<offsetleft+element.offsetWidth); + }, + + within_including_scrolloffsets: function(element, x, y) { + var offsetcache = this.real_offset(element); + this.xcomp = x + offsetcache[0] - this.deltaX; + this.ycomp = y + offsetcache[1] - this.deltaY; + this.xcomp = x; + this.ycomp = y; + var offsettop = element.offsetTop; + var offsetleft = element.offsetLeft; + return (y>=offsettop && + y<offsettop+element.offsetHeight && + x>=offsetleft && + x<offsetleft+element.offsetWidth); + }, + + // within must be called directly before + overlap: function(mode, element) { + if(!mode) return 0; + if(mode == 'vertical') + return ((element.offsetTop+element.offsetHeight)-this.ycomp) / element.offsetHeight; + if(mode == 'horizontal') + return ((element.offsetLeft+element.offsetWidth)-this.xcomp) / element.offsetWidth; + }, + + clone: function(source, target) { + $(target).style.top = $(source).style.top; + $(target).style.left = $(source).style.left; + $(target).style.width = $(source).offsetWidth + "px"; + $(target).style.height = $(source).offsetHeight + "px"; + } +}
\ No newline at end of file |