Участник:Absconditus/revertall.js

Материал из Википедии — свободной энциклопедии
/*
Взято из Луркоморья — lukrmore.to/user:T_nks/revertall.js

Скрипт добавляет в левом меню в разделе «Инструменты» ссылку «Включить откатывалку» (только на страницах вклада участников). По нажатию на неё все правки пользователя, которые можно технически откатить (через инструмент rollback) снабжаются чекбоксами. По умолчанию отмечены все такие правки. По нажатию на красную надпись «Откатить!» будут откачены все выбранные правки. Требует технического права «rollback»!
*/

$(function() {
    var tok ='';

    function delfile(f,_) {
        $.ajax({
            url: '/api.php?'+$.param({
                format: 'json',
                action: 'delete',
                title: f,
                token: tok,
                reason: 'Быстрое удаление неиспользуемого файла'
            }),
            dataType: 'json',
            type: 'POST'
        }).done(function(d) {
            if(mw.config.get('wgCanonicalSpecialPageName')=="Unusedimages") {
                _.closest('td').remove();
            } else {
                _.closest('li').remove();
            }
        });
    }

    function gettok (flist,_) {
        if(!flist.length) {showmessage('Файлы не выбраны'); return false;}

        _.data('delStarted', true)
            .append('<img src="/skins/common/images/ajax-loader.gif" alt="l" height="16"/>');

        $.ajax({
            url: '/api.php',
            data: {
                format: 'json',
                action: 'query',
                prop: 'info',
                intoken: 'delete',
                titles: 'Файл:'+flist+'|Обсуждение файла:'+flist
            },
            dataType: 'json',
            type: 'POST'
        }).done(function(d){
            for(var i in d.query.pages) {
                if(parseInt(i,10) < 0) continue;
                if(d.query.pages[i].ns === 7) {
                    showmessage('Также будет удалена страница: «'+d.query.pages[i].title+'».');
                }
                tok = d.query.pages[i].deletetoken;
                delfile(d.query.pages[i].title,_)
            };
        });
    }


if(mw.config.get('wgNamespaceNumber')==-1 && mw.config.get('wgCanonicalSpecialPageName')=="Unusedimages") {
    $('.gallerytext').append('[',$('<a href="#">x</a>').click(function() {
        var _ = $(this)
            , f = _.closest('.gallerybox').find('a.image > img').eq(0).attr('alt');
        if(!_.data('delStarted')) {
            gettok(f,_);
        }
        return false;
    }), ']');
}


if(mw.config.get('wgCanonicalSpecialPageName')=="Contributions" && $('span.mw-rollback-link,ul > li abbr.newpage+a[title^="Файл:"]').length > 0) {

    $('<li><a href="#">Включить откатывалку</a></li>').appendTo('#p-tb ul').one('click', function(e) {
        e.preventDefault();

        (function($) {
            $.fn.enableCheckboxRangeSelection = function() {
                var lastCheckbox = null, $spec = this;
                $spec.unbind("click.checkboxrange");
                $spec.bind("click.checkboxrange", function(e) {
                    if (lastCheckbox != null && (e.shiftKey || e.metaKey)) {
                        $spec.slice(
                            Math.min($spec.index(lastCheckbox), $spec.index(e.target)),
                            Math.max($spec.index(lastCheckbox), $spec.index(e.target)) + 1
                        ).prop('checked', e.target.checked);
                    }
                    lastCheckbox = e.target;
                });
            };
        })(jQuery);

    function rollback(cd) {
        if(!cd.length) {showmessage('Не выбрано ни одной правки!');return false;}

        var rblinks = $.map(cd, function(n) {
            var n =$(n), title = n.attr('data-pagename');
            showmessage('===> '+title);
            $.get(n.attr('data-rollback-url')).done(function() {showmessage('<=== '+title);})

            return true;
        });
    }

        var rollbacks = $('span.mw-rollback-link')
            , fileslist = {};


        $('ul > li abbr.newpage+a[title^="Файл:"]').each(function(){
            var fname = $(this).attr('title').replace(/^Файл:/,'');
            fileslist[fname] = $(this);
            $(this).closest('li').prepend('&nbsp;[',$('<a href="#">x</a>').click(function() {
                var _ = $(this);
                if(!_.data('delStarted')) {
                    gettok(fname,_);
                    delete fileslist[fname];
                }
                return false;
            }), ']&nbsp;')
        });

        rollbacks.each(function(i) {
            $(this).closest('li').prepend($('<input type="checkbox" class="rtbcbox" checked="checked"/>')
                                            .attr({'data-cbox-num' :i, 'data-rollback-url':$(this).children('a').attr('href'), 'data-pagename': $(this).parent().children('a').attr('title')}));
        })

        $("input.rtbcbox").enableCheckboxRangeSelection();

 var fls = document.getElementsByTagName('fieldset')[0] || document.getElementsByTagName('form')[0];
 $('<li>Выберите правки, которые необходимо откатить: <a href="#" data-choice="all" unselectable="on">все</a>, <a href="#" data-choice="none" unselectable="on">ни одной</a>, <a href="#" data-choice="invert" unselectable="on">обратить выбор</a>. Совет: если хотите отметить несколько чекбоксов, кликните по первому из группы, а затем, удерживая клавишу Shift, по последнему. [<a href="#" data-choice="rollback" style="color:red; font-weight:bold;">Откатить!</a>&nbsp;|&nbsp;<a href="" data-choice="removeimages">Удалить <b>все</b>&nbsp;картинки!</a>]</li>').appendTo(fls).on('click', 'a', function() {
                var choice = $(this).attr('data-choice')
                    , cd = $('input.rtbcbox:checked')
                    , ncd = $('input.rtbcbox:not(:checked)');

                switch(choice) {
                    case 'all':
                        ncd.prop('checked',true);break;
                    case 'none':
                        cd.prop('checked',false);break;
                    case 'rollback':
                        rollback(cd);break;
                    case 'removeimages':
                        if(confirm('Удалить картинки, загруженные пользователем?')) {
                            for (var j in fileslist) gettok(j, fileslist[j]);
                        }
                        break;
                    default:
                        ncd.prop('checked',true); cd.prop('checked',false);break;
                }

                return false;
            })
            .css({color:'#743E27'})
            .prependTo('#bodyContent>ul');

        $('html,body').animate({ scrollTop: navbar.offset().top }, 300);

        $(this).remove();
    }).appendTo('#p-tb .pBody ul');

}

});