Skip to content

Commit ea697b0

Browse files
authored
Merge pull request #6 from reedsy/doc-invert
✨ Add support for `invertWithDoc` for subtypes
2 parents 6089baa + e8152d6 commit ea697b0

File tree

2 files changed

+41
-2
lines changed

2 files changed

+41
-2
lines changed

lib/json0.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,22 @@ json.create = function(data) {
7777
return data === undefined ? null : clone(data);
7878
};
7979

80-
json.invertComponent = function(c) {
80+
json.invertComponent = function(c, doc) {
8181
var c_ = {p: c.p};
8282

83+
var hasDoc = typeof doc !== 'undefined';
84+
for (var i = 0; i < c.p.length; i++) {
85+
var key = c.p[i];
86+
doc = doc && doc[key];
87+
}
88+
8389
// handle subtype ops
8490
if (c.t && subtypes[c.t]) {
8591
c_.t = c.t;
86-
c_.o = subtypes[c.t].invert(c.o);
92+
var subtype = subtypes[c.t];
93+
if (hasDoc && typeof subtype.invertWithDoc === 'function') c_.o = subtype.invertWithDoc(c.o, doc);
94+
else if (typeof subtype.invert === 'function') c_.o = subtype.invert(c.o);
95+
else throw new Error("Subtype '" + c.t + "' is not invertible");
8796
}
8897

8998
if (c.si !== void 0) c_.sd = c.si;
@@ -111,6 +120,15 @@ json.invert = function(op) {
111120
return iop;
112121
};
113122

123+
json.invertWithDoc = function(op, doc) {
124+
var op_ = op.slice().reverse();
125+
var iop = [];
126+
for (var i = 0; i < op_.length; i++) {
127+
iop.push(json.invertComponent(op_[i], doc));
128+
}
129+
return iop;
130+
}
131+
114132
json.checkValidOp = function(op) {
115133
for (var i = 0; i < op.length; i++) {
116134
if (!isArray(op[i].p)) throw new Error('Missing path');

test/json0.coffee

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,27 @@ genTests = (type) ->
230230
assert.deepEqual [{p:[100], si:'hi'}], type.compose [{p:[100], si:'h'}], [{p:[101], si:'i'}]
231231
assert.deepEqual [{p:[], t:'text0', o:[{p:100, i:'hi'}]}], type.compose [{p:[], t:'text0', o:[{p:100, i:'h'}]}], [{p:[], t:'text0', o:[{p:101, i:'i'}]}]
232232

233+
describe '#invertWithDoc()', ->
234+
it 'passes the doc to the subtype', ->
235+
op = null
236+
doc = null
237+
238+
type.registerSubtype
239+
name: 'invertible'
240+
invertWithDoc: (o, d) ->
241+
op = o
242+
doc = d
243+
244+
type.invertWithDoc [{p: ['foo', 'bar'], t: 'invertible', o: [{increment: 1}]}], {foo: {bar: 5}}
245+
assert.deepEqual [{increment: 1}], op
246+
assert.deepEqual 5, doc
247+
248+
it 'throws if the subtype does not support inversion', ->
249+
type.registerSubtype
250+
name: 'not-invertible'
251+
252+
assert.throws -> type.invertWithDoc [{p: ['foo'], t: 'not-invertible', o: [{increment: 1}]}], {foo: 5}
253+
233254
it 'moves ops on a moved element with the element', ->
234255
assert.deepEqual [{p:[10], ld:'x'}], type.transform [{p:[4], ld:'x'}], [{p:[4], lm:10}], 'left'
235256
assert.deepEqual [{p:[10, 1], si:'a'}], type.transform [{p:[4, 1], si:'a'}], [{p:[4], lm:10}], 'left'

0 commit comments

Comments
 (0)