mirror of
				https://github.com/flynx/ImageGrid.git
				synced 2025-10-29 18:30:09 +00:00 
			
		
		
		
	cleanup, tweaks and optimizations...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									8085cbe12a
								
							
						
					
					
						commit
						c187f40653
					
				| @ -1218,6 +1218,7 @@ module.TagsEditActions = actions.Actions({ | |||||||
| 		function(tags, gids){ | 		function(tags, gids){ | ||||||
| 			gids = gids || this.current | 			gids = gids || this.current | ||||||
| 			gids = gids instanceof Array ? gids : [gids] | 			gids = gids instanceof Array ? gids : [gids] | ||||||
|  | 			// XXX this is slow for very large data sets...
 | ||||||
| 			gids = this.data.getImages(gids) | 			gids = this.data.getImages(gids) | ||||||
| 
 | 
 | ||||||
| 			tags = tags instanceof Array ? tags : [tags] | 			tags = tags instanceof Array ? tags : [tags] | ||||||
|  | |||||||
| @ -244,6 +244,15 @@ var DataPrototype = { | |||||||
| 	set base(value){ | 	set base(value){ | ||||||
| 		this.__base = value }, | 		this.__base = value }, | ||||||
| 
 | 
 | ||||||
|  | 	get order(){ | ||||||
|  | 		return this.__order }, | ||||||
|  | 	set order(value){ | ||||||
|  | 		delete this.__order_index | ||||||
|  | 		this.__order = value | ||||||
|  | 	}, | ||||||
|  | 	get order_index(){ | ||||||
|  | 		return this.__order_index = this.__order_index || this.order.toKeys() }, | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	/******************************************************* Utils ***/ | 	/******************************************************* Utils ***/ | ||||||
| @ -346,7 +355,8 @@ var DataPrototype = { | |||||||
| 		target = target == null ? [] : target | 		target = target == null ? [] : target | ||||||
| 
 | 
 | ||||||
| 		order = this.order | 		order = this.order | ||||||
| 		var order_idx = order.toKeys() | 		//var order_idx = order.toKeys()
 | ||||||
|  | 		var order_idx = this.order_index || order.toKeys() | ||||||
| 
 | 
 | ||||||
| 		var rest = [] | 		var rest = [] | ||||||
| 
 | 
 | ||||||
| @ -400,6 +410,24 @@ var DataPrototype = { | |||||||
| 		return target | 		return target | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
|  | 	// Merge sparse images...
 | ||||||
|  | 	//
 | ||||||
|  | 	// NOTE: this expects the lists to already be sparse and consistent,
 | ||||||
|  | 	// 		if not this will return rubbish...
 | ||||||
|  | 	mergeSparseImages: function(...lists){ | ||||||
|  | 		var res = [] | ||||||
|  | 		for(var i=0; i < this.order.length; i++){ | ||||||
|  | 			var e = null | ||||||
|  | 			lists | ||||||
|  | 				.forEach(function(l){ | ||||||
|  | 					e = e == null ? l[i] : e }) | ||||||
|  | 			e  | ||||||
|  | 				&& (res[i] = e) | ||||||
|  | 		} | ||||||
|  | 		return res | ||||||
|  | 	}, | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 	// Remove duplicate items from list in-place...
 | 	// Remove duplicate items from list in-place...
 | ||||||
| 	//
 | 	//
 | ||||||
| 	// NOTE: only the first occurrence is kept...
 | 	// NOTE: only the first occurrence is kept...
 | ||||||
| @ -1145,17 +1173,14 @@ var DataPrototype = { | |||||||
| 
 | 
 | ||||||
| 		// get loaded only gids...
 | 		// get loaded only gids...
 | ||||||
| 		} else if(target === 'loaded'){ | 		} else if(target === 'loaded'){ | ||||||
| 			var res = [] | 			list = this | ||||||
| 			var ribbons = this.ribbons | 				.mergeSparseImages(...Object.values(this.ribbons)) | ||||||
| 			for(var k in ribbons){ | 				.compact() | ||||||
| 				this.makeSparseImages(ribbons[k], res) |  | ||||||
| 			} |  | ||||||
| 			list = res.compact() |  | ||||||
| 			target = null | 			target = null | ||||||
| 
 | 
 | ||||||
| 		// filter out the unloaded gids from given list...
 | 		// filter out the unloaded gids from given list...
 | ||||||
| 		} else if(target instanceof Array){ | 		} else if(target instanceof Array){ | ||||||
| 			var loaded = (count == 'current' ?  | 			var loaded = new Set(count == 'current' ?  | ||||||
| 						this.getImages('current') | 						this.getImages('current') | ||||||
| 					: count == 'all' || count == 'global' ?  | 					: count == 'all' || count == 'global' ?  | ||||||
| 						this.getImages('all') | 						this.getImages('all') | ||||||
| @ -1164,14 +1189,12 @@ var DataPrototype = { | |||||||
| 					: typeof(count) == typeof(123) ?  | 					: typeof(count) == typeof(123) ?  | ||||||
| 						this.ribbons[this.getRibbon(count)].compact() | 						this.ribbons[this.getRibbon(count)].compact() | ||||||
| 					: this.getImages('loaded')) | 					: this.getImages('loaded')) | ||||||
| 				// index the loaded gids for fast lookup...
 |  | ||||||
| 				.toKeys() |  | ||||||
| 
 | 
 | ||||||
| 			list = target | 			list = target | ||||||
| 				.map(function(e){ | 				.map(function(e){ | ||||||
| 					// primary path -- gids...
 | 					// primary path -- gids...
 | ||||||
| 					// NOTE: this is the most probable path...
 | 					// NOTE: this is the most probable path...
 | ||||||
| 					if(e in loaded){ | 					if(loaded.has(e)){ | ||||||
| 						return e | 						return e | ||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| @ -1181,9 +1204,9 @@ var DataPrototype = { | |||||||
| 						that.getImage(e, 'global') | 						that.getImage(e, 'global') | ||||||
| 						: that.getImage(e) | 						: that.getImage(e) | ||||||
| 
 | 
 | ||||||
| 					return e in loaded ? e : null | 					return loaded.has(e) ? e : [] | ||||||
| 				}) | 				}) | ||||||
| 				.filter(function(e){ return e !== null }) | 				.flat() | ||||||
| 
 | 
 | ||||||
| 			count = null  | 			count = null  | ||||||
| 			target = null  | 			target = null  | ||||||
| @ -2774,6 +2797,7 @@ var DataPrototype = { | |||||||
| 	// 		XXX is this correct???
 | 	// 		XXX is this correct???
 | ||||||
| 	//
 | 	//
 | ||||||
| 	// XXX should there be a way to set the base ribbon???
 | 	// XXX should there be a way to set the base ribbon???
 | ||||||
|  | 	// XXX TEST
 | ||||||
| 	mergeRibbonCrop: function(crop){ | 	mergeRibbonCrop: function(crop){ | ||||||
| 		var b = this.ribbon_order.indexOf(this.base) | 		var b = this.ribbon_order.indexOf(this.base) | ||||||
| 		var that = this | 		var that = this | ||||||
| @ -2905,409 +2929,9 @@ var DataPrototype = { | |||||||
| 
 | 
 | ||||||
| /*********************************************************************/ | /*********************************************************************/ | ||||||
| 
 | 
 | ||||||
| // XXX should this handle .split(..) / .join(..)
 |  | ||||||
| var DataWithTagsPrototype = { |  | ||||||
| 	__proto__: DataPrototype, |  | ||||||
| 
 |  | ||||||
| 	// tags store...
 |  | ||||||
| 	//
 |  | ||||||
| 	// Format:
 |  | ||||||
| 	// 	{
 |  | ||||||
| 	// 		<tag>: [<gid>, ...],
 |  | ||||||
| 	// 		...
 |  | ||||||
| 	// 	}
 |  | ||||||
| 	tags: null, |  | ||||||
| 
 |  | ||||||
| 	// XXX hate manual super calls...
 |  | ||||||
| 	// 		....is there a way not to say DataPrototype here???
 |  | ||||||
| 	__gid_lists: DataPrototype.__gid_lists.concat(['tags']), |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 	// Load tags from images...
 |  | ||||||
| 	//
 |  | ||||||
| 	// 	Merge image tags to data...
 |  | ||||||
| 	// 	.tagsFromImages(images)
 |  | ||||||
| 	// 		-> data
 |  | ||||||
| 	//
 |  | ||||||
| 	// 	Load image tags to data dropping any changes in data...
 |  | ||||||
| 	// 	.tagsFromImages(images, 'reset')
 |  | ||||||
| 	// 		-> data
 |  | ||||||
| 	//
 |  | ||||||
| 	// XXX should this be here???
 |  | ||||||
| 	// XXX this depend on image structure...
 |  | ||||||
| 	tagsFromImages: function(images, mode){ |  | ||||||
| 		if(mode == 'reset'){ |  | ||||||
| 			this.tags = {} |  | ||||||
| 		} |  | ||||||
| 		for(var gid in images){ |  | ||||||
| 			var img = images[gid] |  | ||||||
| 			if(img.tags != null){ |  | ||||||
| 				this.tag(img.tags, gid) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		return this |  | ||||||
| 			.sortTags() |  | ||||||
| 	}, |  | ||||||
| 
 |  | ||||||
| 	// Transfer tags to images...
 |  | ||||||
| 	//
 |  | ||||||
| 	// 	Merge data tags to images...
 |  | ||||||
| 	// 	.tagsToImages(images)
 |  | ||||||
| 	// 	.tagsToImages(images, true)
 |  | ||||||
| 	// 	.tagsToImages(images, 'merge')
 |  | ||||||
| 	// 		-> data
 |  | ||||||
| 	//
 |  | ||||||
| 	// 	Merge data tags to images without buffering...
 |  | ||||||
| 	// 	.tagsToImages(images, 'unbuffered')
 |  | ||||||
| 	// 		-> data
 |  | ||||||
| 	//
 |  | ||||||
| 	// 	Reset image tags from data...
 |  | ||||||
| 	// 	.tagsToImages(images, 'reset')
 |  | ||||||
| 	// 		-> data
 |  | ||||||
| 	//
 |  | ||||||
| 	// XXX should this be here???
 |  | ||||||
| 	// XXX this depend on image structure...
 |  | ||||||
| 	// XXX should this use image API for creating images???
 |  | ||||||
| 	tagsToImages: function(images, mode, updated){ |  | ||||||
| 		mode = mode || 'merge' |  | ||||||
| 		updated = updated || [] |  | ||||||
| 
 |  | ||||||
| 		// mark gid as updated...
 |  | ||||||
| 		var _updated = function(gid){ |  | ||||||
| 			if(updated != null && updated.indexOf(gid) < 0){ |  | ||||||
| 				updated.push(gid) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		// get or create an image with tags...
 |  | ||||||
| 		// XXX should this use image API for creating???
 |  | ||||||
| 		var _get = function(images, gid){ |  | ||||||
| 			var img = images[gid] |  | ||||||
| 			// create a new image...
 |  | ||||||
| 			if(img == null){ |  | ||||||
| 				img = images[gid] = {} |  | ||||||
| 				_updated(gid) |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			var tags = img.tags |  | ||||||
| 			// no prior tags...
 |  | ||||||
| 			if(tags == null){ |  | ||||||
| 				tags = img.tags = [] |  | ||||||
| 				_updated(gid) |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			return img |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		// buffered mode...
 |  | ||||||
| 		// 	- uses more memory
 |  | ||||||
| 		// 	+ one write mer image
 |  | ||||||
| 		if(mode != 'unbuffered'){ |  | ||||||
| 			// build the buffer...
 |  | ||||||
| 			var buffer = {} |  | ||||||
| 			this.tagsToImages(buffer, 'unbuffered') |  | ||||||
| 
 |  | ||||||
| 			// reset mode...
 |  | ||||||
| 			if(mode == 'reset'){ |  | ||||||
| 				// iterate through all the gids (both images and buffer/data)
 |  | ||||||
| 				for(var gid in Object.keys(images) |  | ||||||
| 						.concat(Object.keys(buffer)) |  | ||||||
| 						.unique()){ |  | ||||||
| 					// no tags / remove...
 |  | ||||||
| 					if(buffer[gid] == null || buffer[gid].tags.length == 0){ |  | ||||||
| 						// the image exists and has tags...
 |  | ||||||
| 						if(images[gid] != null && images[gid].tags != null){ |  | ||||||
| 							delete images[gid].tags |  | ||||||
| 							_updated(gid) |  | ||||||
| 						} |  | ||||||
| 
 |  | ||||||
| 					// tags / set...
 |  | ||||||
| 					} else { |  | ||||||
| 						var img = _get(images, gid) |  | ||||||
| 						var before = img.tags.slice() |  | ||||||
| 
 |  | ||||||
| 						img.tags = buffer[gid].tags |  | ||||||
| 
 |  | ||||||
| 						// check if we actually changed anything...
 |  | ||||||
| 						if(!before.setCmp(img.tags)){ |  | ||||||
| 							_updated(gid) |  | ||||||
| 						} |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 
 |  | ||||||
| 			// merge mode...
 |  | ||||||
| 			} else { |  | ||||||
| 				for(var gid in buffer){ |  | ||||||
| 					var img = _get(images, gid) |  | ||||||
| 					var l = img.tags.length |  | ||||||
| 					img.tags = img.tags |  | ||||||
| 						.concat(buffer[gid].tags) |  | ||||||
| 						.unique() |  | ||||||
| 					// we are updated iff length changed...
 |  | ||||||
| 					// NOTE: this is true as we are not removing anything 
 |  | ||||||
| 					// 		thus the length can only increase if changes are
 |  | ||||||
| 					// 		made...
 |  | ||||||
| 					if(l != img.tags.length){ |  | ||||||
| 						_updated(gid) |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 		// unbuffered (brain-dead) mode...
 |  | ||||||
| 		// 	+ no extra memory
 |  | ||||||
| 		// 	- multiple writes per image (one per tag)
 |  | ||||||
| 		} else { |  | ||||||
| 			var tagset = this.tags |  | ||||||
| 			for(var tag in tagset){ |  | ||||||
| 				tagset[tag].forEach(function(gid){ |  | ||||||
| 					var img = _get(images, gid) |  | ||||||
| 
 |  | ||||||
| 					if(img.tags.indexOf(tag) < 0){ |  | ||||||
| 						img.tags.push(tag) |  | ||||||
| 						_updated(gid) |  | ||||||
| 					} |  | ||||||
| 				}) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		return this |  | ||||||
| 	}, |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 	// NOTE: this is here only to make the tags mutable...
 |  | ||||||
| 	crop: function(){ |  | ||||||
| 		var crop = DataWithTagsPrototype.__proto__.crop.apply(this, arguments) |  | ||||||
| 
 |  | ||||||
| 		// make the tags mutable...
 |  | ||||||
| 		if(this.tags != null){ |  | ||||||
| 			crop.tags = this.tags |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		return crop |  | ||||||
| 	}, |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 	sortTags: function(){ |  | ||||||
| 		var that = this |  | ||||||
| 		var tags = this.tags |  | ||||||
| 
 |  | ||||||
| 		if(tags == null){ |  | ||||||
| 			return this |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		Object.keys(tags).forEach(function(tag){ |  | ||||||
| 			tags[tag] = that.makeSparseImages(tags[tag]) |  | ||||||
| 		}) |  | ||||||
| 		return this |  | ||||||
| 	}, |  | ||||||
| 
 |  | ||||||
| 	tag: function(tags, gids){ |  | ||||||
| 		tags = tags instanceof Array ? tags : [tags] |  | ||||||
| 
 |  | ||||||
| 		gids = gids == null || gids == 'current' ? this.getImage() : gids |  | ||||||
| 		gids = gids instanceof Array ? gids : [gids] |  | ||||||
| 
 |  | ||||||
| 		if(this.tags == null){ |  | ||||||
| 			this.tags = {} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		var that = this |  | ||||||
| 		var tagset = this.tags |  | ||||||
| 		var order = this.order.toKeys() |  | ||||||
| 		tags.forEach(function(tag){ |  | ||||||
| 			var t = tagset[tag] = tagset[tag] || [] |  | ||||||
| 			gids.forEach(function(gid){ |  | ||||||
| 				var i = order[gid] |  | ||||||
| 				gid = i != null ? gid : that.getImage(gid) |  | ||||||
| 				t[i != null ? i : order[gid]] = gid |  | ||||||
| 			}) |  | ||||||
| 		}) |  | ||||||
| 
 |  | ||||||
| 		return this |  | ||||||
| 	}, |  | ||||||
| 	untag: function(tags, gids){ |  | ||||||
| 		if(this.tags == null){ |  | ||||||
| 			return this |  | ||||||
| 		} |  | ||||||
| 		tags = tags instanceof Array ? tags : [tags] |  | ||||||
| 
 |  | ||||||
| 		gids = gids == null || gids == 'current' ? this.getImage() : gids |  | ||||||
| 		gids = gids instanceof Array ? gids : [gids] |  | ||||||
| 
 |  | ||||||
| 		var that = this |  | ||||||
| 		var tagset = this.tags |  | ||||||
| 		var order = this.order.toKeys() |  | ||||||
| 		tags.forEach(function(tag){ |  | ||||||
| 			if(tag in tagset){ |  | ||||||
| 				var t = tagset[tag] |  | ||||||
| 				gids |  | ||||||
| 					.forEach(function(gid){  |  | ||||||
| 						delete t[order[gid]] }) |  | ||||||
| 				if(t.len == 0){ |  | ||||||
| 					delete tagset[tag] |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		}) |  | ||||||
| 
 |  | ||||||
| 		return this |  | ||||||
| 	}, |  | ||||||
| 
 |  | ||||||
| 	// NOTE: this does not support multiple tags at this point...
 |  | ||||||
| 	toggleTag: function(tag, gids, action){ |  | ||||||
| 		gids = gids == null || gids == 'current' ? this.getImage() : gids |  | ||||||
| 		gids = gids instanceof Array ? gids : [gids] |  | ||||||
| 
 |  | ||||||
| 		// tag all...
 |  | ||||||
| 		if(action == 'on'){ |  | ||||||
| 			this.tag(tag, gids) |  | ||||||
| 			return action |  | ||||||
| 
 |  | ||||||
| 		// untag all...
 |  | ||||||
| 		} else if(action == 'off'){ |  | ||||||
| 			this.untag(tag, gids) |  | ||||||
| 			return action |  | ||||||
| 
 |  | ||||||
| 		// get tag state...
 |  | ||||||
| 		} else if(action == '?'){ |  | ||||||
| 			if(this.tags == null){ |  | ||||||
| 				return gids.length > 1 ? gids.map(function(gid){ return 'off' }) : 'off' |  | ||||||
| 			} |  | ||||||
| 			var that = this |  | ||||||
| 			var tagset = this.tags || {} |  | ||||||
| 			var order = this.order |  | ||||||
| 			var order_idx = order.toKeys() |  | ||||||
| 			var res = tag in tagset ? |  | ||||||
| 				gids.map(function(gid){ |  | ||||||
| 					gid = that.getImage(gid) |  | ||||||
| 					return tagset[tag][order_idx[gid]] != null ?  'on' : 'off' |  | ||||||
| 				}) |  | ||||||
| 				: gids.map(function(){ return 'off' }) |  | ||||||
| 
 |  | ||||||
| 		// toggle each...
 |  | ||||||
| 		} else { |  | ||||||
| 			var that = this |  | ||||||
| 			var tagset = this.tags |  | ||||||
| 			var order = this.order |  | ||||||
| 			var order_idx = order.toKeys() |  | ||||||
| 			var res = gids.map(function(gid){ |  | ||||||
| 				gid = that.getImage(gid) |  | ||||||
| 				var t = tagset == null || !(tag in tagset) ? 'on' |  | ||||||
| 					: tagset[tag][order_idx[gid]] == null ? 'on' |  | ||||||
| 					: 'off' |  | ||||||
| 				if(t == 'on'){ |  | ||||||
| 					that.tag(tag, gid) |  | ||||||
| 				} else { |  | ||||||
| 					that.untag(tag, gid) |  | ||||||
| 				} |  | ||||||
| 				return t |  | ||||||
| 			}) |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		return res.length == 1 ? res[0] : res |  | ||||||
| 	}, |  | ||||||
| 
 |  | ||||||
| 	hasTag: function(gid, tag){ |  | ||||||
| 		return ((this.tags || {})[tag] || []).indexOf(this.getImage(gid)) >= 0 }, |  | ||||||
| 	getTags: function(gids){ |  | ||||||
| 		gids = arguments.length > 1 ? [...arguments]  |  | ||||||
| 			: gids == null || gids == 'current' ? this.getImage()  |  | ||||||
| 			: gids |  | ||||||
| 		gids = gids == null ? [] : gids |  | ||||||
| 		gids = gids instanceof Array ? gids : [gids] |  | ||||||
| 
 |  | ||||||
| 		if(this.tags == null){ |  | ||||||
| 			return [] |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		var tags = this.tags |  | ||||||
| 		var order = this.order |  | ||||||
| 
 |  | ||||||
| 		// index the gids...
 |  | ||||||
| 		var indexes = gids.map(function(gid){ return order.indexOf(gid) }) |  | ||||||
| 
 |  | ||||||
| 		// return only those tags that have at least one non-null gid index...
 |  | ||||||
| 		return Object.keys(tags).filter(function(tag){ |  | ||||||
| 			return indexes.filter(function(i){  |  | ||||||
| 				return tags[tag][i] != null  |  | ||||||
| 			}).length > 0 |  | ||||||
| 		}) |  | ||||||
| 	}, |  | ||||||
| 
 |  | ||||||
| 	// selectors...
 |  | ||||||
| 	//
 |  | ||||||
| 	// NOTE: if raw is set to true then this will return all the tagged 
 |  | ||||||
| 	// 		gids even if they are not loaded in ribbons (i.e. cropped out)...
 |  | ||||||
| 	getTaggedByAny: function(tags, raw){ |  | ||||||
| 		tags = arguments.length > 1 ? [...arguments] : tags |  | ||||||
| 		tags = tags instanceof Array ? tags : [tags] |  | ||||||
| 
 |  | ||||||
| 		var res = [] |  | ||||||
| 
 |  | ||||||
| 		if(this.tags == null){ |  | ||||||
| 			return res |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		var that = this |  | ||||||
| 		var tagset = this.tags |  | ||||||
| 		tags.forEach(function(tag){ |  | ||||||
| 			if(tag in tagset){ |  | ||||||
| 				that.makeSparseImages(tagset[tag], res) |  | ||||||
| 			} |  | ||||||
| 		}) |  | ||||||
| 
 |  | ||||||
| 		return raw ?  |  | ||||||
| 			res.compact()  |  | ||||||
| 			: this.getImages(res.compact()) |  | ||||||
| 	}, |  | ||||||
| 	getTaggedByAll: function(tags, raw){ |  | ||||||
| 		tags = arguments.length > 1 ? [...arguments] : tags |  | ||||||
| 		tags = tags instanceof Array ? tags : [tags] |  | ||||||
| 
 |  | ||||||
| 		if(this.tags == null){ |  | ||||||
| 			return [] |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		var index = [] |  | ||||||
| 		var l = tags.length |  | ||||||
| 
 |  | ||||||
| 		// count how many of the tags each image is tagged...
 |  | ||||||
| 		var that = this |  | ||||||
| 		var tagset = this.tags |  | ||||||
| 		tags.forEach(function(tag){ |  | ||||||
| 			if(tag in tagset){ |  | ||||||
| 				Object.keys(tagset[tag]).forEach(function(n){ |  | ||||||
| 					if(index[n] == null){ |  | ||||||
| 						index[n] = 1 |  | ||||||
| 					} else { |  | ||||||
| 						index[n] += 1 |  | ||||||
| 					} |  | ||||||
| 				}) |  | ||||||
| 			} |  | ||||||
| 		}) |  | ||||||
| 
 |  | ||||||
| 		// filter only the images tagged by all of the tags...
 |  | ||||||
| 		var order = this.order |  | ||||||
| 		var res = [] |  | ||||||
| 		var i = index.indexOf(l) |  | ||||||
| 		while(i != -1){ |  | ||||||
| 			res.push(order[i]) |  | ||||||
| 			delete index[i] |  | ||||||
| 
 |  | ||||||
| 			i = index.indexOf(l) |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		return raw ?  |  | ||||||
| 			res  |  | ||||||
| 			: this.getImages(res) |  | ||||||
| 	}, |  | ||||||
| 
 |  | ||||||
| 	// XXX re-implement the above in this...
 |  | ||||||
| 	tagQuery: function(query){ |  | ||||||
| 		throw Error('.tagQuery(..): Not implemented.') }, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| // XXX make a API compatible replacement to the above -- to access 
 | // XXX make a API compatible replacement to the above -- to access 
 | ||||||
| // 		compatibility and performance...
 | // 		compatibility and performance...
 | ||||||
| var DataWithTags2Prototype = { | var DataWithTagsPrototype = { | ||||||
| 	__proto__: DataPrototype, | 	__proto__: DataPrototype, | ||||||
| 
 | 
 | ||||||
| 	get tags(){ | 	get tags(){ | ||||||
| @ -3338,29 +2962,44 @@ var DataWithTags2Prototype = { | |||||||
| 			.unique() | 			.unique() | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
|  | 	// XXX should these normalize the list of gids via .getImages(gids)
 | ||||||
|  | 	// 		or stay optimistic...
 | ||||||
| 	tag: function(tags, gids){ | 	tag: function(tags, gids){ | ||||||
| 		var that = this | 		this.tags.tag(tags, | ||||||
| 		gids = gids == null || gids == 'current' ? this.getImage() : gids | 			gids == null || gids == 'current' ?  | ||||||
| 
 | 				this.current | ||||||
| 		;(gids instanceof Array ? gids : [gids]) | 			: gids == 'ribbon' ? | ||||||
| 			.forEach(function(gid){ | 				this.getImages('current') | ||||||
| 				that.tags.tag(tags, gid) }) | 			: gids == 'loaded' ? | ||||||
| 
 | 				this.getImages('loaded') | ||||||
|  | 			: gids == 'all' ? | ||||||
|  | 				this.getImages('all') | ||||||
|  | 			: gids) | ||||||
| 		return this | 		return this | ||||||
| 	}, | 	}, | ||||||
| 	untag: function(tags, gids){ | 	untag: function(tags, gids){ | ||||||
| 		var that = this | 		this.tags.untag(tags,  | ||||||
| 		gids = gids == null || gids == 'current' ? this.getImage() : gids | 			gids == null || gids == 'current' ?  | ||||||
| 
 | 				this.current | ||||||
| 		;(gids instanceof Array ? gids : [gids]) | 			: gids == 'ribbon' ? | ||||||
| 			.forEach(function(gid){ | 				this.getImages('current') | ||||||
| 				that.tags.untag(tags, gid) }) | 			: gids == 'loaded' ? | ||||||
| 
 | 				this.getImages('loaded') | ||||||
|  | 			: gids == 'all' ? | ||||||
|  | 				this.getImages('all') | ||||||
|  | 			: gids) | ||||||
| 		return this | 		return this | ||||||
| 	}, | 	}, | ||||||
| 	// XXX should all togglers return true/false or 'on'/'off'???
 |  | ||||||
| 	toggleTag: function(tag, gids, action){ | 	toggleTag: function(tag, gids, action){ | ||||||
| 		gids = gids == null || gids == 'current' ? this.getImage() : gids | 		gids = gids == null || gids == 'current' ?  | ||||||
|  | 				this.current | ||||||
|  | 			: gids == 'ribbon' ? | ||||||
|  | 				this.getImages('current') | ||||||
|  | 			: gids == 'loaded' ? | ||||||
|  | 				this.getImages('loaded') | ||||||
|  | 			: gids == 'all' ? | ||||||
|  | 				this.getImages('all') | ||||||
|  | 			: gids | ||||||
| 
 | 
 | ||||||
| 		var res = this.tags.toggle(tag, gids, action) | 		var res = this.tags.toggle(tag, gids, action) | ||||||
| 
 | 
 | ||||||
| @ -3535,12 +3174,12 @@ var DataWithTags2Prototype = { | |||||||
| 	//
 | 	//
 | ||||||
| 	// special case: make the tags mutable...
 | 	// special case: make the tags mutable...
 | ||||||
| 	crop: function(){ | 	crop: function(){ | ||||||
| 		var crop = DataWithTags2Prototype.__proto__.crop.apply(this, arguments) | 		var crop = DataWithTagsPrototype.__proto__.crop.apply(this, arguments) | ||||||
| 		crop.tags = this.tags | 		crop.tags = this.tags | ||||||
| 		return crop | 		return crop | ||||||
| 	}, | 	}, | ||||||
| 	join: function(...others){ | 	join: function(...others){ | ||||||
| 		var res = DataWithTags2Prototype.__proto__.join.apply(this, arguments) | 		var res = DataWithTagsPrototype.__proto__.join.apply(this, arguments) | ||||||
| 		// clear out the align mode...
 | 		// clear out the align mode...
 | ||||||
| 		!(others[0] instanceof Data) | 		!(others[0] instanceof Data) | ||||||
| 			&& others.shift() | 			&& others.shift() | ||||||
| @ -3552,27 +3191,27 @@ var DataWithTags2Prototype = { | |||||||
| 	// XXX should this account for crop???
 | 	// XXX should this account for crop???
 | ||||||
| 	// XXX test...
 | 	// XXX test...
 | ||||||
| 	split: function(){ | 	split: function(){ | ||||||
| 		var res = DataWithTags2Prototype.__proto__.split.apply(this, arguments) | 		var res = DataWithTagsPrototype.__proto__.split.apply(this, arguments) | ||||||
| 		res.tags = res.tags.keep(res.order) | 		res.tags = res.tags.keep(res.order) | ||||||
| 		return res | 		return res | ||||||
| 	}, | 	}, | ||||||
| 	clone: function(){ | 	clone: function(){ | ||||||
| 		var res = DataWithTags2Prototype.__proto__.clone.apply(this, arguments) | 		var res = DataWithTagsPrototype.__proto__.clone.apply(this, arguments) | ||||||
| 		res.tags = this.tags.clone() | 		res.tags = this.tags.clone() | ||||||
| 		return res | 		return res | ||||||
| 	}, | 	}, | ||||||
| 	_reset: function(){ | 	_reset: function(){ | ||||||
| 		var res = DataWithTags2Prototype.__proto__._reset.apply(this, arguments) | 		var res = DataWithTagsPrototype.__proto__._reset.apply(this, arguments) | ||||||
| 		delete this.__tags | 		delete this.__tags | ||||||
| 		return res | 		return res | ||||||
| 	}, | 	}, | ||||||
| 	json: function(){ | 	json: function(){ | ||||||
| 		var json = DataWithTags2Prototype.__proto__.json.apply(this, arguments) | 		var json = DataWithTagsPrototype.__proto__.json.apply(this, arguments) | ||||||
| 		json.tags = this.tags.json() | 		json.tags = this.tags.json() | ||||||
| 		return json | 		return json | ||||||
| 	}, | 	}, | ||||||
| 	load: function(data, clean){ | 	load: function(data, clean){ | ||||||
| 		var res = DataWithTags2Prototype.__proto__.load.apply(this, arguments) | 		var res = DataWithTagsPrototype.__proto__.load.apply(this, arguments) | ||||||
| 		data.tags | 		data.tags | ||||||
| 			&& res.tags.load(data.tags) | 			&& res.tags.load(data.tags) | ||||||
| 		return res | 		return res | ||||||
| @ -3611,7 +3250,7 @@ var DataWithTags = | |||||||
| module.DataWithTags =  | module.DataWithTags =  | ||||||
| object.makeConstructor('DataWithTags',  | object.makeConstructor('DataWithTags',  | ||||||
| 		DataClassPrototype,  | 		DataClassPrototype,  | ||||||
| 		DataWithTags2Prototype) | 		DataWithTagsPrototype) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| var Data = | var Data = | ||||||
|  | |||||||
| @ -80,16 +80,13 @@ Array.prototype.compact = function(){ | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| // like .length but for sparse arrays will return the element count...
 | // like .length but for sparse arrays will return the element count...
 | ||||||
| Object.defineProperty(Array.prototype, 'len', { | 'len' in Array.prototype | ||||||
|  | 	|| Object.defineProperty(Array.prototype, 'len', { | ||||||
| 		get : function () { | 		get : function () { | ||||||
| 			return Object.keys(this).length | 			return Object.keys(this).length | ||||||
| 		}, | 		}, | ||||||
| 		set : function(val){}, | 		set : function(val){}, | ||||||
| 
 | 	}) | ||||||
| 	// NOTE: this is hear to enable running this module multiple times 
 |  | ||||||
| 	// 		without any side-effects...
 |  | ||||||
| 	configurable: true, |  | ||||||
| }); |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| // Convert an array to object...
 | // Convert an array to object...
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user