Jump to content

User:Enterprisey/fancy-diffs.js

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Enterprisey (talk | contribs) at 08:59, 9 November 2019 (wrong debugger location). 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.
// vim: ts=4 sw=4 et ai
( function () {
    var api;

    function makeExpand( type, name ) {
        return '<span class="fd-expand" data-' + type + '="' + name.replace( /"/g, "&quot;" ) + '">(show)</span>';
    }

    // Sometimes we'll get a page name with a span.diffchange in it.
    // This function replaces those spans with their contents.
    function sanitizeDiffchangeSpans( original ) {
        return original
            .replace( /<(ins|del) class="diffchange diffchange-inline">([^<]+?)($|<\/\1>)/g, "$2" );
    }

    function processText( text ) {
console.log(text)
        return text
            .replace( /\[\[(.+?)(?:\|.+?)?\]\]/g, function ( match, name ) {
                name = sanitizeDiffchangeSpans( name );
                var html = "<a href='" + mw.util.getUrl( name ) + "'>" + match +
                    "</a>";
                if( name.indexOf( "File:" ) === 0 ||
                        name.indexOf( "Image:" ) === 0 ) {
                    html += makeExpand( "img", name );
                }

                return html;
            })
            .replace( /\{\{(.+?)(?:\|.+?)?\}\}/g, function ( match, name ) {
                name = sanitizeDiffchangeSpans( name );
                var fullName = name;
                if( name.indexOf( "#" ) === 0 ) {
                    fullName = name.replace( /^#invoke:/, "Module:" );
                } else if( name.indexOf( ":" ) < 0 ) {
                    fullName = "Template:" + name;
                }

                return "{{<a href='" + mw.util.getUrl( fullName ) + "'>" + name + "</a>" + match.substring( 2 + name.length );
            })
            //.replace( /&lt;ref\s+name\s*=\s*(\w+?|"[^"]+?")\s*\/&gt;/g, function ( match, name ) {
            //  name = sanitizeDiffchangeSpans( name );
            //    name = name.indexOf( '"' ) === 0 ? name.substring( 1, name.length - 1 ) : name;
            //    return match.substring( 0, match.length - 6 ) + makeExpand( "ref", name ) + "/&gt;";
            //})
            .replace( /(?:(?:https|http|gopher|irc|ircs|ftp|news|nnttp|worldwind|telnet|svn|git|mms):\/\/|mailto:)([!#$&-;=?-\[\]_a-z~]|%[0-9a-fA-F]{2})+/g, function ( match ) {
                name = sanitizeDiffchangeSpans( name );
                return '<a href="' + match + '">' + match + '</a>';
            });
    }

    function processDiff( diffTable ) {
console.log(diffTable)
        var rows = diffTable.querySelectorAll( "tr" );
console.log(diffTable.rows.length);
debugger;
rowLoop:
        for( var rowIdx = 0, numRows = rows.length; rowIdx < numRows; rowIdx++ ) {
            var row = rows[rowIdx];
            if( row.tagName.toLowerCase() === "colgroup" ) {
                return;
            }
            for( var cellIdx = 0, numCells = row.children.length; cellIdx < numCells; cellIdx++ ) {
                var td = row.children[cellIdx];
                if( td.querySelector( "a" ) ) continue;
                switch( td.className ) {
                    case "diff-context":
                        if( td.children && td.children.length ) {
                            var text = processText( td.children[0].innerHTML );
                            td.children[0].innerHTML = text;
                            row.children[cellIdx + 2].innerHTML = text;
                            continue rowLoop;
                        }
                        break;
                    case "diff-deletedline":
                    case "diff-addedline":
                        if( td.children && td.children.length ) {
                            td.children[0].innerHTML = processText( td.children[0].innerHTML );
                        }
                        break;
                }
            }
        }

        var expandSpans = diffTable.querySelectorAll( "span.fd-expand" );
        for( var spanIdx = 0, numSpans = expandSpans.length; spanIdx < numSpans; spanIdx++ ) {
            var span = expandSpans[spanIdx];
            span.addEventListener( "click", function () {
                if( !span.nextElementSibling || span.nextElementSibling.tagName.toLowerCase() !== "div" || span.nextElementSibling.className !== "fd-img" ) {
                    api.get( {
                        action: "query",
                        titles: span.dataset.img,
                        prop: "imageinfo",
                        iiprop: "url"
                    } ).done( function ( data ) {
                        if( data.query && data.query.pages ) {
                            var url = Object.values( data.query.pages )[0].imageinfo[0].url;
                            var div = document.createElement( "div" );
                            div.className = "fd-img";
                            var img = document.createElement( "img" );
                            img.src = url;
                            div.appendChild( img );
                            span.parentNode.insertBefore( div, span.nextSibling );
                        }
                    } );
                    span.textContent = "(hide)";
                } else {
                    if( span.nextElementSibling.style.display === "none" ) {
                        span.nextElementSibling.style.display = "";
                        span.textContent = "(hide)";
                    } else {
                        span.nextElementSibling.style.display = "none";
                        span.textContent = "(show)";
                    }
                }
            } );
        }
    }

    $.when(
        $.ready,
        mw.loader.using( [ "mediawiki.api", "mediawiki.util" ] )
    ).then( function () {
        var table = document.querySelector( "table.diff" );
        if( table ) {
            api = new mw.Api();
            mw.util.addCSS( ".fd-expand { cursor: pointer; text-decoration: underline; background-color: #faf3; }" );
            processDiff( table );
        }
        mw.hook( "diff-update" ).add( processDiff );
    } );
} )();