diff --git a/ui (gen4)/imagegrid/data.js b/ui (gen4)/imagegrid/data.js index 0191f792..927a780b 100755 --- a/ui (gen4)/imagegrid/data.js +++ b/ui (gen4)/imagegrid/data.js @@ -2887,6 +2887,7 @@ var DataPrototype = { /*********************************************************************/ var DataWithTagsPrototype = { + __proto__: DataPrototype, // tags store... // @@ -3278,10 +3279,10 @@ var DataWithTagsPrototype = { : this.getImages(res) }, } -DataWithTagsPrototype.__proto__ = DataPrototype -// XXX use tags... +// XXX make a API compatible replacement to the above -- to access +// compatibility and performance... var DataWithTags2Prototype = { __proto__: DataPrototype, @@ -3328,15 +3329,48 @@ var DataWithTags2Prototype = { return this }, - toggleTag: function(){}, + // XXX + toggleTag: function(){ + // XXX + }, // XXX should these be .tags.query(..) ??? - tagQuery: function(query){}, + tagQuery: function(query){ + return this.tags.query(query) }, // Utils... + // XXX tagsFromImages: function(){}, tagsToImages: function(){}, + + // XXX compatibility... + // XXX check if these are ever used without raw... + getTaggedByAll: function(tags, raw){ + var res = this.tags.query(['and', ...tags]) + return raw ? + res + : this.getImages(res) }, + getTaggedByAny: function(tags, raw){ + var res = this.tags.query(['or', ...tags]) + return raw ? + res + : this.getImages(res) }, + + + // NOTE: this is here only to make the tags mutable... + crop: function(){ + var crop = DataWithTags2Prototype.__proto__.crop.apply(this, arguments) + + // make the tags mutable... + if(this.tags != null){ + crop.tags = this.tags + } + + return crop + }, + + // XXX serialization... // XXX init... @@ -3348,6 +3382,9 @@ var DataWithTags2Prototype = { // Proxy Data API to one of the target data objects... var DataProxyPrototype = { + //__proto__: DataPrototype, + __proto__: DataWithTagsPrototype, + datasets: null, get order(){ @@ -3355,8 +3392,6 @@ var DataProxyPrototype = { }, } -//DataProxyPrototype.__proto__ = DataPrototype -DataProxyPrototype.__proto__ = DataWithTagsPrototype /*********************************************************************/ diff --git a/ui (gen4)/imagegrid/tags.js b/ui (gen4)/imagegrid/tags.js index 38d7b7ab..f3e4356e 100755 --- a/ui (gen4)/imagegrid/tags.js +++ b/ui (gen4)/imagegrid/tags.js @@ -258,6 +258,9 @@ var TagsPrototype = { // // NOTE: a tag is also a singular path and a singular set. // NOTE: paths have priority over sets: a/b:c -> a / b:c + // NOTE: there is a special case pattern '*a*' that matches the same + // way as 'a', this is used in cases where 'a' is used as an + // explicit match (see: .untag(..)) // // // Two paths match iff: @@ -311,6 +314,12 @@ var TagsPrototype = { // normalized match... a = this.normalize(a) b = this.normalize(b) + + // special case: *tag* pattern... + a = /^\*[^:\\\/]*\*$/.test(a) ? + a.slice(1, -1) + : a + if(a == b){ return true } @@ -366,7 +375,7 @@ var TagsPrototype = { // .tags(value, tag) // .tags(value, tag, ..) // .tags(value, [tag, ..]) - // -> tags + // -> bool // // NOTE: this includes all the .persistent tags as well as all the // tags actually used. @@ -516,25 +525,68 @@ var TagsPrototype = { // XXX when value is not given, add tags to persistent tags... tag: function(tags, value){ var that = this - this.__index = this.__index || {} - this.normalize(tags instanceof Array ? tags : [tags]) - .forEach(function(tag){ - (that.__index[tag] = that.__index[tag] || new Set()).add(value) }) + value = value instanceof Array ? value : [value] + tags = this.normalize(tags instanceof Array ? tags : [tags]) + var index = this.__index = this.__index || {} + + value.forEach(function(value){ + tags + .forEach(function(tag){ + (index[tag] = index[tag] || new Set()).add(value) }) }) + return this }, + // NOTE: this supports tag patterns (see: ,match(..)) + // NOTE: non-pattern tags are matched explicitly. untag: function(tags, value){ var that = this - this.normalize(tags instanceof Array ? tags : [tags]) - .forEach(function(tag){ - var s = that.__index[tag] || new Set() - s.delete(value) - // remove empty sets... - if(s.size == 0){ - delete that.__index[tag] - } - }) + var index = this.__index = this.__index || {} + + value = value instanceof Array ? value : [value] + tags = this.normalize(tags instanceof Array ? tags : [tags]) + .map(function(tag){ + return /\*/.test(tag) ? + // resolve tag patterns... + that.match(tag) + : tag }) + .flat() + + value.forEach(function(value){ + tags + .forEach(function(tag){ + var s = index[tag] || new Set() + s.delete(value) + // remove empty sets... + if(s.size == 0){ + delete index[tag] + } + }) }) + return this }, + + // NOTE: this supports tag patterns (see: ,match(..)) + // XXX this is not consistent... + // ...should either use explicit matching for everything... + toggleTag: function(tag, values, action){ + var that = this + values = values instanceof Array ? values : [values] + + return action == 'on' ? + this.tag(tag, values) + : action == 'off' ? + this.untag(tag, values) + : action == '?' ? + values + .map(function(v){ + // XXX need to explicitly test tags... (???) + return that.tags(v, tag) }) + // toggle each... + : values + .map(function(v){ + return that.tags(v, tag) ? + (that.untag(tag, v), false) + : (that.tag(tag, v), true) }) }, // Query API... @@ -694,10 +746,6 @@ var TagsPrototype = { // // NOTE: to get the current tags use .tags() // - // - // XXX do we need mode??? - // ...in the current implementation it is pointless to set - // empty sets for tags as they will get cleared... // XXX should this serialize recursively down??? // ...it might be a good idea to decide on a serialization // protocol and use it throughout...