JS: JsDiff

more at: https://github.com/kpdecker/jsdiff

by Danielo Rodriguez

HTML

<label><input type="radio" name="diff_type" value="diffChars" checked> Chars</label>
<label><input type="radio" name="diff_type" value="diffWords"> Words</label>
<label><input type="radio" name="diff_type" value="diffLines"> Lines</label>
<label><input type='radio' name='diff_type' value='diffCss'> CSS</label>

<textarea id='a'>Foo bar is equal to bar foz.</textarea> <textarea id='b'>Foo bar is not equal to bar foo.</textarea>
<div id='result'></div>

CSS

del {
	text-decoration: none;
	color: #b30000;
	background: #fadad7;
}
ins {
	background: #eaf2c2;
	color: #406619;
	text-decoration: none;
}

JavaScript

/* See LICENSE file for terms of use */

/*
 * Text diff implementation.
 *
 * This library supports the following APIS:
 * JsDiff.diffChars: Character by character diff
 * JsDiff.diffWords: Word (as defined by \b regex) diff which ignores whitespace
 * JsDiff.diffLines: Line based diff
 *
 * JsDiff.diffCss: Diff targeted at CSS content
 *
 * These methods are based on the implementation proposed in
 * "An O(ND) Difference Algorithm and its Variations" (Myers, 1986).
 * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927
 */
var JsDiff = (function () {
    /*jshint maxparams: 5*/
    function clonePath(path) {
        return {
            newPos: path.newPos,
            components: path.components.slice(0)
        };
    }

    function removeEmpty(array) {
        var ret = [];
        for (var i = 0; i < array.length; i++) {
            if (array[i]) {
                ret.push(array[i]);
            }
        }
        return ret;
    }

    function escapeHTML(s) {
        var n = s;
        n = n.replace(/&/g, '&amp;');
        n = n.replace(/</g, '&lt;');
        n = n.replace(/>/g, '&gt;');
        n = n.replace(/"/g, '&quot;');

        return n;
    }

    var Diff = function (ignoreWhitespace) {
        this.ignoreWhitespace = ignoreWhitespace;
    };
    Diff.prototype = {
        diff: function (oldString, newString) {
            // Handle the identity case (this is due to unrolling editLength == 0
            if (newString === oldString) {
                return [{
                    value: newString
                }];
            }
            if (!newString) {
                return [{
                    value: oldString,
                    removed: true
                }];
            }
            if (!oldString) {
                return [{
                    value: newString,
                    added: true
                }];
            }

            newString = this.tokenize(newString);
            oldString =...