Team:Freiburg Software/Team/Photos
From 2010.igem.org
(Difference between revisions)
Line 10: | Line 10: | ||
color: white; | color: white; | ||
} | } | ||
- | + | ||
+ | /* for the image frames */ | ||
+ | |||
+ | #showcase { | ||
+ | position: relative; | ||
+ | width: 700px; | ||
+ | height: 170px; | ||
+ | } | ||
+ | #showcase li { | ||
+ | width: 170px; | ||
+ | height: 170px; | ||
+ | float: left; | ||
+ | list-style-type: none; | ||
+ | } | ||
+ | |||
+ | #showcase li img { | ||
+ | width: 100%; | ||
+ | height: 100%; | ||
+ | } | ||
+ | |||
</style> | </style> | ||
<script type="text/javascript"> | <script type="text/javascript"> | ||
+ | // 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/) | ||
+ | // Martin Bialasinki | ||
+ | // | ||
+ | // 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/ | ||
+ | // converts rgb() and #xxx to #xxxxxx format, | ||
+ | // returns self (or first argument) if not convertable | ||
+ | String.prototype.parseColor = function() { | ||
+ | var color = '#'; | ||
+ | if (this.slice(0,4) == 'rgb(') { | ||
+ | var cols = this.slice(4,this.length-1).split(','); | ||
+ | var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3); | ||
+ | } else { | ||
+ | if (this.slice(0,1) == '#') { | ||
+ | if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase(); | ||
+ | if (this.length==7) color = this.toLowerCase(); | ||
+ | } | ||
+ | } | ||
+ | return (color.length==7 ? color : (arguments[0] || this)); | ||
+ | }; | ||
- | + | /*--------------------------------------------------------------------------*/ | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | Element.collectTextNodes = function(element) { | |
+ | return $A($(element).childNodes).collect( function(node) { | ||
+ | return (node.nodeType==3 ? node.nodeValue : | ||
+ | (node.hasChildNodes() ? Element.collectTextNodes(node) : '')); | ||
+ | }).flatten().join(''); | ||
+ | }; | ||
+ | Element.collectTextNodesIgnoreClass = function(element, className) { | ||
+ | return $A($(element).childNodes).collect( function(node) { | ||
+ | return (node.nodeType==3 ? node.nodeValue : | ||
+ | ((node.hasChildNodes() && !Element.hasClassName(node,className)) ? | ||
+ | Element.collectTextNodesIgnoreClass(node, className) : '')); | ||
+ | }).flatten().join(''); | ||
+ | }; | ||
+ | Element.setContentZoom = function(element, percent) { | ||
+ | element = $(element); | ||
+ | element.setStyle({fontSize: (percent/100) + 'em'}); | ||
+ | if (Prototype.Browser.WebKit) window.scrollBy(0,0); | ||
+ | return element; | ||
+ | }; | ||
- | + | Element.getInlineOpacity = function(element){ | |
- | + | return $(element).style.opacity || ''; | |
- | + | }; | |
- | + | Element.forceRerendering = function(element) { | |
- | + | try { | |
- | var | + | element = $(element); |
+ | var n = document.createTextNode(' '); | ||
+ | element.appendChild(n); | ||
+ | element.removeChild(n); | ||
+ | } catch(e) { } | ||
+ | }; | ||
+ | /*--------------------------------------------------------------------------*/ | ||
+ | var Effect = { | ||
+ | _elementDoesNotExistError: { | ||
+ | name: 'ElementDoesNotExistError', | ||
+ | message: 'The specified DOM element does not exist, but is required for this effect to operate' | ||
+ | }, | ||
+ | Transitions: { | ||
+ | linear: Prototype.K, | ||
+ | sinoidal: function(pos) { | ||
+ | return (-Math.cos(pos*Math.PI)/2) + .5; | ||
+ | }, | ||
+ | reverse: function(pos) { | ||
+ | return 1-pos; | ||
+ | }, | ||
+ | flicker: function(pos) { | ||
+ | var pos = ((-Math.cos(pos*Math.PI)/4) + .75) + Math.random()/4; | ||
+ | return pos > 1 ? 1 : pos; | ||
+ | }, | ||
+ | wobble: function(pos) { | ||
+ | return (-Math.cos(pos*Math.PI*(9*pos))/2) + .5; | ||
+ | }, | ||
+ | pulse: function(pos, pulses) { | ||
+ | return (-Math.cos((pos*((pulses||5)-.5)*2)*Math.PI)/2) + .5; | ||
+ | }, | ||
+ | spring: function(pos) { | ||
+ | return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6)); | ||
+ | }, | ||
+ | none: function(pos) { | ||
+ | return 0; | ||
+ | }, | ||
+ | full: function(pos) { | ||
+ | return 1; | ||
+ | } | ||
+ | }, | ||
+ | DefaultOptions: { | ||
+ | duration: 1.0, // seconds | ||
+ | fps: 100, // 100= assume 66fps max. | ||
+ | sync: false, // true for combining | ||
+ | from: 0.0, | ||
+ | to: 1.0, | ||
+ | delay: 0.0, | ||
+ | queue: 'parallel' | ||
+ | }, | ||
+ | tagifyText: function(element) { | ||
+ | var tagifyStyle = 'position:relative'; | ||
+ | if (Prototype.Browser.IE) tagifyStyle += ';zoom:1'; | ||
+ | element = $(element); | ||
+ | $A(element.childNodes).each( function(child) { | ||
+ | if (child.nodeType==3) { | ||
+ | child.nodeValue.toArray().each( function(character) { | ||
+ | element.insertBefore( | ||
+ | new Element('span', {style: tagifyStyle}).update( | ||
+ | character == ' ' ? String.fromCharCode(160) : character), | ||
+ | child); | ||
+ | }); | ||
+ | Element.remove(child); | ||
+ | } | ||
+ | }); | ||
+ | }, | ||
+ | multiple: function(element, effect) { | ||
+ | var elements; | ||
+ | if (((typeof element == 'object') || | ||
+ | Object.isFunction(element)) && | ||
+ | (element.length)) | ||
+ | elements = element; | ||
+ | else | ||
+ | elements = $(element).childNodes; | ||
+ | var options = Object.extend({ | ||
+ | speed: 0.1, | ||
+ | delay: 0.0 | ||
+ | }, arguments[2] || { }); | ||
+ | var masterDelay = options.delay; | ||
- | + | $A(elements).each( function(element, index) { | |
- | + | new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay })); | |
- | + | }); | |
- | + | }, | |
- | function | + | PAIRS: { |
+ | 'slide': ['SlideDown','SlideUp'], | ||
+ | 'blind': ['BlindDown','BlindUp'], | ||
+ | 'appear': ['Appear','Fade'] | ||
+ | }, | ||
+ | toggle: function(element, effect, options) { | ||
+ | element = $(element); | ||
+ | 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 } | ||
+ | }, options || {})); | ||
+ | } | ||
+ | }; | ||
- | + | Effect.DefaultOptions.transition = Effect.Transitions.sinoidal; | |
- | + | /* ------------- core effects ------------- */ | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | Effect.ScopedQueue = Class.create(Enumerable, { | |
- | + | initialize: function() { | |
+ | this.effects = []; | ||
+ | this.interval = null; | ||
+ | }, | ||
+ | _each: function(iterator) { | ||
+ | this.effects._each(iterator); | ||
+ | }, | ||
+ | add: function(effect) { | ||
+ | var timestamp = new Date().getTime(); | ||
+ | |||
+ | var position = Object.isString(effect.options.queue) ? | ||
+ | effect.options.queue : effect.options.queue.position; | ||
+ | |||
+ | switch(position) { | ||
+ | case 'front': | ||
+ | // move unstarted effects after this effect | ||
+ | this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) { | ||
+ | e.startOn += effect.finishOn; | ||
+ | e.finishOn += effect.finishOn; | ||
+ | }); | ||
+ | break; | ||
+ | case 'with-last': | ||
+ | timestamp = this.effects.pluck('startOn').max() || timestamp; | ||
+ | break; | ||
+ | case 'end': | ||
+ | // start effect after last queued effect has finished | ||
+ | timestamp = this.effects.pluck('finishOn').max() || timestamp; | ||
+ | break; | ||
+ | } | ||
+ | |||
+ | effect.startOn += timestamp; | ||
+ | effect.finishOn += timestamp; | ||
+ | |||
+ | if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit)) | ||
+ | this.effects.push(effect); | ||
+ | |||
+ | if (!this.interval) | ||
+ | this.interval = setInterval(this.loop.bind(this), 15); | ||
+ | }, | ||
+ | remove: function(effect) { | ||
+ | this.effects = this.effects.reject(function(e) { return e==effect }); | ||
+ | if (this.effects.length == 0) { | ||
+ | clearInterval(this.interval); | ||
+ | this.interval = null; | ||
+ | } | ||
+ | }, | ||
+ | loop: function() { | ||
+ | var timePos = new Date().getTime(); | ||
+ | for(var i=0, len=this.effects.length;i<len;i++) | ||
+ | this.effects[i] && this.effects[i].loop(timePos); | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | Effect.Queues = { | ||
+ | instances: $H(), | ||
+ | get: function(queueName) { | ||
+ | if (!Object.isString(queueName)) return queueName; | ||
+ | |||
+ | return this.instances.get(queueName) || | ||
+ | this.instances.set(queueName, new Effect.ScopedQueue()); | ||
+ | } | ||
+ | }; | ||
+ | Effect.Queue = Effect.Queues.get('global'); | ||
+ | |||
+ | Effect.Base = Class.create({ | ||
+ | position: null, | ||
+ | start: function(options) { | ||
+ | if (options && options.transition === false) options.transition = Effect.Transitions.linear; | ||
+ | this.options = Object.extend(Object.extend({ },Effect.DefaultOptions), options || { }); | ||
+ | this.currentFrame = 0; | ||
+ | this.state = 'idle'; | ||
+ | this.startOn = this.options.delay*1000; | ||
+ | this.finishOn = this.startOn+(this.options.duration*1000); | ||
+ | this.fromToDelta = this.options.to-this.options.from; | ||
+ | this.totalTime = this.finishOn-this.startOn; | ||
+ | this.totalFrames = this.options.fps*this.options.duration; | ||
+ | |||
+ | this.render = (function() { | ||
+ | function dispatch(effect, eventName) { | ||
+ | if (effect.options[eventName + 'Internal']) | ||
+ | effect.options[eventName + 'Internal'](effect); | ||
+ | if (effect.options[eventName]) | ||
+ | effect.options[eventName](effect); | ||
+ | } | ||
+ | |||
+ | return function(pos) { | ||
+ | if (this.state === "idle") { | ||
+ | this.state = "running"; | ||
+ | dispatch(this, 'beforeSetup'); | ||
+ | if (this.setup) this.setup(); | ||
+ | dispatch(this, 'afterSetup'); | ||
+ | } | ||
+ | if (this.state === "running") { | ||
+ | pos = (this.options.transition(pos) * this.fromToDelta) + this.options.from; | ||
+ | this.position = pos; | ||
+ | dispatch(this, 'beforeUpdate'); | ||
+ | if (this.update) this.update(pos); | ||
+ | dispatch(this, 'afterUpdate'); | ||
+ | } | ||
+ | }; | ||
+ | })(); | ||
+ | |||
+ | this.event('beforeStart'); | ||
+ | if (!this.options.sync) | ||
+ | Effect.Queues.get(Object.isString(this.options.queue) ? | ||
+ | 'global' : this.options.queue.scope).add(this); | ||
+ | }, | ||
+ | loop: function(timePos) { | ||
+ | if (timePos >= this.startOn) { | ||
+ | if (timePos >= this.finishOn) { | ||
+ | this.render(1.0); | ||
+ | this.cancel(); | ||
+ | this.event('beforeFinish'); | ||
+ | if (this.finish) this.finish(); | ||
+ | this.event('afterFinish'); | ||
+ | return; | ||
+ | } | ||
+ | var pos = (timePos - this.startOn) / this.totalTime, | ||
+ | frame = (pos * this.totalFrames).round(); | ||
+ | if (frame > this.currentFrame) { | ||
+ | this.render(pos); | ||
+ | this.currentFrame = frame; | ||
+ | } | ||
+ | } | ||
+ | }, | ||
+ | cancel: function() { | ||
+ | if (!this.options.sync) | ||
+ | Effect.Queues.get(Object.isString(this.options.queue) ? | ||
+ | 'global' : this.options.queue.scope).remove(this); | ||
+ | this.state = 'finished'; | ||
+ | }, | ||
+ | event: function(eventName) { | ||
+ | if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this); | ||
+ | if (this.options[eventName]) this.options[eventName](this); | ||
+ | }, | ||
+ | inspect: function() { | ||
+ | var data = $H(); | ||
+ | for(property in this) | ||
+ | if (!Object.isFunction(this[property])) data.set(property, this[property]); | ||
+ | return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>'; | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | Effect.Parallel = Class.create(Effect.Base, { | ||
+ | initialize: function(effects) { | ||
+ | this.effects = effects || []; | ||
+ | this.start(arguments[1]); | ||
+ | }, | ||
+ | update: function(position) { | ||
+ | this.effects.invoke('render', position); | ||
+ | }, | ||
+ | finish: function(position) { | ||
+ | this.effects.each( function(effect) { | ||
+ | effect.render(1.0); | ||
+ | effect.cancel(); | ||
+ | effect.event('beforeFinish'); | ||
+ | if (effect.finish) effect.finish(position); | ||
+ | effect.event('afterFinish'); | ||
+ | }); | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | Effect.Tween = Class.create(Effect.Base, { | ||
+ | initialize: function(object, from, to) { | ||
+ | object = Object.isString(object) ? $(object) : object; | ||
+ | var args = $A(arguments), method = args.last(), | ||
+ | options = args.length == 5 ? args[3] : null; | ||
+ | this.method = Object.isFunction(method) ? method.bind(object) : | ||
+ | Object.isFunction(object[method]) ? object[method].bind(object) : | ||
+ | function(value) { object[method] = value }; | ||
+ | this.start(Object.extend({ from: from, to: to }, options || { })); | ||
+ | }, | ||
+ | update: function(position) { | ||
+ | this.method(position); | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | Effect.Event = Class.create(Effect.Base, { | ||
+ | initialize: function() { | ||
+ | this.start(Object.extend({ duration: 0 }, arguments[0] || { })); | ||
+ | }, | ||
+ | update: Prototype.emptyFunction | ||
+ | }); | ||
+ | |||
+ | Effect.Opacity = Class.create(Effect.Base, { | ||
+ | initialize: function(element) { | ||
+ | this.element = $(element); | ||
+ | if (!this.element) throw(Effect._elementDoesNotExistError); | ||
+ | // make this work on IE on elements without 'layout' | ||
+ | if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout)) | ||
+ | this.element.setStyle({zoom: 1}); | ||
+ | var options = Object.extend({ | ||
+ | from: this.element.getOpacity() || 0.0, | ||
+ | to: 1.0 | ||
+ | }, arguments[1] || { }); | ||
+ | this.start(options); | ||
+ | }, | ||
+ | update: function(position) { | ||
+ | this.element.setOpacity(position); | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | Effect.Move = Class.create(Effect.Base, { | ||
+ | initialize: function(element) { | ||
+ | this.element = $(element); | ||
+ | if (!this.element) throw(Effect._elementDoesNotExistError); | ||
+ | var options = Object.extend({ | ||
+ | x: 0, | ||
+ | y: 0, | ||
+ | mode: 'relative' | ||
+ | }, arguments[1] || { }); | ||
+ | this.start(options); | ||
+ | }, | ||
+ | setup: function() { | ||
+ | this.element.makePositioned(); | ||
+ | this.originalLeft = parseFloat(this.element.getStyle('left') || '0'); | ||
+ | this.originalTop = parseFloat(this.element.getStyle('top') || '0'); | ||
+ | if (this.options.mode == 'absolute') { | ||
+ | this.options.x = this.options.x - this.originalLeft; | ||
+ | this.options.y = this.options.y - this.originalTop; | ||
+ | } | ||
+ | }, | ||
+ | update: function(position) { | ||
+ | this.element.setStyle({ | ||
+ | left: (this.options.x * position + this.originalLeft).round() + 'px', | ||
+ | top: (this.options.y * position + this.originalTop).round() + 'px' | ||
+ | }); | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | // for backwards compatibility | ||
+ | Effect.MoveBy = function(element, toTop, toLeft) { | ||
+ | return new Effect.Move(element, | ||
+ | Object.extend({ x: toLeft, y: toTop }, arguments[3] || { })); | ||
+ | }; | ||
+ | |||
+ | Effect.Scale = Class.create(Effect.Base, { | ||
+ | initialize: function(element, percent) { | ||
+ | this.element = $(element); | ||
+ | if (!this.element) throw(Effect._elementDoesNotExistError); | ||
+ | var options = Object.extend({ | ||
+ | scaleX: true, | ||
+ | scaleY: true, | ||
+ | scaleContent: true, | ||
+ | scaleFromCenter: false, | ||
+ | scaleMode: 'box', // 'box' or 'contents' or { } with provided values | ||
+ | scaleFrom: 100.0, | ||
+ | scaleTo: percent | ||
+ | }, arguments[2] || { }); | ||
+ | this.start(options); | ||
+ | }, | ||
+ | setup: function() { | ||
+ | this.restoreAfterFinish = this.options.restoreAfterFinish || false; | ||
+ | this.elementPositioning = this.element.getStyle('position'); | ||
+ | |||
+ | this.originalStyle = { }; | ||
+ | ['top','left','width','height','fontSize'].each( function(k) { | ||
+ | this.originalStyle[k] = this.element.style[k]; | ||
+ | }.bind(this)); | ||
+ | |||
+ | this.originalTop = this.element.offsetTop; | ||
+ | this.originalLeft = this.element.offsetLeft; | ||
+ | |||
+ | var fontSize = this.element.getStyle('font-size') || '100%'; | ||
+ | ['em','px','%','pt'].each( function(fontSizeType) { | ||
+ | if (fontSize.indexOf(fontSizeType)>0) { | ||
+ | this.fontSize = parseFloat(fontSize); | ||
+ | this.fontSizeType = fontSizeType; | ||
+ | } | ||
+ | }.bind(this)); | ||
+ | |||
+ | this.factor = (this.options.scaleTo - this.options.scaleFrom)/100; | ||
+ | |||
+ | this.dims = null; | ||
+ | if (this.options.scaleMode=='box') | ||
+ | this.dims = [this.element.offsetHeight, this.element.offsetWidth]; | ||
+ | if (/^content/.test(this.options.scaleMode)) | ||
+ | this.dims = [this.element.scrollHeight, this.element.scrollWidth]; | ||
+ | if (!this.dims) | ||
+ | this.dims = [this.options.scaleMode.originalHeight, | ||
+ | this.options.scaleMode.originalWidth]; | ||
+ | }, | ||
+ | update: function(position) { | ||
+ | var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position); | ||
+ | if (this.options.scaleContent && this.fontSize) | ||
+ | this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType }); | ||
+ | this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale); | ||
+ | }, | ||
+ | finish: function(position) { | ||
+ | if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle); | ||
+ | }, | ||
+ | setDimensions: function(height, width) { | ||
+ | var d = { }; | ||
+ | if (this.options.scaleX) d.width = width.round() + 'px'; | ||
+ | if (this.options.scaleY) d.height = height.round() + 'px'; | ||
+ | if (this.options.scaleFromCenter) { | ||
+ | var topd = (height - this.dims[0])/2; | ||
+ | var leftd = (width - this.dims[1])/2; | ||
+ | if (this.elementPositioning == 'absolute') { | ||
+ | if (this.options.scaleY) d.top = this.originalTop-topd + 'px'; | ||
+ | if (this.options.scaleX) d.left = this.originalLeft-leftd + 'px'; | ||
+ | } else { | ||
+ | if (this.options.scaleY) d.top = -topd + 'px'; | ||
+ | if (this.options.scaleX) d.left = -leftd + 'px'; | ||
+ | } | ||
+ | } | ||
+ | this.element.setStyle(d); | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | Effect.Highlight = Class.create(Effect.Base, { | ||
+ | initialize: function(element) { | ||
+ | this.element = $(element); | ||
+ | if (!this.element) throw(Effect._elementDoesNotExistError); | ||
+ | var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || { }); | ||
+ | this.start(options); | ||
+ | }, | ||
+ | setup: function() { | ||
+ | // Prevent executing on elements not in the layout flow | ||
+ | if (this.element.getStyle('display')=='none') { this.cancel(); return; } | ||
+ | // Disable background image during the effect | ||
+ | this.oldStyle = { }; | ||
+ | if (!this.options.keepBackgroundImage) { | ||
+ | this.oldStyle.backgroundImage = this.element.getStyle('background-image'); | ||
+ | this.element.setStyle({backgroundImage: 'none'}); | ||
+ | } | ||
+ | if (!this.options.endcolor) | ||
+ | this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff'); | ||
+ | if (!this.options.restorecolor) | ||
+ | this.options.restorecolor = this.element.getStyle('background-color'); | ||
+ | // init color calculations | ||
+ | this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this)); | ||
+ | this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this)); | ||
+ | }, | ||
+ | update: function(position) { | ||
+ | this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){ | ||
+ | return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) }); | ||
+ | }, | ||
+ | finish: function() { | ||
+ | this.element.setStyle(Object.extend(this.oldStyle, { | ||
+ | backgroundColor: this.options.restorecolor | ||
+ | })); | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | Effect.ScrollTo = function(element) { | ||
+ | var options = arguments[1] || { }, | ||
+ | scrollOffsets = document.viewport.getScrollOffsets(), | ||
+ | elementOffsets = $(element).cumulativeOffset(); | ||
+ | |||
+ | if (options.offset) elementOffsets[1] += options.offset; | ||
+ | |||
+ | return new Effect.Tween(null, | ||
+ | scrollOffsets.top, | ||
+ | elementOffsets[1], | ||
+ | options, | ||
+ | function(p){ scrollTo(scrollOffsets.left, p.round()); } | ||
+ | ); | ||
+ | }; | ||
+ | |||
+ | /* ------------- combination effects ------------- */ | ||
+ | |||
+ | Effect.Fade = function(element) { | ||
+ | element = $(element); | ||
+ | var oldOpacity = element.getInlineOpacity(); | ||
+ | var options = Object.extend({ | ||
+ | from: element.getOpacity() || 1.0, | ||
+ | to: 0.0, | ||
+ | afterFinishInternal: function(effect) { | ||
+ | if (effect.options.to!=0) return; | ||
+ | effect.element.hide().setStyle({opacity: oldOpacity}); | ||
+ | } | ||
+ | }, arguments[1] || { }); | ||
+ | return new Effect.Opacity(element,options); | ||
+ | }; | ||
+ | |||
+ | Effect.Appear = function(element) { | ||
+ | element = $(element); | ||
+ | var options = Object.extend({ | ||
+ | from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0), | ||
+ | to: 1.0, | ||
+ | // force Safari to render floated elements properly | ||
+ | afterFinishInternal: function(effect) { | ||
+ | effect.element.forceRerendering(); | ||
+ | }, | ||
+ | beforeSetup: function(effect) { | ||
+ | effect.element.setOpacity(effect.options.from).show(); | ||
+ | }}, arguments[1] || { }); | ||
+ | return new Effect.Opacity(element,options); | ||
+ | }; | ||
+ | |||
+ | Effect.Puff = function(element) { | ||
+ | element = $(element); | ||
+ | var oldStyle = { | ||
+ | opacity: element.getInlineOpacity(), | ||
+ | position: element.getStyle('position'), | ||
+ | top: element.style.top, | ||
+ | left: element.style.left, | ||
+ | width: element.style.width, | ||
+ | height: element.style.height | ||
+ | }; | ||
+ | return new Effect.Parallel( | ||
+ | [ new Effect.Scale(element, 200, | ||
+ | { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }), | ||
+ | new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], | ||
+ | Object.extend({ duration: 1.0, | ||
+ | beforeSetupInternal: function(effect) { | ||
+ | Position.absolutize(effect.effects[0].element); | ||
+ | }, | ||
+ | afterFinishInternal: function(effect) { | ||
+ | effect.effects[0].element.hide().setStyle(oldStyle); } | ||
+ | }, arguments[1] || { }) | ||
+ | ); | ||
+ | }; | ||
+ | |||
+ | Effect.BlindUp = function(element) { | ||
+ | element = $(element); | ||
+ | element.makeClipping(); | ||
+ | return new Effect.Scale(element, 0, | ||
+ | Object.extend({ scaleContent: false, | ||
+ | scaleX: false, | ||
+ | restoreAfterFinish: true, | ||
+ | afterFinishInternal: function(effect) { | ||
+ | effect.element.hide().undoClipping(); | ||
+ | } | ||
+ | }, arguments[1] || { }) | ||
+ | ); | ||
+ | }; | ||
+ | |||
+ | Effect.BlindDown = function(element) { | ||
+ | element = $(element); | ||
+ | var elementDimensions = element.getDimensions(); | ||
+ | return new Effect.Scale(element, 100, Object.extend({ | ||
+ | scaleContent: false, | ||
+ | scaleX: false, | ||
+ | scaleFrom: 0, | ||
+ | scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, | ||
+ | restoreAfterFinish: true, | ||
+ | afterSetup: function(effect) { | ||
+ | effect.element.makeClipping().setStyle({height: '0px'}).show(); | ||
+ | }, | ||
+ | afterFinishInternal: function(effect) { | ||
+ | effect.element.undoClipping(); | ||
+ | } | ||
+ | }, arguments[1] || { })); | ||
+ | }; | ||
+ | |||
+ | Effect.SwitchOff = function(element) { | ||
+ | element = $(element); | ||
+ | var oldOpacity = element.getInlineOpacity(); | ||
+ | return new Effect.Appear(element, Object.extend({ | ||
+ | duration: 0.4, | ||
+ | from: 0, | ||
+ | transition: Effect.Transitions.flicker, | ||
+ | afterFinishInternal: function(effect) { | ||
+ | new Effect.Scale(effect.element, 1, { | ||
+ | duration: 0.3, scaleFromCenter: true, | ||
+ | scaleX: false, scaleContent: false, restoreAfterFinish: true, | ||
+ | beforeSetup: function(effect) { | ||
+ | effect.element.makePositioned().makeClipping(); | ||
+ | }, | ||
+ | afterFinishInternal: function(effect) { | ||
+ | effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity}); | ||
+ | } | ||
+ | }); | ||
+ | } | ||
+ | }, arguments[1] || { })); | ||
+ | }; | ||
+ | |||
+ | Effect.DropOut = function(element) { | ||
+ | element = $(element); | ||
+ | var oldStyle = { | ||
+ | top: element.getStyle('top'), | ||
+ | left: element.getStyle('left'), | ||
+ | opacity: element.getInlineOpacity() }; | ||
+ | return new Effect.Parallel( | ||
+ | [ new Effect.Move(element, {x: 0, y: 100, sync: true }), | ||
+ | new Effect.Opacity(element, { sync: true, to: 0.0 }) ], | ||
+ | Object.extend( | ||
+ | { duration: 0.5, | ||
+ | beforeSetup: function(effect) { | ||
+ | effect.effects[0].element.makePositioned(); | ||
+ | }, | ||
+ | afterFinishInternal: function(effect) { | ||
+ | effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle); | ||
+ | } | ||
+ | }, arguments[1] || { })); | ||
+ | }; | ||
+ | |||
+ | Effect.Shake = function(element) { | ||
+ | element = $(element); | ||
+ | var options = Object.extend({ | ||
+ | distance: 20, | ||
+ | duration: 0.5 | ||
+ | }, arguments[1] || {}); | ||
+ | var distance = parseFloat(options.distance); | ||
+ | var split = parseFloat(options.duration) / 10.0; | ||
+ | var oldStyle = { | ||
+ | top: element.getStyle('top'), | ||
+ | left: element.getStyle('left') }; | ||
+ | return new Effect.Move(element, | ||
+ | { x: distance, y: 0, duration: split, afterFinishInternal: function(effect) { | ||
+ | new Effect.Move(effect.element, | ||
+ | { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { | ||
+ | new Effect.Move(effect.element, | ||
+ | { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { | ||
+ | new Effect.Move(effect.element, | ||
+ | { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { | ||
+ | new Effect.Move(effect.element, | ||
+ | { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { | ||
+ | new Effect.Move(effect.element, | ||
+ | { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) { | ||
+ | effect.element.undoPositioned().setStyle(oldStyle); | ||
+ | }}); }}); }}); }}); }}); }}); | ||
+ | }; | ||
+ | |||
+ | Effect.SlideDown = function(element) { | ||
+ | element = $(element).cleanWhitespace(); | ||
+ | // SlideDown need to have the content of the element wrapped in a container element with fixed height! | ||
+ | var oldInnerBottom = element.down().getStyle('bottom'); | ||
+ | var elementDimensions = element.getDimensions(); | ||
+ | return new Effect.Scale(element, 100, Object.extend({ | ||
+ | scaleContent: false, | ||
+ | scaleX: false, | ||
+ | scaleFrom: window.opera ? 0 : 1, | ||
+ | scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, | ||
+ | restoreAfterFinish: true, | ||
+ | afterSetup: function(effect) { | ||
+ | effect.element.makePositioned(); | ||
+ | effect.element.down().makePositioned(); | ||
+ | if (window.opera) effect.element.setStyle({top: ''}); | ||
+ | effect.element.makeClipping().setStyle({height: '0px'}).show(); | ||
+ | }, | ||
+ | afterUpdateInternal: function(effect) { | ||
+ | effect.element.down().setStyle({bottom: | ||
+ | (effect.dims[0] - effect.element.clientHeight) + 'px' }); | ||
+ | }, | ||
+ | afterFinishInternal: function(effect) { | ||
+ | effect.element.undoClipping().undoPositioned(); | ||
+ | effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); } | ||
+ | }, arguments[1] || { }) | ||
+ | ); | ||
+ | }; | ||
+ | |||
+ | Effect.SlideUp = function(element) { | ||
+ | element = $(element).cleanWhitespace(); | ||
+ | var oldInnerBottom = element.down().getStyle('bottom'); | ||
+ | var elementDimensions = element.getDimensions(); | ||
+ | return new Effect.Scale(element, window.opera ? 0 : 1, | ||
+ | Object.extend({ scaleContent: false, | ||
+ | scaleX: false, | ||
+ | scaleMode: 'box', | ||
+ | scaleFrom: 100, | ||
+ | scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, | ||
+ | restoreAfterFinish: true, | ||
+ | afterSetup: function(effect) { | ||
+ | effect.element.makePositioned(); | ||
+ | effect.element.down().makePositioned(); | ||
+ | if (window.opera) effect.element.setStyle({top: ''}); | ||
+ | effect.element.makeClipping().show(); | ||
+ | }, | ||
+ | afterUpdateInternal: function(effect) { | ||
+ | effect.element.down().setStyle({bottom: | ||
+ | (effect.dims[0] - effect.element.clientHeight) + 'px' }); | ||
+ | }, | ||
+ | afterFinishInternal: function(effect) { | ||
+ | effect.element.hide().undoClipping().undoPositioned(); | ||
+ | effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); | ||
+ | } | ||
+ | }, arguments[1] || { }) | ||
+ | ); | ||
+ | }; | ||
+ | |||
+ | // Bug in opera makes the TD containing this element expand for a instance after finish | ||
+ | Effect.Squish = function(element) { | ||
+ | return new Effect.Scale(element, window.opera ? 1 : 0, { | ||
+ | restoreAfterFinish: true, | ||
+ | beforeSetup: function(effect) { | ||
+ | effect.element.makeClipping(); | ||
+ | }, | ||
+ | afterFinishInternal: function(effect) { | ||
+ | effect.element.hide().undoClipping(); | ||
+ | } | ||
+ | }); | ||
+ | }; | ||
+ | |||
+ | Effect.Grow = function(element) { | ||
+ | element = $(element); | ||
+ | var options = Object.extend({ | ||
+ | direction: 'center', | ||
+ | moveTransition: Effect.Transitions.sinoidal, | ||
+ | scaleTransition: Effect.Transitions.sinoidal, | ||
+ | opacityTransition: Effect.Transitions.full | ||
+ | }, arguments[1] || { }); | ||
+ | var oldStyle = { | ||
+ | top: element.style.top, | ||
+ | left: element.style.left, | ||
+ | height: element.style.height, | ||
+ | width: element.style.width, | ||
+ | opacity: element.getInlineOpacity() }; | ||
+ | |||
+ | var dims = element.getDimensions(); | ||
+ | var initialMoveX, initialMoveY; | ||
+ | var moveX, moveY; | ||
+ | |||
+ | switch (options.direction) { | ||
+ | case 'top-left': | ||
+ | initialMoveX = initialMoveY = moveX = moveY = 0; | ||
+ | break; | ||
+ | case 'top-right': | ||
+ | initialMoveX = dims.width; | ||
+ | initialMoveY = moveY = 0; | ||
+ | moveX = -dims.width; | ||
+ | break; | ||
+ | case 'bottom-left': | ||
+ | initialMoveX = moveX = 0; | ||
+ | initialMoveY = dims.height; | ||
+ | moveY = -dims.height; | ||
+ | break; | ||
+ | case 'bottom-right': | ||
+ | initialMoveX = dims.width; | ||
+ | initialMoveY = dims.height; | ||
+ | moveX = -dims.width; | ||
+ | moveY = -dims.height; | ||
+ | break; | ||
+ | case 'center': | ||
+ | initialMoveX = dims.width / 2; | ||
+ | initialMoveY = dims.height / 2; | ||
+ | moveX = -dims.width / 2; | ||
+ | moveY = -dims.height / 2; | ||
+ | break; | ||
+ | } | ||
+ | |||
+ | return new Effect.Move(element, { | ||
+ | x: initialMoveX, | ||
+ | y: initialMoveY, | ||
+ | duration: 0.01, | ||
+ | beforeSetup: function(effect) { | ||
+ | effect.element.hide().makeClipping().makePositioned(); | ||
+ | }, | ||
+ | afterFinishInternal: function(effect) { | ||
+ | new Effect.Parallel( | ||
+ | [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }), | ||
+ | new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }), | ||
+ | new Effect.Scale(effect.element, 100, { | ||
+ | scaleMode: { originalHeight: dims.height, originalWidth: dims.width }, | ||
+ | sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true}) | ||
+ | ], Object.extend({ | ||
+ | beforeSetup: function(effect) { | ||
+ | effect.effects[0].element.setStyle({height: '0px'}).show(); | ||
+ | }, | ||
+ | afterFinishInternal: function(effect) { | ||
+ | effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle); | ||
+ | } | ||
+ | }, options) | ||
+ | ); | ||
+ | } | ||
+ | }); | ||
+ | }; | ||
+ | |||
+ | Effect.Shrink = function(element) { | ||
+ | element = $(element); | ||
+ | var options = Object.extend({ | ||
+ | direction: 'center', | ||
+ | moveTransition: Effect.Transitions.sinoidal, | ||
+ | scaleTransition: Effect.Transitions.sinoidal, | ||
+ | opacityTransition: Effect.Transitions.none | ||
+ | }, arguments[1] || { }); | ||
+ | var oldStyle = { | ||
+ | top: element.style.top, | ||
+ | left: element.style.left, | ||
+ | height: element.style.height, | ||
+ | width: element.style.width, | ||
+ | opacity: element.getInlineOpacity() }; | ||
+ | |||
+ | var dims = element.getDimensions(); | ||
+ | var moveX, moveY; | ||
+ | |||
+ | switch (options.direction) { | ||
+ | case 'top-left': | ||
+ | moveX = moveY = 0; | ||
+ | break; | ||
+ | case 'top-right': | ||
+ | moveX = dims.width; | ||
+ | moveY = 0; | ||
+ | break; | ||
+ | case 'bottom-left': | ||
+ | moveX = 0; | ||
+ | moveY = dims.height; | ||
+ | break; | ||
+ | case 'bottom-right': | ||
+ | moveX = dims.width; | ||
+ | moveY = dims.height; | ||
+ | break; | ||
+ | case 'center': | ||
+ | moveX = dims.width / 2; | ||
+ | moveY = dims.height / 2; | ||
+ | break; | ||
+ | } | ||
+ | |||
+ | return new Effect.Parallel( | ||
+ | [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }), | ||
+ | new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}), | ||
+ | new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }) | ||
+ | ], Object.extend({ | ||
+ | beforeStartInternal: function(effect) { | ||
+ | effect.effects[0].element.makePositioned().makeClipping(); | ||
+ | }, | ||
+ | afterFinishInternal: function(effect) { | ||
+ | effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); } | ||
+ | }, options) | ||
+ | ); | ||
+ | }; | ||
+ | |||
+ | Effect.Pulsate = function(element) { | ||
+ | element = $(element); | ||
+ | var options = arguments[1] || { }, | ||
+ | oldOpacity = element.getInlineOpacity(), | ||
+ | transition = options.transition || Effect.Transitions.linear, | ||
+ | reverser = function(pos){ | ||
+ | return 1 - transition((-Math.cos((pos*(options.pulses||5)*2)*Math.PI)/2) + .5); | ||
+ | }; | ||
+ | |||
+ | return new Effect.Opacity(element, | ||
+ | Object.extend(Object.extend({ duration: 2.0, from: 0, | ||
+ | afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); } | ||
+ | }, options), {transition: reverser})); | ||
+ | }; | ||
+ | |||
+ | Effect.Fold = function(element) { | ||
+ | element = $(element); | ||
+ | var oldStyle = { | ||
+ | top: element.style.top, | ||
+ | left: element.style.left, | ||
+ | width: element.style.width, | ||
+ | height: element.style.height }; | ||
+ | element.makeClipping(); | ||
+ | return new Effect.Scale(element, 5, Object.extend({ | ||
+ | scaleContent: false, | ||
+ | scaleX: false, | ||
+ | afterFinishInternal: function(effect) { | ||
+ | new Effect.Scale(element, 1, { | ||
+ | scaleContent: false, | ||
+ | scaleY: false, | ||
+ | afterFinishInternal: function(effect) { | ||
+ | effect.element.hide().undoClipping().setStyle(oldStyle); | ||
+ | } }); | ||
+ | }}, arguments[1] || { })); | ||
+ | }; | ||
+ | |||
+ | Effect.Morph = Class.create(Effect.Base, { | ||
+ | initialize: function(element) { | ||
+ | this.element = $(element); | ||
+ | if (!this.element) throw(Effect._elementDoesNotExistError); | ||
+ | var options = Object.extend({ | ||
+ | style: { } | ||
+ | }, arguments[1] || { }); | ||
+ | |||
+ | if (!Object.isString(options.style)) this.style = $H(options.style); | ||
+ | else { | ||
+ | if (options.style.include(':')) | ||
+ | this.style = options.style.parseStyle(); | ||
+ | else { | ||
+ | this.element.addClassName(options.style); | ||
+ | this.style = $H(this.element.getStyles()); | ||
+ | this.element.removeClassName(options.style); | ||
+ | var css = this.element.getStyles(); | ||
+ | this.style = this.style.reject(function(style) { | ||
+ | return style.value == css[style.key]; | ||
+ | }); | ||
+ | options.afterFinishInternal = function(effect) { | ||
+ | effect.element.addClassName(effect.options.style); | ||
+ | effect.transforms.each(function(transform) { | ||
+ | effect.element.style[transform.style] = ''; | ||
+ | }); | ||
+ | }; | ||
+ | } | ||
+ | } | ||
+ | this.start(options); | ||
+ | }, | ||
+ | |||
+ | setup: function(){ | ||
+ | function parseColor(color){ | ||
+ | if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff'; | ||
+ | color = color.parseColor(); | ||
+ | return $R(0,2).map(function(i){ | ||
+ | return parseInt( color.slice(i*2+1,i*2+3), 16 ); | ||
+ | }); | ||
+ | } | ||
+ | this.transforms = this.style.map(function(pair){ | ||
+ | var property = pair[0], value = pair[1], unit = null; | ||
+ | |||
+ | if (value.parseColor('#zzzzzz') != '#zzzzzz') { | ||
+ | value = value.parseColor(); | ||
+ | unit = 'color'; | ||
+ | } else if (property == 'opacity') { | ||
+ | value = parseFloat(value); | ||
+ | if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout)) | ||
+ | this.element.setStyle({zoom: 1}); | ||
+ | } else if (Element.CSS_LENGTH.test(value)) { | ||
+ | var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/); | ||
+ | value = parseFloat(components[1]); | ||
+ | unit = (components.length == 3) ? components[2] : null; | ||
+ | } | ||
+ | |||
+ | var originalValue = this.element.getStyle(property); | ||
+ | return { | ||
+ | style: property.camelize(), | ||
+ | originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0), | ||
+ | targetValue: unit=='color' ? parseColor(value) : value, | ||
+ | unit: unit | ||
+ | }; | ||
+ | }.bind(this)).reject(function(transform){ | ||
+ | return ( | ||
+ | (transform.originalValue == transform.targetValue) || | ||
+ | ( | ||
+ | transform.unit != 'color' && | ||
+ | (isNaN(transform.originalValue) || isNaN(transform.targetValue)) | ||
+ | ) | ||
+ | ); | ||
+ | }); | ||
+ | }, | ||
+ | update: function(position) { | ||
+ | var style = { }, transform, i = this.transforms.length; | ||
+ | while(i--) | ||
+ | style[(transform = this.transforms[i]).style] = | ||
+ | transform.unit=='color' ? '#'+ | ||
+ | (Math.round(transform.originalValue[0]+ | ||
+ | (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() + | ||
+ | (Math.round(transform.originalValue[1]+ | ||
+ | (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() + | ||
+ | (Math.round(transform.originalValue[2]+ | ||
+ | (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() : | ||
+ | (transform.originalValue + | ||
+ | (transform.targetValue - transform.originalValue) * position).toFixed(3) + | ||
+ | (transform.unit === null ? '' : transform.unit); | ||
+ | this.element.setStyle(style, true); | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | Effect.Transform = Class.create({ | ||
+ | initialize: function(tracks){ | ||
+ | this.tracks = []; | ||
+ | this.options = arguments[1] || { }; | ||
+ | this.addTracks(tracks); | ||
+ | }, | ||
+ | addTracks: function(tracks){ | ||
+ | tracks.each(function(track){ | ||
+ | track = $H(track); | ||
+ | var data = track.values().first(); | ||
+ | this.tracks.push($H({ | ||
+ | ids: track.keys().first(), | ||
+ | effect: Effect.Morph, | ||
+ | options: { style: data } | ||
+ | })); | ||
+ | }.bind(this)); | ||
+ | return this; | ||
+ | }, | ||
+ | play: function(){ | ||
+ | return new Effect.Parallel( | ||
+ | this.tracks.map(function(track){ | ||
+ | var ids = track.get('ids'), effect = track.get('effect'), options = track.get('options'); | ||
+ | var elements = [$(ids) || $$(ids)].flatten(); | ||
+ | return elements.map(function(e){ return new effect(e, Object.extend({ sync:true }, options)) }); | ||
+ | }).flatten(), | ||
+ | this.options | ||
+ | ); | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | Element.CSS_PROPERTIES = $w( | ||
+ | 'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' + | ||
+ | 'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' + | ||
+ | 'borderRightColor borderRightStyle borderRightWidth borderSpacing ' + | ||
+ | 'borderTopColor borderTopStyle borderTopWidth bottom clip color ' + | ||
+ | 'fontSize fontWeight height left letterSpacing lineHeight ' + | ||
+ | 'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+ | ||
+ | 'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' + | ||
+ | 'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' + | ||
+ | 'right textIndent top width wordSpacing zIndex'); | ||
+ | |||
+ | Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/; | ||
+ | |||
+ | String.__parseStyleElement = document.createElement('div'); | ||
+ | String.prototype.parseStyle = function(){ | ||
+ | var style, styleRules = $H(); | ||
+ | if (Prototype.Browser.WebKit) | ||
+ | style = new Element('div',{style:this}).style; | ||
+ | else { | ||
+ | String.__parseStyleElement.innerHTML = '<div style="' + this + '"></div>'; | ||
+ | style = String.__parseStyleElement.childNodes[0].style; | ||
+ | } | ||
+ | |||
+ | Element.CSS_PROPERTIES.each(function(property){ | ||
+ | if (style[property]) styleRules.set(property, style[property]); | ||
+ | }); | ||
+ | |||
+ | if (Prototype.Browser.IE && this.include('opacity')) | ||
+ | styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]); | ||
+ | |||
+ | return styleRules; | ||
+ | }; | ||
+ | |||
+ | if (document.defaultView && document.defaultView.getComputedStyle) { | ||
+ | Element.getStyles = function(element) { | ||
+ | var css = document.defaultView.getComputedStyle($(element), null); | ||
+ | return Element.CSS_PROPERTIES.inject({ }, function(styles, property) { | ||
+ | styles[property] = css[property]; | ||
+ | return styles; | ||
+ | }); | ||
+ | }; | ||
+ | } else { | ||
+ | Element.getStyles = function(element) { | ||
+ | element = $(element); | ||
+ | var css = element.currentStyle, styles; | ||
+ | styles = Element.CSS_PROPERTIES.inject({ }, function(results, property) { | ||
+ | results[property] = css[property]; | ||
+ | return results; | ||
+ | }); | ||
+ | if (!styles.opacity) styles.opacity = element.getOpacity(); | ||
+ | return styles; | ||
+ | }; | ||
} | } | ||
+ | Effect.Methods = { | ||
+ | morph: function(element, style) { | ||
+ | element = $(element); | ||
+ | new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { })); | ||
+ | return element; | ||
+ | }, | ||
+ | visualEffect: function(element, effect, options) { | ||
+ | element = $(element); | ||
+ | var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1); | ||
+ | new Effect[klass](element, options); | ||
+ | return element; | ||
+ | }, | ||
+ | highlight: function(element, options) { | ||
+ | element = $(element); | ||
+ | new Effect.Highlight(element, options); | ||
+ | return element; | ||
+ | } | ||
+ | }; | ||
+ | $w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+ | ||
+ | 'pulsate shake puff squish switchOff dropOut').each( | ||
+ | function(effect) { | ||
+ | Effect.Methods[effect] = function(element, options){ | ||
+ | element = $(element); | ||
+ | Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options); | ||
+ | return element; | ||
+ | }; | ||
+ | } | ||
+ | ); | ||
- | + | $w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each( | |
- | + | function(f) { Effect.Methods[f] = Element[f]; } | |
- | + | ); | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | Element.addMethods(Effect.Methods); | |
- | + | </script> | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
+ | <script type="text/javascript"> | ||
+ | /* Prototype JavaScript framework, version 1.6.1 | ||
+ | * (c) 2005-2009 Sam Stephenson | ||
+ | * | ||
+ | * Prototype is freely distributable under the terms of an MIT-style license. | ||
+ | * For details, see the Prototype web site: http://www.prototypejs.org/ | ||
+ | * | ||
+ | *--------------------------------------------------------------------------*/ | ||
- | + | var Prototype = { | |
- | + | Version: '1.6.1', | |
+ | |||
+ | Browser: (function(){ | ||
+ | var ua = navigator.userAgent; | ||
+ | var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]'; | ||
+ | return { | ||
+ | IE: !!window.attachEvent && !isOpera, | ||
+ | Opera: isOpera, | ||
+ | WebKit: ua.indexOf('AppleWebKit/') > -1, | ||
+ | Gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1, | ||
+ | MobileSafari: /Apple.*Mobile.*Safari/.test(ua) | ||
+ | } | ||
+ | })(), | ||
+ | |||
+ | BrowserFeatures: { | ||
+ | XPath: !!document.evaluate, | ||
+ | SelectorsAPI: !!document.querySelector, | ||
+ | ElementExtensions: (function() { | ||
+ | var constructor = window.Element || window.HTMLElement; | ||
+ | return !!(constructor && constructor.prototype); | ||
+ | })(), | ||
+ | SpecificElementExtensions: (function() { | ||
+ | if (typeof window.HTMLDivElement !== 'undefined') | ||
+ | return true; | ||
+ | |||
+ | var div = document.createElement('div'); | ||
+ | var form = document.createElement('form'); | ||
+ | var isSupported = false; | ||
+ | |||
+ | if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) { | ||
+ | isSupported = true; | ||
+ | } | ||
+ | |||
+ | div = form = null; | ||
+ | |||
+ | return isSupported; | ||
+ | })() | ||
+ | }, | ||
+ | |||
+ | ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>', | ||
+ | JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/, | ||
+ | |||
+ | emptyFunction: function() { }, | ||
+ | K: function(x) { return x } | ||
+ | }; | ||
+ | |||
+ | if (Prototype.Browser.MobileSafari) | ||
+ | Prototype.BrowserFeatures.SpecificElementExtensions = false; | ||
+ | |||
+ | |||
+ | var Abstract = { }; | ||
+ | |||
+ | |||
+ | var Try = { | ||
+ | these: function() { | ||
+ | var returnValue; | ||
+ | |||
+ | for (var i = 0, length = arguments.length; i < length; i++) { | ||
+ | var lambda = arguments[i]; | ||
+ | try { | ||
+ | returnValue = lambda(); | ||
+ | break; | ||
+ | } catch (e) { } | ||
+ | } | ||
+ | |||
+ | return returnValue; | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | /* Based on Alex Arnell's inheritance implementation. */ | ||
+ | |||
+ | var Class = (function() { | ||
+ | function subclass() {}; | ||
+ | function create() { | ||
+ | var parent = null, properties = $A(arguments); | ||
+ | if (Object.isFunction(properties[0])) | ||
+ | parent = properties.shift(); | ||
+ | |||
+ | function klass() { | ||
+ | this.initialize.apply(this, arguments); | ||
+ | } | ||
+ | |||
+ | Object.extend(klass, Class.Methods); | ||
+ | klass.superclass = parent; | ||
+ | klass.subclasses = []; | ||
+ | |||
+ | if (parent) { | ||
+ | subclass.prototype = parent.prototype; | ||
+ | klass.prototype = new subclass; | ||
+ | parent.subclasses.push(klass); | ||
+ | } | ||
+ | |||
+ | for (var i = 0; i < properties.length; i++) | ||
+ | klass.addMethods(properties[i]); | ||
+ | |||
+ | if (!klass.prototype.initialize) | ||
+ | klass.prototype.initialize = Prototype.emptyFunction; | ||
+ | |||
+ | klass.prototype.constructor = klass; | ||
+ | return klass; | ||
+ | } | ||
+ | |||
+ | function addMethods(source) { | ||
+ | var ancestor = this.superclass && this.superclass.prototype; | ||
+ | var properties = Object.keys(source); | ||
+ | |||
+ | if (!Object.keys({ toString: true }).length) { | ||
+ | if (source.toString != Object.prototype.toString) | ||
+ | properties.push("toString"); | ||
+ | if (source.valueOf != Object.prototype.valueOf) | ||
+ | properties.push("valueOf"); | ||
+ | } | ||
+ | |||
+ | for (var i = 0, length = properties.length; i < length; i++) { | ||
+ | var property = properties[i], value = source[property]; | ||
+ | if (ancestor && Object.isFunction(value) && | ||
+ | value.argumentNames().first() == "$super") { | ||
+ | var method = value; | ||
+ | value = (function(m) { | ||
+ | return function() { return ancestor[m].apply(this, arguments); }; | ||
+ | })(property).wrap(method); | ||
+ | |||
+ | value.valueOf = method.valueOf.bind(method); | ||
+ | value.toString = method.toString.bind(method); | ||
+ | } | ||
+ | this.prototype[property] = value; | ||
+ | } | ||
+ | |||
+ | return this; | ||
+ | } | ||
+ | |||
+ | return { | ||
+ | create: create, | ||
+ | Methods: { | ||
+ | addMethods: addMethods | ||
+ | } | ||
+ | }; | ||
+ | })(); | ||
+ | (function() { | ||
+ | |||
+ | var _toString = Object.prototype.toString; | ||
+ | |||
+ | function extend(destination, source) { | ||
+ | for (var property in source) | ||
+ | destination[property] = source[property]; | ||
+ | return destination; | ||
+ | } | ||
+ | |||
+ | function inspect(object) { | ||
+ | try { | ||
+ | if (isUndefined(object)) return 'undefined'; | ||
+ | if (object === null) return 'null'; | ||
+ | return object.inspect ? object.inspect() : String(object); | ||
+ | } catch (e) { | ||
+ | if (e instanceof RangeError) return '...'; | ||
+ | throw e; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | function toJSON(object) { | ||
+ | var type = typeof object; | ||
+ | switch (type) { | ||
+ | case 'undefined': | ||
+ | case 'function': | ||
+ | case 'unknown': return; | ||
+ | case 'boolean': return object.toString(); | ||
+ | } | ||
+ | |||
+ | if (object === null) return 'null'; | ||
+ | if (object.toJSON) return object.toJSON(); | ||
+ | if (isElement(object)) return; | ||
+ | |||
+ | var results = []; | ||
+ | for (var property in object) { | ||
+ | var value = toJSON(object[property]); | ||
+ | if (!isUndefined(value)) | ||
+ | results.push(property.toJSON() + ': ' + value); | ||
+ | } | ||
+ | |||
+ | return '{' + results.join(', ') + '}'; | ||
+ | } | ||
+ | |||
+ | function toQueryString(object) { | ||
+ | return $H(object).toQueryString(); | ||
+ | } | ||
+ | |||
+ | function toHTML(object) { | ||
+ | return object && object.toHTML ? object.toHTML() : String.interpret(object); | ||
+ | } | ||
+ | |||
+ | function keys(object) { | ||
+ | var results = []; | ||
+ | for (var property in object) | ||
+ | results.push(property); | ||
+ | return results; | ||
+ | } | ||
+ | |||
+ | function values(object) { | ||
+ | var results = []; | ||
+ | for (var property in object) | ||
+ | results.push(object[property]); | ||
+ | return results; | ||
+ | } | ||
+ | |||
+ | function clone(object) { | ||
+ | return extend({ }, object); | ||
+ | } | ||
+ | |||
+ | function isElement(object) { | ||
+ | return !!(object && object.nodeType == 1); | ||
+ | } | ||
+ | |||
+ | function isArray(object) { | ||
+ | return _toString.call(object) == "[object Array]"; | ||
+ | } | ||
+ | |||
+ | |||
+ | function isHash(object) { | ||
+ | return object instanceof Hash; | ||
+ | } | ||
+ | |||
+ | function isFunction(object) { | ||
+ | return typeof object === "function"; | ||
+ | } | ||
+ | |||
+ | function isString(object) { | ||
+ | return _toString.call(object) == "[object String]"; | ||
+ | } | ||
+ | |||
+ | function isNumber(object) { | ||
+ | return _toString.call(object) == "[object Number]"; | ||
+ | } | ||
+ | |||
+ | function isUndefined(object) { | ||
+ | return typeof object === "undefined"; | ||
+ | } | ||
+ | |||
+ | extend(Object, { | ||
+ | extend: extend, | ||
+ | inspect: inspect, | ||
+ | toJSON: toJSON, | ||
+ | toQueryString: toQueryString, | ||
+ | toHTML: toHTML, | ||
+ | keys: keys, | ||
+ | values: values, | ||
+ | clone: clone, | ||
+ | isElement: isElement, | ||
+ | isArray: isArray, | ||
+ | isHash: isHash, | ||
+ | isFunction: isFunction, | ||
+ | isString: isString, | ||
+ | isNumber: isNumber, | ||
+ | isUndefined: isUndefined | ||
+ | }); | ||
+ | })(); | ||
+ | Object.extend(Function.prototype, (function() { | ||
+ | var slice = Array.prototype.slice; | ||
+ | |||
+ | function update(array, args) { | ||
+ | var arrayLength = array.length, length = args.length; | ||
+ | while (length--) array[arrayLength + length] = args[length]; | ||
+ | return array; | ||
+ | } | ||
+ | |||
+ | function merge(array, args) { | ||
+ | array = slice.call(array, 0); | ||
+ | return update(array, args); | ||
+ | } | ||
+ | |||
+ | function argumentNames() { | ||
+ | var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1] | ||
+ | .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '') | ||
+ | .replace(/\s+/g, '').split(','); | ||
+ | return names.length == 1 && !names[0] ? [] : names; | ||
+ | } | ||
+ | |||
+ | function bind(context) { | ||
+ | if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this; | ||
+ | var __method = this, args = slice.call(arguments, 1); | ||
+ | return function() { | ||
+ | var a = merge(args, arguments); | ||
+ | return __method.apply(context, a); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | function bindAsEventListener(context) { | ||
+ | var __method = this, args = slice.call(arguments, 1); | ||
+ | return function(event) { | ||
+ | var a = update([event || window.event], args); | ||
+ | return __method.apply(context, a); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | function curry() { | ||
+ | if (!arguments.length) return this; | ||
+ | var __method = this, args = slice.call(arguments, 0); | ||
+ | return function() { | ||
+ | var a = merge(args, arguments); | ||
+ | return __method.apply(this, a); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | function delay(timeout) { | ||
+ | var __method = this, args = slice.call(arguments, 1); | ||
+ | timeout = timeout * 1000 | ||
+ | return window.setTimeout(function() { | ||
+ | return __method.apply(__method, args); | ||
+ | }, timeout); | ||
+ | } | ||
+ | |||
+ | function defer() { | ||
+ | var args = update([0.01], arguments); | ||
+ | return this.delay.apply(this, args); | ||
+ | } | ||
+ | |||
+ | function wrap(wrapper) { | ||
+ | var __method = this; | ||
+ | return function() { | ||
+ | var a = update([__method.bind(this)], arguments); | ||
+ | return wrapper.apply(this, a); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | function methodize() { | ||
+ | if (this._methodized) return this._methodized; | ||
+ | var __method = this; | ||
+ | return this._methodized = function() { | ||
+ | var a = update([this], arguments); | ||
+ | return __method.apply(null, a); | ||
+ | }; | ||
+ | } | ||
+ | |||
+ | return { | ||
+ | argumentNames: argumentNames, | ||
+ | bind: bind, | ||
+ | bindAsEventListener: bindAsEventListener, | ||
+ | curry: curry, | ||
+ | delay: delay, | ||
+ | defer: defer, | ||
+ | wrap: wrap, | ||
+ | methodize: methodize | ||
+ | } | ||
+ | })()); | ||
+ | |||
+ | |||
+ | Date.prototype.toJSON = function() { | ||
+ | return '"' + this.getUTCFullYear() + '-' + | ||
+ | (this.getUTCMonth() + 1).toPaddedString(2) + '-' + | ||
+ | this.getUTCDate().toPaddedString(2) + 'T' + | ||
+ | this.getUTCHours().toPaddedString(2) + ':' + | ||
+ | this.getUTCMinutes().toPaddedString(2) + ':' + | ||
+ | this.getUTCSeconds().toPaddedString(2) + 'Z"'; | ||
+ | }; | ||
+ | |||
+ | |||
+ | RegExp.prototype.match = RegExp.prototype.test; | ||
+ | |||
+ | RegExp.escape = function(str) { | ||
+ | return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); | ||
+ | }; | ||
+ | var PeriodicalExecuter = Class.create({ | ||
+ | initialize: function(callback, frequency) { | ||
+ | this.callback = callback; | ||
+ | this.frequency = frequency; | ||
+ | this.currentlyExecuting = false; | ||
+ | |||
+ | this.registerCallback(); | ||
+ | }, | ||
+ | |||
+ | registerCallback: function() { | ||
+ | this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); | ||
+ | }, | ||
+ | |||
+ | execute: function() { | ||
+ | this.callback(this); | ||
+ | }, | ||
+ | |||
+ | stop: function() { | ||
+ | if (!this.timer) return; | ||
+ | clearInterval(this.timer); | ||
+ | this.timer = null; | ||
+ | }, | ||
+ | |||
+ | onTimerEvent: function() { | ||
+ | if (!this.currentlyExecuting) { | ||
+ | try { | ||
+ | this.currentlyExecuting = true; | ||
+ | this.execute(); | ||
+ | this.currentlyExecuting = false; | ||
+ | } catch(e) { | ||
+ | this.currentlyExecuting = false; | ||
+ | throw e; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | }); | ||
+ | Object.extend(String, { | ||
+ | interpret: function(value) { | ||
+ | return value == null ? '' : String(value); | ||
+ | }, | ||
+ | specialChar: { | ||
+ | '\b': '\\b', | ||
+ | '\t': '\\t', | ||
+ | '\n': '\\n', | ||
+ | '\f': '\\f', | ||
+ | '\r': '\\r', | ||
+ | '\\': '\\\\' | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | Object.extend(String.prototype, (function() { | ||
+ | |||
+ | function prepareReplacement(replacement) { | ||
+ | if (Object.isFunction(replacement)) return replacement; | ||
+ | var template = new Template(replacement); | ||
+ | return function(match) { return template.evaluate(match) }; | ||
+ | } | ||
+ | |||
+ | function gsub(pattern, replacement) { | ||
+ | var result = '', source = this, match; | ||
+ | replacement = prepareReplacement(replacement); | ||
+ | |||
+ | if (Object.isString(pattern)) | ||
+ | pattern = RegExp.escape(pattern); | ||
+ | |||
+ | if (!(pattern.length || pattern.source)) { | ||
+ | replacement = replacement(''); | ||
+ | return replacement + source.split('').join(replacement) + replacement; | ||
+ | } | ||
+ | |||
+ | while (source.length > 0) { | ||
+ | if (match = source.match(pattern)) { | ||
+ | result += source.slice(0, match.index); | ||
+ | result += String.interpret(replacement(match)); | ||
+ | source = source.slice(match.index + match[0].length); | ||
+ | } else { | ||
+ | result += source, source = ''; | ||
+ | } | ||
+ | } | ||
+ | return result; | ||
+ | } | ||
+ | |||
+ | function sub(pattern, replacement, count) { | ||
+ | replacement = prepareReplacement(replacement); | ||
+ | count = Object.isUndefined(count) ? 1 : count; | ||
+ | |||
+ | return this.gsub(pattern, function(match) { | ||
+ | if (--count < 0) return match[0]; | ||
+ | return replacement(match); | ||
+ | }); | ||
+ | } | ||
+ | |||
+ | function scan(pattern, iterator) { | ||
+ | this.gsub(pattern, iterator); | ||
+ | return String(this); | ||
+ | } | ||
+ | |||
+ | function truncate(length, truncation) { | ||
+ | length = length || 30; | ||
+ | truncation = Object.isUndefined(truncation) ? '...' : truncation; | ||
+ | return this.length > length ? | ||
+ | this.slice(0, length - truncation.length) + truncation : String(this); | ||
+ | } | ||
+ | |||
+ | function strip() { | ||
+ | return this.replace(/^\s+/, '').replace(/\s+$/, ''); | ||
+ | } | ||
+ | |||
+ | function stripTags() { | ||
+ | return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, ''); | ||
+ | } | ||
+ | |||
+ | function stripScripts() { | ||
+ | return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); | ||
+ | } | ||
+ | |||
+ | function extractScripts() { | ||
+ | var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); | ||
+ | var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); | ||
+ | return (this.match(matchAll) || []).map(function(scriptTag) { | ||
+ | return (scriptTag.match(matchOne) || ['', ''])[1]; | ||
+ | }); | ||
+ | } | ||
+ | |||
+ | function evalScripts() { | ||
+ | return this.extractScripts().map(function(script) { return eval(script) }); | ||
+ | } | ||
+ | |||
+ | function escapeHTML() { | ||
+ | return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); | ||
+ | } | ||
+ | |||
+ | function unescapeHTML() { | ||
+ | return this.stripTags().replace(/</g,'<').replace(/>/g,'>').replace(/&/g,'&'); | ||
+ | } | ||
+ | |||
+ | |||
+ | function toQueryParams(separator) { | ||
+ | var match = this.strip().match(/([^?#]*)(#.*)?$/); | ||
+ | if (!match) return { }; | ||
+ | |||
+ | return match[1].split(separator || '&').inject({ }, function(hash, pair) { | ||
+ | if ((pair = pair.split('='))[0]) { | ||
+ | var key = decodeURIComponent(pair.shift()); | ||
+ | var value = pair.length > 1 ? pair.join('=') : pair[0]; | ||
+ | if (value != undefined) value = decodeURIComponent(value); | ||
+ | |||
+ | if (key in hash) { | ||
+ | if (!Object.isArray(hash[key])) hash[key] = [hash[key]]; | ||
+ | hash[key].push(value); | ||
+ | } | ||
+ | else hash[key] = value; | ||
+ | } | ||
+ | return hash; | ||
+ | }); | ||
+ | } | ||
+ | |||
+ | function toArray() { | ||
+ | return this.split(''); | ||
+ | } | ||
+ | |||
+ | function succ() { | ||
+ | return this.slice(0, this.length - 1) + | ||
+ | String.fromCharCode(this.charCodeAt(this.length - 1) + 1); | ||
+ | } | ||
+ | |||
+ | function times(count) { | ||
+ | return count < 1 ? '' : new Array(count + 1).join(this); | ||
+ | } | ||
+ | |||
+ | function camelize() { | ||
+ | var parts = this.split('-'), len = parts.length; | ||
+ | if (len == 1) return parts[0]; | ||
+ | |||
+ | var camelized = this.charAt(0) == '-' | ||
+ | ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1) | ||
+ | : parts[0]; | ||
+ | |||
+ | for (var i = 1; i < len; i++) | ||
+ | camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1); | ||
+ | |||
+ | return camelized; | ||
+ | } | ||
+ | |||
+ | function capitalize() { | ||
+ | return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); | ||
+ | } | ||
+ | |||
+ | function underscore() { | ||
+ | return this.replace(/::/g, '/') | ||
+ | .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') | ||
+ | .replace(/([a-z\d])([A-Z])/g, '$1_$2') | ||
+ | .replace(/-/g, '_') | ||
+ | .toLowerCase(); | ||
+ | } | ||
+ | |||
+ | function dasherize() { | ||
+ | return this.replace(/_/g, '-'); | ||
+ | } | ||
+ | |||
+ | function inspect(useDoubleQuotes) { | ||
+ | var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) { | ||
+ | if (character in String.specialChar) { | ||
+ | return String.specialChar[character]; | ||
+ | } | ||
+ | return '\\u00' + character.charCodeAt().toPaddedString(2, 16); | ||
+ | }); | ||
+ | if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; | ||
+ | return "'" + escapedString.replace(/'/g, '\\\'') + "'"; | ||
+ | } | ||
+ | |||
+ | function toJSON() { | ||
+ | return this.inspect(true); | ||
+ | } | ||
+ | |||
+ | function unfilterJSON(filter) { | ||
+ | return this.replace(filter || Prototype.JSONFilter, '$1'); | ||
+ | } | ||
+ | |||
+ | function isJSON() { | ||
+ | var str = this; | ||
+ | if (str.blank()) return false; | ||
+ | str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''); | ||
+ | return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str); | ||
+ | } | ||
+ | |||
+ | function evalJSON(sanitize) { | ||
+ | var json = this.unfilterJSON(); | ||
+ | try { | ||
+ | if (!sanitize || json.isJSON()) return eval('(' + json + ')'); | ||
+ | } catch (e) { } | ||
+ | throw new SyntaxError('Badly formed JSON string: ' + this.inspect()); | ||
+ | } | ||
+ | |||
+ | function include(pattern) { | ||
+ | return this.indexOf(pattern) > -1; | ||
+ | } | ||
+ | |||
+ | function startsWith(pattern) { | ||
+ | return this.indexOf(pattern) === 0; | ||
+ | } | ||
+ | |||
+ | function endsWith(pattern) { | ||
+ | var d = this.length - pattern.length; | ||
+ | return d >= 0 && this.lastIndexOf(pattern) === d; | ||
+ | } | ||
+ | |||
+ | function empty() { | ||
+ | return this == ''; | ||
+ | } | ||
+ | |||
+ | function blank() { | ||
+ | return /^\s*$/.test(this); | ||
+ | } | ||
+ | |||
+ | function interpolate(object, pattern) { | ||
+ | return new Template(this, pattern).evaluate(object); | ||
+ | } | ||
+ | |||
+ | return { | ||
+ | gsub: gsub, | ||
+ | sub: sub, | ||
+ | scan: scan, | ||
+ | truncate: truncate, | ||
+ | strip: String.prototype.trim ? String.prototype.trim : strip, | ||
+ | stripTags: stripTags, | ||
+ | stripScripts: stripScripts, | ||
+ | extractScripts: extractScripts, | ||
+ | evalScripts: evalScripts, | ||
+ | escapeHTML: escapeHTML, | ||
+ | unescapeHTML: unescapeHTML, | ||
+ | toQueryParams: toQueryParams, | ||
+ | parseQuery: toQueryParams, | ||
+ | toArray: toArray, | ||
+ | succ: succ, | ||
+ | times: times, | ||
+ | camelize: camelize, | ||
+ | capitalize: capitalize, | ||
+ | underscore: underscore, | ||
+ | dasherize: dasherize, | ||
+ | inspect: inspect, | ||
+ | toJSON: toJSON, | ||
+ | unfilterJSON: unfilterJSON, | ||
+ | isJSON: isJSON, | ||
+ | evalJSON: evalJSON, | ||
+ | include: include, | ||
+ | startsWith: startsWith, | ||
+ | endsWith: endsWith, | ||
+ | empty: empty, | ||
+ | blank: blank, | ||
+ | interpolate: interpolate | ||
+ | }; | ||
+ | })()); | ||
+ | |||
+ | var Template = Class.create({ | ||
+ | initialize: function(template, pattern) { | ||
+ | this.template = template.toString(); | ||
+ | this.pattern = pattern || Template.Pattern; | ||
+ | }, | ||
+ | |||
+ | evaluate: function(object) { | ||
+ | if (object && Object.isFunction(object.toTemplateReplacements)) | ||
+ | object = object.toTemplateReplacements(); | ||
+ | |||
+ | return this.template.gsub(this.pattern, function(match) { | ||
+ | if (object == null) return (match[1] + ''); | ||
+ | |||
+ | var before = match[1] || ''; | ||
+ | if (before == '\\') return match[2]; | ||
+ | |||
+ | var ctx = object, expr = match[3]; | ||
+ | var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/; | ||
+ | match = pattern.exec(expr); | ||
+ | if (match == null) return before; | ||
+ | |||
+ | while (match != null) { | ||
+ | var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1]; | ||
+ | ctx = ctx[comp]; | ||
+ | if (null == ctx || '' == match[3]) break; | ||
+ | expr = expr.substring('[' == match[3] ? match[1].length : match[0].length); | ||
+ | match = pattern.exec(expr); | ||
+ | } | ||
+ | |||
+ | return before + String.interpret(ctx); | ||
+ | }); | ||
+ | } | ||
+ | }); | ||
+ | Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; | ||
+ | |||
+ | var $break = { }; | ||
+ | |||
+ | var Enumerable = (function() { | ||
+ | function each(iterator, context) { | ||
+ | var index = 0; | ||
+ | try { | ||
+ | this._each(function(value) { | ||
+ | iterator.call(context, value, index++); | ||
+ | }); | ||
+ | } catch (e) { | ||
+ | if (e != $break) throw e; | ||
+ | } | ||
+ | return this; | ||
+ | } | ||
+ | |||
+ | function eachSlice(number, iterator, context) { | ||
+ | var index = -number, slices = [], array = this.toArray(); | ||
+ | if (number < 1) return array; | ||
+ | while ((index += number) < array.length) | ||
+ | slices.push(array.slice(index, index+number)); | ||
+ | return slices.collect(iterator, context); | ||
+ | } | ||
+ | |||
+ | function all(iterator, context) { | ||
+ | iterator = iterator || Prototype.K; | ||
+ | var result = true; | ||
+ | this.each(function(value, index) { | ||
+ | result = result && !!iterator.call(context, value, index); | ||
+ | if (!result) throw $break; | ||
+ | }); | ||
+ | return result; | ||
+ | } | ||
+ | |||
+ | function any(iterator, context) { | ||
+ | iterator = iterator || Prototype.K; | ||
+ | var result = false; | ||
+ | this.each(function(value, index) { | ||
+ | if (result = !!iterator.call(context, value, index)) | ||
+ | throw $break; | ||
+ | }); | ||
+ | return result; | ||
+ | } | ||
+ | |||
+ | function collect(iterator, context) { | ||
+ | iterator = iterator || Prototype.K; | ||
+ | var results = []; | ||
+ | this.each(function(value, index) { | ||
+ | results.push(iterator.call(context, value, index)); | ||
+ | }); | ||
+ | return results; | ||
+ | } | ||
+ | |||
+ | function detect(iterator, context) { | ||
+ | var result; | ||
+ | this.each(function(value, index) { | ||
+ | if (iterator.call(context, value, index)) { | ||
+ | result = value; | ||
+ | throw $break; | ||
+ | } | ||
+ | }); | ||
+ | return result; | ||
+ | } | ||
+ | |||
+ | function findAll(iterator, context) { | ||
+ | var results = []; | ||
+ | this.each(function(value, index) { | ||
+ | if (iterator.call(context, value, index)) | ||
+ | results.push(value); | ||
+ | }); | ||
+ | return results; | ||
+ | } | ||
+ | |||
+ | function grep(filter, iterator, context) { | ||
+ | iterator = iterator || Prototype.K; | ||
+ | var results = []; | ||
+ | |||
+ | if (Object.isString(filter)) | ||
+ | filter = new RegExp(RegExp.escape(filter)); | ||
+ | |||
+ | this.each(function(value, index) { | ||
+ | if (filter.match(value)) | ||
+ | results.push(iterator.call(context, value, index)); | ||
+ | }); | ||
+ | return results; | ||
+ | } | ||
+ | |||
+ | function include(object) { | ||
+ | if (Object.isFunction(this.indexOf)) | ||
+ | if (this.indexOf(object) != -1) return true; | ||
+ | |||
+ | var found = false; | ||
+ | this.each(function(value) { | ||
+ | if (value == object) { | ||
+ | found = true; | ||
+ | throw $break; | ||
+ | } | ||
+ | }); | ||
+ | return found; | ||
+ | } | ||
+ | |||
+ | function inGroupsOf(number, fillWith) { | ||
+ | fillWith = Object.isUndefined(fillWith) ? null : fillWith; | ||
+ | return this.eachSlice(number, function(slice) { | ||
+ | while(slice.length < number) slice.push(fillWith); | ||
+ | return slice; | ||
+ | }); | ||
+ | } | ||
+ | |||
+ | function inject(memo, iterator, context) { | ||
+ | this.each(function(value, index) { | ||
+ | memo = iterator.call(context, memo, value, index); | ||
+ | }); | ||
+ | return memo; | ||
+ | } | ||
+ | |||
+ | function invoke(method) { | ||
+ | var args = $A(arguments).slice(1); | ||
+ | return this.map(function(value) { | ||
+ | return value[method].apply(value, args); | ||
+ | }); | ||
+ | } | ||
+ | |||
+ | function max(iterator, context) { | ||
+ | iterator = iterator || Prototype.K; | ||
+ | var result; | ||
+ | this.each(function(value, index) { | ||
+ | value = iterator.call(context, value, index); | ||
+ | if (result == null || value >= result) | ||
+ | result = value; | ||
+ | }); | ||
+ | return result; | ||
+ | } | ||
+ | |||
+ | function min(iterator, context) { | ||
+ | iterator = iterator || Prototype.K; | ||
+ | var result; | ||
+ | this.each(function(value, index) { | ||
+ | value = iterator.call(context, value, index); | ||
+ | if (result == null || value < result) | ||
+ | result = value; | ||
+ | }); | ||
+ | return result; | ||
+ | } | ||
+ | |||
+ | function partition(iterator, context) { | ||
+ | iterator = iterator || Prototype.K; | ||
+ | var trues = [], falses = []; | ||
+ | this.each(function(value, index) { | ||
+ | (iterator.call(context, value, index) ? | ||
+ | trues : falses).push(value); | ||
+ | }); | ||
+ | return [trues, falses]; | ||
+ | } | ||
+ | |||
+ | function pluck(property) { | ||
+ | var results = []; | ||
+ | this.each(function(value) { | ||
+ | results.push(value[property]); | ||
+ | }); | ||
+ | return results; | ||
+ | } | ||
+ | |||
+ | function reject(iterator, context) { | ||
+ | var results = []; | ||
+ | this.each(function(value, index) { | ||
+ | if (!iterator.call(context, value, index)) | ||
+ | results.push(value); | ||
+ | }); | ||
+ | return results; | ||
+ | } | ||
+ | |||
+ | function sortBy(iterator, context) { | ||
+ | return this.map(function(value, index) { | ||
+ | return { | ||
+ | value: value, | ||
+ | criteria: iterator.call(context, value, index) | ||
+ | }; | ||
+ | }).sort(function(left, right) { | ||
+ | var a = left.criteria, b = right.criteria; | ||
+ | return a < b ? -1 : a > b ? 1 : 0; | ||
+ | }).pluck('value'); | ||
+ | } | ||
+ | |||
+ | function toArray() { | ||
+ | return this.map(); | ||
+ | } | ||
+ | |||
+ | function zip() { | ||
+ | var iterator = Prototype.K, args = $A(arguments); | ||
+ | if (Object.isFunction(args.last())) | ||
+ | iterator = args.pop(); | ||
+ | |||
+ | var collections = [this].concat(args).map($A); | ||
+ | return this.map(function(value, index) { | ||
+ | return iterator(collections.pluck(index)); | ||
+ | }); | ||
+ | } | ||
+ | |||
+ | function size() { | ||
+ | return this.toArray().length; | ||
+ | } | ||
+ | |||
+ | function inspect() { | ||
+ | return '#<Enumerable:' + this.toArray().inspect() + '>'; | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | return { | ||
+ | each: each, | ||
+ | eachSlice: eachSlice, | ||
+ | all: all, | ||
+ | every: all, | ||
+ | any: any, | ||
+ | some: any, | ||
+ | collect: collect, | ||
+ | map: collect, | ||
+ | detect: detect, | ||
+ | findAll: findAll, | ||
+ | select: findAll, | ||
+ | filter: findAll, | ||
+ | grep: grep, | ||
+ | include: include, | ||
+ | member: include, | ||
+ | inGroupsOf: inGroupsOf, | ||
+ | inject: inject, | ||
+ | invoke: invoke, | ||
+ | max: max, | ||
+ | min: min, | ||
+ | partition: partition, | ||
+ | pluck: pluck, | ||
+ | reject: reject, | ||
+ | sortBy: sortBy, | ||
+ | toArray: toArray, | ||
+ | entries: toArray, | ||
+ | zip: zip, | ||
+ | size: size, | ||
+ | inspect: inspect, | ||
+ | find: detect | ||
+ | }; | ||
+ | })(); | ||
+ | function $A(iterable) { | ||
+ | if (!iterable) return []; | ||
+ | if ('toArray' in Object(iterable)) return iterable.toArray(); | ||
+ | var length = iterable.length || 0, results = new Array(length); | ||
+ | while (length--) results[length] = iterable[length]; | ||
+ | return results; | ||
} | } | ||
+ | function $w(string) { | ||
+ | if (!Object.isString(string)) return []; | ||
+ | string = string.strip(); | ||
+ | return string ? string.split(/\s+/) : []; | ||
+ | } | ||
- | + | Array.from = $A; | |
- | + | ||
- | // | + | |
- | + | (function() { | |
- | function | + | var arrayProto = Array.prototype, |
- | + | slice = arrayProto.slice, | |
- | + | _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available | |
- | + | ||
- | + | function each(iterator) { | |
- | + | for (var i = 0, length = this.length; i < length; i++) | |
- | + | iterator(this[i]); | |
- | + | } | |
+ | if (!_each) _each = each; | ||
+ | |||
+ | function clear() { | ||
+ | this.length = 0; | ||
+ | return this; | ||
+ | } | ||
+ | |||
+ | function first() { | ||
+ | return this[0]; | ||
+ | } | ||
+ | |||
+ | function last() { | ||
+ | return this[this.length - 1]; | ||
+ | } | ||
+ | |||
+ | function compact() { | ||
+ | return this.select(function(value) { | ||
+ | return value != null; | ||
+ | }); | ||
+ | } | ||
+ | |||
+ | function flatten() { | ||
+ | return this.inject([], function(array, value) { | ||
+ | if (Object.isArray(value)) | ||
+ | return array.concat(value.flatten()); | ||
+ | array.push(value); | ||
+ | return array; | ||
+ | }); | ||
+ | } | ||
+ | |||
+ | function without() { | ||
+ | var values = slice.call(arguments, 0); | ||
+ | return this.select(function(value) { | ||
+ | return !values.include(value); | ||
+ | }); | ||
+ | } | ||
+ | |||
+ | function reverse(inline) { | ||
+ | return (inline !== false ? this : this.toArray())._reverse(); | ||
+ | } | ||
+ | |||
+ | function uniq(sorted) { | ||
+ | return this.inject([], function(array, value, index) { | ||
+ | if (0 == index || (sorted ? array.last() != value : !array.include(value))) | ||
+ | array.push(value); | ||
+ | return array; | ||
+ | }); | ||
+ | } | ||
+ | |||
+ | function intersect(array) { | ||
+ | return this.uniq().findAll(function(item) { | ||
+ | return array.detect(function(value) { return item === value }); | ||
+ | }); | ||
+ | } | ||
+ | |||
+ | |||
+ | function clone() { | ||
+ | return slice.call(this, 0); | ||
+ | } | ||
+ | |||
+ | function size() { | ||
+ | return this.length; | ||
+ | } | ||
+ | |||
+ | function inspect() { | ||
+ | return '[' + this.map(Object.inspect).join(', ') + ']'; | ||
+ | } | ||
+ | |||
+ | function toJSON() { | ||
+ | var results = []; | ||
+ | this.each(function(object) { | ||
+ | var value = Object.toJSON(object); | ||
+ | if (!Object.isUndefined(value)) results.push(value); | ||
+ | }); | ||
+ | return '[' + results.join(', ') + ']'; | ||
+ | } | ||
+ | |||
+ | function indexOf(item, i) { | ||
+ | i || (i = 0); | ||
+ | var length = this.length; | ||
+ | if (i < 0) i = length + i; | ||
+ | for (; i < length; i++) | ||
+ | if (this[i] === item) return i; | ||
+ | return -1; | ||
+ | } | ||
+ | |||
+ | function lastIndexOf(item, i) { | ||
+ | i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1; | ||
+ | var n = this.slice(0, i).reverse().indexOf(item); | ||
+ | return (n < 0) ? n : i - n - 1; | ||
+ | } | ||
+ | |||
+ | function concat() { | ||
+ | var array = slice.call(this, 0), item; | ||
+ | for (var i = 0, length = arguments.length; i < length; i++) { | ||
+ | item = arguments[i]; | ||
+ | if (Object.isArray(item) && !('callee' in item)) { | ||
+ | for (var j = 0, arrayLength = item.length; j < arrayLength; j++) | ||
+ | array.push(item[j]); | ||
+ | } else { | ||
+ | array.push(item); | ||
+ | } | ||
+ | } | ||
+ | return array; | ||
+ | } | ||
+ | |||
+ | Object.extend(arrayProto, Enumerable); | ||
+ | |||
+ | if (!arrayProto._reverse) | ||
+ | arrayProto._reverse = arrayProto.reverse; | ||
+ | |||
+ | Object.extend(arrayProto, { | ||
+ | _each: _each, | ||
+ | clear: clear, | ||
+ | first: first, | ||
+ | last: last, | ||
+ | compact: compact, | ||
+ | flatten: flatten, | ||
+ | without: without, | ||
+ | reverse: reverse, | ||
+ | uniq: uniq, | ||
+ | intersect: intersect, | ||
+ | clone: clone, | ||
+ | toArray: clone, | ||
+ | size: size, | ||
+ | inspect: inspect, | ||
+ | toJSON: toJSON | ||
+ | }); | ||
+ | |||
+ | var CONCAT_ARGUMENTS_BUGGY = (function() { | ||
+ | return [].concat(arguments)[0][0] !== 1; | ||
+ | })(1,2) | ||
+ | |||
+ | if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat; | ||
+ | |||
+ | if (!arrayProto.indexOf) arrayProto.indexOf = indexOf; | ||
+ | if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf; | ||
+ | })(); | ||
+ | function $H(object) { | ||
+ | return new Hash(object); | ||
+ | }; | ||
+ | |||
+ | var Hash = Class.create(Enumerable, (function() { | ||
+ | function initialize(object) { | ||
+ | this._object = Object.isHash(object) ? object.toObject() : Object.clone(object); | ||
+ | } | ||
+ | |||
+ | function _each(iterator) { | ||
+ | for (var key in this._object) { | ||
+ | var value = this._object[key], pair = [key, value]; | ||
+ | pair.key = key; | ||
+ | pair.value = value; | ||
+ | iterator(pair); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | function set(key, value) { | ||
+ | return this._object[key] = value; | ||
+ | } | ||
+ | |||
+ | function get(key) { | ||
+ | if (this._object[key] !== Object.prototype[key]) | ||
+ | return this._object[key]; | ||
+ | } | ||
+ | |||
+ | function unset(key) { | ||
+ | var value = this._object[key]; | ||
+ | delete this._object[key]; | ||
+ | return value; | ||
+ | } | ||
+ | |||
+ | function toObject() { | ||
+ | return Object.clone(this._object); | ||
+ | } | ||
+ | |||
+ | function keys() { | ||
+ | return this.pluck('key'); | ||
+ | } | ||
+ | |||
+ | function values() { | ||
+ | return this.pluck('value'); | ||
+ | } | ||
+ | |||
+ | function index(value) { | ||
+ | var match = this.detect(function(pair) { | ||
+ | return pair.value === value; | ||
+ | }); | ||
+ | return match && match.key; | ||
+ | } | ||
+ | |||
+ | function merge(object) { | ||
+ | return this.clone().update(object); | ||
+ | } | ||
+ | |||
+ | function update(object) { | ||
+ | return new Hash(object).inject(this, function(result, pair) { | ||
+ | result.set(pair.key, pair.value); | ||
+ | return result; | ||
+ | }); | ||
+ | } | ||
+ | |||
+ | function toQueryPair(key, value) { | ||
+ | if (Object.isUndefined(value)) return key; | ||
+ | return key + '=' + encodeURIComponent(String.interpret(value)); | ||
+ | } | ||
+ | |||
+ | function toQueryString() { | ||
+ | return this.inject([], function(results, pair) { | ||
+ | var key = encodeURIComponent(pair.key), values = pair.value; | ||
+ | |||
+ | if (values && typeof values == 'object') { | ||
+ | if (Object.isArray(values)) | ||
+ | return results.concat(values.map(toQueryPair.curry(key))); | ||
+ | } else results.push(toQueryPair(key, values)); | ||
+ | return results; | ||
+ | }).join('&'); | ||
+ | } | ||
+ | |||
+ | function inspect() { | ||
+ | return '#<Hash:{' + this.map(function(pair) { | ||
+ | return pair.map(Object.inspect).join(': '); | ||
+ | }).join(', ') + '}>'; | ||
+ | } | ||
+ | |||
+ | function toJSON() { | ||
+ | return Object.toJSON(this.toObject()); | ||
+ | } | ||
+ | |||
+ | function clone() { | ||
+ | return new Hash(this); | ||
+ | } | ||
+ | |||
+ | return { | ||
+ | initialize: initialize, | ||
+ | _each: _each, | ||
+ | set: set, | ||
+ | get: get, | ||
+ | unset: unset, | ||
+ | toObject: toObject, | ||
+ | toTemplateReplacements: toObject, | ||
+ | keys: keys, | ||
+ | values: values, | ||
+ | index: index, | ||
+ | merge: merge, | ||
+ | update: update, | ||
+ | toQueryString: toQueryString, | ||
+ | inspect: inspect, | ||
+ | toJSON: toJSON, | ||
+ | clone: clone | ||
+ | }; | ||
+ | })()); | ||
+ | |||
+ | Hash.from = $H; | ||
+ | Object.extend(Number.prototype, (function() { | ||
+ | function toColorPart() { | ||
+ | return this.toPaddedString(2, 16); | ||
+ | } | ||
+ | |||
+ | function succ() { | ||
+ | return this + 1; | ||
+ | } | ||
+ | |||
+ | function times(iterator, context) { | ||
+ | $R(0, this, true).each(iterator, context); | ||
+ | return this; | ||
+ | } | ||
+ | |||
+ | function toPaddedString(length, radix) { | ||
+ | var string = this.toString(radix || 10); | ||
+ | return '0'.times(length - string.length) + string; | ||
+ | } | ||
+ | |||
+ | function toJSON() { | ||
+ | return isFinite(this) ? this.toString() : 'null'; | ||
+ | } | ||
+ | |||
+ | function abs() { | ||
+ | return Math.abs(this); | ||
+ | } | ||
+ | |||
+ | function round() { | ||
+ | return Math.round(this); | ||
+ | } | ||
+ | |||
+ | function ceil() { | ||
+ | return Math.ceil(this); | ||
+ | } | ||
+ | |||
+ | function floor() { | ||
+ | return Math.floor(this); | ||
+ | } | ||
+ | |||
+ | return { | ||
+ | toColorPart: toColorPart, | ||
+ | succ: succ, | ||
+ | times: times, | ||
+ | toPaddedString: toPaddedString, | ||
+ | toJSON: toJSON, | ||
+ | abs: abs, | ||
+ | round: round, | ||
+ | ceil: ceil, | ||
+ | floor: floor | ||
+ | }; | ||
+ | })()); | ||
+ | |||
+ | function $R(start, end, exclusive) { | ||
+ | return new ObjectRange(start, end, exclusive); | ||
} | } | ||
- | + | var ObjectRange = Class.create(Enumerable, (function() { | |
- | + | function initialize(start, end, exclusive) { | |
- | + | this.start = start; | |
- | + | this.end = end; | |
+ | this.exclusive = exclusive; | ||
+ | } | ||
- | function | + | function _each(iterator) { |
- | + | var value = this.start; | |
- | + | while (this.include(value)) { | |
- | + | iterator(value); | |
- | + | value = value.succ(); | |
- | + | } | |
- | + | } | |
- | + | ||
- | + | function include(value) { | |
+ | if (value < this.start) | ||
+ | return false; | ||
+ | if (this.exclusive) | ||
+ | return value < this.end; | ||
+ | return value <= this.end; | ||
+ | } | ||
+ | |||
+ | return { | ||
+ | initialize: initialize, | ||
+ | _each: _each, | ||
+ | include: include | ||
+ | }; | ||
+ | })()); | ||
+ | |||
+ | |||
+ | |||
+ | var Ajax = { | ||
+ | getTransport: function() { | ||
+ | return Try.these( | ||
+ | function() {return new XMLHttpRequest()}, | ||
+ | function() {return new ActiveXObject('Msxml2.XMLHTTP')}, | ||
+ | function() {return new ActiveXObject('Microsoft.XMLHTTP')} | ||
+ | ) || false; | ||
+ | }, | ||
+ | |||
+ | activeRequestCount: 0 | ||
+ | }; | ||
+ | |||
+ | Ajax.Responders = { | ||
+ | responders: [], | ||
+ | |||
+ | _each: function(iterator) { | ||
+ | this.responders._each(iterator); | ||
+ | }, | ||
+ | |||
+ | register: function(responder) { | ||
+ | if (!this.include(responder)) | ||
+ | this.responders.push(responder); | ||
+ | }, | ||
+ | |||
+ | unregister: function(responder) { | ||
+ | this.responders = this.responders.without(responder); | ||
+ | }, | ||
+ | |||
+ | dispatch: function(callback, request, transport, json) { | ||
+ | this.each(function(responder) { | ||
+ | if (Object.isFunction(responder[callback])) { | ||
+ | try { | ||
+ | responder[callback].apply(responder, [request, transport, json]); | ||
+ | } catch (e) { } | ||
+ | } | ||
+ | }); | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | Object.extend(Ajax.Responders, Enumerable); | ||
+ | |||
+ | Ajax.Responders.register({ | ||
+ | onCreate: function() { Ajax.activeRequestCount++ }, | ||
+ | onComplete: function() { Ajax.activeRequestCount-- } | ||
+ | }); | ||
+ | Ajax.Base = Class.create({ | ||
+ | initialize: function(options) { | ||
+ | this.options = { | ||
+ | method: 'post', | ||
+ | asynchronous: true, | ||
+ | contentType: 'application/x-www-form-urlencoded', | ||
+ | encoding: 'UTF-8', | ||
+ | parameters: '', | ||
+ | evalJSON: true, | ||
+ | evalJS: true | ||
+ | }; | ||
+ | Object.extend(this.options, options || { }); | ||
+ | |||
+ | this.options.method = this.options.method.toLowerCase(); | ||
+ | |||
+ | if (Object.isString(this.options.parameters)) | ||
+ | this.options.parameters = this.options.parameters.toQueryParams(); | ||
+ | else if (Object.isHash(this.options.parameters)) | ||
+ | this.options.parameters = this.options.parameters.toObject(); | ||
+ | } | ||
+ | }); | ||
+ | Ajax.Request = Class.create(Ajax.Base, { | ||
+ | _complete: false, | ||
+ | |||
+ | initialize: function($super, url, options) { | ||
+ | $super(options); | ||
+ | this.transport = Ajax.getTransport(); | ||
+ | this.request(url); | ||
+ | }, | ||
+ | |||
+ | request: function(url) { | ||
+ | this.url = url; | ||
+ | this.method = this.options.method; | ||
+ | var params = Object.clone(this.options.parameters); | ||
+ | |||
+ | if (!['get', 'post'].include(this.method)) { | ||
+ | params['_method'] = this.method; | ||
+ | this.method = 'post'; | ||
+ | } | ||
+ | |||
+ | this.parameters = params; | ||
+ | |||
+ | if (params = Object.toQueryString(params)) { | ||
+ | if (this.method == 'get') | ||
+ | this.url += (this.url.include('?') ? '&' : '?') + params; | ||
+ | else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) | ||
+ | params += '&_='; | ||
+ | } | ||
+ | |||
+ | try { | ||
+ | var response = new Ajax.Response(this); | ||
+ | if (this.options.onCreate) this.options.onCreate(response); | ||
+ | Ajax.Responders.dispatch('onCreate', this, response); | ||
+ | |||
+ | this.transport.open(this.method.toUpperCase(), this.url, | ||
+ | this.options.asynchronous); | ||
+ | |||
+ | if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1); | ||
+ | |||
+ | this.transport.onreadystatechange = this.onStateChange.bind(this); | ||
+ | this.setRequestHeaders(); | ||
+ | |||
+ | this.body = this.method == 'post' ? (this.options.postBody || params) : null; | ||
+ | this.transport.send(this.body); | ||
+ | |||
+ | /* Force Firefox to handle ready state 4 for synchronous requests */ | ||
+ | if (!this.options.asynchronous && this.transport.overrideMimeType) | ||
+ | this.onStateChange(); | ||
+ | |||
+ | } | ||
+ | catch (e) { | ||
+ | this.dispatchException(e); | ||
+ | } | ||
+ | }, | ||
+ | |||
+ | onStateChange: function() { | ||
+ | var readyState = this.transport.readyState; | ||
+ | if (readyState > 1 && !((readyState == 4) && this._complete)) | ||
+ | this.respondToReadyState(this.transport.readyState); | ||
+ | }, | ||
+ | |||
+ | setRequestHeaders: function() { | ||
+ | var headers = { | ||
+ | 'X-Requested-With': 'XMLHttpRequest', | ||
+ | 'X-Prototype-Version': Prototype.Version, | ||
+ | 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' | ||
+ | }; | ||
+ | |||
+ | if (this.method == 'post') { | ||
+ | headers['Content-type'] = this.options.contentType + | ||
+ | (this.options.encoding ? '; charset=' + this.options.encoding : ''); | ||
+ | |||
+ | /* Force "Connection: close" for older Mozilla browsers to work | ||
+ | * around a bug where XMLHttpRequest sends an incorrect | ||
+ | * Content-length header. See Mozilla Bugzilla #246651. | ||
+ | */ | ||
+ | if (this.transport.overrideMimeType && | ||
+ | (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005) | ||
+ | headers['Connection'] = 'close'; | ||
+ | } | ||
+ | |||
+ | if (typeof this.options.requestHeaders == 'object') { | ||
+ | var extras = this.options.requestHeaders; | ||
+ | |||
+ | if (Object.isFunction(extras.push)) | ||
+ | for (var i = 0, length = extras.length; i < length; i += 2) | ||
+ | headers[extras[i]] = extras[i+1]; | ||
+ | else | ||
+ | $H(extras).each(function(pair) { headers[pair.key] = pair.value }); | ||
+ | } | ||
+ | |||
+ | for (var name in headers) | ||
+ | this.transport.setRequestHeader(name, headers[name]); | ||
+ | }, | ||
+ | |||
+ | success: function() { | ||
+ | var status = this.getStatus(); | ||
+ | return !status || (status >= 200 && status < 300); | ||
+ | }, | ||
+ | |||
+ | getStatus: function() { | ||
+ | try { | ||
+ | return this.transport.status || 0; | ||
+ | } catch (e) { return 0 } | ||
+ | }, | ||
+ | |||
+ | respondToReadyState: function(readyState) { | ||
+ | var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this); | ||
+ | |||
+ | if (state == 'Complete') { | ||
+ | try { | ||
+ | this._complete = true; | ||
+ | (this.options['on' + response.status] | ||
+ | || this.options['on' + (this.success() ? 'Success' : 'Failure')] | ||
+ | || Prototype.emptyFunction)(response, response.headerJSON); | ||
+ | } catch (e) { | ||
+ | this.dispatchException(e); | ||
+ | } | ||
+ | |||
+ | var contentType = response.getHeader('Content-type'); | ||
+ | if (this.options.evalJS == 'force' | ||
+ | || (this.options.evalJS && this.isSameOrigin() && contentType | ||
+ | && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i))) | ||
+ | this.evalResponse(); | ||
+ | } | ||
+ | |||
+ | try { | ||
+ | (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON); | ||
+ | Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON); | ||
+ | } catch (e) { | ||
+ | this.dispatchException(e); | ||
+ | } | ||
+ | |||
+ | if (state == 'Complete') { | ||
+ | this.transport.onreadystatechange = Prototype.emptyFunction; | ||
+ | } | ||
+ | }, | ||
+ | |||
+ | isSameOrigin: function() { | ||
+ | var m = this.url.match(/^\s*https?:\/\/[^\/]*/); | ||
+ | return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({ | ||
+ | protocol: location.protocol, | ||
+ | domain: document.domain, | ||
+ | port: location.port ? ':' + location.port : '' | ||
+ | })); | ||
+ | }, | ||
+ | |||
+ | getHeader: function(name) { | ||
+ | try { | ||
+ | return this.transport.getResponseHeader(name) || null; | ||
+ | } catch (e) { return null; } | ||
+ | }, | ||
+ | |||
+ | evalResponse: function() { | ||
+ | try { | ||
+ | return eval((this.transport.responseText || '').unfilterJSON()); | ||
+ | } catch (e) { | ||
+ | this.dispatchException(e); | ||
+ | } | ||
+ | }, | ||
+ | |||
+ | dispatchException: function(exception) { | ||
+ | (this.options.onException || Prototype.emptyFunction)(this, exception); | ||
+ | Ajax.Responders.dispatch('onException', this, exception); | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | Ajax.Request.Events = | ||
+ | ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | Ajax.Response = Class.create({ | ||
+ | initialize: function(request){ | ||
+ | this.request = request; | ||
+ | var transport = this.transport = request.transport, | ||
+ | readyState = this.readyState = transport.readyState; | ||
+ | |||
+ | if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) { | ||
+ | this.status = this.getStatus(); | ||
+ | this.statusText = this.getStatusText(); | ||
+ | this.responseText = String.interpret(transport.responseText); | ||
+ | this.headerJSON = this._getHeaderJSON(); | ||
+ | } | ||
+ | |||
+ | if(readyState == 4) { | ||
+ | var xml = transport.responseXML; | ||
+ | this.responseXML = Object.isUndefined(xml) ? null : xml; | ||
+ | this.responseJSON = this._getResponseJSON(); | ||
+ | } | ||
+ | }, | ||
+ | |||
+ | status: 0, | ||
+ | |||
+ | statusText: '', | ||
+ | |||
+ | getStatus: Ajax.Request.prototype.getStatus, | ||
+ | |||
+ | getStatusText: function() { | ||
+ | try { | ||
+ | return this.transport.statusText || ''; | ||
+ | } catch (e) { return '' } | ||
+ | }, | ||
+ | |||
+ | getHeader: Ajax.Request.prototype.getHeader, | ||
+ | |||
+ | getAllHeaders: function() { | ||
+ | try { | ||
+ | return this.getAllResponseHeaders(); | ||
+ | } catch (e) { return null } | ||
+ | }, | ||
+ | |||
+ | getResponseHeader: function(name) { | ||
+ | return this.transport.getResponseHeader(name); | ||
+ | }, | ||
+ | |||
+ | getAllResponseHeaders: function() { | ||
+ | return this.transport.getAllResponseHeaders(); | ||
+ | }, | ||
+ | |||
+ | _getHeaderJSON: function() { | ||
+ | var json = this.getHeader('X-JSON'); | ||
+ | if (!json) return null; | ||
+ | json = decodeURIComponent(escape(json)); | ||
+ | try { | ||
+ | return json.evalJSON(this.request.options.sanitizeJSON || | ||
+ | !this.request.isSameOrigin()); | ||
+ | } catch (e) { | ||
+ | this.request.dispatchException(e); | ||
+ | } | ||
+ | }, | ||
+ | |||
+ | _getResponseJSON: function() { | ||
+ | var options = this.request.options; | ||
+ | if (!options.evalJSON || (options.evalJSON != 'force' && | ||
+ | !(this.getHeader('Content-type') || '').include('application/json')) || | ||
+ | this.responseText.blank()) | ||
+ | return null; | ||
+ | try { | ||
+ | return this.responseText.evalJSON(options.sanitizeJSON || | ||
+ | !this.request.isSameOrigin()); | ||
+ | } catch (e) { | ||
+ | this.request.dispatchException(e); | ||
+ | } | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | Ajax.Updater = Class.create(Ajax.Request, { | ||
+ | initialize: function($super, container, url, options) { | ||
+ | this.container = { | ||
+ | success: (container.success || container), | ||
+ | failure: (container.failure || (container.success ? null : container)) | ||
+ | }; | ||
+ | |||
+ | options = Object.clone(options); | ||
+ | var onComplete = options.onComplete; | ||
+ | options.onComplete = (function(response, json) { | ||
+ | this.updateContent(response.responseText); | ||
+ | if (Object.isFunction(onComplete)) onComplete(response, json); | ||
+ | }).bind(this); | ||
+ | |||
+ | $super(url, options); | ||
+ | }, | ||
+ | |||
+ | updateContent: function(responseText) { | ||
+ | var receiver = this.container[this.success() ? 'success' : 'failure'], | ||
+ | options = this.options; | ||
+ | |||
+ | if (!options.evalScripts) responseText = responseText.stripScripts(); | ||
+ | |||
+ | if (receiver = $(receiver)) { | ||
+ | if (options.insertion) { | ||
+ | if (Object.isString(options.insertion)) { | ||
+ | var insertion = { }; insertion[options.insertion] = responseText; | ||
+ | receiver.insert(insertion); | ||
+ | } | ||
+ | else options.insertion(receiver, responseText); | ||
+ | } | ||
+ | else receiver.update(responseText); | ||
+ | } | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | Ajax.PeriodicalUpdater = Class.create(Ajax.Base, { | ||
+ | initialize: function($super, container, url, options) { | ||
+ | $super(options); | ||
+ | this.onComplete = this.options.onComplete; | ||
+ | |||
+ | this.frequency = (this.options.frequency || 2); | ||
+ | this.decay = (this.options.decay || 1); | ||
+ | |||
+ | this.updater = { }; | ||
+ | this.container = container; | ||
+ | this.url = url; | ||
+ | |||
+ | this.start(); | ||
+ | }, | ||
+ | |||
+ | start: function() { | ||
+ | this.options.onComplete = this.updateComplete.bind(this); | ||
+ | this.onTimerEvent(); | ||
+ | }, | ||
+ | |||
+ | stop: function() { | ||
+ | this.updater.options.onComplete = undefined; | ||
+ | clearTimeout(this.timer); | ||
+ | (this.onComplete || Prototype.emptyFunction).apply(this, arguments); | ||
+ | }, | ||
+ | |||
+ | updateComplete: function(response) { | ||
+ | if (this.options.decay) { | ||
+ | this.decay = (response.responseText == this.lastText ? | ||
+ | this.decay * this.options.decay : 1); | ||
+ | |||
+ | this.lastText = response.responseText; | ||
+ | } | ||
+ | this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency); | ||
+ | }, | ||
+ | |||
+ | onTimerEvent: function() { | ||
+ | this.updater = new Ajax.Updater(this.container, this.url, this.options); | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | |||
+ | |||
+ | function $(element) { | ||
+ | if (arguments.length > 1) { | ||
+ | for (var i = 0, elements = [], length = arguments.length; i < length; i++) | ||
+ | elements.push($(arguments[i])); | ||
+ | return elements; | ||
+ | } | ||
+ | if (Object.isString(element)) | ||
+ | element = document.getElementById(element); | ||
+ | return Element.extend(element); | ||
} | } | ||
+ | if (Prototype.BrowserFeatures.XPath) { | ||
+ | document._getElementsByXPath = function(expression, parentElement) { | ||
+ | var results = []; | ||
+ | var query = document.evaluate(expression, $(parentElement) || document, | ||
+ | null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); | ||
+ | for (var i = 0, length = query.snapshotLength; i < length; i++) | ||
+ | results.push(Element.extend(query.snapshotItem(i))); | ||
+ | return results; | ||
+ | }; | ||
+ | } | ||
- | // | + | /*--------------------------------------------------------------------------*/ |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | if (!window.Node) var Node = { }; | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | if (!Node.ELEMENT_NODE) { | |
- | + | Object.extend(Node, { | |
- | + | ELEMENT_NODE: 1, | |
+ | ATTRIBUTE_NODE: 2, | ||
+ | TEXT_NODE: 3, | ||
+ | CDATA_SECTION_NODE: 4, | ||
+ | ENTITY_REFERENCE_NODE: 5, | ||
+ | ENTITY_NODE: 6, | ||
+ | PROCESSING_INSTRUCTION_NODE: 7, | ||
+ | COMMENT_NODE: 8, | ||
+ | DOCUMENT_NODE: 9, | ||
+ | DOCUMENT_TYPE_NODE: 10, | ||
+ | DOCUMENT_FRAGMENT_NODE: 11, | ||
+ | NOTATION_NODE: 12 | ||
+ | }); | ||
+ | } | ||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | + | (function(global) { | |
- | + | ||
- | + | ||
- | + | var SETATTRIBUTE_IGNORES_NAME = (function(){ | |
- | + | var elForm = document.createElement("form"); | |
+ | var elInput = document.createElement("input"); | ||
+ | var root = document.documentElement; | ||
+ | elInput.setAttribute("name", "test"); | ||
+ | elForm.appendChild(elInput); | ||
+ | root.appendChild(elForm); | ||
+ | var isBuggy = elForm.elements | ||
+ | ? (typeof elForm.elements.test == "undefined") | ||
+ | : null; | ||
+ | root.removeChild(elForm); | ||
+ | elForm = elInput = null; | ||
+ | return isBuggy; | ||
+ | })(); | ||
- | + | var element = global.Element; | |
- | + | global.Element = function(tagName, attributes) { | |
+ | attributes = attributes || { }; | ||
+ | tagName = tagName.toLowerCase(); | ||
+ | var cache = Element.cache; | ||
+ | if (SETATTRIBUTE_IGNORES_NAME && attributes.name) { | ||
+ | tagName = '<' + tagName + ' name="' + attributes.name + '">'; | ||
+ | delete attributes.name; | ||
+ | return Element.writeAttribute(document.createElement(tagName), attributes); | ||
+ | } | ||
+ | if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName)); | ||
+ | return Element.writeAttribute(cache[tagName].cloneNode(false), attributes); | ||
+ | }; | ||
+ | Object.extend(global.Element, element || { }); | ||
+ | if (element) global.Element.prototype = element.prototype; | ||
+ | })(this); | ||
- | + | Element.cache = { }; | |
- | + | Element.idCounter = 1; | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
+ | Element.Methods = { | ||
+ | visible: function(element) { | ||
+ | return $(element).style.display != 'none'; | ||
+ | }, | ||
- | + | toggle: function(element) { | |
- | + | element = $(element); | |
- | + | Element[Element.visible(element) ? 'hide' : 'show'](element); | |
- | + | return element; | |
- | + | }, | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | |||
- | + | hide: function(element) { | |
- | + | element = $(element); | |
- | + | element.style.display = 'none'; | |
- | + | return element; | |
+ | }, | ||
+ | |||
+ | show: function(element) { | ||
+ | element = $(element); | ||
+ | element.style.display = ''; | ||
+ | return element; | ||
+ | }, | ||
+ | |||
+ | remove: function(element) { | ||
+ | element = $(element); | ||
+ | element.parentNode.removeChild(element); | ||
+ | return element; | ||
+ | }, | ||
+ | |||
+ | update: (function(){ | ||
+ | |||
+ | var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){ | ||
+ | var el = document.createElement("select"), | ||
+ | isBuggy = true; | ||
+ | el.innerHTML = "<option value=\"test\">test</option>"; | ||
+ | if (el.options && el.options[0]) { | ||
+ | isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION"; | ||
+ | } | ||
+ | el = null; | ||
+ | return isBuggy; | ||
+ | })(); | ||
+ | |||
+ | var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){ | ||
+ | try { | ||
+ | var el = document.createElement("table"); | ||
+ | if (el && el.tBodies) { | ||
+ | el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>"; | ||
+ | var isBuggy = typeof el.tBodies[0] == "undefined"; | ||
+ | el = null; | ||
+ | return isBuggy; | ||
} | } | ||
+ | } catch (e) { | ||
+ | return true; | ||
+ | } | ||
+ | })(); | ||
- | + | var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () { | |
- | + | var s = document.createElement("script"), | |
+ | isBuggy = false; | ||
+ | try { | ||
+ | s.appendChild(document.createTextNode("")); | ||
+ | isBuggy = !s.firstChild || | ||
+ | s.firstChild && s.firstChild.nodeType !== 3; | ||
+ | } catch (e) { | ||
+ | isBuggy = true; | ||
+ | } | ||
+ | s = null; | ||
+ | return isBuggy; | ||
+ | })(); | ||
- | + | function update(element, content) { | |
- | + | element = $(element); | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | if (content && content.toElement) | |
- | + | content = content.toElement(); | |
- | + | if (Object.isElement(content)) | |
- | + | return element.update().insert(content); | |
+ | |||
+ | content = Object.toHTML(content); | ||
+ | |||
+ | var tagName = element.tagName.toUpperCase(); | ||
+ | |||
+ | if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) { | ||
+ | element.text = content; | ||
+ | return element; | ||
+ | } | ||
+ | |||
+ | if (SELECT_ELEMENT_INNERHTML_BUGGY || TABLE_ELEMENT_INNERHTML_BUGGY) { | ||
+ | if (tagName in Element._insertionTranslations.tags) { | ||
+ | while (element.firstChild) { | ||
+ | element.removeChild(element.firstChild); | ||
+ | } | ||
+ | Element._getContentFromAnonymousElement(tagName, content.stripScripts()) | ||
+ | .each(function(node) { | ||
+ | element.appendChild(node) | ||
+ | }); | ||
+ | } | ||
+ | else { | ||
+ | element.innerHTML = content.stripScripts(); | ||
+ | } | ||
+ | } | ||
+ | else { | ||
+ | element.innerHTML = content.stripScripts(); | ||
+ | } | ||
+ | |||
+ | content.evalScripts.bind(content).defer(); | ||
+ | return element; | ||
+ | } | ||
+ | |||
+ | return update; | ||
+ | })(), | ||
+ | |||
+ | replace: function(element, content) { | ||
+ | element = $(element); | ||
+ | if (content && content.toElement) content = content.toElement(); | ||
+ | else if (!Object.isElement(content)) { | ||
+ | content = Object.toHTML(content); | ||
+ | var range = element.ownerDocument.createRange(); | ||
+ | range.selectNode(element); | ||
+ | content.evalScripts.bind(content).defer(); | ||
+ | content = range.createContextualFragment(content.stripScripts()); | ||
+ | } | ||
+ | element.parentNode.replaceChild(content, element); | ||
+ | return element; | ||
+ | }, | ||
+ | |||
+ | insert: function(element, insertions) { | ||
+ | element = $(element); | ||
+ | |||
+ | if (Object.isString(insertions) || Object.isNumber(insertions) || | ||
+ | Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML))) | ||
+ | insertions = {bottom:insertions}; | ||
+ | |||
+ | var content, insert, tagName, childNodes; | ||
+ | |||
+ | for (var position in insertions) { | ||
+ | content = insertions[position]; | ||
+ | position = position.toLowerCase(); | ||
+ | insert = Element._insertionTranslations[position]; | ||
+ | |||
+ | if (content && content.toElement) content = content.toElement(); | ||
+ | if (Object.isElement(content)) { | ||
+ | insert(element, content); | ||
+ | continue; | ||
+ | } | ||
+ | |||
+ | content = Object.toHTML(content); | ||
+ | |||
+ | tagName = ((position == 'before' || position == 'after') | ||
+ | ? element.parentNode : element).tagName.toUpperCase(); | ||
+ | |||
+ | childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts()); | ||
+ | |||
+ | if (position == 'top' || position == 'after') childNodes.reverse(); | ||
+ | childNodes.each(insert.curry(element)); | ||
+ | |||
+ | content.evalScripts.bind(content).defer(); | ||
+ | } | ||
+ | |||
+ | return element; | ||
+ | }, | ||
+ | |||
+ | wrap: function(element, wrapper, attributes) { | ||
+ | element = $(element); | ||
+ | if (Object.isElement(wrapper)) | ||
+ | $(wrapper).writeAttribute(attributes || { }); | ||
+ | else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes); | ||
+ | else wrapper = new Element('div', wrapper); | ||
+ | if (element.parentNode) | ||
+ | element.parentNode.replaceChild(wrapper, element); | ||
+ | wrapper.appendChild(element); | ||
+ | return wrapper; | ||
+ | }, | ||
+ | |||
+ | inspect: function(element) { | ||
+ | element = $(element); | ||
+ | var result = '<' + element.tagName.toLowerCase(); | ||
+ | $H({'id': 'id', 'className': 'class'}).each(function(pair) { | ||
+ | var property = pair.first(), attribute = pair.last(); | ||
+ | var value = (element[property] || '').toString(); | ||
+ | if (value) result += ' ' + attribute + '=' + value.inspect(true); | ||
+ | }); | ||
+ | return result + '>'; | ||
+ | }, | ||
+ | |||
+ | recursivelyCollect: function(element, property) { | ||
+ | element = $(element); | ||
+ | var elements = []; | ||
+ | while (element = element[property]) | ||
+ | if (element.nodeType == 1) | ||
+ | elements.push(Element.extend(element)); | ||
+ | return elements; | ||
+ | }, | ||
+ | |||
+ | ancestors: function(element) { | ||
+ | return Element.recursivelyCollect(element, 'parentNode'); | ||
+ | }, | ||
+ | |||
+ | descendants: function(element) { | ||
+ | return Element.select(element, "*"); | ||
+ | }, | ||
+ | |||
+ | firstDescendant: function(element) { | ||
+ | element = $(element).firstChild; | ||
+ | while (element && element.nodeType != 1) element = element.nextSibling; | ||
+ | return $(element); | ||
+ | }, | ||
+ | |||
+ | immediateDescendants: function(element) { | ||
+ | if (!(element = $(element).firstChild)) return []; | ||
+ | while (element && element.nodeType != 1) element = element.nextSibling; | ||
+ | if (element) return [element].concat($(element).nextSiblings()); | ||
+ | return []; | ||
+ | }, | ||
+ | |||
+ | previousSiblings: function(element) { | ||
+ | return Element.recursivelyCollect(element, 'previousSibling'); | ||
+ | }, | ||
+ | |||
+ | nextSiblings: function(element) { | ||
+ | return Element.recursivelyCollect(element, 'nextSibling'); | ||
+ | }, | ||
+ | |||
+ | siblings: function(element) { | ||
+ | element = $(element); | ||
+ | return Element.previousSiblings(element).reverse() | ||
+ | .concat(Element.nextSiblings(element)); | ||
+ | }, | ||
+ | |||
+ | match: function(element, selector) { | ||
+ | if (Object.isString(selector)) | ||
+ | selector = new Selector(selector); | ||
+ | return selector.match($(element)); | ||
+ | }, | ||
+ | |||
+ | up: function(element, expression, index) { | ||
+ | element = $(element); | ||
+ | if (arguments.length == 1) return $(element.parentNode); | ||
+ | var ancestors = Element.ancestors(element); | ||
+ | return Object.isNumber(expression) ? ancestors[expression] : | ||
+ | Selector.findElement(ancestors, expression, index); | ||
+ | }, | ||
+ | |||
+ | down: function(element, expression, index) { | ||
+ | element = $(element); | ||
+ | if (arguments.length == 1) return Element.firstDescendant(element); | ||
+ | return Object.isNumber(expression) ? Element.descendants(element)[expression] : | ||
+ | Element.select(element, expression)[index || 0]; | ||
+ | }, | ||
+ | |||
+ | previous: function(element, expression, index) { | ||
+ | element = $(element); | ||
+ | if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element)); | ||
+ | var previousSiblings = Element.previousSiblings(element); | ||
+ | return Object.isNumber(expression) ? previousSiblings[expression] : | ||
+ | Selector.findElement(previousSiblings, expression, index); | ||
+ | }, | ||
+ | |||
+ | next: function(element, expression, index) { | ||
+ | element = $(element); | ||
+ | if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element)); | ||
+ | var nextSiblings = Element.nextSiblings(element); | ||
+ | return Object.isNumber(expression) ? nextSiblings[expression] : | ||
+ | Selector.findElement(nextSiblings, expression, index); | ||
+ | }, | ||
+ | |||
+ | |||
+ | select: function(element) { | ||
+ | var args = Array.prototype.slice.call(arguments, 1); | ||
+ | return Selector.findChildElements(element, args); | ||
+ | }, | ||
+ | |||
+ | adjacent: function(element) { | ||
+ | var args = Array.prototype.slice.call(arguments, 1); | ||
+ | return Selector.findChildElements(element.parentNode, args).without(element); | ||
+ | }, | ||
+ | |||
+ | identify: function(element) { | ||
+ | element = $(element); | ||
+ | var id = Element.readAttribute(element, 'id'); | ||
+ | if (id) return id; | ||
+ | do { id = 'anonymous_element_' + Element.idCounter++ } while ($(id)); | ||
+ | Element.writeAttribute(element, 'id', id); | ||
+ | return id; | ||
+ | }, | ||
+ | |||
+ | readAttribute: function(element, name) { | ||
+ | element = $(element); | ||
+ | if (Prototype.Browser.IE) { | ||
+ | var t = Element._attributeTranslations.read; | ||
+ | if (t.values[name]) return t.values[name](element, name); | ||
+ | if (t.names[name]) name = t.names[name]; | ||
+ | if (name.include(':')) { | ||
+ | return (!element.attributes || !element.attributes[name]) ? null : | ||
+ | element.attributes[name].value; | ||
+ | } | ||
+ | } | ||
+ | return element.getAttribute(name); | ||
+ | }, | ||
+ | |||
+ | writeAttribute: function(element, name, value) { | ||
+ | element = $(element); | ||
+ | var attributes = { }, t = Element._attributeTranslations.write; | ||
+ | |||
+ | if (typeof name == 'object') attributes = name; | ||
+ | else attributes[name] = Object.isUndefined(value) ? true : value; | ||
+ | |||
+ | for (var attr in attributes) { | ||
+ | name = t.names[attr] || attr; | ||
+ | value = attributes[attr]; | ||
+ | if (t.values[attr]) name = t.values[attr](element, value); | ||
+ | if (value === false || value === null) | ||
+ | element.removeAttribute(name); | ||
+ | else if (value === true) | ||
+ | element.setAttribute(name, name); | ||
+ | else element.setAttribute(name, value); | ||
+ | } | ||
+ | return element; | ||
+ | }, | ||
+ | |||
+ | getHeight: function(element) { | ||
+ | return Element.getDimensions(element).height; | ||
+ | }, | ||
+ | |||
+ | getWidth: function(element) { | ||
+ | return Element.getDimensions(element).width; | ||
+ | }, | ||
+ | |||
+ | classNames: function(element) { | ||
+ | return new Element.ClassNames(element); | ||
+ | }, | ||
+ | |||
+ | hasClassName: function(element, className) { | ||
+ | if (!(element = $(element))) return; | ||
+ | var elementClassName = element.className; | ||
+ | return (elementClassName.length > 0 && (elementClassName == className || | ||
+ | new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName))); | ||
+ | }, | ||
+ | |||
+ | addClassName: function(element, className) { | ||
+ | if (!(element = $(element))) return; | ||
+ | if (!Element.hasClassName(element, className)) | ||
+ | element.className += (element.className ? ' ' : '') + className; | ||
+ | return element; | ||
+ | }, | ||
+ | |||
+ | removeClassName: function(element, className) { | ||
+ | if (!(element = $(element))) return; | ||
+ | element.className = element.className.replace( | ||
+ | new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip(); | ||
+ | return element; | ||
+ | }, | ||
+ | |||
+ | toggleClassName: function(element, className) { | ||
+ | if (!(element = $(element))) return; | ||
+ | return Element[Element.hasClassName(element, className) ? | ||
+ | 'removeClassName' : 'addClassName'](element, className); | ||
+ | }, | ||
+ | |||
+ | cleanWhitespace: function(element) { | ||
+ | element = $(element); | ||
+ | var node = element.firstChild; | ||
+ | while (node) { | ||
+ | var nextNode = node.nextSibling; | ||
+ | if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) | ||
+ | element.removeChild(node); | ||
+ | node = nextNode; | ||
+ | } | ||
+ | return element; | ||
+ | }, | ||
+ | |||
+ | empty: function(element) { | ||
+ | return $(element).innerHTML.blank(); | ||
+ | }, | ||
+ | |||
+ | descendantOf: function(element, ancestor) { | ||
+ | element = $(element), ancestor = $(ancestor); | ||
+ | |||
+ | if (element.compareDocumentPosition) | ||
+ | return (element.compareDocumentPosition(ancestor) & 8) === 8; | ||
+ | |||
+ | if (ancestor.contains) | ||
+ | return ancestor.contains(element) && ancestor !== element; | ||
+ | |||
+ | while (element = element.parentNode) | ||
+ | if (element == ancestor) return true; | ||
+ | |||
+ | return false; | ||
+ | }, | ||
+ | |||
+ | scrollTo: function(element) { | ||
+ | element = $(element); | ||
+ | var pos = Element.cumulativeOffset(element); | ||
+ | window.scrollTo(pos[0], pos[1]); | ||
+ | return element; | ||
+ | }, | ||
+ | |||
+ | getStyle: function(element, style) { | ||
+ | element = $(element); | ||
+ | style = style == 'float' ? 'cssFloat' : style.camelize(); | ||
+ | var value = element.style[style]; | ||
+ | if (!value || value == 'auto') { | ||
+ | var css = document.defaultView.getComputedStyle(element, null); | ||
+ | value = css ? css[style] : null; | ||
+ | } | ||
+ | if (style == 'opacity') return value ? parseFloat(value) : 1.0; | ||
+ | return value == 'auto' ? null : value; | ||
+ | }, | ||
+ | |||
+ | getOpacity: function(element) { | ||
+ | return $(element).getStyle('opacity'); | ||
+ | }, | ||
+ | |||
+ | setStyle: function(element, styles) { | ||
+ | element = $(element); | ||
+ | var elementStyle = element.style, match; | ||
+ | if (Object.isString(styles)) { | ||
+ | element.style.cssText += ';' + styles; | ||
+ | return styles.include('opacity') ? | ||
+ | element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element; | ||
+ | } | ||
+ | for (var property in styles) | ||
+ | if (property == 'opacity') element.setOpacity(styles[property]); | ||
+ | else | ||
+ | elementStyle[(property == 'float' || property == 'cssFloat') ? | ||
+ | (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') : | ||
+ | property] = styles[property]; | ||
+ | |||
+ | return element; | ||
+ | }, | ||
+ | |||
+ | setOpacity: function(element, value) { | ||
+ | element = $(element); | ||
+ | element.style.opacity = (value == 1 || value === '') ? '' : | ||
+ | (value < 0.00001) ? 0 : value; | ||
+ | return element; | ||
+ | }, | ||
+ | |||
+ | getDimensions: function(element) { | ||
+ | element = $(element); | ||
+ | var display = Element.getStyle(element, 'display'); | ||
+ | if (display != 'none' && display != null) // Safari bug | ||
+ | return {width: element.offsetWidth, height: element.offsetHeight}; | ||
+ | |||
+ | var els = element.style; | ||
+ | var originalVisibility = els.visibility; | ||
+ | var originalPosition = els.position; | ||
+ | var originalDisplay = els.display; | ||
+ | els.visibility = 'hidden'; | ||
+ | if (originalPosition != 'fixed') // Switching fixed to absolute causes issues in Safari | ||
+ | els.position = 'absolute'; | ||
+ | els.display = 'block'; | ||
+ | var originalWidth = element.clientWidth; | ||
+ | var originalHeight = element.clientHeight; | ||
+ | els.display = originalDisplay; | ||
+ | els.position = originalPosition; | ||
+ | els.visibility = originalVisibility; | ||
+ | return {width: originalWidth, height: originalHeight}; | ||
+ | }, | ||
+ | |||
+ | makePositioned: function(element) { | ||
+ | element = $(element); | ||
+ | var pos = Element.getStyle(element, 'position'); | ||
+ | if (pos == 'static' || !pos) { | ||
+ | element._madePositioned = true; | ||
+ | element.style.position = 'relative'; | ||
+ | if (Prototype.Browser.Opera) { | ||
+ | element.style.top = 0; | ||
+ | element.style.left = 0; | ||
+ | } | ||
+ | } | ||
+ | return element; | ||
+ | }, | ||
+ | |||
+ | undoPositioned: function(element) { | ||
+ | element = $(element); | ||
+ | if (element._madePositioned) { | ||
+ | element._madePositioned = undefined; | ||
+ | element.style.position = | ||
+ | element.style.top = | ||
+ | element.style.left = | ||
+ | element.style.bottom = | ||
+ | element.style.right = ''; | ||
+ | } | ||
+ | return element; | ||
+ | }, | ||
+ | |||
+ | makeClipping: function(element) { | ||
+ | element = $(element); | ||
+ | if (element._overflow) return element; | ||
+ | element._overflow = Element.getStyle(element, 'overflow') || 'auto'; | ||
+ | if (element._overflow !== 'hidden') | ||
+ | element.style.overflow = 'hidden'; | ||
+ | return element; | ||
+ | }, | ||
+ | |||
+ | undoClipping: function(element) { | ||
+ | element = $(element); | ||
+ | if (!element._overflow) return element; | ||
+ | element.style.overflow = element._overflow == 'auto' ? '' : element._overflow; | ||
+ | element._overflow = null; | ||
+ | return element; | ||
+ | }, | ||
+ | |||
+ | cumulativeOffset: function(element) { | ||
+ | var valueT = 0, valueL = 0; | ||
+ | do { | ||
+ | valueT += element.offsetTop || 0; | ||
+ | valueL += element.offsetLeft || 0; | ||
+ | element = element.offsetParent; | ||
+ | } while (element); | ||
+ | return Element._returnOffset(valueL, valueT); | ||
+ | }, | ||
+ | |||
+ | positionedOffset: function(element) { | ||
+ | var valueT = 0, valueL = 0; | ||
+ | do { | ||
+ | valueT += element.offsetTop || 0; | ||
+ | valueL += element.offsetLeft || 0; | ||
+ | element = element.offsetParent; | ||
+ | if (element) { | ||
+ | if (element.tagName.toUpperCase() == 'BODY') break; | ||
+ | var p = Element.getStyle(element, 'position'); | ||
+ | if (p !== 'static') break; | ||
+ | } | ||
+ | } while (element); | ||
+ | return Element._returnOffset(valueL, valueT); | ||
+ | }, | ||
+ | |||
+ | absolutize: function(element) { | ||
+ | element = $(element); | ||
+ | if (Element.getStyle(element, 'position') == 'absolute') return element; | ||
+ | |||
+ | var offsets = Element.positionedOffset(element); | ||
+ | var top = offsets[1]; | ||
+ | var left = offsets[0]; | ||
+ | var width = element.clientWidth; | ||
+ | var height = element.clientHeight; | ||
+ | |||
+ | element._originalLeft = left - parseFloat(element.style.left || 0); | ||
+ | element._originalTop = top - parseFloat(element.style.top || 0); | ||
+ | element._originalWidth = element.style.width; | ||
+ | element._originalHeight = element.style.height; | ||
+ | |||
+ | element.style.position = 'absolute'; | ||
+ | element.style.top = top + 'px'; | ||
+ | element.style.left = left + 'px'; | ||
+ | element.style.width = width + 'px'; | ||
+ | element.style.height = height + 'px'; | ||
+ | return element; | ||
+ | }, | ||
+ | |||
+ | relativize: function(element) { | ||
+ | element = $(element); | ||
+ | if (Element.getStyle(element, 'position') == 'relative') return element; | ||
+ | |||
+ | element.style.position = 'relative'; | ||
+ | var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); | ||
+ | var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0); | ||
+ | |||
+ | element.style.top = top + 'px'; | ||
+ | element.style.left = left + 'px'; | ||
+ | element.style.height = element._originalHeight; | ||
+ | element.style.width = element._originalWidth; | ||
+ | return element; | ||
+ | }, | ||
+ | |||
+ | cumulativeScrollOffset: function(element) { | ||
+ | var valueT = 0, valueL = 0; | ||
+ | do { | ||
+ | valueT += element.scrollTop || 0; | ||
+ | valueL += element.scrollLeft || 0; | ||
+ | element = element.parentNode; | ||
+ | } while (element); | ||
+ | return Element._returnOffset(valueL, valueT); | ||
+ | }, | ||
+ | |||
+ | getOffsetParent: function(element) { | ||
+ | if (element.offsetParent) return $(element.offsetParent); | ||
+ | if (element == document.body) return $(element); | ||
+ | |||
+ | while ((element = element.parentNode) && element != document.body) | ||
+ | if (Element.getStyle(element, 'position') != 'static') | ||
+ | return $(element); | ||
+ | |||
+ | return $(document.body); | ||
+ | }, | ||
+ | |||
+ | viewportOffset: function(forElement) { | ||
+ | var valueT = 0, valueL = 0; | ||
+ | |||
+ | var element = forElement; | ||
+ | do { | ||
+ | valueT += element.offsetTop || 0; | ||
+ | valueL += element.offsetLeft || 0; | ||
+ | |||
+ | if (element.offsetParent == document.body && | ||
+ | Element.getStyle(element, 'position') == 'absolute') break; | ||
+ | |||
+ | } while (element = element.offsetParent); | ||
+ | |||
+ | element = forElement; | ||
+ | do { | ||
+ | if (!Prototype.Browser.Opera || (element.tagName && (element.tagName.toUpperCase() == 'BODY'))) { | ||
+ | valueT -= element.scrollTop || 0; | ||
+ | valueL -= element.scrollLeft || 0; | ||
+ | } | ||
+ | } while (element = element.parentNode); | ||
+ | |||
+ | return Element._returnOffset(valueL, valueT); | ||
+ | }, | ||
+ | |||
+ | clonePosition: function(element, source) { | ||
+ | var options = Object.extend({ | ||
+ | setLeft: true, | ||
+ | setTop: true, | ||
+ | setWidth: true, | ||
+ | setHeight: true, | ||
+ | offsetTop: 0, | ||
+ | offsetLeft: 0 | ||
+ | }, arguments[2] || { }); | ||
+ | |||
+ | source = $(source); | ||
+ | var p = Element.viewportOffset(source); | ||
+ | |||
+ | element = $(element); | ||
+ | var delta = [0, 0]; | ||
+ | var parent = null; | ||
+ | if (Element.getStyle(element, 'position') == 'absolute') { | ||
+ | parent = Element.getOffsetParent(element); | ||
+ | delta = Element.viewportOffset(parent); | ||
+ | } | ||
+ | |||
+ | if (parent == document.body) { | ||
+ | delta[0] -= document.body.offsetLeft; | ||
+ | delta[1] -= document.body.offsetTop; | ||
+ | } | ||
+ | |||
+ | if (options.setLeft) element.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; | ||
+ | if (options.setTop) element.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; | ||
+ | if (options.setWidth) element.style.width = source.offsetWidth + 'px'; | ||
+ | if (options.setHeight) element.style.height = source.offsetHeight + 'px'; | ||
+ | return element; | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | Object.extend(Element.Methods, { | ||
+ | getElementsBySelector: Element.Methods.select, | ||
+ | |||
+ | childElements: Element.Methods.immediateDescendants | ||
+ | }); | ||
+ | |||
+ | Element._attributeTranslations = { | ||
+ | write: { | ||
+ | names: { | ||
+ | className: 'class', | ||
+ | htmlFor: 'for' | ||
+ | }, | ||
+ | values: { } | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | if (Prototype.Browser.Opera) { | ||
+ | Element.Methods.getStyle = Element.Methods.getStyle.wrap( | ||
+ | function(proceed, element, style) { | ||
+ | switch (style) { | ||
+ | case 'left': case 'top': case 'right': case 'bottom': | ||
+ | if (proceed(element, 'position') === 'static') return null; | ||
+ | case 'height': case 'width': | ||
+ | if (!Element.visible(element)) return null; | ||
+ | |||
+ | var dim = parseInt(proceed(element, style), 10); | ||
+ | |||
+ | if (dim !== element['offset' + style.capitalize()]) | ||
+ | return dim + 'px'; | ||
+ | |||
+ | var properties; | ||
+ | if (style === 'height') { | ||
+ | properties = ['border-top-width', 'padding-top', | ||
+ | 'padding-bottom', 'border-bottom-width']; | ||
+ | } | ||
+ | else { | ||
+ | properties = ['border-left-width', 'padding-left', | ||
+ | 'padding-right', 'border-right-width']; | ||
+ | } | ||
+ | return properties.inject(dim, function(memo, property) { | ||
+ | var val = proceed(element, property); | ||
+ | return val === null ? memo : memo - parseInt(val, 10); | ||
+ | }) + 'px'; | ||
+ | default: return proceed(element, style); | ||
+ | } | ||
+ | } | ||
+ | ); | ||
+ | |||
+ | Element.Methods.readAttribute = Element.Methods.readAttribute.wrap( | ||
+ | function(proceed, element, attribute) { | ||
+ | if (attribute === 'title') return element.title; | ||
+ | return proceed(element, attribute); | ||
+ | } | ||
+ | ); | ||
} | } | ||
+ | else if (Prototype.Browser.IE) { | ||
+ | Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap( | ||
+ | function(proceed, element) { | ||
+ | element = $(element); | ||
+ | try { element.offsetParent } | ||
+ | catch(e) { return $(document.body) } | ||
+ | var position = element.getStyle('position'); | ||
+ | if (position !== 'static') return proceed(element); | ||
+ | element.setStyle({ position: 'relative' }); | ||
+ | var value = proceed(element); | ||
+ | element.setStyle({ position: position }); | ||
+ | return value; | ||
+ | } | ||
+ | ); | ||
+ | $w('positionedOffset viewportOffset').each(function(method) { | ||
+ | Element.Methods[method] = Element.Methods[method].wrap( | ||
+ | function(proceed, element) { | ||
+ | element = $(element); | ||
+ | try { element.offsetParent } | ||
+ | catch(e) { return Element._returnOffset(0,0) } | ||
+ | var position = element.getStyle('position'); | ||
+ | if (position !== 'static') return proceed(element); | ||
+ | var offsetParent = element.getOffsetParent(); | ||
+ | if (offsetParent && offsetParent.getStyle('position') === 'fixed') | ||
+ | offsetParent.setStyle({ zoom: 1 }); | ||
+ | element.setStyle({ position: 'relative' }); | ||
+ | var value = proceed(element); | ||
+ | element.setStyle({ position: position }); | ||
+ | return value; | ||
+ | } | ||
+ | ); | ||
+ | }); | ||
+ | Element.Methods.cumulativeOffset = Element.Methods.cumulativeOffset.wrap( | ||
+ | function(proceed, element) { | ||
+ | try { element.offsetParent } | ||
+ | catch(e) { return Element._returnOffset(0,0) } | ||
+ | return proceed(element); | ||
+ | } | ||
+ | ); | ||
+ | Element.Methods.getStyle = function(element, style) { | ||
+ | element = $(element); | ||
+ | style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize(); | ||
+ | var value = element.style[style]; | ||
+ | if (!value && element.currentStyle) value = element.currentStyle[style]; | ||
- | + | if (style == 'opacity') { | |
- | + | if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/)) | |
- | + | if (value[1]) return parseFloat(value[1]) / 100; | |
- | + | return 1.0; | |
- | { | + | } |
- | + | ||
- | + | ||
- | + | ||
- | + | if (value == 'auto') { | |
- | + | if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none')) | |
- | + | return element['offset' + style.capitalize()] + 'px'; | |
+ | return null; | ||
+ | } | ||
+ | return value; | ||
+ | }; | ||
- | + | Element.Methods.setOpacity = function(element, value) { | |
- | + | function stripAlpha(filter){ | |
- | for ( | + | return filter.replace(/alpha\([^\)]*\)/gi,''); |
- | + | } | |
- | + | element = $(element); | |
+ | var currentStyle = element.currentStyle; | ||
+ | if ((currentStyle && !currentStyle.hasLayout) || | ||
+ | (!currentStyle && element.style.zoom == 'normal')) | ||
+ | element.style.zoom = 1; | ||
+ | |||
+ | var filter = element.getStyle('filter'), style = element.style; | ||
+ | if (value == 1 || value === '') { | ||
+ | (filter = stripAlpha(filter)) ? | ||
+ | style.filter = filter : style.removeAttribute('filter'); | ||
+ | return element; | ||
+ | } else if (value < 0.00001) value = 0; | ||
+ | style.filter = stripAlpha(filter) + | ||
+ | 'alpha(opacity=' + (value * 100) + ')'; | ||
+ | return element; | ||
+ | }; | ||
+ | |||
+ | Element._attributeTranslations = (function(){ | ||
+ | |||
+ | var classProp = 'className'; | ||
+ | var forProp = 'for'; | ||
+ | |||
+ | var el = document.createElement('div'); | ||
+ | |||
+ | el.setAttribute(classProp, 'x'); | ||
+ | |||
+ | if (el.className !== 'x') { | ||
+ | el.setAttribute('class', 'x'); | ||
+ | if (el.className === 'x') { | ||
+ | classProp = 'class'; | ||
+ | } | ||
+ | } | ||
+ | el = null; | ||
+ | |||
+ | el = document.createElement('label'); | ||
+ | el.setAttribute(forProp, 'x'); | ||
+ | if (el.htmlFor !== 'x') { | ||
+ | el.setAttribute('htmlFor', 'x'); | ||
+ | if (el.htmlFor === 'x') { | ||
+ | forProp = 'htmlFor'; | ||
+ | } | ||
+ | } | ||
+ | el = null; | ||
+ | |||
+ | return { | ||
+ | read: { | ||
+ | names: { | ||
+ | 'class': classProp, | ||
+ | 'className': classProp, | ||
+ | 'for': forProp, | ||
+ | 'htmlFor': forProp | ||
+ | }, | ||
+ | values: { | ||
+ | _getAttr: function(element, attribute) { | ||
+ | return element.getAttribute(attribute); | ||
+ | }, | ||
+ | _getAttr2: function(element, attribute) { | ||
+ | return element.getAttribute(attribute, 2); | ||
+ | }, | ||
+ | _getAttrNode: function(element, attribute) { | ||
+ | var node = element.getAttributeNode(attribute); | ||
+ | return node ? node.value : ""; | ||
+ | }, | ||
+ | _getEv: (function(){ | ||
+ | |||
+ | var el = document.createElement('div'); | ||
+ | el.onclick = Prototype.emptyFunction; | ||
+ | var value = el.getAttribute('onclick'); | ||
+ | var f; | ||
+ | |||
+ | if (String(value).indexOf('{') > -1) { | ||
+ | f = function(element, attribute) { | ||
+ | attribute = element.getAttribute(attribute); | ||
+ | if (!attribute) return null; | ||
+ | attribute = attribute.toString(); | ||
+ | attribute = attribute.split('{')[1]; | ||
+ | attribute = attribute.split('}')[0]; | ||
+ | return attribute.strip(); | ||
+ | }; | ||
+ | } | ||
+ | else if (value === '') { | ||
+ | f = function(element, attribute) { | ||
+ | attribute = element.getAttribute(attribute); | ||
+ | if (!attribute) return null; | ||
+ | return attribute.strip(); | ||
+ | }; | ||
+ | } | ||
+ | el = null; | ||
+ | return f; | ||
+ | })(), | ||
+ | _flag: function(element, attribute) { | ||
+ | return $(element).hasAttribute(attribute) ? attribute : null; | ||
+ | }, | ||
+ | style: function(element) { | ||
+ | return element.style.cssText.toLowerCase(); | ||
+ | }, | ||
+ | title: function(element) { | ||
+ | return element.title; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | })(); | ||
+ | |||
+ | Element._attributeTranslations.write = { | ||
+ | names: Object.extend({ | ||
+ | cellpadding: 'cellPadding', | ||
+ | cellspacing: 'cellSpacing' | ||
+ | }, Element._attributeTranslations.read.names), | ||
+ | values: { | ||
+ | checked: function(element, value) { | ||
+ | element.checked = !!value; | ||
+ | }, | ||
+ | |||
+ | style: function(element, value) { | ||
+ | element.style.cssText = value ? value : ''; | ||
+ | } | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | Element._attributeTranslations.has = {}; | ||
+ | |||
+ | $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' + | ||
+ | 'encType maxLength readOnly longDesc frameBorder').each(function(attr) { | ||
+ | Element._attributeTranslations.write.names[attr.toLowerCase()] = attr; | ||
+ | Element._attributeTranslations.has[attr.toLowerCase()] = attr; | ||
+ | }); | ||
+ | |||
+ | (function(v) { | ||
+ | Object.extend(v, { | ||
+ | href: v._getAttr2, | ||
+ | src: v._getAttr2, | ||
+ | type: v._getAttr, | ||
+ | action: v._getAttrNode, | ||
+ | disabled: v._flag, | ||
+ | checked: v._flag, | ||
+ | readonly: v._flag, | ||
+ | multiple: v._flag, | ||
+ | onload: v._getEv, | ||
+ | onunload: v._getEv, | ||
+ | onclick: v._getEv, | ||
+ | ondblclick: v._getEv, | ||
+ | onmousedown: v._getEv, | ||
+ | onmouseup: v._getEv, | ||
+ | onmouseover: v._getEv, | ||
+ | onmousemove: v._getEv, | ||
+ | onmouseout: v._getEv, | ||
+ | onfocus: v._getEv, | ||
+ | onblur: v._getEv, | ||
+ | onkeypress: v._getEv, | ||
+ | onkeydown: v._getEv, | ||
+ | onkeyup: v._getEv, | ||
+ | onsubmit: v._getEv, | ||
+ | onreset: v._getEv, | ||
+ | onselect: v._getEv, | ||
+ | onchange: v._getEv | ||
+ | }); | ||
+ | })(Element._attributeTranslations.read.values); | ||
+ | |||
+ | if (Prototype.BrowserFeatures.ElementExtensions) { | ||
+ | (function() { | ||
+ | function _descendants(element) { | ||
+ | var nodes = element.getElementsByTagName('*'), results = []; | ||
+ | for (var i = 0, node; node = nodes[i]; i++) | ||
+ | if (node.tagName !== "!") // Filter out comment nodes. | ||
+ | results.push(node); | ||
+ | return results; | ||
+ | } | ||
+ | |||
+ | Element.Methods.down = function(element, expression, index) { | ||
+ | element = $(element); | ||
+ | if (arguments.length == 1) return element.firstDescendant(); | ||
+ | return Object.isNumber(expression) ? _descendants(element)[expression] : | ||
+ | Element.select(element, expression)[index || 0]; | ||
+ | } | ||
+ | })(); | ||
+ | } | ||
- | |||
- | |||
} | } | ||
+ | else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) { | ||
+ | Element.Methods.setOpacity = function(element, value) { | ||
+ | element = $(element); | ||
+ | element.style.opacity = (value == 1) ? 0.999999 : | ||
+ | (value === '') ? '' : (value < 0.00001) ? 0 : value; | ||
+ | return element; | ||
+ | }; | ||
+ | } | ||
+ | else if (Prototype.Browser.WebKit) { | ||
+ | Element.Methods.setOpacity = function(element, value) { | ||
+ | element = $(element); | ||
+ | element.style.opacity = (value == 1 || value === '') ? '' : | ||
+ | (value < 0.00001) ? 0 : value; | ||
+ | if (value == 1) | ||
+ | if(element.tagName.toUpperCase() == 'IMG' && element.width) { | ||
+ | element.width++; element.width--; | ||
+ | } else try { | ||
+ | var n = document.createTextNode(' '); | ||
+ | element.appendChild(n); | ||
+ | element.removeChild(n); | ||
+ | } catch (e) { } | ||
- | + | return element; | |
- | + | }; | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | Element.Methods.cumulativeOffset = function(element) { | |
- | + | var valueT = 0, valueL = 0; | |
- | + | do { | |
+ | valueT += element.offsetTop || 0; | ||
+ | valueL += element.offsetLeft || 0; | ||
+ | if (element.offsetParent == document.body) | ||
+ | if (Element.getStyle(element, 'position') == 'absolute') break; | ||
- | + | element = element.offsetParent; | |
- | + | } while (element); | |
- | + | ||
- | + | ||
+ | return Element._returnOffset(valueL, valueT); | ||
+ | }; | ||
+ | } | ||
- | + | if ('outerHTML' in document.documentElement) { | |
- | + | Element.Methods.replace = function(element, content) { | |
- | + | element = $(element); | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | if (content && content.toElement) content = content.toElement(); | |
- | + | if (Object.isElement(content)) { | |
- | + | element.parentNode.replaceChild(content, element); | |
- | + | return element; | |
- | + | } | |
- | + | content = Object.toHTML(content); | |
- | + | var parent = element.parentNode, tagName = parent.tagName.toUpperCase(); | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | if (Element._insertionTranslations.tags[tagName]) { | |
+ | var nextSibling = element.next(); | ||
+ | var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts()); | ||
+ | parent.removeChild(element); | ||
+ | if (nextSibling) | ||
+ | fragments.each(function(node) { parent.insertBefore(node, nextSibling) }); | ||
+ | else | ||
+ | fragments.each(function(node) { parent.appendChild(node) }); | ||
+ | } | ||
+ | else element.outerHTML = content.stripScripts(); | ||
- | + | content.evalScripts.bind(content).defer(); | |
- | + | return element; | |
+ | }; | ||
+ | } | ||
- | + | Element._returnOffset = function(l, t) { | |
+ | var result = [l, t]; | ||
+ | result.left = l; | ||
+ | result.top = t; | ||
+ | return result; | ||
+ | }; | ||
- | + | Element._getContentFromAnonymousElement = function(tagName, html) { | |
- | + | var div = new Element('div'), t = Element._insertionTranslations.tags[tagName]; | |
- | + | if (t) { | |
- | + | div.innerHTML = t[0] + html + t[1]; | |
- | + | t[2].times(function() { div = div.firstChild }); | |
- | + | } else div.innerHTML = html; | |
- | + | return $A(div.childNodes); | |
- | + | }; | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | Element._insertionTranslations = { | |
- | + | before: function(element, node) { | |
+ | element.parentNode.insertBefore(node, element); | ||
+ | }, | ||
+ | top: function(element, node) { | ||
+ | element.insertBefore(node, element.firstChild); | ||
+ | }, | ||
+ | bottom: function(element, node) { | ||
+ | element.appendChild(node); | ||
+ | }, | ||
+ | after: function(element, node) { | ||
+ | element.parentNode.insertBefore(node, element.nextSibling); | ||
+ | }, | ||
+ | tags: { | ||
+ | TABLE: ['<table>', '</table>', 1], | ||
+ | TBODY: ['<table><tbody>', '</tbody></table>', 2], | ||
+ | TR: ['<table><tbody><tr>', '</tr></tbody></table>', 3], | ||
+ | TD: ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4], | ||
+ | SELECT: ['<select>', '</select>', 1] | ||
+ | } | ||
+ | }; | ||
- | + | (function() { | |
- | + | var tags = Element._insertionTranslations.tags; | |
+ | Object.extend(tags, { | ||
+ | THEAD: tags.TBODY, | ||
+ | TFOOT: tags.TBODY, | ||
+ | TH: tags.TD | ||
+ | }); | ||
+ | })(); | ||
- | + | Element.Methods.Simulated = { | |
- | + | hasAttribute: function(element, attribute) { | |
- | + | attribute = Element._attributeTranslations.has[attribute] || attribute; | |
- | + | var node = $(element).getAttributeNode(attribute); | |
- | + | return !!(node && node.specified); | |
- | + | } | |
+ | }; | ||
- | + | Element.Methods.ByTag = { }; | |
- | + | ||
- | + | Object.extend(Element, Element.Methods); | |
- | + | (function(div) { | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | if (!Prototype.BrowserFeatures.ElementExtensions && div['__proto__']) { | |
- | + | window.HTMLElement = { }; | |
- | + | window.HTMLElement.prototype = div['__proto__']; | |
- | + | Prototype.BrowserFeatures.ElementExtensions = true; | |
- | + | } | |
- | + | div = null; | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
+ | })(document.createElement('div')) | ||
+ | Element.extend = (function() { | ||
+ | |||
+ | function checkDeficiency(tagName) { | ||
+ | if (typeof window.Element != 'undefined') { | ||
+ | var proto = window.Element.prototype; | ||
+ | if (proto) { | ||
+ | var id = '_' + (Math.random()+'').slice(2); | ||
+ | var el = document.createElement(tagName); | ||
+ | proto[id] = 'x'; | ||
+ | var isBuggy = (el[id] !== 'x'); | ||
+ | delete proto[id]; | ||
+ | el = null; | ||
+ | return isBuggy; | ||
+ | } | ||
+ | } | ||
+ | return false; | ||
+ | } | ||
+ | |||
+ | function extendElementWith(element, methods) { | ||
+ | for (var property in methods) { | ||
+ | var value = methods[property]; | ||
+ | if (Object.isFunction(value) && !(property in element)) | ||
+ | element[property] = value.methodize(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = checkDeficiency('object'); | ||
+ | |||
+ | if (Prototype.BrowserFeatures.SpecificElementExtensions) { | ||
+ | if (HTMLOBJECTELEMENT_PROTOTYPE_BUGGY) { | ||
+ | return function(element) { | ||
+ | if (element && typeof element._extendedByPrototype == 'undefined') { | ||
+ | var t = element.tagName; | ||
+ | if (t && (/^(?:object|applet|embed)$/i.test(t))) { | ||
+ | extendElementWith(element, Element.Methods); | ||
+ | extendElementWith(element, Element.Methods.Simulated); | ||
+ | extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]); | ||
+ | } | ||
+ | } | ||
+ | return element; | ||
+ | } | ||
+ | } | ||
+ | return Prototype.K; | ||
+ | } | ||
+ | |||
+ | var Methods = { }, ByTag = Element.Methods.ByTag; | ||
+ | |||
+ | var extend = Object.extend(function(element) { | ||
+ | if (!element || typeof element._extendedByPrototype != 'undefined' || | ||
+ | element.nodeType != 1 || element == window) return element; | ||
+ | |||
+ | var methods = Object.clone(Methods), | ||
+ | tagName = element.tagName.toUpperCase(); | ||
+ | |||
+ | if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]); | ||
+ | |||
+ | extendElementWith(element, methods); | ||
+ | |||
+ | element._extendedByPrototype = Prototype.emptyFunction; | ||
+ | return element; | ||
+ | |||
+ | }, { | ||
+ | refresh: function() { | ||
+ | if (!Prototype.BrowserFeatures.ElementExtensions) { | ||
+ | Object.extend(Methods, Element.Methods); | ||
+ | Object.extend(Methods, Element.Methods.Simulated); | ||
+ | } | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | extend.refresh(); | ||
+ | return extend; | ||
+ | })(); | ||
+ | |||
+ | Element.hasAttribute = function(element, attribute) { | ||
+ | if (element.hasAttribute) return element.hasAttribute(attribute); | ||
+ | return Element.Methods.Simulated.hasAttribute(element, attribute); | ||
+ | }; | ||
+ | |||
+ | Element.addMethods = function(methods) { | ||
+ | var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag; | ||
+ | |||
+ | if (!methods) { | ||
+ | Object.extend(Form, Form.Methods); | ||
+ | Object.extend(Form.Element, Form.Element.Methods); | ||
+ | Object.extend(Element.Methods.ByTag, { | ||
+ | "FORM": Object.clone(Form.Methods), | ||
+ | "INPUT": Object.clone(Form.Element.Methods), | ||
+ | "SELECT": Object.clone(Form.Element.Methods), | ||
+ | "TEXTAREA": Object.clone(Form.Element.Methods) | ||
+ | }); | ||
+ | } | ||
+ | |||
+ | if (arguments.length == 2) { | ||
+ | var tagName = methods; | ||
+ | methods = arguments[1]; | ||
+ | } | ||
+ | |||
+ | if (!tagName) Object.extend(Element.Methods, methods || { }); | ||
+ | else { | ||
+ | if (Object.isArray(tagName)) tagName.each(extend); | ||
+ | else extend(tagName); | ||
+ | } | ||
+ | |||
+ | function extend(tagName) { | ||
+ | tagName = tagName.toUpperCase(); | ||
+ | if (!Element.Methods.ByTag[tagName]) | ||
+ | Element.Methods.ByTag[tagName] = { }; | ||
+ | Object.extend(Element.Methods.ByTag[tagName], methods); | ||
+ | } | ||
+ | |||
+ | function copy(methods, destination, onlyIfAbsent) { | ||
+ | onlyIfAbsent = onlyIfAbsent || false; | ||
+ | for (var property in methods) { | ||
+ | var value = methods[property]; | ||
+ | if (!Object.isFunction(value)) continue; | ||
+ | if (!onlyIfAbsent || !(property in destination)) | ||
+ | destination[property] = value.methodize(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | function findDOMClass(tagName) { | ||
+ | var klass; | ||
+ | var trans = { | ||
+ | "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph", | ||
+ | "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList", | ||
+ | "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading", | ||
+ | "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote", | ||
+ | "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION": | ||
+ | "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD": | ||
+ | "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR": | ||
+ | "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET": | ||
+ | "FrameSet", "IFRAME": "IFrame" | ||
+ | }; | ||
+ | if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element'; | ||
+ | if (window[klass]) return window[klass]; | ||
+ | klass = 'HTML' + tagName + 'Element'; | ||
+ | if (window[klass]) return window[klass]; | ||
+ | klass = 'HTML' + tagName.capitalize() + 'Element'; | ||
+ | if (window[klass]) return window[klass]; | ||
+ | |||
+ | var element = document.createElement(tagName); | ||
+ | var proto = element['__proto__'] || element.constructor.prototype; | ||
+ | element = null; | ||
+ | return proto; | ||
+ | } | ||
+ | |||
+ | var elementPrototype = window.HTMLElement ? HTMLElement.prototype : | ||
+ | Element.prototype; | ||
+ | |||
+ | if (F.ElementExtensions) { | ||
+ | copy(Element.Methods, elementPrototype); | ||
+ | copy(Element.Methods.Simulated, elementPrototype, true); | ||
+ | } | ||
+ | |||
+ | if (F.SpecificElementExtensions) { | ||
+ | for (var tag in Element.Methods.ByTag) { | ||
+ | var klass = findDOMClass(tag); | ||
+ | if (Object.isUndefined(klass)) continue; | ||
+ | copy(T[tag], klass.prototype); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | Object.extend(Element, Element.Methods); | ||
+ | delete Element.ByTag; | ||
+ | |||
+ | if (Element.extend.refresh) Element.extend.refresh(); | ||
+ | Element.cache = { }; | ||
+ | }; | ||
+ | |||
+ | |||
+ | document.viewport = { | ||
+ | |||
+ | getDimensions: function() { | ||
+ | return { width: this.getWidth(), height: this.getHeight() }; | ||
+ | }, | ||
+ | |||
+ | getScrollOffsets: function() { | ||
+ | return Element._returnOffset( | ||
+ | window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft, | ||
+ | window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | (function(viewport) { | ||
+ | var B = Prototype.Browser, doc = document, element, property = {}; | ||
+ | |||
+ | function getRootElement() { | ||
+ | if (B.WebKit && !doc.evaluate) | ||
+ | return document; | ||
+ | |||
+ | if (B.Opera && window.parseFloat(window.opera.version()) < 9.5) | ||
+ | return document.body; | ||
+ | |||
+ | return document.documentElement; | ||
+ | } | ||
+ | |||
+ | function define(D) { | ||
+ | if (!element) element = getRootElement(); | ||
+ | |||
+ | property[D] = 'client' + D; | ||
+ | |||
+ | viewport['get' + D] = function() { return element[property[D]] }; | ||
+ | return viewport['get' + D](); | ||
+ | } | ||
+ | |||
+ | viewport.getWidth = define.curry('Width'); | ||
+ | |||
+ | viewport.getHeight = define.curry('Height'); | ||
+ | })(document.viewport); | ||
+ | |||
+ | |||
+ | Element.Storage = { | ||
+ | UID: 1 | ||
+ | }; | ||
+ | |||
+ | Element.addMethods({ | ||
+ | getStorage: function(element) { | ||
+ | if (!(element = $(element))) return; | ||
+ | |||
+ | var uid; | ||
+ | if (element === window) { | ||
+ | uid = 0; | ||
+ | } else { | ||
+ | if (typeof element._prototypeUID === "undefined") | ||
+ | element._prototypeUID = [Element.Storage.UID++]; | ||
+ | uid = element._prototypeUID[0]; | ||
+ | } | ||
+ | |||
+ | if (!Element.Storage[uid]) | ||
+ | Element.Storage[uid] = $H(); | ||
+ | |||
+ | return Element.Storage[uid]; | ||
+ | }, | ||
+ | |||
+ | store: function(element, key, value) { | ||
+ | if (!(element = $(element))) return; | ||
+ | |||
+ | if (arguments.length === 2) { | ||
+ | Element.getStorage(element).update(key); | ||
+ | } else { | ||
+ | Element.getStorage(element).set(key, value); | ||
+ | } | ||
+ | |||
+ | return element; | ||
+ | }, | ||
+ | |||
+ | retrieve: function(element, key, defaultValue) { | ||
+ | if (!(element = $(element))) return; | ||
+ | var hash = Element.getStorage(element), value = hash.get(key); | ||
+ | |||
+ | if (Object.isUndefined(value)) { | ||
+ | hash.set(key, defaultValue); | ||
+ | value = defaultValue; | ||
+ | } | ||
+ | |||
+ | return value; | ||
+ | }, | ||
+ | |||
+ | clone: function(element, deep) { | ||
+ | if (!(element = $(element))) return; | ||
+ | var clone = element.cloneNode(deep); | ||
+ | clone._prototypeUID = void 0; | ||
+ | if (deep) { | ||
+ | var descendants = Element.select(clone, '*'), | ||
+ | i = descendants.length; | ||
+ | while (i--) { | ||
+ | descendants[i]._prototypeUID = void 0; | ||
+ | } | ||
+ | } | ||
+ | return Element.extend(clone); | ||
+ | } | ||
+ | }); | ||
+ | /* Portions of the Selector class are derived from Jack Slocum's DomQuery, | ||
+ | * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style | ||
+ | * license. Please see http://www.yui-ext.com/ for more information. */ | ||
+ | |||
+ | var Selector = Class.create({ | ||
+ | initialize: function(expression) { | ||
+ | this.expression = expression.strip(); | ||
+ | |||
+ | if (this.shouldUseSelectorsAPI()) { | ||
+ | this.mode = 'selectorsAPI'; | ||
+ | } else if (this.shouldUseXPath()) { | ||
+ | this.mode = 'xpath'; | ||
+ | this.compileXPathMatcher(); | ||
+ | } else { | ||
+ | this.mode = "normal"; | ||
+ | this.compileMatcher(); | ||
+ | } | ||
+ | |||
+ | }, | ||
+ | |||
+ | shouldUseXPath: (function() { | ||
+ | |||
+ | var IS_DESCENDANT_SELECTOR_BUGGY = (function(){ | ||
+ | var isBuggy = false; | ||
+ | if (document.evaluate && window.XPathResult) { | ||
+ | var el = document.createElement('div'); | ||
+ | el.innerHTML = '<ul><li></li></ul><div><ul><li></li></ul></div>'; | ||
+ | |||
+ | var xpath = ".//*[local-name()='ul' or local-name()='UL']" + | ||
+ | "//*[local-name()='li' or local-name()='LI']"; | ||
+ | |||
+ | var result = document.evaluate(xpath, el, null, | ||
+ | XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); | ||
+ | |||
+ | isBuggy = (result.snapshotLength !== 2); | ||
+ | el = null; | ||
+ | } | ||
+ | return isBuggy; | ||
+ | })(); | ||
+ | |||
+ | return function() { | ||
+ | if (!Prototype.BrowserFeatures.XPath) return false; | ||
+ | |||
+ | var e = this.expression; | ||
+ | |||
+ | if (Prototype.Browser.WebKit && | ||
+ | (e.include("-of-type") || e.include(":empty"))) | ||
+ | return false; | ||
+ | |||
+ | if ((/(\[[\w-]*?:|:checked)/).test(e)) | ||
+ | return false; | ||
+ | |||
+ | if (IS_DESCENDANT_SELECTOR_BUGGY) return false; | ||
+ | |||
+ | return true; | ||
+ | } | ||
+ | |||
+ | })(), | ||
+ | |||
+ | shouldUseSelectorsAPI: function() { | ||
+ | if (!Prototype.BrowserFeatures.SelectorsAPI) return false; | ||
+ | |||
+ | if (Selector.CASE_INSENSITIVE_CLASS_NAMES) return false; | ||
+ | |||
+ | if (!Selector._div) Selector._div = new Element('div'); | ||
+ | |||
+ | try { | ||
+ | Selector._div.querySelector(this.expression); | ||
+ | } catch(e) { | ||
+ | return false; | ||
+ | } | ||
+ | |||
+ | return true; | ||
+ | }, | ||
+ | |||
+ | compileMatcher: function() { | ||
+ | var e = this.expression, ps = Selector.patterns, h = Selector.handlers, | ||
+ | c = Selector.criteria, le, p, m, len = ps.length, name; | ||
+ | |||
+ | if (Selector._cache[e]) { | ||
+ | this.matcher = Selector._cache[e]; | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | this.matcher = ["this.matcher = function(root) {", | ||
+ | "var r = root, h = Selector.handlers, c = false, n;"]; | ||
+ | |||
+ | while (e && le != e && (/\S/).test(e)) { | ||
+ | le = e; | ||
+ | for (var i = 0; i<len; i++) { | ||
+ | p = ps[i].re; | ||
+ | name = ps[i].name; | ||
+ | if (m = e.match(p)) { | ||
+ | this.matcher.push(Object.isFunction(c[name]) ? c[name](m) : | ||
+ | new Template(c[name]).evaluate(m)); | ||
+ | e = e.replace(m[0], ''); | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | this.matcher.push("return h.unique(n);\n}"); | ||
+ | eval(this.matcher.join('\n')); | ||
+ | Selector._cache[this.expression] = this.matcher; | ||
+ | }, | ||
+ | |||
+ | compileXPathMatcher: function() { | ||
+ | var e = this.expression, ps = Selector.patterns, | ||
+ | x = Selector.xpath, le, m, len = ps.length, name; | ||
+ | |||
+ | if (Selector._cache[e]) { | ||
+ | this.xpath = Selector._cache[e]; return; | ||
+ | } | ||
+ | |||
+ | this.matcher = ['.//*']; | ||
+ | while (e && le != e && (/\S/).test(e)) { | ||
+ | le = e; | ||
+ | for (var i = 0; i<len; i++) { | ||
+ | name = ps[i].name; | ||
+ | if (m = e.match(ps[i].re)) { | ||
+ | this.matcher.push(Object.isFunction(x[name]) ? x[name](m) : | ||
+ | new Template(x[name]).evaluate(m)); | ||
+ | e = e.replace(m[0], ''); | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | this.xpath = this.matcher.join(''); | ||
+ | Selector._cache[this.expression] = this.xpath; | ||
+ | }, | ||
+ | |||
+ | findElements: function(root) { | ||
+ | root = root || document; | ||
+ | var e = this.expression, results; | ||
+ | |||
+ | switch (this.mode) { | ||
+ | case 'selectorsAPI': | ||
+ | if (root !== document) { | ||
+ | var oldId = root.id, id = $(root).identify(); | ||
+ | id = id.replace(/([\.:])/g, "\\$1"); | ||
+ | e = "#" + id + " " + e; | ||
+ | } | ||
+ | |||
+ | results = $A(root.querySelectorAll(e)).map(Element.extend); | ||
+ | root.id = oldId; | ||
+ | |||
+ | return results; | ||
+ | case 'xpath': | ||
+ | return document._getElementsByXPath(this.xpath, root); | ||
+ | default: | ||
+ | return this.matcher(root); | ||
+ | } | ||
+ | }, | ||
+ | |||
+ | match: function(element) { | ||
+ | this.tokens = []; | ||
+ | |||
+ | var e = this.expression, ps = Selector.patterns, as = Selector.assertions; | ||
+ | var le, p, m, len = ps.length, name; | ||
+ | |||
+ | while (e && le !== e && (/\S/).test(e)) { | ||
+ | le = e; | ||
+ | for (var i = 0; i<len; i++) { | ||
+ | p = ps[i].re; | ||
+ | name = ps[i].name; | ||
+ | if (m = e.match(p)) { | ||
+ | if (as[name]) { | ||
+ | this.tokens.push([name, Object.clone(m)]); | ||
+ | e = e.replace(m[0], ''); | ||
+ | } else { | ||
+ | return this.findElements(document).include(element); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | var match = true, name, matches; | ||
+ | for (var i = 0, token; token = this.tokens[i]; i++) { | ||
+ | name = token[0], matches = token[1]; | ||
+ | if (!Selector.assertions[name](element, matches)) { | ||
+ | match = false; break; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | return match; | ||
+ | }, | ||
+ | |||
+ | toString: function() { | ||
+ | return this.expression; | ||
+ | }, | ||
+ | |||
+ | inspect: function() { | ||
+ | return "#<Selector:" + this.expression.inspect() + ">"; | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | if (Prototype.BrowserFeatures.SelectorsAPI && | ||
+ | document.compatMode === 'BackCompat') { | ||
+ | Selector.CASE_INSENSITIVE_CLASS_NAMES = (function(){ | ||
+ | var div = document.createElement('div'), | ||
+ | span = document.createElement('span'); | ||
+ | |||
+ | div.id = "prototype_test_id"; | ||
+ | span.className = 'Test'; | ||
+ | div.appendChild(span); | ||
+ | var isIgnored = (div.querySelector('#prototype_test_id .test') !== null); | ||
+ | div = span = null; | ||
+ | return isIgnored; | ||
+ | })(); | ||
} | } | ||
+ | Object.extend(Selector, { | ||
+ | _cache: { }, | ||
+ | xpath: { | ||
+ | descendant: "//*", | ||
+ | child: "/*", | ||
+ | adjacent: "/following-sibling::*[1]", | ||
+ | laterSibling: '/following-sibling::*', | ||
+ | tagName: function(m) { | ||
+ | if (m[1] == '*') return ''; | ||
+ | return "[local-name()='" + m[1].toLowerCase() + | ||
+ | "' or local-name()='" + m[1].toUpperCase() + "']"; | ||
+ | }, | ||
+ | className: "[contains(concat(' ', @class, ' '), ' #{1} ')]", | ||
+ | id: "[@id='#{1}']", | ||
+ | attrPresence: function(m) { | ||
+ | m[1] = m[1].toLowerCase(); | ||
+ | return new Template("[@#{1}]").evaluate(m); | ||
+ | }, | ||
+ | attr: function(m) { | ||
+ | m[1] = m[1].toLowerCase(); | ||
+ | m[3] = m[5] || m[6]; | ||
+ | return new Template(Selector.xpath.operators[m[2]]).evaluate(m); | ||
+ | }, | ||
+ | pseudo: function(m) { | ||
+ | var h = Selector.xpath.pseudos[m[1]]; | ||
+ | if (!h) return ''; | ||
+ | if (Object.isFunction(h)) return h(m); | ||
+ | return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m); | ||
+ | }, | ||
+ | operators: { | ||
+ | '=': "[@#{1}='#{3}']", | ||
+ | '!=': "[@#{1}!='#{3}']", | ||
+ | '^=': "[starts-with(@#{1}, '#{3}')]", | ||
+ | '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']", | ||
+ | '*=': "[contains(@#{1}, '#{3}')]", | ||
+ | '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]", | ||
+ | '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]" | ||
+ | }, | ||
+ | pseudos: { | ||
+ | 'first-child': '[not(preceding-sibling::*)]', | ||
+ | 'last-child': '[not(following-sibling::*)]', | ||
+ | 'only-child': '[not(preceding-sibling::* or following-sibling::*)]', | ||
+ | 'empty': "[count(*) = 0 and (count(text()) = 0)]", | ||
+ | 'checked': "[@checked]", | ||
+ | 'disabled': "[(@disabled) and (@type!='hidden')]", | ||
+ | 'enabled': "[not(@disabled) and (@type!='hidden')]", | ||
+ | 'not': function(m) { | ||
+ | var e = m[6], p = Selector.patterns, | ||
+ | x = Selector.xpath, le, v, len = p.length, name; | ||
+ | var exclusion = []; | ||
+ | while (e && le != e && (/\S/).test(e)) { | ||
+ | le = e; | ||
+ | for (var i = 0; i<len; i++) { | ||
+ | name = p[i].name | ||
+ | if (m = e.match(p[i].re)) { | ||
+ | v = Object.isFunction(x[name]) ? x[name](m) : new Template(x[name]).evaluate(m); | ||
+ | exclusion.push("(" + v.substring(1, v.length - 1) + ")"); | ||
+ | e = e.replace(m[0], ''); | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | return "[not(" + exclusion.join(" and ") + ")]"; | ||
+ | }, | ||
+ | 'nth-child': function(m) { | ||
+ | return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m); | ||
+ | }, | ||
+ | 'nth-last-child': function(m) { | ||
+ | return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m); | ||
+ | }, | ||
+ | 'nth-of-type': function(m) { | ||
+ | return Selector.xpath.pseudos.nth("position() ", m); | ||
+ | }, | ||
+ | 'nth-last-of-type': function(m) { | ||
+ | return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m); | ||
+ | }, | ||
+ | 'first-of-type': function(m) { | ||
+ | m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m); | ||
+ | }, | ||
+ | 'last-of-type': function(m) { | ||
+ | m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m); | ||
+ | }, | ||
+ | 'only-of-type': function(m) { | ||
+ | var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m); | ||
+ | }, | ||
+ | nth: function(fragment, m) { | ||
+ | var mm, formula = m[6], predicate; | ||
+ | if (formula == 'even') formula = '2n+0'; | ||
+ | if (formula == 'odd') formula = '2n+1'; | ||
+ | if (mm = formula.match(/^(\d+)$/)) // digit only | ||
+ | return '[' + fragment + "= " + mm[1] + ']'; | ||
+ | if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b | ||
+ | if (mm[1] == "-") mm[1] = -1; | ||
+ | var a = mm[1] ? Number(mm[1]) : 1; | ||
+ | var b = mm[2] ? Number(mm[2]) : 0; | ||
+ | predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " + | ||
+ | "((#{fragment} - #{b}) div #{a} >= 0)]"; | ||
+ | return new Template(predicate).evaluate({ | ||
+ | fragment: fragment, a: a, b: b }); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | }, | ||
- | + | criteria: { | |
- | + | tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;', | |
- | + | className: 'n = h.className(n, r, "#{1}", c); c = false;', | |
- | + | id: 'n = h.id(n, r, "#{1}", c); c = false;', | |
- | + | attrPresence: 'n = h.attrPresence(n, r, "#{1}", c); c = false;', | |
- | function | + | attr: function(m) { |
- | { | + | m[3] = (m[5] || m[6]); |
- | + | return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = false;').evaluate(m); | |
- | + | }, | |
- | + | pseudo: function(m) { | |
- | + | if (m[6]) m[6] = m[6].replace(/"/g, '\\"'); | |
- | + | return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m); | |
- | + | }, | |
- | + | descendant: 'c = "descendant";', | |
- | + | child: 'c = "child";', | |
- | + | adjacent: 'c = "adjacent";', | |
+ | laterSibling: 'c = "laterSibling";' | ||
+ | }, | ||
+ | patterns: [ | ||
+ | { name: 'laterSibling', re: /^\s*~\s*/ }, | ||
+ | { name: 'child', re: /^\s*>\s*/ }, | ||
+ | { name: 'adjacent', re: /^\s*\+\s*/ }, | ||
+ | { name: 'descendant', re: /^\s/ }, | ||
+ | |||
+ | { name: 'tagName', re: /^\s*(\*|[\w\-]+)(\b|$)?/ }, | ||
+ | { name: 'id', re: /^#([\w\-\*]+)(\b|$)/ }, | ||
+ | { name: 'className', re: /^\.([\w\-\*]+)(\b|$)/ }, | ||
+ | { name: 'pseudo', re: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/ }, | ||
+ | { name: 'attrPresence', re: /^\[((?:[\w-]+:)?[\w-]+)\]/ }, | ||
+ | { name: 'attr', re: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/ } | ||
+ | ], | ||
+ | |||
+ | assertions: { | ||
+ | tagName: function(element, matches) { | ||
+ | return matches[1].toUpperCase() == element.tagName.toUpperCase(); | ||
+ | }, | ||
+ | |||
+ | className: function(element, matches) { | ||
+ | return Element.hasClassName(element, matches[1]); | ||
+ | }, | ||
+ | |||
+ | id: function(element, matches) { | ||
+ | return element.id === matches[1]; | ||
+ | }, | ||
+ | |||
+ | attrPresence: function(element, matches) { | ||
+ | return Element.hasAttribute(element, matches[1]); | ||
+ | }, | ||
+ | |||
+ | attr: function(element, matches) { | ||
+ | var nodeValue = Element.readAttribute(element, matches[1]); | ||
+ | return nodeValue && Selector.operators[matches[2]](nodeValue, matches[5] || matches[6]); | ||
+ | } | ||
+ | }, | ||
+ | |||
+ | handlers: { | ||
+ | concat: function(a, b) { | ||
+ | for (var i = 0, node; node = b[i]; i++) | ||
+ | a.push(node); | ||
+ | return a; | ||
+ | }, | ||
+ | |||
+ | mark: function(nodes) { | ||
+ | var _true = Prototype.emptyFunction; | ||
+ | for (var i = 0, node; node = nodes[i]; i++) | ||
+ | node._countedByPrototype = _true; | ||
+ | return nodes; | ||
+ | }, | ||
+ | |||
+ | unmark: (function(){ | ||
+ | |||
+ | var PROPERTIES_ATTRIBUTES_MAP = (function(){ | ||
+ | var el = document.createElement('div'), | ||
+ | isBuggy = false, | ||
+ | propName = '_countedByPrototype', | ||
+ | value = 'x' | ||
+ | el[propName] = value; | ||
+ | isBuggy = (el.getAttribute(propName) === value); | ||
+ | el = null; | ||
+ | return isBuggy; | ||
+ | })(); | ||
+ | |||
+ | return PROPERTIES_ATTRIBUTES_MAP ? | ||
+ | function(nodes) { | ||
+ | for (var i = 0, node; node = nodes[i]; i++) | ||
+ | node.removeAttribute('_countedByPrototype'); | ||
+ | return nodes; | ||
+ | } : | ||
+ | function(nodes) { | ||
+ | for (var i = 0, node; node = nodes[i]; i++) | ||
+ | node._countedByPrototype = void 0; | ||
+ | return nodes; | ||
+ | } | ||
+ | })(), | ||
+ | |||
+ | index: function(parentNode, reverse, ofType) { | ||
+ | parentNode._countedByPrototype = Prototype.emptyFunction; | ||
+ | if (reverse) { | ||
+ | for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) { | ||
+ | var node = nodes[i]; | ||
+ | if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++; | ||
+ | } | ||
+ | } else { | ||
+ | for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++) | ||
+ | if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++; | ||
+ | } | ||
+ | }, | ||
+ | |||
+ | unique: function(nodes) { | ||
+ | if (nodes.length == 0) return nodes; | ||
+ | var results = [], n; | ||
+ | for (var i = 0, l = nodes.length; i < l; i++) | ||
+ | if (typeof (n = nodes[i])._countedByPrototype == 'undefined') { | ||
+ | n._countedByPrototype = Prototype.emptyFunction; | ||
+ | results.push(Element.extend(n)); | ||
+ | } | ||
+ | return Selector.handlers.unmark(results); | ||
+ | }, | ||
+ | |||
+ | descendant: function(nodes) { | ||
+ | var h = Selector.handlers; | ||
+ | for (var i = 0, results = [], node; node = nodes[i]; i++) | ||
+ | h.concat(results, node.getElementsByTagName('*')); | ||
+ | return results; | ||
+ | }, | ||
+ | |||
+ | child: function(nodes) { | ||
+ | var h = Selector.handlers; | ||
+ | for (var i = 0, results = [], node; node = nodes[i]; i++) { | ||
+ | for (var j = 0, child; child = node.childNodes[j]; j++) | ||
+ | if (child.nodeType == 1 && child.tagName != '!') results.push(child); | ||
+ | } | ||
+ | return results; | ||
+ | }, | ||
+ | |||
+ | adjacent: function(nodes) { | ||
+ | for (var i = 0, results = [], node; node = nodes[i]; i++) { | ||
+ | var next = this.nextElementSibling(node); | ||
+ | if (next) results.push(next); | ||
+ | } | ||
+ | return results; | ||
+ | }, | ||
+ | |||
+ | laterSibling: function(nodes) { | ||
+ | var h = Selector.handlers; | ||
+ | for (var i = 0, results = [], node; node = nodes[i]; i++) | ||
+ | h.concat(results, Element.nextSiblings(node)); | ||
+ | return results; | ||
+ | }, | ||
+ | |||
+ | nextElementSibling: function(node) { | ||
+ | while (node = node.nextSibling) | ||
+ | if (node.nodeType == 1) return node; | ||
+ | return null; | ||
+ | }, | ||
+ | |||
+ | previousElementSibling: function(node) { | ||
+ | while (node = node.previousSibling) | ||
+ | if (node.nodeType == 1) return node; | ||
+ | return null; | ||
+ | }, | ||
+ | |||
+ | tagName: function(nodes, root, tagName, combinator) { | ||
+ | var uTagName = tagName.toUpperCase(); | ||
+ | var results = [], h = Selector.handlers; | ||
+ | if (nodes) { | ||
+ | if (combinator) { | ||
+ | if (combinator == "descendant") { | ||
+ | for (var i = 0, node; node = nodes[i]; i++) | ||
+ | h.concat(results, node.getElementsByTagName(tagName)); | ||
+ | return results; | ||
+ | } else nodes = this[combinator](nodes); | ||
+ | if (tagName == "*") return nodes; | ||
+ | } | ||
+ | for (var i = 0, node; node = nodes[i]; i++) | ||
+ | if (node.tagName.toUpperCase() === uTagName) results.push(node); | ||
+ | return results; | ||
+ | } else return root.getElementsByTagName(tagName); | ||
+ | }, | ||
+ | |||
+ | id: function(nodes, root, id, combinator) { | ||
+ | var targetNode = $(id), h = Selector.handlers; | ||
+ | |||
+ | if (root == document) { | ||
+ | if (!targetNode) return []; | ||
+ | if (!nodes) return [targetNode]; | ||
+ | } else { | ||
+ | if (!root.sourceIndex || root.sourceIndex < 1) { | ||
+ | var nodes = root.getElementsByTagName('*'); | ||
+ | for (var j = 0, node; node = nodes[j]; j++) { | ||
+ | if (node.id === id) return [node]; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | if (nodes) { | ||
+ | if (combinator) { | ||
+ | if (combinator == 'child') { | ||
+ | for (var i = 0, node; node = nodes[i]; i++) | ||
+ | if (targetNode.parentNode == node) return [targetNode]; | ||
+ | } else if (combinator == 'descendant') { | ||
+ | for (var i = 0, node; node = nodes[i]; i++) | ||
+ | if (Element.descendantOf(targetNode, node)) return [targetNode]; | ||
+ | } else if (combinator == 'adjacent') { | ||
+ | for (var i = 0, node; node = nodes[i]; i++) | ||
+ | if (Selector.handlers.previousElementSibling(targetNode) == node) | ||
+ | return [targetNode]; | ||
+ | } else nodes = h[combinator](nodes); | ||
+ | } | ||
+ | for (var i = 0, node; node = nodes[i]; i++) | ||
+ | if (node == targetNode) return [targetNode]; | ||
+ | return []; | ||
+ | } | ||
+ | return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : []; | ||
+ | }, | ||
+ | |||
+ | className: function(nodes, root, className, combinator) { | ||
+ | if (nodes && combinator) nodes = this[combinator](nodes); | ||
+ | return Selector.handlers.byClassName(nodes, root, className); | ||
+ | }, | ||
+ | |||
+ | byClassName: function(nodes, root, className) { | ||
+ | if (!nodes) nodes = Selector.handlers.descendant([root]); | ||
+ | var needle = ' ' + className + ' '; | ||
+ | for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) { | ||
+ | nodeClassName = node.className; | ||
+ | if (nodeClassName.length == 0) continue; | ||
+ | if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle)) | ||
+ | results.push(node); | ||
+ | } | ||
+ | return results; | ||
+ | }, | ||
+ | |||
+ | attrPresence: function(nodes, root, attr, combinator) { | ||
+ | if (!nodes) nodes = root.getElementsByTagName("*"); | ||
+ | if (nodes && combinator) nodes = this[combinator](nodes); | ||
+ | var results = []; | ||
+ | for (var i = 0, node; node = nodes[i]; i++) | ||
+ | if (Element.hasAttribute(node, attr)) results.push(node); | ||
+ | return results; | ||
+ | }, | ||
+ | |||
+ | attr: function(nodes, root, attr, value, operator, combinator) { | ||
+ | if (!nodes) nodes = root.getElementsByTagName("*"); | ||
+ | if (nodes && combinator) nodes = this[combinator](nodes); | ||
+ | var handler = Selector.operators[operator], results = []; | ||
+ | for (var i = 0, node; node = nodes[i]; i++) { | ||
+ | var nodeValue = Element.readAttribute(node, attr); | ||
+ | if (nodeValue === null) continue; | ||
+ | if (handler(nodeValue, value)) results.push(node); | ||
+ | } | ||
+ | return results; | ||
+ | }, | ||
+ | |||
+ | pseudo: function(nodes, name, value, root, combinator) { | ||
+ | if (nodes && combinator) nodes = this[combinator](nodes); | ||
+ | if (!nodes) nodes = root.getElementsByTagName("*"); | ||
+ | return Selector.pseudos[name](nodes, value, root); | ||
+ | } | ||
+ | }, | ||
+ | |||
+ | pseudos: { | ||
+ | 'first-child': function(nodes, value, root) { | ||
+ | for (var i = 0, results = [], node; node = nodes[i]; i++) { | ||
+ | if (Selector.handlers.previousElementSibling(node)) continue; | ||
+ | results.push(node); | ||
+ | } | ||
+ | return results; | ||
+ | }, | ||
+ | 'last-child': function(nodes, value, root) { | ||
+ | for (var i = 0, results = [], node; node = nodes[i]; i++) { | ||
+ | if (Selector.handlers.nextElementSibling(node)) continue; | ||
+ | results.push(node); | ||
+ | } | ||
+ | return results; | ||
+ | }, | ||
+ | 'only-child': function(nodes, value, root) { | ||
+ | var h = Selector.handlers; | ||
+ | for (var i = 0, results = [], node; node = nodes[i]; i++) | ||
+ | if (!h.previousElementSibling(node) && !h.nextElementSibling(node)) | ||
+ | results.push(node); | ||
+ | return results; | ||
+ | }, | ||
+ | 'nth-child': function(nodes, formula, root) { | ||
+ | return Selector.pseudos.nth(nodes, formula, root); | ||
+ | }, | ||
+ | 'nth-last-child': function(nodes, formula, root) { | ||
+ | return Selector.pseudos.nth(nodes, formula, root, true); | ||
+ | }, | ||
+ | 'nth-of-type': function(nodes, formula, root) { | ||
+ | return Selector.pseudos.nth(nodes, formula, root, false, true); | ||
+ | }, | ||
+ | 'nth-last-of-type': function(nodes, formula, root) { | ||
+ | return Selector.pseudos.nth(nodes, formula, root, true, true); | ||
+ | }, | ||
+ | 'first-of-type': function(nodes, formula, root) { | ||
+ | return Selector.pseudos.nth(nodes, "1", root, false, true); | ||
+ | }, | ||
+ | 'last-of-type': function(nodes, formula, root) { | ||
+ | return Selector.pseudos.nth(nodes, "1", root, true, true); | ||
+ | }, | ||
+ | 'only-of-type': function(nodes, formula, root) { | ||
+ | var p = Selector.pseudos; | ||
+ | return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root); | ||
+ | }, | ||
+ | |||
+ | getIndices: function(a, b, total) { | ||
+ | if (a == 0) return b > 0 ? [b] : []; | ||
+ | return $R(1, total).inject([], function(memo, i) { | ||
+ | if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i); | ||
+ | return memo; | ||
+ | }); | ||
+ | }, | ||
+ | |||
+ | nth: function(nodes, formula, root, reverse, ofType) { | ||
+ | if (nodes.length == 0) return []; | ||
+ | if (formula == 'even') formula = '2n+0'; | ||
+ | if (formula == 'odd') formula = '2n+1'; | ||
+ | var h = Selector.handlers, results = [], indexed = [], m; | ||
+ | h.mark(nodes); | ||
+ | for (var i = 0, node; node = nodes[i]; i++) { | ||
+ | if (!node.parentNode._countedByPrototype) { | ||
+ | h.index(node.parentNode, reverse, ofType); | ||
+ | indexed.push(node.parentNode); | ||
+ | } | ||
+ | } | ||
+ | if (formula.match(/^\d+$/)) { // just a number | ||
+ | formula = Number(formula); | ||
+ | for (var i = 0, node; node = nodes[i]; i++) | ||
+ | if (node.nodeIndex == formula) results.push(node); | ||
+ | } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b | ||
+ | if (m[1] == "-") m[1] = -1; | ||
+ | var a = m[1] ? Number(m[1]) : 1; | ||
+ | var b = m[2] ? Number(m[2]) : 0; | ||
+ | var indices = Selector.pseudos.getIndices(a, b, nodes.length); | ||
+ | for (var i = 0, node, l = indices.length; node = nodes[i]; i++) { | ||
+ | for (var j = 0; j < l; j++) | ||
+ | if (node.nodeIndex == indices[j]) results.push(node); | ||
+ | } | ||
+ | } | ||
+ | h.unmark(nodes); | ||
+ | h.unmark(indexed); | ||
+ | return results; | ||
+ | }, | ||
+ | |||
+ | 'empty': function(nodes, value, root) { | ||
+ | for (var i = 0, results = [], node; node = nodes[i]; i++) { | ||
+ | if (node.tagName == '!' || node.firstChild) continue; | ||
+ | results.push(node); | ||
+ | } | ||
+ | return results; | ||
+ | }, | ||
+ | |||
+ | 'not': function(nodes, selector, root) { | ||
+ | var h = Selector.handlers, selectorType, m; | ||
+ | var exclusions = new Selector(selector).findElements(root); | ||
+ | h.mark(exclusions); | ||
+ | for (var i = 0, results = [], node; node = nodes[i]; i++) | ||
+ | if (!node._countedByPrototype) results.push(node); | ||
+ | h.unmark(exclusions); | ||
+ | return results; | ||
+ | }, | ||
+ | |||
+ | 'enabled': function(nodes, value, root) { | ||
+ | for (var i = 0, results = [], node; node = nodes[i]; i++) | ||
+ | if (!node.disabled && (!node.type || node.type !== 'hidden')) | ||
+ | results.push(node); | ||
+ | return results; | ||
+ | }, | ||
+ | |||
+ | 'disabled': function(nodes, value, root) { | ||
+ | for (var i = 0, results = [], node; node = nodes[i]; i++) | ||
+ | if (node.disabled) results.push(node); | ||
+ | return results; | ||
+ | }, | ||
+ | |||
+ | 'checked': function(nodes, value, root) { | ||
+ | for (var i = 0, results = [], node; node = nodes[i]; i++) | ||
+ | if (node.checked) results.push(node); | ||
+ | return results; | ||
+ | } | ||
+ | }, | ||
+ | |||
+ | operators: { | ||
+ | '=': function(nv, v) { return nv == v; }, | ||
+ | '!=': function(nv, v) { return nv != v; }, | ||
+ | '^=': function(nv, v) { return nv == v || nv && nv.startsWith(v); }, | ||
+ | '$=': function(nv, v) { return nv == v || nv && nv.endsWith(v); }, | ||
+ | '*=': function(nv, v) { return nv == v || nv && nv.include(v); }, | ||
+ | '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); }, | ||
+ | '|=': function(nv, v) { return ('-' + (nv || "").toUpperCase() + | ||
+ | '-').include('-' + (v || "").toUpperCase() + '-'); } | ||
+ | }, | ||
+ | |||
+ | split: function(expression) { | ||
+ | var expressions = []; | ||
+ | expression.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) { | ||
+ | expressions.push(m[1].strip()); | ||
+ | }); | ||
+ | return expressions; | ||
+ | }, | ||
+ | |||
+ | matchElements: function(elements, expression) { | ||
+ | var matches = $$(expression), h = Selector.handlers; | ||
+ | h.mark(matches); | ||
+ | for (var i = 0, results = [], element; element = elements[i]; i++) | ||
+ | if (element._countedByPrototype) results.push(element); | ||
+ | h.unmark(matches); | ||
+ | return results; | ||
+ | }, | ||
+ | |||
+ | findElement: function(elements, expression, index) { | ||
+ | if (Object.isNumber(expression)) { | ||
+ | index = expression; expression = false; | ||
+ | } | ||
+ | return Selector.matchElements(elements, expression || '*')[index || 0]; | ||
+ | }, | ||
+ | |||
+ | findChildElements: function(element, expressions) { | ||
+ | expressions = Selector.split(expressions.join(',')); | ||
+ | var results = [], h = Selector.handlers; | ||
+ | for (var i = 0, l = expressions.length, selector; i < l; i++) { | ||
+ | selector = new Selector(expressions[i].strip()); | ||
+ | h.concat(results, selector.findElements(element)); | ||
+ | } | ||
+ | return (l > 1) ? h.unique(results) : results; | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | if (Prototype.Browser.IE) { | ||
+ | Object.extend(Selector.handlers, { | ||
+ | concat: function(a, b) { | ||
+ | for (var i = 0, node; node = b[i]; i++) | ||
+ | if (node.tagName !== "!") a.push(node); | ||
+ | return a; | ||
+ | } | ||
+ | }); | ||
} | } | ||
+ | function $$() { | ||
+ | return Selector.findChildElements(document, $A(arguments)); | ||
+ | } | ||
+ | var Form = { | ||
+ | reset: function(form) { | ||
+ | form = $(form); | ||
+ | form.reset(); | ||
+ | return form; | ||
+ | }, | ||
- | + | serializeElements: function(elements, options) { | |
+ | if (typeof options != 'object') options = { hash: !!options }; | ||
+ | else if (Object.isUndefined(options.hash)) options.hash = true; | ||
+ | var key, value, submitted = false, submit = options.submit; | ||
+ | |||
+ | var data = elements.inject({ }, function(result, element) { | ||
+ | if (!element.disabled && element.name) { | ||
+ | key = element.name; value = $(element).getValue(); | ||
+ | if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted && | ||
+ | submit !== false && (!submit || key == submit) && (submitted = true)))) { | ||
+ | if (key in result) { | ||
+ | if (!Object.isArray(result[key])) result[key] = [result[key]]; | ||
+ | result[key].push(value); | ||
+ | } | ||
+ | else result[key] = value; | ||
+ | } | ||
+ | } | ||
+ | return result; | ||
+ | }); | ||
+ | |||
+ | return options.hash ? data : Object.toQueryString(data); | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | Form.Methods = { | ||
+ | serialize: function(form, options) { | ||
+ | return Form.serializeElements(Form.getElements(form), options); | ||
+ | }, | ||
+ | |||
+ | getElements: function(form) { | ||
+ | var elements = $(form).getElementsByTagName('*'), | ||
+ | element, | ||
+ | arr = [ ], | ||
+ | serializers = Form.Element.Serializers; | ||
+ | for (var i = 0; element = elements[i]; i++) { | ||
+ | arr.push(element); | ||
+ | } | ||
+ | return arr.inject([], function(elements, child) { | ||
+ | if (serializers[child.tagName.toLowerCase()]) | ||
+ | elements.push(Element.extend(child)); | ||
+ | return elements; | ||
+ | }) | ||
+ | }, | ||
+ | |||
+ | getInputs: function(form, typeName, name) { | ||
+ | form = $(form); | ||
+ | var inputs = form.getElementsByTagName('input'); | ||
+ | |||
+ | if (!typeName && !name) return $A(inputs).map(Element.extend); | ||
+ | |||
+ | for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) { | ||
+ | var input = inputs[i]; | ||
+ | if ((typeName && input.type != typeName) || (name && input.name != name)) | ||
+ | continue; | ||
+ | matchingInputs.push(Element.extend(input)); | ||
+ | } | ||
+ | |||
+ | return matchingInputs; | ||
+ | }, | ||
+ | |||
+ | disable: function(form) { | ||
+ | form = $(form); | ||
+ | Form.getElements(form).invoke('disable'); | ||
+ | return form; | ||
+ | }, | ||
+ | |||
+ | enable: function(form) { | ||
+ | form = $(form); | ||
+ | Form.getElements(form).invoke('enable'); | ||
+ | return form; | ||
+ | }, | ||
+ | |||
+ | findFirstElement: function(form) { | ||
+ | var elements = $(form).getElements().findAll(function(element) { | ||
+ | return 'hidden' != element.type && !element.disabled; | ||
+ | }); | ||
+ | var firstByIndex = elements.findAll(function(element) { | ||
+ | return element.hasAttribute('tabIndex') && element.tabIndex >= 0; | ||
+ | }).sortBy(function(element) { return element.tabIndex }).first(); | ||
+ | |||
+ | return firstByIndex ? firstByIndex : elements.find(function(element) { | ||
+ | return /^(?:input|select|textarea)$/i.test(element.tagName); | ||
+ | }); | ||
+ | }, | ||
+ | |||
+ | focusFirstElement: function(form) { | ||
+ | form = $(form); | ||
+ | form.findFirstElement().activate(); | ||
+ | return form; | ||
+ | }, | ||
+ | |||
+ | request: function(form, options) { | ||
+ | form = $(form), options = Object.clone(options || { }); | ||
+ | |||
+ | var params = options.parameters, action = form.readAttribute('action') || ''; | ||
+ | if (action.blank()) action = window.location.href; | ||
+ | options.parameters = form.serialize(true); | ||
+ | |||
+ | if (params) { | ||
+ | if (Object.isString(params)) params = params.toQueryParams(); | ||
+ | Object.extend(options.parameters, params); | ||
+ | } | ||
+ | |||
+ | if (form.hasAttribute('method') && !options.method) | ||
+ | options.method = form.method; | ||
+ | |||
+ | return new Ajax.Request(action, options); | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | /*--------------------------------------------------------------------------*/ | ||
+ | |||
+ | |||
+ | Form.Element = { | ||
+ | focus: function(element) { | ||
+ | $(element).focus(); | ||
+ | return element; | ||
+ | }, | ||
+ | |||
+ | select: function(element) { | ||
+ | $(element).select(); | ||
+ | return element; | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | Form.Element.Methods = { | ||
+ | |||
+ | serialize: function(element) { | ||
+ | element = $(element); | ||
+ | if (!element.disabled && element.name) { | ||
+ | var value = element.getValue(); | ||
+ | if (value != undefined) { | ||
+ | var pair = { }; | ||
+ | pair[element.name] = value; | ||
+ | return Object.toQueryString(pair); | ||
+ | } | ||
+ | } | ||
+ | return ''; | ||
+ | }, | ||
+ | |||
+ | getValue: function(element) { | ||
+ | element = $(element); | ||
+ | var method = element.tagName.toLowerCase(); | ||
+ | return Form.Element.Serializers[method](element); | ||
+ | }, | ||
+ | |||
+ | setValue: function(element, value) { | ||
+ | element = $(element); | ||
+ | var method = element.tagName.toLowerCase(); | ||
+ | Form.Element.Serializers[method](element, value); | ||
+ | return element; | ||
+ | }, | ||
+ | |||
+ | clear: function(element) { | ||
+ | $(element).value = ''; | ||
+ | return element; | ||
+ | }, | ||
+ | |||
+ | present: function(element) { | ||
+ | return $(element).value != ''; | ||
+ | }, | ||
+ | |||
+ | activate: function(element) { | ||
+ | element = $(element); | ||
+ | try { | ||
+ | element.focus(); | ||
+ | if (element.select && (element.tagName.toLowerCase() != 'input' || | ||
+ | !(/^(?:button|reset|submit)$/i.test(element.type)))) | ||
+ | element.select(); | ||
+ | } catch (e) { } | ||
+ | return element; | ||
+ | }, | ||
+ | |||
+ | disable: function(element) { | ||
+ | element = $(element); | ||
+ | element.disabled = true; | ||
+ | return element; | ||
+ | }, | ||
+ | |||
+ | enable: function(element) { | ||
+ | element = $(element); | ||
+ | element.disabled = false; | ||
+ | return element; | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | /*--------------------------------------------------------------------------*/ | ||
+ | |||
+ | var Field = Form.Element; | ||
+ | |||
+ | var $F = Form.Element.Methods.getValue; | ||
+ | |||
+ | /*--------------------------------------------------------------------------*/ | ||
+ | |||
+ | Form.Element.Serializers = { | ||
+ | input: function(element, value) { | ||
+ | switch (element.type.toLowerCase()) { | ||
+ | case 'checkbox': | ||
+ | case 'radio': | ||
+ | return Form.Element.Serializers.inputSelector(element, value); | ||
+ | default: | ||
+ | return Form.Element.Serializers.textarea(element, value); | ||
+ | } | ||
+ | }, | ||
+ | |||
+ | inputSelector: function(element, value) { | ||
+ | if (Object.isUndefined(value)) return element.checked ? element.value : null; | ||
+ | else element.checked = !!value; | ||
+ | }, | ||
+ | |||
+ | textarea: function(element, value) { | ||
+ | if (Object.isUndefined(value)) return element.value; | ||
+ | else element.value = value; | ||
+ | }, | ||
+ | |||
+ | select: function(element, value) { | ||
+ | if (Object.isUndefined(value)) | ||
+ | return this[element.type == 'select-one' ? | ||
+ | 'selectOne' : 'selectMany'](element); | ||
+ | else { | ||
+ | var opt, currentValue, single = !Object.isArray(value); | ||
+ | for (var i = 0, length = element.length; i < length; i++) { | ||
+ | opt = element.options[i]; | ||
+ | currentValue = this.optionValue(opt); | ||
+ | if (single) { | ||
+ | if (currentValue == value) { | ||
+ | opt.selected = true; | ||
+ | return; | ||
+ | } | ||
+ | } | ||
+ | else opt.selected = value.include(currentValue); | ||
+ | } | ||
+ | } | ||
+ | }, | ||
+ | |||
+ | selectOne: function(element) { | ||
+ | var index = element.selectedIndex; | ||
+ | return index >= 0 ? this.optionValue(element.options[index]) : null; | ||
+ | }, | ||
+ | |||
+ | selectMany: function(element) { | ||
+ | var values, length = element.length; | ||
+ | if (!length) return null; | ||
+ | |||
+ | for (var i = 0, values = []; i < length; i++) { | ||
+ | var opt = element.options[i]; | ||
+ | if (opt.selected) values.push(this.optionValue(opt)); | ||
+ | } | ||
+ | return values; | ||
+ | }, | ||
+ | |||
+ | optionValue: function(opt) { | ||
+ | return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text; | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | /*--------------------------------------------------------------------------*/ | ||
+ | |||
+ | |||
+ | Abstract.TimedObserver = Class.create(PeriodicalExecuter, { | ||
+ | initialize: function($super, element, frequency, callback) { | ||
+ | $super(callback, frequency); | ||
+ | this.element = $(element); | ||
+ | this.lastValue = this.getValue(); | ||
+ | }, | ||
+ | |||
+ | execute: function() { | ||
+ | var value = this.getValue(); | ||
+ | if (Object.isString(this.lastValue) && Object.isString(value) ? | ||
+ | this.lastValue != value : String(this.lastValue) != String(value)) { | ||
+ | this.callback(this.element, value); | ||
+ | this.lastValue = value; | ||
+ | } | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | Form.Element.Observer = Class.create(Abstract.TimedObserver, { | ||
+ | getValue: function() { | ||
+ | return Form.Element.getValue(this.element); | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | Form.Observer = Class.create(Abstract.TimedObserver, { | ||
+ | getValue: function() { | ||
+ | return Form.serialize(this.element); | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | /*--------------------------------------------------------------------------*/ | ||
+ | |||
+ | Abstract.EventObserver = Class.create({ | ||
+ | initialize: function(element, callback) { | ||
+ | this.element = $(element); | ||
+ | this.callback = callback; | ||
+ | |||
+ | this.lastValue = this.getValue(); | ||
+ | if (this.element.tagName.toLowerCase() == 'form') | ||
+ | this.registerFormCallbacks(); | ||
+ | else | ||
+ | this.registerCallback(this.element); | ||
+ | }, | ||
+ | |||
+ | onElementEvent: function() { | ||
+ | var value = this.getValue(); | ||
+ | if (this.lastValue != value) { | ||
+ | this.callback(this.element, value); | ||
+ | this.lastValue = value; | ||
+ | } | ||
+ | }, | ||
+ | |||
+ | registerFormCallbacks: function() { | ||
+ | Form.getElements(this.element).each(this.registerCallback, this); | ||
+ | }, | ||
+ | |||
+ | registerCallback: function(element) { | ||
+ | if (element.type) { | ||
+ | switch (element.type.toLowerCase()) { | ||
+ | case 'checkbox': | ||
+ | case 'radio': | ||
+ | Event.observe(element, 'click', this.onElementEvent.bind(this)); | ||
+ | break; | ||
+ | default: | ||
+ | Event.observe(element, 'change', this.onElementEvent.bind(this)); | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | Form.Element.EventObserver = Class.create(Abstract.EventObserver, { | ||
+ | getValue: function() { | ||
+ | return Form.Element.getValue(this.element); | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | Form.EventObserver = Class.create(Abstract.EventObserver, { | ||
+ | getValue: function() { | ||
+ | return Form.serialize(this.element); | ||
+ | } | ||
+ | }); | ||
+ | (function() { | ||
+ | |||
+ | 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, | ||
+ | KEY_HOME: 36, | ||
+ | KEY_END: 35, | ||
+ | KEY_PAGEUP: 33, | ||
+ | KEY_PAGEDOWN: 34, | ||
+ | KEY_INSERT: 45, | ||
+ | |||
+ | cache: {} | ||
+ | }; | ||
+ | |||
+ | var docEl = document.documentElement; | ||
+ | var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl | ||
+ | && 'onmouseleave' in docEl; | ||
+ | |||
+ | var _isButton; | ||
+ | if (Prototype.Browser.IE) { | ||
+ | var buttonMap = { 0: 1, 1: 4, 2: 2 }; | ||
+ | _isButton = function(event, code) { | ||
+ | return event.button === buttonMap[code]; | ||
+ | }; | ||
+ | } else if (Prototype.Browser.WebKit) { | ||
+ | _isButton = function(event, code) { | ||
+ | switch (code) { | ||
+ | case 0: return event.which == 1 && !event.metaKey; | ||
+ | case 1: return event.which == 1 && event.metaKey; | ||
+ | default: return false; | ||
+ | } | ||
+ | }; | ||
+ | } else { | ||
+ | _isButton = function(event, code) { | ||
+ | return event.which ? (event.which === code + 1) : (event.button === code); | ||
+ | }; | ||
+ | } | ||
+ | |||
+ | function isLeftClick(event) { return _isButton(event, 0) } | ||
+ | |||
+ | function isMiddleClick(event) { return _isButton(event, 1) } | ||
+ | |||
+ | function isRightClick(event) { return _isButton(event, 2) } | ||
+ | |||
+ | function element(event) { | ||
+ | event = Event.extend(event); | ||
+ | |||
+ | var node = event.target, type = event.type, | ||
+ | currentTarget = event.currentTarget; | ||
+ | |||
+ | if (currentTarget && currentTarget.tagName) { | ||
+ | if (type === 'load' || type === 'error' || | ||
+ | (type === 'click' && currentTarget.tagName.toLowerCase() === 'input' | ||
+ | && currentTarget.type === 'radio')) | ||
+ | node = currentTarget; | ||
+ | } | ||
+ | |||
+ | if (node.nodeType == Node.TEXT_NODE) | ||
+ | node = node.parentNode; | ||
+ | |||
+ | return Element.extend(node); | ||
+ | } | ||
+ | |||
+ | function findElement(event, expression) { | ||
+ | var element = Event.element(event); | ||
+ | if (!expression) return element; | ||
+ | var elements = [element].concat(element.ancestors()); | ||
+ | return Selector.findElement(elements, expression, 0); | ||
+ | } | ||
+ | |||
+ | function pointer(event) { | ||
+ | return { x: pointerX(event), y: pointerY(event) }; | ||
+ | } | ||
+ | |||
+ | function pointerX(event) { | ||
+ | var docElement = document.documentElement, | ||
+ | body = document.body || { scrollLeft: 0 }; | ||
+ | |||
+ | return event.pageX || (event.clientX + | ||
+ | (docElement.scrollLeft || body.scrollLeft) - | ||
+ | (docElement.clientLeft || 0)); | ||
+ | } | ||
+ | |||
+ | function pointerY(event) { | ||
+ | var docElement = document.documentElement, | ||
+ | body = document.body || { scrollTop: 0 }; | ||
+ | |||
+ | return event.pageY || (event.clientY + | ||
+ | (docElement.scrollTop || body.scrollTop) - | ||
+ | (docElement.clientTop || 0)); | ||
+ | } | ||
+ | |||
+ | |||
+ | function stop(event) { | ||
+ | Event.extend(event); | ||
+ | event.preventDefault(); | ||
+ | event.stopPropagation(); | ||
+ | |||
+ | event.stopped = true; | ||
+ | } | ||
+ | |||
+ | Event.Methods = { | ||
+ | isLeftClick: isLeftClick, | ||
+ | isMiddleClick: isMiddleClick, | ||
+ | isRightClick: isRightClick, | ||
+ | |||
+ | element: element, | ||
+ | findElement: findElement, | ||
+ | |||
+ | pointer: pointer, | ||
+ | pointerX: pointerX, | ||
+ | pointerY: pointerY, | ||
+ | |||
+ | stop: stop | ||
+ | }; | ||
+ | |||
+ | |||
+ | var methods = Object.keys(Event.Methods).inject({ }, function(m, name) { | ||
+ | m[name] = Event.Methods[name].methodize(); | ||
+ | return m; | ||
+ | }); | ||
+ | |||
+ | if (Prototype.Browser.IE) { | ||
+ | function _relatedTarget(event) { | ||
+ | var element; | ||
+ | switch (event.type) { | ||
+ | case 'mouseover': element = event.fromElement; break; | ||
+ | case 'mouseout': element = event.toElement; break; | ||
+ | default: return null; | ||
+ | } | ||
+ | return Element.extend(element); | ||
+ | } | ||
+ | |||
+ | Object.extend(methods, { | ||
+ | stopPropagation: function() { this.cancelBubble = true }, | ||
+ | preventDefault: function() { this.returnValue = false }, | ||
+ | inspect: function() { return '[object Event]' } | ||
+ | }); | ||
+ | |||
+ | Event.extend = function(event, element) { | ||
+ | if (!event) return false; | ||
+ | if (event._extendedByPrototype) return event; | ||
+ | |||
+ | event._extendedByPrototype = Prototype.emptyFunction; | ||
+ | var pointer = Event.pointer(event); | ||
+ | |||
+ | Object.extend(event, { | ||
+ | target: event.srcElement || element, | ||
+ | relatedTarget: _relatedTarget(event), | ||
+ | pageX: pointer.x, | ||
+ | pageY: pointer.y | ||
+ | }); | ||
+ | |||
+ | return Object.extend(event, methods); | ||
+ | }; | ||
+ | } else { | ||
+ | Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__; | ||
+ | Object.extend(Event.prototype, methods); | ||
+ | Event.extend = Prototype.K; | ||
+ | } | ||
+ | |||
+ | function _createResponder(element, eventName, handler) { | ||
+ | var registry = Element.retrieve(element, 'prototype_event_registry'); | ||
+ | |||
+ | if (Object.isUndefined(registry)) { | ||
+ | CACHE.push(element); | ||
+ | registry = Element.retrieve(element, 'prototype_event_registry', $H()); | ||
+ | } | ||
+ | |||
+ | var respondersForEvent = registry.get(eventName); | ||
+ | if (Object.isUndefined(respondersForEvent)) { | ||
+ | respondersForEvent = []; | ||
+ | registry.set(eventName, respondersForEvent); | ||
+ | } | ||
+ | |||
+ | if (respondersForEvent.pluck('handler').include(handler)) return false; | ||
+ | |||
+ | var responder; | ||
+ | if (eventName.include(":")) { | ||
+ | responder = function(event) { | ||
+ | if (Object.isUndefined(event.eventName)) | ||
+ | return false; | ||
+ | |||
+ | if (event.eventName !== eventName) | ||
+ | return false; | ||
+ | |||
+ | Event.extend(event, element); | ||
+ | handler.call(element, event); | ||
+ | }; | ||
+ | } else { | ||
+ | if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED && | ||
+ | (eventName === "mouseenter" || eventName === "mouseleave")) { | ||
+ | if (eventName === "mouseenter" || eventName === "mouseleave") { | ||
+ | responder = function(event) { | ||
+ | Event.extend(event, element); | ||
+ | |||
+ | var parent = event.relatedTarget; | ||
+ | while (parent && parent !== element) { | ||
+ | try { parent = parent.parentNode; } | ||
+ | catch(e) { parent = element; } | ||
+ | } | ||
+ | |||
+ | if (parent === element) return; | ||
+ | |||
+ | handler.call(element, event); | ||
+ | }; | ||
+ | } | ||
+ | } else { | ||
+ | responder = function(event) { | ||
+ | Event.extend(event, element); | ||
+ | handler.call(element, event); | ||
+ | }; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | responder.handler = handler; | ||
+ | respondersForEvent.push(responder); | ||
+ | return responder; | ||
+ | } | ||
+ | |||
+ | function _destroyCache() { | ||
+ | for (var i = 0, length = CACHE.length; i < length; i++) { | ||
+ | Event.stopObserving(CACHE[i]); | ||
+ | CACHE[i] = null; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | var CACHE = []; | ||
+ | |||
+ | if (Prototype.Browser.IE) | ||
+ | window.attachEvent('onunload', _destroyCache); | ||
+ | |||
+ | if (Prototype.Browser.WebKit) | ||
+ | window.addEventListener('unload', Prototype.emptyFunction, false); | ||
+ | |||
+ | |||
+ | var _getDOMEventName = Prototype.K; | ||
+ | |||
+ | if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) { | ||
+ | _getDOMEventName = function(eventName) { | ||
+ | var translations = { mouseenter: "mouseover", mouseleave: "mouseout" }; | ||
+ | return eventName in translations ? translations[eventName] : eventName; | ||
+ | }; | ||
+ | } | ||
+ | |||
+ | function observe(element, eventName, handler) { | ||
+ | element = $(element); | ||
+ | |||
+ | var responder = _createResponder(element, eventName, handler); | ||
+ | |||
+ | if (!responder) return element; | ||
+ | |||
+ | if (eventName.include(':')) { | ||
+ | if (element.addEventListener) | ||
+ | element.addEventListener("dataavailable", responder, false); | ||
+ | else { | ||
+ | element.attachEvent("ondataavailable", responder); | ||
+ | element.attachEvent("onfilterchange", responder); | ||
+ | } | ||
+ | } else { | ||
+ | var actualEventName = _getDOMEventName(eventName); | ||
+ | |||
+ | if (element.addEventListener) | ||
+ | element.addEventListener(actualEventName, responder, false); | ||
+ | else | ||
+ | element.attachEvent("on" + actualEventName, responder); | ||
+ | } | ||
+ | |||
+ | return element; | ||
+ | } | ||
+ | |||
+ | function stopObserving(element, eventName, handler) { | ||
+ | element = $(element); | ||
+ | |||
+ | var registry = Element.retrieve(element, 'prototype_event_registry'); | ||
+ | |||
+ | if (Object.isUndefined(registry)) return element; | ||
+ | |||
+ | if (eventName && !handler) { | ||
+ | var responders = registry.get(eventName); | ||
+ | |||
+ | if (Object.isUndefined(responders)) return element; | ||
+ | |||
+ | responders.each( function(r) { | ||
+ | Element.stopObserving(element, eventName, r.handler); | ||
+ | }); | ||
+ | return element; | ||
+ | } else if (!eventName) { | ||
+ | registry.each( function(pair) { | ||
+ | var eventName = pair.key, responders = pair.value; | ||
+ | |||
+ | responders.each( function(r) { | ||
+ | Element.stopObserving(element, eventName, r.handler); | ||
+ | }); | ||
+ | }); | ||
+ | return element; | ||
+ | } | ||
+ | |||
+ | var responders = registry.get(eventName); | ||
+ | |||
+ | if (!responders) return; | ||
+ | |||
+ | var responder = responders.find( function(r) { return r.handler === handler; }); | ||
+ | if (!responder) return element; | ||
+ | |||
+ | var actualEventName = _getDOMEventName(eventName); | ||
+ | |||
+ | if (eventName.include(':')) { | ||
+ | if (element.removeEventListener) | ||
+ | element.removeEventListener("dataavailable", responder, false); | ||
+ | else { | ||
+ | element.detachEvent("ondataavailable", responder); | ||
+ | element.detachEvent("onfilterchange", responder); | ||
+ | } | ||
+ | } else { | ||
+ | if (element.removeEventListener) | ||
+ | element.removeEventListener(actualEventName, responder, false); | ||
+ | else | ||
+ | element.detachEvent('on' + actualEventName, responder); | ||
+ | } | ||
+ | |||
+ | registry.set(eventName, responders.without(responder)); | ||
+ | |||
+ | return element; | ||
+ | } | ||
+ | |||
+ | function fire(element, eventName, memo, bubble) { | ||
+ | element = $(element); | ||
+ | |||
+ | if (Object.isUndefined(bubble)) | ||
+ | bubble = true; | ||
+ | |||
+ | 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 = bubble ? 'ondataavailable' : 'onfilterchange'; | ||
+ | } | ||
+ | |||
+ | 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); | ||
+ | |||
+ | Object.extend(Event, { | ||
+ | fire: fire, | ||
+ | observe: observe, | ||
+ | stopObserving: stopObserving | ||
+ | }); | ||
+ | |||
+ | Element.addMethods({ | ||
+ | fire: fire, | ||
+ | |||
+ | observe: observe, | ||
+ | |||
+ | stopObserving: stopObserving | ||
+ | }); | ||
+ | |||
+ | Object.extend(document, { | ||
+ | fire: fire.methodize(), | ||
+ | |||
+ | observe: observe.methodize(), | ||
+ | |||
+ | stopObserving: stopObserving.methodize(), | ||
+ | |||
+ | loaded: false | ||
+ | }); | ||
+ | |||
+ | if (window.Event) Object.extend(window.Event, Event); | ||
+ | else window.Event = Event; | ||
+ | })(); | ||
+ | |||
+ | (function() { | ||
+ | /* Support for the DOMContentLoaded event is based on work by Dan Webb, | ||
+ | Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */ | ||
+ | |||
+ | var timer; | ||
+ | |||
+ | function fireContentLoadedEvent() { | ||
+ | if (document.loaded) return; | ||
+ | if (timer) window.clearTimeout(timer); | ||
+ | document.loaded = true; | ||
+ | document.fire('dom:loaded'); | ||
+ | } | ||
+ | |||
+ | function checkReadyState() { | ||
+ | if (document.readyState === 'complete') { | ||
+ | document.stopObserving('readystatechange', checkReadyState); | ||
+ | fireContentLoadedEvent(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | function pollDoScroll() { | ||
+ | try { document.documentElement.doScroll('left'); } | ||
+ | catch(e) { | ||
+ | timer = pollDoScroll.defer(); | ||
+ | return; | ||
+ | } | ||
+ | fireContentLoadedEvent(); | ||
+ | } | ||
+ | |||
+ | if (document.addEventListener) { | ||
+ | document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false); | ||
+ | } else { | ||
+ | document.observe('readystatechange', checkReadyState); | ||
+ | if (window == top) | ||
+ | timer = pollDoScroll.defer(); | ||
+ | } | ||
+ | |||
+ | Event.observe(window, 'load', fireContentLoadedEvent); | ||
+ | })(); | ||
+ | |||
+ | Element.addMethods(); | ||
+ | |||
+ | /*------------------------------- DEPRECATED -------------------------------*/ | ||
+ | |||
+ | Hash.toQueryString = Object.toQueryString; | ||
+ | |||
+ | var Toggle = { display: Element.toggle }; | ||
+ | |||
+ | Element.Methods.childOf = Element.Methods.descendantOf; | ||
+ | |||
+ | var Insertion = { | ||
+ | Before: function(element, content) { | ||
+ | return Element.insert(element, {before:content}); | ||
+ | }, | ||
+ | |||
+ | Top: function(element, content) { | ||
+ | return Element.insert(element, {top:content}); | ||
+ | }, | ||
+ | |||
+ | Bottom: function(element, content) { | ||
+ | return Element.insert(element, {bottom:content}); | ||
+ | }, | ||
+ | |||
+ | After: function(element, content) { | ||
+ | return Element.insert(element, {after:content}); | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | var $continue = new Error('"throw $continue" is deprecated, use "return" instead'); | ||
+ | |||
+ | var Position = { | ||
+ | includeScrollOffsets: false, | ||
+ | |||
+ | prepare: function() { | ||
+ | this.deltaX = window.pageXOffset | ||
+ | || document.documentElement.scrollLeft | ||
+ | || document.body.scrollLeft | ||
+ | || 0; | ||
+ | this.deltaY = window.pageYOffset | ||
+ | || document.documentElement.scrollTop | ||
+ | || document.body.scrollTop | ||
+ | || 0; | ||
+ | }, | ||
+ | |||
+ | within: function(element, x, y) { | ||
+ | if (this.includeScrollOffsets) | ||
+ | return this.withinIncludingScrolloffsets(element, x, y); | ||
+ | this.xcomp = x; | ||
+ | this.ycomp = y; | ||
+ | this.offset = Element.cumulativeOffset(element); | ||
+ | |||
+ | return (y >= this.offset[1] && | ||
+ | y < this.offset[1] + element.offsetHeight && | ||
+ | x >= this.offset[0] && | ||
+ | x < this.offset[0] + element.offsetWidth); | ||
+ | }, | ||
+ | |||
+ | withinIncludingScrolloffsets: function(element, x, y) { | ||
+ | var offsetcache = Element.cumulativeScrollOffset(element); | ||
+ | |||
+ | this.xcomp = x + offsetcache[0] - this.deltaX; | ||
+ | this.ycomp = y + offsetcache[1] - this.deltaY; | ||
+ | this.offset = Element.cumulativeOffset(element); | ||
+ | |||
+ | return (this.ycomp >= this.offset[1] && | ||
+ | this.ycomp < this.offset[1] + element.offsetHeight && | ||
+ | this.xcomp >= this.offset[0] && | ||
+ | this.xcomp < this.offset[0] + element.offsetWidth); | ||
+ | }, | ||
+ | |||
+ | overlap: function(mode, element) { | ||
+ | if (!mode) return 0; | ||
+ | if (mode == 'vertical') | ||
+ | return ((this.offset[1] + element.offsetHeight) - this.ycomp) / | ||
+ | element.offsetHeight; | ||
+ | if (mode == 'horizontal') | ||
+ | return ((this.offset[0] + element.offsetWidth) - this.xcomp) / | ||
+ | element.offsetWidth; | ||
+ | }, | ||
+ | |||
+ | |||
+ | cumulativeOffset: Element.Methods.cumulativeOffset, | ||
+ | |||
+ | positionedOffset: Element.Methods.positionedOffset, | ||
+ | |||
+ | absolutize: function(element) { | ||
+ | Position.prepare(); | ||
+ | return Element.absolutize(element); | ||
+ | }, | ||
+ | |||
+ | relativize: function(element) { | ||
+ | Position.prepare(); | ||
+ | return Element.relativize(element); | ||
+ | }, | ||
+ | |||
+ | realOffset: Element.Methods.cumulativeScrollOffset, | ||
+ | |||
+ | offsetParent: Element.Methods.getOffsetParent, | ||
+ | |||
+ | page: Element.Methods.viewportOffset, | ||
+ | |||
+ | clone: function(source, target, options) { | ||
+ | options = options || { }; | ||
+ | return Element.clonePosition(target, source, options); | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | /*--------------------------------------------------------------------------*/ | ||
+ | |||
+ | if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){ | ||
+ | function iter(name) { | ||
+ | return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]"; | ||
+ | } | ||
+ | |||
+ | instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ? | ||
+ | function(element, className) { | ||
+ | className = className.toString().strip(); | ||
+ | var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className); | ||
+ | return cond ? document._getElementsByXPath('.//*' + cond, element) : []; | ||
+ | } : function(element, className) { | ||
+ | className = className.toString().strip(); | ||
+ | var elements = [], classNames = (/\s/.test(className) ? $w(className) : null); | ||
+ | if (!classNames && !className) return elements; | ||
+ | |||
+ | var nodes = $(element).getElementsByTagName('*'); | ||
+ | className = ' ' + className + ' '; | ||
+ | |||
+ | for (var i = 0, child, cn; child = nodes[i]; i++) { | ||
+ | if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) || | ||
+ | (classNames && classNames.all(function(name) { | ||
+ | return !name.toString().blank() && cn.include(' ' + name + ' '); | ||
+ | })))) | ||
+ | elements.push(Element.extend(child)); | ||
+ | } | ||
+ | return elements; | ||
+ | }; | ||
+ | |||
+ | return function(className, parentElement) { | ||
+ | return $(parentElement || document.body).getElementsByClassName(className); | ||
+ | }; | ||
+ | }(Element.Methods); | ||
+ | |||
+ | /*--------------------------------------------------------------------------*/ | ||
+ | |||
+ | Element.ClassNames = Class.create(); | ||
+ | Element.ClassNames.prototype = { | ||
+ | initialize: function(element) { | ||
+ | this.element = $(element); | ||
+ | }, | ||
+ | |||
+ | _each: function(iterator) { | ||
+ | this.element.className.split(/\s+/).select(function(name) { | ||
+ | return name.length > 0; | ||
+ | })._each(iterator); | ||
+ | }, | ||
+ | |||
+ | set: function(className) { | ||
+ | this.element.className = className; | ||
+ | }, | ||
+ | |||
+ | add: function(classNameToAdd) { | ||
+ | if (this.include(classNameToAdd)) return; | ||
+ | this.set($A(this).concat(classNameToAdd).join(' ')); | ||
+ | }, | ||
+ | |||
+ | remove: function(classNameToRemove) { | ||
+ | if (!this.include(classNameToRemove)) return; | ||
+ | this.set($A(this).without(classNameToRemove).join(' ')); | ||
+ | }, | ||
+ | |||
+ | toString: function() { | ||
+ | return $A(this).join(' '); | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | Object.extend(Element.ClassNames.prototype, Enumerable); | ||
+ | |||
+ | /*--------------------------------------------------------------------------*/ | ||
</script> | </script> | ||
+ | <script type="text/javascript"> | ||
+ | /** | ||
+ | Copyright (c) 2008 Victor Stanciu; contact [at] victorstanciu [dot] ro; http://www.victorstanciu.ro/ | ||
+ | |||
+ | 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. | ||
+ | */ | ||
+ | |||
+ | /** | ||
+ | * @description showcase plugin for prototype.js | ||
+ | * @author Victor Stanciu; contact [at] victorstanciu [dot] ro; http://www.victorstanciu.ro/ | ||
+ | * @date 03/10/2008 | ||
+ | * @requires prototype.js 1.6, effects.js 1.8 | ||
+ | */ | ||
+ | |||
+ | Showcase = Class.create(Abstract, { | ||
+ | initialize: function (sections, controls, options) { | ||
+ | |||
+ | this.allSections = this.sections = sections; | ||
+ | this.controls = controls; | ||
+ | |||
+ | this.options = Object.extend({ | ||
+ | ratio: 0.5, | ||
+ | initialDelay: 1, | ||
+ | duration: 0.5, | ||
+ | size: this.sections.size() | ||
+ | }, options || {}); | ||
+ | |||
+ | this.running = false; | ||
+ | this.queue = new Array; | ||
+ | |||
+ | this.computeMetrics(); | ||
+ | |||
+ | this.sections = this.allSections.slice(this.currentIndex - this.half, this.currentIndex + this.half + 1); | ||
+ | |||
+ | this.allSections.each((function (section, index) { | ||
+ | section.setStyle({position: 'absolute', zIndex: Math.abs(index - this.sections.size()), left: '50%', top: '50%', marginLeft: -Math.round(section.getWidth() / 2) + 'px', marginTop: -Math.round(section.getHeight() / 2) + 'px'}).initialIndex = index; | ||
+ | |||
+ | section.observe('click', this.jump.bind(this)).observe('mouseover', function (event) { | ||
+ | section.setOpacity(1); | ||
+ | }).observe('mouseout', function () { | ||
+ | section.setOpacity(section.opacity); | ||
+ | }).opacity = 1; | ||
+ | |||
+ | if (!this.sections.member(section)) { | ||
+ | this.queue.push(section.hide()); | ||
+ | } | ||
+ | }).bind(this)); | ||
+ | |||
+ | for (i = 0; i <= this.half; i++) { | ||
+ | this.sections.push(this.sections.shift()); | ||
+ | } | ||
+ | |||
+ | this.controls.invoke('observe', 'click', this.click.bind(this)); | ||
+ | (this.animate.bind(this)).delay(this.options.initialDelay); | ||
+ | }, | ||
+ | |||
+ | computeMetrics: function () { | ||
+ | this.half = this.currentIndex = (this.options.size - 1) / 2; | ||
+ | this.ratioStep = Math.round(((1 - this.options.ratio) / this.currentIndex) * 100) / 100; | ||
+ | this.positionStep = Math.round(50 / this.half * 100) / 100; | ||
+ | this.maxDimensions = this.sections.first().getDimensions(); | ||
+ | }, | ||
+ | |||
+ | click: function (event) { | ||
+ | event.stop(); | ||
+ | var element = event.findElement('a'); | ||
+ | if (!this.running) { | ||
+ | eval("this." + element.rel + "()"); | ||
+ | } | ||
+ | this.animate(element.rel); | ||
+ | }, | ||
+ | |||
+ | previous: function () { | ||
+ | if (this.options.size < this.allSections.size()) { | ||
+ | var sectionIn = this.queue.shift(); | ||
+ | var sectionOut = this.sections.pop(); | ||
+ | |||
+ | this.sections.unshift(sectionIn); | ||
+ | this.queue.push(sectionOut.fade({duration: this.options.duration})); | ||
+ | } else { | ||
+ | this.sections.unshift(this.sections.pop()); | ||
+ | } | ||
+ | }, | ||
+ | |||
+ | next: function () { | ||
+ | if (this.options.size < this.allSections.size()) { | ||
+ | var sectionIn = this.queue.shift(); | ||
+ | var sectionOut = this.sections.shift(); | ||
+ | |||
+ | this.sections.push(sectionIn); | ||
+ | this.queue.push(sectionOut.fade({duration: this.options.duration})); | ||
+ | } else { | ||
+ | this.sections.push(this.sections.shift()); | ||
+ | } | ||
+ | }, | ||
+ | |||
+ | jump: function (event) { | ||
+ | event.stop(); | ||
+ | |||
+ | if (!this.running) { | ||
+ | var section = this.sections[this.sections.indexOf(event.findElement('li'))]; | ||
+ | |||
+ | var direction = ''; | ||
+ | |||
+ | if (section.index < this.half) { | ||
+ | (this.half - section.index).times((function () { | ||
+ | this.previous(); | ||
+ | }).bind(this)); | ||
+ | direction = 'previous'; | ||
+ | } else if (section.index == this.half) { | ||
+ | } else { | ||
+ | (section.index - this.half).times((function () { | ||
+ | this.next(); | ||
+ | }).bind(this)); | ||
+ | direction = 'next'; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | this.animate(direction); | ||
+ | }, | ||
+ | |||
+ | runEffects: function () { | ||
+ | |||
+ | this.stackSections.bind(this).delay(this.options.duration / 2); | ||
+ | |||
+ | this.running = new Effect.Parallel( | ||
+ | this.effects.map(function (effect) { | ||
+ | return new Effect.Parallel([ | ||
+ | new Effect.Morph(effect.section, { | ||
+ | style: effect.style, | ||
+ | sync: true, | ||
+ | delay: 1, | ||
+ | transition: Effect.Transitions.linear | ||
+ | }), | ||
+ | new Effect.Appear(effect.section, { | ||
+ | to: Math.min(effect.section.ratio, 1), | ||
+ | sync: true | ||
+ | }) | ||
+ | ], { | ||
+ | sync: true, | ||
+ | beforeStart: function () { | ||
+ | } | ||
+ | }); | ||
+ | }), { | ||
+ | duration: this.options.duration, | ||
+ | afterFinish: (function () { | ||
+ | this.running = false; | ||
+ | }).bind(this) | ||
+ | }); | ||
+ | }, | ||
+ | |||
+ | stackSections: function () { | ||
+ | this.sections.each(function (section) { | ||
+ | section.setStyle({zIndex: section.stackIndex}); | ||
+ | }); | ||
+ | }, | ||
+ | |||
+ | indexSections: function () { | ||
+ | this.sections.each((function (section, index) { | ||
+ | section.index = index; | ||
+ | section.modifier = Math.abs(Math.abs((section.index - (this.sections.size() - 1) / 2)) - this.half); | ||
+ | |||
+ | section.ratio = Math.round(((section.modifier * this.ratioStep) + this.options.ratio) * 100) / 100; | ||
+ | |||
+ | section.width = Math.min(Math.round(this.maxDimensions.width * section.ratio), this.maxDimensions.width); | ||
+ | section.height = Math.min(Math.round(this.maxDimensions.height * section.ratio), this.maxDimensions.height); | ||
+ | |||
+ | section.positionIndex = (section.index - (this.sections.size() - 1) / 2); | ||
+ | section.stackIndex = Math.abs(Math.abs((section.index - (this.sections.size() - 1) / 2)) - this.half) + 1; | ||
+ | |||
+ | section.left = section.top = Math.round((this.half + section.positionIndex) * this.positionStep); | ||
+ | section.opacity = Math.min(section.ratio, 1); | ||
+ | }).bind(this)); | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | Showcase.Horizontal = Class.create(Showcase, { | ||
+ | |||
+ | animate: function (direction) { | ||
+ | this.indexSections(); | ||
+ | |||
+ | this.effects = new Array(); | ||
+ | this.sections.each((function (section) { | ||
+ | var style = { | ||
+ | left: section.left + '%', | ||
+ | top: '50%', | ||
+ | marginTop: -Math.abs(section.height / 2) + 'px', | ||
+ | width: section.width + 'px', | ||
+ | height: section.height + 'px' | ||
+ | }; | ||
+ | |||
+ | if (section.left == 0) { | ||
+ | style.marginLeft = '0px'; | ||
+ | } else if (section.left == 50) { | ||
+ | style.marginLeft = -Math.round(section.width / 2) + 'px'; | ||
+ | } else if (section.left == 100) { | ||
+ | style.marginLeft = -section.width + 'px'; | ||
+ | } else { | ||
+ | style.marginLeft = -Math.round(section.width / 2) + 'px'; | ||
+ | } | ||
+ | |||
+ | this.effects.push({section: section, style: style}); | ||
+ | }).bind(this)); | ||
+ | |||
+ | this.currentIndex = this.sections[this.half].initialIndex; | ||
+ | |||
+ | this.runEffects(); | ||
+ | } | ||
+ | |||
+ | }); | ||
+ | |||
+ | Showcase.Vertical = Class.create(Showcase, { | ||
+ | |||
+ | animate: function (direction) { | ||
+ | this.indexSections(); | ||
+ | |||
+ | this.effects = new Array(); | ||
+ | this.sections.each((function (section) { | ||
+ | var style = { | ||
+ | top: section.top + '%', | ||
+ | left: '50%', | ||
+ | marginLeft: -Math.abs(section.width / 2) + 'px', | ||
+ | width: section.width + 'px', | ||
+ | height: section.height + 'px' | ||
+ | }; | ||
+ | |||
+ | if (section.top == 0) { | ||
+ | style.marginTop = '0px'; | ||
+ | } else if (section.top == 50) { | ||
+ | style.marginTop = -Math.round(section.height / 2) + 'px'; | ||
+ | } else if (section.top == 100) { | ||
+ | style.marginTop = -section.height + 'px'; | ||
+ | } else { | ||
+ | style.marginTop = -Math.round(section.height / 2) + 'px'; | ||
+ | } | ||
+ | |||
+ | this.effects.push({section: section, style: style}); | ||
+ | }).bind(this)); | ||
+ | |||
+ | this.currentIndex = this.sections[this.half].initialIndex; | ||
+ | |||
+ | this.runEffects(); | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | Showcase.Diagonal = Class.create(Showcase, { | ||
+ | |||
+ | animate: function (direction) { | ||
+ | this.indexSections(); | ||
+ | |||
+ | this.effects = new Array(); | ||
+ | this.sections.each((function (section) { | ||
+ | var style = { | ||
+ | left: section.left + '%', | ||
+ | top: section.top + '%', | ||
+ | width: section.width + 'px', | ||
+ | height: section.height + 'px' | ||
+ | }; | ||
+ | |||
+ | if (section.left == 0) { | ||
+ | style.marginLeft = '0px'; | ||
+ | } else if (section.left == 50) { | ||
+ | style.marginLeft = -Math.round(section.width / 2) + 'px'; | ||
+ | } else if (section.left == 100) { | ||
+ | style.marginLeft = -section.width + 'px'; | ||
+ | } else { | ||
+ | style.marginLeft = -Math.round(section.width / 2) + 'px'; | ||
+ | } | ||
+ | |||
+ | if (section.top == 0) { | ||
+ | style.marginTop = '0px'; | ||
+ | } else if (section.top == 50) { | ||
+ | style.marginTop = -Math.round(section.height / 2) + 'px'; | ||
+ | } else if (section.top == 100) { | ||
+ | style.marginTop = -section.height + 'px'; | ||
+ | } else { | ||
+ | style.marginTop = -Math.round(section.height / 2) + 'px'; | ||
+ | } | ||
+ | |||
+ | this.effects.push({section: section, style: style}); | ||
+ | }).bind(this)); | ||
+ | |||
+ | this.currentIndex = this.sections[this.half].initialIndex; | ||
+ | |||
+ | this.runEffects(); | ||
+ | } | ||
+ | |||
+ | }); | ||
+ | </script> | ||
+ | |||
+ | |||
+ | <a href="#next" class="controls" rel="next">Next</a> | ||
+ | <a href="#previous" class="controls" rel="previous">Previous</a> | ||
- | < | + | <ul id="showcase"> |
- | < | + | <li><img src="https://static.igem.org/mediawiki/2010/0/00/Freiburg_software_10_team_icon.png" alt="1" /></li> |
- | < | + | <li><img src="https://static.igem.org/mediawiki/2010/d/de/Freiburg_software_10_synbiowave_logo_2.png" alt="2" /></li> |
- | < | + | <li><img src="https://static.igem.org/mediawiki/2010/6/61/Freiburg_software_10_user_icon_2.png" alt="3" /></li> |
- | < | + | <li><img src="https://static.igem.org/mediawiki/2010/c/c1/Freiburg_software_10_developer_icon_2.png" alt="n" /></li> |
- | <img src="https://static.igem.org/mediawiki/2010/ | + | <li><img src="https://static.igem.org/mediawiki/2010/b/b0/Freiburg_software_10_synbiowave_homepage.png" alt="n" /></li> |
- | <img | + | <li><img src="https://static.igem.org/mediawiki/2010/d/db/Freiburg_software_10_google_wave_schrift.png" alt="n" /></li> |
- | </ | + | <li><img src="https://static.igem.org/mediawiki/2010/e/ec/Freiburg_software_10_Kuklab_logo.jpg" alt="n" /></li> |
- | < | + | <li><img src="https://static.igem.org/mediawiki/2010/b/b6/Freiburg_software_10_Sourceforge-logo_v1.png" alt="n" /></li> |
- | + | </ul> | |
- | < | + | |
- | </ | + | |
- | </ | + | |
</html> | </html> |
Revision as of 19:29, 25 October 2010