11 lines
5.1 KiB
JavaScript
11 lines
5.1 KiB
JavaScript
/*!
|
|
* Backbone.Undo.js v0.1
|
|
*
|
|
* Copyright (c)2013 Oliver Sartun
|
|
* Released under the MIT License
|
|
*
|
|
* Documentation and full license available at
|
|
* https://github.com/Bloli/Backbone.Undo.js
|
|
*/
|
|
(function(a,b,c,d,e,f){function g(a,b,c){return 4>=c.length?a.call(b,c[0],c[1],c[2],c[3]):a.apply(b,c)}function h(a,b){if(null==a)return!1;d.isArray(b)||(b=p(arguments,1));for(var c=0,e=b.length;e>c;c++)if(!(b[c]in a))return!1;return!0}function j(){this.registeredObjects=[],this.cidIndexes=[]}function k(a,b,c,e){for(var h,f=0,g=b.length;g>f;f++)if(h=b[f]){if("on"===a){if(e.objectRegistry.isRegistered(h))continue;e.objectRegistry.register(h)}else{if(!e.objectRegistry.isRegistered(h))continue;e.objectRegistry.unregister(h)}d.isFunction(h[a])&&h[a]("all",c,e)}}function l(a,b,c){var e=b.type,f=!c[e]||c[e][a];d.isFunction(f)&&f(b.object,b.before,b.after,b)}function m(a,b,c){if(!(c.isCurrentlyUndoRedoing||"undo"===a&&-1===c.pointer||"redo"===a&&c.pointer===c.length-1)){c.isCurrentlyUndoRedoing=!0;var d,e,f="undo"===a;for(f?(d=c.at(c.pointer),c.pointer--):(c.pointer++,d=c.at(c.pointer)),e=c.where({cycleIndex:d.get("cycleIndex")}),c.pointer+=(f?-1:1)*(e.length-1);d=f?e.pop():e.shift();)d[a](c.undoTypes);c.isCurrentlyUndoRedoing=!1,b.trigger(a,b)}}function n(a,b,c,d,e){if(a.track&&!a.isCurrentlyUndoRedoing&&b in d){var j,f=g(d[b].on,null,c);if(h(f,"object","before","after")){if(f.type=b,f.cycleIndex=i(),a.pointer<a.length-1)for(var j=a.length-a.pointer-1;j--;)a.pop();a.pointer=a.length,a.add(f),a.length>e&&(a.shift(),a.pointer--)}}}function u(){}function v(a,b,c,e){if("object"==typeof b)return d.each(type,function(b,d){2===a?v(a,b,c,e):v(a,d,b,e)});switch(a){case 0:h(c,"undo","redo","on")&&d.all(d.pick(c,"undo","redo","on"),d.isFunction)&&(e[b]=c);break;case 1:e[b]&&d.isObject(c)&&d.extend(e[b],c);break;case 2:delete e[b]}}var i=function(){function c(){b++,a=!0,d.defer(function(){a=!1})}var a=!1,b=-1;return function(){return a||c(),0|b}}();j.prototype={isRegistered:function(a){return a&&a.cid?this.registeredObjects[a.cid]:d.contains(this.registeredObjects,a)},register:function(a){a&&a.cid?(this.registeredObjects[a.cid]=a,this.cidIndexes.push(a.cid)):this.registeredObjects.push(a)},unregister:function(a){if(a&&a.cid)delete this.registeredObjects[a.cid],this.cidIndexes.splice(d.indexOf(this.cidIndexes,a.cid),1);else{var b=d.indexOf(this.registeredObjects,a);this.registeredObjects.splice(b,1)}},get:function(){return d.map(this.indexes,function(a){return this.registeredObjects[a]},this).concat(this.registeredObjects)}};var o=Array.prototype.slice,p=function(a,b){return o.call(a,b)},q={add:{undo:function(a,b,c,d){a.remove(c,d.options)},redo:function(a,b,c,d){var e=d.options;e.index&&(e.at=e.index),a.add(c,d.options)},on:function(a,b,c){return{object:b,before:f,after:a,options:d.clone(c)}}},remove:{undo:function(a,b,c,d){var e=d.options;e.index&&(e.at=e.index),a.add(b,e)},redo:function(a,b,c,d){a.remove(b,d.options)},on:function(a,b,c){return{object:b,before:a,after:f,options:d.clone(c)}}},change:{undo:function(a,b,c){d.isEmpty(b)?d.each(d.keys(c),a.unset,a):a.set(b)},redo:function(a,b,c){d.isEmpty(c)?d.each(d.keys(b),a.unset,a):a.set(c)},on:function(a){var c=a.changedAttributes(),e=d.pick(a.previousAttributes(),d.keys(c));return{object:a,before:e,after:c}}},reset:{undo:function(a,b){a.reset(b)},redo:function(a,b,c){a.reset(c)},on:function(a,b){return{object:a,before:b.previousModels,after:d.clone(a.models)}}}},r=e.Model.extend({defaults:{type:null,object:null,before:null,after:null,cycleIndex:null},undo:function(a){l("undo",this.attributes,a)},redo:function(a){l("redo",this.attributes,a)}}),s=e.Collection.extend({model:r,pointer:-1,track:!1,isCurrentlyUndoRedoing:!1,maximumStackLength:1/0,initialize:function(){this.objectRegistry=new j,this.undoTypes=new u},setMaxLength:function(a){this.maximumStackLength=a},addToStack:function(a){n(this,a,p(arguments,1),this.undoTypes,this.maximumStackLength)}}),t=e.Model.extend({defaults:{maximumStackLength:1/0},initialize:function(){this.stack=new s,this.stack.setMaxLength(this.get("maximumStackLength")),this.on("change:maximumStackLength",function(a,b){this.stack.setMaxLength(b)},this)},startTracking:function(){this.stack.track=!0},stopTracking:function(){this.stack.track=!1},register:function(){k("on",arguments,this.stack.addToStack,this.stack)},unregister:function(){k("off",arguments,this.stack.addToStack,this.stack)},undo:function(){m("undo",this,this.stack)},redo:function(){m("redo",this,this.stack)},isAvailable:function(a){var b=this.stack;switch(a){case"undo":return!!(b.length&&b.pointer>-1);case"redo":return!!(b.length&&b.pointer<b.length-1);default:return!1}},merge:function(a){if(a instanceof t&&a.stack instanceof s){var b=this.stack.objectRegistry.get(),c=!!b.length;c&&g(this.unregister,this,b),this.stack=a.stack,c&&g(this.register,this,b)}},addUndoType:function(a,b){v(0,a,b,this.stack.undoTypes)},changeUndoType:function(a,b){v(1,a,b,this.stack.undoTypes)},removeUndoType:function(a){v(2,a,f,this.stack.undoTypes)}});u.prototype=q,d.extend(t,{addUndoType:function(a,b){v(0,a,b,q)},changeUndoType:function(a,b){v(1,a,b,q)},removeUndoType:function(a){v(2,a,f,q)}}),e.UndoManager=t})(window,window.document,window.jQuery,window._,window.Backbone);
|