History

by dafastestfingers

HTML

<div id="toolbar">
    <button id="add">add</button>
    <button id="remove">remove</button>
    <button id="undo">undo</button>
    <button id="redo">redo</button>
    <button id="repeat">repeat</button>
</div>
<br/>
<ul id="canvas"></ul>

CSS

#toolbar > button {
    width: 80px;
}

.selected {
    background: yellow;
}

JavaScript

var History = function() {
    var undoStack = [];
    var redoStack = [];
    var callStack = [];
    var args = {};
    
    (function init() {
        // initialise
    })();
    
    this.undo = function() {
        var callback = undoStack.pop();
        var i = (callStack.length - 1);
        if (callback) {
            redoStack.push(callStack[i]);
            callback(args);
        }
    };
        
    this.redo = function() {
        var callback = redoStack.pop();
        if (callback) {
            callback(args);
        }
    };

    this.repeat = function() {
        var callback = callStack.pop();
        if (callback) {
            callback(args);
        }
    };
    
    this.push = function(undo, caller, kwargs) {
        undoStack.push(undo);
        callStack.push(caller);
        args = kwargs;
    };
}

var history = new History();

$('#add').click(function() {
    var $elm = $('<li>').click(function() {
        $(this).toggleClass('selected');
    });
    $('#canvas').append($elm)
    $elm.text('item:' + $elm.index());
    history.push(function() {
        $elm.detach();
    }, arguments.callee);
});

$('#remove').click(function() {
    var $elm = $('.selected');
    var kwargs = {indexes: []};
    $elm.each(function(i) {
        kwargs.indexes.push($(this).index());    
    });
    $elm.detach();
    history.push(function(args) {
        $elm.each(function(index) {
            var i = args.indexes[index];
            alert(i + ':' + $('#canvas').children().length);
            if (i < $('#canvas').children().length) {
                $('#canvas').children().eq(i).before($(this));
            } else {
                $('#canvas:last-child').append($(this));
            }
        })
    }, arguments.callee, kwargs);
});

$('#undo').click(function() {
     history.undo();
});

$('#redo').click(function() {
    history.redo();
});

$('#repeat').click(function() {
    history.repeat();
});