-
Notifications
You must be signed in to change notification settings - Fork 51
/
backbone.memento.js
115 lines (94 loc) · 2.74 KB
/
backbone.memento.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// Backbone.Memento v0.2.0
//
// Copyright (C)2011 Derick Bailey, Muted Solutions, LLC
// Distributed Under MIT Liscene
//
// Documentation and Full Licence Availabe at:
// http://github.com/derickbailey/backbone.memento
// ----------------------------
// Backbone.Memento
// ----------------------------
Backbone.Memento = function(model, config){
this.version = "0.2.0";
config = _.extend({
ignore: []
}, config);
var attributeStack;
function getAddedAttrDiff(newAttrs, oldAttrs){
var removedAttrs = [];
// guard clause to ensure we have attrs to compare
if (!newAttrs || !oldAttrs){
return removedAttrs;
}
// if the attr is found in the old set but not in
// the new set, then it was remove in the new set
for (var attr in oldAttrs){
if (oldAttrs.hasOwnProperty(attr)){
if (!newAttrs.hasOwnProperty(attr)){
removedAttrs.push(attr);
}
}
}
return removedAttrs;
}
function removeAttributes(model, attrsToRemove){
for (var index in attrsToRemove){
var attr = attrsToRemove[index];
model.unset(attr);
}
}
function restoreState(last, restoreConfig){
//get the previous state
var oldAttrs = attributeStack[last];
if (oldAttrs === undefined){ return; }
oldAttrs = dropIgnored(oldAttrs, restoreConfig);
//get the current state
var currentAttrs = model.toJSON();
currentAttrs = dropIgnored(currentAttrs, restoreConfig);
//handle removing attributes that were added
var removedAttrs = getAddedAttrDiff(oldAttrs, currentAttrs);
removeAttributes(model, removedAttrs);
//restore the previous state
model.set(oldAttrs);
//destroy the no-longer-current state
delete attributeStack[last];
}
function dropIgnored(attrs, restoreConfig){
attrs = _.clone(attrs);
if (restoreConfig.hasOwnProperty("ignore") && restoreConfig.ignore.length > 0){
for(var index in restoreConfig.ignore){
var ignore = restoreConfig.ignore[index];
delete attrs[ignore];
}
}
return attrs;
}
function initialize(){
attributeStack = new Array();
}
this.store = function(){
var attrs = model.toJSON();
attrs = dropIgnored(attrs, config);
attributeStack.push(attrs);
}
this.restore = function(restoreConfig){
if (restoreConfig === undefined){
restoreConfig = _.clone(config);
}
var last = attributeStack.length-1;
if (last < 0) {
return null;
}
restoreState(last, restoreConfig);
}
this.reset = function(){
if(attributeStack.length === 0){
return null;
}
restoreState(0, config);
// restoreState deleted item 0, but really
// we should be starting from scratch.
initialize();
}
initialize();
};