var is_IE6 = !window.XMLHttpRequest;
Lightbox = Class.create({
initialize: function( options ) {
this.options = Object.extend( {zIndex:50,opacity:0.5}, arguments[0] || {});
},
_make_shade: function() {
this.shade = new Element( 'div', {
'id': 'lightbox_shade',
'style': 'display:none;background-color:black;position:absolute;top:0px;left:0px;'
} );
this.shade.style.zIndex = this.options.zIndex;
document.body.appendChild( this.shade );
if( Prototype.Browser.IE )
this.blocking_iframe = new BlockingIframe( this.shade );
},
_make_visible: function() {
if ( !this.shade )
this._make_shade();
this.shade.style.width = Element.getWidth( document.body ) + "px";
this.shade.style.height = Element.getHeight( document.body ) + "px";
this.shade.setOpacity( this.options.opacity );
this.shade.style.display = '';
if( this.blocking_iframe )
this.blocking_iframe.update();
},
_make_invisible: function() {
if( this.shade ) {
this.shade.style.display = 'none';
if( this.blocking_iframe )
this.blocking_iframe.update();
}
},
show: function () {
var options = Object.extend({
before_show: function(){},
after_show: function(){}
}, arguments[0] || {});
options.before_show();
this._make_visible();
options.after_show();
},
hide: function() {
var options = Object.extend({
before_hide: function(){},
after_hide: function(){}
}, arguments[0] || {});
options.before_hide();
this._make_invisible();
options.after_hide();
}
});
BlockingIframe = Class.create( {
initialize: function( layer ) {
this.layer = layer;
},
attach: function( layer ) {
this.layer = layer;
Element.insert( this.layer,  { before: this.iframe } );
},
detach: function() {
Element.remove( this.iframe );
},
_make_iframe: function() {
this.iframe = document.createElement( "iframe" );
this.iframe.style.display = "none";
this.iframe.style.position = "absolute";
this.iframe.frameborder = "0";
this.iframe.style.backgroundColor = "transparent";
this.iframe.src="javascript:''";
this.iframe.style.filter='progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)';
this.attach( this.layer );
},
update: function() {
if ( !this.iframe )
this._make_iframe();
var size = Element.getDimensions( this.layer );
with( this.iframe ) {
style.left = this.layer.style.left;
style.top = this.layer.style.top;
style.width = size.width + "px";
style.height = size.height + "px";
style.zIndex = this.layer.style.zIndex - 1;
style.display = this.layer.style.display;
}
}
} );
Popup = Class.create( {
initialize: function( layer_id ) {
this.defaults = {
anchor_align: {
x: -1,
y: 1
},
popup_align: {
x: -1,
y: -1
},
link_event: 'click',
adjust_on_resize: true,
close_on_clickoff: false
};
this.options = Object.extend(this.defaults, arguments[1] || {});
this.layer = $(layer_id);
this.layer.style.zIndex = this.options.zIndex || '100';
this.layer.style.position = 'absolute';
this.layer.style.display = 'none';
if ( this.options.lightbox ) {
this.lightbox = new Lightbox( { zIndex: this.layer.style.zIndex - 1, opacity: this.options.lightbox.opacity } );
}
else if( Prototype.Browser.IE && !this.options.no_iframe )
this.blocking_iframe = new BlockingIframe( this.layer );
if ( this.options.drag_id )
this.setDrag( this.options.drag_id );
if ( this.options.close_id )
this.setClose( this.options.close_id );
this.links = {};
if( this.options.links )
this.addLinks( this.options.links );
Event.observe( window, 'resize', this._onResize.bind( this ), false );
},
_update_blocking_iframe: function( draggable ) {
if( this.blocking_iframe )
this.blocking_iframe.update();
},
_resetAutoHideTimer: function() {
if( this.hide_timeout ) {
clearTimeout( this.hide_timeout );
delete this.hide_timeout;
}
},
_startAutohideTimer: function() {
var link = this._buildOptions( arguments[0] );
this.hide_timeout = setTimeout( this._onAutoHide.bind( this ), link.autohide_timeout );
},
_onAutoHide: function() {
this.hide();
delete this.hide_timeout;
},
addLinks: function( links ) {
for( var i = 0 ; i < links.length ; i ++ ) {
var link = links[i];
var defaults = Object.extend( {}, this.defaults );
link = Object.extend( defaults, link );
var link_id = link.link_id;
var onLinkClick = this.show.bind(this, link);
Event.observe( $(link_id), link.link_event, onLinkClick );
link.onLinkClick = onLinkClick;
if( link.autohide_timeout ) {
link.onMouseOverLink = this._resetAutoHideTimer.bind(this);
Event.observe( $(link_id), 'mouseover', link.onMouseOverLink );
link.onMouseOverPopup = this._resetAutoHideTimer.bind(this);
Event.observe( this.layer, 'mouseover', link.onMouseOverPopup );
link.onMouseOutLink = this._startAutohideTimer.bind(this, link);
Event.observe( $(link_id), 'mouseout', link.onMouseOutLink );
link.onMouseOutPopup = this._startAutohideTimer.bind(this, link);
Event.observe( this.layer, 'mouseout', link.onMouseOutPopup );
}
this.links[link_id] = link;
}
},
removeLink: function( link_id ) {
var link = this.links[link_id];
Event.stopObserving( $(link.link_id), link.link_event, link.onLinkClick );
if( link.autohide_timeout ) {
Event.stopObserving( $(link_id), 'mouseover', link.onMouseOverLink );
Event.stopObserving( this.layer, 'mouseover', link.onMouseOverPopup );
Event.stopObserving( $(link_id), 'mouseout', link.onMouseOutLink );
Event.stopObserving( this.layer, 'mouseout', link.onMouseOutPopup );
}
delete this.links[link_id];
},
removeLinks: function() {
var link_ids;
if( arguments[0] )
link_ids = arguments[0];
else
link_ids = $H(this.links ).keys();
for( var i = 0 ; i < link_ids.length ; i ++ )
this.removeLink( link_ids[i] );
},
setDrag: function ( drag_id ) {
if ( typeof(drag_id) == 'string' )
drag_id = [ drag_id ];
for ( var i = 0 ; i < drag_id.length ; i ++ )
this.dragger = new Draggable( this.layer, {
handle: $(drag_id[i]),
change: this.on_drag.bind( this ),
endeffect: false
} );
},
on_drag: function() {
this._update_blocking_iframe();
},
setClose: function ( close_id ) {
if ( typeof(close_id) == 'string' )
close_id = [ close_id ];
for ( var i = 0 ; i < close_id.length ; i ++ ) {
$(close_id[i]).observe( 'click', this.hide.bind(this) );
}
},
moveTo: function( x, y ) {
this.layer.style.left = x + "px";
this.layer.style.top = y + "px";
this._update_blocking_iframe();
},
_onResize: function() {
if( this.options.adjust_on_resize && this.layer.style.display != "none" ) {
if( this.current_anchor ) {
var offset = this.current_anchor.cumulativeOffset();
var x = offset[0] - this.popup_anchor_offset.x;
var y = offset[1] - this.popup_anchor_offset.y;
x = x < 0 ? 0 : x;
y = y < 0 ? 0 : y;
this.moveTo( x, y );
}
}
},
_buildOptions: function() {
var options = {};
Object.extend( options, this.options );
Object.extend(
options,
arguments[0] || ( $H(this.links).keys().length ? this.links[$H(this.links).keys()[0]] : {} )
);
return options;
},
_checkClickOff: function( e ) {
var clicked = Event.element(e);
if (
(clicked == this.layer || !Element.descendantOf(clicked, this.layer)) &&
$H(this.links).keys().find(function (link) {
return clicked.id == link || Element.descendantOf(clicked, link);
}) == null
)
this.hide();
},
show: function() {
var anchor_options = this._buildOptions( arguments[0] );
if( anchor_options.onShow )
anchor_options.onShow( this );
if ( anchor_options.toggle && !this.layer.style.display ) {
this.hide();
return;
}
var anchor_id = anchor_options.anchor_id || anchor_options.link_id;
var anchor = $( anchor_id );
if( anchor ) {
if( this.layer.style.display == "none" ) {
this.moveTo( -1200, -1200 );
this.layer.style.display = "";
}
if ( this.lightbox )
this.lightbox.show({ after_show: this.update_position.bind( this, anchor_options ) });
else
this.update_position( anchor_options );
if ( anchor_options.close_on_clickoff ) {
this.click_off_initial = true;
this.click_off_callback = this._checkClickOff.bindAsEventListener( this );
Event.observe(document.body, 'click', this.click_off_callback);
}
}
if ( anchor_options.fixed_position ) {
this.fix_position_handler = this.fix_position.bind( this, anchor_options );
Event.observe( window, 'scroll', this.fix_position_handler );
Event.observe( window, 'resize', this.fix_position_handler );
}
},
update_position: function( anchor_options ) {
var anchor_id = anchor_options.anchor_id || anchor_options.link_id;
var anchor = $( anchor_id );
if ( anchor ) {
var offset = anchor.cumulativeOffset();
this.current_anchor = anchor;
this.anchor_offset = offset;
this.popup_anchor_offset = { x: offset[0], y: offset[1] };
var popup_align = anchor_options.popup_align;
if ( popup_align ) {
var anchor_align = anchor_options.anchor_align;
if ( popup_align.x == 'center' ) {
offset[0] = Math.round(document.viewport.getScrollOffsets().left +
((document.viewport.getWidth() - this.layer.getWidth()))/2);
}
else if ( anchor_align ) {
if( anchor_align.x > -1 ) {
offset[0] += anchor.offsetWidth / ( anchor_align.x ? 1 : 2 );
}
if( popup_align.x > -1 ) {
offset[0] -= this.layer.offsetWidth / ( popup_align.x ? 1 : 2 );
}
}
if ( popup_align.y == 'center' ) {
offset[1] = Math.round(document.viewport.getScrollOffsets().top +
((document.viewport.getHeight() - this.layer.getHeight()))/2);
}
else if ( anchor_align ) {
if( anchor_align.y > -1 ) {
offset[1] += anchor.offsetHeight / ( anchor_align.y ? 1 : 2 );
}
if( popup_align.y > -1 ) {
offset[1] -= this.layer.offsetHeight / ( popup_align.y ? 1 : 2 );
}
}
}
if ( anchor_options.offset ) {
offset[0] += anchor_options.offset.x;
offset[1] += anchor_options.offset.y;
}
var fixed = anchor_options.fixed_position;
var constrain = anchor_options.constrain;
var viewport = document.viewport;
var upper_left = viewport.getScrollOffsets();
if ( constrain ) {
fixed = false;
var lower_right = [ upper_left[0] + viewport.getWidth(), upper_left[1] + viewport.getHeight() ];
if ( typeof(constrain.top) != 'undefined' ) {
if ( (offset[1] - constrain.top) < upper_left[1] ) {
offset[1] = upper_left[1] + constrain.top;
fixed = true;
}
}
if ( typeof(constrain.right) != 'undefined' ) {
if ( (offset[0] + this.layer.offsetWidth - constrain.right) > lower_right[0] ) {
offset[0] = lower_right[0] - this.layer.offsetWidth + constrain.right;
fixed = true;
}
}
if ( typeof(constrain.bottom) != 'undefined' ) {
if ( (offset[1] + this.layer.offsetHeight - constrain.bottom) > lower_right[1] ) {
offset[1] = lower_right[1] - this.layer.offsetHeight + constrain.bottom;
fixed = true;
}
}
if ( typeof(constrain.left) != 'undefined' ) {
if ( (offset[0] - constrain.left) < upper_left[0] ) {
offset[0] = upper_left[0] + constrain.left;
fixed = true;
}
}
}
if ( fixed && !is_IE6 ) {
offset[0] -= upper_left[0];
offset[1] -= upper_left[1];
this.layer.style.position = 'fixed';
}
else {
this.layer.style.position = 'absolute';
}
this.moveTo( offset[0], offset[1] );
this.popup_anchor_offset.x -= offset[0];
this.popup_anchor_offset.y -= offset[1];
}
},
fix_position: function ( anchor_options ) {
this.update_position( anchor_options);
},
hide: function() {
this.layer.style.display = "none";
this._update_blocking_iframe();
var options = this._buildOptions( arguments[0] );
if( options.onHide )
options.onHide( this );
if ( this.lightbox ) {
this.lightbox.hide();
}
if ( this.click_off_callback != null )
Event.stopObserving(document.body, 'click', this.click_off_callback);
if ( this.fix_position_handler ) {
Event.stopObserving( window, 'scroll', this.fix_position_handler );
Event.stopObserving( window, 'resize', this.fix_position_handler );
delete this.fix_position_handler;
}
}
} );
