Defines Fx.Reveal, a class that shows and hides elements with a transition.
Fx.Reveal = new Class({
Extends: Fx.Morph,
options: {/*
onShow: function(thisElement){},
onHide: function(thisElement){},
onComplete: function(thisElement){},
heightOverride: null,
widthOverride: null,*/
link: 'cancel',
styles: ['padding', 'border', 'margin'],
transitionOpacity: !Browser.ie6,
mode: 'vertical',
display: 'block',
opacity: 1,
hideInputs: Browser.ie ? 'select, input, textarea, object, embed' : null
},
dissolve: function(){
if (!this.hiding && !this.showing){
if (this.element.getStyle('display') != 'none'){
this.hiding = true;
this.showing = false;
this.hidden = true;
this.cssText = this.element.style.cssText;
var startStyles = this.element.getComputedSize({
styles: this.options.styles,
mode: this.options.mode
});
if (this.options.transitionOpacity) startStyles.opacity = this.options.opacity;
var zero = {};
Object.each(startStyles, function(style, name){
zero[name] = [style, 0];
});
this.element.setStyles({
display: this.options.display,
overflow: 'hidden'
});
var hideThese = this.options.hideInputs ? this.element.getElements(this.options.hideInputs) : null;
if (hideThese) hideThese.setStyle('visibility', 'hidden');
this.$chain.unshift(function(){
if (this.hidden){
this.hiding = false;
this.element.style.cssText = this.cssText;
this.element.setStyle('display', 'none');
if (hideThese) hideThese.setStyle('visibility', 'visible');
}
this.fireEvent('hide', this.element);
this.callChain();
}.bind(this));
this.start(zero);
} else {
this.callChain.delay(10, this);
this.fireEvent('complete', this.element);
this.fireEvent('hide', this.element);
}
} else if (this.options.link == 'chain'){
this.chain(this.dissolve.bind(this));
} else if (this.options.link == 'cancel' && !this.hiding){
this.cancel();
this.dissolve();
}
return this;
},
reveal: function(){
if (!this.showing && !this.hiding){
if (this.element.getStyle('display') == 'none' ||
this.element.getStyle('visiblity') == 'hidden' ||
this.element.getStyle('opacity') == 0){
this.hiding = false;
this.showing = true;
this.hidden = false;
this.cssText = this.element.style.cssText;
var startStyles;
this.element.measure(function(){
startStyles = this.element.getComputedSize({
styles: this.options.styles,
mode: this.options.mode
});
}.bind(this));
if (this.options.heightOverride != null) startStyles.height = this.options.heightOverride.toInt();
if (this.options.widthOverride != null) startStyles.width = this.options.widthOverride.toInt();
if (this.options.transitionOpacity){
this.element.setStyle('opacity', 0);
startStyles.opacity = this.options.opacity;
}
var zero = {
height: 0,
display: this.options.display
};
Object.each(startStyles, function(style, name){
zero[name] = 0;
});
zero.overflow = 'hidden';
this.element.setStyles(zero);
var hideThese = this.options.hideInputs ? this.element.getElements(this.options.hideInputs) : null;
if (hideThese) hideThese.setStyle('visibility', 'hidden');
this.$chain.unshift(function(){
this.element.style.cssText = this.cssText;
this.element.setStyle('display', this.options.display);
if (!this.hidden) this.showing = false;
if (hideThese) hideThese.setStyle('visibility', 'visible');
this.callChain();
this.fireEvent('show', this.element);
}.bind(this));
this.start(startStyles);
} else {
this.callChain();
this.fireEvent('complete', this.element);
this.fireEvent('show', this.element);
}
} else if (this.options.link == 'chain'){
this.chain(this.reveal.bind(this));
} else if (this.options.link == 'cancel' && !this.showing){
this.cancel();
this.reveal();
}
return this;
},
toggle: function(){
if (this.element.getStyle('display') == 'none' ||
this.element.getStyle('visiblity') == 'hidden' ||
this.element.getStyle('opacity') == 0){
this.reveal();
} else {
this.dissolve();
}
return this;
},
cancel: function(){
this.parent.apply(this, arguments);
this.element.style.cssText = this.cssText;
this.hiding = false;
this.showing = false;
}
});
Element.Properties.reveal = {
set: function(options){
this.get('reveal').cancel().setOptions(options);
return this;
},
get: function(){
var reveal = this.retrieve('reveal');
if (!reveal){
reveal = new Fx.Reveal(this);
this.store('reveal', reveal);
}
return reveal;
}
};
Element.Properties.dissolve = Element.Properties.reveal;
Element.implement({
reveal: function(options){
this.get('reveal').setOptions(options).reveal();
return this;
},
dissolve: function(options){
this.get('reveal').setOptions(options).dissolve();
return this;
},
nix: function(options){
var params = Array.link(arguments, {destroy: Boolean.type, options: Object.type});
this.get('reveal').setOptions(options).dissolve().chain(function(){
this[params.destroy ? 'destroy' : 'dispose']();
}.bind(this));
return this;
},
wink: function(){
var params = Array.link(arguments, {duration: Number.type, options: Object.type});
var reveal = this.get('reveal').setOptions(params.options);
reveal.reveal().chain(function(){
(function(){
reveal.dissolve();
}).delay(params.duration || 2000);
});
}
});