mirror of
				https://github.com/flynx/diff.js.git
				synced 2025-10-30 19:40:10 +00:00 
			
		
		
		
	some refactoring...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									829d2c31d9
								
							
						
					
					
						commit
						13492f9907
					
				
							
								
								
									
										196
									
								
								diff.js
									
									
									
									
									
								
							
							
						
						
									
										196
									
								
								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)) | ||||||
|  | 	}, | ||||||
|  | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -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,91 +2204,37 @@ 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) | ||||||
|  | 		res.parent = this | ||||||
|  | 		return res | ||||||
|  | 	}, | ||||||
|  | 	// XXX
 | ||||||
|  | 	merge: function(diff){ | ||||||
|  | 		var res = this.clone() | ||||||
| 
 | 
 | ||||||
| 		// string filter...
 | 		// XXX there are two approaches to this:
 | ||||||
| 		filter = typeof(filter) == typeof('str') ?  | 		// 		1) naive: simply concatenate all the changes in order...
 | ||||||
| 			filter.split(/[\\\/]/)  | 		// 		2) filter and merge changes based on path...
 | ||||||
| 			: filter | 		// XXX do we need a conflict resolution policy???
 | ||||||
| 
 | 
 | ||||||
| 		// path filter (non-function)...
 | 		res.parent = this | ||||||
| 		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 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(){ | ||||||
| 		return { | 		return { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user