refactoring imagegrid/data + docs...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2017-08-30 00:13:38 +03:00
parent 9b4dc520fe
commit 4fa38da17c
2 changed files with 164 additions and 151 deletions

View File

@ -530,8 +530,7 @@ var CollectionActions = actions.Actions({
delete this.data.tags delete this.data.tags
this.data this.data
.removeGIDs(gids) .clear(gids)
.removeEmptyRibbons()
.run(function(){ .run(function(){
this.tags = tags this.tags = tags
this.sortTags() this.sortTags()
@ -544,8 +543,7 @@ var CollectionActions = actions.Actions({
// need to protect them... // need to protect them...
if(this.data !== this.collections[collection].data){ if(this.data !== this.collections[collection].data){
this.collections[collection].data this.collections[collection].data
.removeGIDs(gids) .clear(gids)
.removeEmptyRibbons()
} }
}], }],

View File

@ -200,6 +200,7 @@ var DataPrototype = {
// NOTE: ribbons are sparse... // NOTE: ribbons are sparse...
// NOTE: ribbons can be compact when serialized... // NOTE: ribbons can be compact when serialized...
// //
//
/*****************************************************************/ /*****************************************************************/
get current(){ get current(){
@ -358,19 +359,33 @@ var DataPrototype = {
// Iterate through image lists... // Iterate through image lists...
// //
// .eachImageList(func)
// -> this
//
//
// This accepts a function: // This accepts a function:
// func(list, key, set) // func(list, key, set)
// //
// Where: // Where:
// list - the sparse list of gids // list - the sparse list of gids
// key - the list key in set // key - the list key in set
// set - the set name // set - the set name
// //
// The function is called in the context of the data object. // The function is called in the context of the data object.
// //
// The arguments can be used to access the list directly like this: // The arguments can be used to access the list directly like this:
// this[set][key] -> list // this[set][key] -> list
// //
//
// Set order attribute is used if available to determine the key
// iteration order.
// For 'ribbons' the order is determined as follows:
// .ribbons_order + any missing keys
// .ribbon_order + any missing keys
// Object.keys(this[ribbons])
//
// XXX not sure if we should keep .<set>_order processing as-is,
// might a good idea just to drop it...
eachImageList: function(func){ eachImageList: function(func){
var that = this var that = this
this.__gid_lists.forEach(function(k){ this.__gid_lists.forEach(function(k){
@ -378,9 +393,15 @@ var DataPrototype = {
if(lst == null){ if(lst == null){
return return
} }
Object.keys(lst).forEach(function(l){ var keys = (that[k + '_order']
func.call(that, lst[l], l, k) || that[k.replace(/s$/, '') + '_order']
}) || [])
.concat(Object.keys(lst))
.unique()
//Object.keys(lst)
keys
.forEach(function(l){
func.call(that, lst[l], l, k) })
}) })
return this return this
}, },
@ -426,19 +447,25 @@ var DataPrototype = {
return gid return gid
}, },
// Clear elements from data... // Clear elements from data...
// //
// Clear all data: // Clear all data...
// .clear() // .clear()
// .clear('*') // .clear('*')
// .clear('all') // .clear('all')
// -> data // -> data
// //
// Clear empty ribbons: // Clear empty ribbons...
// .clear('empty') // .clear('empty')
// -> data // -> data
// //
// Clear gid(s) form data: // Clear duplicate gids...
// .clear('dup')
// .clear('duplicates')
// -> data
//
// Clear gid(s) form data...
// .clear(gid) // .clear(gid)
// .clear([gid, gid, ..]) // .clear([gid, gid, ..])
// -> data // -> data
@ -459,12 +486,8 @@ var DataPrototype = {
// cleared... // cleared...
// thus setting appropriate .base and .current values is the // thus setting appropriate .base and .current values is the
// responsibility of the caller. // responsibility of the caller.
//
// XXX not sure this should be here...
// XXX should this reset .base and .current to appropriate values
// other than null?
// XXX should this return this or the removed gids???
clear: function(gids, deep, clear_empty){ clear: function(gids, deep, clear_empty){
var that = this
gids = gids || 'all' gids = gids || 'all'
deep = deep == null ? true : false deep = deep == null ? true : false
clear_empty = clear_empty == null ? true : false clear_empty = clear_empty == null ? true : false
@ -473,6 +496,28 @@ var DataPrototype = {
if(gids == '*' || gids == 'all'){ if(gids == '*' || gids == 'all'){
this._reset() this._reset()
} else if(gids == 'dup' || gids == 'duplicates'){
// horizontal...
this.removeDuplicates(this.order)
this.updateImagePositions()
// vertical...
// if a gid is in more than one ribbon keep only the top
// occurrence...
this.order.forEach(function(gid, i){
var found = false
that.ribbon_order.forEach(function(r){
r = that.ribbons[r]
if(found){
delete r[i]
} else if(r[i] != null){
found = true
}
})
})
// clear empty ribbons only... // clear empty ribbons only...
} else if(gids == 'empty'){ } else if(gids == 'empty'){
for(var r in this.ribbons){ for(var r in this.ribbons){
@ -483,58 +528,123 @@ var DataPrototype = {
// clear gids... // clear gids...
} else { } else {
gids = gids.constructor === Array ? gids : [gids] var ribbons = []
var that = this gids = gids instanceof Array ? gids : [gids]
gids.forEach(function(gid){ // split ribbon and image gids...
var r = that.ribbon_order.indexOf(gid) gids = gids
var i = that.order.indexOf(gid) .filter(function(gid){
// gid is a ribbon... return gid in that.ribbons ?
if(r >= 0){ !ribbons.push(gid)
// clear from order... : true })
that.ribbon_order.splice(r, 1)
// clear from ribbons...
var images = that.ribbons[gid]
delete that.ribbons[gid]
// remove ribbon images... // remove ribbons...
if(deep){ ribbons.forEach(function(gid){
images.forEach(function(gid){ that.clear(gid) }) var i = that.ribbon_order.indexOf(gid)
}
// no more ribbons left... // clear from order...
if(that.ribbon_order.length == 0){ that.ribbon_order.splice(i, 1)
delete that.__base
// shift base up or to first image... // clear from ribbons...
} else if(that.base == gid){ var images = that.ribbons[gid]
that.setBase(Math.max(0, r-1)) delete that.ribbons[gid]
}
// gid is an image... // remove ribbon images...
} else if(i >= 0) { if(deep){
// remove from order... gids = gids.concat(images)
that.order.splice(i, 1) }
that.eachImageList(function(lst){ // no more ribbons left...
lst.splice(i, 1) if(that.ribbon_order.length == 0){
}) delete that.__base
if(that.current == gid){ // shift base up or to first image...
delete that.__current } else if(that.base == gid){
} that.setBase(Math.max(0, i-1))
} }
}) })
// cleanup...
if(clear_empty){ // remove images...
this.clear('empty') var order = this.order
.filter(function(g){ return gids.indexOf(g) < 0 })
// handle current image...
if(gids.indexOf(this.current) >= 0){
var r = this.getImages('current')
.filter(function(g){ return order.indexOf(g) >= 0 })
// attempt to first get next/prev within the current ribbon...
r = r.length > 0 ? r : order
this.current =
this.getImage(this.current, 'after', r)
|| this.getImage(this.current, 'before', r)
} }
// do the actual removal...
// NOTE: splicing fixed image indexes is faster than
// .updateImagePositions('remove')
gids.forEach(function(gid){
var i = that.order.indexOf(gid)
that.eachImageList(function(lst){
lst.splice(i, 1) })
})
this.order = order
// cleanup...
clear_empty
&& this.clear('empty')
} }
return this return this
}, },
// Remove duplicate gids...
//
// If a gid is in more than one ribbon, this will keep the top
// occurrence only...
//
// NOTE: this may result in empty ribbons...
// NOTE: this is slow-ish...
removeDuplicateGIDs: function(){
var that = this
// horizontal...
this.removeDuplicates(this.order)
this.updateImagePositions()
// vertical...
// if a gid is in more than one ribbon keep only the top occurence...
this.order.forEach(function(gid, i){
var found = false
that.ribbon_order.forEach(function(r){
r = that.ribbons[r]
if(found){
delete r[i]
} else if(r[i] != null){
found = true
}
})
})
return this
},
// Remove unloaded gids...
//
// This removes:
// - images from .data that are not in any ribbon
//
// NOTE: this may result in empty ribbons...
removeUnloadedGIDs: function(){
this.order = this.getImages('loaded')
this.updateImagePositions('remove')
return this
},
// Replace image gid... // Replace image gid...
// //
// XXX should this work for ribbon gids??? // XXX should this work for ribbon gids???
@ -2335,7 +2445,7 @@ var DataPrototype = {
base base
// XXX this is slow-ish... // XXX this is slow-ish...
.removeDuplicateGIDs() .removeDuplicateGIDs()
.removeEmptyRibbons() .clear('empty')
return base return base
}, },
@ -2631,101 +2741,6 @@ var DataPrototype = {
/***************************************** Cleanup and removal ***/
// Remove empty ribbons...
//
removeEmptyRibbons: function(){
var that = this
this.ribbon_order = this.ribbon_order
.filter(function(r){
if(that.ribbons[r].len == 0){
delete that.ribbons[r]
return false
}
return true
})
return this
},
// Remove duplicate gids...
//
// If a gid is in more than one ribbon, this will keep the top
// occurrence only...
//
// NOTE: this may result in empty ribbons...
// NOTE: this is slow-ish...
removeDuplicateGIDs: function(){
var that = this
this.removeDuplicates(this.order)
this.updateImagePositions()
// if a gid is in more than one ribbon keep only the top occurence...
this.order.forEach(function(gid, i){
var found = false
that.ribbon_order.forEach(function(r){
r = that.ribbons[r]
if(found){
delete r[i]
} else if(r[i] != null){
found = true
}
})
})
return this
},
// Remove unloaded gids...
//
// This removes:
// - images from .data that are not in any ribbon
//
// NOTE: this may result in empty ribbons...
removeUnloadedGIDs: function(){
this.order = this.getImages('loaded')
this.updateImagePositions('remove')
return this
},
// Remove GIDs...
//
// NOTE: this may result in empty ribbons...
// NOTE: to remove gids from lists but keep them in order use:
// .updateImagePositions(gids, 'hide')
removeGIDs: function(gids, direction){
var that = this
gids = gids || []
gids = (gids instanceof Array ? gids : [gids])
.map(function(gid){ return that.getImage(gid) })
if(gids.length == 0){
return
}
var order = this.order.filter(function(g){ return gids.indexOf(g) < 0 })
// handle current image...
if(gids.indexOf(this.current) >= 0){
var r = this.getImages('current')
.filter(function(g){ return order.indexOf(g) >= 0 })
// attempt to first get next/prev within the current ribbon...
r = r.length > 0 ? r : order
this.current = this.getImage(this.current, direction || 'before', r)
|| this.getImage(this.current, direction == 'after' ? 'before' : 'after', r)
}
this.order = order
this.updateImagePositions('remove')
return this
},
/****************************************** JSON serialization ***/ /****************************************** JSON serialization ***/
// Load data from JSON... // Load data from JSON...