83
edits
(Created page with "→<pre> * Thickbox4MediaWiki v3.13 - Based on Thickbox 3.1 By Cody Lindley (http://www.codylindley.com) * Copyright (c) 2010 - 2023 Jesús Martínez (User:Ciencia_Al_Poder), Original Thickbox Copyright (c) 2007 Cody Lindley * Licensed under the MIT License: http://www.opensource.org/licenses/mit-license.php: window.Thickbox = (function($, mw) { 'use strict'; var _version = '3.13', // Dimensiones mínimas _minWidth = 210, // Margen entre la imagen y el borde de...") |
No edit summary |
||
Line 1: | Line 1: | ||
/* | /* | ||
* Thickbox4MediaWiki v3. | * Thickbox4MediaWiki v3.12 - Based on Thickbox 3.1 By Cody Lindley (http://www.codylindley.com) | ||
* Copyright (c) 2010 - | * Copyright (c) 2010 - 2022 Jesús Martínez (User:Ciencia_Al_Poder), Original Thickbox Copyright (c) 2007 Cody Lindley | ||
* Licensed under the MIT License: http://www.opensource.org/licenses/mit-license.php | * Licensed under the MIT License: http://www.opensource.org/licenses/mit-license.php | ||
*/ | */ | ||
window.Thickbox = (function($, mw) { | window.Thickbox = (function($, mw) { | ||
'use strict'; | 'use strict'; | ||
var _version = '3. | var _version = '3.12', | ||
// | // Minimum dimensions | ||
_minWidth = 210, | _minWidth = 210, | ||
// | // Margin between the image and the border of ThickBox | ||
_imageMarginWidth = 15, | _imageMarginWidth = 15, | ||
// | // Minimum margin to the edge of the window. If the image is exceeded it will be reduced | ||
_minMarginWidth = 30, | _minMarginWidth = 30, | ||
_minMarginHeight = 15, | _minMarginHeight = 15, | ||
// | // Waiting time for the loader to appear in ms | ||
_loaderWait = 500, | _loaderWait = 500, | ||
// | // Internal | ||
_imgPreloader = null, | _imgPreloader = null, | ||
_galleryData = null, | _galleryData = null, | ||
Line 29: | Line 29: | ||
_loaderTm = null, | _loaderTm = null, | ||
_logger = null, | _logger = null, | ||
// | // Private functions | ||
_init = function() { | _init = function() { | ||
// | // COMPAT | ||
if (window.Thickbox4MediaWikiLoaded) { return; } | |||
window.Thickbox4MediaWikiLoaded = true; | |||
// You could have put an event directly in each 'a.image', but this is much faster and more efficient (it only takes 20% in FF2) than to go through the entire DOM | |||
$('#mw-content-text').off('click.thickbox mouseover.thickbox_imgtip').on({ | $('#mw-content-text').off('click.thickbox mouseover.thickbox_imgtip').on({ | ||
'click.thickbox': _triggerEvent, | 'click.thickbox': _triggerEvent, | ||
Line 38: | Line 41: | ||
}, | }, | ||
_triggerEvent = function(e) { | _triggerEvent = function(e) { | ||
// | // If there is any special key pressed, we exit | ||
if (e.ctrlKey || e.altKey || e.shiftKey) { | if (e.ctrlKey || e.altKey || e.shiftKey) { | ||
return true; | return true; | ||
Line 45: | Line 48: | ||
if (_isTag(target,'img')) { // Gallery o thumb | if (_isTag(target,'img')) { // Gallery o thumb | ||
var a = target.parentNode; | var a = target.parentNode; | ||
// | // Images with links to other articles do not have the "image" class, except in Wikia where it does and add "link-internal" or "link-external" | ||
if (!a || !_isTag(a,'a') || ! | if (!a || !_isTag(a,'a') || !_isClass(a,'image') || _isClass(a, 'link-internal') || _isClass(a, 'link-external')) { | ||
return true; | return true; | ||
} | } | ||
// | // Wikia 2 Gallery | ||
if (_isClass( | if (_isClass(a,'lightbox')) { | ||
target.blur(); | |||
a. | _getCaption = _getCaptionWikia; | ||
_galleryData = $(target).closest('div.wikia-gallery').find('> div.wikia-gallery-item > div.thumb > div.gallery-image-wrapper > a.lightbox'); | |||
if (_galleryData.length === 0) { | |||
_galleryData = $(target).closest('div.wikia-gallery').find('> div.wikia-gallery-row > div.wikia-gallery-item > div.thumb > div.gallery-image-wrapper > a.lightbox'); | |||
} | |||
if (_galleryData.length === 0) { | |||
return true; | |||
} | |||
_galleryIndex = _galleryData.index(a); | |||
_showImage(a); | _showImage(a); | ||
return false; | return false; | ||
} | } | ||
if (_isClass(target,'thumbimage')) { | |||
if ( | // Its thumbnail | ||
// | |||
a.blur(); | a.blur(); | ||
_getCaption = | _getCaption = _getCaptionThumb; | ||
_showImage(a); | _showImage(a); | ||
return false; | return false; | ||
} | } | ||
var gb = | var gb = a.parentNode.parentNode.parentNode.parentNode; | ||
// MediaWiki gallery | // MediaWiki gallery | ||
if (gb) { | if (_isTag(gb,'li') && _isClass(gb,'gallerybox')) { | ||
var t = gb.parentNode; | var t = gb.parentNode; | ||
if (_isTag(t,'ul') && _isClass(t,'gallery')) { | if (_isTag(t,'ul') && _isClass(t,'gallery')) { | ||
a.blur(); | a.blur(); | ||
_getCaption = _getCaptionMW; | _getCaption = _getCaptionMW; | ||
_galleryData = $(t).find('div.thumb a.image | _galleryData = $(t).find('div.thumb a.image'); | ||
_galleryIndex = _galleryData.index(a); | _galleryIndex = _galleryData.index(a); | ||
_showImage(a); | _showImage(a); | ||
Line 78: | Line 87: | ||
} | } | ||
} | } | ||
// | // Its generic thumbnail | ||
a.blur(); | a.blur(); | ||
_getCaption = _getCaptionEmpty; | _getCaption = _getCaptionEmpty; | ||
_showImage(a); | _showImage(a); | ||
return false; | return false; | ||
} else if (_isTag(target,'a')) { | /*} else if (_isTag(target,'a')) { | ||
var sup = target.parentNode; | var sup = target.parentNode; | ||
if (!_isTag(sup,'sup') || !_isClass(sup,'reference')) { | if (!_isTag(sup,'sup') || !_isClass(sup,'reference')) { | ||
Line 90: | Line 99: | ||
target.blur(); | target.blur(); | ||
_showElement(target); | _showElement(target); | ||
return false; | return false;*/ | ||
} | } | ||
return true; | return true; | ||
Line 146: | Line 155: | ||
descUrl = $a.attr('href'); | descUrl = $a.attr('href'); | ||
if ($img.data('image-key')) { | if ($img.data('image-key')) { | ||
// image-key | // image-key is the name for the URL. Do not use image-name because it is encoded | ||
descUrl = mw.util.wikiGetlink(mw.config.get('wgFormattedNamespaces')['6'] + ':' + decodeURIComponent($img.data('image-key'))); | descUrl = mw.util.wikiGetlink(mw.config.get('wgFormattedNamespaces')['6'] + ':' + decodeURIComponent($img.data('image-key'))); | ||
} | } | ||
TB_descLink = '<a id="TB_descLink" class="sprite details" title=" | TB_descLink = '<a id="TB_descLink" class="sprite details" title="Go to the image\'s description page">File Page</a>'; | ||
// | // Is it a gallery? | ||
if (_galleryIndex != -1) { | if (_galleryIndex != -1) { | ||
TB_secondLine = '<div id="TB_secondLine">'+ | TB_secondLine = '<div id="TB_secondLine">'+ | ||
'<span id="TB_imageCount"></span>'+ | '<span id="TB_imageCount"></span>'+ | ||
'<span id="TB_prev"><a href="#" title=" | '<span id="TB_prev"><a href="#" title="See previous image [Left arrow]"></a></span>'+ | ||
'<span id="TB_next"><a href="#" title=" | '<span id="TB_next"><a href="#" title="See next image [Right arrow]"></a></span></div>'; | ||
} | } | ||
$('#TB_window').append('<div id="TB_closeWindow"><a href="#" id="TB_closeWindowButton" title=" | $('#TB_window').append('<div id="TB_closeWindow"><a href="#" id="TB_closeWindowButton" title="Close [ESC]">close</a></div>' + | ||
'<div id="TB_ImageOff"><img id="TB_Image" alt="Image" title="Close" />' + TB_descLink + '</div>' + TB_secondLine + '<div id="TB_caption"></div>'); | |||
if (_galleryIndex != -1) { | if (_galleryIndex != -1) { | ||
_updateNavigation(); | _updateNavigation(); | ||
Line 168: | Line 177: | ||
$('#TB_prev').add('#TB_next').click(_navigate); | $('#TB_prev').add('#TB_next').click(_navigate); | ||
$('#TB_descLink').attr('href', descUrl); | $('#TB_descLink').attr('href', descUrl); | ||
if (_imgPreloader === null) { | if (_imgPreloader === null) { | ||
Line 184: | Line 185: | ||
_imgPreloader.src = ''; // chromium bug 7731 | _imgPreloader.src = ''; // chromium bug 7731 | ||
if (url.length > 3 && url.substr(url.length - 4).toLowerCase() == '.svg') { | if (url.length > 3 && url.substr(url.length - 4).toLowerCase() == '.svg') { | ||
// | // For SVG we already know its aspect ratio, although not its original dimensions | ||
// | // It would have to be done differently to load the SVG. Instead, here it is dynamically determined | ||
// | // It is artificially enlarged, and then this function will reduce it to the maximum window size | ||
_updateImageView($img.prop('width') * 1000, $img.prop('height') * 1000, url); | _updateImageView($img.prop('width') * 1000, $img.prop('height') * 1000, url); | ||
} else { | } else { | ||
_imgPreloader.src = url; | _imgPreloader.src = url; | ||
} | } | ||
} catch(e) { | } catch(e) { | ||
_log(e); | _log(e); | ||
Line 203: | Line 205: | ||
var baseurl = url.substr(0, idx), | var baseurl = url.substr(0, idx), | ||
hash = decodeURIComponent(url.substr(idx + 1)), | hash = decodeURIComponent(url.substr(idx + 1)), | ||
// | // We check that the URL is from the same document | ||
locbase = document.location.href.replace(baseurl, ''), | locbase = document.location.href.replace(baseurl, ''), | ||
rel = document.getElementById(hash); | rel = document.getElementById(hash); | ||
Line 214: | Line 216: | ||
$('#TB_overlay').click(_remove); | $('#TB_overlay').click(_remove); | ||
var titleHTML = '<div id="TB_title"><div id="TB_closeAjaxWindow"><a href="#" id="TB_closeWindowButton" title=" | var titleHTML = '<div id="TB_title"><div id="TB_closeAjaxWindow"><a href="#" id="TB_closeWindowButton" title="Close [ESC]">close</a></div></div>', | ||
wnd = $('#TB_window'), | wnd = $('#TB_window'), | ||
cel = $(rel).clone(); | cel = $(rel).clone(); | ||
Line 222: | Line 224: | ||
var tgEl = $(target), | var tgEl = $(target), | ||
// | // horizontal space on each side of the element | ||
elOffset = tgEl.offset(), | elOffset = tgEl.offset(), | ||
lw = elOffset.left, | lw = elOffset.left, | ||
rw = $(document).width() - elOffset.left - tgEl.width(), | rw = $(document).width() - elOffset.left - tgEl.width(), | ||
// | // We calculate the optimal dimensions. We calculate the area and determine that the ideal is ratio 3/2 | ||
prefw = parseInt(Math.sqrt(wnd.width()*wnd.height()*3/2),10), | prefw = parseInt(Math.sqrt(wnd.width()*wnd.height()*3/2),10), | ||
// | // Minimum width correction if scroll occurs | ||
cd = $('#TB_ajaxContent')[0]; | cd = $('#TB_ajaxContent')[0]; | ||
prefw += cd.scrollWidth-cd.clientWidth; | prefw += cd.scrollWidth-cd.clientWidth; | ||
// | // The minimum width should not be reduced | ||
if (prefw < _minWidth) { | if (prefw < _minWidth) { | ||
prefw = _minWidth; | prefw = _minWidth; | ||
} | } | ||
// | // Position. 5px of margin with respect to the origin. Ideal situation: to the right of the element | ||
var margen = 5, left = $(document).width() - rw + margen; | var margen = 5, left = $(document).width() - rw + margen; | ||
if (rw > prefw + margen) { | if (rw > prefw + margen) { | ||
// | // is already correct | ||
} else if (lw > prefw + margen) { | } else if (lw > prefw + margen) { | ||
left = lw - prefw - margen; | left = lw - prefw - margen; | ||
} else if (lw < 250 || rw < 250) { // | } else if (lw < 250 || rw < 250) { // It does not fit on either side. We look to see if the minimum width (250) cannot be used. In that case the width we force it and put it to the right | ||
prefw = 250; | prefw = 250; | ||
} else if (rw > lw) { // | } else if (rw > lw) { // The available width of the major side is used | ||
prefw = rw - margen; | prefw = rw - margen; | ||
} else { | } else { | ||
Line 250: | Line 252: | ||
} | } | ||
wnd.css({width: prefw, left: left}); | wnd.css({width: prefw, left: left}); | ||
// | // Now the vertical position. it needs that we have assigned the width to calculate it well | ||
var top = elOffset.top - parseInt(wnd.height(), 10) - margen; | var top = elOffset.top - parseInt(wnd.height(), 10) - margen; | ||
// | // If it does not fit above we place it below | ||
if (top < margen) { | if (top < margen) { | ||
top = elOffset.top + tgEl.height() + margen; | top = elOffset.top + tgEl.height() + margen; | ||
} | } | ||
wnd.css({top: top, visibility: 'visible'}); | wnd.css({top: top, visibility: 'visible'}); | ||
// | // Animation if it is outside the visual field | ||
if (($('html')[0].scrollTop||$('body')[0].scrollTop) > top-margen) { | if (($('html')[0].scrollTop||$('body')[0].scrollTop) > top-margen) { | ||
$('html,body').animate({scrollTop: top - margen}, 250, 'swing'); | $('html,body').animate({scrollTop: top - margen}, 250, 'swing'); | ||
Line 292: | Line 294: | ||
if (keycode == 27) { // close | if (keycode == 27) { // close | ||
_remove(); | _remove(); | ||
} else if (keycode == | } else if (keycode == 37) { // 'Left arrow' display previous image | ||
$('#TB_prev').click(); | $('#TB_prev').click(); | ||
} else if (keycode == | } else if (keycode == 39) { // 'Right arrow' display next image | ||
$('#TB_next').click(); | $('#TB_next').click(); | ||
} | } | ||
Line 324: | Line 326: | ||
//return thumb.replace(/\/revision\/latest\/scale-to-width(-down)?\/\d+/, ''); | //return thumb.replace(/\/revision\/latest\/scale-to-width(-down)?\/\d+/, ''); | ||
// | // If the image is not thumb, or it is an SVG, we use the image as is. | ||
if (thumb.indexOf('/thumb/') == -1 || thumb.indexOf('.svg/') != -1 ) { | if (thumb.indexOf('/thumb/') == -1 || thumb.indexOf('.svg/') != -1 ) { | ||
return thumb; | return thumb; | ||
Line 334: | Line 336: | ||
_getCaptionThumb = function(elem) { | _getCaptionThumb = function(elem) { | ||
return elem.closest('.thumbinner').find('> .thumbcaption').clone().find('> div.magnify').remove().end().html(); | return elem.closest('.thumbinner').find('> .thumbcaption').clone().find('> div.magnify').remove().end().html(); | ||
}, | }, | ||
_getCaptionEmpty = function(elem) { | _getCaptionEmpty = function(elem) { | ||
Line 359: | Line 358: | ||
// Resizing large images - orginal by Christian Montoya edited by me. | // Resizing large images - orginal by Christian Montoya edited by me. | ||
pagesize = _getPageSize(), | pagesize = _getPageSize(), | ||
// | // Maximum dimensions | ||
x = pagesize[0] - _minMarginWidth * 2 - _imageMarginWidth * 2, | x = pagesize[0] - _minMarginWidth * 2 - _imageMarginWidth * 2, | ||
y = pagesize[1] - _minMarginHeight * 2 - wndH + img.height(), | y = pagesize[1] - _minMarginHeight * 2 - wndH + img.height(), | ||
imageWidth = _imgPreloader.width, | |||
imageHeight = _imgPreloader.height, | |||
firstNav, imgOpt; | firstNav, imgOpt; | ||
// | // You can enter by one or both. In fact, this check is enough, because if you have to go through both it does not matter which side is reduced first | ||
if (imageWidth > x) { | if (imageWidth > x) { | ||
imageHeight = imageHeight * (x / imageWidth); | imageHeight = imageHeight * (x / imageWidth); | ||
Line 375: | Line 376: | ||
firstNav = (img.attr('src') || '') === ''; | firstNav = (img.attr('src') || '') === ''; | ||
// | // Thickbox window dimensions to position | ||
_width = imageWidth + _imageMarginWidth * 2; // 15px de espacio en cada lado | _width = imageWidth + _imageMarginWidth * 2; // 15px de espacio en cada lado | ||
// | // We know the height of the window. Just replace the old image and put the new one, that is, its dimensions. The height has to be done differently because more elements are involved than in the width | ||
_height = wndH - img.height() + imageHeight; | _height = wndH - img.height() + imageHeight; | ||
img.attr({ | img.attr({ | ||
Line 385: | Line 386: | ||
imgOpt = {width: imageWidth, height: imageHeight, opacity: 1}; | imgOpt = {width: imageWidth, height: imageHeight, opacity: 1}; | ||
// | // We look to see if it loads when opening or after browsing. If it comes from opening, without animation | ||
if (firstNav) { | if (firstNav) { | ||
img.css(imgOpt); | img.css(imgOpt); | ||
Line 399: | Line 400: | ||
$('#TB_prev').css('display', (seq === 0 ? 'none' : '')); | $('#TB_prev').css('display', (seq === 0 ? 'none' : '')); | ||
$('#TB_next').css('display', (seq >= len-1 ? 'none' : '')); | $('#TB_next').css('display', (seq >= len-1 ? 'none' : '')); | ||
$('#TB_imageCount').text(' | $('#TB_imageCount').text('Image ' + (seq+1) + ' of ' + len); | ||
}, | }, | ||
_navigate = function() { | _navigate = function() { | ||
Line 416: | Line 417: | ||
if (url.length > 3 && url.substr(url.length - 4).toLowerCase() == '.svg') { | if (url.length > 3 && url.substr(url.length - 4).toLowerCase() == '.svg') { | ||
$img = gitem.find('> img').eq(0); | $img = gitem.find('> img').eq(0); | ||
// For SVG we already know its aspect ratio, although not its original dimensions | |||
// It would have to be done differently to load the SVG. Instead, here it is dynamically determined | |||
// It is artificially enlarged, and then this function will reduce it to the maximum window size | |||
_updateImageView($img.prop('width') * 1000, $img.prop('height') * 1000, url); | _updateImageView($img.prop('width') * 1000, $img.prop('height') * 1000, url); | ||
_imgPreloader.src = ''; | _imgPreloader.src = ''; | ||
Line 426: | Line 427: | ||
}}); | }}); | ||
} | } | ||
// | // If the function does not find the item, it can return undefined, and in this case the content does not change. We force a null in that case | ||
$('#TB_caption').html( ( _getCaption(gitem) || null ) ); | $('#TB_caption').html( ( _getCaption(gitem) || null ) ); | ||
$('#TB_descLink').attr('href',gitem.attr('href')); | $('#TB_descLink').attr('href',gitem.attr('href')); | ||
Line 475: | Line 476: | ||
if (_isTag(target,'img')) { // Gallery o thumb | if (_isTag(target,'img')) { // Gallery o thumb | ||
a = target.parentNode; | a = target.parentNode; | ||
if (!_isTag(a,'a') || ! | if (!_isTag(a,'a') || !_isClass(a,'image') || _isClass(a,'link-internal')) { | ||
_hideImgTip(); | _hideImgTip(); | ||
return; | return; | ||
} | } | ||
t = $(target); | t = $(target); | ||
// | // We show only if the image has a minimum size | ||
if (t.width() < 40 || t.height() < 40) { | if (t.width() < 40 || t.height() < 40) { | ||
return; | return; | ||
Line 496: | Line 497: | ||
}, | }, | ||
_createImgTip = function() { | _createImgTip = function() { | ||
_imgTip = $('<div id="TB_imagetip" title=" | _imgTip = $('<div id="TB_imagetip" title="Click on the image to enlarge. Click with Ctrl or Shift to go to the file page.">').appendTo(document.body); | ||
_imgTip.on('click',_imgTipClickEvent); | _imgTip.on('click',_imgTipClickEvent); | ||
}, | }, | ||
Line 507: | Line 508: | ||
display: 'block', | display: 'block', | ||
left: of.left + target.width(), | left: of.left + target.width(), | ||
top: of.top | top: of.top | ||
}); | }); | ||
_imgTipVisible = true; | _imgTipVisible = true; | ||
Line 534: | Line 535: | ||
$(window.Thickbox.init); | $(window.Thickbox.init); | ||
} | } | ||