mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-28 18:00:09 +00:00
reworked system caches...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
026ff53ab2
commit
d77c01e63e
@ -1806,9 +1806,19 @@ module.Crop = core.ImageGridFeatures.Feature({
|
||||
tag: 'crop',
|
||||
depends: [
|
||||
'base',
|
||||
//'cache',
|
||||
],
|
||||
|
||||
actions: CropActions,
|
||||
|
||||
handlers: [
|
||||
[[
|
||||
'crop',
|
||||
'uncrop',
|
||||
'removeFromCrop',
|
||||
],
|
||||
'clearCache: "view(-.*)?" "*" -- Clear view cache'],
|
||||
],
|
||||
})
|
||||
|
||||
|
||||
|
||||
@ -1779,6 +1779,13 @@ module.Collection = core.ImageGridFeatures.Feature({
|
||||
// XXX
|
||||
})
|
||||
}],
|
||||
|
||||
// invalidate caches...
|
||||
[[
|
||||
'loadCollection',
|
||||
'uncollect',
|
||||
],
|
||||
'clearCache: "view(-.*)?" "*" -- Clear view cache'],
|
||||
],
|
||||
})
|
||||
|
||||
|
||||
@ -1027,9 +1027,21 @@ module.Serialization = ImageGridFeatures.Feature({
|
||||
// Cache...
|
||||
|
||||
// XXX should this be in actions.js???
|
||||
// XXX should we invalidate the cache automatically???
|
||||
// XXX the cache can also be saved to localStorage and loaded until either
|
||||
// the version changes or the feature list...
|
||||
// XXX revise: cache group naming...
|
||||
// currently the used groups are:
|
||||
// Session groups -- cleared on .clear() ('cache')
|
||||
// session-*
|
||||
// view-*
|
||||
// View groups -- cleared by crop/collection ('crop', 'collections')
|
||||
// view-*
|
||||
// Changes groups -- cleared when specific changes are made ('changes')
|
||||
// *-data
|
||||
// *-images
|
||||
// ...
|
||||
// This approach seems not flexible enough...
|
||||
// Ideas:
|
||||
// - use keywords in group names??
|
||||
// XXX should we consider persistent caches -- localStorage???
|
||||
var CacheActions = actions.Actions({
|
||||
config: {
|
||||
// Enable/disable caching...
|
||||
@ -1062,11 +1074,30 @@ var CacheActions = actions.Actions({
|
||||
// action is available...
|
||||
'pre-cache-progress': 3000,
|
||||
|
||||
|
||||
// Groups to be cleared at the longest on session change...
|
||||
//
|
||||
// These include by default:
|
||||
// 'session' - will live through the whole session.
|
||||
// 'view' - cleared when view changes
|
||||
//
|
||||
'cache-session-groups': [
|
||||
'session',
|
||||
'view',
|
||||
],
|
||||
|
||||
// XXX handler cache..
|
||||
},
|
||||
|
||||
// Cache utility method...
|
||||
//
|
||||
// .cache(title, handler)
|
||||
// -> value
|
||||
//
|
||||
// .cache(group, title, handler)
|
||||
// -> value
|
||||
//
|
||||
//
|
||||
// Example use:
|
||||
// someAction: [
|
||||
// function(){
|
||||
@ -1086,18 +1117,106 @@ var CacheActions = actions.Actions({
|
||||
// return data
|
||||
// }) }],
|
||||
//
|
||||
cache: function(title, lister){
|
||||
// XXX what should the default group be???
|
||||
// XXX should this be an action???
|
||||
__cache: null,
|
||||
cache: function(title, handler){
|
||||
var group = 'global'
|
||||
// caching disabled...
|
||||
if(!(this.config || {}).cache){
|
||||
return lister.call(this)
|
||||
}
|
||||
return handler.call(this) }
|
||||
arguments.length > 2
|
||||
&& ([group, title, handler] = arguments)
|
||||
var cache = this.__cache = this.__cache || {}
|
||||
cache = cache[group] = cache[group] || {}
|
||||
return (cache[title] =
|
||||
title in cache ?
|
||||
// pass the cached data for cloning/update to the lister...
|
||||
lister.call(this, cache[title])
|
||||
: lister.call(this))
|
||||
},
|
||||
// pass the cached data for cloning/update to the handler...
|
||||
handler.call(this, cache[title])
|
||||
: handler.call(this)) },
|
||||
clearCache: ['System/Clear cache',
|
||||
doc`
|
||||
|
||||
Clear cache fully...
|
||||
.clearCache()
|
||||
|
||||
Clear title (global group)...
|
||||
.clearCache(title)
|
||||
|
||||
Clear title from group...
|
||||
.clearCache(group, title)
|
||||
|
||||
Clear out the full group...
|
||||
.clearCache(group, '*')
|
||||
|
||||
|
||||
NOTE: a group can be a string, list or a regexp object.
|
||||
`,
|
||||
function(title){
|
||||
var that = this
|
||||
// full clear...
|
||||
if(arguments.length == 0
|
||||
|| (arguments[0] == '*'
|
||||
&& arguments[1] == '*')){
|
||||
delete this.__cache
|
||||
// partial clear...
|
||||
} else {
|
||||
var group = 'global'
|
||||
// both group and title given...
|
||||
arguments.length > 1
|
||||
&& ([group, title] = arguments)
|
||||
|
||||
// regexp...
|
||||
// NOTE: these are only supported in groups...
|
||||
if(group != '*' && group.includes('*')){
|
||||
group = new RegExp('^'+ group +'$', 'i')
|
||||
group = Object.keys(this.__cache || {})
|
||||
.filter(function(g){
|
||||
return group.test(g) }) }
|
||||
|
||||
// clear title from each group...
|
||||
if(group == '*' || group instanceof Array || group instanceof RegExp){
|
||||
;(group instanceof Array ?
|
||||
group
|
||||
: group instanceof RegExp ?
|
||||
Object.keys(this.__cache || {})
|
||||
.filter(function(g){
|
||||
return group.test(g) })
|
||||
: Object.keys(this.__cache || {}))
|
||||
.forEach(function(group){
|
||||
that.clearCache(group, title) })
|
||||
// clear multiple titles...
|
||||
} else if(title instanceof Array){
|
||||
title.forEach(function(title){
|
||||
delete ((that.__cache || {})[group] || {})[title] })
|
||||
// clear group...
|
||||
} else if(title == '*'){
|
||||
delete (this.__cache || {})[group]
|
||||
// clear title from group...
|
||||
} else {
|
||||
delete ((this.__cache || {})[group] || {})[title] } } }],
|
||||
|
||||
// special caches...
|
||||
//
|
||||
sessionCache: ['- System/',
|
||||
doc`Add to session cache...
|
||||
|
||||
.sessionCache(title, handler)
|
||||
-> value
|
||||
|
||||
|
||||
This is a shorthand to:
|
||||
|
||||
.cache('session', title, handler)
|
||||
-> value
|
||||
|
||||
|
||||
NOTE: also see .cache(..)
|
||||
`,
|
||||
'cache: "session" ...'],
|
||||
|
||||
|
||||
// XXX doc: what are we precaching???
|
||||
preCache: ['System/Run pre-cache',
|
||||
doc`Run pre-cache...
|
||||
|
||||
@ -1120,8 +1239,7 @@ var CacheActions = actions.Actions({
|
||||
var done = 0
|
||||
var attrs = []
|
||||
for(var k in this){
|
||||
attrs.push(k)
|
||||
}
|
||||
attrs.push(k) }
|
||||
var l = attrs.length
|
||||
|
||||
var started = Date.now()
|
||||
@ -1131,45 +1249,25 @@ var CacheActions = actions.Actions({
|
||||
var a = Date.now()
|
||||
var b = a
|
||||
if(attrs.length == 0){
|
||||
return
|
||||
}
|
||||
|
||||
return }
|
||||
while(b - a < c){
|
||||
this[attrs.pop()]
|
||||
b = Date.now()
|
||||
done += 1
|
||||
|
||||
this.showProgress
|
||||
&& (show === true || (show && b - started > show))
|
||||
&& this.showProgress('Caching', done, l)
|
||||
}
|
||||
|
||||
&& this.showProgress('Caching', done, l) }
|
||||
t === true ?
|
||||
tick()
|
||||
: setTimeout(tick, t)
|
||||
}.bind(this)
|
||||
: setTimeout(tick, t) }.bind(this)
|
||||
|
||||
tick()
|
||||
}
|
||||
}],
|
||||
clearCache: ['System/Clear cache',
|
||||
function(title){
|
||||
if(title){
|
||||
delete (this.__cache|| {})[title]
|
||||
|
||||
} else {
|
||||
delete this.__cache
|
||||
}
|
||||
}],
|
||||
|
||||
// XXX do we need this...
|
||||
tick() } }],
|
||||
reCache: ['System/Re-cache',
|
||||
function(t){
|
||||
this
|
||||
.clearCache()
|
||||
.preCache(t) }],
|
||||
|
||||
|
||||
toggleHandlerCache: ['System/Action handler cache',
|
||||
makeConfigToggler('action-handler-cache',
|
||||
['off', 'on']/*,
|
||||
@ -1192,15 +1290,16 @@ module.Cache = ImageGridFeatures.Feature({
|
||||
actions: CacheActions,
|
||||
|
||||
handlers: [
|
||||
// System...
|
||||
['start.pre',
|
||||
function(){
|
||||
this.clearCache()
|
||||
var t = this.config['pre-cache']
|
||||
t === true ?
|
||||
this.preCache('now')
|
||||
: t >= 0 ?
|
||||
this.preCache()
|
||||
: false
|
||||
}],
|
||||
: false }],
|
||||
['start',
|
||||
function(){
|
||||
// XXX this breaks loading...
|
||||
@ -1208,7 +1307,6 @@ module.Cache = ImageGridFeatures.Feature({
|
||||
// there seems to be no problems...
|
||||
//this.toggleHandlerCache(this.config['action-handler-cache'] || 'on')
|
||||
}],
|
||||
|
||||
/*/ XXX clear cache when feature/action topology changes...
|
||||
[[
|
||||
'inlineMixin',
|
||||
@ -1222,6 +1320,16 @@ module.Cache = ImageGridFeatures.Feature({
|
||||
this.clearCache()
|
||||
}],
|
||||
//*/
|
||||
|
||||
|
||||
// clear session cache...
|
||||
['clear',
|
||||
//'clearCache: "(session|view)(-.*)?" "*" -- Clear session cache'],
|
||||
function(){
|
||||
this.clearCache(`(${
|
||||
(this.config['cache-session-groups']
|
||||
|| ['session', 'view'])
|
||||
.join('|') })(-.*)?`) }],
|
||||
],
|
||||
})
|
||||
|
||||
@ -2148,6 +2256,16 @@ module.Changes = ImageGridFeatures.Feature({
|
||||
this.changes = JSON.parse(JSON.stringify(data.changes))
|
||||
}
|
||||
}],
|
||||
|
||||
// clear caches relating to stuff we just changed...
|
||||
['markChanged',
|
||||
function(_, section){
|
||||
section = (section instanceof Array ?
|
||||
section
|
||||
: [section])
|
||||
.map(function(section){
|
||||
return '.*-'+section })
|
||||
this.clearCache(section, '*') }],
|
||||
],
|
||||
})
|
||||
|
||||
|
||||
@ -25,8 +25,7 @@ var base = require('features/base')
|
||||
|
||||
var makeStateIndicator = function(type){
|
||||
return $('<div>')
|
||||
.addClass('state-indicator-container ' + type || '')
|
||||
}
|
||||
.addClass('state-indicator-container ' + type || '') }
|
||||
|
||||
// XXX do we need this???
|
||||
var makeStateIndicatorItem = function(container, type, text){
|
||||
@ -35,8 +34,7 @@ var makeStateIndicatorItem = function(container, type, text){
|
||||
.attr('text', text)
|
||||
this.dom.find('.state-indicator-container.'+container)
|
||||
.append(item)
|
||||
return item
|
||||
}
|
||||
return item }
|
||||
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
@ -102,6 +100,13 @@ var StatusBarActions = actions.Actions({
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
get __statusbar_cache(){
|
||||
return this.cache('view-data', 'statusbar',
|
||||
function(data){
|
||||
return data || {}}) },
|
||||
|
||||
|
||||
__statusbar_elements__: {
|
||||
/* item template...
|
||||
item: function(item){
|
||||
@ -133,8 +138,7 @@ var StatusBarActions = actions.Actions({
|
||||
index: function(item, gid, img){
|
||||
// cleanup...
|
||||
if(item == null){
|
||||
return
|
||||
}
|
||||
return }
|
||||
|
||||
var that = this
|
||||
gid = gid || this.current
|
||||
@ -162,8 +166,7 @@ var StatusBarActions = actions.Actions({
|
||||
// toggle index state...
|
||||
.click(function(){
|
||||
that.toggleStatusBarIndexMode()
|
||||
that.updateStatusBar()
|
||||
})
|
||||
that.updateStatusBar() })
|
||||
// editable...
|
||||
: $('<span>')
|
||||
.addClass('position editable')
|
||||
@ -182,40 +185,35 @@ var StatusBarActions = actions.Actions({
|
||||
//event.stopPropagation()
|
||||
|
||||
(that.config['status-bar-index'] || {})['live-update-on-edit']
|
||||
&& go(parseInt($(this).text()))
|
||||
})
|
||||
&& go(parseInt($(this).text())) })
|
||||
.focus(function(){
|
||||
$(this).selectText()
|
||||
})
|
||||
$(this).selectText() })
|
||||
.blur(function(){
|
||||
that.updateStatusBar()
|
||||
}))
|
||||
that.updateStatusBar() }))
|
||||
.append($('<span>')
|
||||
.addClass('length')
|
||||
.attr('info', 'Image count (click to toggle ribbon/global)')
|
||||
// toggle index state...
|
||||
.click(function(){
|
||||
that.toggleStatusBarIndexMode()
|
||||
that.updateStatusBar()
|
||||
}))
|
||||
that.updateStatusBar() }))
|
||||
|
||||
} else {
|
||||
var type = item.attr('type')
|
||||
}
|
||||
var type = item.attr('type') }
|
||||
|
||||
// NOTE: using .toggleStatusBarIndexMode(..) here will fall
|
||||
// into an infinite recursion...
|
||||
var cls = (that.config['status-bar-index'] || {})['mode'] || 'normal'
|
||||
|
||||
// XXX get the cached length...
|
||||
// XXX make this part of the status bar cache...
|
||||
var cache = this.__statusbar_index_length_cache || []
|
||||
cache = cache[0] == cls ?
|
||||
cache[1]
|
||||
// get the cached length...
|
||||
var cache = this.__statusbar_cache.index_total
|
||||
cache = cache ?
|
||||
(cache[0] == cls
|
||||
&& cache[1])
|
||||
: null
|
||||
|
||||
// empty view...
|
||||
if(this.data){
|
||||
if(!this.data){
|
||||
var i = -1
|
||||
var l = 0
|
||||
|
||||
@ -234,11 +232,16 @@ var StatusBarActions = actions.Actions({
|
||||
// ribbon index...
|
||||
} else {
|
||||
var i = this.data.getImageOrder('ribbon', gid)
|
||||
var l = cache =
|
||||
cache || this.data.getImages(gid).len }
|
||||
var r = this.current_ribbon
|
||||
var l = cache
|
||||
&& cache instanceof Array
|
||||
&& cache[0] == r
|
||||
&& cache[1]
|
||||
l = l || this.data.getImages(gid).len
|
||||
cache = [r, l] }
|
||||
|
||||
// XXX save cache...
|
||||
this.__statusbar_index_length_cache = [cls, cache]
|
||||
// save cache...
|
||||
this.__statusbar_cache.index_total = [cls, cache]
|
||||
|
||||
// update...
|
||||
item
|
||||
@ -250,13 +253,11 @@ var StatusBarActions = actions.Actions({
|
||||
.find('.length')
|
||||
.text(l > 0 ? ('/' + l) : '')
|
||||
|
||||
return item
|
||||
},
|
||||
return item },
|
||||
ribbon: function(item, gid, img){
|
||||
// cleanup...
|
||||
if(item == null){
|
||||
return
|
||||
}
|
||||
return }
|
||||
|
||||
var that = this
|
||||
|
||||
@ -294,8 +295,7 @@ var StatusBarActions = actions.Actions({
|
||||
}))
|
||||
.append($('<span>')
|
||||
.addClass('ribbon-count')
|
||||
.attr('info', 'Ribbon count'))
|
||||
}
|
||||
.attr('info', 'Ribbon count')) }
|
||||
|
||||
item
|
||||
.find('.ribbon-number')
|
||||
@ -312,22 +312,18 @@ var StatusBarActions = actions.Actions({
|
||||
item[0].setAttribute('base', '')
|
||||
|
||||
} else {
|
||||
item[0].removeAttribute('base')
|
||||
}
|
||||
item[0].removeAttribute('base') }
|
||||
|
||||
return item
|
||||
},
|
||||
return item },
|
||||
changes: function(item, gid, img){
|
||||
// cleanup...
|
||||
if(item == null){
|
||||
return
|
||||
}
|
||||
return }
|
||||
|
||||
if(typeof(item) == typeof('str')){
|
||||
item = $('<span>')
|
||||
.addClass('changes')
|
||||
.attr('info', 'Unsaved changes')
|
||||
}
|
||||
.attr('info', 'Unsaved changes') }
|
||||
|
||||
//item.html(this.changes !== false ?
|
||||
// this.config['status-bar-changes-text'] || '*'
|
||||
@ -337,14 +333,12 @@ var StatusBarActions = actions.Actions({
|
||||
this.config['status-bar-changes-text'] || '*'
|
||||
: '')
|
||||
|
||||
return item
|
||||
},
|
||||
return item },
|
||||
// XXX handle path correctly...
|
||||
gid: function(item, gid, img){
|
||||
// cleanup...
|
||||
if(item == null){
|
||||
return
|
||||
}
|
||||
return }
|
||||
|
||||
var that = this
|
||||
gid = gid || this.current
|
||||
@ -363,12 +357,10 @@ var StatusBarActions = actions.Actions({
|
||||
// select the text...
|
||||
// XXX should this also copy???
|
||||
.click(function(){
|
||||
$(this).selectText()
|
||||
}))
|
||||
$(this).selectText() }))
|
||||
|
||||
} else {
|
||||
var type = item.attr('type')
|
||||
}
|
||||
var type = item.attr('type') }
|
||||
|
||||
// update...
|
||||
var txt = ''
|
||||
@ -386,14 +378,14 @@ var StatusBarActions = actions.Actions({
|
||||
text = (img && img.path && ((img.base_path || '') +'/'+ img.path) || '---')
|
||||
// remove /./
|
||||
.replace(/[\\\/]\.[\\\/]/, '/')
|
||||
txt = img && ((img.name || '') + (img.ext || '')) || text.split(/[\\\/]/).pop()
|
||||
}
|
||||
txt = img
|
||||
&& ((img.name || '') + (img.ext || ''))
|
||||
|| text.split(/[\\\/]/).pop() }
|
||||
|
||||
item.find('.shown').text(txt)
|
||||
item.find('.hidden').text(text)
|
||||
|
||||
return item
|
||||
},
|
||||
return item },
|
||||
path: 'gid',
|
||||
'edit-mode': function(item){
|
||||
// cleanup...
|
||||
@ -401,21 +393,20 @@ var StatusBarActions = actions.Actions({
|
||||
this.__edit_mode_indicator_update
|
||||
&& this.off('keyPress', this.__edit_mode_indicator_update)
|
||||
delete this.__edit_mode_indicator_update
|
||||
return
|
||||
}
|
||||
return }
|
||||
|
||||
var update = this.__edit_mode_indicator_update = this.__edit_mode_indicator_update
|
||||
|| (function(){
|
||||
var caps = this.keyboard.capslock
|
||||
caps = typeof(event) != 'undefined' && event.getModifierState ?
|
||||
event.getModifierState('CapsLock')
|
||||
: caps
|
||||
item
|
||||
.attr('info', 'Edit mode '
|
||||
+ (caps ? 'on' : 'off')
|
||||
+ ' (Click to update / Press CapsLock to toggle)')
|
||||
[caps ? 'addClass' : 'removeClass']('on')
|
||||
}).bind(this)
|
||||
var update = this.__edit_mode_indicator_update =
|
||||
this.__edit_mode_indicator_update
|
||||
|| (function(){
|
||||
var caps = this.keyboard.capslock
|
||||
caps = typeof(event) != 'undefined' && event.getModifierState ?
|
||||
event.getModifierState('CapsLock')
|
||||
: caps
|
||||
item
|
||||
.attr('info', 'Edit mode '
|
||||
+ (caps ? 'on' : 'off')
|
||||
+ ' (Click to update / Press CapsLock to toggle)')
|
||||
[caps ? 'addClass' : 'removeClass']('on') }).bind(this)
|
||||
|
||||
// cleanup interval handling...
|
||||
this.__edit_mode_indicator_update_interval
|
||||
@ -426,8 +417,7 @@ var StatusBarActions = actions.Actions({
|
||||
if(item == null){
|
||||
this.off('keyPress', update)
|
||||
this.dom.off('focus', update)
|
||||
return
|
||||
}
|
||||
return }
|
||||
|
||||
// setup...
|
||||
if(typeof(item) == typeof('str')){
|
||||
@ -441,8 +431,7 @@ var StatusBarActions = actions.Actions({
|
||||
.click(update)
|
||||
|
||||
this.on('keyPress', update)
|
||||
this.dom.focus(update)
|
||||
}
|
||||
this.dom.focus(update) }
|
||||
|
||||
// update timer...
|
||||
// NOTE: this is needed so as to reflect changes to settings...
|
||||
@ -454,15 +443,13 @@ var StatusBarActions = actions.Actions({
|
||||
// update state...
|
||||
update()
|
||||
|
||||
return item
|
||||
},
|
||||
return item },
|
||||
// XXX show menu in the appropriate corner...
|
||||
// XXX remove the type+ed class...
|
||||
mark: function(item, gid, img){
|
||||
// cleanup...
|
||||
if(item == null){
|
||||
return
|
||||
}
|
||||
return }
|
||||
|
||||
gid = gid || this.current
|
||||
var that = this
|
||||
@ -484,12 +471,10 @@ var StatusBarActions = actions.Actions({
|
||||
evt.preventDefault()
|
||||
evt.stopPropagation()
|
||||
|
||||
that.browseActions('/'+ type.capitalize() +'/')
|
||||
})
|
||||
that.browseActions('/'+ type.capitalize() +'/') })
|
||||
|
||||
} else {
|
||||
var type = item.attr('type')
|
||||
}
|
||||
var type = item.attr('type') }
|
||||
|
||||
// NOTE: we are not using .toggleMark('?') and friends
|
||||
// here to avoid recursion as we might be handling
|
||||
@ -503,8 +488,7 @@ var StatusBarActions = actions.Actions({
|
||||
'removeClass'
|
||||
: 'addClass']('on')
|
||||
|
||||
return item
|
||||
},
|
||||
return item },
|
||||
bookmark: 'mark',
|
||||
},
|
||||
|
||||
@ -520,8 +504,7 @@ var StatusBarActions = actions.Actions({
|
||||
function(){
|
||||
// no viewer yet...
|
||||
if(!this.ribbons || !this.dom){
|
||||
return $()
|
||||
}
|
||||
return $() }
|
||||
|
||||
var bar = this.dom.find('.state-indicator-container.global-info')
|
||||
if(bar.length == 0){
|
||||
@ -543,17 +526,14 @@ var StatusBarActions = actions.Actions({
|
||||
.on('mouseout', function(){
|
||||
bar.find('.info').empty()
|
||||
})
|
||||
.appendTo(this.dom)
|
||||
}
|
||||
return bar
|
||||
},
|
||||
.appendTo(this.dom) }
|
||||
return bar },
|
||||
function(){ return Object.keys(this.config['status-bars']).concat(['none']) },
|
||||
// XXX check if we will be getting gid reliably...
|
||||
function(state, bar, gid){
|
||||
// do not do anything unless the status bar exists...
|
||||
if(bar.length == 0){
|
||||
return
|
||||
}
|
||||
return }
|
||||
var that = this
|
||||
this.config['status-bar'] = state
|
||||
|
||||
@ -564,8 +544,7 @@ var StatusBarActions = actions.Actions({
|
||||
var handler = elems[key] || base_elems[key]
|
||||
|
||||
if(handler == null){
|
||||
return
|
||||
}
|
||||
return }
|
||||
|
||||
// handle aliases...
|
||||
var seen = []
|
||||
@ -576,15 +555,13 @@ var StatusBarActions = actions.Actions({
|
||||
if(seen.indexOf(handler) >= 0){
|
||||
console.error('state indicator alias loop detected at:', key)
|
||||
handler = null
|
||||
break
|
||||
}
|
||||
}
|
||||
break } }
|
||||
|
||||
return handler
|
||||
}
|
||||
return handler }
|
||||
|
||||
// clear...
|
||||
if(state == 'none' || !bar.hasClass(state)){
|
||||
this.clearStatusBarCache()
|
||||
// notify items that they are removed...
|
||||
bar.children()
|
||||
.each(function(i, item){
|
||||
@ -592,25 +569,21 @@ var StatusBarActions = actions.Actions({
|
||||
var type = item.attr('type')
|
||||
|
||||
if(type == null){
|
||||
return
|
||||
}
|
||||
return }
|
||||
|
||||
var handler = _getHandler(type)
|
||||
|
||||
if(handler != null){
|
||||
handler.call(that, null)
|
||||
}
|
||||
handler.call(that, null) }
|
||||
})
|
||||
bar.empty()
|
||||
}
|
||||
bar.empty() }
|
||||
|
||||
if(state == 'none'){
|
||||
!('none' in this.config['status-bars'])
|
||||
// XXX this feels like a hack...
|
||||
&& setTimeout(function(){ this.toggleStatusBar(0) }.bind(this), 0)
|
||||
//return Object.keys(this.config['status-bars'])[0]
|
||||
return
|
||||
}
|
||||
return }
|
||||
|
||||
// build/update...
|
||||
gid = gid || this.current
|
||||
@ -642,11 +615,9 @@ var StatusBarActions = actions.Actions({
|
||||
item = (handler ?
|
||||
handler.call(that, item, gid, img)
|
||||
: $('<span>'))
|
||||
.attr('type', item)
|
||||
}
|
||||
.attr('type', item) }
|
||||
|
||||
bar.append(item)
|
||||
})
|
||||
bar.append(item) })
|
||||
|
||||
// update...
|
||||
} else {
|
||||
@ -656,17 +627,12 @@ var StatusBarActions = actions.Actions({
|
||||
var type = item.attr('type')
|
||||
|
||||
if(type == null){
|
||||
return
|
||||
}
|
||||
return }
|
||||
|
||||
var handler = _getHandler(type)
|
||||
|
||||
if(handler != null){
|
||||
handler.call(that, item, gid, img)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
handler.call(that, item, gid, img) } }) } },
|
||||
null)],
|
||||
updateStatusBar: ['- Interface/Update satus bar',
|
||||
'toggleStatusBar: "!"'],
|
||||
@ -675,8 +641,10 @@ var StatusBarActions = actions.Actions({
|
||||
function(){
|
||||
var mode = this.toggleStatusBar('?')
|
||||
this.toggleStatusBar('none')
|
||||
this.toggleStatusBar(mode)
|
||||
}],
|
||||
this.toggleStatusBar(mode) }],
|
||||
clearStatusBarCache: ['- Interface/Clear status bar cache',
|
||||
'clearCache: "*" "statusbar"'],
|
||||
|
||||
|
||||
// XXX should this blink the on state only???
|
||||
statusItemBlink: ['- Interface/',
|
||||
@ -685,8 +653,7 @@ var StatusBarActions = actions.Actions({
|
||||
NOTE: type is the same as in .__statusbar_elements__`,
|
||||
function(type){
|
||||
if(type == null){
|
||||
return
|
||||
}
|
||||
return }
|
||||
|
||||
var gid = this.current
|
||||
var item = this.dom.find(`.state-indicator-container.global-info [type=${type}]`)
|
||||
@ -695,42 +662,36 @@ var StatusBarActions = actions.Actions({
|
||||
item
|
||||
.removeClass('blink')
|
||||
.addClass('blink')
|
||||
.on('animationend', function(){ item.removeClass('blink') })
|
||||
}],
|
||||
.on('animationend', function(){ item.removeClass('blink') }) }],
|
||||
|
||||
// XXX should these be here???
|
||||
// XXX should this show a dialog???
|
||||
editStatusBarIndex: ['- Interface/Edit image focus position in statusbar',
|
||||
function(){
|
||||
if((this.config['status-bar-index'] || {} )['editable']){
|
||||
this.toggleStatusBar('?') == 'none' && this.toggleStatusBar()
|
||||
|
||||
this.toggleStatusBar('?') == 'none'
|
||||
&& this.toggleStatusBar()
|
||||
// XXX do this better...
|
||||
this.dom.find('.global-info .index .position').focus().click()
|
||||
}
|
||||
}],
|
||||
this.dom.find('.global-info .index .position').focus().click() } }],
|
||||
editStatusBarRibbon: ['- Interface/Edit ribbon focus position in statusbar',
|
||||
function(){
|
||||
this.toggleStatusBar('?') == 'none' && this.toggleStatusBar()
|
||||
|
||||
this.toggleStatusBar('?') == 'none'
|
||||
&& this.toggleStatusBar()
|
||||
// XXX do this better...
|
||||
this.dom.find('.global-info .ribbon-number').focus().click()
|
||||
}],
|
||||
this.dom.find('.global-info .ribbon-number').focus().click() }],
|
||||
toggleStatusBarIndexMode: ['Interface/Status bar index mode',
|
||||
toggler.CSSClassToggler(
|
||||
function(){
|
||||
return this.dom.find('.global-info .index') },
|
||||
['normal', 'loaded', 'global'],
|
||||
function(state){
|
||||
this.toggleStatusBar('?') == 'none' && this.toggleStatusBar()
|
||||
|
||||
this.toggleStatusBar('?') == 'none'
|
||||
&& this.toggleStatusBar()
|
||||
// prepare for saving the config...
|
||||
this.config['status-bar-index'] =
|
||||
JSON.parse(JSON.stringify(this.config['status-bar-index']))
|
||||
this.config['status-bar-index']['mode'] = state
|
||||
|
||||
this.updateStatusBar()
|
||||
})],
|
||||
this.updateStatusBar() })],
|
||||
|
||||
// XXX revise...
|
||||
showStatusBarInfo: ['- Interface/',
|
||||
@ -807,12 +768,10 @@ module.StatusBar = core.ImageGridFeatures.Feature({
|
||||
handlers: [
|
||||
['start',
|
||||
function(){
|
||||
this.toggleStatusBar(this.config['status-bar'])
|
||||
}],
|
||||
this.toggleStatusBar(this.config['status-bar']) }],
|
||||
['focusImage clear markChanged refresh',
|
||||
function(){
|
||||
this.updateStatusBar()
|
||||
}],
|
||||
this.updateStatusBar() }],
|
||||
[[
|
||||
'tag',
|
||||
'untag',
|
||||
@ -823,14 +782,12 @@ module.StatusBar = core.ImageGridFeatures.Feature({
|
||||
&& (gids.indexOf('current') >= 0
|
||||
|| gids.indexOf(this.current) >= 0)
|
||||
|| this.data.getImage(gids) == this.current){
|
||||
this.updateStatusBar()
|
||||
}
|
||||
}],
|
||||
this.updateStatusBar() } }],
|
||||
|
||||
['ribbonPanning.post',
|
||||
function(_, gid){
|
||||
gid == this.data.getRibbon() && this.updateStatusBar()
|
||||
}],
|
||||
gid == this.data.getRibbon()
|
||||
&& this.updateStatusBar() }],
|
||||
|
||||
// blink status mark indicators on toggle...
|
||||
['toggleMark',
|
||||
@ -853,13 +810,11 @@ module.StatusBar = core.ImageGridFeatures.Feature({
|
||||
],
|
||||
function(workspace){
|
||||
if(!workspace || workspace in this.workspaces){
|
||||
return
|
||||
}
|
||||
return }
|
||||
|
||||
this.config['status-bar'] =
|
||||
(this.config['status-bar-workspace-defaults'][workspace]
|
||||
|| this.config['status-bar'])
|
||||
}],
|
||||
|| this.config['status-bar']) }],
|
||||
['loadWorkspace',
|
||||
core.makeWorkspaceConfigLoader(
|
||||
function(){
|
||||
@ -871,9 +826,7 @@ module.StatusBar = core.ImageGridFeatures.Feature({
|
||||
} else {
|
||||
'status-bar' in workspace ?
|
||||
this.toggleStatusBar(workspace['status-bar'])
|
||||
: this.toggleStatusBar(this.config['status-bar'])
|
||||
}
|
||||
})],
|
||||
: this.toggleStatusBar(this.config['status-bar']) } })],
|
||||
],
|
||||
})
|
||||
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
|
||||
var sha1 = require('ext-lib/sha1')
|
||||
|
||||
var types = require('lib/types')
|
||||
var object = require('lib/object')
|
||||
|
||||
var tags = require('imagegrid/tags')
|
||||
@ -223,6 +224,7 @@ var DataPrototype = {
|
||||
ribbon_order: null,
|
||||
ribbons: null,
|
||||
|
||||
//__current: null,
|
||||
get current(){
|
||||
return this.__current = this.__current
|
||||
|| this.getImages(this.ribbon_order[0])[0]
|
||||
@ -230,6 +232,7 @@ var DataPrototype = {
|
||||
set current(value){
|
||||
this.focusImage(value) },
|
||||
|
||||
//__base: null,
|
||||
get base(){
|
||||
return this.__base || this.ribbon_order[0] },
|
||||
set base(value){
|
||||
@ -237,13 +240,18 @@ var DataPrototype = {
|
||||
this.getRibbon(value)
|
||||
: value },
|
||||
|
||||
// NOTE: experiments with wrapping data in Proxy yielded a
|
||||
// significant slowdown on edits...
|
||||
//__order: null,
|
||||
get order(){
|
||||
return this.__order },
|
||||
set order(value){
|
||||
delete this.__order_index
|
||||
this.__order = value },
|
||||
//__order_index: null,
|
||||
get order_index(){
|
||||
return this.__order_index = this.__order_index || this.order.toKeys() },
|
||||
return this.__order_index =
|
||||
this.__order_index || this.order.toKeys() },
|
||||
|
||||
|
||||
|
||||
@ -1027,16 +1035,16 @@ var DataPrototype = {
|
||||
// order.
|
||||
getImageOrder: function(context, target, mode, list){
|
||||
if(context == 'loaded' || context == 'global'){
|
||||
return this.getImages('loaded').indexOf(this.getImage(target, mode, list))
|
||||
return this.getImages('loaded').lastIndexOf(this.getImage(target, mode, list))
|
||||
|
||||
} else if(context == 'ribbon'){
|
||||
var gid = this.getImage(target, mode, list)
|
||||
return this.getImages(gid).indexOf(gid)
|
||||
return this.getImages(gid).lastIndexOf(gid)
|
||||
|
||||
} else if(context == 'all'){
|
||||
return this.order.indexOf(this.getImage(target, mode, list)) }
|
||||
return this.order.lastIndexOf(this.getImage(target, mode, list)) }
|
||||
|
||||
return this.order.indexOf(this.getImage(context, target, mode)) },
|
||||
return this.order.lastIndexOf(this.getImage(context, target, mode)) },
|
||||
|
||||
// Get a list of image gids...
|
||||
//
|
||||
@ -1183,7 +1191,6 @@ var DataPrototype = {
|
||||
|
||||
target = this.getImage(target)
|
||||
|| this.getImage(target, 'after')
|
||||
var i = list.indexOf(target)
|
||||
|
||||
// prepare to slice the list...
|
||||
if(mode == 'around' || mode == 'total'){
|
||||
@ -1204,6 +1211,10 @@ var DataPrototype = {
|
||||
|
||||
var res = [target]
|
||||
|
||||
// XXX can we avoid .indexOf(..) here???
|
||||
//var i = list.indexOf(target)
|
||||
//var i = list.index(target)
|
||||
var i = list.lastIndexOf(target)
|
||||
// pre...
|
||||
for(var n = i-1; n >= 0 && pre > 0; n--){
|
||||
// NOTE: list may be sparse so we skip the items that are not
|
||||
@ -1227,7 +1238,9 @@ var DataPrototype = {
|
||||
// in the post section...
|
||||
if(mode == 'total' && post > 0){
|
||||
var pad = count - res.length
|
||||
var i = list.indexOf(res[0])
|
||||
//var i = list.indexOf(res[0])
|
||||
//var i = list.index(res[0])
|
||||
var i = list.lastIndexOf(res[0])
|
||||
|
||||
res.reverse()
|
||||
for(var n = i-1; n >= 0 && pad > 0; n--){
|
||||
|
||||
8
Viewer/package-lock.json
generated
8
Viewer/package-lock.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ImageGrid.Viewer.g4",
|
||||
"version": "4.0.0a",
|
||||
"version": "4.0.0-a",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@ -1110,9 +1110,9 @@
|
||||
"integrity": "sha512-9kZM80Js9/eTwXN9VXwLDC1wDJ7gIAdYU9GIzb5KJmNcLAMaW+zhgFrwFFMrcSfggUuadgnqSrS41E4XLe8JZw=="
|
||||
},
|
||||
"ig-types": {
|
||||
"version": "5.0.18",
|
||||
"resolved": "https://registry.npmjs.org/ig-types/-/ig-types-5.0.18.tgz",
|
||||
"integrity": "sha512-8c16slG/J0qC9oYW1Mx6oSriEYKEY/HLs4SvgWDLqac/qx/nMaa6HlEUA/fi+whGxvTk03t4s/IKca+MKWV9oQ==",
|
||||
"version": "5.0.20",
|
||||
"resolved": "https://registry.npmjs.org/ig-types/-/ig-types-5.0.20.tgz",
|
||||
"integrity": "sha512-d2IEwY3ZDSWxn2PY0e7XxMzuOPWzeK/py0sBgqfoCNbKlc4IHEogFwoQIv0C4EZdcXL0cJOsCo74NwbetoSWiA==",
|
||||
"requires": {
|
||||
"ig-object": "^5.4.12",
|
||||
"object-run": "^1.0.1"
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
"ig-argv": "^2.15.0",
|
||||
"ig-features": "^3.4.2",
|
||||
"ig-object": "^5.4.12",
|
||||
"ig-types": "^5.0.18",
|
||||
"ig-types": "^5.0.20",
|
||||
"moment": "^2.29.1",
|
||||
"object-run": "^1.0.1",
|
||||
"requirejs": "^2.3.6",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user