-
Notifications
You must be signed in to change notification settings - Fork 4
/
index.js
75 lines (58 loc) · 1.99 KB
/
index.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
var Immutable = require('immutable');
var Cursor = require('immutable/contrib/cursor');
var events = require('events')
var EVENT_CHANGE = 'change'
function isImmutable(obj) {
return (obj instanceof Immutable.Seq);
}
function History(immutableCollection, changed) {
// if constructor wasn't called with new, call it with new!
if (!this instanceof History) {
return new History(immutableCollection, changed);
}
// accept an immutablejs object or js object
if (!isImmutable(immutableCollection)) {
immutableCollection = Immutable.fromJS(immutableCollection);
}
// Immutable.List will coerce other data types to a list, and will
// silently fail to wrap a List in another list, so we do it ourselves
this.history = Immutable.List([immutableCollection]);
this.emitter = new events.EventEmitter();
this.changed = changed;
var self = this;
this._onChange = function(newData, oldData, path) {
self.history = self.history.push(newData);
self.cursor = Cursor.from(newData, [], self._onChange);
self._emitChange()
}
// allows this to be passed around
this.onChange = this.onChange.bind(this)
this.cursor = Cursor.from(immutableCollection, [], self._onChange);
this._emitChange()
}
History.prototype._emitChange = function() {
this.changed(this.cursor);
this.emitter.emit(EVENT_CHANGE, this.cursor)
}
History.prototype.at = function(index) {
return this.history.get(this.history.count() + index - 1);
};
History.prototype.previousVersion = function() {
return this.at(-1);
}
History.prototype.undoUntilData = function(data) {
this.history = this.history.takeWhile(function(v) {
return v != data;
}).toList().push(data);
var newData = data;
this.cursor = Cursor.from(data, [], this._onChange);
self._emitChange()
return data;
}
History.prototype.undo = function() {
return this.undoUntilData(this.previousVersion());
}
History.prototype.onChange = function(handler) {
return this.emitter.on(EVENT_CHANGE, handler);
}
module.exports = History;