/* * nyroModal - jQuery Plugin * http://nyromodal.nyrodev.com * * Copyright (c) 2008 Cedric Nirousset (nyrodev.com) * Licensed under the MIT license * * $Date: 2009-08-14 (Fri, 14 Aug 2009) $ * $version: 1.5.5 */ jQuery(function($) { // ------------------------------------------------------- // Private Variables // ------------------------------------------------------- var userAgent = navigator.userAgent.toLowerCase(); 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 || typeof(XMLHttpRequest) === 'function')); var body = $('body'); var currentSettings; var callingSettings; 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(e.isDefaultPrevented()) return false; 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) { // if(e.isDefaultPrevented()) // return false; // 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 windowResize: true, // indicates if the modal should resize when the window is resized modal: false, // Esc key or click backgrdound enabling or not type: '', // nyroModal type (form, formData, iframe, image, etc...) forceType: null, // Used to force the type 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: 50, // Minimum width minHeight: 50, // 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 images addImageDivTitle: false, // Indicate if the div title should be inserted defaultImgAlt: 'Image', // Default alt attribute for the images 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: 'PrevNext', // Use .nyroModalPrev and .nyroModalNext to set the navigation link galleryCounts: galleryCounts, // Callback to show the gallery count galleryLoop: false, // Indicate if the gallery should loop 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: { }, loading: { position: 'absolute', top: '50%', left: '50%', marginTop: '-50px', marginLeft: '-50px' } }, wrap: { // Wrapper div used to style the modal regarding the content type div: '
', ajax: '
', form: '
', formData: '
', image: '
', swf: '
', iframe: '
', iframeForm: '
', manual: '
' }, closeButton: 'Close', // 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: 'Cancel', // Loading div content errorClass: 'error', // CSS Error class added to the loading div in case of error contentError: 'The requested content cannot be loaded.
Please try again later.
Close', // 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; callingSettings = $.extend(true, settings); 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 (currentSettings.forceType) { if (!currentSettings.content) currentSettings.from = true; currentSettings.type = currentSettings.forceType; currentSettings.forceType = null; } if ($.isFunction(currentSettings.processHandler)) currentSettings.processHandler(currentSettings); var from = currentSettings.from; var url = currentSettings.url; initSettingsSize.width = currentSettings.width; initSettingsSize.height = currentSettings.height; if (currentSettings.type == 'swf') { // Swf is transforming as a raw content setCurrentSettings({overflow: 'visible'}, 'css', 'content'); currentSettings.content = ''; var tmp = ''; $.each(currentSettings.swf, function(name, val) { currentSettings.content+= ''; tmp+= ' '+name+'="'+val+'"'; }); currentSettings.content+= ''; } if (from) { var jFrom = $(from).blur(); 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(''); if (currentSettings.selector) jFrom.prepend(''); modal.tmp.html(''); $('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('').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: 'visible'}, 'css', 'content'); modal.dataReady = true; if (modal.loadingShown || modal.transition) showContentOrLoading(); }) .attr('src', url); showModal(); } else if (currentSettings.type == 'iframeForm') { initModal(); modal.tmp.html(''); debug('Iframe Form Load: '+url); $('iframe', modal.tmp).eq(0) .css({ width: '100%', height: $.support.boxModel? '99%' : '100%' }) .load(iframeLoaded); modal.dataReady = true; showModal(); } else if (currentSettings.type == 'iframe') { initModal(); modal.tmp.html(''); debug('Iframe Load: '+url); $('iframe', modal.tmp).eq(0) .css({ width: '100%', height: $.support.boxModel? '99%' : '100%' }) .load(iframeLoaded); 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($('
').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); 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('

'+currentSettings.title+'

'); } // 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()+200)+'px', //130% width: (body.width()+200)+'px', //130% 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 = $('') .css($.extend({}, currentSettings.css.bg, { opacity: 0, zIndex: 50, border: 'none' })); } contain.append($('
').hide()); modal.full = $('#nyroModalFull') .css(full) .show(); modal.bg = $('#nyroModalBg') .css($.extend({ backgroundColor: currentSettings.bgColor }, currentSettings.css.bg)) .before(iframeHideIE); modal.bg.bind('click.nyroModal', clickBg); 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 && currentSettings.windowResize) { $(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();}); } } // Called when user click on background function clickBg(e) { if (!currentSettings.modal) removeModal(); } // 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() { 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') { var indexSpace = from.rel.indexOf(' '); currentSettings.gallery = indexSpace > 0 ? from.rel.substr(0, indexSpace) : 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://|https:///", "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 || req == $('base').attr('href')) { 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() { return callingSettings; 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+'"], [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($('').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($('') .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); else if (currentSettings.galleryLoop) { if (index < 0) return gallery.links.eq(gallery.links.length-1); else return gallery.links.eq(0); } } 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 = $('
'+currentSettings.title+'
'); 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 $('iframe', modal.content).hide(); // Fix issue 359 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($('
'+data+'
').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 iframeLoaded() { if ((window.location.hostname && currentSettings.url.indexOf(window.location.hostname) > -1) || currentSettings.url.indexOf('http://')) { var iframe = $('iframe', modal.full).contents(); var tmp = {}; if (currentSettings.titleFromIframe) tmp.title = iframe.find('title').text(); if (!tmp.title) { // for IE try { tmp.title = iframe.find('title').html(); } catch(err) {} } var body = iframe.find('body'); if (!currentSettings.height && body.height()) tmp.height = body.height(); if (!currentSettings.width && body.width()) tmp.width = body.width(); $.extend(initSettingsSize, tmp); $.nyroModalSettings(tmp); } } function galleryCounts(nb, total, elts, settings) { if (total > 1) 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.type == 'iframe') modal.content.find('iframe').attr('src', currentSettings.url); 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+'
'); }