MediaWiki:Gadget-PatrolEntirePage.js

From Pikipedia, the Pikmin wiki
Jump to navigation Jump to search

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
// Adds a "Patrol entire page" link to the wiki's toolbox
// by Espyo

$(function() {
    'use strict';

    // Spinner element. If the wiki's spinner.js is loaded, this is a spinner object. Otherwise, just a span.
    var patrolEntirePageSpinner = null;
    // Button a element.
    var patrolEntirePageA = null;
    // List of revisions to be patrolled.
    var revsToPatrol = [];
    // Number of revisions patrolled so far.
    var revsPatrolled = 0;

    // Can this user even do patrols, and is it a non-Special page?
    function canPatrol() {
        return mw.user.tokens.values.patrolToken.length > 4 && mw.config.get('wgCanonicalNamespace') !== 'Special';
    }

    // Create the button in the toolbox.
    function createPatrolEntirePageButton() {
        var toolsNav = document.getElementById('p-tb');
        if(!toolsNav) return;
        var toolsUl = toolsNav.children[1].children[0];
        if(!toolsUl) return;
        if(!canPatrol()) return;

        var patrolEntirePageLi = document.createElement('li');
        toolsUl.appendChild(patrolEntirePageLi);
        patrolEntirePageLi.id = 't-patrolentirepagescript';
        patrolEntirePageLi.className = 'mw-list-item';

        patrolEntirePageA = document.createElement('a');
        patrolEntirePageLi.appendChild(patrolEntirePageA);
        patrolEntirePageA.innerHTML = 'Patrol entire page';
        patrolEntirePageA.href = 'javascript:;';
        patrolEntirePageA.title =
            'Use this to patrol all edits on this page. ' +
            'This makes use of the recent changes, ' +
            'so edits older than the recent changes limit will not be patrolled.';
        patrolEntirePageA.onclick = fetchUnpatrolledEdits;
    }

    // Obtains a list of unpatrolled edits from the recent changes.
    // That is the only possible place to fetch unpatrolled edits from.
    function fetchUnpatrolledEdits() {
        if(!canPatrol()) {
            patrolEntirePageA.innerHTML = 'Patrol entire page: no permissions!';
            patrolEntirePageA.title = 'This user\'s patrol token is too short, which means this user has no patrolling permissions.';
            return;
        }

        showSpinner();

        var api = new mw.Api();

        api.get({
            action: 'query',
            list: 'recentchanges',
            rcshow: '!patrolled',
            rclimit: 500,
            rcprop: 'ids'
        }).then(
            parseUnpatrolledEdits
        ).catch(
            handlePatrolError
        );
    }

    // Shows a spinner in place of the button, and hides the button.
    function showSpinner() {
        if(patrolEntirePageSpinner == null) {
            if($.createSpinner === undefined) {
                patrolEntirePageSpinner = document.createElement('span');
                patrolEntirePageSpinner.innerHTML = '...';
            } else {
                patrolEntirePageSpinner = $.createSpinner({size:'small', type:'inline'});
            }
            $(patrolEntirePageA).after(patrolEntirePageSpinner);
        }
        $(patrolEntirePageSpinner).css('display', '');
        $(patrolEntirePageA).css('display', 'none');
    }

    // Shows the button, and hides the spinner if any.
    function showButton() {
        if(patrolEntirePageSpinner != null) {
            $(patrolEntirePageSpinner).css('display', 'none');
        }
        $(patrolEntirePageA).css('display', '');
    }

    // Parses the list of unpatrolled edits received from the API.
    // It also prepares the button for the next step.
    function parseUnpatrolledEdits(data) {
        // DEBUG:
        // console.log(data);

        for(var e = 0; e < data.query.recentchanges.length; e++) {
            if(data.query.recentchanges[e].pageid != mw.config.values.wgArticleId) continue;
            revsToPatrol.push(data.query.recentchanges[e]);
        }

        if(revsToPatrol.length == 0) {
            patrolEntirePageA.innerHTML = 'Patrol entire page: no edits to patrol';
            patrolEntirePageA.title = 'All of the edits on this page have already been patrolled.';
            patrolEntirePageA.onclick = undefined;
            showButton();
            return;
        }

        var tooltip = 'Click here to confirm that you want to patrol all changes in this page. RC IDs: ';
        for(var r = 0; r < revsToPatrol.length; r++) {
            tooltip += revsToPatrol[r].rcid + ', ';
        }
        tooltip = tooltip.substr(0, tooltip.length - 2) + '.';
        patrolEntirePageA.innerHTML = 'Patrol entire page: are you sure? (' + revsToPatrol.length + ' edit' + (revsToPatrol.length > 1 ? 's' : '') + '.)';
        patrolEntirePageA.title = tooltip;
        patrolEntirePageA.onclick = doPatrol;
        showButton();
    }

    // Starts the full patrolling process.
    function doPatrol() {
        showSpinner();

        for(var r = 0; r < revsToPatrol.length; r++) {
            var api = new mw.Api();
            var rcid = revsToPatrol[r].rcid;

            console.log('MediaWiki patrol entire page script -- patrolling RC ID ' + rcid + '.');

            // DEBUG:
            // handleRevPatrolled();

            api.postWithToken(
                'patrol',
                {
                    formatversion: 2,
                    action: 'patrol',
                    rcid: rcid
                }
            ).then(
                handleRevPatrolled
            ).catch(
                handlePatrolError
            );

        }
    }

    // Handles one of the revisions being successfully patrolled.
    function handleRevPatrolled(data) {
        revsPatrolled++;
        if(revsPatrolled == revsToPatrol.length) {
            patrolEntirePageA.innerHTML = 'Patrol entire page: finished!';
            patrolEntirePageA.title = 'The script has finished patrolling all unpatrolled edits (' + revsPatrolled + ').';
            patrolEntirePageA.onclick = undefined;
            showButton();
            return;
        }
    }

    // Handles an error while trying to patrol a revision.
    function handlePatrolError(code, data) {
        showButton();
        var api=new mw.Api();
        mw.notify(
            api.getErrorMessage(data),
            {type: code === 'noautopatrol' ? 'warn' : 'error'}
        );
    }

    createPatrolEntirePageButton();
});