User:Venkatraghavang/Slide.js

/** * jQuery Galleriffic plugin * * Copyright (c) 2008 Trent Foley (http://trentacular.com) * Licensed under the MIT License: *  http://www.opensource.org/licenses/mit-license.php * * Much thanks to primary contributer Ponticlaro (http://www.ponticlaro.com) * * Rewritten for commons by User:DieBuche, * additional features by User:Rillke */ if (typeof(window.GallerySlide) === 'undefined' &&	(mw.config.get('wgNamespaceNumber') === 14 || mw.config.get('wgNamespaceNumber') === 4 || mw.config.get('wgNamespaceNumber') === 0)) { //Declare global var for todays specific gallery window.GallerySlide = 0; (function ($) {	// Globally keep track of all images by their unique hash. Each item is an image data object.	var isCategory = (mw.config.get('wgNamespaceNumber') === 14);	var allImages = {};	var imageCounter = 0;	// Galleriffic static class	$.galleriffic = {		version: '2.2',		// Strips invalid characters and any leading # characters		normalizeHash: function (hash) {			return hash.replace('#', '');		},		getImage: function (hash) {			if (!hash) return undefined;			hash = $.galleriffic.normalizeHash(hash);			return allImages[hash];		},		// Global function that looks up an image by its hash and displays the image.		// Returns false when an image is not found for the specified hash.		// @param {String} hash This is the unique hash value assigned to an image.		gotoImage: function (hash) {			var imageData = $.galleriffic.getImage(hash);			//if (!imageData) return false;			var gallery = imageData.gallery; gallery.gotoImage(imageData); return true; }	};	var i18n = { fr: { delayInsertBtn: 'Définir l’intervalle de temps', delayInsert: 'Combien de millisecondes entre chaque image ?', delayInvalid: 'Entrée invalide. Seuls les nombres supérieurs à 2500 sont acceptés.', playLinkText: 'Lire', pauseLinkText: 'Pause', prevLinkText: 'Précédent', nextLinkText: 'Suivant', hideText: 'Quitter le diaporama', continueKeyHowTo: 'Clé de départ − Vous pouvez sauvegarder cette clé ou mettre en marque-page le lien si vous souhaitez commencer à cette position plus tard.', continueKeyInsert: 'Veuillez insérer la clé de départ. Vous devez faire défiler le diaporama pour constater un changement.', continueKeyInsertBtn: 'Insérer la clé de départ', continueKeyInvalid: 'Clé invalide', licenseLabel: 'Licences disponibles : ', uploaderLabel: 'La personne qui a téléchargé le fichier sur le serveur: ', helpLinkTitle: 'Aide et documentation de cet outil', descriptionLoadText: 'Chargement de la description ...' },		delayInsertBtn: 'Set delay in ms', delayInsert: 'How many ms to wait for a new image?', delayInvalid: 'Invalid input. Only numbers greater than 2500 are accepted.', playLinkText: 'Play', pauseLinkText: 'Pause', prevLinkText: 'Previous', nextLinkText: 'Next', hideText: 'Close slideshow', continueKeyHowTo: 'Continue Key - You can save this key or bookmark the link if you\'d like to start at this position later.', continueKeyInsert: 'Please insert the continue-key. You have to go forward in the slideshow to see effect.', continueKeyInsertBtn: 'Insert continue-key', continueKeyInvalid: 'Invalid key.', licenseLabel: 'Available Licenses: ', uploaderLabel: 'Uploader: ', helpLinkTitle: 'Help and documentation for this tool', descriptionLoadText: 'Loading description ...' };	if (i18n[mw.config.get('wgUserLanguage')]) { $.extend(i18n, i18n[mw.config.get('wgUserLanguage')]); }	var defaults = { delay: 7000, preloadAhead: 25, playLinkIcon: '//upload.wikimedia.org/wikipedia/commons/thumb/9/93/Gnome-media-playback-start.svg/35px-Gnome-media-playback-start.svg.png', pauseLinkIcon: '//upload.wikimedia.org/wikipedia/commons/thumb/0/04/Gnome-media-playback-pause.svg/35px-Gnome-media-playback-pause.svg.png', prevLinkIcon: '//upload.wikimedia.org/wikipedia/commons/thumb/9/92/Gnome-media-skip-backward.svg/35px-Gnome-media-skip-backward.svg.png', nextLinkIcon: '//upload.wikimedia.org/wikipedia/commons/thumb/7/73/Gnome-media-skip-forward.svg/35px-Gnome-media-skip-forward.svg.png', descriptionSpinner: '//bits.wikimedia.org/skins-1.5/common/images/ajax-loader.gif', enableKeyboardNavigation: true, autoPlay: false, defaultTransitionDuration: 700, maxImageHeight: Math.floor(($(window).height - 125)/50) * 50, // using Interval-Sizes to reduce server-load (cached thumbs) maxImageWidth: Math.floor(($(window).width - 50 - Math.max(Math.min($(window).width*0.2, 320), 180) )/50) * 50, cmdir: 'asc', continueKey: '', continueKeyPattern: isCategory ? /^file\|[\da-fA-F]+\|\d+$/ : /\d+\|.+/, licenseRecognization: [ // RegExp for the tag			note to add to the thumb-page [/Category:CC[\- _]BY-SA.*/i,	'CC-By-SA'], [/Category:CC[\- _]BY.*/i,		'CC-By'], [/Category:CC[\- _]Zero.*/i,	'CC0'], [/Category:GFDL.*/i,			'GFDL'], [/Category:PD[\- _]Old.*/i,		'PD-old'], [/Category:PD[\- _]self.*/i,	'PD-self'], [/Category:PD[\- _]author.*/i,	'PD-author'], [/Category:PD.*/i,				'PDx'], [/Category:FAL/i,				'Art Libre - Free Art'], [/Category:Images requiring attribution/i,		'Attribution'], [/Category:Copyrighted free use.*/i,			'Copyrighted FreeUse'], [/Category:Mozilla Public License/i,			'MPL'], [/Category:GPL/i,								'GPL'], [/Category:LGPL/i,								'LGPL'], [/Category:Free screenshot.*/i,					'free-Screenshot'] ],		onSlideChange: function (prevIndex, nextIndex) { var displayed = Math.floor(this.$thumbsUl.parent.width / 81); var spaceRight = displayed - (nextIndex - this.hiddenLeft); var spaceLeft = (1 + nextIndex - this.hiddenLeft); if (spaceRight < 3) { //Time to slide viewport var current = this.$thumbsUl.css('left').replace('px', ''); var offset = (parseFloat(current) - (3 - spaceRight) * 81); this.$thumbsUl.animate({					left: offset + 'px'				}, 'fast'); this.hiddenLeft = this.hiddenLeft + (3 - spaceRight); }			if (spaceLeft < 3 && nextIndex > 1) { var current = this.$thumbsUl.css('left').replace('px', ''); var offset = (parseFloat(current) + (3 - spaceLeft) * 81); this.$thumbsUl.animate({					left: offset + 'px'				}, 'fast'); this.hiddenLeft = this.hiddenLeft - (3 - spaceLeft); }			if (nextIndex === 0) { this.$thumbsUl.animate({					left: '0px'				}, 'fast'); this.hiddenLeft = 0; }			if (this.data.length - 5 < nextIndex) { //Time to fetch more this.queryApi; }		},		// accepts a delegate like such: function(prevIndex, nextIndex) { ... }		onTransitionOut: undefined, // accepts a delegate like such: function(slide, caption, isSync, callback) { ... }		onTransitionIn: undefined };	// Primary Galleriffic initialization function that should be called on the thumbnail container. $.fn.galleriffic = function (settings) { // Extend Gallery Object $.extend(this, {			// Returns the version of the script			version: $.galleriffic.version,			// Current state of the slideshow			isSlideshowRunning: false,			slideshowTimeout: undefined,			hiddenLeft: 0,			apiURL: mw.util.wikiScript( 'api' ),			indexURL: mw.util.wikiScript( 'index' ),			initial: true,			data: [],			// This function is attached to the click event of generated hyperlinks within the gallery			clickHandler: function (e, link) {				this.pause;				// The href attribute holds the unique hash for an image				var hash = $.galleriffic.normalizeHash($(link).attr('href'));				$.galleriffic.gotoImage(hash);				e.preventDefault;			},			createContainer: function {				var gallery = this;				this.$slideshowContainer = $(' '); 				this.$imageContainer = $(' ');				this.$captionContainer = $(' ');				this.$loadingContainer = $(' ');				this.$controlsContainer = $(' ');				// Gray lines for navigation this.$ctrBack = $(' ', { 'class': 'bar-rwd' } ) .append($(' ', { 'class': 'bar-btn-rwd' }).text('<')) .click(function (e) { gallery.previous; e.preventDefault; }) .mouseenter(function { $(this).find('div').fadeIn('fast'); }).mouseleave(function  { $(this).find('div').fadeOut('fast'); }); this.$ctrFwd = $(' ', { 'class': 'bar-fwd' } ) .append( $(' ', { 'class': 'bar-btn-fwd' }).text('>')) .click(function (e) { gallery.next; e.preventDefault; }) .mouseenter(function { $(this).find('div').last.fadeIn('fast'); }).mouseleave(function  { $(this).find('div').last.fadeOut('fast'); }); this.$closeButton = $(' ', { 'class': 'slideshow-close-button', 'title' : this.hideText } ) .text('×').click(function (e) {						gallery.pause;						gallery.toggleVisibility;						return false; // stop propagation & prevent default					}); this.append('  '); this.append(this.$controlsContainer).append( this.$slideshowContainer ); this.$slideshowContainer.append(this.$loadingContainer).append(this.$captionContainer).append(this.$imageContainer); this.append(this.$ctrBack).append(this.$ctrFwd.prepend(this.$closeButton)); this.$thumbsUl = this.find('ul.thumbs'); },			// Scrapes the thumbnail container for thumbs and adds each to the gallery initializeThumbs: function { var data = this.passedData; var gallery = this; for (i in data) { imageData = data[i]; imageData.index = hash = imageCounter; imageData.gallery = gallery; var aspect = (imageData.width / imageData.height); var size = (aspect > 1) ? 'height' : 'width'; var $thumb = $(' '); $thumb.css('opacity', 0.67).hover(					function {						$(this).not('.selected').fadeTo('fast', 1);					}, function  {						$(this).not('.selected').fadeTo('fast', 0.67);					}); this.$thumbsUl.append($thumb); imageData.caption = $(' ').append( $('', { href: imageData.link }).text(imageData.title.replace('File:', ).replace(/\.[\w]{3,4}$/, )) ).html; // Register the image globally allImages['' + hash] = imageData; // Setup attributes and click handler $thumb.find('a').attr('href', '#' + hash).removeAttr('name').click(function (e) {						gallery.clickHandler(e, this);					}); imageCounter++; }				this.data = this.data.concat(data); return this; },			isPreloadComplete: false, // Initalizes the image preloader preloadInit: function { if (this.preloadAhead === 0) return this; this.preloadStartIndex = this.currentImage.index; var nextIndex = this.getNextIndex(this.preloadStartIndex); return this.preloadRecursive(this.preloadStartIndex, nextIndex); },			// Changes the location in the gallery the preloader should work // @param {Integer} index The index of the image where the preloader should restart at. preloadRelocate: function (index) { // By changing this startIndex, the current preload script will restart this.preloadStartIndex = index; return this; },			// Recursive function that performs the image preloading // @param {Integer} startIndex The index of the first image the current preloader started on. // @param {Integer} currentIndex The index of the current image to preload. preloadRecursive: function (startIndex, currentIndex) { // Check if startIndex has been relocated if (startIndex != this.preloadStartIndex) { var nextIndex = this.getNextIndex(this.preloadStartIndex); return this.preloadRecursive(this.preloadStartIndex, nextIndex); }				var gallery = this; // Now check for preloadAhead count var preloadCount = currentIndex - startIndex; if (preloadCount < 0) preloadCount = this.data.length - 1 - startIndex + currentIndex; if (this.preloadAhead >= 0 && preloadCount > this.preloadAhead) { // Do this in order to keep checking for relocated start index setTimeout(function {						gallery.preloadRecursive(startIndex, currentIndex);					}, 500); return this; }				var imageData = this.data[currentIndex]; if (!imageData) return this; // If already loaded, continue if (imageData.image) return this.preloadNext(startIndex, currentIndex); // Preload the image var image = new Image; image.onload = function { imageData.image = this; gallery.preloadNext(startIndex, currentIndex); };				image.alt = imageData.title; image.src = imageData.slideUrl; return this; },			// Called by preloadRecursive in order to preload the next image after the previous has loaded. // @param {Integer} startIndex The index of the first image the current preloader started on. // @param {Integer} currentIndex The index of the current image to preload. preloadNext: function (startIndex, currentIndex) { var nextIndex = this.getNextIndex(currentIndex); if (nextIndex === startIndex) { this.isPreloadComplete = true; } else { // Use setTimeout to free up thread var gallery = this; setTimeout(function {						gallery.preloadRecursive(startIndex, nextIndex);					}, 100); }				return this; },			// Safe way to get the next image index relative to the current image. // If the current image is the last, returns 0 getNextIndex: function (index) { var nextIndex = index + 1; if (nextIndex >= this.data.length) nextIndex = 0; return nextIndex; },			// Safe way to get the previous image index relative to the current image. // If the current image is the first, return the index of the last image in the gallery. getPrevIndex: function (index) { var prevIndex = index - 1; if (prevIndex < 0) prevIndex = this.data.length - 1; return prevIndex; },			// Pauses the slideshow pause: function { this.isSlideshowRunning = false; $(document).triggerHandler('slideshow', ['actionPause', this]); // For external scripts if (this.slideshowTimeout) { clearTimeout(this.slideshowTimeout); this.slideshowTimeout = undefined; }				if (this.$controlsContainer) { this.$controlsContainer.find('div.nav-controls a.pause').removeClass.addClass('play').attr('title', this.playLinkText).attr('href', '#play') .html(''); }				return this; },			// Plays the slideshow play: function { this.isSlideshowRunning = true; $(document).triggerHandler('slideshow', ['actionPlay', this]); // For external scripts if (this.$controlsContainer) { this.$controlsContainer.find('div.nav-controls a.play').removeClass.addClass('pause').attr('title', this.pauseLinkText).attr('href', '#pause') .html(''); }				if (!this.slideshowTimeout) { var gallery = this; this.slideshowTimeout = setTimeout(function {						gallery.next(true);					}, this.delay); }				return this; },			// Toggles the state of the slideshow (playing/paused) toggleSlideshow: function { if (this.isSlideshowRunning) this.pause; else this.play; return this; },			// Advances the gallery to the next image. // @param {Boolean} dontPause Specifies whether to pause the slideshow. next: function (dontPause) { this.gotoIndex(this.getNextIndex(this.currentImage.index), dontPause); return this; },			// Navigates to the previous image in the gallery. // @param {Boolean} dontPause Specifies whether to pause the slideshow. previous: function (dontPause) { this.gotoIndex(this.getPrevIndex(this.currentImage.index), dontPause); return this; },			// Navigates to the image at the specified index in the gallery // @param {Integer} index The index of the image in the gallery to display. // @param {Boolean} dontPause Specifies whether to pause the slideshow. gotoIndex: function (index, dontPause) { if (!dontPause) this.pause; if (index < 0) index = 0; else if (index >= this.data.length) index = this.data.length - 1; var imageData = this.data[index]; this.gotoImage(imageData); return this; },			// This function is guaranteed to be called anytime a gallery slide changes. // @param {Object} imageData An object holding the image metadata of the image to navigate to. gotoImage: function (imageData) { var index = imageData.index; if (this.onSlideChange) this.onSlideChange(this.currentImage.index, index); this.currentImage = imageData; this.preloadRelocate(index); this.refresh; return this; },			// Returns the default transition duration value. The value is halved when not // performing a synchronized transition. // @param {Boolean} isSync Specifies whether the transitions are synchronized. getDefaultTransitionDuration: function (isSync) { if (isSync) return this.defaultTransitionDuration; return this.defaultTransitionDuration / 2; },			// Rebuilds the slideshow image and controls and performs transitions refresh: function { var imageData = this.currentImage; if (!imageData) return this; var index = imageData.index; var previousSlide = this.$imageContainer.find('span.current').addClass('previous').removeClass('current'); var previousCaption = 0; if (this.$captionContainer) { previousCaption = this.$captionContainer.find('span.current').addClass('previous').removeClass('current'); }				// Perform transitions simultaneously if the next image is already preloaded var isSync = imageData.image; // Flag we are transitioning var isTransitioning = true; var gallery = this; var transitionOutCallback = function { // Flag that the transition has completed isTransitioning = false; // Remove the old slide previousSlide.remove; // Remove old caption if (previousCaption) previousCaption.remove; if (!isSync) { if (imageData.image && imageData.index === gallery.data[gallery.currentImage.index].index) { gallery.buildImage(imageData, isSync); } else { // Show loading container if (gallery.$loadingContainer) { gallery.$loadingContainer.show; }						}					}				};				if (previousSlide.length === 0) { // For the first slide, the previous slide will be empty, so we will call the callback immediately transitionOutCallback; } else { previousSlide.fadeTo(this.getDefaultTransitionDuration(isSync), 0.0, transitionOutCallback); if (previousCaption) previousCaption.fadeTo(this.getDefaultTransitionDuration(isSync), 0.0); }				// Go ahead and begin transitioning in of next image if (isSync) this.buildImage(imageData, isSync); if (!imageData.image) { var image = new Image; // Wire up mainImage onload event image.onload = function { imageData.image = this; // Only build image if the out transition has completed and we are still on the same image hash if (!isTransitioning && imageData.index === gallery.data[gallery.currentImage.index].index) { gallery.buildImage(imageData, isSync); }					};					// set alt and src image.alt = imageData.title; image.src = imageData.slideUrl; }				// This causes the preloader (if still running) to relocate out from the currentIndex this.relocatePreload = true; return this.syncThumbs; },			// Called by the refresh method after the previous image has been transitioned out or at the same time // as the out transition when performing a synchronous transition. // @param {Object} imageData An object holding the image metadata of the image to build. // @param {Boolean} isSync Specifies whether the transitions are synchronized. buildImage: function (imageData, isSync) { var gallery = this; var nextIndex = this.getNextIndex(imageData.index); // computing the "center-position of the space" var hSpace = (this.$imageContainer.width - this.$captionContainer.position.left - this.$captionContainer.width); var left = this.$captionContainer.position.left + this.$captionContainer.width + (hSpace - imageData.width) / 2; var vSpace = this.$imageContainer.height - 130; var top = (vSpace - imageData.height) / 2; // Send a XHrequest in case of unknown description if ('string' !== typeof imageData.description) this.queryFile(imageData.title); if ('string' !== typeof this.data[nextIndex].description) this.queryFile(this.data[nextIndex].title); // Construct new hidden span for the image var newSlide = this.$imageContainer.append($(' ', { 'class': 'image-wrapper current', style: 'left:' + left + 'px; top:' + top + 'px; ' })					.append($('', { 'class': 'advance-link', href: imageData.link, title: imageData.title, target: '_blank', style: 'width:' + imageData.width + 'px; ' } ))).find('span.current').css('opacity', '0'); newSlide.find('a').append(imageData.image); var descript = imageData.description ? imageData.description : $(' ').append($(' ', { src: this.descriptionSpinner, height: 20, width: 20 }), mw.html.escape(this.descriptionLoadText)); var newCaption = 0; var extraParams = '&gsDir=' + this.cmdir + '&gsAutoStart=1' + (mw.util.getParamValue('withJS') ? ('&withJS=' + mw.util.getParamValue('withJS')) : '' ) + (mw.util.getParamValue('withCSS') ? ('&withCSS=' + mw.util.getParamValue('withCSS')) : '' ); if (this.$captionContainer) { // Construct new hidden caption for the image newCaption = this.$captionContainer.append( $(' ', { 'class': 'image-caption current', style: 'height:' + (this.maxImageHeight - 20) + 'px;' }) ).find('span.current').css('opacity', '0') .append(imageData.caption, $(' ')) .append( $(' ', { 'class': 'gs-img-description', id: 'desc' + imageData.index }).append(descript) ) .append( $(' ', { 'class': 'gs-img-uploader' }).append(imageData.$user.clone) ) .append( imageData.$cats, imageData.$licenses, $(' ') ) .append( $(' ', { 'class': 'gs-img-metrics' }).html('(' + imageData.oWidth + '×' + imageData.oHeight + ' (' + imageData.oSize + '))') ) .append( (imageData.contKey ? $(' ', { 'class': 'cont-key-container', title: this.continueKeyHowTo }).append( 								$('', { href: mw.util.getUrl(mw.config.get('wgPageName')) + '?gsContinue=' + imageData.contKey + extraParams, target: '_blank' } ).text(imageData.contKey) ) : '' ) );				}				// Hide the loading conatiner if (this.$loadingContainer) { this.$loadingContainer.hide; }				// Transition in the new image if (this.onTransitionIn) { this.onTransitionIn(newSlide, newCaption, isSync); } else { newSlide.fadeTo(this.getDefaultTransitionDuration(isSync), 1.0); if (newCaption) newCaption.fadeTo(this.getDefaultTransitionDuration(isSync), 1.0); }				if (this.isSlideshowRunning) { if (this.slideshowTimeout) clearTimeout(this.slideshowTimeout); this.slideshowTimeout = setTimeout(function {						gallery.next(true);					}, this.delay); }				// Save the current position in a cookie or delete the cookie if (imageData.contKey) { this.saveContinueKey(imageData.contKey); } else { this.saveContinueKey(null); }				$(document).triggerHandler('slideshow', ['newSlide', this]); // For external scripts return this; },			saveContinueKey: function (key) { mw.cookie.get( 'gs' + mw.config.get('wgPageName').replace('Category:', '1:').replace('Commons:', '2:'), key, { expires: 8 } ); },			getContinueKey: function { return mw.cookie.get( 'gs' + mw.config.get('wgPageName').replace('Category:', '1:').replace('Commons:', '2:') ); },			// Applies the selected class to the current image's corresponding thumbnail. // Also checks if the current page has changed and updates the displayed page of thumbnails if necessary. syncThumbs: function { // Remove existing selected class and add selected class to new thumb var $thumbs = this.$thumbsUl.children; $thumbs.filter('.selected').removeClass('selected').fadeTo('fast', 0.67); $thumbs.eq(this.currentImage.index).addClass('selected').fadeTo('fast', 1); return this; },			init: function { this.createContainer; var that = this; $(window).resize(function { 					that.maxImageHeight = Math.floor(($(window).height - that.$thumbsUl.height - that.$controlsContainer.height) / 50) * 50;  					that.maxImageWidth = Math.floor((that.$slideshowContainer.width - that.$captionContainer.width - 16) / 50) * 50;					that.css('height', $(window).height + 'px');				}).resize; // Initialize the thumbails this.initializeThumbs; this.currentImage = this.data[0]; var gallery = this; // Hide the loadingContainer this.$loadingContainer.hide; this.gotoIndex(0); // Setup controls var playBtn, nextBtn, prevBtn, navCont; if (this.autoPlay) { playBtn = $('' + '' + ''); } else { playBtn = $('' + '' + ''); }				playBtn.click(function (e) {					gallery.toggleSlideshow;					e.preventDefault;				}); prevBtn = $('<a class="prev" href="#" title="' + this.prevLinkText + '">' + '<img src="' + this.prevLinkIcon + '" height="35" width="35" alt="' + this.prevLinkText + '"/>' + '</a>'); nextBtn = $('<a class="next" href="#" title="' + this.nextLinkText + '">' + '<img src="' + this.nextLinkIcon + '" height="35" width="35" alt="' + this.nextLinkText + '"/>' + '</a>'); prevBtn.click(function (e) {					gallery.previous;					e.preventDefault;				}); nextBtn.click(function (e) {					gallery.next;					e.preventDefault;				}); navCont = $(' '); navCont.hover( function { $(this).fadeTo('fast', 0.75) }, function { $(this).fadeTo('fast', 0.4) }); this.$controlsContainer.append( navCont.append(prevBtn, playBtn, nextBtn)); // Option icons this.$continueKey = $('<a>', { 'class': 'continue-key-insert', href: '#', title: gallery.continueKeyInsertBtn }) .append($(' ', {style: 'width:16px'})) .click( function (e) {						e.preventDefault;						var ckey = prompt(gallery.continueKeyInsert, gallery.cont ? gallery.cont : '' );						ckey = $.trim(ckey);						if (gallery.continueKeyPattern.test(ckey)) {							gallery.cont = ckey;						} else {							alert(gallery.continueKeyInvalid);						}					}); var $setDelay = $('<a>', { 'class': 'delay-insert', href: '#', title: gallery.delayInsertBtn }) .append($(' ', {style: 'width:16px'})) .click( function (e) {						e.preventDefault;						var delay = prompt(gallery.delayInsert, gallery.delay ? gallery.delay :  );						if (!delay) return;						delay = $.trim( delay.replace(/ms|s/, ) );						if (/^\d+$/.test(delay)) {							if (delay > 2499) {								gallery.delay = delay;							} else if ((0 < delay) && (delay < 61)) {								gallery.delay = delay * 1000;							} else {								alert(gallery.delayInvalid);							}							// Set cookie							mw.cookie.set('slideshow-delay', gallery.delay, { expires: 100, path: '/' });						} else {							alert(gallery.delayInvalid);						}					}); var $helpLink = $('<a>', { 'class': 'gs-help-link', href: mw.util.getUrl('Help:Slideshow'), title: gallery.helpLinkTitle, target: '_blank' }) .append($(' ', {style: 'width:16px'})); var otherCont = $(' ', { 'class' : 'other-controls'} ); this.$controlsContainer.append( otherCont.append( this.$continueKey, $setDelay, $helpLink ) ); otherCont.hover( function { $(this).fadeTo('fast', 1) }, function { $(this).fadeTo('fast', 0.6) }); // Setup Keyboard Navigation if (this.enableKeyboardNavigation) { var hidingEnabled = true; $(document).keydown(function (e) {						var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;						switch (key) {						case 32:							// space							gallery.next;							e.preventDefault;							break;						case 35:							// End							gallery.gotoIndex(gallery.data.length - 1);							e.preventDefault;							break;						case 37:							// left arrow							gallery.previous;							e.preventDefault;							break;						case 39:							// right arrow							gallery.next;							e.preventDefault;							break;						}					}); $(document).keyup(function (e) {						var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;						//Hide on escape						if ($('#SlideContainer').height && key == 27) {							gallery.pause;							gallery.toggleVisibility;						}					}); }				// Auto start the slideshow if (this.autoPlay) this.play; // Kickoff Image Preloader after 1 second setTimeout(function {					gallery.preloadInit;				}, 1000); $(document).triggerHandler('slideshow', ['shown', this]); // For external scripts },			start: function { $(document).triggerHandler('slideshow', ['starting', this]); // For external scripts $('#GallerySlideInit').hide; $('#GallerySlideContinue').hide; $('#SlideContainer').animate({					height: $(window).height + 'px'				}); //Once done, hide scrollbar if ( !$.browser.msie ) { // disabled for IE 6/7 $('body').css('overflow', 'hidden'); }				// Settings from URL var autoPlay = mw.util.getParamValue('gsAutoPlay'); if (autoPlay) { if ('1' === autoPlay || 'true' === autoPlay || 'yes' === autoPlay || '-1' === autoPlay) { this.autoPlay = true; } else { this.autoPlay = false; }				}				var delay = mw.util.getParamValue('gsDelay') || mw.cookie.get('slideshow-delay'); if (delay) { if (/^\d+$/.test(delay)) { if (delay > 2499) { this.delay = delay; } else if ((3 < delay) && (delay < 61)) { this.delay = delay * 1000; }					}				}				var cmdir = mw.util.getParamValue('gsDir'); if (cmdir) { if ('climbing' === cmdir || 'ascending' === cmdir || 'asc' === cmdir || '123' === cmdir || 'rising' === cmdir) { this.cmdir = 'asc'; } else { this.cmdir = 'desc'; }				}				var cmcontinue = mw.util.getParamValue('gsContinue'); if (cmcontinue) { if (this.continueKeyPattern.test(cmcontinue)) { this.cont = cmcontinue; } else { this.cont = ''; }				}				this.queryApi; if ( $.browser.msie ) { setTimeout( function { 						window.location.hash = "#SlideContainer"; 				}, 	2000); // For IE 6 }			},			toggleVisibility: function { $('#GallerySlideInit').toggle.unbind('click').click(GallerySlide.toggleVisibility); $('#SlideContainer').slideToggle; $('body').css('overflow', 'visible'); $(document).triggerHandler('slideshow', ['visibility', GallerySlide]); // For external scripts },			queryFile: function ( title ) { var _this = this; params = { action: 'render', title: title };				$.ajax({					url: this.indexURL,					cache: true,					dataType: 'html',					data: params,					type: 'GET',					success: function (result, status, x) {						_this.processDetails(result, title);					}				}); },			processDetails: function ( result, title ) { if ('string' !== typeof result) return; var i,					dItem, dDescription, $node, parsedDOM = $(result); // dTitle = result.match(/File\:(.+\..{3,5})\&amp;/)[1].replace(/_/g, ' '); // superflous? title ever right? parsedDOM.find('table, div').attr('style', ''); parsedDOM.find('table').attr('cellspacing', 1).attr('cellpadding', 0); dDescription = $(' ').append( 					$('#fileinfotpl_desc', parsedDOM).siblings.eq(0).contents, 					$('#fileinfotpl_aut', parsedDOM).siblings.eq(0).contents,					$('#fileinfotpl_date', parsedDOM).siblings.eq(0).contents				).html; if (!dDescription) dDescription = 'Unable to determine description.'; for (i in this.data) { dItem = this.data[i]; if (dItem.title === title) { dItem.description = dDescription; $node = $('#desc' + i); if ($node.length !== 0) $node.html(dDescription); }				}			},			queryApi: function { var _this = this; $(document).triggerHandler('slideshow', ['beforeQuery', this]); // For external scripts if (isCategory) { params = { action: 'query', rawcontinue: '', generator: 'categorymembers', gcmtitle: mw.config.get('wgPageName'), gcmlimit: Math.floor($('#SlideContainer').width / 81) + 1, gcmtype: 'file', gcmdir: this.cmdir, prop: 'imageinfo|categories', clprop: 'sortkey|hidden', cllimit: 500, iiprop: 'url|user|size', iilimit: 500, iiurlwidth: this.maxImageWidth, iiurlheight: this.maxImageHeight, format: 'json' };					if (this.cont) params.gcmcontinue = this.cont; } else { params = { action: 'query', rawcontinue: '', generator: 'images', titles: mw.config.get('wgPageName'), gimlimit: Math.floor($('#SlideContainer').width / 81) + 1, prop: 'imageinfo|categories', clprop: 'hidden', cllimit: 500, iiprop: 'url|user|size', iilimit: 500, iiurlwidth: this.maxImageWidth, iiurlheight: this.maxImageHeight, format: 'json' };					if (this.cont) params.gimcontinue = this.cont; }				if (!this.initial && !this.cont) return; $.ajax({					url: this.apiURL,					cache: false,					dataType: 'json',					data: params,					type: 'POST',					success: function (result, status, x) {						_this.processReturn(result);					}				}); },			processReturn: function (result) { $(document).triggerHandler('slideshow', ['afterQuery', this]); // For external scripts var pages = result.query.pages, data = [], i = 0; if (result['query-continue']) { if ('undefined' !== typeof this.cont) { this.contOld = this.cont; }					this.cont = isCategory ? result['query-continue'].categorymembers.gcmcontinue : result['query-continue'].images.gimcontinue; }				else this.cont = false; // Fromatt a number var fm = function( iNr ) { iNr += ''; var rx = /(\d+)(\d{3})/; while (rx.test(iNr)) { iNr = iNr.replace(rx, '$1' + ' ' + '$2'); }					return iNr; };				for (var id in pages) { var v = pages[id]; if ('undefined' !== typeof v.missing || !v.categories || !v.imageinfo) { continue; }					var r = v.imageinfo[v.imageinfo.length - 1], rc = v.imageinfo[0], n = data[i] = {}, sortkey = '', $cats = $(' ', { 'class': 'cat-wrap' }), $licenses = $(' ', { 'class': 'license-wrap' }).text(this.licenseLabel); // Process categories; Extract visible cats, sortkey for current cat, licenses processCats: for (var c in v.categories) { var tCat = v.categories[c]; if (isCategory && tCat.title === mw.config.get('wgPageName').replace(/_/g, ' ')) sortkey = 'file' + '|' + tCat.sortkey + '|' + id; if ('undefined' === typeof tCat.hidden) { $cats.append( $('<a>', { 'class': 'cat-label', href: mw.util.getUrl(tCat.title), target: '_blank' }).text(tCat.title.replace('Category:', '')), ' ' ); } else { for (var recogID in this.licenseRecognization) { if (this.licenseRecognization[recogID][0].test(tCat.title)) { $licenses.append( $(' ', { 'class': 'license-label', title: tCat.title.replace('Category:', '') }).html(this.licenseRecognization[recogID][1]), ' ' ); continue processCats; }							}						}					}					if (!isCategory) sortkey = mw.config.get('wgArticleId') + '|' + v.title.replace('File:', ''); n.title = v.title; n['link'] = rc.descriptionurl; n.slideUrl = rc.thumburl; n.width = rc.thumbwidth; n.height = rc.thumbheight; n.oWidth = fm(r.width); n.oHeight = fm(r.height); n.oSize = fm(r.size >> 10) + ' <abbr title="1 KibiByte= 1024 Bytes">KiB '; n.$user = $(' ').text(this.uploaderLabel).append(						$('<a>', { href: mw.util.getUrl(mw.config.get('wgFormattedNamespaces')[2] + ':' + r.user), target: '_blank' }).text(r.user),						' (', $('<a>', { href: mw.util.getUrl(mw.config.get('wgFormattedNamespaces')[3] + ':' + r.user), target: '_blank' }).text('talk'), ')'					);					n.$cats = $cats; n.$licenses = $licenses; n.contKey = (sortkey || this.contOld); i++; }				this.passedData = data; if (this.initial) { this.init; } else { this.initializeThumbs; }				this.initial = false; }		});		// Now initialize the gallery		$.extend(this, defaults, i18n, settings);		return this;	}; })(jQuery); $(document).ready(function {	if ($('.gallery li').length < 2) return; // no need for a gallery with a few images	mw.loader.using(['mediawiki.cookie', 'mediawiki.html', 'mediawiki.util'], function  { $('body').append(' '); window.GallerySlide = $('#SlideContainer').galleriffic; $(document).triggerHandler('slideshow', ['codeLoaded', window.GallerySlide]); // For external scripts }); }); }