User:Bradv/Scripts/WhatLinksHereSnippets.js

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')==='view' 
    && mw.config.get('wgCanonicalSpecialPageName')==='Whatlinkshere') {
        const api = new mw.Api();
        const app = {
            styleSheet: mw.util.addCSS(`
                body.hidesnippets pre.snippet {
                    display:none
                }
                pre.snippet {
                    padding:0.5em;
                    margin:0 0 0.5em 1em;
                    font-size:0.8em;
                }
                pre.snippet .highlight {
                    background-color: #FFFF99;
                }
            `),
            init: function () {
                app.button = $('<span>', {'class': 'mw-ui-button mw-ui-progressive', 'style': 'float:right'})
                    .text('Show snippets')
                    .insertAfter($('#mw-content-text > hr'))
                    .click(function() {
                        app.button.toggleClass('mw-ui-progressive');
                        if (app.button.hasClass('mw-ui-progressive')) {
                            app.button.text('Show snippets');
                            $('body').addClass('hidesnippets');
                        } else {
                            app.button.text('Hide snippets');
                            $('body').removeClass('hidesnippets');
                        }

                        if ($('pre.snippet').length==0) {
                            app.load();
                        }
                    });
                app.makeRegexes();
            },
            load: function() {
                var selector = '#mw-whatlinkshere-list > li';
                function loop($row) {
                    if ($row.length) {
                        app.loadSnippet($row)
                        .then(function($row) {
                            loop($row.next(selector));
                        });
                    }
                }
                loop($(selector).first());
            },
            makeRegexes: function() {
                app.regexes = {};

                var page = mw.config.get('wgRelevantPageName')
                    .replace(/[-[\]{}()* ?.,\\^$|#\s]/g, '\\$&')
                    .replace(/^Wikipedia:/,'\(Wikipedia\|WP\|Project\):')
                    .replace(/^Wikipedia_talk:/, '\(Wikipedia_talk\|WT\|Project_talk\):')
                    .replace(/^File:/, '\(Image\|File\):')
                    .replace(/^File_talk:/, '\(Image_talk\|File_talk\):')
                    .replaceAll('_','\[_\ \]');

                var template = page.replace(/^Template:/,'\(Template:\)?');
                app.regexes.transcludes = new RegExp("(^|\\w?).*{{\\s*:?"   template   "\\s*(\[\\|#\]\[\\w\\W\]*?)?}}.*($|\\n)", 'gi');
                app.regexes.transcludesHilite = new RegExp("{{\\s*:?"   template   "\\s*(\[\\|#\]\[\\w\\W\]*?)?}}", 'gi');
                    
                app.regexes.links = new RegExp("(^|\\w?).*\\[\\[\\s*:?"   page   "\\s*(\[\\|#\]\[\\w\\W\]*?)?\\]\\].*($|\\n)", 'gi');
                app.regexes.linksHilite = new RegExp("\\[\\[\\s*:?"   page   "\\s*(\[\\|#\]\[\\w\\W\]*?)?\\]\\]", 'gi');
                
                console.log(app.regexes);
            },
            loadSnippet: function($row) {
                var deferred = new $.Deferred();
                var page = $row.children('a').text();
                api.get({
                    action: 'parse',
                    format: 'json',
                    page: page,
                    prop: 'wikitext'
                }).done(function (response, data) {
                    var text = data.responseJSON.parse.wikitext['*'];
                    var transcludes = ($row.contents().filter(function() {return this.nodeType==3}).text().includes('(transclusion)'));
                    var arr = [];
                    var hilite = null;
                    if (transcludes) {
                        arr = text.match(app.regexes.transcludes);
                        hilite = app.regexes.transcludesHilite;
                    } else {
                        arr = text.match(app.regexes.links);
                        hilite = app.regexes.linksHilite;
                    }

                    if (arr) {
                        arr = arr.map(function(s) {
                            return s.trim()
                                .replaceAll('<', '&lt;')
                                .replaceAll('>', '&gt;')
                                .replace(hilite, x => "<span class='highlight'>"   x   "</span>");
                        });
                        
                        $.each(arr, function() {
                            var $pre = $('<pre>', {'class': 'snippet'})
                                .append(this);
                            if ($row.children().filter('ul').length) {
                                $pre.insertBefore($row.children().filter('ul'));
                            } else {
                                $pre.appendTo($row);
                            }
                        });
                    }

                    deferred.resolve($row);
                });
                return deferred.promise();
            }
        }
        app.init();
    }
}(jQuery, mediaWiki ));