mirror of
				https://github.com/flynx/ImageGrid.git
				synced 2025-10-31 03:10:07 +00:00 
			
		
		
		
	added .replace(..) and .replaceValues(..) + some tweaks...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									b5f4a08cdf
								
							
						
					
					
						commit
						9f11fa834b
					
				| @ -92,6 +92,8 @@ var makeJoiner = function(separator){ | |||||||
| 		return normalizeSplit(items).join(this[separator]) } } | 		return normalizeSplit(items).join(this[separator]) } } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
 | ||||||
|  | //
 | ||||||
| var BaseTagsClassPrototype = { | var BaseTagsClassPrototype = { | ||||||
| 
 | 
 | ||||||
| 	// NOTE: do not include 'g' flag here, it will make the RE objects
 | 	// NOTE: do not include 'g' flag here, it will make the RE objects
 | ||||||
| @ -372,6 +374,9 @@ var BaseTagsPrototype = { | |||||||
| 	// not account for persistent tags (see: .match(..)).
 | 	// not account for persistent tags (see: .match(..)).
 | ||||||
| 	// This does not build the path graph... (XXX)
 | 	// This does not build the path graph... (XXX)
 | ||||||
| 	//
 | 	//
 | ||||||
|  | 	// NOTE: to disable using definitions for a match pass true as the 
 | ||||||
|  | 	// 		last argument.
 | ||||||
|  | 	//
 | ||||||
| 	//
 | 	//
 | ||||||
| 	// Query syntax:
 | 	// Query syntax:
 | ||||||
| 	// 	a		- single tag
 | 	// 	a		- single tag
 | ||||||
| @ -437,18 +442,27 @@ var BaseTagsPrototype = { | |||||||
| 	//
 | 	//
 | ||||||
| 	// NOTE: this is not symmetric e.g. a will match a:b but not vice-versa.
 | 	// NOTE: this is not symmetric e.g. a will match a:b but not vice-versa.
 | ||||||
| 	// 
 | 	// 
 | ||||||
| 	directMatch: function(a, b, cmp){ | 	// XXX BUG: .directMatch('a/*', 'a/a/a') -> false (should be true)
 | ||||||
|  | 	directMatch: function(a, b, cmp, no_definitions){ | ||||||
| 		var that = this | 		var that = this | ||||||
|  | 		// parse args...
 | ||||||
| 		if(b instanceof Function){ | 		if(b instanceof Function){ | ||||||
| 			cmp = b | 			cmp = b | ||||||
| 			b = null | 			b = null | ||||||
| 		} | 		} | ||||||
|  | 		if(typeof(b) == typeof(true)){ | ||||||
|  | 			no_definitions = b | ||||||
|  | 			b = null | ||||||
|  | 		} else if(typeof(cmp) == typeof(true)){ | ||||||
|  | 			no_definitions = cmp | ||||||
|  | 			cmp = null | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 		// no given tags or multiple tags -> filter...
 | 		// no given tags or multiple tags -> filter...
 | ||||||
| 		if(b == null || b instanceof Array){ | 		if(b == null || b instanceof Array){ | ||||||
| 			return (b || this.tags()) | 			return (b || this.tags()) | ||||||
| 				.filter(function(tag){  | 				.filter(function(tag){  | ||||||
| 					return that.directMatch(a, tag, cmp)}) | 					return that.directMatch(a, tag, cmp, no_definitions)}) | ||||||
| 
 | 
 | ||||||
| 		// match two tags...
 | 		// match two tags...
 | ||||||
| 		} else { | 		} else { | ||||||
| @ -475,9 +489,6 @@ var BaseTagsPrototype = { | |||||||
| 			// NOTE: this does the same job as adding .definitions to 
 | 			// NOTE: this does the same job as adding .definitions to 
 | ||||||
| 			// 		.persistent but much much faster...
 | 			// 		.persistent but much much faster...
 | ||||||
| 			var expand = function(tags, res){ | 			var expand = function(tags, res){ | ||||||
| 				if(!definitions){ |  | ||||||
| 					return tags |  | ||||||
| 				} |  | ||||||
| 				res = (res || new Set()).unite(tags) | 				res = (res || new Set()).unite(tags) | ||||||
| 
 | 
 | ||||||
| 				tags = tags | 				tags = tags | ||||||
| @ -500,7 +511,9 @@ var BaseTagsPrototype = { | |||||||
| 			// NOTE: this matches single tags too...
 | 			// NOTE: this matches single tags too...
 | ||||||
| 			var matchSet = function(a, b){ | 			var matchSet = function(a, b){ | ||||||
| 				a = that.splitSet(a) | 				a = that.splitSet(a) | ||||||
| 				b = expand(that.splitSet(b)) | 				b = (no_definitions || !definitions) ?  | ||||||
|  | 					that.splitSet(b)  | ||||||
|  | 					: expand(that.splitSet(b)) | ||||||
| 				return a.length <= b.length | 				return a.length <= b.length | ||||||
| 					// keep only the non-matches -> if at least one exists we fail...
 | 					// keep only the non-matches -> if at least one exists we fail...
 | ||||||
| 					&& a.filter(function(e){  | 					&& a.filter(function(e){  | ||||||
| @ -869,7 +882,7 @@ var BaseTagsPrototype = { | |||||||
| 						return [tag, definitions[tag]] })) | 						return [tag, definitions[tag]] })) | ||||||
| 			.map(function(e){ | 			.map(function(e){ | ||||||
| 				return e[1] != null ?  | 				return e[1] != null ?  | ||||||
| 					[e[1].join(SS), e[0]].join(SP)  | 					[e[1].join(SS), e[0]].join(PS)  | ||||||
| 					: e[1] })  | 					: e[1] })  | ||||||
| 		return arguments.length == 1 && typeof(arguments[0]) == typeof('str') ? | 		return arguments.length == 1 && typeof(arguments[0]) == typeof('str') ? | ||||||
| 			res[0] | 			res[0] | ||||||
| @ -1179,6 +1192,120 @@ var BaseTagsPrototype = { | |||||||
| 		return res | 		return res | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
|  | 	// Replace tags...
 | ||||||
|  | 	//
 | ||||||
|  | 	//	Replace tags...
 | ||||||
|  | 	//	.replace(from, to)
 | ||||||
|  | 	//		-> this
 | ||||||
|  | 	//
 | ||||||
|  | 	//	Replace tags in list...
 | ||||||
|  | 	//	.replace(from, to, tag, ..)
 | ||||||
|  | 	//	.replace(from, to, [tag, ..])
 | ||||||
|  | 	//		-> tags
 | ||||||
|  | 	//
 | ||||||
|  | 	//	Replace tags via func's return values...
 | ||||||
|  | 	//	.replace(tag, func)
 | ||||||
|  | 	//		-> this
 | ||||||
|  | 	//
 | ||||||
|  | 	//	Replace tags in list via func's return values...
 | ||||||
|  | 	//	.replace(tag, func, tag, ..)
 | ||||||
|  | 	//	.replace(tag, func, [tag, ..])
 | ||||||
|  | 	//		-> tags
 | ||||||
|  | 	//
 | ||||||
|  | 	//
 | ||||||
|  | 	//	func(match)
 | ||||||
|  | 	//		-> tag
 | ||||||
|  | 	//
 | ||||||
|  | 	//
 | ||||||
|  | 	// NOTE: this will only match tags directly not accounting for 
 | ||||||
|  | 	// 		reachability or definitions...
 | ||||||
|  | 	// NOTE: this will match tags in .__index, .persistent and .definitions
 | ||||||
|  | 	//
 | ||||||
|  | 	// XXX EXPERIMENTAL...
 | ||||||
|  | 	replace: function(from, to, ...tags){ | ||||||
|  | 		var that = this | ||||||
|  | 		tags = normalizeSplit(tags) | ||||||
|  | 
 | ||||||
|  | 		var index = this.__index || {}  | ||||||
|  | 		var persistent = this.persistent || new Set() | ||||||
|  | 		var definitions = this.definitions || {} | ||||||
|  | 		var def_index = new Map() | ||||||
|  | 
 | ||||||
|  | 		var local = arguments.length > 2 | ||||||
|  | 
 | ||||||
|  | 		if(from instanceof Function){ | ||||||
|  | 			to = from | ||||||
|  | 			from = '*' | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// XXX this uses definitions to collect tags, this is too broad...
 | ||||||
|  | 		var res = this.directMatch(from, local ? tags : null, true) | ||||||
|  | 			// XXX is this needed / correct / worth it???
 | ||||||
|  | 			.concat(local ? [] : this.directMatch(from,  | ||||||
|  | 				Object.entries(definitions) | ||||||
|  | 					.map(function(e){  | ||||||
|  | 						e[1] = e[1].join(that.SET_SEPARATOR) | ||||||
|  | 						def_index.set(e[1], (def_index.get(e[1]) || []).concat(e[0])) | ||||||
|  | 						return e }) | ||||||
|  | 					.flat(), true)) | ||||||
|  | 			.unique() | ||||||
|  | 			.map(function(from){ | ||||||
|  | 				var target = to instanceof Function ?  | ||||||
|  | 					to.call(that, from)  | ||||||
|  | 					: to | ||||||
|  | 
 | ||||||
|  | 				if(from == target || target == undefined){ | ||||||
|  | 					return [] | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				// persistent...
 | ||||||
|  | 				if(persistent.has(from)){ | ||||||
|  | 					persistent.delete(from) | ||||||
|  | 					target != '' | ||||||
|  | 						&& persistent.add(target) | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				// index...
 | ||||||
|  | 				if(from in index){ | ||||||
|  | 					target != '' | ||||||
|  | 						&& (index[target] = index[from].unite(index[target] || [])) | ||||||
|  | 					delete index[from] | ||||||
|  | 				} | ||||||
|  | 				 | ||||||
|  | 				// definitions (key)...
 | ||||||
|  | 				if(from in definitions){ | ||||||
|  | 					target != '' | ||||||
|  | 						&& that.define(target, definitions[from].join(that.SET_SEPARATOR)) | ||||||
|  | 					delete definitions[from] | ||||||
|  | 				} | ||||||
|  | 				// definitions (value)...
 | ||||||
|  | 				if(def_index.has(from)){ | ||||||
|  | 					def_index.get(from) | ||||||
|  | 						.forEach(function(key){ | ||||||
|  | 							that.define(key, target == '' ? null : target) }) | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				return target == '' ?  | ||||||
|  | 					[]  | ||||||
|  | 					: target | ||||||
|  | 			}) | ||||||
|  | 
 | ||||||
|  | 		return local ?  | ||||||
|  | 			res.flat()  | ||||||
|  | 			: this | ||||||
|  | 	}, | ||||||
|  | 	// Replace values...
 | ||||||
|  | 	//
 | ||||||
|  | 	// 	.replaceValue(from, to)
 | ||||||
|  | 	// 		-> this
 | ||||||
|  | 	//
 | ||||||
|  | 	replaceValue: function(from, to){ | ||||||
|  | 		Object.values(this.__index || {}) | ||||||
|  | 			.forEach(function(values){ | ||||||
|  | 				values.has(from) | ||||||
|  | 					&& values.delete(from) | ||||||
|  | 					&& values.add(to) }) }, | ||||||
|  | 
 | ||||||
| 	// Get/set/remove tag definitions...
 | 	// Get/set/remove tag definitions...
 | ||||||
| 	//
 | 	//
 | ||||||
| 	// A definition is a single tag that is defined by ("means") a tag set.
 | 	// A definition is a single tag that is defined by ("means") a tag set.
 | ||||||
| @ -1704,7 +1831,11 @@ object.makeConstructor('BaseTags', | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| //---------------------------------------------------------------------
 | //---------------------------------------------------------------------
 | ||||||
| 
 | // Special tag handlers...
 | ||||||
|  | //
 | ||||||
|  | // Add an ability to trigger handlers when working with specific (special)
 | ||||||
|  | // tags.
 | ||||||
|  | //
 | ||||||
| // XXX EXPERIMENTAL...
 | // XXX EXPERIMENTAL...
 | ||||||
| var TagsWithHandlersPrototype = { | var TagsWithHandlersPrototype = { | ||||||
| 	__proto__: BaseTagsPrototype, | 	__proto__: BaseTagsPrototype, | ||||||
| @ -1842,8 +1973,13 @@ module.TagsWithHandlers = | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| //---------------------------------------------------------------------
 | //---------------------------------------------------------------------
 | ||||||
| 
 | // Tag dictionary...
 | ||||||
|  | //
 | ||||||
|  | // Maintain non-normalized forms of tags added when tagging and provide
 | ||||||
|  | // means of translating a tag back to that form.
 | ||||||
|  | //
 | ||||||
| // XXX EXPERIMENTAL...
 | // XXX EXPERIMENTAL...
 | ||||||
|  | // XXX do we need to hook .rename(..)
 | ||||||
| var TagsWithDictPrototype = { | var TagsWithDictPrototype = { | ||||||
| 	__proto__: BaseTagsPrototype, | 	__proto__: BaseTagsPrototype, | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user