mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-28 18:00:09 +00:00
preparing to move to new tags (data format 3.1)...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
9993323d5c
commit
2a99cd9889
@ -361,17 +361,17 @@ actions.Actions({
|
||||
|
||||
|
||||
This will collect JSON data from every available attribute supporting
|
||||
the .dumpJSON() method.
|
||||
Attributes starting with '__' will be ignored.
|
||||
the .json() method.
|
||||
Attributes starting with '_' will be ignored.
|
||||
|
||||
`,
|
||||
function(mode){
|
||||
return function(res){
|
||||
for(var k in this){
|
||||
if(!k.startsWith('__')
|
||||
if(!k.startsWith('_')
|
||||
&& this[k] != null
|
||||
&& this[k].dumpJSON != null){
|
||||
res[k] = this[k].dumpJSON()
|
||||
&& this[k].json != null){
|
||||
res[k] = this[k].json()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -588,7 +588,7 @@ actions.Actions({
|
||||
NOTE: this is .symmetrical to .nextImage(..) see it for docs.
|
||||
`,
|
||||
{browseMode: 'firstImage'},
|
||||
function(a){
|
||||
function(a, mode){
|
||||
// keep track of traverse direction...
|
||||
this.direction = 'left'
|
||||
|
||||
@ -598,6 +598,10 @@ actions.Actions({
|
||||
// go to the first image if it's closer than s...
|
||||
|| this.data.getImage('first'))
|
||||
|
||||
} else if(a instanceof Array && mode){
|
||||
mode = mode == 'ribbon' ? 'current' : mode
|
||||
this.focusImage('prev', this.data.getImages(a, mode))
|
||||
|
||||
} else {
|
||||
this.focusImage('prev', a)
|
||||
}
|
||||
@ -617,10 +621,17 @@ actions.Actions({
|
||||
Focus next image globally...
|
||||
.nextImage('global')
|
||||
|
||||
Focus next image in list...
|
||||
.nextImage(list)
|
||||
|
||||
Focus next image in list constrained to current ribbon...
|
||||
.nextImage(list, 'ribbon')
|
||||
.nextImage(list, <ribbon-gid>)
|
||||
|
||||
NOTE: this also modifies .direction
|
||||
`,
|
||||
{browseMode: 'lastImage'},
|
||||
function(a){
|
||||
function(a, mode){
|
||||
// keep track of traverse direction...
|
||||
this.direction = 'right'
|
||||
|
||||
@ -630,6 +641,10 @@ actions.Actions({
|
||||
// go to the first image if it's closer than s...
|
||||
|| this.data.getImage('last'))
|
||||
|
||||
} else if(a instanceof Array && mode){
|
||||
mode = mode == 'ribbon' ? 'current' : mode
|
||||
this.focusImage('next', this.data.getImages(a, mode))
|
||||
|
||||
} else {
|
||||
this.focusImage('next', a)
|
||||
}
|
||||
@ -1161,23 +1176,12 @@ var makeTagWalker =
|
||||
module.makeTagWalker =
|
||||
function(direction, dfl_tag){
|
||||
var meth = direction == 'next' ? 'nextImage' : 'prevImage'
|
||||
|
||||
return function(tag, mode){
|
||||
mode = mode == null ? 'all' : mode
|
||||
tag = tag || dfl_tag
|
||||
|
||||
// account for no tags or no images tagged...
|
||||
var lst = this.data.tags != null ? this.data.tags[tag] : []
|
||||
lst = lst || []
|
||||
|
||||
if(mode == 'ribbon'){
|
||||
this[meth](this.data.getImages(lst, 'current'))
|
||||
|
||||
} else {
|
||||
this[meth](lst)
|
||||
}
|
||||
}
|
||||
}
|
||||
this[meth](
|
||||
this.data.version >= '3.1' ?
|
||||
this.data.tags.values(tag || dfl_tag)
|
||||
: (this.data.tags || {})[tag || dfl_tag] || [],
|
||||
mode) } }
|
||||
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
@ -1550,12 +1554,12 @@ module.CropActions = actions.Actions({
|
||||
return function(res){
|
||||
if(this.cropped){
|
||||
if(mode == 'base'){
|
||||
res.data = this.crop_stack[0].dumpJSON()
|
||||
res.data = this.crop_stack[0].json()
|
||||
|
||||
} else if(mode == 'full'){
|
||||
res.crop_stack = this.crop_stack.map(function(c){
|
||||
return c
|
||||
.dumpJSON()
|
||||
.json()
|
||||
.run(function(){
|
||||
delete this.tags })
|
||||
})
|
||||
@ -1790,6 +1794,12 @@ module.CropActions = actions.Actions({
|
||||
}],
|
||||
|
||||
// XXX should this be here???
|
||||
/*
|
||||
cropTagged: ['- Tag|Crop/Crop tagged images',
|
||||
function(query, flatten){
|
||||
return this.crop(this.data.tagQuery(query), flatten) }],
|
||||
//*/
|
||||
//*
|
||||
cropTagged: ['- Tag|Crop/Crop tagged images',
|
||||
function(tags, mode, flatten){
|
||||
if(this.data.length == 0){
|
||||
@ -1798,6 +1808,7 @@ module.CropActions = actions.Actions({
|
||||
var selector = mode == 'any' ? 'getTaggedByAny' : 'getTaggedByAll'
|
||||
this.crop(this.data[selector](tags), flatten)
|
||||
}],
|
||||
//*/
|
||||
|
||||
|
||||
// crop edit actions...
|
||||
|
||||
@ -1195,7 +1195,7 @@ var CollectionActions = actions.Actions({
|
||||
res.data = (main.crop_stack ?
|
||||
(main.crop_stack[0] || main.data)
|
||||
: main.data)
|
||||
.dumpJSON()
|
||||
.json()
|
||||
|
||||
delete res.location.collection
|
||||
}
|
||||
@ -1225,7 +1225,7 @@ var CollectionActions = actions.Actions({
|
||||
(state.crop_stack[0] || state.data)
|
||||
: state.data)
|
||||
if(data){
|
||||
s.data = data.dumpJSON()
|
||||
s.data = data.json()
|
||||
s.count = data.length
|
||||
|
||||
} else if(state.count) {
|
||||
@ -1236,7 +1236,7 @@ var CollectionActions = actions.Actions({
|
||||
// NOTE: in base mode, crop_stack is ignored...
|
||||
if(mode != 'base' && state.crop_stack){
|
||||
s.crop_stack = state.crop_stack
|
||||
.map(function(d){ return d.dumpJSON() })
|
||||
.map(function(d){ return d.json() })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -21,7 +21,7 @@ var core = require('features/core')
|
||||
|
||||
var demo_data =
|
||||
module.demo_data = {
|
||||
varsion: '3.0',
|
||||
version: '3.0',
|
||||
|
||||
current: '3',
|
||||
base: 'r0',
|
||||
@ -76,7 +76,7 @@ module.demo_images = {
|
||||
//demo_data = data.Data(demo_data)
|
||||
// .tagsToImages(demo_images, 'merge')
|
||||
// .tagsFromImages(demo_images, 'merge')
|
||||
// .dumpJSON()
|
||||
// .json()
|
||||
|
||||
|
||||
|
||||
|
||||
@ -79,6 +79,7 @@ function makeTagTogglerAction(tag){
|
||||
return action == '??' ? ['off', 'on'] : 'off'
|
||||
|
||||
// special case: multiple targets and toggle action...
|
||||
// XXX do we need this???
|
||||
} else if((target == 'all' || target == 'loaded' || target == 'ribbon'
|
||||
|| target instanceof Array)
|
||||
&& (action == null || action == 'next' || action == 'prev'
|
||||
@ -229,12 +230,13 @@ var ImageMarkActions = actions.Actions({
|
||||
// chunk of memory...
|
||||
get marked(){
|
||||
if(this.data == null
|
||||
|| this.data.tags == null
|
||||
|| !('marked' in this.data.tags)){
|
||||
|| this.data.tags == null){
|
||||
return []
|
||||
}
|
||||
//return this.data.tags['marked'].slice()
|
||||
return this.data.getImages(this.data.tags['marked'])
|
||||
// XXX remove the version test here....
|
||||
return this.data.version >= '3.1' ?
|
||||
this.data.tagQuery('marked')
|
||||
: this.data.getImages((this.data.tags || {marked:[]})['marked'])
|
||||
},
|
||||
|
||||
markedInRibbon: ['- Mark|Ribbon/',
|
||||
@ -508,12 +510,14 @@ var ImageBookmarkActions = actions.Actions({
|
||||
// chunk of memory...
|
||||
get bookmarked(){
|
||||
if(this.data == null
|
||||
|| this.data.tags == null
|
||||
|| !('bookmark' in this.data.tags)){
|
||||
|| this.data.tags == null){
|
||||
return []
|
||||
}
|
||||
//return this.data.tags['bookmark'].slice()
|
||||
return this.data.getImages(this.data.tags['bookmark'])
|
||||
// XXX remove the version test here....
|
||||
return this.data.version >= '3.1' ?
|
||||
this.data.tagQuery('bookmark')
|
||||
: this.data.getImages((this.data.tags || {bookmark:[]})['bookmark'])
|
||||
},
|
||||
|
||||
prevBookmarked: ['Bookmark|Navigate/Previous bookmarked image',
|
||||
|
||||
@ -11,7 +11,6 @@
|
||||
(function(require){ var module={} // make module AMD/node compatible...
|
||||
/*********************************************************************/
|
||||
|
||||
|
||||
var sha1 = require('ext-lib/sha1')
|
||||
|
||||
var object = require('lib/object')
|
||||
@ -20,9 +19,21 @@ var tags = require('imagegrid/tags')
|
||||
var formats = require('imagegrid/formats')
|
||||
|
||||
|
||||
|
||||
/*********************************************************************/
|
||||
|
||||
// NOTE: this actively indicates the format used, changing this will
|
||||
// affect the loading of serialized data, do not change unless you
|
||||
// know what you are doing.
|
||||
// ...this is done to gradually migrate to new format versions with
|
||||
// minimal changes.
|
||||
var DATA_VERSION =
|
||||
// XXX 3.1 not ready for production yet...
|
||||
//module.DATA_VERSION = '3.1'
|
||||
module.DATA_VERSION = '3.0'
|
||||
|
||||
|
||||
|
||||
/*********************************************************************/
|
||||
//
|
||||
// General format info...
|
||||
@ -46,6 +57,20 @@ module.DATA_VERSION = '3.0'
|
||||
//
|
||||
//
|
||||
// Data format change history:
|
||||
// 3.1 - Moved to the new tag implementation -- changed the tag JSON
|
||||
// format:
|
||||
// {
|
||||
// aliases: {
|
||||
// <alias>: <tag>,
|
||||
// },
|
||||
// persistent: [<tag>, ...],
|
||||
// tags: {
|
||||
// <tag>: [<gid>, ...],
|
||||
// ...
|
||||
// }
|
||||
// }
|
||||
// (see: tags.js for more info)
|
||||
// (still in development)
|
||||
// 3.0 - Gen4 DATA format, introduced several backwards incompatible
|
||||
// changes:
|
||||
// - added ribbon GIDs, .ribbons now is a gid indexed object
|
||||
@ -129,8 +154,8 @@ var DataClassPrototype = {
|
||||
},
|
||||
// XXX is this the right way to construct data???
|
||||
fromJSON: function(data){
|
||||
//return new Data().loadJSON(data)
|
||||
return new this().loadJSON(data)
|
||||
//return new Data().load(data)
|
||||
return new this().load(data)
|
||||
},
|
||||
}
|
||||
|
||||
@ -142,6 +167,10 @@ var DataClassPrototype = {
|
||||
//
|
||||
var DataPrototype = {
|
||||
|
||||
get version(){
|
||||
return DATA_VERSION },
|
||||
|
||||
|
||||
/*****************************************************************/
|
||||
//
|
||||
// Base Terminology:
|
||||
@ -2769,7 +2798,8 @@ var DataPrototype = {
|
||||
// Clone/copy the data object...
|
||||
//
|
||||
clone: function(){
|
||||
var res = new Data()
|
||||
//var res = new Data()
|
||||
var res = new this.constructor()
|
||||
res.base = this.base
|
||||
res.current = this.current
|
||||
res.order = this.order.slice()
|
||||
@ -2806,10 +2836,10 @@ var DataPrototype = {
|
||||
//
|
||||
// NOTE: this loads in-place, use .fromJSON(..) to create new data...
|
||||
// XXX should this process defaults for unset values???
|
||||
loadJSON: function(data, clean){
|
||||
load: function(data, clean){
|
||||
var that = this
|
||||
data = typeof(data) == typeof('str') ? JSON.parse(data) : data
|
||||
data = formats.updateData(data)
|
||||
data = formats.updateData(data, DATA_VERSION)
|
||||
this.base = data.base
|
||||
this.order = data.order.slice()
|
||||
this.ribbon_order = data.ribbon_order.slice()
|
||||
@ -2842,11 +2872,9 @@ var DataPrototype = {
|
||||
|
||||
// Generate JSON from data...
|
||||
//
|
||||
// NOTE: if mode is either 'str' or 'string' then this will stringify
|
||||
// the result...
|
||||
dumpJSON: function(mode){
|
||||
json: function(){
|
||||
var res = {
|
||||
version: module.DATA_VERSION,
|
||||
version: DATA_VERSION,
|
||||
base: this.base,
|
||||
current: this.current,
|
||||
order: this.order.slice(),
|
||||
@ -2860,9 +2888,6 @@ var DataPrototype = {
|
||||
}
|
||||
res[s][k] = lst.compact()
|
||||
})
|
||||
if(mode == 'string' || mode == 'str'){
|
||||
res = JSON.stringify(res)
|
||||
}
|
||||
return res
|
||||
},
|
||||
|
||||
@ -2873,7 +2898,7 @@ var DataPrototype = {
|
||||
__init__: function(json){
|
||||
// load initial state...
|
||||
if(json != null){
|
||||
this.loadJSON(json)
|
||||
this.load(json)
|
||||
|
||||
} else {
|
||||
this._reset()
|
||||
@ -2886,6 +2911,7 @@ var DataPrototype = {
|
||||
|
||||
/*********************************************************************/
|
||||
|
||||
// XXX should this handle .split(..) / .join(..)
|
||||
var DataWithTagsPrototype = {
|
||||
__proto__: DataPrototype,
|
||||
|
||||
@ -3288,7 +3314,10 @@ var DataWithTags2Prototype = {
|
||||
|
||||
get tags(){
|
||||
return (this.__tags = this.__tags || new tags.Tags()) },
|
||||
set tags(value){
|
||||
this.__tags = value },
|
||||
|
||||
// XXX do we need these???
|
||||
hasTag: function(gid, ...tags){
|
||||
return this.tags.tags(this.getImage(gid), ...tags) },
|
||||
getTags: function(gids){
|
||||
@ -3309,29 +3338,37 @@ var DataWithTags2Prototype = {
|
||||
tag: function(tags, gids){
|
||||
var that = this
|
||||
gids = gids == null || gids == 'current' ? this.getImage() : gids
|
||||
gids = gids instanceof Array ? gids : [gids]
|
||||
|
||||
gids
|
||||
;(gids instanceof Array ? gids : [gids])
|
||||
.forEach(function(gid){
|
||||
this.tags.tag(tags, gid) })
|
||||
that.tags.tag(tags, gid) })
|
||||
|
||||
return this
|
||||
},
|
||||
untag: function(tags, gids){
|
||||
var that = this
|
||||
gids = gids == null || gids == 'current' ? this.getImage() : gids
|
||||
gids = gids instanceof Array ? gids : [gids]
|
||||
|
||||
gids
|
||||
;(gids instanceof Array ? gids : [gids])
|
||||
.forEach(function(gid){
|
||||
this.tags.untag(tags, gid) })
|
||||
that.tags.untag(tags, gid) })
|
||||
|
||||
return this
|
||||
},
|
||||
// XXX should all togglers return true/false or 'on'/'off'???
|
||||
toggleTag: function(tag, gids, action){
|
||||
gids = gids == null || gids == 'current' ? this.getImage() : gids
|
||||
|
||||
// XXX
|
||||
toggleTag: function(){
|
||||
// XXX
|
||||
var res = this.tags.toggleTag(tag, gids, action)
|
||||
|
||||
return res === this.tags ?
|
||||
this
|
||||
: res === true ?
|
||||
'on'
|
||||
: res === false ?
|
||||
'off'
|
||||
: res
|
||||
.map(function(r){ return r ? 'on' : 'off' })
|
||||
},
|
||||
|
||||
// XXX should these be .tags.query(..) ???
|
||||
@ -3340,8 +3377,10 @@ var DataWithTags2Prototype = {
|
||||
|
||||
// Utils...
|
||||
// XXX
|
||||
tagsFromImages: function(){},
|
||||
tagsToImages: function(){},
|
||||
tagsFromImages: function(){
|
||||
throw Error('.tagsFromImages(..): Not implemented.') },
|
||||
tagsToImages: function(){
|
||||
throw Error('.tagsToImages(..): Not implemented.') },
|
||||
|
||||
|
||||
// XXX compatibility...
|
||||
@ -3358,22 +3397,49 @@ var DataWithTags2Prototype = {
|
||||
: this.getImages(res) },
|
||||
|
||||
|
||||
// NOTE: this is here only to make the tags mutable...
|
||||
// Extended methods...
|
||||
//
|
||||
// special case: 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
|
||||
}
|
||||
|
||||
crop.tags = this.tags
|
||||
return crop
|
||||
},
|
||||
|
||||
|
||||
// XXX serialization...
|
||||
|
||||
// XXX init...
|
||||
// XXX
|
||||
join: function(){
|
||||
var res = DataWithTags2Prototype.__proto__.join.apply(this, arguments)
|
||||
// XXX
|
||||
throw Error('.join(..): Not implemented.')
|
||||
return res
|
||||
},
|
||||
// XXX
|
||||
split: function(){
|
||||
var res = DataWithTags2Prototype.__proto__.split.apply(this, arguments)
|
||||
// XXX
|
||||
throw Error('.split(..): Not implemented.')
|
||||
return res
|
||||
},
|
||||
clone: function(){
|
||||
var res = DataWithTags2Prototype.__proto__.clone.apply(this, arguments)
|
||||
res.tags = this.tags.clone()
|
||||
return res
|
||||
},
|
||||
_reset: function(){
|
||||
var res = DataWithTags2Prototype.__proto__._reset.apply(this, arguments)
|
||||
delete this.__tags
|
||||
return res
|
||||
},
|
||||
json: function(){
|
||||
var json = DataWithTags2Prototype.__proto__.json.apply(this, arguments)
|
||||
json.tags = this.tags.json()
|
||||
return json
|
||||
},
|
||||
load: function(data, clean){
|
||||
var res = DataWithTags2Prototype.__proto__.load.apply(this, arguments)
|
||||
data.tags
|
||||
&& res.tags.load(data.tags)
|
||||
return res
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@ -3408,7 +3474,10 @@ var DataWithTags =
|
||||
module.DataWithTags =
|
||||
object.makeConstructor('DataWithTags',
|
||||
DataClassPrototype,
|
||||
DataWithTagsPrototype)
|
||||
// XXX remove the version test here....
|
||||
DATA_VERSION >= '3.1' ?
|
||||
DataWithTags2Prototype
|
||||
: DataWithTagsPrototype)
|
||||
|
||||
|
||||
var Data =
|
||||
|
||||
@ -42,6 +42,7 @@ function(data){
|
||||
module.VERSIONS['2.0'] =
|
||||
function(data, cmp){
|
||||
//data = data.version < '2.0' ? module.VERSIONS['2.0'](data) : data
|
||||
console.log('Updating data to: ', '2.0')
|
||||
|
||||
var res = {
|
||||
data: {
|
||||
@ -102,11 +103,14 @@ function(data){
|
||||
|
||||
var res = {}
|
||||
res.version = '3.0'
|
||||
console.log('Updating data to: ', res.version)
|
||||
|
||||
res.current = data.current
|
||||
res.order = data.order.slice()
|
||||
res.ribbon_order = data.ribbon_order == null ? [] : data.ribbon_order.slice()
|
||||
res.ribbons = {}
|
||||
|
||||
|
||||
// generate gids...
|
||||
// NOTE: this will use the structures stored in data if available,
|
||||
// otherwise new structures will be generated...
|
||||
@ -128,13 +132,26 @@ function(data){
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* XXX template...
|
||||
module.VERSIONS['3.1'] =
|
||||
function(data){
|
||||
var res = data.version < '3.0' ? module.VERSIONS['3.0'](data) : data
|
||||
|
||||
res.version = '3.1'
|
||||
console.log('Updating data to: ', res.version)
|
||||
|
||||
data.tags
|
||||
&& (res.tags = { tags: data.tags })
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
|
||||
/* XXX template...
|
||||
module.VERSIONS['3.2'] =
|
||||
function(data){
|
||||
var res = data.version < '3.1' ? module.VERSIONS['3.1'](data) : data
|
||||
|
||||
res.version = '3.2'
|
||||
|
||||
// XXX
|
||||
|
||||
@ -165,8 +182,8 @@ module.getLatestUpdaterVersion = function(){
|
||||
// format.
|
||||
// NOTE: if data is already in the latest format this will return it
|
||||
// as-is.
|
||||
module.updateData = function(data, clean){
|
||||
var v = module.getLatestUpdaterVersion()
|
||||
module.updateData = function(data, version, clean){
|
||||
var v = version || module.getLatestUpdaterVersion()
|
||||
var res = data.version < v
|
||||
? module.VERSIONS[v](data)
|
||||
: completeData(data)
|
||||
|
||||
@ -344,7 +344,7 @@ module.ImagesClassPrototype = {
|
||||
return images
|
||||
},
|
||||
fromJSON: function(data){
|
||||
return new this().loadJSON(data)
|
||||
return new this().load(data)
|
||||
},
|
||||
}
|
||||
|
||||
@ -689,7 +689,7 @@ module.ImagesPrototype = {
|
||||
|
||||
|
||||
clone: function(){
|
||||
return (new Images()).loadJSON(this.dumpJSON()) },
|
||||
return (new Images()).load(this.json()) },
|
||||
// NOTE: this will join the other data into the current object in-place,
|
||||
// use .clone() to preserve current data...
|
||||
join: function(other){
|
||||
@ -703,7 +703,7 @@ module.ImagesPrototype = {
|
||||
},
|
||||
|
||||
// serialization...
|
||||
loadJSON: function(data){
|
||||
load: function(data){
|
||||
data = typeof(data) == typeof('str')
|
||||
? JSON.parse(data)
|
||||
: JSON.parse(JSON.stringify(data))
|
||||
@ -727,7 +727,7 @@ module.ImagesPrototype = {
|
||||
},
|
||||
// XXX this is really odd: renaming this to 'toJSON' breaks JavaScript
|
||||
// making chrome/node just say: "<error>" and a filename...
|
||||
dumpJSON: function(data){
|
||||
json: function(data){
|
||||
var res = JSON.parse(JSON.stringify(this))
|
||||
// XXX
|
||||
res.version = '3.0'
|
||||
@ -742,7 +742,7 @@ module.ImagesPrototype = {
|
||||
__init__: function(json){
|
||||
// load initial state...
|
||||
if(json != null){
|
||||
this.loadJSON(json)
|
||||
this.load(json)
|
||||
} else {
|
||||
this._reset()
|
||||
}
|
||||
|
||||
@ -628,7 +628,7 @@ var TagsPrototype = {
|
||||
return that.tags(v, tag) ?
|
||||
(that.untag(tag, v), false)
|
||||
// NOTE: we set only if we are not a pattern...
|
||||
: (pattern ?
|
||||
: (!pattern ?
|
||||
(that.tag(tag, v), true)
|
||||
: null) }) },
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user