mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 02:10:08 +00:00
lots of minor chnages, fixes and cleanup + refactoring...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
76cb68a725
commit
267d5f705b
@ -258,6 +258,14 @@ body {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
/* Collection list */
|
||||
.browse-widget.collection-list .list .item .text[cropped]:after {
|
||||
content: "(cropped)";
|
||||
margin-left: 5px;
|
||||
opacity: 0.5;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
|
||||
/* External Editor List */
|
||||
.browse-widget.editor-list .list .item:first-child .text:after {
|
||||
|
||||
@ -1112,6 +1112,9 @@ module.TagsEditActions = actions.Actions({
|
||||
gids = gids.constructor !== Array ? [gids] : gids
|
||||
tags = tags.constructor !== Array ? [tags] : tags
|
||||
|
||||
var that = this
|
||||
gids = gids.map(function(gid){ return that.data.getImage(gid) })
|
||||
|
||||
// data...
|
||||
this.data.tag(tags, gids)
|
||||
|
||||
@ -1190,7 +1193,9 @@ module.TagsEditActions = actions.Actions({
|
||||
|
||||
source = source || 'both'
|
||||
mode = mode || 'merge'
|
||||
images = this.images
|
||||
|
||||
var images = this.images
|
||||
|
||||
if(typeof(source) != typeof('str')){
|
||||
images = source
|
||||
source = 'images'
|
||||
@ -1415,16 +1420,6 @@ module.CropActions = actions.Actions({
|
||||
|
||||
crop_stack: null,
|
||||
|
||||
// load the crop stack if present...
|
||||
load: [function(data){
|
||||
return function(){
|
||||
if(data.crop_stack){
|
||||
this.crop_stack = data.crop_stack.map(function(j){
|
||||
return data.Data(j)
|
||||
})
|
||||
}
|
||||
}
|
||||
}],
|
||||
clear: [function(){
|
||||
delete this.crop_stack }],
|
||||
|
||||
@ -1458,17 +1453,29 @@ module.CropActions = actions.Actions({
|
||||
}
|
||||
}
|
||||
}],
|
||||
// load the crop stack if present...
|
||||
load: [function(state){
|
||||
return function(){
|
||||
var that = this
|
||||
|
||||
if(!('crop_stack' in state)){
|
||||
return
|
||||
}
|
||||
|
||||
// load...
|
||||
if(state.crop_stack){
|
||||
that.crop_stack = (state.crop_stack || [])
|
||||
this.crop_stack = state.crop_stack
|
||||
.map(function(d){
|
||||
return d instanceof data.Data ? d : data.Data(d) })
|
||||
return d instanceof data.Data ?
|
||||
d
|
||||
: data.Data(d) })
|
||||
|
||||
// merge the tags...
|
||||
that.crop_stack.forEach(function(d){ d.tags = that.data.tags })
|
||||
this.crop_stack.forEach(function(d){ d.tags = that.data.tags })
|
||||
|
||||
// remove...
|
||||
} else {
|
||||
delete this.crop_stack
|
||||
}
|
||||
}
|
||||
}],
|
||||
|
||||
@ -26,7 +26,7 @@ var widgets = require('features/ui-widgets')
|
||||
// logical, would simplify control, etc.
|
||||
//
|
||||
|
||||
var MAIN_COLLECTION_TITLE = 'All'
|
||||
var MAIN_COLLECTION_TITLE = 'ALL'
|
||||
|
||||
// XXX things we need to do to collections:
|
||||
// - auto-collections
|
||||
@ -101,19 +101,30 @@ var CollectionActions = actions.Actions({
|
||||
.unique()
|
||||
.reverse()
|
||||
|
||||
// keep MAIN_COLLECTION_TITLE out of the collection order...
|
||||
var m = res.indexOf(MAIN_COLLECTION_TITLE)
|
||||
m >= 0
|
||||
&& res.splice(m, 1)
|
||||
|
||||
// remove stuff not present...
|
||||
if(res.length > keys.length){
|
||||
res = res.filter(function(e){ return e in collections })
|
||||
}
|
||||
|
||||
this.__collection_order.splice.apply(this.__collection_order,
|
||||
[0, this.__collection_order.length].concat(res))
|
||||
this.__collection_order.splice(0, this.__collection_order.length, ...res)
|
||||
|
||||
return this.__collection_order
|
||||
},
|
||||
set collection_order(value){
|
||||
this.__collection_order = value },
|
||||
|
||||
get collections_length(){
|
||||
var c = (this.collections || {})
|
||||
return MAIN_COLLECTION_TITLE in c ?
|
||||
Object.keys(c).length - 1
|
||||
: Object.keys(c).length
|
||||
},
|
||||
|
||||
// Format:
|
||||
// {
|
||||
// // NOTE: this is always the first handler...
|
||||
@ -207,6 +218,7 @@ var CollectionActions = actions.Actions({
|
||||
var handlers = this.collection_handlers
|
||||
|
||||
// save current collection state...
|
||||
//
|
||||
// main view -> save it...
|
||||
if(this.collection == null){
|
||||
var main = this.collections[MAIN_COLLECTION_TITLE] = {
|
||||
@ -223,12 +235,11 @@ var CollectionActions = actions.Actions({
|
||||
//this.saveCollection(this.collection, 'crop')
|
||||
main.data = this.data
|
||||
main.crop_stack = this.crop_stack
|
||||
&& this.crop_stack.slice()
|
||||
}
|
||||
|
||||
} else if(crop_mode == 'all'){
|
||||
this.saveCollection(this.collection, 'crop')
|
||||
//this.collections[this.collection].data = this.data
|
||||
//this.collections[this.collection].crop_stack = this.crop_stack
|
||||
}
|
||||
|
||||
// load collection...
|
||||
@ -257,15 +268,21 @@ var CollectionActions = actions.Actions({
|
||||
// data needs to be updated as collections
|
||||
// may contain different numbers/orders of
|
||||
// images...
|
||||
data.updateImagePositions()
|
||||
// XXX
|
||||
//data.updateImagePositions()
|
||||
data.sortTags()
|
||||
|
||||
that.load({
|
||||
data: data,
|
||||
|
||||
crop_stack: collection_data.crop_stack,
|
||||
crop_stack: collection_data.crop_stack
|
||||
&& collection_data.crop_stack.slice(),
|
||||
|
||||
collections: that.collections,
|
||||
collection_order: that.collection_order,
|
||||
// NOTE: we do not need to pass collections
|
||||
// and order here as they stay in from
|
||||
// the last .load(..) in merge mode...
|
||||
//collections: that.collections,
|
||||
//collection_order: that.collection_order,
|
||||
}, true)
|
||||
|
||||
// maintain the .collection state...
|
||||
@ -375,15 +392,15 @@ var CollectionActions = actions.Actions({
|
||||
: mode == 'crop' ?
|
||||
this.data.clone()
|
||||
: this.data.clone()
|
||||
.removeUnloadedGIDs())
|
||||
.run(function(){
|
||||
this.collection = collection
|
||||
|
||||
// NOTE: we are doing this manually after .removeUnloadedGIDs(..)
|
||||
// as the later will mess-up the structures
|
||||
// inherited from the main .data, namely tags...
|
||||
//this.tags = that.data.tags
|
||||
}),
|
||||
// optimization:
|
||||
// avoid processing .tags as we'll
|
||||
// overwrite them anyway later...
|
||||
delete this.tags
|
||||
})
|
||||
.removeUnloadedGIDs()),
|
||||
}
|
||||
|
||||
if(mode == 'crop' && this.crop_stack && depth != 0){
|
||||
@ -410,10 +427,11 @@ var CollectionActions = actions.Actions({
|
||||
var that = this
|
||||
gid = this.data.getImage(gid)
|
||||
//return Object.keys(this.collections || {})
|
||||
return this.collection_order
|
||||
return (this.collection_order || [])
|
||||
.filter(function(c){
|
||||
return !gid
|
||||
|| that.collections[c].data.getImage(gid) })
|
||||
return c != MAIN_COLLECTION_TITLE
|
||||
&& (!gid
|
||||
|| that.collections[c].data.getImage(gid)) })
|
||||
}],
|
||||
|
||||
collect: ['- Collections/',
|
||||
@ -484,6 +502,7 @@ var CollectionActions = actions.Actions({
|
||||
this.saveCollection(collection)
|
||||
}
|
||||
}],
|
||||
// XXX BUG: .uncollect(..) from crop messes up global tags...
|
||||
uncollect: ['Collections|Image/$Uncollect image',
|
||||
{browseMode: function(){ return !this.collection && 'disabled' }},
|
||||
function(gids, collection){
|
||||
@ -505,31 +524,30 @@ var CollectionActions = actions.Actions({
|
||||
: [that.data.getImage(gid)] })
|
||||
.reduce(function(a, b){ return a.concat(b) }, [])
|
||||
|
||||
/*/ NOTE: we are not using .data.updateImagePositions(gids, 'hide')
|
||||
// here because it will remove the gids from everything
|
||||
// while we need them removed only from ribbons...
|
||||
var hideGIDs = function(){
|
||||
var d = this
|
||||
gids.forEach(function(gid){
|
||||
var i = d.order.indexOf(gid)
|
||||
Object.keys(d.ribbons).forEach(function(r){
|
||||
delete d.ribbons[r][i]
|
||||
})
|
||||
})
|
||||
}
|
||||
//*/
|
||||
|
||||
if(this.collection == collection){
|
||||
// need to keep this from updating .tags...
|
||||
// XXX this seems a bit hacky...
|
||||
var tags = this.data.tags
|
||||
delete this.data.tags
|
||||
|
||||
this.data
|
||||
//.run(hideGIDs)
|
||||
.removeGIDs(gids)
|
||||
.removeEmptyRibbons()
|
||||
.run(function(){
|
||||
this.tags = tags
|
||||
this.sortTags()
|
||||
})
|
||||
}
|
||||
|
||||
// NOTE: we do both this and the above iff data is cloned...
|
||||
// NOTE: if tags are saved to the collection it means that
|
||||
// those tags are local to the collection and we do not
|
||||
// need to protect them...
|
||||
if(this.data !== this.collections[collection].data){
|
||||
this.collections[collection].data
|
||||
.removeGIDs(gids)
|
||||
.removeEmptyRibbons()
|
||||
}
|
||||
|
||||
this.collections[collection].data
|
||||
//.run(hideGIDs)
|
||||
.removeGIDs(gids)
|
||||
.removeEmptyRibbons()
|
||||
}],
|
||||
|
||||
|
||||
@ -541,6 +559,7 @@ var CollectionActions = actions.Actions({
|
||||
// their data on load as needed.
|
||||
load: [function(json){
|
||||
var that = this
|
||||
|
||||
var collections = {}
|
||||
var c = json.collections || {}
|
||||
var order = json.collection_order || Object.keys(c)
|
||||
@ -550,6 +569,7 @@ var CollectionActions = actions.Actions({
|
||||
}
|
||||
|
||||
Object.keys(c).forEach(function(title){
|
||||
// load data...
|
||||
var d = c[title].data instanceof data.Data ?
|
||||
c[title].data
|
||||
: data.Data
|
||||
@ -564,6 +584,18 @@ var CollectionActions = actions.Actions({
|
||||
data: d,
|
||||
}
|
||||
|
||||
// NOTE: this can be done lazily when loading each collection
|
||||
// but doing so will make the system more complex and
|
||||
// confuse (or complicate) some code that expects
|
||||
// .collections[*].crop_stack[*] to be instances of Data.
|
||||
if(c[title].crop_stack){
|
||||
state.crop_stack = c[title].crop_stack
|
||||
.map(function(c){
|
||||
return c instanceof data.Data ?
|
||||
c
|
||||
: data.Data(c) })
|
||||
}
|
||||
|
||||
// copy the rest of collection data as-is...
|
||||
Object.keys(c[title])
|
||||
.forEach(function(key){
|
||||
@ -761,6 +793,10 @@ module.Collection = core.ImageGridFeatures.Feature({
|
||||
// XXX show collections in image metadata...
|
||||
var UICollectionActions = actions.Actions({
|
||||
browseCollections: ['Collections|Crop/$Collec$tions...',
|
||||
core.doc`Collection list...
|
||||
|
||||
NOTE: collections are added live and not on dialog close...
|
||||
`,
|
||||
widgets.makeUIDialog(function(action){
|
||||
var that = this
|
||||
var to_remove = []
|
||||
@ -774,34 +810,66 @@ var UICollectionActions = actions.Actions({
|
||||
.addClass('highlighted')
|
||||
})
|
||||
|
||||
//var collections = Object.keys(that.collections || {})
|
||||
var collections = that.collection_order = that.collection_order || []
|
||||
|
||||
make.EditableList(collections,
|
||||
{
|
||||
unique: true,
|
||||
sortable: 'y',
|
||||
to_remove: to_remove,
|
||||
itemopen: function(title){
|
||||
var openHandler = function(_, title){
|
||||
var gid = that.current
|
||||
action ?
|
||||
action.call(that, title)
|
||||
: that.loadCollection(title)
|
||||
that.focusImage(gid)
|
||||
dialog.close()
|
||||
}
|
||||
var setCroppedState = function(title){
|
||||
// indicate collection crop...
|
||||
var cs =
|
||||
title == (that.collection || MAIN_COLLECTION_TITLE) ?
|
||||
that.crop_stack
|
||||
: (that.collections || {})[title] ?
|
||||
that.collections[title].crop_stack
|
||||
: null
|
||||
cs
|
||||
&& this.find('.text').last()
|
||||
.attr('cropped', cs.length)
|
||||
}
|
||||
|
||||
//var collections = Object.keys(that.collections || {})
|
||||
var collections = that.collection_order = that.collection_order || []
|
||||
|
||||
// main collection...
|
||||
!action && collections.indexOf(MAIN_COLLECTION_TITLE) < 0
|
||||
&& make([
|
||||
MAIN_COLLECTION_TITLE,
|
||||
],
|
||||
{ events: {
|
||||
update: function(_, title){
|
||||
// make this look almost like a list element...
|
||||
// XXX hack???
|
||||
$(this).find('.text:first-child')
|
||||
.before($('<span>')
|
||||
.css('color', 'transparent')
|
||||
.addClass('sort-handle')
|
||||
.html('☰'))
|
||||
setCroppedState
|
||||
.call($(this), title)
|
||||
},
|
||||
open: openHandler,
|
||||
}})
|
||||
|
||||
// collection list...
|
||||
make.EditableList(collections,
|
||||
{
|
||||
unique: true,
|
||||
sortable: 'y',
|
||||
to_remove: to_remove,
|
||||
|
||||
itemopen: openHandler,
|
||||
|
||||
normalize: function(title){
|
||||
return title.trim() },
|
||||
check: function(title){
|
||||
return title.length > 0 },
|
||||
|
||||
// remove the 'x' button from main collection...
|
||||
// XXX is this the correct way to go???
|
||||
each: function(title){
|
||||
title == MAIN_COLLECTION_TITLE
|
||||
&& this.find('.button-container').remove() },
|
||||
each: setCroppedState,
|
||||
|
||||
// XXX should this be "on close"???
|
||||
itemadded: function(title){
|
||||
action ?
|
||||
that.newCollection(title)
|
||||
@ -810,6 +878,7 @@ var UICollectionActions = actions.Actions({
|
||||
disabled: action ? [MAIN_COLLECTION_TITLE] : false,
|
||||
})
|
||||
}, {
|
||||
cls: 'collection-list',
|
||||
// focus current collection...
|
||||
selected: that.collection || MAIN_COLLECTION_TITLE,
|
||||
})
|
||||
@ -869,7 +938,7 @@ var UICollectionActions = actions.Actions({
|
||||
dialog.update()
|
||||
},
|
||||
})
|
||||
: make.Empty()
|
||||
: make.Empty('No collections...')
|
||||
})
|
||||
.close(function(){
|
||||
all.forEach(function(title){
|
||||
|
||||
@ -56,6 +56,10 @@ var demo_images =
|
||||
module.demo_images = {
|
||||
a: {
|
||||
orientation: 90,
|
||||
tags: ['test'],
|
||||
},
|
||||
d: {
|
||||
tags: ['test', 'bookmark']
|
||||
},
|
||||
f: {
|
||||
orientation: 270,
|
||||
@ -68,6 +72,13 @@ module.demo_images = {
|
||||
},
|
||||
}
|
||||
|
||||
// sync tags with images...
|
||||
//demo_data = data.Data(demo_data)
|
||||
// .tagsToImages(demo_images, 'merge')
|
||||
// .tagsFromImages(demo_images, 'merge')
|
||||
// .dumpJSON()
|
||||
|
||||
|
||||
|
||||
/*********************************************************************/
|
||||
|
||||
|
||||
@ -138,7 +138,7 @@ module.GLOBAL_KEYBOARD = {
|
||||
'Collection': {
|
||||
pattern: '.collection-mode',
|
||||
|
||||
Esc: 'loadCollection: "All" -- Load all images',
|
||||
Esc: 'loadCollection: "ALL" -- Load all images',
|
||||
},
|
||||
|
||||
'Range': {
|
||||
|
||||
@ -567,6 +567,7 @@ core.ImageGridFeatures.Feature({
|
||||
'reverseImages',
|
||||
'reverseRibbons',
|
||||
'cropGroup',
|
||||
'syncTags',
|
||||
],
|
||||
function(target){ return this.reload() }],
|
||||
],
|
||||
|
||||
@ -1846,8 +1846,14 @@ module.Buttons = core.ImageGridFeatures.Feature({
|
||||
}],
|
||||
|
||||
// update crop button status...
|
||||
['load clear reload',
|
||||
[[
|
||||
'load',
|
||||
'clear',
|
||||
'reload',
|
||||
],
|
||||
function(){
|
||||
var l = (this.crop_stack || []).length
|
||||
|
||||
$('.main-buttons.buttons .crop.button sub')
|
||||
// XXX should this be here or in CSS???
|
||||
.css({
|
||||
@ -1855,11 +1861,38 @@ module.Buttons = core.ImageGridFeatures.Feature({
|
||||
'width': '0px',
|
||||
'overflow': 'visible',
|
||||
})
|
||||
.text(this.crop_stack ? this.crop_stack.length : '')
|
||||
.text(l == 0 ? ''
|
||||
: l > 99 ? '99+'
|
||||
: l)
|
||||
}],
|
||||
// update collection button status...
|
||||
['load clear reload collectionLoaded collectionUnloaded',
|
||||
[[
|
||||
'load',
|
||||
'clear',
|
||||
'reload',
|
||||
'saveCollection',
|
||||
'collectionLoaded',
|
||||
'collectionUnloaded',
|
||||
],
|
||||
function(){
|
||||
$('.main-buttons.buttons .collections.button')
|
||||
.css({
|
||||
'color': this.collection ? 'yellow' : '',
|
||||
//'text-decoration': this.collection ? 'underline': '',
|
||||
})
|
||||
|
||||
var l = this.collections_length
|
||||
$('.main-buttons.buttons .collections.button sub')
|
||||
.css({
|
||||
'display': 'inline-block',
|
||||
'width': '0px',
|
||||
'overflow': 'visible',
|
||||
//'color': this.collection ? 'yellow' : '',
|
||||
})
|
||||
.text(l > 99 ? '99+'
|
||||
: l == 0 ? ''
|
||||
: l)
|
||||
/*
|
||||
$('.main-buttons.buttons .collections.button sub')
|
||||
// XXX should this be here or in CSS???
|
||||
.css({
|
||||
@ -1869,6 +1902,7 @@ module.Buttons = core.ImageGridFeatures.Feature({
|
||||
'color': 'yellow',
|
||||
})
|
||||
.html(this.collection ? '●' : '')
|
||||
//*/
|
||||
}],
|
||||
// update zoom button status...
|
||||
['viewScale',
|
||||
|
||||
@ -222,9 +222,44 @@ var DataPrototype = {
|
||||
|
||||
// Make a sparse list of image gids...
|
||||
//
|
||||
// Make sparse list out of gids...
|
||||
// .makeSparseImages(gids)
|
||||
// -> list
|
||||
//
|
||||
// Make sparse list out of gids and drop gids not in .order...
|
||||
// .makeSparseImages(gids, true)
|
||||
// .makeSparseImages(gids, null, null, true)
|
||||
// -> list
|
||||
// NOTE: this sets drop_non_order_gids...
|
||||
//
|
||||
// Plase gids into their .order positions into target...
|
||||
// .makeSparseImages(gids, target)
|
||||
// -> list
|
||||
// NOTE: items in target on given gid .order positions will
|
||||
// get overwritten...
|
||||
//
|
||||
// Plase gids into their .order positions into target and reposition
|
||||
// overwritten target items...
|
||||
// .makeSparseImages(gids, target, true)
|
||||
// -> list
|
||||
// NOTE: this sets keep_target_items...
|
||||
//
|
||||
// Plase gids into their .order positions into target and reposition
|
||||
// overwritten target items and drop gids not in .order...
|
||||
// .makeSparseImages(gids, target, true, true)
|
||||
// -> list
|
||||
// NOTE: this sets keep_target_items and drop_non_order_gids...
|
||||
//
|
||||
//
|
||||
// This uses .order as the base for ordering the list.
|
||||
//
|
||||
// If target is given then it will get updated with the input gids.
|
||||
// By default items in gids that are not present in .order are
|
||||
// appended to the output/target tail after .order.length, which ever
|
||||
// is greater (this puts these items out of reach of further calls
|
||||
// of .makeSparseImages(..)).
|
||||
// Setting drop_non_order_gids to true will drop these items from
|
||||
// output.
|
||||
//
|
||||
//
|
||||
// NOTE: this can be used to re-sort sections of a target ribbon,
|
||||
// but care must be taken not to overwrite existing data...
|
||||
@ -234,44 +269,65 @@ var DataPrototype = {
|
||||
// (see next for more info).
|
||||
// Another way to deal with this is to .makeSparseImages(target)
|
||||
// before using it as a target.
|
||||
// NOTE: if keep_target_items is set items that are overwritten in
|
||||
// the target will get pushed to gids.
|
||||
// This flag has no effect if target is an empty list (default).
|
||||
makeSparseImages: function(gids, target, keep_target_items){
|
||||
// NOTE: keep_target_items has no effect if target is not given...
|
||||
makeSparseImages: function(gids, target, keep_target_items, drop_non_order_gids){
|
||||
if(arguments.length == 2 && target === true){
|
||||
drop_non_order_gids = true
|
||||
target = null
|
||||
}
|
||||
// avoid mutating gids...
|
||||
gids = gids === target || keep_target_items ?
|
||||
gids.slice()
|
||||
: gids
|
||||
target = target == null ? [] : target
|
||||
keep_target_items = keep_target_items == null ? false : keep_target_items
|
||||
|
||||
order = this.order
|
||||
|
||||
// avoid directly updating self...
|
||||
if(gids === target){
|
||||
gids = gids.slice()
|
||||
}
|
||||
var rest = []
|
||||
|
||||
gids.forEach(function(e, i){
|
||||
for(var i=0; i < gids.length; i++){
|
||||
var e = gids[i]
|
||||
|
||||
// skip undefined...
|
||||
if(e === undefined
|
||||
// if the element is in its place alredy do nothing...
|
||||
if(e == order[i] && e == target[i]){
|
||||
return
|
||||
|| (e == order[i] && e == target[i])){
|
||||
continue
|
||||
}
|
||||
|
||||
// NOTE: try and avoid the expensive .indexOf(..) as much as
|
||||
// possible...
|
||||
i = e != order[i] ? order.indexOf(e) : i
|
||||
// try and avoid the expensive .indexOf(..) as much as possible...
|
||||
var j = e != order[i] ? order.indexOf(e) : i
|
||||
|
||||
if(i >= 0){
|
||||
var o = target[i]
|
||||
if(j >= 0){
|
||||
// save overwritten target items if keep_target_items
|
||||
// is set...
|
||||
if(keep_target_items
|
||||
var o = target[j]
|
||||
keep_target_items
|
||||
&& o != null
|
||||
// if the items is already in gids, forget it...
|
||||
// if the item is already in gids, forget it...
|
||||
// NOTE: this is to avoid juggling loops...
|
||||
&& gids.indexOf(o) < 0){
|
||||
gids.push(o)
|
||||
&& gids.indexOf(o) < 0
|
||||
// look at o again later...
|
||||
// NOTE: we should not loop endlessly here as target
|
||||
// will eventually get exhausted...
|
||||
&& gids.push(o)
|
||||
|
||||
target[j] = e
|
||||
|
||||
// handle elements in gids that are not in .order
|
||||
} else if(!drop_non_order_gids){
|
||||
rest.push(e)
|
||||
}
|
||||
}
|
||||
|
||||
target[i] = e
|
||||
// avoid duplicating target items...
|
||||
rest = rest
|
||||
.filter(function(e){ return target.indexOf(e) < 0 })
|
||||
|
||||
if(rest.length > 0){
|
||||
target.length = Math.max(order.length, target.length)
|
||||
target.splice(target.length, 0, ...rest)
|
||||
}
|
||||
})
|
||||
|
||||
return target
|
||||
},
|
||||
@ -1271,22 +1327,31 @@ var DataPrototype = {
|
||||
// .updateImagePositions()
|
||||
// -> data
|
||||
//
|
||||
// Reposition item(s)
|
||||
// Full sort and remove items not in .order
|
||||
// .updateImagePositions('remove')
|
||||
// -> data
|
||||
//
|
||||
// Reposition specific item(s)...
|
||||
// .updateImagePositions(gid|index)
|
||||
// .updateImagePositions([gid|index, .. ])
|
||||
// -> data
|
||||
//
|
||||
// Reposition item(s) and the item(s) they replace
|
||||
// Reposition item(s) and the item(s) they replace...
|
||||
// .updateImagePositions(gid|index, 'keep')
|
||||
// .updateImagePositions([gid|index, ..], 'keep')
|
||||
// -> data
|
||||
//
|
||||
// Hide item(s) from lists
|
||||
// Hide item(s) from lists...
|
||||
// .updateImagePositions(gid|index, 'hide')
|
||||
// .updateImagePositions([gid|index, ..], 'hide')
|
||||
// -> data
|
||||
//
|
||||
// Remove item(s) from lists
|
||||
// Remove item(s) from lists...
|
||||
// .updateImagePositions(gid|index, 'remove')
|
||||
// .updateImagePositions([gid|index, ..], 'remove')
|
||||
// -> data
|
||||
//
|
||||
//
|
||||
// NOTE: hide will not change the order of other items while remove
|
||||
// will do a full sort...
|
||||
// NOTE: in any case other that the first this will not try to
|
||||
@ -1295,6 +1360,10 @@ var DataPrototype = {
|
||||
// XXX needs more thought....
|
||||
// do we need to move images by this???
|
||||
updateImagePositions: function(from, mode, direction){
|
||||
if(['keep', 'hide', 'remove'].indexOf(from) >= 0){
|
||||
mode = from
|
||||
from = null
|
||||
}
|
||||
from = from != null && from.constructor !== Array ? [from] : from
|
||||
|
||||
var r = this.getRibbon('current')
|
||||
@ -1304,7 +1373,9 @@ var DataPrototype = {
|
||||
|
||||
// resort...
|
||||
if(from == null){
|
||||
set[key] = this.makeSparseImages(cur)
|
||||
set[key] = mode == 'remove' ?
|
||||
this.makeSparseImages(cur, true)
|
||||
: this.makeSparseImages(cur)
|
||||
|
||||
// remove/hide elements...
|
||||
} else if(mode == 'remove' || mode == 'hide'){
|
||||
@ -1313,7 +1384,7 @@ var DataPrototype = {
|
||||
})
|
||||
// if we are removing we'll also need to resort...
|
||||
if(mode == 'remove'){
|
||||
set[key] = this.makeSparseImages(cur)
|
||||
set[key] = this.makeSparseImages(cur, true)
|
||||
}
|
||||
|
||||
// place and keep existing...
|
||||
@ -1328,7 +1399,7 @@ var DataPrototype = {
|
||||
|
||||
// maintain focus...
|
||||
if(from && from.indexOf(this.current) >= 0){
|
||||
this.focusImage('r')
|
||||
this.focusImage(r)
|
||||
}
|
||||
|
||||
return this
|
||||
@ -2613,7 +2684,7 @@ var DataPrototype = {
|
||||
// NOTE: this may result in empty ribbons...
|
||||
removeUnloadedGIDs: function(){
|
||||
this.order = this.getImages('loaded')
|
||||
this.updateImagePositions()
|
||||
this.updateImagePositions('remove')
|
||||
return this
|
||||
},
|
||||
|
||||
@ -2647,7 +2718,8 @@ var DataPrototype = {
|
||||
}
|
||||
|
||||
this.order = order
|
||||
this.updateImagePositions()
|
||||
|
||||
this.updateImagePositions('remove')
|
||||
|
||||
return this
|
||||
},
|
||||
|
||||
@ -559,11 +559,11 @@ function(data, options){
|
||||
//
|
||||
// length_limit: <number>,
|
||||
//
|
||||
// // Called when an item is opend...
|
||||
// // Item open event handler...
|
||||
// //
|
||||
// // NOTE: this is simpler that binding to the global open event
|
||||
// // and filtering through the results...
|
||||
// itemopen: function(value){ ... },
|
||||
// itemopen: function(evt, value){ ... },
|
||||
//
|
||||
// // Check input value...
|
||||
// check: function(value){ ... },
|
||||
@ -910,7 +910,7 @@ function(list, options){
|
||||
})
|
||||
|
||||
options.itemopen
|
||||
&& res.on('open', function(){ options.itemopen(dialog.selected) })
|
||||
&& res.on('open', function(evt){ options.itemopen(evt, dialog.selected) })
|
||||
|
||||
res = res.toArray()
|
||||
|
||||
@ -2026,6 +2026,13 @@ var BrowserPrototype = {
|
||||
//
|
||||
// // event handlers...
|
||||
// events: {
|
||||
// // item-specific update events...
|
||||
// //
|
||||
// // item added to dom by .update(..)...
|
||||
// // NOTE: this is not propagated up, thus it will not trigger
|
||||
// // the list update.
|
||||
// update: <handler>,
|
||||
//
|
||||
// <event>: <handler>,
|
||||
// ...
|
||||
// },
|
||||
@ -2477,6 +2484,7 @@ var BrowserPrototype = {
|
||||
})
|
||||
|
||||
//--------------------------------- user event handlers ---
|
||||
res.on('update', function(evt){ evt.stopPropagation() })
|
||||
Object.keys(opts.events || {})
|
||||
.forEach(function(evt){
|
||||
res.on(evt, opts.events[evt]) })
|
||||
@ -2498,8 +2506,11 @@ var BrowserPrototype = {
|
||||
res.appendTo(l)
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------
|
||||
|
||||
//------------------------------- item lifecycle events ---
|
||||
res.trigger('update', txt)
|
||||
|
||||
//---------------------------------------------------------
|
||||
return res
|
||||
}
|
||||
|
||||
|
||||
@ -238,12 +238,12 @@ $(function(){
|
||||
// load some testing data if nothing else loaded...
|
||||
if(!this.url_history || Object.keys(this.url_history).length == 0){
|
||||
// NOTE: we can (and do) load this in parts...
|
||||
this.loadDemoIndex()
|
||||
|
||||
this
|
||||
.loadDemoIndex()
|
||||
// this is needed when loading legacy sources that do not have tags
|
||||
// synced...
|
||||
// do not do for actual data...
|
||||
//.syncTags()
|
||||
.syncTags('both')
|
||||
}
|
||||
})
|
||||
.start()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user