aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_view
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_view')
-rw-r--r--actionpack/lib/action_view/helpers/javascripts/controls.js76
-rw-r--r--actionpack/lib/action_view/helpers/javascripts/dragdrop.js56
-rw-r--r--actionpack/lib/action_view/helpers/javascripts/effects.js124
3 files changed, 163 insertions, 93 deletions
diff --git a/actionpack/lib/action_view/helpers/javascripts/controls.js b/actionpack/lib/action_view/helpers/javascripts/controls.js
index 8c273f874f..bc9beea3c1 100644
--- a/actionpack/lib/action_view/helpers/javascripts/controls.js
+++ b/actionpack/lib/action_view/helpers/javascripts/controls.js
@@ -1,6 +1,6 @@
-// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
-// (c) 2005, 2006 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
-// (c) 2005, 2006 Jon Tirsen (http://www.tirsen.com)
+// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// (c) 2005-2007 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
+// (c) 2005-2007 Jon Tirsen (http://www.tirsen.com)
// Contributors:
// Richard Livsey
// Rahul Bhargava
@@ -41,7 +41,8 @@ var Autocompleter = {}
Autocompleter.Base = function() {};
Autocompleter.Base.prototype = {
baseInitialize: function(element, update, options) {
- this.element = $(element);
+ element = $(element)
+ this.element = element;
this.update = $(update);
this.hasFocus = false;
this.changed = false;
@@ -81,15 +82,20 @@ Autocompleter.Base.prototype = {
Element.hide(this.update);
- Event.observe(this.element, "blur", this.onBlur.bindAsEventListener(this));
- Event.observe(this.element, "keypress", this.onKeyPress.bindAsEventListener(this));
+ Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this));
+ Event.observe(this.element, 'keypress', this.onKeyPress.bindAsEventListener(this));
+
+ // Turn autocomplete back on when the user leaves the page, so that the
+ // field's value will be remembered on Mozilla-based browsers.
+ Event.observe(window, 'beforeunload', function(){
+ element.setAttribute('autocomplete', 'on');
+ });
},
show: function() {
if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
if(!this.iefix &&
- (navigator.appVersion.indexOf('MSIE')>0) &&
- (navigator.userAgent.indexOf('Opera')<0) &&
+ (Prototype.Browser.IE) &&
(Element.getStyle(this.update, 'position')=='absolute')) {
new Insertion.After(this.update,
'<iframe id="' + this.update.id + '_iefix" '+
@@ -139,17 +145,17 @@ Autocompleter.Base.prototype = {
case Event.KEY_UP:
this.markPrevious();
this.render();
- if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event);
+ if(Prototype.Browser.WebKit) Event.stop(event);
return;
case Event.KEY_DOWN:
this.markNext();
this.render();
- if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event);
+ if(Prototype.Browser.WebKit) Event.stop(event);
return;
}
else
if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
- (navigator.appVersion.indexOf('AppleWebKit') > 0 && event.keyCode == 0)) return;
+ (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;
this.changed = true;
this.hasFocus = true;
@@ -195,7 +201,6 @@ Autocompleter.Base.prototype = {
this.index==i ?
Element.addClassName(this.getEntry(i),"selected") :
Element.removeClassName(this.getEntry(i),"selected");
-
if(this.hasFocus) {
this.show();
this.active = true;
@@ -297,7 +302,6 @@ Autocompleter.Base.prototype = {
onObserverEvent: function() {
this.changed = false;
if(this.getToken().length>=this.options.minChars) {
- this.startIndicator();
this.getUpdatedChoices();
} else {
this.active = false;
@@ -338,7 +342,9 @@ Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.pro
},
getUpdatedChoices: function() {
- entry = encodeURIComponent(this.options.paramName) + '=' +
+ this.startIndicator();
+
+ var entry = encodeURIComponent(this.options.paramName) + '=' +
encodeURIComponent(this.getToken());
this.options.parameters = this.options.callback ?
@@ -346,7 +352,7 @@ Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.pro
if(this.options.defaultParams)
this.options.parameters += '&' + this.options.defaultParams;
-
+
new Ajax.Request(this.url, this.options);
},
@@ -475,9 +481,14 @@ Ajax.InPlaceEditor.prototype = {
this.options = Object.extend({
paramName: "value",
okButton: true,
+ okLink: false,
okText: "ok",
+ cancelButton: false,
cancelLink: true,
cancelText: "cancel",
+ textBeforeControls: '',
+ textBetweenControls: '',
+ textAfterControls: '',
savingText: "Saving...",
clickToEditText: "Click to edit",
okText: "ok",
@@ -565,23 +576,52 @@ Ajax.InPlaceEditor.prototype = {
var br = document.createElement("br");
this.form.appendChild(br);
}
+
+ if (this.options.textBeforeControls)
+ this.form.appendChild(document.createTextNode(this.options.textBeforeControls));
if (this.options.okButton) {
- okButton = document.createElement("input");
+ var okButton = document.createElement("input");
okButton.type = "submit";
okButton.value = this.options.okText;
okButton.className = 'editor_ok_button';
this.form.appendChild(okButton);
}
+
+ if (this.options.okLink) {
+ var okLink = document.createElement("a");
+ okLink.href = "#";
+ okLink.appendChild(document.createTextNode(this.options.okText));
+ okLink.onclick = this.onSubmit.bind(this);
+ okLink.className = 'editor_ok_link';
+ this.form.appendChild(okLink);
+ }
+
+ if (this.options.textBetweenControls &&
+ (this.options.okLink || this.options.okButton) &&
+ (this.options.cancelLink || this.options.cancelButton))
+ this.form.appendChild(document.createTextNode(this.options.textBetweenControls));
+
+ if (this.options.cancelButton) {
+ var cancelButton = document.createElement("input");
+ cancelButton.type = "submit";
+ cancelButton.value = this.options.cancelText;
+ cancelButton.onclick = this.onclickCancel.bind(this);
+ cancelButton.className = 'editor_cancel_button';
+ this.form.appendChild(cancelButton);
+ }
if (this.options.cancelLink) {
- cancelLink = document.createElement("a");
+ var cancelLink = document.createElement("a");
cancelLink.href = "#";
cancelLink.appendChild(document.createTextNode(this.options.cancelText));
cancelLink.onclick = this.onclickCancel.bind(this);
- cancelLink.className = 'editor_cancel';
+ cancelLink.className = 'editor_cancel editor_cancel_link';
this.form.appendChild(cancelLink);
}
+
+ if (this.options.textAfterControls)
+ this.form.appendChild(document.createTextNode(this.options.textAfterControls));
},
hasHTMLLineBreaks: function(string) {
if (!this.options.handleLineBreaks) return false;
diff --git a/actionpack/lib/action_view/helpers/javascripts/dragdrop.js b/actionpack/lib/action_view/helpers/javascripts/dragdrop.js
index 7ee9a5f317..cfea72ad83 100644
--- a/actionpack/lib/action_view/helpers/javascripts/dragdrop.js
+++ b/actionpack/lib/action_view/helpers/javascripts/dragdrop.js
@@ -1,5 +1,5 @@
-// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
-// (c) 2005, 2006 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
+// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// (c) 2005-2007 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
//
// 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/
@@ -110,8 +110,10 @@ var Droppables = {
Position.prepare();
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);
+ if (this.last_active.onDrop) {
+ this.last_active.onDrop(element, this.last_active.element, event);
+ return true;
+ }
},
reset: function() {
@@ -243,6 +245,7 @@ Draggable.prototype = {
},
zindex: 1000,
revert: false,
+ quiet: false,
scroll: false,
scrollSensitivity: 20,
scrollSpeed: 15,
@@ -351,8 +354,12 @@ Draggable.prototype = {
updateDrag: function(event, pointer) {
if(!this.dragging) this.startDrag(event);
- Position.prepare();
- Droppables.show(pointer, this.element);
+
+ if(!this.options.quiet){
+ Position.prepare();
+ Droppables.show(pointer, this.element);
+ }
+
Draggables.notify('onDrag', this, event);
this.draw(pointer);
@@ -380,13 +387,19 @@ Draggable.prototype = {
}
// fix AppleWebKit rendering
- if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
+ if(Prototype.Browser.WebKit) window.scrollBy(0,0);
Event.stop(event);
},
finishDrag: function(event, success) {
this.dragging = false;
+
+ if(this.options.quiet){
+ Position.prepare();
+ var pointer = [Event.pointerX(event), Event.pointerY(event)];
+ Droppables.show(pointer, this.element);
+ }
if(this.options.ghosting) {
Position.relativize(this.element);
@@ -394,7 +407,12 @@ Draggable.prototype = {
this._clone = null;
}
- if(success) Droppables.fire(event, this.element);
+ var dropped = false;
+ if(success) {
+ dropped = Droppables.fire(event, this.element);
+ if (!dropped) dropped = false;
+ }
+ if(dropped && this.options.onDropped) this.options.onDropped(this.element);
Draggables.notify('onEnd', this, event);
var revert = this.options.revert;
@@ -402,8 +420,9 @@ Draggable.prototype = {
var d = this.currentDelta();
if(revert && this.options.reverteffect) {
- this.options.reverteffect(this.element,
- d[1]-this.delta[1], d[0]-this.delta[0]);
+ if (dropped == 0 || revert != 'failure')
+ this.options.reverteffect(this.element,
+ d[1]-this.delta[1], d[0]-this.delta[0]);
} else {
this.delta = d;
}
@@ -612,10 +631,17 @@ var Sortable = {
delay: 0,
hoverclass: null,
ghosting: false,
+ quiet: false,
scroll: false,
scrollSensitivity: 20,
scrollSpeed: 15,
format: this.SERIALIZE_RULE,
+
+ // these take arrays of elements or ids and can be
+ // used for better initialization performance
+ elements: false,
+ handles: false,
+
onChange: Prototype.emptyFunction,
onUpdate: Prototype.emptyFunction
}, arguments[1] || {});
@@ -626,6 +652,7 @@ var Sortable = {
// build options for the draggables
var options_for_draggable = {
revert: true,
+ quiet: options.quiet,
scroll: options.scroll,
scrollSpeed: options.scrollSpeed,
scrollSensitivity: options.scrollSensitivity,
@@ -679,10 +706,9 @@ var Sortable = {
options.droppables.push(element);
}
- (this.findElements(element, options) || []).each( function(e) {
- // handles are per-draggable
- var handle = options.handle ?
- $(e).down('.'+options.handle,0) : e;
+ (options.elements || this.findElements(element, options) || []).each( function(e,i) {
+ var handle = options.handles ? $(options.handles[i]) :
+ (options.handle ? $(e).getElementsByClassName(options.handle)[0] : e);
options.draggables.push(
new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
Droppables.add(e, options_for_droppable);
@@ -919,7 +945,7 @@ Element.isParent = function(child, element) {
return Element.isParent(child.parentNode, element);
}
-Element.findChildren = function(element, only, recursive, tagName) {
+Element.findChildren = function(element, only, recursive, tagName) {
if(!element.hasChildNodes()) return null;
tagName = tagName.toUpperCase();
if(only) only = [only].flatten();
diff --git a/actionpack/lib/action_view/helpers/javascripts/effects.js b/actionpack/lib/action_view/helpers/javascripts/effects.js
index 4893e7c367..4d9fc6e071 100644
--- a/actionpack/lib/action_view/helpers/javascripts/effects.js
+++ b/actionpack/lib/action_view/helpers/javascripts/effects.js
@@ -1,4 +1,4 @@
-// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
// Contributors:
// Justin Palmer (http://encytemedia.com/)
// Mark Pilgrim (http://diveintomark.org/)
@@ -43,18 +43,10 @@ Element.collectTextNodesIgnoreClass = function(element, className) {
Element.setContentZoom = function(element, percent) {
element = $(element);
element.setStyle({fontSize: (percent/100) + 'em'});
- if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
+ if(Prototype.Browser.WebKit) window.scrollBy(0,0);
return element;
}
-Element.getOpacity = function(element){
- return $(element).getStyle('opacity');
-}
-
-Element.setOpacity = function(element, value){
- return $(element).setStyle({opacity:value});
-}
-
Element.getInlineOpacity = function(element){
return $(element).style.opacity || '';
}
@@ -87,7 +79,7 @@ var Effect = {
throw("Effect.tagifyText requires including script.aculo.us' builder.js library");
var tagifyStyle = 'position:relative';
- if(/MSIE/.test(navigator.userAgent) && !window.opera) tagifyStyle += ';zoom:1';
+ if(Prototype.Browser.IE) tagifyStyle += ';zoom:1';
element = $(element);
$A(element.childNodes).each( function(child) {
@@ -150,7 +142,8 @@ Effect.Transitions = {
return 1-pos;
},
flicker: function(pos) {
- return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
+ var pos = ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
+ return (pos > 1 ? 1 : pos);
},
wobble: function(pos) {
return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
@@ -177,7 +170,7 @@ Effect.ScopedQueue = Class.create();
Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), {
initialize: function() {
this.effects = [];
- this.interval = null;
+ this.interval = null;
},
_each: function(iterator) {
this.effects._each(iterator);
@@ -211,7 +204,7 @@ Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), {
if(!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
this.effects.push(effect);
- if(!this.interval)
+ if(!this.interval)
this.interval = setInterval(this.loop.bind(this), 15);
},
remove: function(effect) {
@@ -224,7 +217,7 @@ Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), {
loop: function() {
var timePos = new Date().getTime();
for(var i=0, len=this.effects.length;i<len;i++)
- if(this.effects[i]) this.effects[i].loop(timePos);
+ this.effects[i] && this.effects[i].loop(timePos);
}
});
@@ -244,7 +237,7 @@ Effect.Queue = Effect.Queues.get('global');
Effect.DefaultOptions = {
transition: Effect.Transitions.sinoidal,
duration: 1.0, // seconds
- fps: 60.0, // max. 60fps due to Effect.Queue implementation
+ fps: 100, // 100= assume 66fps max.
sync: false, // true for combining
from: 0.0,
to: 1.0,
@@ -256,11 +249,35 @@ Effect.Base = function() {};
Effect.Base.prototype = {
position: null,
start: function(options) {
+ function codeForEvent(options,eventName){
+ return (
+ (options[eventName+'Internal'] ? 'this.options.'+eventName+'Internal(this);' : '') +
+ (options[eventName] ? 'this.options.'+eventName+'(this);' : '')
+ );
+ }
+ if(options.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.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;
+
+ eval('this.render = function(pos){ '+
+ 'if(this.state=="idle"){this.state="running";'+
+ codeForEvent(options,'beforeSetup')+
+ (this.setup ? 'this.setup();':'')+
+ codeForEvent(options,'afterSetup')+
+ '};if(this.state=="running"){'+
+ 'pos=this.options.transition(pos)*'+this.fromToDelta+'+'+this.options.from+';'+
+ 'this.position=pos;'+
+ codeForEvent(options,'beforeUpdate')+
+ (this.update ? 'this.update(pos);':'')+
+ codeForEvent(options,'afterUpdate')+
+ '}}');
+
this.event('beforeStart');
if(!this.options.sync)
Effect.Queues.get(typeof this.options.queue == 'string' ?
@@ -276,31 +293,14 @@ Effect.Base.prototype = {
this.event('afterFinish');
return;
}
- var pos = (timePos - this.startOn) / (this.finishOn - this.startOn);
- var frame = Math.round(pos * this.options.fps * this.options.duration);
+ var pos = (timePos - this.startOn) / this.totalTime,
+ frame = Math.round(pos * this.totalFrames);
if(frame > this.currentFrame) {
this.render(pos);
this.currentFrame = frame;
}
}
},
- render: function(pos) {
- if(this.state == 'idle') {
- this.state = 'running';
- this.event('beforeSetup');
- if(this.setup) this.setup();
- this.event('afterSetup');
- }
- 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.Queues.get(typeof this.options.queue == 'string' ?
@@ -356,7 +356,7 @@ Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
this.element = $(element);
if(!this.element) throw(Effect._elementDoesNotExistError);
// make this work on IE on elements without 'layout'
- if(/MSIE/.test(navigator.userAgent) && !window.opera && (!this.element.currentStyle.hasLayout))
+ if(Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
this.element.setStyle({zoom: 1});
var options = Object.extend({
from: this.element.getOpacity() || 0.0,
@@ -951,7 +951,7 @@ Object.extend(Object.extend(Effect.Morph.prototype, Effect.Base.prototype), {
effect.element.addClassName(effect.options.style);
effect.transforms.each(function(transform) {
if(transform.style != 'opacity')
- effect.element.style[transform.style.camelize()] = '';
+ effect.element.style[transform.style] = '';
});
}
} else this.style = options.style.parseStyle();
@@ -967,26 +967,28 @@ Object.extend(Object.extend(Effect.Morph.prototype, Effect.Base.prototype), {
});
}
this.transforms = this.style.map(function(pair){
- var property = pair[0].underscore().dasherize(), value = pair[1], unit = null;
+ 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(/MSIE/.test(navigator.userAgent) && !window.opera && (!this.element.currentStyle.hasLayout))
+ 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;
+ } 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 $H({
- style: 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) ||
@@ -998,17 +1000,19 @@ Object.extend(Object.extend(Effect.Morph.prototype, Effect.Base.prototype), {
});
},
update: function(position) {
- var style = $H(), value = null;
- this.transforms.each(function(transform){
- value = transform.unit=='color' ?
- $R(0,2).inject('#',function(m,v,i){
- return m+(Math.round(transform.originalValue[i]+
- (transform.targetValue[i] - transform.originalValue[i])*position)).toColorPart() }) :
+ 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 + Math.round(
((transform.targetValue - transform.originalValue) * position) * 1000)/1000 + transform.unit;
- style[transform.style] = value;
- });
- this.element.setStyle(style);
+ this.element.setStyle(style, true);
}
});
@@ -1055,14 +1059,14 @@ Element.CSS_PROPERTIES = $w(
Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
String.prototype.parseStyle = function(){
- var element = Element.extend(document.createElement('div'));
+ var element = document.createElement('div');
element.innerHTML = '<div style="' + this + '"></div>';
- var style = element.down().style, styleRules = $H();
+ var style = element.childNodes[0].style, styleRules = $H();
Element.CSS_PROPERTIES.each(function(property){
if(style[property]) styleRules[property] = style[property];
});
- if(/MSIE/.test(navigator.userAgent) && !window.opera && this.indexOf('opacity') > -1) {
+ if(Prototype.Browser.IE && this.indexOf('opacity') > -1) {
styleRules.opacity = this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1];
}
return styleRules;
@@ -1073,13 +1077,13 @@ Element.morph = function(element, style) {
return element;
};
-['setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom',
+['getInlineOpacity','forceRerendering','setContentZoom',
'collectTextNodes','collectTextNodesIgnoreClass','morph'].each(
function(f) { Element.Methods[f] = Element[f]; }
);
Element.Methods.visualEffect = function(element, effect, options) {
- s = effect.gsub(/_/, '-').camelize();
+ s = effect.dasherize().camelize();
effect_class = s.charAt(0).toUpperCase() + s.substring(1);
new Effect[effect_class](element, options);
return $(element);