Jump to content

User:Bradv/Scripts/ExpandDiffs.js

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Bradv (talk | contribs) at 15:33, 17 September 2020 (new version, with links in diffs). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
(function( $, mw ) {
    'use strict';
    
    if (mw.config.get('wgAction')==='history' || mw.config.get('wgCanonicalSpecialPageName')=='Contributions') {
        const api = new mw.Api();
        const app = {
            styleSheet: mw.util.addCSS(`
                .diff-addedline, .diff-deletedline, .diff-context {
                    font-size: 0.9em;
                }
                .diff > tr.hidden {
                    display:none;
                }
                .difftoggle {
                    background-image: url(/w/resources/src/mediawiki.icon/images/arrow-expanded.svg?d0685);
                    background-repeat: no-repeat;
                    background-position: left bottom;
                    width: 15px;
                    height: 15px;
                    display: inline-block;
                    cursor: pointer;
                }
                .difftoggle.diffcollapsed {
                    background-image: url(/w/resources/src/mediawiki.icon/images/arrow-collapsed-ltr.svg?40e9a);
                }
                .diff.diffcollapsed {
                    display:none;
                }
                *[data-mw-revid]:hover {
                    background-color: #fcfdfe;
                    outline:1px dashed #a2a9b1 !important;
                }
                .diff a:not(:hover) {
                    color: inherit;
                }
                .diff a:hover, .diff a:active, .diff a:focus {
                    text-decoration:none;
                }
            `),
            init: function () {
                $('*[data-mw-revid]').each(function() {
                    $('<span>', {'class': 'difftoggle diffcollapsed'})
                        .prependTo($(this))
                        .click(app.toggle);
                });
                mw.loader.using('mediawiki.util').then(function () {
                    var $link = $(mw.util.addPortletLink('p-views', '', 'Expand diffs', 'ca-expand', '', '', '#ca-history'))
                    .click(function(e) {
                        e.preventDefault();
                        if (!$link.hasClass('selected')) {
                            $link.addClass('selected');
                            app.expandAll();
                        }
                    })
                });
            },
            load: function ($row) {
                var deferred = new $.Deferred();
                if ($row.attr('diffloaded')===undefined) {
                    var revid = $row.attr('data-mw-revid');
                    api.get({
                        action: 'compare',
                        format: 'json',
                        fromrev: revid,
                        torelative: 'prev',
                        prop: 'diff'
                    }).done(function (response, data) {
                        var diff = data.responseJSON.compare['*'];
                        var $diff = $('<table>', {'class':'diff diff-contentalign-left diff-editfont-monospace'})
                            .append($('<colgroup><col class="diff-marker"/><col class="diff-content"/><col class="diff-marker"/><col class="diff-content"/></colgroup>'))
                            .append(diff)
                            .appendTo($row);
                        $row.find('tr:has(td.diff-context), tr:has(td.diff-lineno)').addClass('hidden');
                        $row.attr('diffloaded', '');
                        $row.find('.difftoggle').removeClass('diffcollapsed');
                        app.linkify($diff);
                        deferred.resolve($row);
                    });
                } else {
                    $row.find('.diff, .difftoggle').removeClass('diffcollapsed');
                    deferred.resolve($row);
                }
                return deferred.promise();
            },
            expandAll: function () {
                var counter = 0;

                function loop($row) {
                    app.load($row)
                    .done(function($row) {
                        counter++;
                        var $next = $row.next();
                        if (counter<50 && $next) {
                            loop($next);
                        }
                    });
                }

                loop($('*[data-mw-revid]:first-of-type'));
            },
            toggle: function (e) {
                var $row = $(e.target).parent();
                if ($row.attr('diffloaded')===undefined) {
                    app.load($row);
                } else {
                    $row.find('.diff, .difftoggle').toggleClass('diffcollapsed');
                }
            },
            linkify: function ($diff) {
                try {
                    function makelinks(text, regex1, regex2, urlprefix) {
                        var out = text;
                        var arr = text.match(regex1);
                        if (arr) {
                            for (var i=0;i<arr.length;i++) {
                                var s = arr[i];
                                var slink;
                                if (regex2) {
                                    slink = s.match(regex2)[0].replace(' ', '_');
                                } else {
                                    slink = s.replace(' ', '_');
                                }
                                var snew = "<a href='" + (urlprefix ? urlprefix : '') + slink + "'>" + s + "</a>";
                                out = out.replace(s, snew);
                            }
                        }
                        return out;
                    }

                    $.each($diff.find('div'), function () {
                        var html = $(this).html();

                        html = makelinks(html, /https?:\/\/.+?(?=[\s\]\|])/gi);
                        html = makelinks(html, /\[\[.*?\]\]/g, /(?<=\[\[).*?(?=\||\]\])/, '/wiki/');
                        html = makelinks(html, /\{\{.*?\}\}/g, /(?<=\{\{).*?(?=\||\}\})/, '/wiki/Template:');

                        $(this).html(html);
                    });
                } catch (e) {
                    console.log(e)
                }
            }
        }
        app.init();
    }
}(jQuery, mediaWiki ));