Utilisateur:Od1n/EtatsFiltres v2.js

Une page de Wikipédia, l'encyclopédie libre.
Note : après avoir enregistré la page, vous devrez forcer le rechargement complet du cache de votre navigateur pour voir les changements.

Mozilla / Firefox / Konqueror / Safari : maintenez la touche Majuscule (Shift) en cliquant sur le bouton Actualiser (Reload) ou pressez Maj-Ctrl-R (Cmd-R sur Apple Mac) ;

Chrome / Internet Explorer / Opera : maintenez la touche Ctrl en cliquant sur le bouton Actualiser ou pressez Ctrl-F5.
/*
 * Script pour aider à mettre à jour [[Wikipédia:AbuseFilter/Tableau de bord]]
 */

/* jshint esversion: 6 */
/* globals Promise, mw, $ */

mw.loader.using('mediawiki.api', function () {
    mw.hook('wikipage.content').add(function ($content) {
        'use strict';

        function getFilters() {
            return new Promise(function (resolve, reject) {
                let filters = [];
                let userGroups = mw.config.get('wgUserGroups');
                let apiLimit = userGroups.includes('sysop') || userGroups.includes('bot') ? 5000 : 500;
                function makeRequest(apiContinue) {
                    let params = {
                        action: 'query',
                        list: 'abusefilters',
                        abfprop: ['id', 'description', 'status'],
                        abflimit: apiLimit,
                    };
                    if (apiContinue) {
                        Object.assign(params, apiContinue);
                    }
                    new mw.Api().get(params).done(function (data) {
                        if (!data.query) {
                            reject();
                        }
                        filters = filters.concat(data.query.abusefilters);
                        if (data['continue']) {
                            makeRequest(data['continue']);
                        } else {
                            resolve(filters);
                        }
                    });
                }
                makeRequest();
            });
        }

        getFilters().then(function (filters) {
            let filterInfo = {};

            for (let filter of filters) {
                let etat;
                if (filter.enabled !== undefined) {
                    etat = 'Activé';
                } else if (filter.deleted !== undefined) {
                    etat = 'Supprimé';
                } else {
                    etat = 'Désactivé';
                }

                filterInfo[filter.id] = {
                    'titre': filter.description,
                    'etat': etat,
                };
            }

            // note : de nombreux éléments ont des trailing spaces : les <caption>, les <th>, les <td>…

            $content.find('.mw-parser-output').find('table').each(function (_, table) {
                let $table = $(table);
                let nbErreurs = 0;

                let $trs = $table.find('tr');

                let indexColNumero;
                let indexColTitre;
                let indexColEtat;

                $trs.first().find('th').each(function (index, th) {
                    let cellText = th.textContent.trim();
                    if (cellText === 'No' || cellText === 'N°') {
                        indexColNumero = index;
                    } else if (cellText === 'Titre') {
                        indexColTitre = index;
                    } else if (cellText === 'État') {
                        indexColEtat = index;
                    }
                });

                if (indexColNumero === undefined || indexColTitre === undefined || indexColEtat === undefined) {
                    return;
                }

                $trs.slice(1).each(function (_, tr) {
                    let $tds = $(tr).find('td');

                    let cellNumero = $tds.get(indexColNumero);
                    let cellTitre = $tds.get(indexColTitre);
                    let cellEtat = $tds.get(indexColEtat);

                    let filterId = findFilterId(cellNumero);
                    let titreAffiche = cellTitre.textContent.trim();
                    let etatAffiche = cellEtat.textContent.trim();

                    // pour les comparaisons, il faut défaire la mise en forme automatique de MediaWiki
                    titreAffiche = titreAffiche.replaceAll('«\xA0', '« ').replaceAll('\xA0»', ' »');
                    titreAffiche = titreAffiche.replaceAll(/(?<=[a-zA-Z])\xA0: (?=[a-zA-Z])/g, ' : ');

                    let titreReel = filterInfo[filterId].titre;
                    if (titreAffiche !== titreReel) {
                        ajouteErreur(cellTitre, 'TITRE RÉEL\xA0: ' + titreReel);
                        nbErreurs += 1;
                    }

                    let etatReel = filterInfo[filterId].etat;
                    if (etatAffiche !== 'N/A' && etatReel !== etatAffiche) {
                        ajouteErreur(cellEtat, 'ÉTAT RÉEL\xA0: ' + etatReel);
                        nbErreurs += 1;
                    }
                });

                let msgErreurs = '[' + nbErreurs + '\xA0erreur' + (nbErreurs > 1 ? 's' : '') + ']';

                let $caption = $table.find('caption');
                if ($caption.length) {
                    $caption.append(' ' + msgErreurs);
                } else {
                    $caption = $table.prepend('<caption>');
                    $caption.append(msgErreurs);
                }
            });

            function findFilterId(elm) {
                let filterId;
                for (let link of elm.getElementsByTagName('a')) {
                    // on limite aux liens dont le texte est un nombre (non formaté, ou formaté)
                    if (!/^(\d+|\d{1,3}(\xA0\d{3})*)$/.test(link.textContent)) {
                        continue;
                    }
                    // on traite les liens vers [[Spécial:Filtre antiabus/<nombre>]]
                    let match = (link.title || '').match(/^Spécial:Filtre antiabus\/(\d+)$/);
                    if (match) {
                        filterId = match[1];
                        // simple sécurité - TODO : à intégrer plus proprement
                        if (link.textContent.replaceAll('\xA0', '') !== filterId) {
                            alert('Lien de filtre avec un numéro erroné\xA0: ' + link.textContent + ' (envoie vers le ' + filterId + ')');
                        }
                        break;
                    }
                }
                return filterId;
            }

            function ajouteErreur(cell, message) {
                $(cell).append('<br>', '<span style="color:red; font-weight:bold;">' + message + '</span>');
            }
        });

    });
});