Jump to content

User:Quarl/diff.js

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Quarl (talk | contribs) at 07:46, 30 January 2006 (new script). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
(diff) ← Previous revision | Latest revision (diff) | Newer revision → (diff)
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.
// [[User:Quarl/diff.js]] - utility functions for doing diffs

// quarl 2006-01-29 initial version

// <pre><nowiki>

/*
 * diff() and diffString() are Copyright John Resig, see
 *  http://ejohn.org/projects/javascript-diff-algorithm/
 */

function trimspaces(x) {
    x = x.replace(/^\s+/, '');
    x = x.replace(/\s$/, '');
    return x;
}

function diffString( o, n ) {
    var out = diff( o.split(/\s+/), n.split(/\s+/) );
    var str = "";

    for ( var i = 0; i < out.n.length - 1; i++ ) {
        if ( out.n[i].text == null ) {
            if ( out.n[i].indexOf('"') == -1 && out.n[i].indexOf('<') == -1 )
                str += "<ins style='background:#E6FFE6;'> " + out.n[i] +"</ins>";
            else
                str += " " + out.n[i];
        } else {
            var pre = "";
            if ( out.n[i].text.indexOf('"') == -1 && out.n[i].text.indexOf('<') == -1 ) {

                var n = out.n[i].row + 1;
                while ( n < out.o.length && out.o[n].text == null ) {
                    if ( out.o[n].indexOf('"') == -1 && out.o[n].indexOf('<') == -1 && out.o[n].indexOf(':') == -1 && out.o[n].indexOf(';') == -1 )
                        pre += " <del style='background:#FFE6E6;'>" + out.o[n] +" </del>";
                    n++;
                }
            }
            str += " " + out.n[i].text + pre;
        }
    }

    return str;
}

function diff( o, n ) {
    var ns = new Array();
    var os = new Array();

    for ( var i = 0; i < n.length; i++ ) {
        if ( ns[ n[i] ] == null )
            ns[ n[i] ] = { rows: new Array(), o: null };
        ns[ n[i] ].rows.push( i );
    }

    for ( var i = 0; i < o.length; i++ ) {
        if ( os[ o[i] ] == null )
            os[ o[i] ] = { rows: new Array(), n: null };
        os[ o[i] ].rows.push( i );
    }

    for ( var i in ns ) {
        if ( ns[i].rows.length == 1 && typeof(os[i]) != "undefined" && os[i].rows.length == 1 ) {
            n[ ns[i].rows[0] ] = { text: n[ ns[i].rows[0] ], row: os[i].rows[0] };
            o[ os[i].rows[0] ] = { text: o[ os[i].rows[0] ], row: ns[i].rows[0] };
        }
    }

    for ( var i = 0; i < n.length - 1; i++ ) {
        if ( n[i].text != null && n[i+1].text == null && o[ n[i].row + 1 ].text == null &&
             n[i+1] == o[ n[i].row + 1 ] ) {
            n[i+1] = { text: n[i+1], row: n[i].row + 1 };
            o[n[i].row+1] = { text: o[n[i].row+1], row: i + 1 };
        }
    }

    for ( var i = n.length - 1; i > 0; i-- ) {
        if ( n[i].text != null && n[i-1].text == null && o[ n[i].row - 1 ].text == null &&
             n[i-1] == o[ n[i].row - 1 ] ) {
            n[i-1] = { text: n[i-1], row: n[i].row - 1 };
            o[n[i].row-1] = { text: o[n[i].row-1], row: i - 1 };
        }
    }

    return { o: o, n: n };
}

function diffAggregate(o, n) {
    var out = diff( trimspaces(o).split(/\s+/), trimspaces(n).split(/\s+/) );
    var ret = new Array();
    var cur = null;

    for ( var i = 0; i < out.n.length - 1; i++ ) {
        if ( out.n[i].text == null ) {
            if (!cur) {
                cur = { o: "", n: "" };
                ret.push(cur);
            }
            cur.n += " " + out.n[i];
        } else {

            var pre = "";
            var j = out.n[i].row + 1;
            while ( j < out.o.length && out.o[j].text == null ) {
                pre += " " + out.o[j];
                j++;
            }
            if (pre) {
                if (!cur) {
                    cur = { o: "", n: "" };
                    ret.push(cur);
                }
                cur.o += pre;
            }
            cur = null;
        }
    }

    for (var i in ret) {
        ret[i].n = trimspaces(ret[i].n);
        ret[i].o = trimspaces(ret[i].o);
    }

    return ret;
}

function diffSummary(o, n) {
    var diff = diffAggregate(o, n);

    var str = [];

    for (var i in diff) {
        if (diff[i].o && diff[i].n) {
            str.push('"'+diff[i].o+'" &rawr; "' + diff[i].n + '"');
        } else if (diff[i].o) {
            str.push('-"'+diff[i].o+'"');
        } else if (diff[i].n) {
            str.push('+"'+diff[i].n+'"');
        } else {
            alert("## internal error 15e1b13f-bae3-4399-86c5-721786822fa2");
        }
    }

    return str.join(", ");
}

// </nowiki></pre>