mirror of
				https://github.com/flynx/ImageGrid.git
				synced 2025-10-31 03:10:07 +00:00 
			
		
		
		
	refactored .untag(..) and .replace(..) + some cleanup...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									8d0fbc3e40
								
							
						
					
					
						commit
						c05d713aa5
					
				| @ -1073,55 +1073,78 @@ var BaseTagsPrototype = { | ||||
| 
 | ||||
| 		return this | ||||
| 	}, | ||||
| 	//	
 | ||||
| 	//	Remove tags...
 | ||||
| 	//	.untag(tags)
 | ||||
| 	//	.untag(tags, '*')
 | ||||
| 	//		-> this
 | ||||
| 	//
 | ||||
| 	//	Remove tags form values...
 | ||||
| 	//	.untag(tags, values)
 | ||||
| 	//		-> this
 | ||||
| 	//
 | ||||
| 	//	// Remove 
 | ||||
| 	//	.untag(tags, values, tag, ..)
 | ||||
| 	//		-> this
 | ||||
| 	//
 | ||||
| 	// Pattern syntax:
 | ||||
| 	// 	a			- untag only explicit a
 | ||||
| 	// 	"a"			- the same as above
 | ||||
| 	// 	*a*			- remove all matching a
 | ||||
| 	//
 | ||||
| 	// NOTE: .untag(tags, '*', ..) is similar to .removeTag(tags, ..) 
 | ||||
| 	// 		but not identical. The differences being:
 | ||||
| 	// 			.untag(..)
 | ||||
| 	// 				- removes whole tags only
 | ||||
| 	// 			.removesTag(..)
 | ||||
| 	// 				- can modify tags
 | ||||
| 	//
 | ||||
| 	// NOTE: this supports tag patterns (see: .match(..))
 | ||||
| 	// NOTE: non-pattern tags are matched explicitly.
 | ||||
| 	// XXX Q: should this support blanket untagging. i.e. .untag(tag) 
 | ||||
| 	// 		to remove all the tags???
 | ||||
| 	// 		...this would make this similar to .removeTag(..)
 | ||||
| 	// XXX Q: should this remove tags directly (current) or via matching??
 | ||||
| 	// 			.tag('a:b', 'x')
 | ||||
| 	// 			.untag('a', 'x')		-- this will do nothing.
 | ||||
| 	// 			.untag('*a*', 'x')		-- remove the tag.
 | ||||
| 	// 		...currently I think that matching should be default while 
 | ||||
| 	// 		explicit tag removal should be triggered via something like
 | ||||
| 	// 		putting a tag in quotes:
 | ||||
| 	// 			.untag('"a"', 'x')		-- should remove tagged explicitly 
 | ||||
| 	// 										with "a"...
 | ||||
| 	// 			.untag('a', 'x')		-- like the current '*a*'
 | ||||
| 	// 		what should the default be????
 | ||||
| 	// 		...logic would say that making this query compatible with 
 | ||||
| 	// 		.match(..) is the right way to go from the uniformity point 
 | ||||
| 	// 		of view, but, this would also make this potentially more 
 | ||||
| 	// 		destructive by default...
 | ||||
| 	untag: function(tags, value){ | ||||
| 	// XXX do we do .match(..) or .directMatch(..) here for patterns???
 | ||||
| 	untag: function(tag, value, ...tags){ | ||||
| 		var that = this | ||||
| 		var index = this.__index = this.__index || {} | ||||
| 		value = value instanceof Array ? value : [value] | ||||
| 		value = !value ? | ||||
| 				'*' | ||||
| 			: value instanceof Array ? | ||||
| 				value | ||||
| 			: [value] | ||||
| 		var local = arguments.length > 2 | ||||
| 
 | ||||
| 		this | ||||
| 			.normalize(tags instanceof Array ? tags : [tags]) | ||||
| 		var remove = this.normalize(tag instanceof Array ? tag : [tag]) | ||||
| 			// resolve/match tags...
 | ||||
| 			.map(function(tag){ | ||||
| 				// XXX should we use .isQuoted(..) here???
 | ||||
| 				return /\*/.test(tag) ?  | ||||
| 					// resolve tag patterns...
 | ||||
| 					that.match(tag)  | ||||
| 					// XXX is .match(..) to broad here???
 | ||||
| 					that.match(tag, local ? tags : null)  | ||||
| 					: tag }) | ||||
| 			.flat() | ||||
| 			// do the untagging...
 | ||||
| 			.forEach(function(tag){ | ||||
| 				var s = (index[tag] || new Set()).subtract(value) | ||||
| 			.flat(Infinity) | ||||
| 
 | ||||
| 				// remove empty sets...
 | ||||
| 				if(s.size == 0){ | ||||
| 					delete index[tag] | ||||
| 		return local ? | ||||
| 			[...new Set(normalizeSplit(tags)).subtract(remove)] | ||||
| 			: (remove | ||||
| 				// do the untagging...
 | ||||
| 				.forEach(function(tag){ | ||||
| 					if(!(tag in index)){ | ||||
| 						return | ||||
| 					} | ||||
| 
 | ||||
| 				// update...
 | ||||
| 				} else { | ||||
| 					index[tag] = s | ||||
| 				} | ||||
| 			}) | ||||
| 					var s = value == '*' ? | ||||
| 						new Set() | ||||
| 						: (index[tag] || new Set()).subtract(value) | ||||
| 
 | ||||
| 		return this | ||||
| 					// remove empty sets...
 | ||||
| 					if(s.size == 0){ | ||||
| 						delete index[tag] | ||||
| 
 | ||||
| 					// update...
 | ||||
| 					} else { | ||||
| 						index[tag] = s | ||||
| 					} | ||||
| 				}), this) | ||||
| 	}, | ||||
| 	//
 | ||||
| 	//	Toggle tag for each values...
 | ||||
| @ -1234,6 +1257,7 @@ var BaseTagsPrototype = { | ||||
| 	//
 | ||||
| 	// NOTE: this is not called .map(..) because this edits the object 
 | ||||
| 	// 		in-place while map is expected to return a new instance.
 | ||||
| 	// XXX do we do .match(..) or .directMatch(..) here for patterns???
 | ||||
| 	replace: function(tag, to, ...tags){ | ||||
| 		var that = this | ||||
| 		tags = normalizeSplit(tags) | ||||
| @ -1253,26 +1277,21 @@ var BaseTagsPrototype = { | ||||
| 			to  | ||||
| 			: this.normalize(to) | ||||
| 
 | ||||
| 		// XXX this uses definitions to collect tags, this is too broad...
 | ||||
| 		var res = this.directMatch(tag, local ? tags : null, true) | ||||
| 			// XXX is this needed / correct / worth it???
 | ||||
| 			.concat(local ? [] : this.directMatch(tag,  | ||||
| 				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(tag){ | ||||
| 				var target = to instanceof Function ?  | ||||
| 					that.normalize(to.call(that, tag)) | ||||
| 					: to | ||||
| 		// NOTE: this needs the results to get .flat()...
 | ||||
| 		var handle = function(tag){ | ||||
| 			var target = to instanceof Function ?  | ||||
| 				to.call(that, tag) | ||||
| 				: to | ||||
| 			target = target ?  | ||||
| 				that.normalize(target)  | ||||
| 				: target | ||||
| 
 | ||||
| 				if(tag == target || target == undefined){ | ||||
| 					return [] | ||||
| 				} | ||||
| 			// no change to tag...
 | ||||
| 			if(tag == target || target == undefined){ | ||||
| 				return [tag] | ||||
| 			} | ||||
| 
 | ||||
| 			if(!local){ | ||||
| 				// persistent...
 | ||||
| 				if(persistent.has(tag)){ | ||||
| 					persistent.delete(tag) | ||||
| @ -1299,14 +1318,40 @@ var BaseTagsPrototype = { | ||||
| 						.forEach(function(key){ | ||||
| 							that.define(key, target == '' ? null : target) }) | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 				return target == '' ?  | ||||
| 					[]  | ||||
| 					: target | ||||
| 			}) | ||||
| 			return target == '' ?  | ||||
| 				[]  | ||||
| 				: [target] | ||||
| 		} | ||||
| 
 | ||||
| 		// do the processing...
 | ||||
| 		var res = local ? | ||||
| 			// local...
 | ||||
| 			tags | ||||
| 				.unique() | ||||
| 				.map(function(t){ | ||||
| 					return !that.directMatch(tag, t, true) ? | ||||
| 						[t] | ||||
| 						: handle(t) }) | ||||
| 				.flat() | ||||
| 				.unique() | ||||
| 			// index...
 | ||||
| 			// XXX this uses definitions to collect tags, this is too broad...
 | ||||
| 			: this.directMatch(tag, true) | ||||
| 					// XXX is this needed / correct / worth it???
 | ||||
| 					.concat(this.directMatch(tag,  | ||||
| 						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(handle) | ||||
| 
 | ||||
| 		return local ?  | ||||
| 			res.flat()  | ||||
| 			res  | ||||
| 			: this | ||||
| 	}, | ||||
| 	// Rename a tag...
 | ||||
| @ -1360,90 +1405,6 @@ var BaseTagsPrototype = { | ||||
| 	removeTag: function(tag, ...tags){ | ||||
| 		return this.rename(tag, '', ...tags) }, | ||||
| 
 | ||||
| 	//	
 | ||||
| 	//	Remove tags...
 | ||||
| 	//	.untag(tags)
 | ||||
| 	//	.untag(tags, '*')
 | ||||
| 	//		-> this
 | ||||
| 	//
 | ||||
| 	//	.untag(tags, values)
 | ||||
| 	//		-> this
 | ||||
| 	//
 | ||||
| 	//	.untag(tags, values, tag, ..)
 | ||||
| 	//		-> this
 | ||||
| 	//
 | ||||
| 	// Pattern syntax:
 | ||||
| 	// 	a			- remove a from any matching tag
 | ||||
| 	// 	"a"			- untag only explicit a
 | ||||
| 	// 	*a*			- remove all tags containing a
 | ||||
| 	//
 | ||||
| 	// XXX EXPERIMENTAL...
 | ||||
| 	// XXX this will incorrectly rename sets...
 | ||||
| 	// 		.untag('a:c') // will not correctly rename tag 'a:b:c'...
 | ||||
| 	untag2: function(tag, value, ...tags){ | ||||
| 		var that = this | ||||
| 		value = !value ? | ||||
| 				'*' | ||||
| 			: value instanceof Array ? | ||||
| 				value | ||||
| 			: [value] | ||||
| 		var index = this.__index || {} | ||||
| 
 | ||||
| 		;(tag instanceof Array ? tag : [tag]) | ||||
| 			.forEach(function(tag){ | ||||
| 				var quoted = that.isQuoted(tag) | ||||
| 				var starred = that.isStarred(tag) | ||||
| 				var root = /^\s*['"]?[\\\/]/.test(tag) | ||||
| 				var base = /[\\\/]['"]?\s*$/.test(tag) | ||||
| 				tag = that.normalize(starred ? tag.trim().slice(1, -1) : tag) | ||||
| 
 | ||||
| 				var pattern = !quoted && !starred  | ||||
| 					&& new RegExp( | ||||
| 						`(^|[${that.SET_SEPARATOR}\\${that.PATH_SEPARATOR}])` | ||||
| 							+`${tag}` | ||||
| 							+`(?=$|[${that.SET_SEPARATOR}\\${that.PATH_SEPARATOR}])`, 'g') | ||||
| 				var target = `$1`  | ||||
| 
 | ||||
| 				return that | ||||
| 					.replace(tag, function(t){ | ||||
| 						// skip tags without values (.persistent only)
 | ||||
| 						if(index[t] == null){ | ||||
| 							return | ||||
| 						} | ||||
| 
 | ||||
| 						// special case: literal match...
 | ||||
| 						if(quoted){ | ||||
| 							tag == t && console.log('REMOVE:', t) | ||||
| 							tag == t | ||||
| 								&& (value == '*' ? | ||||
| 									(delete index[t]) | ||||
| 									: (index[t] = index[t].subtract(value))) | ||||
| 
 | ||||
| 						// special case: remove all matching tags...
 | ||||
| 						} else if(starred){ | ||||
| 							value == '*' ? | ||||
| 								(delete index[t]) | ||||
| 								: (index[t] = index[t].subtract(value)) | ||||
| 
 | ||||
| 						// replace occurrence...
 | ||||
| 						} else { | ||||
| 							var values = value == '*' ?  | ||||
| 								index[t]  | ||||
| 								: value | ||||
| 
 | ||||
| 							// remove from old tag...
 | ||||
| 							value == '*' ? | ||||
| 								(delete index[t]) | ||||
| 								: (index[t] = index[t].subtract(value)) | ||||
| 
 | ||||
| 							var renamed = that.normalize(t.replace(pattern, target)) | ||||
| 							// add to modified tag...
 | ||||
| 							renamed != '' | ||||
| 								&& (index[renamed] = (index[renamed] || new Set()).unite(values)) | ||||
| 						} | ||||
| 					}, ...tags) }) | ||||
| 		return this | ||||
| 	}, | ||||
| 
 | ||||
| 	// Replace values...
 | ||||
| 	//
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user