mirror of
https://github.com/flynx/diff.js.git
synced 2025-10-29 11:00:12 +00:00
revised the docs and notes + changed cr/lf format to unix...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
28de14211d
commit
867e51842a
93
diff.js
93
diff.js
@ -21,7 +21,7 @@
|
|||||||
// zip(func, array, array, ...)
|
// zip(func, array, array, ...)
|
||||||
// -> [func(i, [item, item, ...]), ...]
|
// -> [func(i, [item, item, ...]), ...]
|
||||||
//
|
//
|
||||||
// XXX revise...
|
// XXX revise -- is this too complicated...
|
||||||
var zip = function(func, ...arrays){
|
var zip = function(func, ...arrays){
|
||||||
var i = arrays[0] instanceof Array ? 0 : arrays.shift()
|
var i = arrays[0] instanceof Array ? 0 : arrays.shift()
|
||||||
if(func instanceof Array){
|
if(func instanceof Array){
|
||||||
@ -182,6 +182,12 @@ var getDiffSections = function(A, B, cmp, min_chunk){
|
|||||||
|
|
||||||
// Make a proxy method...
|
// Make a proxy method...
|
||||||
//
|
//
|
||||||
|
// proxy('path.to.attr')
|
||||||
|
// -> method
|
||||||
|
//
|
||||||
|
// proxy('path.to.attr', function)
|
||||||
|
// -> method
|
||||||
|
//
|
||||||
var proxy = function(path, func){
|
var proxy = function(path, func){
|
||||||
path = path instanceof Array ?
|
path = path instanceof Array ?
|
||||||
path.slice()
|
path.slice()
|
||||||
@ -236,7 +242,7 @@ var proxy = function(path, func){
|
|||||||
// ...
|
// ...
|
||||||
// ],
|
// ],
|
||||||
// // only for non-index keys...
|
// // only for non-index keys...
|
||||||
// // XXX unused...
|
// // XXX not implemented...
|
||||||
// item_order: <array-diff>,
|
// item_order: <array-diff>,
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
@ -247,11 +253,11 @@ var proxy = function(path, func){
|
|||||||
// items: [
|
// items: [
|
||||||
// [<key>, <diff>],
|
// [<key>, <diff>],
|
||||||
//
|
//
|
||||||
// // XXX unused....
|
// // XXX not implemented....
|
||||||
// [<key-a>, <key-b>, <diff>],
|
// [<key-a>, <key-b>, <diff>],
|
||||||
// ...
|
// ...
|
||||||
// ],
|
// ],
|
||||||
// // XXX unused...
|
// // XXX not implemented...
|
||||||
// item_order: <array-diff>,
|
// item_order: <array-diff>,
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
@ -272,6 +278,9 @@ var proxy = function(path, func){
|
|||||||
// //
|
// //
|
||||||
// // If not present then the change is simple item insertion
|
// // If not present then the change is simple item insertion
|
||||||
// // or splicing...
|
// // or splicing...
|
||||||
|
// //
|
||||||
|
// // NOTE: insertion vs. splicing depends on the values of .A,
|
||||||
|
// // .B and/or .path, see docs for those...
|
||||||
// type: <change-type>,
|
// type: <change-type>,
|
||||||
//
|
//
|
||||||
// // The path to the item in the object tree...
|
// // The path to the item in the object tree...
|
||||||
@ -309,12 +318,27 @@ var proxy = function(path, func){
|
|||||||
// like the type information which is not needed for patching but
|
// like the type information which is not needed for patching but
|
||||||
// may be useful for a more thorough compatibility check.
|
// may be useful for a more thorough compatibility check.
|
||||||
var Types = {
|
var Types = {
|
||||||
|
// Object-level utilities...
|
||||||
|
clone: function(){
|
||||||
|
var res = Object.create(this)
|
||||||
|
res.handlers = new Map(this.handlers.entries())
|
||||||
|
return res
|
||||||
|
},
|
||||||
|
clear: function(){
|
||||||
|
// XXX should we instead this.handlers.clear() ???
|
||||||
|
this.handlers = new Map()
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
// Placeholder objects...
|
// Placeholder objects...
|
||||||
//
|
//
|
||||||
// Inseted when an item exists on one side and does not on the other.
|
// Inseted when an item exists on one side and does not on the other.
|
||||||
//
|
//
|
||||||
// NOTE: for Array items this does not shift positions of other item
|
// NOTE: for Array items this does not shift positions of other item
|
||||||
// positions nor does it affect the the array lengths.
|
// positions nor does it affect the the array lengths.
|
||||||
|
// NOTE: these are compared by identity while diffing but are compared
|
||||||
|
// by value when patching...
|
||||||
NONE: NONE,
|
NONE: NONE,
|
||||||
EMPTY: EMPTY,
|
EMPTY: EMPTY,
|
||||||
get DIFF_TYPES(){
|
get DIFF_TYPES(){
|
||||||
@ -448,6 +472,9 @@ var Types = {
|
|||||||
|
|
||||||
return type
|
return type
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Handle the difference between A and B...
|
||||||
|
//
|
||||||
handle: function(type, obj, diff, A, B, options){
|
handle: function(type, obj, diff, A, B, options){
|
||||||
// set .type
|
// set .type
|
||||||
type = type == null ? this.detect(A, B, options) : type
|
type = type == null ? this.detect(A, B, options) : type
|
||||||
@ -478,9 +505,12 @@ var Types = {
|
|||||||
// 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...
|
||||||
// ...or is this a quastion of how we treat indexes and the patching
|
// ...or is this a question of how we treat indexes and the patching
|
||||||
// algorithm???
|
// algorithm???
|
||||||
// XXX we should be able to provide "fuzz" (context) to the changes...
|
// XXX we should be able to provide "fuzz" (context, horizontal) to
|
||||||
|
// the changes in ordered containers...
|
||||||
|
// ...it might also be possible to provide vertical/topological
|
||||||
|
// "fuzz", need to think about this...
|
||||||
// XXX TEST: the format should survive JSON.parse(JSON.stringify(..))...
|
// XXX TEST: the format should survive JSON.parse(JSON.stringify(..))...
|
||||||
flatten: function(diff, res, path, options){
|
flatten: function(diff, res, path, options){
|
||||||
res = res || []
|
res = res || []
|
||||||
@ -509,20 +539,20 @@ var Types = {
|
|||||||
// NOTE: for format info see doc for Types...
|
// NOTE: for format info see doc for Types...
|
||||||
//
|
//
|
||||||
// XXX special case: empty sections do not need to be inserted...
|
// XXX special case: empty sections do not need to be inserted...
|
||||||
//
|
// ...splice in a sparse array and store an Array diff with only
|
||||||
|
// length changed...
|
||||||
// XXX do we need to differentiate things like: new Number(123) vs. 123???
|
// XXX do we need to differentiate things like: new Number(123) vs. 123???
|
||||||
// XXX check seen -- avoid recursion...
|
// XXX might be a god idea to mix in default options (different
|
||||||
|
// defaults per mode)...
|
||||||
// XXX TEST: the format should survive JSON.parse(JSON.stringify(..))...
|
// XXX TEST: the format should survive JSON.parse(JSON.stringify(..))...
|
||||||
diff: function(A, B, options, cache){
|
diff: function(A, B, options, cache){
|
||||||
var that = this
|
var that = this
|
||||||
// XXX might be a god idea to mix in default options (different
|
|
||||||
// defaults per mode)...
|
|
||||||
options = options ? Object.create(options) : {}
|
options = options ? Object.create(options) : {}
|
||||||
options.cmp = options.cmp || function(a, b){
|
options.cmp = options.cmp || function(a, b){
|
||||||
return a === b
|
return a === b
|
||||||
|| a == b
|
|| a == b
|
||||||
|
// NOTE: diff(..) is in closure, see cache setup below...
|
||||||
|| (diff(a, b) == null) }
|
|| (diff(a, b) == null) }
|
||||||
// XXX update this depending on mode...
|
|
||||||
options.as_object = options.as_object || []
|
options.as_object = options.as_object || []
|
||||||
|
|
||||||
|
|
||||||
@ -539,7 +569,6 @@ var Types = {
|
|||||||
|
|
||||||
|
|
||||||
// cache...
|
// cache...
|
||||||
// XXX check seen -- avoid recursion...
|
|
||||||
cache = cache || new Map()
|
cache = cache || new Map()
|
||||||
var diff = cache.diff = cache.diff || function(a, b){
|
var diff = cache.diff = cache.diff || function(a, b){
|
||||||
var l2 = cache.get(a) || new Map()
|
var l2 = cache.get(a) || new Map()
|
||||||
@ -679,6 +708,7 @@ Types.set(Object, {
|
|||||||
priority: -50,
|
priority: -50,
|
||||||
|
|
||||||
handle: function(obj, diff, A, B, options){
|
handle: function(obj, diff, A, B, options){
|
||||||
|
// attrebutes/items...
|
||||||
obj.items = (obj.items || [])
|
obj.items = (obj.items || [])
|
||||||
.concat(this.get(Object).attributes.call(this, diff, A, B, options))
|
.concat(this.get(Object).attributes.call(this, diff, A, B, options))
|
||||||
|
|
||||||
@ -901,6 +931,10 @@ Types.set('Text', {
|
|||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
|
// Diff interface function...
|
||||||
|
//
|
||||||
|
// This is a front-end to Types.diff(..), adding a metadata wrapper to
|
||||||
|
// the format, and optionally handling the topology of the output...
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Options format:
|
// Options format:
|
||||||
@ -950,6 +984,11 @@ Types.set('Text', {
|
|||||||
// format: 'object-diff',
|
// format: 'object-diff',
|
||||||
// version: '0.0.0',
|
// version: '0.0.0',
|
||||||
// structure: 'flat' | 'tree',
|
// structure: 'flat' | 'tree',
|
||||||
|
// // NOTE: these are stored in the diff to make the diff independent
|
||||||
|
// // of future changes to the values of the placeholder, both
|
||||||
|
// // in spec and as means to avoid data collisions...
|
||||||
|
// // NOTE: these are compared by identity while diffing but are
|
||||||
|
// // compared by value when patching...
|
||||||
// placeholders: {
|
// placeholders: {
|
||||||
// ...
|
// ...
|
||||||
// },
|
// },
|
||||||
@ -960,15 +999,20 @@ Types.set('Text', {
|
|||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// NOTE: the format itself is JSON compatible (XXX) but the data in the
|
// NOTE: the format itself is JSON compatible but the data in the changes
|
||||||
// changes may not be, so if JSON compatibility is desired, the
|
// may not be, so if JSON compatibility is desired, the inputs or
|
||||||
// inputs or at least the differences between them must be JSON
|
// at least the differences between them must be JSON compatible.
|
||||||
// compatible.
|
|
||||||
// NOTE: recursive inputs will result in recursive diff objects.
|
// NOTE: recursive inputs will result in recursive diff objects.
|
||||||
|
//
|
||||||
|
// XXX should we instantiate Types here so as to make all the caching
|
||||||
|
// call-specific???
|
||||||
|
// XXX revise how the types can be passed in...
|
||||||
var diff =
|
var diff =
|
||||||
module.diff =
|
module.diff =
|
||||||
function(A, B, options){
|
function(A, B, options, types){
|
||||||
options = options || {}
|
options = options || {}
|
||||||
|
types = types || Types.clone()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// system meta information...
|
// system meta information...
|
||||||
format: 'object-diff',
|
format: 'object-diff',
|
||||||
@ -983,18 +1027,23 @@ function(A, B, options){
|
|||||||
options: Object.assign({}, options),
|
options: Object.assign({}, options),
|
||||||
|
|
||||||
diff: options.tree_diff ?
|
diff: options.tree_diff ?
|
||||||
Types.diff(A, B, options)
|
types.diff(A, B, options)
|
||||||
: Types.flatten(Types.diff(A, B, options), null, null, options)
|
: types.flatten(Types.diff(A, B, options), null, null, options)
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
|
||||||
|
// Apply diff (patch) to obj...
|
||||||
|
//
|
||||||
|
// This is a front-end to Types.patch(..), handling loading the options
|
||||||
|
// from the diff...
|
||||||
|
//
|
||||||
var patch =
|
var patch =
|
||||||
module.patch =
|
module.patch =
|
||||||
function(diff, obj){
|
function(diff, obj, options, types){
|
||||||
var t = Object.create(Types)
|
var t = Object.create(types || Types)
|
||||||
diff.placeholders
|
diff.placeholders
|
||||||
&& Object.assign(t, diff.placeholders)
|
&& Object.assign(t, diff.placeholders)
|
||||||
return t.patch(diff, obj)
|
return t.patch(diff, obj, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user