Note: After saving, changes may not occur immediately. Click here to learn how to bypass your browser's cache.
  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (Cmd-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (Cmd-Shift-R on a Mac)
  • Internet Explorer: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Clear the cache in Tools → Preferences

For details and instructions about other browsers, see Wikipedia:Bypass your cache.

/* Page image carousel
 * ==================================================================
 * page_carousel.js
 *
 * Adds forward/back and reset arrows to the ProofreadPage edit mode image.
 *
 * This is useful for quickly checking things on the next/previous pages,
 * for example new paragraphs, running headers, and so on.
 *
 * Configuration is done with this hook
 *
 * mw.hook( "page_carousel.config" ).add(function(cfg) {
 *   cfg.debug = true;
 * });
 *
 * Options:
 * * debug: boolean, true to print debugging messages
 * ================================================================== */

( function () {

	const signature = 'page_carousel',
		version = '1.1';

	const CFG = {
		debug: false
	};

	mw.hook( signature + '.config' ).fire( CFG );

	mw.messages.set( {
		'ext.gadget.carousel.home': 'Return to original page ($1)',
		'ext.gadget.carousel.next': 'Load next page',
		'ext.gadget.carousel.prev': 'Load previous page',
		'ext.gadget.carousel.current': 'The currently visible page'
	} );

	let addedIndex;
	/* eslint-disable-next-line no-jquery/no-global-selector */
	const $prpImg = $( '.prp-page-image img' );

	// Gets the page number from the current page (assuming Page namespace)
	function getPageNum() {
		return parseInt( mw.config.get( 'wgPageName' ).split( /\// ).pop() );
	}

	const startPage = getPageNum();
	let currPage = startPage;

	let currPageLabel;

	const log = function ( s ) {
			if ( CFG.debug ) {
				/* eslint-disable-next-line no-console */
				console.log( signature + ': ' + s );
			}
		},

		setCurrPageLabel = function () {
			if ( currPageLabel ) {
				currPageLabel.$element
					.html( currPage )
					.css( 'font-style', ( currPage === startPage ) ? 'italic' : 'normal' );
			}
		},

		changePage = function () {

			log( 'Carousel changing page to page ' + currPage );

			if ( addedIndex === undefined ) {
				addedIndex = mw.proofreadpage.openseadragon.viewer.world.getItemCount();
			}

			const addedItem = mw.proofreadpage.openseadragon.viewer.world.getItemAt( addedIndex );

			// handler for when a highres image is set using the srcset attribute
			// tl'dr store it and restore it for the original page but us the normal images
			// for other pages
			if ( currPage === startPage ) {
				if ( addedItem ) {
					mw.proofreadpage.openseadragon.viewer.world.removeItem( addedItem );
					addedIndex = undefined;
				}
			} else {
				// TODO get from JS config
				const src = $prpImg.attr( 'src' ).replace( /page[0-9]+-/, 'page' + currPage + '-' );

				log( 'New image: ' + src );

				// set the new image source
				mw.proofreadpage.openseadragon.viewer
					.addSimpleImage( {
						index: addedIndex,
						replace: !!addedItem,
						url: src
					} );
			}

			// update label
			setCurrPageLabel();
		},

		advPage = function ( step ) {
			currPage += step;
			changePage();
		},

		resetPage = function () {
			currPage = startPage;
			changePage();
		},

		installCarousel = function () {
			const $controlBox = $( '<div>' )
					.attr( 'id', 'page-carousel-ctrls' )
					.css( {
						position: 'absolute',
						top: '0px',
						right: '0px'
					} ),

				// Create an icon.
				prevIcon = new OO.ui.IconWidget( {
					icon: 'previous',
					title: mw.msg( 'ext.gadget.carousel.next' )
				} ),

				nextIcon = new OO.ui.IconWidget( {
					icon: 'next',
					title: mw.msg( 'ext.gadget.carousel.next' )
				} ),

				resetIcon = new OO.ui.IconWidget( {
					icon: 'home',
					title: mw.msg( 'ext.gadget.carousel.home', startPage )
				} );

			currPageLabel = new OO.ui.LabelWidget( {
				label: 'Current',
				title: mw.msg( 'ext.gadget.carousel.current' )
			} );

			$( prevIcon.$element ).on( 'click', function () {
				advPage( -1 );
			} );
			$( nextIcon.$element ).on( 'click', function () {
				advPage( 1 );
			} );
			$( resetIcon.$element ).on( 'click', function () {
				resetPage();
			} );

			// Append the icons
			$controlBox.append( prevIcon.$element, resetIcon.$element, nextIcon.$element,
				currPageLabel.$element );

			$controlBox
				.find( '.oo-ui-iconWidget' )
				.css( 'cursor', 'pointer' );

			// mw.proofreadpage.$viewportControls
			$( '.prp-page-image' )
				.append( $controlBox );

			setCurrPageLabel();
		};

	$( function () {

		// only care for editing in the Page: namespace
		if ( !( mw.config.get( 'wgAction' ) === 'edit' || mw.config.get( 'wgAction' ) ===
				'submit' ) ||
			mw.config.get( 'wgCanonicalNamespace' ) !== 'Page' ) {
			return;
		}

		mw.loader.using( 'oojs-ui-core' ).done( function () {
			mw.hook( 'ext.proofreadpage.osd-controller-available' ).add( function () {
				log( 'Installing page image carousel. Version: ' + version );
				installCarousel();
			} );
		} );
	} );

}() );