mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 10:20:08 +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
|
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: this supports tag patterns (see: .match(..))
|
||||||
// NOTE: non-pattern tags are matched explicitly.
|
// NOTE: non-pattern tags are matched explicitly.
|
||||||
// XXX Q: should this support blanket untagging. i.e. .untag(tag)
|
// XXX do we do .match(..) or .directMatch(..) here for patterns???
|
||||||
// to remove all the tags???
|
untag: function(tag, value, ...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){
|
|
||||||
var that = this
|
var that = this
|
||||||
var index = this.__index = this.__index || {}
|
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
|
var remove = this.normalize(tag instanceof Array ? tag : [tag])
|
||||||
.normalize(tags instanceof Array ? tags : [tags])
|
|
||||||
// resolve/match tags...
|
// resolve/match tags...
|
||||||
.map(function(tag){
|
.map(function(tag){
|
||||||
|
// XXX should we use .isQuoted(..) here???
|
||||||
return /\*/.test(tag) ?
|
return /\*/.test(tag) ?
|
||||||
// resolve tag patterns...
|
// resolve tag patterns...
|
||||||
that.match(tag)
|
// XXX is .match(..) to broad here???
|
||||||
|
that.match(tag, local ? tags : null)
|
||||||
: tag })
|
: tag })
|
||||||
.flat()
|
.flat(Infinity)
|
||||||
// do the untagging...
|
|
||||||
.forEach(function(tag){
|
|
||||||
var s = (index[tag] || new Set()).subtract(value)
|
|
||||||
|
|
||||||
// remove empty sets...
|
return local ?
|
||||||
if(s.size == 0){
|
[...new Set(normalizeSplit(tags)).subtract(remove)]
|
||||||
delete index[tag]
|
: (remove
|
||||||
|
// do the untagging...
|
||||||
|
.forEach(function(tag){
|
||||||
|
if(!(tag in index)){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// update...
|
var s = value == '*' ?
|
||||||
} else {
|
new Set()
|
||||||
index[tag] = s
|
: (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...
|
// Toggle tag for each values...
|
||||||
@ -1234,6 +1257,7 @@ var BaseTagsPrototype = {
|
|||||||
//
|
//
|
||||||
// NOTE: this is not called .map(..) because this edits the object
|
// NOTE: this is not called .map(..) because this edits the object
|
||||||
// in-place while map is expected to return a new instance.
|
// 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){
|
replace: function(tag, to, ...tags){
|
||||||
var that = this
|
var that = this
|
||||||
tags = normalizeSplit(tags)
|
tags = normalizeSplit(tags)
|
||||||
@ -1253,26 +1277,21 @@ var BaseTagsPrototype = {
|
|||||||
to
|
to
|
||||||
: this.normalize(to)
|
: this.normalize(to)
|
||||||
|
|
||||||
// XXX this uses definitions to collect tags, this is too broad...
|
// NOTE: this needs the results to get .flat()...
|
||||||
var res = this.directMatch(tag, local ? tags : null, true)
|
var handle = function(tag){
|
||||||
// XXX is this needed / correct / worth it???
|
var target = to instanceof Function ?
|
||||||
.concat(local ? [] : this.directMatch(tag,
|
to.call(that, tag)
|
||||||
Object.entries(definitions)
|
: to
|
||||||
.map(function(e){
|
target = target ?
|
||||||
e[1] = e[1].join(that.SET_SEPARATOR)
|
that.normalize(target)
|
||||||
def_index.set(e[1], (def_index.get(e[1]) || []).concat(e[0]))
|
: target
|
||||||
return e })
|
|
||||||
.flat(), true))
|
|
||||||
.unique()
|
|
||||||
.map(function(tag){
|
|
||||||
var target = to instanceof Function ?
|
|
||||||
that.normalize(to.call(that, tag))
|
|
||||||
: to
|
|
||||||
|
|
||||||
if(tag == target || target == undefined){
|
// no change to tag...
|
||||||
return []
|
if(tag == target || target == undefined){
|
||||||
}
|
return [tag]
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!local){
|
||||||
// persistent...
|
// persistent...
|
||||||
if(persistent.has(tag)){
|
if(persistent.has(tag)){
|
||||||
persistent.delete(tag)
|
persistent.delete(tag)
|
||||||
@ -1299,14 +1318,40 @@ var BaseTagsPrototype = {
|
|||||||
.forEach(function(key){
|
.forEach(function(key){
|
||||||
that.define(key, target == '' ? null : target) })
|
that.define(key, target == '' ? null : target) })
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return target == '' ?
|
return target == '' ?
|
||||||
[]
|
[]
|
||||||
: 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 ?
|
return local ?
|
||||||
res.flat()
|
res
|
||||||
: this
|
: this
|
||||||
},
|
},
|
||||||
// Rename a tag...
|
// Rename a tag...
|
||||||
@ -1360,90 +1405,6 @@ var BaseTagsPrototype = {
|
|||||||
removeTag: function(tag, ...tags){
|
removeTag: function(tag, ...tags){
|
||||||
return this.rename(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...
|
// Replace values...
|
||||||
//
|
//
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user