Jump to content

User:Kangaroopower/AjaxRC.js

From Wikipedia, the free encyclopedia
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
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> */