some more refactoring...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2018-07-17 15:43:19 +03:00
parent f515995db3
commit 6d17023cf7

165
diff.js
View File

@ -383,61 +383,87 @@ var partHandlers = {
// //
// XXX might be a good idea to add sub-section splicing, i.e. sub-arrays // XXX might be a good idea to add sub-section splicing, i.e. sub-arrays
// and not just rely on item-level... // and not just rely on item-level...
var Types = new Map([ var Types = Object.assign(
['Basic', new Map([
function(diff, A, B, options){ ['Basic',
this.A = A function(diff, A, B, options){
this.B = B this.A = A
}], this.B = B
[Object, }],
function(diff, A, B, options){ [Object,
this.items = (this.items || []) function(diff, A, B, options){
.concat(partHandlers.attributes(diff, A, B, options)) this.items = (this.items || [])
.concat(partHandlers.attributes(diff, A, B, options))
// XXX optional stuff: // XXX optional stuff:
// - attr ordering... // - attr ordering...
// - prototypes // - prototypes
}], }],
[Array, [Array,
function(diff, A, B, options){ function(diff, A, B, options){
this.length = A.length != B.length ? [A.length, B.length] : [] this.length = A.length != B.length ? [A.length, B.length] : []
this.items = partHandlers.items(diff, A, B, options) this.items = partHandlers.items(diff, A, B, options)
}], }],
/*/ XXX other JS types... /*/ XXX other JS types...
[Map, [Map,
function(diff, A, B, options){ function(diff, A, B, options){
// XXX make the set and map types compatible... // XXX make the set and map types compatible...
// XXX diff [...A.entries()] and [...B.entries()] // XXX diff [...A.entries()] and [...B.entries()]
// ...might be a good idea to sort them too // ...might be a good idea to sort them too
}], }],
[Set, Map], [Set, Map],
//*/ //*/
// XXX not used yet... // Custom types...
['Text', ['Text',
function(diff, A, B, options){ function(diff, A, B, options){
return Types.handle(Array, this, A.split(/\n/), B.split(/\n/), options) }], return Types.handle(Array, this, A.split(/\n/), B.split(/\n/), options) }],
]) ]),
Types.handle = function(type, obj, ...args){ {
// set .type detect: function(A, B){
obj.type = obj.type || (type.name ? type.name : type) var type = Object
for(var t of Types.keys()){
// leave pure objects for last...
if(t === Object
// skip non-conctructor stuff...
|| !(t instanceof Function)){
continue
}
// get the handler + resolve aliases... // full hit -- type match...
var handler = type if(A instanceof t && B instanceof t){
do { type = t
var handler = this.get(handler) break
// unhandled type... }
if(handler == null){ // partial hit -- type mismatch...
throw new TypeError('Diff: can\'t handle: ' + type) if(A instanceof t || B instanceof t){
type = 'Basic'
break
}
}
return type
},
handle: function(type, obj, ...args){
// set .type
obj.type = obj.type || (type.name ? type.name : type)
// get the handler + resolve aliases...
var handler = type
do {
var handler = this.get(handler)
// unhandled type...
if(handler == null){
throw new TypeError('Diff: can\'t handle: ' + type)
}
} while(!(handler instanceof Function))
// call the handler...
handler.call(obj, ...args)
return obj
} }
} while(!(handler instanceof Function)) })
// call the handler...
handler.call(obj, ...args)
return obj
}
// Build a diff between A and B... // Build a diff between A and B...
// //
@ -490,8 +516,9 @@ function(A, B, options, cache){
// find the matching type... // find the matching type...
// NOTE: if A and B types mismatch we treat them as Object... // NOTE: if A and B types mismatch we treat them as Object...
// XXX this may have issues with key ordering, for example if Object // XXX this may have issues with type (key) ordering, for example
// is not last it will match any set of items... // if Object is not last it will match any set of items...
// XXX should type detection be here or in types?
var type = Object var type = Object
for(var t of Types.keys()){ for(var t of Types.keys()){
// leave pure objects for last... // leave pure objects for last...
@ -577,6 +604,8 @@ function(A, B, options, cache){
// may be useful for a more thorough compatibility check. // may be useful for a more thorough compatibility check.
// //
// //
// XXX might be good to include some type info so as to enable patching
// custom stuff like Text...
// XXX does change order matter here??? // XXX does change order matter here???
// ...some changes can affect changes after them (like splicing // ...some changes can affect changes after them (like splicing
// with arrays), this ultimately affects how patching is done... // with arrays), this ultimately affects how patching is done...
@ -620,6 +649,8 @@ function(diff, res, path, options){
;(diff.items || []) ;(diff.items || [])
.forEach(function(e){ .forEach(function(e){
var v = e[2] var v = e[2]
// index...
var i = e[0] == e[1] ? var i = e[0] == e[1] ?
e[0] e[0]
: [e[0], e[1]] : [e[0], e[1]]
@ -651,6 +682,27 @@ function(diff, res, path, options){
flatten(v, res, p, options) flatten(v, res, p, options)
}) })
// Text...
} else if(diff.type == 'Text'){
// items...
;(diff.items || [])
.forEach(function(e){
var v = e[2]
// index...
var i = e[0] == e[1] ?
e[0]
: [e[0], e[1]]
var p = path.concat([i])
res.push({
type: 'Text',
path: p,
// write only the value that is not NONE...
[v.A === NONE ? 'B' : 'A']: v.A === NONE ? v.B : v.A,
})
})
// Other... // Other...
// XXX revise this... // XXX revise this...
} else { } else {
@ -663,11 +715,14 @@ function(diff, res, path, options){
//--------------------------------------------------------------------- //---------------------------------------------------------------------
var diff = var diff =
module.diff = module.diff =
function(A, B, options){ function(A, B, options){
// XXX options = options || {}
} return options.tree_diff ?
_diff(A, B, options)
: flatten(_diff(A, B, options)) }
var patch = var patch =