mirror of
https://github.com/flynx/diff.js.git
synced 2025-10-29 02:50:10 +00:00
revised .patch(..) and the .walk(..) protocol...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
5a0ddfdd68
commit
4afcdfb26e
90
diff.js
90
diff.js
@ -681,33 +681,57 @@ var Types = {
|
|||||||
|
|
||||||
// Patch (update) obj via diff...
|
// Patch (update) obj via diff...
|
||||||
//
|
//
|
||||||
// XXX this needs to be able to replace obj or parts of it...
|
// XXX should we check for patch integrity???
|
||||||
// XXX this does not work for:
|
// bad patches would include:
|
||||||
// patch(diff(4,5), 4)
|
// - including both a.b and a.b.c is a conflict.
|
||||||
patch: function(diff, obj, options){
|
patch: function(diff, obj, options){
|
||||||
var that = this
|
var that = this
|
||||||
var NONE = diff.placeholders.NONE
|
var NONE = diff.placeholders.NONE
|
||||||
var EMPTY = diff.placeholders.EMPTY
|
var EMPTY = diff.placeholders.EMPTY
|
||||||
var options = diff.options
|
var options = diff.options
|
||||||
|
|
||||||
this.walk(diff.diff, function(change){
|
// NOTE: in .walk(..) we always return the root object bing
|
||||||
// replace the object itself...
|
// patched, this way the handlers have control over the
|
||||||
if(change.path.length == 0){
|
// patching process and it's results on all levels...
|
||||||
return change.B
|
// ...and this is why we can just pop the last item and
|
||||||
}
|
// return it...
|
||||||
|
// NOTE: this will do odd things for conflicting patches...
|
||||||
|
// a conflict can be for example patching both a.b and
|
||||||
|
// a.b.c etc.
|
||||||
|
return this
|
||||||
|
.walk(diff.diff, function(change){
|
||||||
|
// replace the object itself...
|
||||||
|
if(change.path.length == 0){
|
||||||
|
return change.B
|
||||||
|
}
|
||||||
|
|
||||||
var type = change.type || Object
|
var type = change.type || Object
|
||||||
|
|
||||||
var target = change.path
|
var parent
|
||||||
.slice(0, -1)
|
var parent_key
|
||||||
.reduce(function(res, e){
|
var target = change.path
|
||||||
return res[e]}, obj)
|
.slice(0, -1)
|
||||||
var key = change.path[change.path.length-1]
|
.reduce(function(res, e){
|
||||||
|
parent = res
|
||||||
|
parent_key = e
|
||||||
|
return res[e]
|
||||||
|
}, obj)
|
||||||
|
var key = change.path[change.path.length-1]
|
||||||
|
|
||||||
// XXX this needs to be able to replace the target...
|
// call the actual patch...
|
||||||
that.get(type).patch.call(that, target, key, change, options)
|
var res = that.get(type).patch.call(that, target, key, change, obj, options)
|
||||||
})
|
|
||||||
return obj
|
// replace the parent value...
|
||||||
|
if(parent){
|
||||||
|
parent[parent_key] = res
|
||||||
|
|
||||||
|
} else {
|
||||||
|
obj = res
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj
|
||||||
|
})
|
||||||
|
.pop()
|
||||||
},
|
},
|
||||||
|
|
||||||
// Check if diff is applicable to obj...
|
// Check if diff is applicable to obj...
|
||||||
@ -781,6 +805,12 @@ var Types = {
|
|||||||
// ..
|
// ..
|
||||||
// },
|
// },
|
||||||
//
|
//
|
||||||
|
// // Patch the object...
|
||||||
|
// //
|
||||||
|
// patch: function(target, key, change, root, options){
|
||||||
|
// ..
|
||||||
|
// },
|
||||||
|
//
|
||||||
// // Reverse the change...
|
// // Reverse the change...
|
||||||
// //
|
// //
|
||||||
// reverse: function(change){
|
// reverse: function(change){
|
||||||
@ -882,7 +912,7 @@ Types.set(Object, {
|
|||||||
// array item...
|
// array item...
|
||||||
// XXX should this make this decision???
|
// XXX should this make this decision???
|
||||||
} else {
|
} else {
|
||||||
return this.get(Array).patch.call(this, obj, key, change)
|
this.get(Array).patch.call(this, obj, key, change)
|
||||||
}
|
}
|
||||||
return obj
|
return obj
|
||||||
},
|
},
|
||||||
@ -1166,12 +1196,26 @@ Types.set('Text', {
|
|||||||
}, path)
|
}, path)
|
||||||
},
|
},
|
||||||
|
|
||||||
// XXX
|
// XXX this is not efficient...
|
||||||
|
// ...find a way to do all the changes in one go...
|
||||||
// XXX add object compatibility checks...
|
// XXX add object compatibility checks...
|
||||||
patch: function(change, obj){
|
patch: function(obj, key, change){
|
||||||
// XXX
|
var lines = obj.split(/\n/)
|
||||||
|
|
||||||
|
// remove line...
|
||||||
|
if(!('B' in change) || change.B == this.NONE){
|
||||||
|
lines.splice(key, 1)
|
||||||
|
|
||||||
|
// insert line...
|
||||||
|
} else if(!('A' in change) || change.A == this.NONE){
|
||||||
|
lines.splice(key, 0, change.B)
|
||||||
|
|
||||||
|
// replace line...
|
||||||
|
} else {
|
||||||
|
obj.split(/\n/)[key] = change.B
|
||||||
|
}
|
||||||
|
|
||||||
return obj
|
return lines.join('\n')
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user