Updated for Rails 1.0

git-svn-id: http://www.rousette.org.uk/svn/tracks-repos/trunk@170 a4c988fc-2ded-0310-b66e-134b36920a42
This commit is contained in:
bsag 2005-12-24 10:57:19 +00:00
parent bfbd89bb7d
commit e5d9a413d5
4 changed files with 631 additions and 616 deletions

View file

@ -80,7 +80,10 @@ Autocompleter.Base.prototype = {
show: function() {
if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
if(!this.iefix && (navigator.appVersion.indexOf('MSIE')>0) && (Element.getStyle(this.update, 'position')=='absolute')) {
if(!this.iefix &&
(navigator.appVersion.indexOf('MSIE')>0) &&
(navigator.userAgent.indexOf('Opera')<0) &&
(Element.getStyle(this.update, 'position')=='absolute')) {
new Insertion.After(this.update,
'<iframe id="' + this.update.id + '_iefix" '+
'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
@ -718,4 +721,30 @@ Ajax.InPlaceEditor.prototype = {
Event.stopObserving(this.options.externalControl, 'mouseout', this.mouseoutListener);
}
}
};
// Delayed observer, like Form.Element.Observer,
// but waits for delay after last key input
// Ideal for live-search fields
Form.Element.DelayedObserver = Class.create();
Form.Element.DelayedObserver.prototype = {
initialize: function(element, delay, callback) {
this.delay = delay || 0.5;
this.element = $(element);
this.callback = callback;
this.timer = null;
this.lastValue = $F(this.element);
Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
},
delayedListener: function(event) {
if(this.lastValue == $F(this.element)) return;
if(this.timer) clearTimeout(this.timer);
this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
this.lastValue = $F(this.element);
},
onTimerEvent: function() {
this.timer = null;
this.callback(this.element, $F(this.element));
}
};

View file

@ -1,7 +1,5 @@
// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
//
// Element.Class part Copyright (c) 2005 by Rick Olson
//
// See scriptaculous.js for full license.
/*--------------------------------------------------------------------------*/
@ -10,7 +8,7 @@ var Droppables = {
drops: [],
remove: function(element) {
this.drops = this.drops.reject(function(d) { return d.element==element });
this.drops = this.drops.reject(function(d) { return d.element==$(element) });
},
add: function(element) {
@ -31,6 +29,8 @@ var Droppables = {
options._containers.push($(containment));
}
}
if(options.accept) options.accept = [options.accept].flatten();
Element.makePositioned(element); // fix IE
options.element = element;
@ -43,55 +43,50 @@ var Droppables = {
return drop._containers.detect(function(c) { return parentNode == c });
},
isAffected: function(pX, pY, element, drop) {
isAffected: function(point, element, drop) {
return (
(drop.element!=element) &&
((!drop._containers) ||
this.isContained(element, drop)) &&
((!drop.accept) ||
(Element.Class.has_any(element, drop.accept))) &&
Position.within(drop.element, pX, pY) );
(Element.classNames(element).detect(
function(v) { return drop.accept.include(v) } ) )) &&
Position.within(drop.element, point[0], point[1]) );
},
deactivate: function(drop) {
if(drop.hoverclass)
Element.Class.remove(drop.element, drop.hoverclass);
Element.removeClassName(drop.element, drop.hoverclass);
this.last_active = null;
},
activate: function(drop) {
if(this.last_active) this.deactivate(this.last_active);
if(drop.hoverclass)
Element.Class.add(drop.element, drop.hoverclass);
Element.addClassName(drop.element, drop.hoverclass);
this.last_active = drop;
},
show: function(event, element) {
show: function(point, element) {
if(!this.drops.length) return;
var pX = Event.pointerX(event);
var pY = Event.pointerY(event);
Position.prepare();
var i = this.drops.length-1; do {
var drop = this.drops[i];
if(this.isAffected(pX, pY, element, drop)) {
if(this.last_active) this.deactivate(this.last_active);
this.drops.each( function(drop) {
if(Droppables.isAffected(point, element, drop)) {
if(drop.onHover)
drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
if(drop.greedy) {
this.activate(drop);
return;
Droppables.activate(drop);
throw $break;
}
}
} while (i--);
if(this.last_active) this.deactivate(this.last_active);
});
},
fire: function(event, element) {
if(!this.last_active) return;
Position.prepare();
if (this.isAffected(Event.pointerX(event), Event.pointerY(event), element, this.last_active))
if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active))
if (this.last_active.onDrop)
this.last_active.onDrop(element, this.last_active.element, event);
},
@ -103,15 +98,84 @@ var Droppables = {
}
var Draggables = {
drags: [],
observers: [],
register: function(draggable) {
if(this.drags.length == 0) {
this.eventMouseUp = this.endDrag.bindAsEventListener(this);
this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
this.eventKeypress = this.keyPress.bindAsEventListener(this);
Event.observe(document, "mouseup", this.eventMouseUp);
Event.observe(document, "mousemove", this.eventMouseMove);
Event.observe(document, "keypress", this.eventKeypress);
}
this.drags.push(draggable);
},
unregister: function(draggable) {
this.drags = this.drags.reject(function(d) { return d==draggable });
if(this.drags.length == 0) {
Event.stopObserving(document, "mouseup", this.eventMouseUp);
Event.stopObserving(document, "mousemove", this.eventMouseMove);
Event.stopObserving(document, "keypress", this.eventKeypress);
}
},
activate: function(draggable) {
window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
this.activeDraggable = draggable;
},
deactivate: function(draggbale) {
this.activeDraggable = null;
},
updateDrag: function(event) {
if(!this.activeDraggable) return;
var pointer = [Event.pointerX(event), Event.pointerY(event)];
// Mozilla-based browsers fire successive mousemove events with
// the same coordinates, prevent needless redrawing (moz bug?)
if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
this._lastPointer = pointer;
this.activeDraggable.updateDrag(event, pointer);
},
endDrag: function(event) {
if(!this.activeDraggable) return;
this._lastPointer = null;
this.activeDraggable.endDrag(event);
},
keyPress: function(event) {
if(this.activeDraggable)
this.activeDraggable.keyPress(event);
},
addObserver: function(observer) {
this.observers.push(observer);
this.observers.push(observer);
this._cacheObserverCallbacks();
},
removeObserver: function(element) { // element instead of obsever fixes mem leaks
removeObserver: function(element) { // element instead of observer fixes mem leaks
this.observers = this.observers.reject( function(o) { return o.element==element });
this._cacheObserverCallbacks();
},
notify: function(eventName, draggable) { // 'onStart', 'onEnd'
this.observers.invoke(eventName, draggable);
notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag'
if(this[eventName+'Count'] > 0)
this.observers.each( function(o) {
if(o[eventName]) o[eventName](eventName, draggable, event);
});
},
_cacheObserverCallbacks: function() {
['onStart','onEnd','onDrag'].each( function(eventName) {
Draggables[eventName+'Count'] = Draggables.observers.select(
function(o) { return o[eventName]; }
).length;
});
}
}
@ -127,68 +191,48 @@ Draggable.prototype = {
},
reverteffect: function(element, top_offset, left_offset) {
var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02;
new Effect.MoveBy(element, -top_offset, -left_offset, {duration:dur});
element._revert = new Effect.MoveBy(element, -top_offset, -left_offset, {duration:dur});
},
endeffect: function(element) {
new Effect.Opacity(element, {duration:0.2, from:0.7, to:1.0});
new Effect.Opacity(element, {duration:0.2, from:0.7, to:1.0});
},
zindex: 1000,
revert: false
revert: false,
snap: false // false, or xy or [x,y] or function(x,y){ return [x,y] }
}, arguments[1] || {});
this.element = $(element);
this.element = $(element);
if(options.handle && (typeof options.handle == 'string'))
this.handle = Element.Class.childrenWith(this.element, options.handle)[0];
this.handle = Element.childrenWithClassName(this.element, options.handle)[0];
if(!this.handle) this.handle = $(options.handle);
if(!this.handle) this.handle = this.element;
Element.makePositioned(this.element); // fix IE
this.offsetX = 0;
this.offsetY = 0;
this.originalLeft = this.currentLeft();
this.originalTop = this.currentTop();
this.originalX = this.element.offsetLeft;
this.originalY = this.element.offsetTop;
this.delta = this.currentDelta();
this.options = options;
this.dragging = false;
this.options = options;
this.active = false;
this.dragging = false;
this.eventMouseDown = this.startDrag.bindAsEventListener(this);
this.eventMouseUp = this.endDrag.bindAsEventListener(this);
this.eventMouseMove = this.update.bindAsEventListener(this);
this.eventKeypress = this.keyPress.bindAsEventListener(this);
this.eventMouseDown = this.initDrag.bindAsEventListener(this);
Event.observe(this.handle, "mousedown", this.eventMouseDown);
this.registerEvents();
Draggables.register(this);
},
destroy: function() {
Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
this.unregisterEvents();
Draggables.unregister(this);
},
registerEvents: function() {
Event.observe(document, "mouseup", this.eventMouseUp);
Event.observe(document, "mousemove", this.eventMouseMove);
Event.observe(document, "keypress", this.eventKeypress);
Event.observe(this.handle, "mousedown", this.eventMouseDown);
currentDelta: function() {
return([
parseInt(this.element.style.left || '0'),
parseInt(this.element.style.top || '0')]);
},
unregisterEvents: function() {
//if(!this.active) return;
//Event.stopObserving(document, "mouseup", this.eventMouseUp);
//Event.stopObserving(document, "mousemove", this.eventMouseMove);
//Event.stopObserving(document, "keypress", this.eventKeypress);
},
currentLeft: function() {
return parseInt(this.element.style.left || '0');
},
currentTop: function() {
return parseInt(this.element.style.top || '0')
},
startDrag: function(event) {
if(Event.isLeftClick(event)) {
initDrag: function(event) {
if(Event.isLeftClick(event)) {
// abort on form elements, fixes a Firefox issue
var src = Event.element(event);
if(src.tagName && (
@ -196,20 +240,53 @@ Draggable.prototype = {
src.tagName=='SELECT' ||
src.tagName=='BUTTON' ||
src.tagName=='TEXTAREA')) return;
if(this.element._revert) {
this.element._revert.cancel();
this.element._revert = null;
}
// this.registerEvents();
this.active = true;
var pointer = [Event.pointerX(event), Event.pointerY(event)];
var offsets = Position.cumulativeOffset(this.element);
this.offsetX = (pointer[0] - offsets[0]);
this.offsetY = (pointer[1] - offsets[1]);
var pos = Position.cumulativeOffset(this.element);
this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });
Draggables.activate(this);
Event.stop(event);
}
},
startDrag: function(event) {
this.dragging = true;
if(this.options.zindex) {
this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
this.element.style.zIndex = this.options.zindex;
}
if(this.options.ghosting) {
this._clone = this.element.cloneNode(true);
Position.absolutize(this.element);
this.element.parentNode.insertBefore(this._clone, this.element);
}
Draggables.notify('onStart', this, event);
if(this.options.starteffect) this.options.starteffect(this.element);
},
updateDrag: function(event, pointer) {
if(!this.dragging) this.startDrag(event);
Position.prepare();
Droppables.show(pointer, this.element);
Draggables.notify('onDrag', this, event);
this.draw(pointer);
if(this.options.change) this.options.change(this);
// fix AppleWebKit rendering
if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
Event.stop(event);
},
finishDrag: function(event, success) {
// this.unregisterEvents();
this.active = false;
this.dragging = false;
if(this.options.ghosting) {
@ -219,18 +296,17 @@ Draggable.prototype = {
}
if(success) Droppables.fire(event, this.element);
Draggables.notify('onEnd', this);
Draggables.notify('onEnd', this, event);
var revert = this.options.revert;
if(revert && typeof revert == 'function') revert = revert(this.element);
var d = this.currentDelta();
if(revert && this.options.reverteffect) {
this.options.reverteffect(this.element,
this.currentTop()-this.originalTop,
this.currentLeft()-this.originalLeft);
d[1]-this.delta[1], d[0]-this.delta[0]);
} else {
this.originalLeft = this.currentLeft();
this.originalTop = this.currentTop();
this.delta = d;
}
if(this.options.zindex)
@ -239,70 +315,48 @@ Draggable.prototype = {
if(this.options.endeffect)
this.options.endeffect(this.element);
Draggables.deactivate(this);
Droppables.reset();
},
keyPress: function(event) {
if(this.active) {
if(event.keyCode==Event.KEY_ESC) {
this.finishDrag(event, false);
Event.stop(event);
}
}
if(!event.keyCode==Event.KEY_ESC) return;
this.finishDrag(event, false);
Event.stop(event);
},
endDrag: function(event) {
if(this.active && this.dragging) {
this.finishDrag(event, true);
Event.stop(event);
}
this.active = false;
this.dragging = false;
if(!this.dragging) return;
this.finishDrag(event, true);
Event.stop(event);
},
draw: function(event) {
var pointer = [Event.pointerX(event), Event.pointerY(event)];
var offsets = Position.cumulativeOffset(this.element);
offsets[0] -= this.currentLeft();
offsets[1] -= this.currentTop();
draw: function(point) {
var pos = Position.cumulativeOffset(this.element);
var d = this.currentDelta();
pos[0] -= d[0]; pos[1] -= d[1];
var p = [0,1].map(function(i){ return (point[i]-pos[i]-this.offset[i]) }.bind(this));
if(this.options.snap) {
if(typeof this.options.snap == 'function') {
p = this.options.snap(p[0],p[1]);
} else {
if(this.options.snap instanceof Array) {
p = p.map( function(v, i) {
return Math.round(v/this.options.snap[i])*this.options.snap[i] }.bind(this))
} else {
p = p.map( function(v) {
return Math.round(v/this.options.snap)*this.options.snap }.bind(this))
}
}}
var style = this.element.style;
if((!this.options.constraint) || (this.options.constraint=='horizontal'))
style.left = (pointer[0] - offsets[0] - this.offsetX) + "px";
style.left = p[0] + "px";
if((!this.options.constraint) || (this.options.constraint=='vertical'))
style.top = (pointer[1] - offsets[1] - this.offsetY) + "px";
style.top = p[1] + "px";
if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
},
update: function(event) {
if(this.active) {
if(!this.dragging) {
var style = this.element.style;
this.dragging = true;
if(Element.getStyle(this.element,'position')=='')
style.position = "relative";
if(this.options.zindex) {
this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
style.zIndex = this.options.zindex;
}
if(this.options.ghosting) {
this._clone = this.element.cloneNode(true);
Position.absolutize(this.element);
this.element.parentNode.insertBefore(this._clone, this.element);
}
Draggables.notify('onStart', this);
if(this.options.starteffect) this.options.starteffect(this.element);
}
Droppables.show(event, this.element);
this.draw(event);
if(this.options.change) this.options.change(this);
// fix AppleWebKit rendering
if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
Event.stop(event);
}
}
}
@ -315,9 +369,11 @@ SortableObserver.prototype = {
this.observer = observer;
this.lastValue = Sortable.serialize(this.element);
},
onStart: function() {
this.lastValue = Sortable.serialize(this.element);
},
onEnd: function() {
Sortable.unmark();
if(this.lastValue != Sortable.serialize(this.element))
@ -327,10 +383,12 @@ SortableObserver.prototype = {
var Sortable = {
sortables: new Array(),
options: function(element){
element = $(element);
return this.sortables.detect(function(s) { return s.element == element });
},
destroy: function(element){
element = $(element);
this.sortables.findAll(function(s) { return s.element == element }).each(function(s){
@ -340,6 +398,7 @@ var Sortable = {
});
this.sortables = this.sortables.reject(function(s) { return s.element == element });
},
create: function(element) {
element = $(element);
var options = Object.extend({
@ -413,7 +472,7 @@ var Sortable = {
(this.findElements(element, options) || []).each( function(e) {
// handles are per-draggable
var handle = options.handle ?
Element.Class.childrenWith(e, options.handle)[0] : e;
Element.childrenWithClassName(e, options.handle)[0] : e;
options.draggables.push(
new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
Droppables.add(e, options_for_droppable);
@ -433,8 +492,8 @@ var Sortable = {
if(!element.hasChildNodes()) return null;
var elements = [];
$A(element.childNodes).each( function(e) {
if(e.tagName && e.tagName==options.tag.toUpperCase() &&
(!options.only || (Element.Class.has(e, options.only))))
if(e.tagName && e.tagName.toUpperCase()==options.tag.toUpperCase() &&
(!options.only || (Element.hasClassName(e, options.only))))
elements.push(e);
if(options.tree) {
var grandchildren = this.findElements(e, options);
@ -491,14 +550,20 @@ var Sortable = {
if(!Sortable._marker) {
Sortable._marker = $('dropmarker') || document.createElement('DIV');
Element.hide(Sortable._marker);
Element.Class.add(Sortable._marker, 'dropmarker');
Element.addClassName(Sortable._marker, 'dropmarker');
Sortable._marker.style.position = 'absolute';
document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
}
var offsets = Position.cumulativeOffset(dropon);
Sortable._marker.style.top = offsets[1] + 'px';
if(position=='after') Sortable._marker.style.top = (offsets[1]+dropon.clientHeight) + 'px';
Sortable._marker.style.left = offsets[0] + 'px';
Sortable._marker.style.top = offsets[1] + 'px';
if(position=='after')
if(sortable.overlap == 'horizontal')
Sortable._marker.style.left = (offsets[0]+dropon.clientWidth) + 'px';
else
Sortable._marker.style.top = (offsets[1]+dropon.clientHeight) + 'px';
Element.show(Sortable._marker);
},
@ -511,7 +576,7 @@ var Sortable = {
name: element.id,
format: sortableOptions.format || /^[^_]*_(.*)$/
}, arguments[1] || {});
return $(this.findElements(element, options) || []).collect( function(item) {
return $(this.findElements(element, options) || []).map( function(item) {
return (encodeURIComponent(options.name) + "[]=" +
encodeURIComponent(item.id.match(options.format) ? item.id.match(options.format)[1] : ''));
}).join("&");

View file

@ -11,8 +11,8 @@
// converts rgb() and #xxx to #xxxxxx format,
// returns self (or first argument) if not convertable
String.prototype.parseColor = function() {
color = "#";
if(this.slice(0,4) == "rgb(") {
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 {
@ -26,8 +26,8 @@ String.prototype.parseColor = function() {
Element.collectTextNodesIgnoreClass = function(element, ignoreclass) {
var children = $(element).childNodes;
var text = "";
var classtest = new RegExp("^([^ ]+ )*" + ignoreclass+ "( [^ ]+)*$","i");
var text = '';
var classtest = new RegExp('^([^ ]+ )*' + ignoreclass+ '( [^ ]+)*$','i');
for (var i = 0; i < children.length; i++) {
if(children[i].nodeType==3) {
@ -41,157 +41,70 @@ Element.collectTextNodesIgnoreClass = function(element, ignoreclass) {
return text;
}
Element.setStyle = function(element, style) {
element = $(element);
for(k in style) element.style[k.camelize()] = style[k];
}
Element.setContentZoom = function(element, percent) {
element = $(element);
element.style.fontSize = (percent/100) + "em";
Element.setStyle(element, {fontSize: (percent/100) + 'em'});
if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
}
Element.getOpacity = function(element){
var opacity;
if (opacity = Element.getStyle(element, "opacity"))
var opacity;
if (opacity = Element.getStyle(element, 'opacity'))
return parseFloat(opacity);
if (opacity = (Element.getStyle(element, "filter") || '').match(/alpha\(opacity=(.*)\)/))
if (opacity = (Element.getStyle(element, 'filter') || '').match(/alpha\(opacity=(.*)\)/))
if(opacity[1]) return parseFloat(opacity[1]) / 100;
return 1.0;
}
Element.setOpacity = function(element, value){
element= $(element);
var els = element.style;
if (value == 1){
els.opacity = '0.999999';
if (value == 1){
Element.setStyle(element, { opacity:
(/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ?
0.999999 : null });
if(/MSIE/.test(navigator.userAgent))
els.filter = Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'');
Element.setStyle(element, {filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')});
} else {
if(value < 0.00001) value = 0;
els.opacity = value;
Element.setStyle(element, {opacity: value});
if(/MSIE/.test(navigator.userAgent))
els.filter = Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') +
"alpha(opacity="+value*100+")";
Element.setStyle(element,
{ filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') +
'alpha(opacity='+value*100+')' });
}
}
Element.getInlineOpacity = function(element){
element= $(element);
var op;
op = element.style.opacity;
if (typeof op != "undefined" && op != "") return op;
return "";
return $(element).style.opacity || '';
}
Element.setInlineOpacity = function(element, value){
element= $(element);
var els = element.style;
els.opacity = value;
}
/*--------------------------------------------------------------------------*/
Element.Class = {
// Element.toggleClass(element, className) toggles the class being on/off
// Element.toggleClass(element, className1, className2) toggles between both classes,
// defaulting to className1 if neither exist
toggle: function(element, className) {
if(Element.Class.has(element, className)) {
Element.Class.remove(element, className);
if(arguments.length == 3) Element.Class.add(element, arguments[2]);
} else {
Element.Class.add(element, className);
if(arguments.length == 3) Element.Class.remove(element, arguments[2]);
}
},
// gets space-delimited classnames of an element as an array
get: function(element) {
return $(element).className.split(' ');
},
// functions adapted from original functions by Gavin Kistner
remove: function(element) {
element = $(element);
var removeClasses = arguments;
$R(1,arguments.length-1).each( function(index) {
element.className =
element.className.split(' ').reject(
function(klass) { return (klass == removeClasses[index]) } ).join(' ');
});
},
add: function(element) {
element = $(element);
for(var i = 1; i < arguments.length; i++) {
Element.Class.remove(element, arguments[i]);
element.className += (element.className.length > 0 ? ' ' : '') + arguments[i];
}
},
// returns true if all given classes exist in said element
has: function(element) {
element = $(element);
if(!element || !element.className) return false;
var regEx;
for(var i = 1; i < arguments.length; i++) {
if((typeof arguments[i] == 'object') &&
(arguments[i].constructor == Array)) {
for(var j = 0; j < arguments[i].length; j++) {
regEx = new RegExp("(^|\\s)" + arguments[i][j] + "(\\s|$)");
if(!regEx.test(element.className)) return false;
}
} else {
regEx = new RegExp("(^|\\s)" + arguments[i] + "(\\s|$)");
if(!regEx.test(element.className)) return false;
}
}
return true;
},
// expects arrays of strings and/or strings as optional paramters
// Element.Class.has_any(element, ['classA','classB','classC'], 'classD')
has_any: function(element) {
element = $(element);
if(!element || !element.className) return false;
var regEx;
for(var i = 1; i < arguments.length; i++) {
if((typeof arguments[i] == 'object') &&
(arguments[i].constructor == Array)) {
for(var j = 0; j < arguments[i].length; j++) {
regEx = new RegExp("(^|\\s)" + arguments[i][j] + "(\\s|$)");
if(regEx.test(element.className)) return true;
}
} else {
regEx = new RegExp("(^|\\s)" + arguments[i] + "(\\s|$)");
if(regEx.test(element.className)) return true;
}
}
return false;
},
childrenWith: function(element, className) {
var children = $(element).getElementsByTagName('*');
var elements = new Array();
for (var i = 0; i < children.length; i++)
if (Element.Class.has(children[i], className))
elements.push(children[i]);
return elements;
}
}
Element.childrenWithClassName = function(element, className) {
return $A($(element).getElementsByTagName('*')).select(
function(c) { return Element.hasClassName(c, className) });
}
Array.prototype.call = function() {
var args = arguments;
this.each(function(f){ f.apply(this, args) });
}
/*--------------------------------------------------------------------------*/
var Effect = {
tagifyText: function(element) {
var tagifyStyle = "position:relative";
if(/MSIE/.test(navigator.userAgent)) tagifyStyle += ";zoom:1";
var tagifyStyle = 'position:relative';
if(/MSIE/.test(navigator.userAgent)) tagifyStyle += ';zoom:1';
element = $(element);
$A(element.childNodes).each( function(child) {
if(child.nodeType==3) {
child.nodeValue.toArray().each( function(character) {
element.insertBefore(
Builder.node('span',{style: tagifyStyle},
character == " " ? String.fromCharCode(160) : character),
character == ' ' ? String.fromCharCode(160) : character),
child);
});
Element.remove(child);
@ -211,11 +124,10 @@ var Effect = {
speed: 0.1,
delay: 0.0
}, arguments[2] || {});
var speed = options.speed;
var delay = options.delay;
var masterDelay = options.delay;
$A(elements).each( function(element, index) {
new effect(element, Object.extend(options, { delay: delay + index * speed }));
new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
});
}
};
@ -346,13 +258,15 @@ Effect.Base.prototype = {
if(this.setup) this.setup();
this.event('afterSetup');
}
if(this.options.transition) pos = this.options.transition(pos);
pos *= (this.options.to-this.options.from);
pos += this.options.from;
this.position = pos;
this.event('beforeUpdate');
if(this.update) this.update(pos);
this.event('afterUpdate');
if(this.state == 'running') {
if(this.options.transition) pos = this.options.transition(pos);
pos *= (this.options.to-this.options.from);
pos += this.options.from;
this.position = pos;
this.event('beforeUpdate');
if(this.update) this.update(pos);
this.event('afterUpdate');
}
},
cancel: function() {
if(!this.options.sync) Effect.Queue.remove(this);
@ -361,6 +275,9 @@ Effect.Base.prototype = {
event: function(eventName) {
if(this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
if(this.options[eventName]) this.options[eventName](this);
},
inspect: function() {
return '#<Effect:' + $H(this).inspect() + ',options:' + $H(this.options).inspect() + '>';
}
}
@ -390,7 +307,7 @@ Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
this.element = $(element);
// make this work on IE on elements without 'layout'
if(/MSIE/.test(navigator.userAgent) && (!this.element.hasLayout))
this.element.style.zoom = 1;
Element.setStyle(this.element, {zoom: 1});
var options = Object.extend({
from: Element.getOpacity(this.element) || 0.0,
to: 1.0
@ -414,20 +331,16 @@ Object.extend(Object.extend(Effect.MoveBy.prototype, Effect.Base.prototype), {
// Bug in Opera: Opera returns the "real" position of a static element or
// relative element that does not have top/left explicitly set.
// ==> Always set top and left for position relative elements in your stylesheets
// (to 0 if you do not need them)
// (to 0 if you do not need them)
Element.makePositioned(this.element);
this.originalTop = parseFloat(Element.getStyle(this.element,'top') || '0');
this.originalLeft = parseFloat(Element.getStyle(this.element,'left') || '0');
},
update: function(position) {
var topd = this.toTop * position + this.originalTop;
var leftd = this.toLeft * position + this.originalLeft;
this.setPosition(topd, leftd);
},
setPosition: function(topd, leftd) {
this.element.style.top = topd + "px";
this.element.style.left = leftd + "px";
Element.setStyle(this.element, {
top: this.toTop * position + this.originalTop + 'px',
left: this.toLeft * position + this.originalLeft + 'px'
});
}
});
@ -447,33 +360,31 @@ Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
this.start(options);
},
setup: function() {
var effect = this;
this.restoreAfterFinish = this.options.restoreAfterFinish || false;
this.elementPositioning = Element.getStyle(this.element,'position');
effect.originalStyle = {};
this.originalStyle = {};
['top','left','width','height','fontSize'].each( function(k) {
effect.originalStyle[k] = effect.element.style[k];
});
this.originalStyle[k] = this.element.style[k];
}.bind(this));
this.originalTop = this.element.offsetTop;
this.originalLeft = this.element.offsetLeft;
var fontSize = Element.getStyle(this.element,'font-size') || "100%";
var fontSize = Element.getStyle(this.element,'font-size') || '100%';
['em','px','%'].each( function(fontSizeType) {
if(fontSize.indexOf(fontSizeType)>0) {
effect.fontSize = parseFloat(fontSize);
effect.fontSizeType = fontSizeType;
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.clientHeight, this.element.clientWidth];
if(this.options.scaleMode=='content')
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,
@ -482,32 +393,28 @@ Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
update: function(position) {
var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
if(this.options.scaleContent && this.fontSize)
this.element.style.fontSize = this.fontSize*currentScale + this.fontSizeType;
Element.setStyle(this.element, {fontSize: this.fontSize * currentScale + this.fontSizeType });
this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
},
finish: function(position) {
if (this.restoreAfterFinish) {
var effect = this;
['top','left','width','height','fontSize'].each( function(k) {
effect.element.style[k] = effect.originalStyle[k];
});
}
if (this.restoreAfterFinish) Element.setStyle(this.element, this.originalStyle);
},
setDimensions: function(height, width) {
var els = this.element.style;
if(this.options.scaleX) els.width = width + 'px';
if(this.options.scaleY) els.height = height + 'px';
var d = {};
if(this.options.scaleX) d.width = width + 'px';
if(this.options.scaleY) d.height = height + '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) els.top = this.originalTop-topd + "px";
if(this.options.scaleX) els.left = this.originalLeft-leftd + "px";
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) els.top = -topd + "px";
if(this.options.scaleX) els.left = -leftd + "px";
if(this.options.scaleY) d.top = -topd + 'px';
if(this.options.scaleX) d.left = -leftd + 'px';
}
}
Element.setStyle(this.element, d);
}
});
@ -515,41 +422,32 @@ Effect.Highlight = Class.create();
Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), {
initialize: function(element) {
this.element = $(element);
var options = Object.extend({
startcolor: "#ffff99"
}, arguments[1] || {});
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.style.display=='none') { this.cancel(); return; }
if(Element.getStyle(this.element, 'display')=='none') { this.cancel(); return; }
// Disable background image during the effect
this.oldBgImage = this.element.style.backgroundImage;
this.element.style.backgroundImage = "none";
this.oldStyle = {
backgroundImage: Element.getStyle(this.element, 'background-image') };
Element.setStyle(this.element, {backgroundImage: 'none'});
if(!this.options.endcolor)
this.options.endcolor = Element.getStyle(this.element, 'background-color').parseColor('#ffffff');
if (typeof this.options.restorecolor == "undefined")
this.options.restorecolor = this.element.style.backgroundColor;
if(!this.options.restorecolor)
this.options.restorecolor = Element.getStyle(this.element, 'background-color');
// init color calculations
this.colors_base = [
parseInt(this.options.startcolor.slice(1,3),16),
parseInt(this.options.startcolor.slice(3,5),16),
parseInt(this.options.startcolor.slice(5),16) ];
this.colors_delta = [
parseInt(this.options.endcolor.slice(1,3),16)-this.colors_base[0],
parseInt(this.options.endcolor.slice(3,5),16)-this.colors_base[1],
parseInt(this.options.endcolor.slice(5),16)-this.colors_base[2]];
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) {
var effect = this; var colors = $R(0,2).map( function(i){
return Math.round(effect.colors_base[i]+(effect.colors_delta[i]*position))
});
this.element.style.backgroundColor = "#" +
colors[0].toColorPart() + colors[1].toColorPart() + colors[2].toColorPart();
Element.setStyle(this.element,{backgroundColor: $R(0,2).inject('#',function(m,v,i){
return m+(Math.round(this._base[i]+(this._delta[i]*position)).toColorPart()); }.bind(this)) });
},
finish: function() {
this.element.style.backgroundColor = this.options.restorecolor;
this.element.style.backgroundImage = this.oldBgImage;
Element.setStyle(this.element, Object.extend(this.oldStyle, {
backgroundColor: this.options.restorecolor
}));
}
});
@ -562,6 +460,7 @@ Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), {
setup: function() {
Position.prepare();
var offsets = Position.cumulativeOffset(this.element);
if(this.options.offset) offsets[1] += this.options.offset;
var max = window.innerHeight ?
window.height - window.innerHeight :
document.body.scrollHeight -
@ -584,42 +483,38 @@ Effect.Fade = function(element) {
var options = Object.extend({
from: Element.getOpacity(element) || 1.0,
to: 0.0,
afterFinishInternal: function(effect)
{ if (effect.options.to == 0) {
Element.hide(effect.element);
Element.setInlineOpacity(effect.element, oldOpacity);
}
}
afterFinishInternal: function(effect) { with(Element) {
if(effect.options.to!=0) return;
hide(effect.element);
setStyle(effect.element, {opacity: oldOpacity}); }}
}, arguments[1] || {});
return new Effect.Opacity(element,options);
}
Effect.Appear = function(element) {
var options = Object.extend({
from: (Element.getStyle(element, "display") == "none" ? 0.0 : Element.getOpacity(element) || 0.0),
from: (Element.getStyle(element, 'display') == 'none' ? 0.0 : Element.getOpacity(element) || 0.0),
to: 1.0,
beforeSetup: function(effect)
{ Element.setOpacity(effect.element, effect.options.from);
Element.show(effect.element); }
beforeSetup: function(effect) { with(Element) {
setOpacity(effect.element, effect.options.from);
show(effect.element); }}
}, arguments[1] || {});
return new Effect.Opacity(element,options);
}
Effect.Puff = function(element) {
element = $(element);
var oldOpacity = Element.getInlineOpacity(element);
var oldPosition = element.style.position;
var oldStyle = { opacity: Element.getInlineOpacity(element), position: Element.getStyle(element, 'position') };
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)
{ effect.effects[0].element.style.position = 'absolute'; },
afterFinishInternal: function(effect)
{ Element.hide(effect.effects[0].element);
effect.effects[0].element.style.position = oldPosition;
Element.setInlineOpacity(effect.effects[0].element, oldOpacity); }
beforeSetupInternal: function(effect) { with(Element) {
setStyle(effect.effects[0].element, {position: 'absolute'}); }},
afterFinishInternal: function(effect) { with(Element) {
hide(effect.effects[0].element);
setStyle(effect.effects[0].element, oldStyle); }}
}, arguments[1] || {})
);
}
@ -631,18 +526,15 @@ Effect.BlindUp = function(element) {
Object.extend({ scaleContent: false,
scaleX: false,
restoreAfterFinish: true,
afterFinishInternal: function(effect)
{
Element.hide(effect.element);
Element.undoClipping(effect.element);
}
afterFinishInternal: function(effect) { with(Element) {
[hide, undoClipping].call(effect.element); }}
}, arguments[1] || {})
);
}
Effect.BlindDown = function(element) {
element = $(element);
var oldHeight = element.style.height;
var oldHeight = Element.getStyle(element, 'height');
var elementDimensions = Element.getDimensions(element);
return new Effect.Scale(element, 100,
Object.extend({ scaleContent: false,
@ -650,15 +542,15 @@ Effect.BlindDown = function(element) {
scaleFrom: 0,
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
restoreAfterFinish: true,
afterSetup: function(effect) {
Element.makeClipping(effect.element);
effect.element.style.height = "0px";
Element.show(effect.element);
},
afterFinishInternal: function(effect) {
Element.undoClipping(effect.element);
effect.element.style.height = oldHeight;
}
afterSetup: function(effect) { with(Element) {
makeClipping(effect.element);
setStyle(effect.element, {height: '0px'});
show(effect.element);
}},
afterFinishInternal: function(effect) { with(Element) {
undoClipping(effect.element);
setStyle(effect.element, {height: oldHeight});
}}
}, arguments[1] || {})
);
}
@ -674,16 +566,13 @@ Effect.SwitchOff = function(element) {
new Effect.Scale(effect.element, 1, {
duration: 0.3, scaleFromCenter: true,
scaleX: false, scaleContent: false, restoreAfterFinish: true,
beforeSetup: function(effect) {
Element.makePositioned(effect.element);
Element.makeClipping(effect.element);
},
afterFinishInternal: function(effect) {
Element.hide(effect.element);
Element.undoClipping(effect.element);
Element.undoPositioned(effect.element);
Element.setInlineOpacity(effect.element, oldOpacity);
}
beforeSetup: function(effect) { with(Element) {
[makePositioned,makeClipping].call(effect.element);
}},
afterFinishInternal: function(effect) { with(Element) {
[hide,undoClipping,undoPositioned].call(effect.element);
setStyle(effect.element, {opacity: oldOpacity});
}}
})
}
});
@ -691,29 +580,28 @@ Effect.SwitchOff = function(element) {
Effect.DropOut = function(element) {
element = $(element);
var oldTop = element.style.top;
var oldLeft = element.style.left;
var oldOpacity = Element.getInlineOpacity(element);
var oldStyle = {
top: Element.getStyle(element, 'top'),
left: Element.getStyle(element, 'left'),
opacity: Element.getInlineOpacity(element) };
return new Effect.Parallel(
[ new Effect.MoveBy(element, 100, 0, { sync: true }),
new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
Object.extend(
{ duration: 0.5,
beforeSetup: function(effect) {
Element.makePositioned(effect.effects[0].element); },
afterFinishInternal: function(effect) {
Element.hide(effect.effects[0].element);
Element.undoPositioned(effect.effects[0].element);
effect.effects[0].element.style.left = oldLeft;
effect.effects[0].element.style.top = oldTop;
Element.setInlineOpacity(effect.effects[0].element, oldOpacity); }
beforeSetup: function(effect) { with(Element) {
makePositioned(effect.effects[0].element); }},
afterFinishInternal: function(effect) { with(Element) {
[hide, undoPositioned].call(effect.effects[0].element);
setStyle(effect.effects[0].element, oldStyle); }}
}, arguments[1] || {}));
}
Effect.Shake = function(element) {
element = $(element);
var oldTop = element.style.top;
var oldLeft = element.style.left;
var oldStyle = {
top: Element.getStyle(element, 'top'),
left: Element.getStyle(element, 'left') };
return new Effect.MoveBy(element, 0, 20,
{ duration: 0.05, afterFinishInternal: function(effect) {
new Effect.MoveBy(effect.element, 0, -40,
@ -725,39 +613,39 @@ Effect.Shake = function(element) {
new Effect.MoveBy(effect.element, 0, 40,
{ duration: 0.1, afterFinishInternal: function(effect) {
new Effect.MoveBy(effect.element, 0, -20,
{ duration: 0.05, afterFinishInternal: function(effect) {
Element.undoPositioned(effect.element);
effect.element.style.left = oldLeft;
effect.element.style.top = oldTop;
}}) }}) }}) }}) }}) }});
{ duration: 0.05, afterFinishInternal: function(effect) { with(Element) {
undoPositioned(effect.element);
setStyle(effect.element, oldStyle);
}}}) }}) }}) }}) }}) }});
}
Effect.SlideDown = function(element) {
element = $(element);
Element.cleanWhitespace(element);
// SlideDown need to have the content of the element wrapped in a container element with fixed height!
var oldInnerBottom = element.firstChild.style.bottom;
var oldInnerBottom = Element.getStyle(element.firstChild, 'bottom');
var elementDimensions = Element.getDimensions(element);
return new Effect.Scale(element, 100,
Object.extend({ scaleContent: false,
return new Effect.Scale(element, 100, Object.extend({
scaleContent: false,
scaleX: false,
scaleFrom: 0,
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
restoreAfterFinish: true,
afterSetup: function(effect) {
Element.makePositioned(effect.element.firstChild);
if (window.opera) effect.element.firstChild.style.top = "";
Element.makeClipping(effect.element);
element.style.height = '0';
Element.show(element);
},
afterUpdateInternal: function(effect) {
effect.element.firstChild.style.bottom =
(effect.dims[0] - effect.element.clientHeight) + 'px'; },
afterFinishInternal: function(effect) {
Element.undoClipping(effect.element);
Element.undoPositioned(effect.element.firstChild);
effect.element.firstChild.style.bottom = oldInnerBottom; }
afterSetup: function(effect) { with(Element) {
makePositioned(effect.element);
makePositioned(effect.element.firstChild);
if(window.opera) setStyle(effect.element, {top: ''});
makeClipping(effect.element);
setStyle(effect.element, {height: '0px'});
show(element); }},
afterUpdateInternal: function(effect) { with(Element) {
setStyle(effect.element.firstChild, {bottom:
(effect.dims[0] - effect.element.clientHeight) + 'px' }); }},
afterFinishInternal: function(effect) { with(Element) {
undoClipping(effect.element);
undoPositioned(effect.element.firstChild);
undoPositioned(effect.element);
setStyle(effect.element.firstChild, {bottom: oldInnerBottom}); }}
}, arguments[1] || {})
);
}
@ -765,122 +653,111 @@ Effect.SlideDown = function(element) {
Effect.SlideUp = function(element) {
element = $(element);
Element.cleanWhitespace(element);
var oldInnerBottom = element.firstChild.style.bottom;
var oldInnerBottom = Element.getStyle(element.firstChild, 'bottom');
return new Effect.Scale(element, 0,
Object.extend({ scaleContent: false,
scaleX: false,
scaleMode: 'box',
scaleFrom: 100,
restoreAfterFinish: true,
beforeStartInternal: function(effect) {
Element.makePositioned(effect.element.firstChild);
if (window.opera) effect.element.firstChild.style.top = "";
Element.makeClipping(effect.element);
Element.show(element);
},
afterUpdateInternal: function(effect) {
effect.element.firstChild.style.bottom =
(effect.dims[0] - effect.element.clientHeight) + 'px'; },
afterFinishInternal: function(effect) {
Element.hide(effect.element);
Element.undoClipping(effect.element);
Element.undoPositioned(effect.element.firstChild);
effect.element.firstChild.style.bottom = oldInnerBottom; }
beforeStartInternal: function(effect) { with(Element) {
makePositioned(effect.element);
makePositioned(effect.element.firstChild);
if(window.opera) setStyle(effect.element, {top: ''});
makeClipping(effect.element);
show(element); }},
afterUpdateInternal: function(effect) { with(Element) {
setStyle(effect.element.firstChild, {bottom:
(effect.dims[0] - effect.element.clientHeight) + 'px' }); }},
afterFinishInternal: function(effect) { with(Element) {
[hide, undoClipping].call(effect.element);
undoPositioned(effect.element.firstChild);
undoPositioned(effect.element);
setStyle(effect.element.firstChild, {bottom: oldInnerBottom}); }}
}, arguments[1] || {})
);
}
// Bug in opera makes the TD containing this element expand for a instance after finish
Effect.Squish = function(element) {
// Bug in opera makes the TD containing this element expand for a instance after finish
return new Effect.Scale(element, window.opera ? 1 : 0,
{ restoreAfterFinish: true,
beforeSetup: function(effect) {
Element.makeClipping(effect.element); },
afterFinishInternal: function(effect) {
Element.hide(effect.element);
Element.undoClipping(effect.element); }
beforeSetup: function(effect) { with(Element) {
makeClipping(effect.element); }},
afterFinishInternal: function(effect) { with(Element) {
hide(effect.element);
undoClipping(effect.element); }}
});
}
Effect.Grow = function(element) {
element = $(element);
var options = arguments[1] || {};
var elementDimensions = Element.getDimensions(element);
var originalWidth = elementDimensions.width;
var originalHeight = elementDimensions.height;
var oldTop = element.style.top;
var oldLeft = element.style.left;
var oldHeight = element.style.height;
var oldWidth = element.style.width;
var oldOpacity = Element.getInlineOpacity(element);
var direction = options.direction || 'center';
var moveTransition = options.moveTransition || Effect.Transitions.sinoidal;
var scaleTransition = options.scaleTransition || Effect.Transitions.sinoidal;
var opacityTransition = options.opacityTransition || Effect.Transitions.full;
var options = Object.extend({
direction: 'center',
moveTransistion: 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(element) };
var dims = Element.getDimensions(element);
var initialMoveX, initialMoveY;
var moveX, moveY;
switch (direction) {
switch (options.direction) {
case 'top-left':
initialMoveX = initialMoveY = moveX = moveY = 0;
break;
case 'top-right':
initialMoveX = originalWidth;
initialMoveX = dims.width;
initialMoveY = moveY = 0;
moveX = -originalWidth;
moveX = -dims.width;
break;
case 'bottom-left':
initialMoveX = moveX = 0;
initialMoveY = originalHeight;
moveY = -originalHeight;
initialMoveY = dims.height;
moveY = -dims.height;
break;
case 'bottom-right':
initialMoveX = originalWidth;
initialMoveY = originalHeight;
moveX = -originalWidth;
moveY = -originalHeight;
initialMoveX = dims.width;
initialMoveY = dims.height;
moveX = -dims.width;
moveY = -dims.height;
break;
case 'center':
initialMoveX = originalWidth / 2;
initialMoveY = originalHeight / 2;
moveX = -originalWidth / 2;
moveY = -originalHeight / 2;
initialMoveX = dims.width / 2;
initialMoveY = dims.height / 2;
moveX = -dims.width / 2;
moveY = -dims.height / 2;
break;
}
return new Effect.MoveBy(element, initialMoveY, initialMoveX, {
duration: 0.01,
beforeSetup: function(effect) {
Element.hide(effect.element);
Element.makeClipping(effect.element);
Element.makePositioned(effect.element);
},
beforeSetup: function(effect) { with(Element) {
hide(effect.element);
makeClipping(effect.element);
makePositioned(effect.element);
}},
afterFinishInternal: function(effect) {
new Effect.Parallel(
[ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: opacityTransition }),
new Effect.MoveBy(effect.element, moveY, moveX, { sync: true, transition: moveTransition }),
[ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
new Effect.MoveBy(effect.element, moveY, moveX, { sync: true, transition: options.moveTransition }),
new Effect.Scale(effect.element, 100, {
scaleMode: { originalHeight: originalHeight, originalWidth: originalWidth },
sync: true, scaleFrom: window.opera ? 1 : 0, transition: scaleTransition, restoreAfterFinish: true})
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.style.height = 0;
Element.show(effect.effects[0].element);
},
afterFinishInternal: function(effect) {
var el = effect.effects[0].element;
var els = el.style;
Element.undoClipping(el);
Element.undoPositioned(el);
els.top = oldTop;
els.left = oldLeft;
els.height = oldHeight;
els.width = originalWidth + 'px';
Element.setInlineOpacity(el, oldOpacity);
}
beforeSetup: function(effect) { with(Element) {
setStyle(effect.effects[0].element, {height: '0px'});
show(effect.effects[0].element); }},
afterFinishInternal: function(effect) { with(Element) {
[undoClipping, undoPositioned].call(effect.effects[0].element);
setStyle(effect.effects[0].element, oldStyle); }}
}, options)
)
}
@ -889,66 +766,54 @@ Effect.Grow = function(element) {
Effect.Shrink = function(element) {
element = $(element);
var options = arguments[1] || {};
var originalWidth = element.clientWidth;
var originalHeight = element.clientHeight;
var oldTop = element.style.top;
var oldLeft = element.style.left;
var oldHeight = element.style.height;
var oldWidth = element.style.width;
var oldOpacity = Element.getInlineOpacity(element);
var options = Object.extend({
direction: 'center',
moveTransistion: 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(element) };
var direction = options.direction || 'center';
var moveTransition = options.moveTransition || Effect.Transitions.sinoidal;
var scaleTransition = options.scaleTransition || Effect.Transitions.sinoidal;
var opacityTransition = options.opacityTransition || Effect.Transitions.none;
var dims = Element.getDimensions(element);
var moveX, moveY;
switch (direction) {
switch (options.direction) {
case 'top-left':
moveX = moveY = 0;
break;
case 'top-right':
moveX = originalWidth;
moveX = dims.width;
moveY = 0;
break;
case 'bottom-left':
moveX = 0;
moveY = originalHeight;
moveY = dims.height;
break;
case 'bottom-right':
moveX = originalWidth;
moveY = originalHeight;
moveX = dims.width;
moveY = dims.height;
break;
case 'center':
moveX = originalWidth / 2;
moveY = originalHeight / 2;
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: opacityTransition }),
new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: scaleTransition, restoreAfterFinish: true}),
new Effect.MoveBy(element, moveY, moveX, { sync: true, transition: moveTransition })
[ 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.MoveBy(element, moveY, moveX, { sync: true, transition: options.moveTransition })
], Object.extend({
beforeStartInternal: function(effect) {
Element.makePositioned(effect.effects[0].element);
Element.makeClipping(effect.effects[0].element);
},
afterFinishInternal: function(effect) {
var el = effect.effects[0].element;
var els = el.style;
Element.hide(el);
Element.undoClipping(el);
Element.undoPositioned(el);
els.top = oldTop;
els.left = oldLeft;
els.height = oldHeight;
els.width = oldWidth;
Element.setInlineOpacity(el, oldOpacity);
}
beforeStartInternal: function(effect) { with(Element) {
[makePositioned, makeClipping].call(effect.effects[0].element) }},
afterFinishInternal: function(effect) { with(Element) {
[hide, undoClipping, undoPositioned].call(effect.effects[0].element);
setStyle(effect.effects[0].element, oldStyle); }}
}, options)
);
}
@ -962,16 +827,17 @@ Effect.Pulsate = function(element) {
reverser.bind(transition);
return new Effect.Opacity(element,
Object.extend(Object.extend({ duration: 3.0, from: 0,
afterFinishInternal: function(effect) { Element.setInlineOpacity(effect.element, oldOpacity); }
afterFinishInternal: function(effect) { Element.setStyle(effect.element, {opacity: oldOpacity}); }
}, options), {transition: reverser}));
}
Effect.Fold = function(element) {
element = $(element);
var originalTop = element.style.top;
var originalLeft = element.style.left;
var originalWidth = element.style.width;
var originalHeight = element.style.height;
var oldStyle = {
top: element.style.top,
left: element.style.left,
width: element.style.width,
height: element.style.height };
Element.makeClipping(element);
return new Effect.Scale(element, 5, Object.extend({
scaleContent: false,
@ -980,13 +846,9 @@ Effect.Fold = function(element) {
new Effect.Scale(element, 1, {
scaleContent: false,
scaleY: false,
afterFinishInternal: function(effect) {
Element.hide(effect.element);
Element.undoClipping(effect.element);
effect.element.style.top = originalTop;
effect.element.style.left = originalLeft;
effect.element.style.width = originalWidth;
effect.element.style.height = originalHeight;
} });
afterFinishInternal: function(effect) { with(Element) {
[hide, undoClipping].call(effect.element);
setStyle(effect.element, oldStyle);
}} });
}}, arguments[1] || {}));
}

View file

@ -1,4 +1,4 @@
/* Prototype JavaScript framework, version 1.4.0_rc2
/* Prototype JavaScript framework, version 1.4.0
* (c) 2005 Sam Stephenson <sam@conio.net>
*
* THIS FILE IS AUTOMATICALLY GENERATED. When sending patches, please diff
@ -11,7 +11,8 @@
/*--------------------------------------------------------------------------*/
var Prototype = {
Version: '1.4.0_rc2',
Version: '1.4.0',
ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
emptyFunction: function() {},
K: function(x) {return x}
@ -45,10 +46,10 @@ Object.inspect = function(object) {
}
}
Function.prototype.bind = function(object) {
var __method = this;
Function.prototype.bind = function() {
var __method = this, args = $A(arguments), object = args.shift();
return function() {
return __method.apply(object, arguments);
return __method.apply(object, args.concat($A(arguments)));
}
}
@ -143,6 +144,22 @@ Object.extend(String.prototype, {
return this.replace(/<\/?[^>]+>/gi, '');
},
stripScripts: function() {
return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
},
extractScripts: function() {
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];
});
},
evalScripts: function() {
return this.extractScripts().map(eval);
},
escapeHTML: function() {
var div = document.createElement('div');
var text = document.createTextNode(this);
@ -214,8 +231,8 @@ var Enumerable = {
all: function(iterator) {
var result = true;
this.each(function(value, index) {
if (!(result &= (iterator || Prototype.K)(value, index)))
throw $break;
result = result && !!(iterator || Prototype.K)(value, index);
if (!result) throw $break;
});
return result;
},
@ -223,7 +240,7 @@ var Enumerable = {
any: function(iterator) {
var result = true;
this.each(function(value, index) {
if (result &= (iterator || Prototype.K)(value, index))
if (result = !!(iterator || Prototype.K)(value, index))
throw $break;
});
return result;
@ -376,6 +393,7 @@ Object.extend(Enumerable, {
entries: Enumerable.toArray
});
var $A = Array.from = function(iterable) {
if (!iterable) return [];
if (iterable.toArray) {
return iterable.toArray();
} else {
@ -388,12 +406,19 @@ var $A = Array.from = function(iterable) {
Object.extend(Array.prototype, Enumerable);
Array.prototype._reverse = Array.prototype.reverse;
Object.extend(Array.prototype, {
_each: function(iterator) {
for (var i = 0; i < this.length; i++)
iterator(this[i]);
},
clear: function() {
this.length = 0;
return this;
},
first: function() {
return this[0];
},
@ -425,13 +450,18 @@ Object.extend(Array.prototype, {
indexOf: function(object) {
for (var i = 0; i < this.length; i++)
if (this[i] == object) return i;
return false;
return -1;
},
reverse: function() {
var result = [];
for (var i = this.length; i > 0; i--)
result.push(this[i-1]);
reverse: function(inline) {
return (inline !== false ? this : this.toArray())._reverse();
},
shift: function() {
var result = this[0];
for (var i = 0; i < this.length - 1; i++)
this[i] = this[i + 1];
this.length--;
return result;
},
@ -486,9 +516,9 @@ function $H(object) {
Object.extend(hash, Hash);
return hash;
}
var Range = Class.create();
Object.extend(Range.prototype, Enumerable);
Object.extend(Range.prototype, {
ObjectRange = Class.create();
Object.extend(ObjectRange.prototype, Enumerable);
Object.extend(ObjectRange.prototype, {
initialize: function(start, end, exclusive) {
this.start = start;
this.end = end;
@ -513,7 +543,7 @@ Object.extend(Range.prototype, {
});
var $R = function(start, end, exclusive) {
return new Range(start, end, exclusive);
return new ObjectRange(start, end, exclusive);
}
var Ajax = {
@ -549,8 +579,7 @@ Ajax.Responders = {
if (responder[callback] && typeof responder[callback] == 'function') {
try {
responder[callback].apply(responder, [request, transport, json]);
} catch (e) {
}
} catch (e) {}
}
});
}
@ -626,8 +655,7 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
this.transport.send(this.options.method == 'post' ? body : null);
} catch (e) {
(this.options.onException || Prototype.emptyFunction)(this, e);
Ajax.Responders.dispatch('onException', this, e);
this.dispatchException(e);
}
},
@ -661,12 +689,23 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
this.respondToReadyState(this.transport.readyState);
},
header: function(name) {
try {
return this.transport.getResponseHeader(name);
} catch (e) {}
},
evalJSON: function() {
try {
var json = this.transport.getResponseHeader('X-JSON'), object;
object = eval(json);
return object;
return eval(this.header('X-JSON'));
} catch (e) {}
},
evalResponse: function() {
try {
return eval(this.transport.responseText);
} catch (e) {
this.dispatchException(e);
}
},
@ -674,22 +713,38 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
var event = Ajax.Request.Events[readyState];
var transport = this.transport, json = this.evalJSON();
if (event == 'Complete')
(this.options['on' + this.transport.status]
|| this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
|| Prototype.emptyFunction)(transport, json);
if (event == 'Complete') {
try {
(this.options['on' + this.transport.status]
|| this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
|| Prototype.emptyFunction)(transport, json);
} catch (e) {
this.dispatchException(e);
}
(this.options['on' + event] || Prototype.emptyFunction)(transport, json);
Ajax.Responders.dispatch('on' + event, this, transport, json);
if ((this.header('Content-type') || '').match(/^text\/javascript/i))
this.evalResponse();
}
try {
(this.options['on' + event] || Prototype.emptyFunction)(transport, json);
Ajax.Responders.dispatch('on' + event, this, transport, json);
} catch (e) {
this.dispatchException(e);
}
/* Avoid memory leak in MSIE: clean up the oncomplete event handler */
if (event == 'Complete')
this.transport.onreadystatechange = Prototype.emptyFunction;
},
dispatchException: function(exception) {
(this.options.onException || Prototype.emptyFunction)(this, exception);
Ajax.Responders.dispatch('onException', this, exception);
}
});
Ajax.Updater = Class.create();
Ajax.Updater.ScriptFragment = '(?:<script.*?>)((\n|.)*?)(?:<\/script>)';
Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
initialize: function(container, url, options) {
@ -714,16 +769,16 @@ Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
updateContent: function() {
var receiver = this.responseIsSuccess() ?
this.containers.success : this.containers.failure;
var response = this.transport.responseText;
var match = new RegExp(Ajax.Updater.ScriptFragment, 'img');
var response = this.transport.responseText.replace(match, '');
var scripts = this.transport.responseText.match(match);
if (!this.options.evalScripts)
response = response.stripScripts();
if (receiver) {
if (this.options.insertion) {
new this.options.insertion(receiver, response);
} else {
receiver.innerHTML = response;
Element.update(receiver, response);
}
}
@ -731,14 +786,6 @@ Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
if (this.onComplete)
setTimeout(this.onComplete.bind(this), 10);
}
if (this.options.evalScripts && scripts) {
match = new RegExp(Ajax.Updater.ScriptFragment, 'im');
setTimeout((function() {
for (var i = 0; i < scripts.length; i++)
eval(scripts[i].match(match)[1]);
}).bind(this), 10);
}
}
});
@ -830,6 +877,11 @@ Object.extend(Element, {
element.parentNode.removeChild(element);
},
update: function(element, html) {
$(element).innerHTML = html.stripScripts();
setTimeout(function() {html.evalScripts()}, 10);
},
getHeight: function(element) {
element = $(element);
return element.offsetHeight;
@ -893,6 +945,12 @@ Object.extend(Element, {
return value == 'auto' ? null : value;
},
setStyle: function(element, style) {
element = $(element);
for (name in style)
element.style[name.camelize()] = style[name];
},
getDimensions: function(element) {
element = $(element);
if (Element.getStyle(element, 'display') != 'none')
@ -969,7 +1027,7 @@ Abstract.Insertion = function(adjacency) {
Abstract.Insertion.prototype = {
initialize: function(element, content) {
this.element = $(element);
this.content = content;
this.content = content.stripScripts();
if (this.adjacency && this.element.insertAdjacentHTML) {
try {
@ -986,6 +1044,8 @@ Abstract.Insertion.prototype = {
if (this.initializeRange) this.initializeRange();
this.insertContent([this.range.createContextualFragment(this.content)]);
}
setTimeout(function() {content.evalScripts()}, 10);
},
contentFromAnonymousTable: function() {
@ -1018,7 +1078,7 @@ Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
},
insertContent: function(fragments) {
fragments.reverse().each((function(fragment) {
fragments.reverse(false).each((function(fragment) {
this.element.insertBefore(fragment, this.element.firstChild);
}).bind(this));
}
@ -1079,7 +1139,7 @@ Element.ClassNames.prototype = {
if (!this.include(classNameToRemove)) return;
this.set(this.select(function(className) {
return className != classNameToRemove;
}));
}).join(' '));
},
toString: function() {
@ -1109,8 +1169,10 @@ var Field = {
},
activate: function(element) {
$(element).focus();
$(element).select();
element = $(element);
element.focus();
if (element.select)
element.select();
}
}
@ -1178,16 +1240,15 @@ var Form = {
}
},
findFirstElement: function(form) {
return Form.getElements(form).find(function(element) {
return element.type != 'hidden' && !element.disabled &&
['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
});
},
focusFirstElement: function(form) {
form = $(form);
var elements = Form.getElements(form);
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
if (element.type != 'hidden' && !element.disabled) {
Field.activate(element);
break;
}
}
Field.activate(Form.findFirstElement(form));
},
reset: function(form) {
@ -1201,9 +1262,17 @@ Form.Element = {
var method = element.tagName.toLowerCase();
var parameter = Form.Element.Serializers[method](element);
if (parameter)
return encodeURIComponent(parameter[0]) + '=' +
encodeURIComponent(parameter[1]);
if (parameter) {
var key = encodeURIComponent(parameter[0]);
if (key.length == 0) return;
if (parameter[1].constructor != Array)
parameter[1] = [parameter[1]];
return parameter[1].map(function(value) {
return key + '=' + encodeURIComponent(value);
}).join('&');
}
},
getValue: function(element) {
@ -1349,24 +1418,14 @@ Abstract.EventObserver.prototype = {
switch (element.type.toLowerCase()) {
case 'checkbox':
case 'radio':
element.target = this;
element.prev_onclick = element.onclick || Prototype.emptyFunction;
element.onclick = function() {
this.prev_onclick();
this.target.onElementEvent();
}
Event.observe(element, 'click', this.onElementEvent.bind(this));
break;
case 'password':
case 'text':
case 'textarea':
case 'select-one':
case 'select-multiple':
element.target = this;
element.prev_onchange = element.onchange || Prototype.emptyFunction;
element.onchange = function() {
this.prev_onchange();
this.target.onElementEvent();
}
Event.observe(element, 'change', this.onElementEvent.bind(this));
break;
}
}