Медијавики:Gadget-DeluxeHistory.js

Iz Vojne Enciklopedije
/**
 * 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' ;
 *  — 'user' (chargement du common.js).
 * {{Catégorisation JS|DeluxeHistory}}
 */

/*global document, localStorage, mediaWiki, jQuery */
/*jslint vars: true, plusplus: true */

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

    var botMembers, sysopMembers;

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

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

    if (supportLocalStorage) {
        dateNow = new Date();
        dateNowUTC = dateNow.getTime() + dateNow.getTimezoneOffset() * 60000;
    }

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

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

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

    function getUserClass(jUserlink) {
        var UserName = jUserlink.text();
        if (UserName === watcherName) { return 'UserIs-Self'; }
        if (botMembers.indexOf(UserName) > -1) { return 'UserIs-Bot'; }
        if (sysopMembers.indexOf(UserName) > -1) { return 'UserIs-Sysop'; }
        if (isUserIP(jUserlink)) { 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(jUserlinks) {
        var className = '';
        var localClassName;
        jUserlinks.each(function() {
            var $this = $(this);
            localClassName = getUserClass($this);
            $this.addClass(localClassName);
            if (className === '') {
                className = localClassName;
            } else if (className !== localClassName) {
                className = 'UserIs-Mixed';
            }
        });
        return className;
    }

    function userGroupClassName(Li) {
        var jLi = $(Li);
        var jUserlink = jLi.find('a.mw-userlink');
        if (jUserlink.length > 0) {
            if (jLi.find('.changedby').length === 0) {  // groupe des RC "améliorées"
                jLi.addClass(getUserClass(jUserlink));
            } else {
                jLi.addClass(getMultipleClassName(jUserlink) + ' UserIs-Multiple');
            }
        }
    }

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

    function get_bodyContent() {
        var Content = document.getElementById('bodyContent');
        if (!Content) { Content = document.getElementById('mw_contentholder'); }
        if (!Content) { Content = document.getElementById('article'); }
        return Content;
    }

    function scan_first_ul() {
        var Content = get_bodyContent();
        $(Content).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) {
        switch( $.type(DeluxeHistory_Enabled[pageType]) ) {
            case 'boolean':
                return DeluxeHistory_Enabled[pageType];
            case 'function':
                return DeluxeHistory_Enabled[pageType]();
            default:
                return false;
        }
    }

    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');
    }

})(mediaWiki, jQuery);
Vojna Enciklopedija - Glavni i odgovorni urednik Branislav Kapetanović