mirror of
https://github.com/flynx/diff.js.git
synced 2025-10-29 02:50:10 +00:00
some refactoring...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
829d2c31d9
commit
13492f9907
204
diff.js
204
diff.js
@ -1260,6 +1260,95 @@ module.Types = {
|
|||||||
: !that.cmp(change.A, target[key])
|
: !that.cmp(change.A, target[key])
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
// Filter diff changes and return a new diff...
|
||||||
|
//
|
||||||
|
// .filter(path)
|
||||||
|
// .filter(func)
|
||||||
|
// -> diff
|
||||||
|
//
|
||||||
|
// path can be either a '/' separated string of path elements or
|
||||||
|
// an array...
|
||||||
|
//
|
||||||
|
// path supports a limited glob syntax:
|
||||||
|
// * - matches any single path element (like ANY)
|
||||||
|
// ** - matches 0 or more path elements
|
||||||
|
//
|
||||||
|
// NOTE: array path also supports patterns...
|
||||||
|
//
|
||||||
|
filter: function(diff, filter){
|
||||||
|
// string filter...
|
||||||
|
filter = typeof(filter) == typeof('str') ?
|
||||||
|
filter.split(/[\\\/]/)
|
||||||
|
: filter
|
||||||
|
|
||||||
|
// path filter (non-function)...
|
||||||
|
if(!(filter instanceof Function)){
|
||||||
|
// normalize path...
|
||||||
|
// format:
|
||||||
|
// [
|
||||||
|
// '**' | [ .. ],
|
||||||
|
// ...
|
||||||
|
// ]
|
||||||
|
// XXX when OF(..) is ready, replace '**' with OF(ANY, ANY)...
|
||||||
|
var pattern = (filter instanceof Array ? filter : [filter])
|
||||||
|
// '*' -> ANY
|
||||||
|
.map(function(e){
|
||||||
|
return e == '*' ? ANY : e })
|
||||||
|
// remove consecutive repeating '**'
|
||||||
|
.filter(function(e, i, lst){
|
||||||
|
return e == '**' && lst[i-1] != '**' || true })
|
||||||
|
// split to array sections at '**'...
|
||||||
|
.reduce(function(res, e){
|
||||||
|
var n = res.length-1
|
||||||
|
e == '**' ?
|
||||||
|
res.push('**')
|
||||||
|
: (res.length == 0 || res[n] == '**') ?
|
||||||
|
res.push([e])
|
||||||
|
: res[n].push(e)
|
||||||
|
return res
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
// min length...
|
||||||
|
var min = pattern
|
||||||
|
.reduce(function(l, e){
|
||||||
|
return l + (e instanceof Array ? e.length : 0) }, 0)
|
||||||
|
|
||||||
|
// XXX account for pattern/path end...
|
||||||
|
var test = function(path, pattern){
|
||||||
|
return (
|
||||||
|
// end of path/pattern...
|
||||||
|
path.length == 0 && pattern.length == 0 ?
|
||||||
|
true
|
||||||
|
|
||||||
|
// consumed pattern with path left over -> fail...
|
||||||
|
: (path.length > 0 && pattern.length == 0)
|
||||||
|
|| (path.length == 0 && pattern.length > 1)?
|
||||||
|
false
|
||||||
|
|
||||||
|
// '**' -> test, skip elem and repeat...
|
||||||
|
: pattern[0] == '**' ?
|
||||||
|
(test(path, pattern.slice(1))
|
||||||
|
|| test(path.slice(1), pattern))
|
||||||
|
|
||||||
|
// compare sections...
|
||||||
|
: (cmp(
|
||||||
|
path.slice(0, pattern[0].length),
|
||||||
|
pattern[0])
|
||||||
|
// test next section...
|
||||||
|
&& test(
|
||||||
|
path.slice(pattern[0].length),
|
||||||
|
pattern.slice(1)))) }
|
||||||
|
|
||||||
|
// XXX Q: should we ignore the last element of the path???
|
||||||
|
filter = function(change, i, lst){
|
||||||
|
return test(change.path, pattern) }
|
||||||
|
}
|
||||||
|
|
||||||
|
return diff.filter(filter.bind(this))
|
||||||
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2065,7 +2154,7 @@ var DiffPrototype = {
|
|||||||
// instance when returned like this...
|
// instance when returned like this...
|
||||||
//get types(){
|
//get types(){
|
||||||
// return this.constructor.type },
|
// return this.constructor.type },
|
||||||
|
|
||||||
structure: null,
|
structure: null,
|
||||||
placeholders: null,
|
placeholders: null,
|
||||||
options: null,
|
options: null,
|
||||||
@ -2108,13 +2197,6 @@ var DiffPrototype = {
|
|||||||
return res
|
return res
|
||||||
},
|
},
|
||||||
|
|
||||||
// NOTE: this will not mutate this...
|
|
||||||
reverse: function(obj){
|
|
||||||
var res = this.clone()
|
|
||||||
res.diff = Object.create(this.constructor.types).reverse(this.diff)
|
|
||||||
return res
|
|
||||||
},
|
|
||||||
|
|
||||||
check: function(obj){
|
check: function(obj){
|
||||||
return Object.create(this.constructor.types).check(this.diff, obj) },
|
return Object.create(this.constructor.types).check(this.diff, obj) },
|
||||||
patch: function(obj){
|
patch: function(obj){
|
||||||
@ -2122,90 +2204,36 @@ var DiffPrototype = {
|
|||||||
unpatch: function(obj){
|
unpatch: function(obj){
|
||||||
return this.reverse().patch(obj) },
|
return this.reverse().patch(obj) },
|
||||||
|
|
||||||
//
|
// these are non-mutating...
|
||||||
// .filter(path)
|
reverse: function(obj){
|
||||||
// .filter(func)
|
var res = this.clone()
|
||||||
// -> diff
|
res.diff = Object.create(this.constructor.types).reverse(this.diff)
|
||||||
//
|
res.parent = this
|
||||||
|
return res
|
||||||
|
},
|
||||||
filter: function(filter){
|
filter: function(filter){
|
||||||
var res = this.clone()
|
var res = this.clone()
|
||||||
|
res.diff = this.constructor.types.filter.call(this, this.diff, filter)
|
||||||
// string filter...
|
res.parent = this
|
||||||
filter = typeof(filter) == typeof('str') ?
|
|
||||||
filter.split(/[\\\/]/)
|
|
||||||
: filter
|
|
||||||
|
|
||||||
// path filter (non-function)...
|
|
||||||
if(!(filter instanceof Function)){
|
|
||||||
// normalize path...
|
|
||||||
// format:
|
|
||||||
// [
|
|
||||||
// '**' | [ .. ],
|
|
||||||
// ...
|
|
||||||
// ]
|
|
||||||
// XXX when OF(..) is ready, replace '**' with OF(ANY, ANY)...
|
|
||||||
var pattern = (filter instanceof Array ? filter : [filter])
|
|
||||||
// '*' -> ANY
|
|
||||||
.map(function(e){
|
|
||||||
return e == '*' ? ANY : e })
|
|
||||||
// remove consecutive repeating '**'
|
|
||||||
.filter(function(e, i, lst){
|
|
||||||
return e == '**' && lst[i-1] != '**' || true })
|
|
||||||
// split to array sections at '**'...
|
|
||||||
.reduce(function(res, e){
|
|
||||||
var n = res.length-1
|
|
||||||
e == '**' ?
|
|
||||||
res.push('**')
|
|
||||||
: (res.length == 0 || res[n] == '**') ?
|
|
||||||
res.push([e])
|
|
||||||
: res[n].push(e)
|
|
||||||
return res
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
// min length...
|
|
||||||
var min = pattern
|
|
||||||
.reduce(function(l, e){
|
|
||||||
return l + (e instanceof Array ? e.length : 0) }, 0)
|
|
||||||
|
|
||||||
// XXX account for pattern/path end...
|
|
||||||
var test = function(path, pattern){
|
|
||||||
return (
|
|
||||||
// end of path/pattern...
|
|
||||||
path.length == 0 && pattern.length == 0 ?
|
|
||||||
true
|
|
||||||
|
|
||||||
// consumed pattern with path left over -> fail...
|
|
||||||
: (path.length > 0 && pattern.length == 0)
|
|
||||||
|| (path.length == 0 && pattern.length > 1)?
|
|
||||||
false
|
|
||||||
|
|
||||||
// '**' -> test, skip elem and repeat...
|
|
||||||
: pattern[0] == '**' ?
|
|
||||||
(test(path, pattern.slice(1))
|
|
||||||
|| test(path.slice(1), pattern))
|
|
||||||
|
|
||||||
// compare sections...
|
|
||||||
: (cmp(
|
|
||||||
path.slice(0, pattern[0].length),
|
|
||||||
pattern[0])
|
|
||||||
// test next section...
|
|
||||||
&& test(
|
|
||||||
path.slice(pattern[0].length),
|
|
||||||
pattern.slice(1)))) }
|
|
||||||
|
|
||||||
// XXX Q: should we ignore the last element of the path???
|
|
||||||
filter = function(change, i, lst){
|
|
||||||
return test(change.path, pattern) }
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX should we add filter to options or at least set a .filtered attr???
|
|
||||||
// ...or maybe a reference to the original diff...
|
|
||||||
// ...might event implement a jQuery-like .end()
|
|
||||||
|
|
||||||
res.diff = res.diff.filter(filter.bind(this))
|
|
||||||
|
|
||||||
return res
|
return res
|
||||||
},
|
},
|
||||||
|
// XXX
|
||||||
|
merge: function(diff){
|
||||||
|
var res = this.clone()
|
||||||
|
|
||||||
|
// XXX there are two approaches to this:
|
||||||
|
// 1) naive: simply concatenate all the changes in order...
|
||||||
|
// 2) filter and merge changes based on path...
|
||||||
|
// XXX do we need a conflict resolution policy???
|
||||||
|
|
||||||
|
res.parent = this
|
||||||
|
|
||||||
|
return res
|
||||||
|
},
|
||||||
|
|
||||||
|
// XXX EXPERIMENTAL...
|
||||||
|
end: function(){
|
||||||
|
return this.parent || this },
|
||||||
|
|
||||||
// XXX need to normalize .diff and .options...
|
// XXX need to normalize .diff and .options...
|
||||||
json: function(){
|
json: function(){
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user