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