Ember.js v0.9.7.1

by pangratz666

HTML

<script src="https://github.com/downloads/emberjs/ember.js/ember-0.9.7.1.js"></script>
<script type="text/x-handlebars" >
    myArray: {{#each App.obj.myArray }}{{this}}{{/each}}
    <hr/>
    name: {{view Ember.TextField valueBinding="App.obj.name"}}
    <hr/>
    age: {{view Ember.TextField valueBinding="App.obj.age"}}
    <hr/>
    <button {{action "undo" target="App.obj"}} >undo</button>
    <button {{action "redo" target="App.obj"}} >redo</button>
    <hr/>
    {{#each App.obj.memento}}
        {{undoDescription}} / {{redoDescription}}<br/>
    {{/each}}
</script>

JavaScript

App = Ember.Application.create({});

App.Memento = Ember.Mixin.create({
    // holds all history items
    memento: [],

    // current history index
    mementoIndex: -1,

    _addHistory: function(history) {
        /**
         * since _addHistory is invoked on every property change,
         * we have to check if the property value is set from within
         * a "undo" or "redo", and if so, we don't add another history item
         */
        if (!this.get('_isUndo')) {
            /**
             * check if a value has been changed while we have gone
             * back in time via "undo". if so, we delete all history items
             * after the current one
             */
            var mementoIndex = this.get('mementoIndex');
            var lastIndex = this.getPath('memento.length') - 1;
            if (mementoIndex !== lastIndex) {
                this.get('memento').replace(mementoIndex + 1, lastIndex - mementoIndex);
            }

            // add new history item and increase current history index
            this.get('memento').pushObject(history);
            this.incrementProperty('mementoIndex');
        }
    },

    /**
     * Go back in time
     */
    undo: function() {
        this.set('_isUndo', true);
        // check if we can go back in time
        var mementoIndex = this.get('mementoIndex');
        if (mementoIndex >= 0) {
            var historyItem = this.get('memento').objectAt(mementoIndex);
            historyItem.undo();
            this.decrementProperty('mementoIndex');
        }
        this.set('_isUndo', false);
    },

    /**
     * Redo a step in history
     */
    redo: function() {
        this.set('_isUndo', true);
        // check if we can do a step into future
        var mementoIndex = this.get('mementoIndex');
        var historyLength = this.getPath('memento.length');
        if (mementoIndex < historyLength - 1) {
            mementoIndex = this.incrementProperty('mementoIndex');
            var...