Jump to content

User:Kangaroopower/AjaxRC.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/* <syntaxhighlight lang="javascript"> */
/*
 * ADVANCED AJAX AUTO-REFRESHING ARTICLES
 *
 * Original by pcj of Wowpedia
 * Maintenance, cleanup, style and bug fixes by:
 *   Grunny (http://c.wikia.com/wiki/User:Grunny)
 *   Kangaroopower (http://en.wikipedia.org/wiki/User:Kangaroopower)
 *   Cqm (http://c.wikia.com/wiki/User:Cqm)
 */

/*jshint browser:true, camelcase:true, curly:true, eqeqeq:true, immed:true, jquery:true, latedef:true, newcap:true, noarg:true, noempty:true, nonew:true, quotmark:single, trailing:true, undef:true, unused:true, onevar:true */
/*global mediaWiki:true */

;( function ( window, $, mw, dev ) {
	'use strict';

	var config = dev.ajaxRC || {},
		ns = {};
		
	// Some util stuff for AjaxRC
	ns.util = {
		mw: mw.config.get( [
			'stylepath',
			'wgAction',
			'wgCanonicalSpecialPageName',
			'wgPageName'
		] ),
		timer: false
	};

	// AjaxRC config
	// Maintain backwards compatibility with older configuration options
	ns.config = {
		pages: config.pages || window.ajaxPages || [ 'Special:RecentChanges' ],
		// use common file for default as it's very likely to be already cached by user
		// used in oasis sidebar loading, preview modal, etc.
		indicator: config.indicator || window.ajaxIndicator || ns.util.mw.stylepath + '/common/images/ajax.gif',
		refresh: config.refresh || window.ajaxRefresh || 60000,
		text: config.text || window.AjaxRCRefreshText || 'AJAX',
		hovertext: config.hovertext ||  window.AjaxRCRefreshHoverText || 'Enable auto-refreshing page loads'
	};

	/**
	 * storage function to save checkbox value for future use
	 * @param setTo {boolean} If given, this is the value saved to localStorage
	 *                        that contains whether the ajaxRC checkbox is checked (true)
	 *                        or isn't checked (false)
	 */
	ns.storage = function ( setTo ) {
		if ( localStorage.getItem( 'AjaxRC-refresh' ) === null ) {
			localStorage.setItem( 'AjaxRC-refresh', true );
		}

		if ( typeof setTo === 'boolean' ) {
			localStorage.setItem( 'AjaxRC-refresh', setTo );
		}

		return JSON.parse( localStorage.getItem( 'AjaxRC-refresh' ) );
	};


	/**
	 * Main function to start the Auto-refresh process
	 */
	ns.preloadAJAXRL = function () {
		var $appTo = $( '.firstHeading' ),
			$checkbox = $( '<span id="ajaxRefresh"></span>' )
				.css( { 'font-size': 'xx-small', 'line-height': '100%', 'margin-left': '5px' } )
				.append(
					$( '<label id="ajaxToggleText" for="ajaxToggle"></label>' )
						.css( { 'border-bottom': '1px dotted', 'cursor': 'help' } )
						.attr( 'title', ns.config.hovertext )
						.text( ns.config.text + ':' ),
					$( '<input type="checkbox" id="ajaxToggle">' )
						.css( { 'margin-bottom': 0 } ),
					$( '<span id="ajaxLoadProgress"></span>' )
						.css( 'display', 'none' )
						.append(
							$( '<img>' )
								.css( { 'vertical-align': 'baseline', 'float': 'none', 'border': 0 } )
								.attr( {'src': ns.config.indicator, 'alt': 'Refreshing page' } )
						)
				),
			$throbber;

		// fallback for pages with profile masthead
		$appTo.append( $checkbox );

		$throbber = $appTo.find( '#ajaxLoadProgress' );

		$( document ).ajaxSend( function ( event, xhr, settings ) {
			if ( location.href === settings.url ) {
				$throbber.show();
			}
		} ).ajaxComplete ( function ( event, xhr, settings ) {
			var $collapsibleElements = $( '#mw-content-text' ).find( '.mw-collapsible' ),
				i;

			ns.config.ajCallAgain = dev.ajaxRC.ajaxCallAgain || window.ajaxCallAgain || [];

			if ( location.href === settings.url ) {
				$throbber.hide();
				if ( $collapsibleElements.length ) {
					$collapsibleElements.makeCollapsible();
				}
				if ( ns.util.mw.wgCanonicalSpecialPageName === 'Recentchanges' ) {
					mw.special.recentchanges.init();
				}
				for ( i = 0; i < ns.config.ajCallAgain.length; i++ ) {
					if ( $.isFunction( ns.config.ajCallAgain[i] ) ) {
						ns.config.ajCallAgain[i]();
					}
				}
			}
		} );
		$( '#ajaxToggle' ).click( ns.toggleAjaxReload );
		$( '#ajaxToggle' ).attr( 'checked', ns.storage() );
	};

	/**
	 * Turn refresh on and off by toggling the checkbox
	 */
	ns.toggleAjaxReload = function () {
		if ( $( '#ajaxToggle' ).prop( 'checked' ) ) {
			ns.storage( true );
			ns.loadPageData();
		} else {
			ns.storage( false );
			clearTimeout( ns.util.timer );
		}
	};

	/**
	 * Does the actual refresh
	 */
	ns.loadPageData = function () {
		var $temp = $( '<div>' );

		$temp.load( location.href + ' #mw-content-text', function () {
			var $newContent = $temp.children( '#mw-content-text' );

			if ( $newContent.length ) {
				$( '#mw-content-text' ).replaceWith( $newContent );
			}

			ns.util.timer = setTimeout( ns.loadPageData, ns.config.refresh );
		} );
		$temp.remove();
	};

	/**
	 * Load the script on specific pages
	 * and only on certain values for wgAction (see disallowActions below)
	 */
	ns.init = function () {
		// don't load on these values of wgAction
		// @todo check if markpatrolled should be here
		var disallowActions = [
			'delete',
			'edit',
			'protect',
			'revisiondelete'
		];
		
		if (
			$.inArray( ns.util.mw.wgPageName, ns.config.pages ) !== -1 &&
			!$( '#ajaxToggle' ).length &&
			$.inArray( ns.util.mw.wgAction, disallowActions ) === -1
		) {
			ns.preloadAJAXRL();
		}
	};
	
	/* Expose ajaxRC to the world */
	dev.ajaxRC = ns;

	$( ns.init ); //load script

}( this, jQuery, mediaWiki, window.dev = window.dev || {} ) );

/* </syntaxhighlight> */