/* * nyroModal - jQuery Plugin * http://nyromodal.nyrodev.com * * Copyright (c) 2008 Cedric Nirousset (nyrodev.com) * Licensed under the MIT license * * $Date: 2009-05-14 (Thu, 14 May 2009) $ * $version: 1.5.0 */jQuery(function($) {	// -------------------------------------------------------	// Private Variables	// -------------------------------------------------------	var userAgent = navigator.userAgent.toLowerCase();	//var browserVersion = (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1];	var browserVersion = (userAgent.match(/.+(?:rv|webkit|khtml|opera|msie)[\/: ]([\d.]+)/ ) || [0,'0'])[1];	var isIE6 = (/msie/.test(userAgent) && !/opera/.test(userAgent) && parseInt(browserVersion) < 7 && !window.XMLHttpRequest);	var body = $('body');	var currentSettings;	var shouldResize = false;		var gallery = {};	// To know if the fix for the Issue 10 should be applied (or has been applied)	var fixFF = false;	// Used for retrieve the content from an hidden div	var contentElt;	var contentEltLast;	// Contains info about nyroModal state and all div references	var modal = {		started: false,		ready: false,		dataReady: false,		anim: false,		animContent: false,		loadingShown: false,		transition: false,		resizing: false,		closing: false,		error: false,		blocker: null,		blockerVars: null,		full: null,		bg: null,		loading: null,		tmp: null,		content: null,		wrapper: null,		contentWrapper: null,		scripts: new Array(),		scriptsShown: new Array()	};	// Indicate of the height or the width was resized, to reinit the currentsettings related to null	var resized = {		width: false,		height: false,		windowResizing: false	};		var initSettingsSize = {		width: null,		height: null,		windowResizing: true	};		var windowResizeTimeout;	// -------------------------------------------------------	// Public function	// -------------------------------------------------------	// jQuery extension function. A paramater object could be used to overwrite the default settings	$.fn.nyroModal = function(settings) {		if (!this)			return false;		return this.each(function() {			var me = $(this);			if (this.nodeName.toLowerCase() == 'form') {				me				.unbind('submit.nyroModal')				.bind('submit.nyroModal', function(e) {					if (me.data('nyroModalprocessing'))						return true;					if (this.enctype == 'multipart/form-data') {						processModal($.extend(settings, {							from: this						}));						return true;					}					e.preventDefault();					processModal($.extend(settings, {						from: this					}));					return false;				});			} else {				me				.unbind('click.nyroModal')				.bind('click.nyroModal', function(e) {					e.preventDefault();					processModal($.extend(settings, {						from: this					}));					return false;				});			}		});	};	// jQuery extension function to call manually the modal. A paramater object could be used to overwrite the default settings	$.fn.nyroModalManual = function(settings) {		if (!this.length)			processModal(settings);		return this.each(function(){			processModal($.extend(settings, {				from: this			}));		});	};	$.nyroModalManual = function(settings) {		processModal(settings);	};	// Update the current settings	// object settings	// string deep1 first key where overwrite the settings	// string deep2 second key where overwrite the settings	$.nyroModalSettings = function(settings, deep1, deep2) {		setCurrentSettings(settings, deep1, deep2);		if (!deep1 && modal.started) {			if (modal.bg && settings.bgColor)				currentSettings.updateBgColor(modal, currentSettings, function(){});			if (modal.contentWrapper && settings.title)				setTitle();			if (!modal.error && (settings.windowResizing || (!modal.resizing && (('width' in settings && settings.width == currentSettings.width) || ('height' in settings && settings.height == currentSettings.height))))) {				modal.resizing = true;				if (modal.contentWrapper)					calculateSize(true);				if (modal.contentWrapper && modal.contentWrapper.is(':visible') && !modal.animContent) {					if (fixFF)						modal.content.css({position: ''});					currentSettings.resize(modal, currentSettings, function() {						currentSettings.windowResizing = false;						modal.resizing = false;						if (fixFF)							modal.content.css({position: 'fixed'});						if ($.isFunction(currentSettings.endResize))							currentSettings.endResize(modal, currentSettings);					});				}			}		}	};	// Remove the modal function	$.nyroModalRemove = function() {		removeModal();	};	// Go to the next image for a gallery	// return false if nothing was done	$.nyroModalNext = function() {		var link = getGalleryLink(1);		if (link)			return link.nyroModalManual(getCurrentSettingsNew());		return false;	};	// Go to the previous image for a gallery	// return false if nothing was done	$.nyroModalPrev = function() {		var link = getGalleryLink(-1);		if (link)			return link.nyroModalManual(getCurrentSettingsNew());		return false;	};	// -------------------------------------------------------	// Default Settings	// -------------------------------------------------------	$.fn.nyroModal.settings = {		debug: false, // Show the debug in the background		blocker: false, // Element which will be blocked by the modal		modal: false, // Esc key or click backgrdound enabling or not		type: '', // nyroModal type (form, formData, iframe, image, etc...)		from: '', // Dom object where the call come from		hash: '', // Eventual hash in the url		processHandler: null, // Handler just before the real process		selIndicator: 'nyroModalSel', // Value added when a form or Ajax is sent with a filter content		formIndicator: 'nyroModal', // Value added when a form is sent		content: null, // Raw content if type content is used		bgColor: '#000000', // Background color		ajax: {}, // Ajax option (url, data, type, success will be overwritten for a form, url and success only for an ajax call)		swf: { // Swf player options if swf type is used.			wmode: 'transparent'		},		width: null, // default Width If null, will be calculate automatically		height: null, // default Height If null, will be calculate automatically		minWidth: 400, // Minimum width		minHeight: 300, // Minimum height		resizable: true, // Indicate if the content is resizable. Will be set to false for swf		autoSizable: true, // Indicate if the content is auto sizable. If not, the min size will be used		padding: 25, // padding for the max modal size		regexImg: '[^\.]\.(jpg|jpeg|png|tiff|gif|bmp)\s*$', // Regex to find img		addImageDivTitle: true, // Indicate if the div title should be inserted		defaultImgAlt: 'Image', // Default alt attribute for the img		setWidthImgTitle: true, // Set the width to the image title		ltr: true, // Left to Right by default. Put to false for Hebrew or Right to Left language		gallery: null, // Gallery name if provided		galleryLinks: '<a href="/#" class="nyroModalPrev">Prev</a><a href="/#"  class="nyroModalNext">Next</a>', // Use .nyroModalPrev and .nyroModalNext to set the navigation link		galleryCounts: galleryCounts, // Callback to show the gallery count				zIndexStart: 100,		css: { // Default CSS option for the nyroModal Div. Some will be overwritten or updated when using IE6			bg: {				position: 'absolute',				overflow: 'hidden',				top: 0,				left: 0,				height: '100%',				width: '100%'			},			wrapper: {				position: 'absolute',				top: '50%',				left: '50%'			},			wrapper2: {			},			content: {				overflow: 'auto'			},			loading: {				position: 'absolute',				top: '50%',				left: '50%',				marginTop: '-50px',				marginLeft: '-50px'			}		},		wrap: { // Wrapper div used to style the modal regarding the content type			div: '<div class="wrapper"></div>',			ajax: '<div class="wrapper"></div>',			form: '<div class="wrapper"></div>',			formData: '<div class="wrapper"></div>',			image: '<div class="wrapperImg"></div>',			swf: '<div class="wrapperSwf"></div>',			iframe: '<div class="wrapperIframe"></div>',			iframeForm: '<div class="wrapperIframe"></div>',			manual: '<div class="wrapper"></div>'		},		closeButton: '<a href="/#" class="nyroModalClose" id="closeBut" title="close">Close</a>', // Adding automaticly as the first child of #nyroModalWrapper		title: null, // Modal title		titleFromIframe: true, // When using iframe in the same domain, try to get the title from it		openSelector: '.nyroModal', // selector for open a new modal. will be used to parse automaticly at page loading		closeSelector: '.nyroModalClose', // selector to close the modal		contentLoading: '<a href="/#" class="nyroModalClose">Cancel</a>', // Loading div content		errorClass: 'error', // CSS Error class added to the loading div in case of error		contentError: 'The requested content cannot be loaded.<br />Please try again later.<br /><a href="/#" class="nyroModalClose">Close</a>', // Content placed in the loading div in case of error		handleError: null, // Callback in case of error		showBackground: showBackground, // Show background animation function		hideBackground: hideBackground, // Hide background animation function		endFillContent: null, // Will be called after filling and wraping the content, before parsing closeSelector and openSelector and showing the content		showContent: showContent, // Show content animation function		endShowContent: null, // Will be called once the content is shown		beforeHideContent: null, // Will be called just before the modal closing		hideContent: hideContent, // Hide content animation function		showTransition: showTransition, // Show the transition animation (a modal is already shown and a new one is requested)		hideTransition: hideTransition, // Hide the transition animation to show the content		showLoading: showLoading, // show loading animation function		hideLoading: hideLoading, // hide loading animation function		resize: resize, // Resize animation function		endResize: null, // Will be called one the content is resized		updateBgColor: updateBgColor, // Change background color animation function		endRemove: null // Will be called once the modal is totally gone	};	// -------------------------------------------------------	// Private function	// -------------------------------------------------------	// Main function	function processModal(settings) {		if (modal.loadingShown || modal.transition || modal.anim)			return;		debug('processModal');		modal.started = true;		setDefaultCurrentSettings(settings);		if (!modal.full)			modal.blockerVars = modal.blocker = null;		modal.error = false;		modal.closing = false;		modal.dataReady = false;		modal.scripts = new Array();		modal.scriptsShown = new Array();		currentSettings.type = fileType();		if ($.isFunction(currentSettings.processHandler))			currentSettings.processHandler(currentSettings);		from = currentSettings.from;		url = currentSettings.url;		initSettingsSize.width = currentSettings.width;		initSettingsSize.height = currentSettings.height;		if (currentSettings.type == 'swf') {			// Swf is transforming as a raw content			setCurrentSettings({overflow: 'hidden'}, 'css', 'content');			currentSettings.content = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="'+currentSettings.width+'" height="'+currentSettings.height+'"><param name="movie" value="'+url+'"></param>';			var tmp = '';			$.each(currentSettings.swf, function(name, val) {				currentSettings.content+= '<param name="'+name+'" value="'+val+'"></param>';				tmp+= ' '+name+'="'+val+'"';			});			currentSettings.content+= '<embed src="'+url+'" type="application/x-shockwave-flash" width="'+currentSettings.width+'" height="'+currentSettings.height+'"'+tmp+'></embed></object>';		}		if (from) {			var jFrom = $(from);			if (currentSettings.type == 'form') {				var data = $(from).serializeArray();				data.push({name: currentSettings.formIndicator, value: 1});				if (currentSettings.selector)					data.push({name: currentSettings.selIndicator, value: currentSettings.selector.substring(1)});				$.ajax($.extend({}, currentSettings.ajax, {						url: url,						data: data,						type: jFrom.attr('method') ? jFrom.attr('method') : 'get',						success: ajaxLoaded,						error: loadingError					}));				debug('Form Ajax Load: '+jFrom.attr('action'));				showModal();			} else if (currentSettings.type == 'formData') {				// Form with data. We're using a hidden iframe				initModal();				jFrom.attr('target', 'nyroModalIframe');				jFrom.attr('action', url);				jFrom.prepend('<input type="hidden" name="'+currentSettings.formIndicator+'" value="1" />');				if (currentSettings.selector)					jFrom.prepend('<input type="hidden" name="'+currentSettings.selIndicator+'" value="'+currentSettings.selector.substring(1)+'" />');				modal.tmp.html('<iframe frameborder="0" hspace="0" name="nyroModalIframe" src="javascript:false;"></iframe>');				$('iframe', modal.tmp)					.css({						width: currentSettings.width,						height: currentSettings.height					})					.error(loadingError)					.load(formDataLoaded);				debug('Form Data Load: '+jFrom.attr('action'));				showModal();				showContentOrLoading();			} else if (currentSettings.type == 'image') {				debug('Image Load: '+url);				var title = jFrom.attr('title') || currentSettings.defaultImgAlt;				initModal();				modal.tmp.html('<img id="nyroModalImg" />').find('img').attr('alt', title);				modal.tmp.css({lineHeight: 0});				$('img', modal.tmp)					.error(loadingError)					.load(function() {						debug('Image Loaded: '+this.src);						$(this).unbind('load');						var w = modal.tmp.width();						var h = modal.tmp.height();						modal.tmp.css({lineHeight: ''});						resized.width = w;						resized.height = h;						setCurrentSettings({							width: w,							height: h,							imgWidth: w,							imgHeight: h						});						initSettingsSize.width = w;						initSettingsSize.height = h;						setCurrentSettings({overflow: 'hidden'}, 'css', 'content');						modal.dataReady = true;						if (modal.loadingShown || modal.transition)							showContentOrLoading();					})					.attr('src', url);				showModal();			} else if (currentSettings.type == 'iframeForm') {				initModal();				modal.tmp.html('<iframe frameborder="0" hspace="0" src="javascript:false;" name="nyroModalIframe" id="nyroModalIframe"></iframe>');				debug('Iframe Form Load: '+url);				$('iframe', modal.tmp).eq(0)					.css({						width: '100%',						height: $.support.boxModel? '99%' : '100%'					})					.load(function(e) {						if (currentSettings.titleFromIframe && url.indexOf(window.location.hostname) > -1)							$.nyroModalSettings({title: $('iframe', modal.full).contents().find('title').text()});					});				modal.dataReady = true;				showModal();			} else if (currentSettings.type == 'iframe') {				initModal();				modal.tmp.html('<iframe frameborder="0" hspace="0" src="'+url+'" name="nyroModalIframe" id="nyroModalIframe"></iframe>');				debug('Iframe Load: '+url);				$('iframe', modal.tmp).eq(0)					.css({						width: '100%',						height: $.support.boxModel? '99%' : '100%'					})					.load(function(e) {						if (currentSettings.titleFromIframe && url.indexOf(window.location.hostname) > -1)							$.nyroModalSettings({title: $('iframe', modal.full).contents().find('title').text()});					});				modal.dataReady = true;				showModal();			} else if (currentSettings.type) {				// Could be every other kind of type or a dom selector				debug('Content: '+currentSettings.type);				initModal();				modal.tmp.html(currentSettings.content);				var w = modal.tmp.width();				var h = modal.tmp.height();				var div = $(currentSettings.type);				if (div.length) {					setCurrentSettings({type: 'div'});					w = div.width();					h = div.height();					if (contentElt)						contentEltLast = contentElt;					contentElt = div;					modal.tmp.append(div.contents());				}				initSettingsSize.width = w;				initSettingsSize.height = h;				setCurrentSettings({					width: w,					height: h				});				if (modal.tmp.html())					modal.dataReady = true;				else					loadingError();				if (!modal.ready)					showModal();				else					endHideContent();			} else {				debug('Ajax Load: '+url);				setCurrentSettings({type: 'ajax'});				var data = currentSettings.ajax.data || {};				if (currentSettings.selector) {					if (typeof data == "string") {						data+= '&'+currentSettings.selIndicator+'='+currentSettings.selector.substring(1);					} else {						data[currentSettings.selIndicator] = currentSettings.selector.substring(1);					}				}				$.ajax($.extend(true, currentSettings.ajax, {					url: url,					success: ajaxLoaded,					error: loadingError,					data: data				}));				showModal();			}		} else if (currentSettings.content) {			// Raw content not from a DOM element			debug('Content: '+currentSettings.type);			setCurrentSettings({type: 'manual'});			initModal();			modal.tmp.html($('<div/>').html(currentSettings.content).contents());			if (modal.tmp.html())				modal.dataReady = true;			else				loadingError();			showModal();		} else {			// What should we show here? nothing happen		}	}	// Update the current settings	// object settings	// string deep1 first key where overwrite the settings	// string deep2 second key where overwrite the settings	function setDefaultCurrentSettings(settings) {		debug('setDefaultCurrentSettings');		currentSettings = $.extend(true, {}, $.fn.nyroModal.settings, settings);		currentSettings.selector = '';		currentSettings.borderW = 0;		currentSettings.borderH = 0;		currentSettings.resizable = true;		setMargin();	}	function setCurrentSettings(settings, deep1, deep2) {		if (modal.started) {			if (deep1 && deep2) {				$.extend(true, currentSettings[deep1][deep2], settings);			} else if (deep1) {				$.extend(true, currentSettings[deep1], settings);			} else {				if (modal.animContent) {					if ('width' in settings) {						if (!modal.resizing) {							settings.setWidth = settings.width;							shouldResize = true;						}						delete settings['width'];					}					if ('height' in settings) {						if (!modal.resizing) {							settings.setHeight = settings.height;							shouldResize = true;						}						delete settings['height'];					}				}				$.extend(true, currentSettings, settings);			}		} else {			if (deep1 && deep2) {				$.extend(true, $.fn.nyroModal.settings[deep1][deep2], settings);			} else if (deep1) {				$.extend(true, $.fn.nyroModal.settings[deep1], settings);			} else {				$.extend(true, $.fn.nyroModal.settings, settings);			}		}	}	// Set the margin for postionning the element. Useful for IE6	function setMarginScroll() {		if (isIE6 && !modal.blocker) {			if (document.documentElement) {				currentSettings.marginScrollLeft = document.documentElement.scrollLeft;				currentSettings.marginScrollTop = document.documentElement.scrollTop;			} else {				currentSettings.marginScrollLeft = document.body.scrollLeft;				currentSettings.marginScrollTop = document.body.scrollTop;			}		} else {			currentSettings.marginScrollLeft = 0;			currentSettings.marginScrollTop = 0;		}	}	// Set the margin for the content	function setMargin() {		setMarginScroll();		currentSettings.marginLeft = -(currentSettings.width+currentSettings.borderW)/2;		currentSettings.marginTop = -(currentSettings.height+currentSettings.borderH)/2;		if (!modal.blocker) {			currentSettings.marginLeft+= currentSettings.marginScrollLeft;			currentSettings.marginTop+= currentSettings.marginScrollTop;		}	}	// Set the margin for the current loading	function setMarginLoading() {		setMarginScroll();		var outer = getOuter(modal.loading);		currentSettings.marginTopLoading = -(modal.loading.height() + outer.h.border + outer.h.padding)/2;		currentSettings.marginLeftLoading = -(modal.loading.width() + outer.w.border + outer.w.padding)/2;		if (!modal.blocker) {			currentSettings.marginLefttLoading+= currentSettings.marginScrollLeft;			currentSettings.marginTopLoading+= currentSettings.marginScrollTop;		}	}	// Set the modal Title	function setTitle() {		var title = $('h1#nyroModalTitle', modal.contentWrapper);		if (title.length)			title.text(currentSettings.title);		else			modal.contentWrapper.prepend('<h1 id="nyroModalTitle">'+currentSettings.title+'</h1>');	}	// Init the nyroModal div by settings the CSS elements and hide needed elements	function initModal() {		debug('initModal');		if (!modal.full) {			if (currentSettings.debug)				setCurrentSettings({color: 'white'}, 'css', 'bg');			var full = {				zIndex: currentSettings.zIndexStart,				position: 'fixed',				top: 0,				left: 0,				width: '100%',				height: '100%'			};			var contain = body;			var iframeHideIE = '';			if (currentSettings.blocker) {				modal.blocker = contain = $(currentSettings.blocker);				var pos = modal.blocker.offset();				var w = modal.blocker.outerWidth();				var h = modal.blocker.outerHeight();				if (isIE6) {					setCurrentSettings({						height: '100%',						width: '100%',						top: 0,						left: 0					}, 'css', 'bg');				}				modal.blockerVars = {					top: pos.top,					left: pos.left,					width: w,					height: h				};				var plusTop = (/msie/.test(userAgent) ?0:getCurCSS(body.get(0), 'borderTopWidth'));				var plusLeft = (/msie/.test(userAgent) ?0:getCurCSS(body.get(0), 'borderLeftWidth'));				full = {					position: 'absolute',					top: pos.top + plusTop,					left: pos.left + plusLeft,					width: w,					height: h				};			} else if (isIE6) {				body.css({					height: body.height()+'px',					width: body.width()+'px',					position: 'static',					overflow: 'hidden'				});				$('html').css({overflow: 'hidden'});				setCurrentSettings({					css: {						bg: {							position: 'absolute',							zIndex: currentSettings.zIndexStart+1,							height: '110%',							width: '110%',							top: currentSettings.marginScrollTop+'px',							left: currentSettings.marginScrollLeft+'px'						},						wrapper: { zIndex: currentSettings.zIndexStart+2 },						loading: { zIndex: currentSettings.zIndexStart+3 }					}				});				iframeHideIE = $('<iframe id="nyroModalIframeHideIe"></iframe>')								.css($.extend({},									currentSettings.css.bg, {										opacity: 0,										zIndex: 50,										border: 'none'									}));			}			contain.append($('<div id="nyroModalFull"><div id="nyroModalBg"></div><div id="nyroModalWrapper"><div id="nyroModalContent"></div></div><div id="nyrModalTmp"></div><div id="nyroModalLoading"></div></div>').hide());			modal.full = $('#nyroModalFull')				.css(full)				.show();			modal.bg = $('#nyroModalBg')				.css($.extend({						backgroundColor: currentSettings.bgColor					}, currentSettings.css.bg))				.before(iframeHideIE);			if (!currentSettings.modal)				modal.bg.click(removeModal);			modal.loading = $('#nyroModalLoading')				.css(currentSettings.css.loading)				.hide();			modal.contentWrapper = $('#nyroModalWrapper')				.css(currentSettings.css.wrapper)				.hide();			modal.content = $('#nyroModalContent');			modal.tmp = $('#nyrModalTmp').hide();			// To stop the mousewheel if the the plugin is available			if ($.isFunction($.fn.mousewheel)) {				modal.content.mousewheel(function(e, d) {					var elt = modal.content.get(0);					if ((d > 0 && elt.scrollTop == 0) ||							(d < 0 && elt.scrollHeight - elt.scrollTop == elt.clientHeight)) {						e.preventDefault();						e.stopPropagation();					}				});			}			$(document).bind('keydown.nyroModal', keyHandler);			modal.content.css({width: 'auto', height: 'auto'});			modal.contentWrapper.css({width: 'auto', height: 'auto'});						if (!currentSettings.blocker) {				$(window).bind('resize.nyroModal', function() {					window.clearTimeout(windowResizeTimeout);					windowResizeTimeout = window.setTimeout(windowResizeHandler, 200);				});			}		}	}		function windowResizeHandler() {		$.nyroModalSettings(initSettingsSize);	}	// Show the modal (ie: the background and then the loading if needed or the content directly)	function showModal() {		debug('showModal');		if (!modal.ready) {			initModal();			modal.anim = true;			currentSettings.showBackground(modal, currentSettings, endBackground);		} else {			modal.anim = true;			modal.transition = true;			currentSettings.showTransition(modal, currentSettings, function(){endHideContent();modal.anim=false;showContentOrLoading();});		}	}	// Used for the escape key or the arrow in the gallery type	function keyHandler(e) {		if (e.keyCode == 27) {			if (!currentSettings.modal)				removeModal();		} else if (currentSettings.gallery && modal.ready && modal.dataReady && !modal.anim && !modal.transition) {			if (e.keyCode == 39 || e.keyCode == 40) {				e.preventDefault();				$.nyroModalNext();				return false;			} else if (e.keyCode == 37 || e.keyCode == 38) {				e.preventDefault();				$.nyroModalPrev();				return false;			}		}	}	// Determine the filetype regarding the link DOM element	function fileType() {		if (currentSettings.forceType) {			var tmp = currentSettings.forceType;			if (!currentSettings.content)				currentSettings.from = true;			currentSettings.forceType = null;			return tmp;		}		var from = currentSettings.from;		var url;		if (from && from.nodeName) {			var jFrom = $(from);						url = jFrom.attr(from.nodeName.toLowerCase() == 'form' ? 'action' : 'href');			if (!url)				url = location.href.substring(window.location.host.length+7);			currentSettings.url = url;			if (jFrom.attr('rev') == 'modal')				currentSettings.modal = true;			currentSettings.title = jFrom.attr('title');			if (from && from.rel && from.rel.toLowerCase() != 'nofollow')				currentSettings.gallery = from.rel;			var imgType = imageType(url, from);			if (imgType)				return imgType;						if (isSwf(url))				return 'swf';			var iframe = false;			if (from.target && from.target.toLowerCase() == '_blank' || (from.hostname && from.hostname.replace(/:\d*$/,'') != window.location.hostname.replace(/:\d*$/,''))) {				iframe = true;			}			if (from.nodeName.toLowerCase() == 'form') {				if (iframe)					return 'iframeForm';				setCurrentSettings(extractUrlSel(url));				if (jFrom.attr('enctype') == 'multipart/form-data')					return 'formData';				return 'form';			}			if (iframe)				return 'iframe';		} else {			url = currentSettings.url;			if (!currentSettings.content)				currentSettings.from = true;			if (!url)				return null;							if (isSwf(url))				return 'swf';			var reg1 = new RegExp("^http://", "g");			if (url.match(reg1))				return 'iframe';		}		var imgType = imageType(url, from);		if (imgType)			return imgType;		var tmp = extractUrlSel(url);		setCurrentSettings(tmp);		if (!tmp.url)			return tmp.selector;	}	function imageType(url, from) {		var image = new RegExp(currentSettings.regexImg, 'i');		if (image.test(url)) {			return 'image';		}	}		function isSwf(url) {		var swf = new RegExp('[^\.]\.(swf)\s*$', 'i');		return swf.test(url);	}	function extractUrlSel(url) {		var ret = {			url: null,			selector: null		};		if (url) {			var hash = getHash(url);			var hashLoc = getHash(window.location.href);			var curLoc = window.location.href.substring(0, window.location.href.length - hashLoc.length);			var req = url.substring(0, url.length - hash.length);			if (req == curLoc) {				ret.selector = hash;			} else {				ret.url = req;				ret.selector = hash;			}		}		return ret;	}	// Called when the content cannot be loaded or tiemout reached	function loadingError() {		debug('loadingError');		modal.error = true;		if (!modal.ready)			return;		if ($.isFunction(currentSettings.handleError))			currentSettings.handleError(modal, currentSettings);		modal.loading			.addClass(currentSettings.errorClass)			.html(currentSettings.contentError);		$(currentSettings.closeSelector, modal.loading)			.unbind('click.nyroModal')			.bind('click.nyroModal', removeModal);		setMarginLoading();		modal.loading			.css({				marginTop: currentSettings.marginTopLoading+'px',				marginLeft: currentSettings.marginLeftLoading+'px'			});	}	// Put the content from modal.tmp to modal.content	function fillContent() {		debug('fillContent');		if (!modal.tmp.html())			return;		modal.content.html(modal.tmp.contents());		modal.tmp.empty();		wrapContent();		if (currentSettings.type == 'iframeForm') {			$(currentSettings.from)				.attr('target', 'nyroModalIframe')				.data('nyroModalprocessing', 1)				.submit()				.attr('target', '_blank')				.removeData('nyroModalprocessing');		}				if (!currentSettings.modal)			modal.wrapper.prepend(currentSettings.closeButton);						if ($.isFunction(currentSettings.endFillContent))			currentSettings.endFillContent(modal, currentSettings);		modal.content.append(modal.scripts);		$(currentSettings.closeSelector, modal.contentWrapper)			.unbind('click.nyroModal')			.bind('click.nyroModal', removeModal);		$(currentSettings.openSelector, modal.contentWrapper).nyroModal(getCurrentSettingsNew());	}	// Get the current settings to be used in new links	function getCurrentSettingsNew() {		var currentSettingsNew = $.extend(true, {}, currentSettings);		if (resized.width)			currentSettingsNew.width = null;		else			currentSettingsNew.width = initSettingsSize.width;		if (resized.height)			currentSettingsNew.height = null;		else			currentSettingsNew.height = initSettingsSize.height;		currentSettingsNew.css.content.overflow = 'auto';		return currentSettingsNew;	}	// Wrap the content and update the modal size if needed	function wrapContent() {		debug('wrapContent');		var wrap = $(currentSettings.wrap[currentSettings.type]);		modal.content.append(wrap.children().remove());		modal.contentWrapper.wrapInner(wrap);		if (currentSettings.gallery) {			// Set the action for the next and prev button (or remove them)			modal.content.append(currentSettings.galleryLinks);						gallery.links = $('[rel="'+currentSettings.gallery+'"]');			gallery.index = gallery.links.index(currentSettings.from);						if (currentSettings.galleryCounts && $.isFunction(currentSettings.galleryCounts))				currentSettings.galleryCounts(gallery.index + 1, gallery.links.length, modal, currentSettings);			var currentSettingsNew = getCurrentSettingsNew();			var linkPrev = getGalleryLink(-1);			if (linkPrev) {				var prev = $('.nyroModalPrev', modal.contentWrapper)					.attr('href', linkPrev.attr('href'))					.click(function(e) {						e.preventDefault();						$.nyroModalPrev();						return false;					});				if (isIE6 && currentSettings.type == 'swf') {					prev.before($('<iframe id="nyroModalIframeHideIeGalleryPrev"></iframe>').css({											position: prev.css('position'),											top: prev.css('top'),											left: prev.css('left'),											width: prev.width(),											height: prev.height(),											opacity: 0,											border: 'none'										}));				}			} else {				$('.nyroModalPrev', modal.contentWrapper).remove();			}			var linkNext = getGalleryLink(1);			if (linkNext) {				var next = $('.nyroModalNext', modal.contentWrapper)					.attr('href', linkNext.attr('href'))					.click(function(e) {						e.preventDefault();						$.nyroModalNext();						return false;					});				if (isIE6 && currentSettings.type == 'swf') {					next.before($('<iframe id="nyroModalIframeHideIeGalleryNext"></iframe>')									.css($.extend({}, {											position: next.css('position'),											top: next.css('top'),											left: next.css('left'),											width: next.width(),											height: next.height(),											opacity: 0,											border: 'none'										})));				}			} else {				$('.nyroModalNext', modal.contentWrapper).remove();			}		}				calculateSize();	}		function getGalleryLink(dir) {		if (currentSettings.gallery) {			if (!currentSettings.ltr)				dir *= -1;			var index = gallery.index + dir;			if (index >= 0 && index < gallery.links.length)				return gallery.links.eq(index);		}		return false;	}	// Calculate the size for the contentWrapper	function calculateSize(resizing) {		debug('calculateSize');		modal.wrapper = modal.contentWrapper.children('div:first');		resized.width = false;		resized.height = false;		if (false && !currentSettings.windowResizing) {			initSettingsSize.width = currentSettings.width;			initSettingsSize.height = currentSettings.height;		}				if (currentSettings.autoSizable && (!currentSettings.width || !currentSettings.height)) {			modal.contentWrapper				.css({					opacity: 0,					width: 'auto',					height: 'auto'				})				.show();			var tmp = {				width: 'auto',				height: 'auto'			};			if (currentSettings.width) {				tmp.width = currentSettings.width;			} else if (currentSettings.type == 'iframe') {				tmp.width = currentSettings.minWidth;			}							if (currentSettings.height) {				tmp.height = currentSettings.height			} else if (currentSettings.type == 'iframe') {				tmp.height = currentSettings.minHeight;			}						modal.content.css(tmp);			if (!currentSettings.width) {				currentSettings.width = modal.content.outerWidth(true);				resized.width = true;			}			if (!currentSettings.height) {				currentSettings.height = modal.content.outerHeight(true);				resized.height = true;			}			modal.contentWrapper.css({opacity: 1});			if (!resizing)				modal.contentWrapper.hide();		}		if (currentSettings.type != 'image' && currentSettings.type != 'swf') {			currentSettings.width = Math.max(currentSettings.width, currentSettings.minWidth);			currentSettings.height = Math.max(currentSettings.height, currentSettings.minHeight);		}		var outerWrapper = getOuter(modal.contentWrapper);		var outerWrapper2 = getOuter(modal.wrapper);		var outerContent = getOuter(modal.content);		var tmp = {			content: {				width: currentSettings.width,				height: currentSettings.height			},			wrapper2: {				width: currentSettings.width + outerContent.w.total,				height: currentSettings.height + outerContent.h.total			},			wrapper: {				width: currentSettings.width + outerContent.w.total + outerWrapper2.w.total,				height: currentSettings.height + outerContent.h.total + outerWrapper2.h.total			}		};		if (currentSettings.resizable) {			var maxHeight = modal.blockerVars? modal.blockerVars.height : $(window).height()								- outerWrapper.h.border								- (tmp.wrapper.height - currentSettings.height);			var maxWidth = modal.blockerVars? modal.blockerVars.width : $(window).width()								- outerWrapper.w.border								- (tmp.wrapper.width - currentSettings.width);			maxHeight-= currentSettings.padding*2;			maxWidth-= currentSettings.padding*2;			if (tmp.content.height > maxHeight || tmp.content.width > maxWidth) {				// We're gonna resize the modal as it will goes outside the view port				if (currentSettings.type == 'image' || currentSettings.type == 'swf') {					// An image is resized proportionnaly					var useW = currentSettings.imgWidth?currentSettings.imgWidth : currentSettings.width;					var useH = currentSettings.imgHeight?currentSettings.imgHeight : currentSettings.height;					var diffW = tmp.content.width - useW;					var diffH = tmp.content.height - useH;						if (diffH < 0) diffH = 0;						if (diffW < 0) diffW = 0;					var calcH = maxHeight - diffH;					var calcW = maxWidth - diffW;					var ratio = Math.min(calcH/useH, calcW/useW);					calcW = Math.floor(useW*ratio);					calcH = Math.floor(useH*ratio);					tmp.content.height = calcH + diffH;					tmp.content.width = calcW + diffW;				} else {					// For an HTML content, we simply decrease the size					tmp.content.height = Math.min(tmp.content.height, maxHeight);					tmp.content.width = Math.min(tmp.content.width, maxWidth);				}				tmp.wrapper2 = {						width: tmp.content.width + outerContent.w.total,						height: tmp.content.height + outerContent.h.total					};				tmp.wrapper = {						width: tmp.content.width + outerContent.w.total + outerWrapper2.w.total,						height: tmp.content.height + outerContent.h.total + outerWrapper2.h.total					};			}		}				if (currentSettings.type == 'swf') {			$('object, embed', modal.content)				.attr('width', tmp.content.width)				.attr('height', tmp.content.height);		} else if (currentSettings.type == 'image') {			$('img', modal.content).css({				width: tmp.content.width,				height: tmp.content.height			});		}		modal.content.css($.extend({}, tmp.content, currentSettings.css.content));		modal.wrapper.css($.extend({}, tmp.wrapper2, currentSettings.css.wrapper2));		if (!resizing)			modal.contentWrapper.css($.extend({}, tmp.wrapper, currentSettings.css.wrapper));		if (currentSettings.type == 'image' && currentSettings.addImageDivTitle) {			// Adding the title for the image			$('img', modal.content).removeAttr('alt');			var divTitle = $('div', modal.content);			if (currentSettings.title != currentSettings.defaultImgAlt && currentSettings.title) {				if (divTitle.length == 0) {					divTitle = $('<div>'+currentSettings.title+'</div>');					modal.content.append(divTitle);				}				if (currentSettings.setWidthImgTitle) {					var outerDivTitle = getOuter(divTitle);					divTitle.css({width: (tmp.content.width + outerContent.w.padding - outerDivTitle.w.total)+'px'});				}			} else if (divTitle.length = 0) {				divTitle.remove();			}		}		if (currentSettings.title)			setTitle();		tmp.wrapper.borderW = outerWrapper.w.border;		tmp.wrapper.borderH = outerWrapper.h.border;		setCurrentSettings(tmp.wrapper);		setMargin();	}	function removeModal(e) {		debug('removeModal');		if (e)			e.preventDefault();		if (modal.full && modal.ready) {			$(document).unbind('keydown.nyroModal');			if (!currentSettings.blocker)				$(window).unbind('resize.nyroModal');			modal.ready = false;			modal.anim = true;			modal.closing = true;			if (modal.loadingShown || modal.transition) {				currentSettings.hideLoading(modal, currentSettings, function() {						modal.loading.hide();						modal.loadingShown = false;						modal.transition = false;						currentSettings.hideBackground(modal, currentSettings, endRemove);					});			} else {				if (fixFF)					modal.content.css({position: ''}); // Fix Issue #10, remove the attribute				modal.wrapper.css({overflow: 'hidden'}); // Used to fix a visual issue when hiding				modal.content.css({overflow: 'hidden'}); // Used to fix a visual issue when hiding				if ($.isFunction(currentSettings.beforeHideContent)) {					currentSettings.beforeHideContent(modal, currentSettings, function() {						currentSettings.hideContent(modal, currentSettings, function() {							endHideContent();							currentSettings.hideBackground(modal, currentSettings, endRemove);						});					});				} else {					currentSettings.hideContent(modal, currentSettings, function() {							endHideContent();							currentSettings.hideBackground(modal, currentSettings, endRemove);						});				}			}		}		if (e)			return false;	}	function showContentOrLoading() {		debug('showContentOrLoading');		if (modal.ready && !modal.anim) {			if (modal.dataReady) {				if (modal.tmp.html()) {					modal.anim = true;					if (modal.transition) {						fillContent();						modal.animContent = true;						currentSettings.hideTransition(modal, currentSettings, function() {							modal.loading.hide();							modal.transition = false;							modal.loadingShown = false;							endShowContent();						});					} else {						currentSettings.hideLoading(modal, currentSettings, function() {								modal.loading.hide();								modal.loadingShown = false;								fillContent();								setMarginLoading();								setMargin();								modal.animContent = true;								currentSettings.showContent(modal, currentSettings, endShowContent);							});					}				}			} else if (!modal.loadingShown && !modal.transition) {				modal.anim = true;				modal.loadingShown = true;				if (modal.error)					loadingError();				else					modal.loading.html(currentSettings.contentLoading);				$(currentSettings.closeSelector, modal.loading)					.unbind('click.nyroModal')					.bind('click.nyroModal', removeModal);				setMarginLoading();				currentSettings.showLoading(modal, currentSettings, function(){modal.anim=false;showContentOrLoading();});			}		}	}	// -------------------------------------------------------	// Private Data Loaded callback	// -------------------------------------------------------	function ajaxLoaded(data) {		debug('AjaxLoaded: '+this.url);		modal.tmp.html(currentSettings.selector			?filterScripts($('<div>'+data+'</div>').find(currentSettings.selector).contents())			:filterScripts(data));		if (modal.tmp.html()) {			modal.dataReady = true;			showContentOrLoading();		} else			loadingError();	}	function formDataLoaded() {		debug('formDataLoaded');		var jFrom = $(currentSettings.from);		jFrom.attr('action', jFrom.attr('action')+currentSettings.selector);		jFrom.attr('target', '');		$('input[name='+currentSettings.formIndicator+']', currentSettings.from).remove();		var iframe = modal.tmp.children('iframe');		var iframeContent = iframe.unbind('load').contents().find(currentSettings.selector || 'body').not('script[src]');		iframe.attr('src', 'about:blank'); // Used to stop the loading in FF		modal.tmp.html(iframeContent.html());		if (modal.tmp.html()) {			modal.dataReady = true;			showContentOrLoading();		} else			loadingError();	}		function galleryCounts(nb, total, elts, settings) {		settings.title+= (settings.title?' - ':'') +nb+'/'+total;	}	// -------------------------------------------------------	// Private Animation callback	// -------------------------------------------------------	function endHideContent() {		debug('endHideContent');		modal.anim = false;		if (contentEltLast) {			contentEltLast.append(modal.content.contents());			contentEltLast = null;		} else if (contentElt) {			contentElt.append(modal.content.contents());			contentElt= null;		}		modal.content.empty();				gallery = {};				modal.contentWrapper.hide().children().remove().empty().attr('style', '').hide();		if (modal.closing || modal.transition)			modal.contentWrapper.hide();		modal.contentWrapper			.css(currentSettings.css.wrapper)			.append(modal.content);		showContentOrLoading();	}	function endRemove() {		debug('endRemove');		$(document).unbind('keydown', keyHandler);		modal.anim = false;		modal.full.remove();		modal.full = null;		if (isIE6) {			body.css({height: '', width: '', position: '', overflow: ''});			$('html').css({overflow: ''});		}		if ($.isFunction(currentSettings.endRemove))			currentSettings.endRemove(modal, currentSettings);	}	function endBackground() {		debug('endBackground');		modal.ready = true;		modal.anim = false;		showContentOrLoading();	}	function endShowContent() {		debug('endShowContent');		modal.anim = false;		modal.animContent = false;		modal.contentWrapper.css({opacity: ''}); // for the close button in IE		fixFF = /mozilla/.test(userAgent) && !/(compatible|webkit)/.test(userAgent) && parseFloat(browserVersion) < 1.9 && currentSettings.type != 'image';		if (fixFF)			modal.content.css({position: 'fixed'}); // Fix Issue #10		modal.content.append(modal.scriptsShown);		if (currentSettings.autoSizable && currentSettings.type == 'iframe') {		//*			var iframe = modal.content.find('iframe');			if (iframe.length && iframe.attr('src').indexOf(window.location.hostname) !== -1) {				var body = iframe.contents().find('body');							if (body.height() > 0) {					var h = body.outerHeight(true)+1;					var w = body.outerWidth(true)+1;					$.nyroModalSettings({						height: h,						width: w					});				} else {					iframe.bind('load', function() {						var body = iframe.contents().find('body');						if (body.length && body.height() > 0) {							var h = body.outerHeight(true)+1;							var w = body.outerWidth(true)+1;							$.nyroModalSettings({								height: h,								width: w							});						}					});				}			}		// */		}		if ($.isFunction(currentSettings.endShowContent))			currentSettings.endShowContent(modal, currentSettings);		if (shouldResize) {			shouldResize = false;			$.nyroModalSettings({width: currentSettings.setWidth, height: currentSettings.setHeight});			delete currentSettings['setWidth'];			delete currentSettings['setHeight'];		}		if (resized.width)			setCurrentSettings({width: null});		if (resized.height)			setCurrentSettings({height: null});	}	// -------------------------------------------------------	// Utilities	// -------------------------------------------------------	// Get the selector from an url (as string)	function getHash(url) {		if (typeof url == 'string') {			var hashPos = url.indexOf('#');			if (hashPos > -1)				return url.substring(hashPos);		}		return '';	}	// Filter an html content to remove the script[src]	function filterScripts(data) {		// Removing the body, head and html tag		if (typeof data == 'string')			data = data.replace(/<\/?(html|head|body)([^>]*)>/gi, '');		var tmp = new Array();		$.each($.clean({0:data}, this.ownerDocument), function() {			if ($.nodeName(this, "script")) {				if (!this.src || $(this).attr('rel') == 'forceLoad') {					if ($(this).attr('rev') == 'shown')						modal.scriptsShown.push(this);					else						modal.scripts.push(this);				}			} else				tmp.push(this);		});		return tmp;	}	// Get the vertical and horizontal margin, padding and border dimension	function getOuter(elm) {		elm = elm.get(0);		var ret = {			h: {				margin: getCurCSS(elm, 'marginTop') + getCurCSS(elm, 'marginBottom'),				border: getCurCSS(elm, 'borderTopWidth') + getCurCSS(elm, 'borderBottomWidth'),				padding: getCurCSS(elm, 'paddingTop') + getCurCSS(elm, 'paddingBottom')			},			w: {				margin: getCurCSS(elm, 'marginLeft') + getCurCSS(elm, 'marginRight'),				border: getCurCSS(elm, 'borderLeftWidth') + getCurCSS(elm, 'borderRightWidth'),				padding: getCurCSS(elm, 'paddingLeft') + getCurCSS(elm, 'paddingRight')			}		};		ret.h.outer = ret.h.margin + ret.h.border;		ret.w.outer = ret.w.margin + ret.w.border;		ret.h.inner = ret.h.padding + ret.h.border;		ret.w.inner = ret.w.padding + ret.w.border;		ret.h.total = ret.h.outer + ret.h.padding;		ret.w.total = ret.w.outer + ret.w.padding;		return ret;	}	function getCurCSS(elm, name) {		var ret = parseInt($.curCSS(elm, name, true));		if (isNaN(ret))			ret = 0;		return ret;	}	// Proxy Debug function	function debug(msg) {		if ($.fn.nyroModal.settings.debug || currentSettings && currentSettings.debug)			nyroModalDebug(msg, modal, currentSettings || {});	}	// -------------------------------------------------------	// Default animation function	// -------------------------------------------------------	function showBackground(elts, settings, callback) {		elts.bg.css({opacity:0}).fadeTo(500, 0.75, callback);	}	function hideBackground(elts, settings, callback) {		elts.bg.fadeOut(300, callback);	}	function showLoading(elts, settings, callback) {		elts.loading			.css({				marginTop: settings.marginTopLoading+'px',				marginLeft: settings.marginLeftLoading+'px',				opacity: 0			})			.show()			.animate({				opacity: 1			}, {complete: callback, duration: 400});	}	function hideLoading(elts, settings, callback) {		callback();	}	function showContent(elts, settings, callback) {		elts.loading			.css({				marginTop: settings.marginTopLoading+'px',				marginLeft: settings.marginLeftLoading+'px'			})			.show()			.animate({				width: settings.width+'px',				height: settings.height+'px',				marginTop: settings.marginTop+'px',				marginLeft: settings.marginLeft+'px'			}, {duration: 350, complete: function() {				elts.contentWrapper					.css({						width: settings.width+'px',						height: settings.height+'px',						marginTop: settings.marginTop+'px',						marginLeft: settings.marginLeft+'px'					})					.show();					elts.loading.fadeOut(200, callback);				}			});	}	function hideContent(elts, settings, callback) {		elts.contentWrapper			.animate({				height: '50px',				width: '50px',				marginTop: (-(25+settings.borderH)/2 + settings.marginScrollTop)+'px',				marginLeft: (-(25+settings.borderW)/2 + settings.marginScrollLeft)+'px'			}, {duration: 350, complete: function() {				elts.contentWrapper.hide();				callback();			}});	}	function showTransition(elts, settings, callback) {		// Put the loading with the same dimensions of the current content		elts.loading			.css({				marginTop: elts.contentWrapper.css('marginTop'),				marginLeft: elts.contentWrapper.css('marginLeft'),				height: elts.contentWrapper.css('height'),				width: elts.contentWrapper.css('width'),				opacity: 0			})			.show()			.fadeTo(400, 1, function() {					elts.contentWrapper.hide();					callback();				});	}	function hideTransition(elts, settings, callback) {		// Place the content wrapper underneath the the loading with the right dimensions		elts.contentWrapper			.hide()			.css({				width: settings.width+'px',				height: settings.height+'px',				marginLeft: settings.marginLeft+'px',				marginTop: settings.marginTop+'px',				opacity: 1			});		elts.loading			.animate({				width: settings.width+'px',				height: settings.height+'px',				marginLeft: settings.marginLeft+'px',				marginTop: settings.marginTop+'px'			}, {complete: function() {					elts.contentWrapper.show();					elts.loading.fadeOut(400, function() {						elts.loading.hide();						callback();					});				}, duration: 350});	}	function resize(elts, settings, callback) {		elts.contentWrapper			.animate({				width: settings.width+'px',				height: settings.height+'px',				marginLeft: settings.marginLeft+'px',				marginTop: settings.marginTop+'px'			}, {complete: callback, duration: 400});	}	function updateBgColor(elts, settings, callback) {		if (!$.fx.step.backgroundColor) {			elts.bg.css({backgroundColor: settings.bgColor});			callback();		} else			elts.bg				.animate({					backgroundColor: settings.bgColor				}, {complete: callback, duration: 400});	}	// -------------------------------------------------------	// Default initialization	// -------------------------------------------------------	$($.fn.nyroModal.settings.openSelector).nyroModal();});// Default debug function, to be overwritten if needed//      Be aware that the settings parameter could be emptyfunction nyroModalDebug(msg, elts, settings) {	if (elts.full)		elts.bg.prepend(msg+'<br />');}