Index: branches/RC/core/admin_templates/js/jquery/thickbox/thickbox.js =================================================================== diff -u -r11418 -r11482 --- branches/RC/core/admin_templates/js/jquery/thickbox/thickbox.js (.../thickbox.js) (revision 11418) +++ branches/RC/core/admin_templates/js/jquery/thickbox/thickbox.js (.../thickbox.js) (revision 11482) @@ -17,14 +17,19 @@ } ); -function TB () { - this.imgLoader = null; - this.pathToImage = 'images/loadingAnimation.gif'; +function TB () {} - this.Width = null; - this.Height = null; -} +TB.pathToImage = 'images/loadingAnimation.gif'; +TB.Width = null; +TB.Height = null; + +TB.lastParams = {}; +TB.windows = new Array(); +TB.windowMetaData = new Array (); +TB.useStack = true; +TB.closeHtml = 'close
'; // 'close'; + //add thickbox to href & area elements that have a class of .thickbox TB.init = function (domChunk) { $(domChunk).click( @@ -40,27 +45,61 @@ ); } +TB.getId = function ($id, $diff) { + var $length = TB.windows.length; + + if ($diff !== undefined) { + $length += $diff; + } + + if ($length == 0) { + return $id; + } + + return $id + $length; +} + // function called when the user clicks on a thickbox link TB.show = function (params) { - + TB.lastParams = params; // caption, url, imageGroup, onDataReceived, onAfterShow, postParams try { + if (TB.useStack) { + // increment window counter + if (TB.windows.length == 0) { + getFrame('head').$FrameResizer.fullScreen(); + } + + TB.windows[TB.windows.length] = '#' + TB.getId('TB_window', 1); + TB.windowMetaData[TB.windowMetaData.length] = {}; + } + if (typeof document.body.style.maxHeight === 'undefined') { - // if IE 6 + // if IE6 browser only $('body', 'html').css( {height: '100%', width: '100%'} ); $('html').css('overflow', 'hidden'); - if (document.getElementById('TB_HideSelect') === null) { - // iframe to hide select elements in ie6 - $('body').append("
"); + if ($('#TB_overlay').length == 0) { + // create overlay + $('body').append("
"); $('#TB_overlay').click(TB.remove); } + + if (document.getElementById( TB.getId('TB_window') ) === null) { + // iframe to hide select elements in ie6 + $('body').append("
"); + } } else { - // all others - if (document.getElementById('TB_overlay') === null) { - $('body').append("
"); + // all other browsers + if ($('#TB_overlay').length == 0) { + // create overlay + $('body').append("
"); $('#TB_overlay').click(TB.remove); } + + if ( $('#' + TB.getId('TB_window') ).length == 0) { + $('body').append("
"); + } } if (TB.detectMacXFF()) { @@ -109,6 +148,7 @@ } } catch(e) { //nothing here + alert("An exception occurred in the script.\nError name: " + e.name + ".\nError message: " + e.message); } } @@ -155,13 +195,13 @@ TB.Width = $image_size.width + 30; TB.Height = $image_size.height + 60; - $('#TB_window').append("" + params.caption + "" + "
" + params.caption + "
" + TB_imageCount + TB_PrevHTML + TB_NextHTML + "
close or Esc Key
"); - $('#TB_closeWindowButton').click(TB.remove); + $('#' + TB.getId('TB_window')).append("" + params.caption + "" + "
" + params.caption + "
" + TB_imageCount + TB_PrevHTML + TB_NextHTML + "
close or Esc Key
"); + $('#' + TB.getId('TB_closeWindowButton')).click(TB.remove); if (TB_PrevHTML !== '') { function goPrev() { - $('#TB_window').remove(); - $('body').append("
"); + $('#' + TB.getId('TB_window')).remove(); + $('body').append("
"); TB.show( {caption: TB_PrevCaption, url: TB_PrevURL, imageGroup: params.imageGroup} ); return false; } @@ -171,8 +211,8 @@ if (TB_NextHTML !== '') { function goNext() { - $('#TB_window').remove(); - $('body').append("
"); + $('#' + TB.getId('TB_window')).remove(); + $('body').append("
"); TB.show( {caption: TB_NextCaption, url: TB_NextURL, imageGroup: params.imageGroup} ); return false; } @@ -208,7 +248,7 @@ TB.position(); $('#TB_load').remove(); $('#TB_ImageOff').click(TB.remove); - $('#TB_window').css('display', 'block'); // for safari using css instead of show + $('#' + TB.getId('TB_window')).css('display', 'block'); // for safari using css instead of show } ); @@ -224,20 +264,31 @@ var imageWidth = $image.width; var imageHeight = $image.height; - if (imageWidth > x) { - imageHeight = imageHeight * (x / imageWidth); - imageWidth = x; - if (imageHeight > y) { + if ($image.src !== undefined) { + if (imageWidth > x) { + imageHeight = imageHeight * (x / imageWidth); + imageWidth = x; + if (imageHeight > y) { + imageWidth = imageWidth * (y / imageHeight); + imageHeight = y; + } + } else if (imageHeight > y) { imageWidth = imageWidth * (y / imageHeight); imageHeight = y; + if (imageWidth > x) { + imageHeight = imageHeight * (x / imageWidth); + imageWidth = x; + } } - } else if (imageHeight > y) { - imageWidth = imageWidth * (y / imageHeight); - imageHeight = y; + } + else { if (imageWidth > x) { - imageHeight = imageHeight * (x / imageWidth); imageWidth = x; } + + if (imageHeight > y) { + imageHeight = y; + } } return {width: imageWidth, height: imageHeight}; @@ -247,70 +298,80 @@ // code to show html // window size is global - TB.Width = (url_params['width'] * 1) + 30 || 630; // defaults to 630 if no paramaters were added to URL - TB.Height = (url_params['height'] * 1) + 40 || 440; // defaults to 440 if no paramaters were added to URL + var $fake_image = { + width: (url_params['width'] * 1) || 600, // defaults to 630 if no paramaters were added to URL + height: (url_params['height'] * 1) || 400 // defaults to 440 if no paramaters were added to URL + } + var $image_size = TB.scaleImage.call(TB, $fake_image); + + TB.Width = $image_size.width + 30; + TB.Height = $image_size.height + 40; + var ajaxContentW = TB.Width - 30; var ajaxContentH = TB.Height - 45; + var $modal = url_params['modal'] == 'true'; if (params.url.indexOf('TB_iframe') != -1) { // either iframe or ajax window urlNoQuery = params.url.split('TB_'); - $('#TB_iframeContent').remove(); - - if (url_params['modal'] != 'true') { - // iframe no modal - $('#TB_window').append("
" + params.caption + "
close or Esc Key
"); - }else{ - // iframe modal + $('#' + TB.getId('TB_iframeContent')).remove(); + if ($modal) { + // iframe modal -> don't close when clicking on grayed-out area $('#TB_overlay').unbind(); - $('#TB_window').append(""); } + + var $caption_html = "
" + params.caption + "
" + TB.closeHtml + "" + ($modal ? '' : ' or Esc Key') + "
"; + $('#' + TB.getId('TB_window')).append($caption_html + ""); } else { // not an iframe, ajax - if ($('#TB_window').css('display') != 'block') { - if (url_params['modal'] != 'true') { + if ($('#' + TB.getId('TB_window')).css('display') != 'block') { + var $caption_html = "
" + params.caption + "
" + TB.closeHtml + "" + ($modal ? '' : ' or Esc Key') + "
"; + + if (!$modal) { // ajax no modal - $('#TB_window').append("
" + params.caption + "
close or Esc Key
"); + $('#' + TB.getId('TB_window')).append($caption_html + "
"); } else { // ajax modal $('#TB_overlay').unbind(); - $('#TB_window').append("
"); + $('#' + TB.getId('TB_window')).append($caption_html + "
"); } } else { // this means the window is already up, we are just loading new content via ajax - $('#TB_ajaxContent')[0].style.width = ajaxContentW + 'px'; - $('#TB_ajaxContent')[0].style.height = ajaxContentH + 'px'; - $('#TB_ajaxContent')[0].scrollTop = 0; - $('#TB_ajaxWindowTitle').html(params.caption); + var $ajax_content = $('#' + TB.getId('TB_ajaxContent')).get(0); + + $ajax_content.style.width = ajaxContentW + 'px'; + $ajax_content.style.height = ajaxContentH + 'px'; + $ajax_content.scrollTop = 0; + $('#' + TB.getId('TB_ajaxWindowTitle')).html(params.caption); } } - $('#TB_closeWindowButton').click(TB.remove); + $('#' + TB.getId('TB_closeWindowButton')).click(TB.remove); if (params.url.indexOf('TB_inline') != -1) { - $('#TB_ajaxContent').html( $('#' + url_params['inlineId']).html() ); - $('#TB_window').unload( + $('#' + TB.getId('TB_ajaxContent')).html( $('#' + url_params['inlineId']).html() ); + $('#' + TB.getId('TB_window')).unload( function () { // move elements back when you're finished - $('#' + url_params['inlineId']).html( $('#TB_ajaxContent').html() ); + $('#' + url_params['inlineId']).html( $('#' + TB.getId('TB_ajaxContent')).html() ); } ); TB.position(); $('#TB_load').remove(); - $('#TB_window').css('display', 'block'); + $('#' + TB.getId('TB_window')).css('display', 'block'); } else if (params.url.indexOf('TB_iframe') != -1) { TB.position(); - if ($.browser.safari) { // safari needs help because it will not fire iframe onload $('#TB_load').remove(); - $('#TB_window').css('display', 'block'); + $('#' + TB.getId('TB_window')).css('display', 'block'); } } else { - var $content_url = params.url + '&random=' + (new Date().getTime()); + $.ajaxSetup({cache: false}); + var $content_url = params.url; if (params.postParams === undefined) { $.get( $content_url, @@ -328,23 +389,23 @@ } ); } + } - /*$('#TB_ajaxContent').load( - params.url += '&random=' + (new Date().getTime()), - params.postParams, - function() { - //to do a post change this load method - TB.position(); - $('#TB_load').remove(); - TB.init('#TB_ajaxContent a.thickbox'); - $('#TB_window').css('display', 'block'); + TB.updateZIndex(); // update z-index on window open +} - if ( $.isFunction(params.showCallback) ) { - params.showCallback(); - } - } - );*/ +TB.setWindowTitle = function ($title) { + if (TB.useStack) { + // remember window titles + if (TB.windowMetaData.length == 0) { + // remember title of topmost window too + TB.windowMetaData[TB.windowMetaData.length] = {window_name: 'main'}; + } + + TB.setWindowMetaData('title', $title); } + + $('#' + TB.getId('TB_ajaxWindowTitle') ).html($title); } TB.parseRedirect = function ($data) { @@ -372,12 +433,12 @@ return ; } - $('#TB_ajaxContent').html($data); + $('#' + TB.getId('TB_ajaxContent')).html($data); TB.position(); $('#TB_load').remove(); - TB.init('#TB_ajaxContent a.thickbox'); - $('#TB_window').css('display', 'block'); + TB.init('#' + TB.getId('TB_ajaxContent') + ' a.thickbox'); + $('#' + TB.getId('TB_window')).css('display', 'block'); if ( $.isFunction($params.onAfterShow) ) { $params.onAfterShow(); @@ -386,39 +447,118 @@ TB.showIframe = function () { $('#TB_load').remove(); - $('#TB_window').css('display', 'block'); + $('#' + TB.getId('TB_window')).css('display', 'block'); + + try { + if ( $.isFunction(TB.lastParams.onAfterShow) ) { + TB.lastParams.onAfterShow(); + } + } + catch (e) { + // IE gives "Can't execute code from a freed script" when iframe is closed and parent window is reloaded + // It's not a big problem, that our method is not called in this case, becase it doesn't do anything in + // such case either + } } -TB.remove = function () { - $('#TB_imageOff').unbind('click'); - $('#TB_closeWindowButton').unbind('click'); +TB.remove = function ($e, $on_close) { + var $last_window = TB.useStack && TB.windows.length <= 1; - $('#TB_window').fadeOut( + $('#TB_imageOff').unbind('click'); + $('#' + TB.getId('TB_closeWindowButton')).unbind('click'); + + /*$('#' + TB.getId('TB_window')).fadeOut( 'fast', - function(){ - $('#TB_window,#TB_overlay,#TB_HideSelect').trigger('unload').unbind().remove(); + function() { + TB.onAfterFade($last_window); } - ); + )*/ - $('#TB_load').remove(); - if (typeof document.body.style.maxHeight == 'undefined') { - // if IE 6 - $('body','html').css( {height: 'auto', width: 'auto'} ); - $('html').css('overflow', ''); - } + $('#' + TB.getId('TB_window')).hide(); - $(document).unbind('keydown').unbind('keyup'); + TB.onAfterFade($last_window, $on_close); + if ($last_window) { + $('#TB_load').remove(); + if (typeof document.body.style.maxHeight == 'undefined') { + // if IE 6 + $('body','html').css( {height: 'auto', width: 'auto'} ); + $('html').css('overflow', ''); + } + + $(document).unbind('keydown').unbind('keyup'); + } + return false; } +TB.onAfterFade = function ($last_window, $on_close) { + if ($last_window) { + // hide overlays first + $('#TB_overlay,#TB_HideSelect').remove(); + } + + if ($.isFunction($on_close)) { + // use close callback, because iframe will be removed later in this method + $on_close(); + } + + $('#' + TB.getId('TB_window')).unload().remove(); + + if (TB.useStack) { + // tricky window removing to prevent memory leaks + var n_nesting = TB.windows.length - 1; + $(TB.windows[n_nesting]).remove(); + TB.windows[n_nesting] = null; + TB.windows.length = n_nesting; + + // window meta data has one more record at beginning for topmost window + TB.windowMetaData[n_nesting + 1] = null; + TB.windowMetaData.length = n_nesting + 1; + + TB.updateZIndex(); // update z-index on window close + + set_window_title(TB.windowMetaData[TB.windowMetaData.length - 1].title); + + if (TB.windows.length == 0) { + getFrame('head').$FrameResizer.fullScreen(true); + } + } +} + TB.position = function () { - $('#TB_window').css( {marginLeft: '-' + parseInt((TB.Width / 2), 10) + 'px', width: TB.Width + 'px'} ); + var pagesize = TB.getPageSize(); + + $('#' + TB.getId('TB_window')).css( + { + width: TB.Width + 'px', + height: TB.Height + 'px', + left: Math.round((pagesize[0] - TB.Width) / 2) + 'px', + top: Math.round((pagesize[1] - TB.Height) / 2) + 'px' + } + ); + + $('#' + TB.getId('TB_window')) + .resizable( + { + alsoResize: '#' + TB.getId('TB_iframeContent') + } + ) + .draggable( + { + handle: '.TB_title', + containment: 'window' + } + ); + + + /*$('#' + TB.getId('TB_window')).css( {marginLeft: '-' + parseInt((TB.Width / 2), 10) + 'px', width: TB.Width + 'px'} ); + if ( !(jQuery.browser.msie && jQuery.browser.version < 7)) { // take away IE6 - $('#TB_window').css( {marginTop: '-' + parseInt((TB.Height / 2), 10) + 'px'} ); - } + $('#' + TB.getId('TB_window')).css( {marginTop: '-' + parseInt((TB.Height / 2), 10) + 'px'} ); + }*/ } TB.parseQuery = function (query) { @@ -455,11 +595,47 @@ TB.detectMacXFF = function () { var userAgent = navigator.userAgent.toLowerCase(); - if (userAgent.indexOf('mac') != -1 && userAgent.indexOf('firefox') != -1) { - return true; - } - return false; + return userAgent.indexOf('mac') != -1 && userAgent.indexOf('firefox') != -1; } +TB.updateZIndex = function () { + // #TB_overlay - 100 + // .TB_window - 102 [ok] + // #TB_load - 103 [ok] + // #TB_HideSelect - 99 + var n_nesting = TB.windows.length - 1; + var $window_index = 102 + n_nesting + TB.windows.length; + +// alert('nesting ' + n_nesting + ', window index ' + $window_index); + + $(TB.windows[n_nesting]).css('z-index', $window_index); // window position is dependend on it's opening order + $('#TB_load').css('z-index', $window_index + 1); // progress bar is over window + $('#TB_overlay').css('z-index', $window_index - 1); // overlay is under window +} + +TB.setWindowMetaData = function ($title, $value) { + TB.windowMetaData[TB.windowMetaData.length - 1][$title] = $value; +} + +TB.findWindow = function ($name, $diff) { + if (!isset($diff)) { + $diff = 0; + } + + for (var $i = TB.windowMetaData.length - 1; $i >= 0; $i--) { +// alert('comparing [' + TB.windowMetaData[$i].window_name + '] to [' + $name + ']'); + if (TB.windowMetaData[$i].window_name == $name) { + break; + } + } + + var $window_index = $i + $diff; + if ($i == 0 || $window_index <= 0) { + // not found or "main" window was requested -> it's not in TB.windows array anyway + return window; + } + + return $found_window = $('.TB_iframeContent', TB.windows[$window_index - 1]).get(0).contentWindow; +} \ No newline at end of file