MediaWiki:Gadget-DeluxeHistory.js

Une page de Wikiversité, la communauté pédagogique libre.

Note : après avoir publié vos modifications, il se peut que vous deviez forcer le rechargement complet du cache de votre navigateur pour voir les changements.

  • Firefox / Safari : maintenez la touche Maj (Shift) en cliquant sur le bouton Actualiser ou appuyez sur Ctrl + F5 ou Ctrl + R (⌘ + R sur un Mac).
  • Google Chrome : appuyez sur Ctrl + Maj + R (⌘ + Shift + R sur un Mac).
  • Internet Explorer / Edge : maintenez la touche Ctrl en cliquant sur le bouton Actualiser ou pressez Ctrl + F5.
  • Opera : appuyez sur Ctrl + F5.
/* [[Catégorie:MediaWiki:Fonction Monobook en JavaScript|DeluxeHistory.js]] */
/**
 * Nom : DeluxeHistory
 * Implémentation originale de Dake, basée sur du code Ajax de GôTô
 * Réécriture complète par Dr Brains et Od1n, avec améliorations de Ltrlg
 * Dépendances :
 *  — les habituelles implicites 'mediawiki' & 'jquery' ;
 *  — 'mediawiki.util' (fonctions mw.util.*) ;
 *  — 'user' (assure le chargement du common.js avant ce script, pour la configuration) ;
 *  — 'user.options' (pour tester si le gadget est coché dans les préférences) ;
 * {{Catégorisation JS|DeluxeHistory}}
 */

/*global document, localStorage, mw, $ */
/*jslint vars: true, plusplus: true */

mw.loader.using(['mediawiki.util', 'user', 'user.options'], function () {
	'use strict';

	if (!mw.user.options.get('gadget-DeluxeHistory')) {
		mw.loader.load( '/w/index.php?title=MediaWiki:Gadget-DeluxeHistory.css&action=raw&ctype=text/css', 'text/css' );
	}

	var botMembers, sysopMembers;

	/////////////////////////////////////// DÉTECTION SUPPORT LOCALSTORAGE ///////////////////////////////////////

	var supportLocalStorage;
	try {
		localStorage.setItem('modernizr', 'modernizr');
		localStorage.removeItem('modernizr');
		supportLocalStorage = true;
	} catch (e) {
		supportLocalStorage = false;
	}

	var dateNowUTC = Date.now();

	/////////////////////////////////////// FONCTIONS DE TRAITEMENT DES LIENS ///////////////////////////////////////

	var nsSpecial = mw.config.get('wgFormattedNamespaces')[-1] + ':';
	var watcherName = mw.config.get('wgUserName');

	function isUserIP(userlink) {
		// Les liens des IP sont de la forme « Spécial:Contributions/<IP> »
		return userlink.title.indexOf(nsSpecial) === 0;
	}

	function getUserClass(userlink) {
		var UserName = userlink.textContent;
		if (UserName === watcherName) { return 'UserIs-Self'; }
		if (botMembers.indexOf(UserName) > -1) { return 'UserIs-Bot'; }
		if (sysopMembers.indexOf(UserName) > -1) { return 'UserIs-Sysop'; }
		if (isUserIP(userlink)) { return 'UserIs-IP'; }
		return 'UserIs-User';
	}

	// Renvoie 'UserIs-…' si un seul type, 'UserIs-Mixed' sinon (RC "améliorée").
	// Colore les liens vers les utilisateurs pour disposer de la différentiation même si historique mixte.
	function getMultipleClassName(userlinks) {
		var className = '';
		$.each(userlinks, function () {
			var localClassName = getUserClass(this);
			$(this).addClass(localClassName);
			if (className === '') {
				className = localClassName;
			} else if (className !== localClassName) {
				className = 'UserIs-Mixed';
			}
		});
		return className;
	}

	function userGroupClassName(Li) {
		var userlinks = Li.getElementsByClassName('mw-userlink');
		if (userlinks.length > 1) {  // groupe des RC "améliorées"
			$(Li).addClass(getMultipleClassName(userlinks) + ' UserIs-Multiple');
		} else if (userlinks.length === 1) {
			$(Li).addClass(getUserClass(userlinks[0]));
		}
	}

	/////////////////////////////////////// FONCTIONS DE PARCOURS DES ÉLÉMENTS ///////////////////////////////////////

	function scan_first_ul() {
		$('#mw-content-text').find('ul').eq(0).find('li').each(function () {
			userGroupClassName(this);
		});
	}

	function scan_ul_special_li() {
		$('ul.special li').each(function () {
			userGroupClassName(this);
		});
	}

	function scan_td() {
		$('td').each(function () {
			userGroupClassName(this);
		});
	}

	/////////////////////////////////////// FONCTIONS DE SÉLECTION DES FILTRES ///////////////////////////////////////

	function process_History() {
		$('#pagehistory, .flow-board-history').find('li').each(function () {
			userGroupClassName(this);
		});
	}

	function process_Watchlist() {
		scan_ul_special_li(); // Liste de suivi normale
		scan_td(); // Liste de suivi "améliorée"
	}

	function process_Recentchanges() {
		scan_ul_special_li(); // RC normale
		scan_td(); // RC "améliorées"
	}

	function process_Recentchangeslinked() {
		scan_ul_special_li(); // RC liées normales
		scan_td(); // RC liées "améliorées"
	}

	function process_Newpages() {
		scan_first_ul();
	}

	function process_Log() {
		scan_first_ul();
	}

	function process_AbuseLog() {
		scan_first_ul();
	}

	function process_OtherPages() {
		scan_ul_special_li();
	}

	/////////////////////////////////////// LANCEMENTS ///////////////////////////////////////

	var DeluxeHistory_ClassesApplied = false;
	var DeluxeHistory_Enabled = $.extend({
		"history": true,
		"watchlist": true,
		"recentchanges": true,
		"recentchangeslinked": true,
		"newpages": true,
		"log": true,
		"abuseLog": true,
		"other": true
	}, window.DeluxeHistory_Enabled);

	function enabled(pageType) {
		return DeluxeHistory_Enabled[pageType];
	}

	function applyClasses() {
		if (botMembers && sysopMembers && !DeluxeHistory_ClassesApplied) {
			DeluxeHistory_ClassesApplied = true;

			var paramAction = mw.config.get('wgAction');
			var paramCanonicalSpecialPageName = mw.config.get('wgCanonicalSpecialPageName');

			if ( paramAction === 'history' ) {
				if( enabled("history") ) {
					$(document).ready(process_History);
				}
			} else if ( paramCanonicalSpecialPageName === 'Watchlist' ) {
				if( enabled("watchlist") ) {
					$(document).ready(process_Watchlist);
				}
			} else if ( paramCanonicalSpecialPageName === 'Recentchanges' ) {
				if( enabled("recentchanges") ) {
					$(document).ready(process_Recentchanges);
				}
			} else if ( paramCanonicalSpecialPageName === 'Recentchangeslinked' ) {
				if( enabled("recentchangeslinked") ) {
					$(document).ready(process_Recentchangeslinked);
				}
			} else if ( paramCanonicalSpecialPageName === 'Newpages' ) {
				if( enabled("newpages") ) {
					$(document).ready(process_Newpages);
					mw.util.addCSS('.not-patrolled { text-decoration: underline !important; }');
				}
			} else if ( paramCanonicalSpecialPageName === 'Log' ) {
				if( enabled("log") ) {
					$(document).ready(process_Log);
				}
			} else if ( paramCanonicalSpecialPageName === 'AbuseLog' ) {
				if( enabled("abuseLog") ) {
					$(document).ready(process_AbuseLog);
				}
			} else {
				if( enabled("other") ) {
					$(document).ready(process_OtherPages);
				}
			}
		}
	}

	/////////////////////////////////////// RÉCUPÉRATION DE LA LISTE DES BOTS ET SYSOPS ///////////////////////////////////////

	var validCache;

	function updateUserList(Group, UserList, UserContinue) {
		if (!UserList) { UserList = []; }

		var paramUserGroups = mw.config.get('wgUserGroups');
		var APILimit = paramUserGroups.indexOf('sysop') > -1 || paramUserGroups.indexOf('bot') > -1
			? 5000 : 500;
		var params = {
			'format'   : 'json',
			'action'   : 'query',
			'list'	 : 'allusers',
			'aulimit'  : APILimit,
			'augroup'  : Group,
			'continue' : '' // https://www.mediawiki.org/wiki/API:Query#Continuing_queries
		};
		if (UserContinue) {
			$.extend(params, UserContinue);
		}

		$.get(mw.util.wikiScript('api'), params, function (data) {
			$.each(data.query.allusers, function () {
				UserList.push(this.name);
			});
			if (data['continue']) {
				updateUserList(Group, UserList, data['continue']);
			} else {
				if (supportLocalStorage) {
					var storedValue = UserList.join('|');
					localStorage.setItem('HistoryDeluxe_' + Group, storedValue);
					localStorage.setItem('HistoryDeluxe_lastUpdate', dateNowUTC);
				}
				if (Group === 'bot') {
					botMembers = UserList;
				} else if (Group === 'sysop') {
					sysopMembers = UserList;
				}
				applyClasses();
			}
		});
	}

	function testCacheValidity() {
		var lastUpdate;
		if (supportLocalStorage) {
			lastUpdate = localStorage.getItem('HistoryDeluxe_lastUpdate');
			validCache = lastUpdate && dateNowUTC - lastUpdate < 1000 * 3600 * 24 && dateNowUTC - lastUpdate > 0;
		} else {
			validCache = false;
		}
	}

	// Exécutée si validCache, ie. si (supportLocalStorage && lastUpdate pas trop loin)
	function getUserList(Group) {
		var storedValue;
		storedValue = localStorage.getItem('HistoryDeluxe_' + Group);
		return storedValue ? storedValue.split('|') : null;
	}

	/////////////////////////////////////// INITIALISATION ///////////////////////////////////////

	testCacheValidity();

	if (validCache) {
		botMembers = getUserList('bot');
		sysopMembers = getUserList('sysop');
		applyClasses();
	} else {
		updateUserList('bot');
		updateUserList('sysop');
	}

});