mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-28 18:00:09 +00:00
refactoring...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
9cc007a2cb
commit
0924383bcd
@ -250,6 +250,7 @@ body {
|
||||
font-style: italic;
|
||||
}
|
||||
/* do not show top border if after another action or separator... */
|
||||
.browse-widget .list>.action:first-child,
|
||||
.browse-widget .list>.action+.action,
|
||||
.browse-widget .list>.separator+.action {
|
||||
border-top: none;
|
||||
|
||||
@ -884,17 +884,22 @@ var KeyboardActions = actions.Actions({
|
||||
.concat($('<span>')
|
||||
.addClass('text')
|
||||
.html(keys[mode][action]
|
||||
// mark key if it is in dropped...
|
||||
// mark key if it's dropped...
|
||||
.map(function(s){
|
||||
s = s.split('+')
|
||||
var k = s.pop()
|
||||
var i = dropped.indexOf(k)
|
||||
i >= 0
|
||||
&& bound_ignored
|
||||
.push(dropped[i])
|
||||
s.push(k
|
||||
+ (i >= 0 ? '<sup>*</sup>' : ''))
|
||||
return s.join('+') })
|
||||
if(dropped == '*'){
|
||||
s += '<sup>*</sup>'
|
||||
} else {
|
||||
s = s.split('+')
|
||||
var k = s.pop()
|
||||
var i = dropped.indexOf(k)
|
||||
i >= 0
|
||||
&& bound_ignored
|
||||
.push(dropped[i])
|
||||
s.push(k + (i >= 0 ? '<sup>*</sup>' : ''))
|
||||
s = s.join('+')
|
||||
}
|
||||
return s
|
||||
})
|
||||
.join(' / '))),
|
||||
{
|
||||
// hide stuff that is not an action...
|
||||
@ -940,10 +945,12 @@ var KeyboardActions = actions.Actions({
|
||||
// together in path...
|
||||
' ',
|
||||
'$BUTTONS',
|
||||
dropped
|
||||
.filter(function(k){
|
||||
return bound_ignored.indexOf(k) == -1 })
|
||||
.join(' / ')],
|
||||
dropped == '*' ?
|
||||
dropped
|
||||
: dropped
|
||||
.filter(function(k){
|
||||
return bound_ignored.indexOf(k) == -1 })
|
||||
.join(' / ')],
|
||||
{
|
||||
buttons: options.drop_buttons,
|
||||
})
|
||||
@ -974,6 +981,7 @@ var KeyboardActions = actions.Actions({
|
||||
.addClass('info')
|
||||
},
|
||||
{
|
||||
path: path,
|
||||
cls: [
|
||||
'key-bindings',
|
||||
'no-item-numbers',
|
||||
@ -1107,7 +1115,13 @@ var KeyboardActions = actions.Actions({
|
||||
|
||||
sub_dialog
|
||||
&& sub_dialog
|
||||
.close(function(){ dialog.update() })
|
||||
// XXX for some magical reason this is triggered BEFORE
|
||||
// the base event handler...
|
||||
// ...seems that there's an async something hidden
|
||||
// in the middle, need to check this! (XXX)
|
||||
//.close(function(){ dialog.update() })
|
||||
.close(function(){
|
||||
setTimeout(function(){ dialog.update() }, 0) })
|
||||
})
|
||||
return dialog
|
||||
})],
|
||||
@ -1116,7 +1130,13 @@ var KeyboardActions = actions.Actions({
|
||||
editKeyBinding: ['- Interface/Key mapping...',
|
||||
widgets.makeUIDialog(function(mode, code){
|
||||
var that = this
|
||||
// XXX
|
||||
|
||||
// list the keys (cache)...
|
||||
var keys = that.keyboard.keys(code)
|
||||
keys = mode in keys ?
|
||||
(keys[mode][code] || [])
|
||||
: []
|
||||
|
||||
var dialog = browse.makeLister(null,
|
||||
function(path, make){
|
||||
// XXX make editable...
|
||||
@ -1126,39 +1146,24 @@ var KeyboardActions = actions.Actions({
|
||||
|
||||
make('---')
|
||||
|
||||
// list the keys...
|
||||
var keys = that.keyboard.keys(code)
|
||||
keys = mode in keys ?
|
||||
(keys[mode][code] || [])
|
||||
: []
|
||||
|
||||
var to_remove = []
|
||||
keys
|
||||
.forEach(function(key){
|
||||
// XXX make editable...
|
||||
make(key, { buttons: [
|
||||
browse.buttons.markForRemoval(to_remove)
|
||||
], })
|
||||
})
|
||||
|
||||
var new_button = make.Action('New key...')
|
||||
.on('open', function(){
|
||||
widgets.editItem(dialog, new_button)
|
||||
})
|
||||
make.EditableList(keys)
|
||||
|
||||
make('---')
|
||||
|
||||
make.ConfirmAction('Delete', {
|
||||
callback: function(){
|
||||
// XXX
|
||||
dialog.close()
|
||||
},
|
||||
callback: function(){ dialog.close() },
|
||||
timeout: that.config['confirm-delete-timeout'] || 2000,
|
||||
})
|
||||
},
|
||||
{
|
||||
cls: 'metadata-view',
|
||||
})
|
||||
// save the keys...
|
||||
.on('close', function(){
|
||||
// XXX
|
||||
})
|
||||
|
||||
return dialog
|
||||
})],
|
||||
@ -1193,28 +1198,72 @@ var KeyboardActions = actions.Actions({
|
||||
|
||||
return dialog
|
||||
})],
|
||||
// XXX need a way to abort edits...
|
||||
// XXX need a way to set a special '*' key...
|
||||
// XXX revise...
|
||||
// - '*' toggle
|
||||
// - done/cancel
|
||||
editKeyboardModeDroppedKeys: ['- Interface/Dropped keys...',
|
||||
widgets.makeUIDialog(function(mode){
|
||||
var that = this
|
||||
//var abort = false
|
||||
var abort = true
|
||||
var drop = that.keybindings[mode].drop || []
|
||||
|
||||
// XXX need a way to set a special '*' key...
|
||||
var dialog = browse.makeListEditor(function(keys){
|
||||
// get...
|
||||
if(keys === undefined){
|
||||
return that.keybindings[mode].drop || []
|
||||
return browse.makeLister(null,
|
||||
function(path, make){
|
||||
var drop_all
|
||||
|
||||
// set...
|
||||
} else {
|
||||
that.keybindings[mode].drop = keys
|
||||
}
|
||||
},
|
||||
{
|
||||
unique: true,
|
||||
})
|
||||
// '*' toggler...
|
||||
// XXX should this close the dialog???
|
||||
make.ConfirmAction('Drop all keys', {
|
||||
callback: function(){
|
||||
drop_all = '*'
|
||||
|
||||
make.dialog.close()
|
||||
},
|
||||
timeout: that.config['confirm-delete-timeout'] || 2000,
|
||||
})
|
||||
|
||||
return dialog
|
||||
make('---')
|
||||
|
||||
// the list editor...
|
||||
make.EditableList(function(keys){
|
||||
// get...
|
||||
if(keys === undefined){
|
||||
return drop && drop != '*' ? drop : []
|
||||
|
||||
// set...
|
||||
} else {
|
||||
drop = drop_all ? '*' : keys
|
||||
}
|
||||
},
|
||||
{
|
||||
unique: true
|
||||
})
|
||||
|
||||
make('---')
|
||||
|
||||
//make.Action('Cancel')
|
||||
// .on('open', function(){
|
||||
// abort = true
|
||||
// make.dialog.close()
|
||||
// })
|
||||
make.Action('Done', {
|
||||
buttons: [
|
||||
['Cancel', function(){
|
||||
make.dialog.close()
|
||||
}],
|
||||
]})
|
||||
.on('open', function(){
|
||||
abort = false
|
||||
make.dialog.close()
|
||||
})
|
||||
|
||||
})
|
||||
.on('close', function(){
|
||||
if(!abort){
|
||||
that.keybindings[mode].drop = drop
|
||||
}
|
||||
})
|
||||
})],
|
||||
|
||||
|
||||
|
||||
@ -129,9 +129,43 @@ Items.Selectable =
|
||||
function(text, options){
|
||||
}
|
||||
|
||||
// make Editable on select element...
|
||||
//
|
||||
// options format:
|
||||
// {
|
||||
// clear_on_edit: true,
|
||||
//
|
||||
// editaborted:
|
||||
// editdone:
|
||||
//
|
||||
// action: <bool>,
|
||||
// }
|
||||
// XXX
|
||||
Items.Editable =
|
||||
function(text, options){
|
||||
options = options || {}
|
||||
var dialog = this.dialog
|
||||
var elem = (options.action ? this.Action : this).call(this, text, options)
|
||||
.on('select', function(){
|
||||
var editable = elem.find('.text')
|
||||
.makeEditable({
|
||||
activate: true,
|
||||
clear_on_edit: options.clear_on_edit,
|
||||
blur_on_abort: false,
|
||||
blur_on_commit: false,
|
||||
})
|
||||
// deselect on abort...
|
||||
.on('edit-aborted', function(){
|
||||
dialog.select(null)
|
||||
dialog.update()
|
||||
})
|
||||
|
||||
options.editaborted
|
||||
&& editable.on('edit-aborted', options.editaborted)
|
||||
options.editdone
|
||||
&& editable.on('edit-done', options.editdone)
|
||||
})
|
||||
return elem
|
||||
}
|
||||
|
||||
// XXX
|
||||
@ -145,39 +179,87 @@ function(text, options){
|
||||
}
|
||||
|
||||
|
||||
// Make list of elements...
|
||||
//
|
||||
Items.List =
|
||||
function(list, options){
|
||||
var make = this
|
||||
var res = []
|
||||
list.forEach(function(e){
|
||||
make(e, options)
|
||||
res.push(make(e, options)[0])
|
||||
})
|
||||
return $(res)
|
||||
}
|
||||
|
||||
|
||||
// Make editable list of elements...
|
||||
//
|
||||
// This will edit the passed list in-place.
|
||||
//
|
||||
// options format:
|
||||
// {
|
||||
// new_button: <text>|<bool>,
|
||||
//
|
||||
// // if true, disable delete item button...
|
||||
// no_delete_button: <bool>,
|
||||
//
|
||||
// editdone: function(lst){ .. },
|
||||
// // XXX
|
||||
// changed: function(lst){ .. },
|
||||
// length_limit: <number>,
|
||||
//
|
||||
// // check input value...
|
||||
// check: function(value){ ... },
|
||||
//
|
||||
// // if true only unique values will be stored...
|
||||
// // if a function this will be used to normalize the values before
|
||||
// // uniqueness check is performed...
|
||||
// unique: <bool>|function(value){ ... },
|
||||
//
|
||||
// // if true sort values...
|
||||
// // if function will be used as cmp for sorting...
|
||||
// sort: <bool> || function(a, b){ ... },
|
||||
//
|
||||
// // this is called when a new value is added via new_button but
|
||||
// // list length limit is reached...
|
||||
// overflow: function(selected){ ... },
|
||||
//
|
||||
// // see: itemButtons doc in browse.js for more info...
|
||||
// itemButtons: [..]
|
||||
//
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
// NOTE: this will return a list of elements with the new button...
|
||||
// NOTE: this will push a remove button to the end of the button list,
|
||||
// this can be disabled by setting .no_delete_button to false in
|
||||
// options...
|
||||
//
|
||||
// XXX add sort buttons: up/down/top/bottom...
|
||||
Items.EditableList =
|
||||
function(list, options){
|
||||
var make = this
|
||||
var dialog = make.dialog
|
||||
|
||||
var editdone = options.editdone
|
||||
// XXX
|
||||
var changed = options.changed
|
||||
var write = function(list, lst){
|
||||
// write back the list...
|
||||
return list instanceof Function ?
|
||||
// call the writer...
|
||||
list(lst)
|
||||
// in-place replace list elements...
|
||||
// NOTE: this is necessary as not everything we do with lst
|
||||
// is in-place...
|
||||
: list.splice.apply(list, [0, list.length].concat(lst))
|
||||
}
|
||||
|
||||
var to_remove = []
|
||||
|
||||
// make a copy of options, to keep it safe from changes we are going
|
||||
// to make...
|
||||
options = options || {}
|
||||
var opts = {}
|
||||
for(var k in options){
|
||||
opts[k] = options[k]
|
||||
}
|
||||
options = opts
|
||||
|
||||
var lst = list instanceof Function ?
|
||||
list()
|
||||
: list
|
||||
@ -185,137 +267,117 @@ function(list, options){
|
||||
// view objects...
|
||||
lst = !editable ? Object.keys(lst) : lst.slice()
|
||||
|
||||
var buttons = options.buttons = options.buttons || []
|
||||
// add the 'x' button if not disabled...
|
||||
var buttons = options.buttons = (options.buttons || []).slice()
|
||||
!options.no_delete_button
|
||||
&& buttons.push(Buttons.markForRemoval(to_remove))
|
||||
|
||||
// XXX make this generic...
|
||||
var _makeEditable = function(elem){
|
||||
return $(elem).find('.text')
|
||||
.makeEditable({
|
||||
activate: true,
|
||||
clear_on_edit: true,
|
||||
blur_on_abort: false,
|
||||
blur_on_commit: false,
|
||||
})
|
||||
.on('edit-aborted', function(){
|
||||
dialog.select(null)
|
||||
dialog.update()
|
||||
})
|
||||
.on('edit-done', function(evt, text){
|
||||
var txt = $(this).text()
|
||||
|
||||
// invalid format...
|
||||
if(options.check && !options.check(txt)){
|
||||
dialog.update()
|
||||
return
|
||||
}
|
||||
|
||||
// list length limit
|
||||
if(options.length_limit
|
||||
&& (lst.length >= options.length_limit)){
|
||||
|
||||
options.callback && options.callback.call(dialog, txt)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// prevent editing non-arrays...
|
||||
if(!editable || !lst){
|
||||
return
|
||||
}
|
||||
|
||||
// add new value and sort list...
|
||||
lst.push(txt)
|
||||
|
||||
// unique...
|
||||
if(options.unique == null || options.unique === true){
|
||||
lst = lst.unique()
|
||||
|
||||
// unique normalized...
|
||||
} else if(options.unique instanceof Function){
|
||||
lst = lst.unique(options.unique)
|
||||
}
|
||||
|
||||
// sort...
|
||||
if(options.sort){
|
||||
lst = lst
|
||||
.sort(options.sort instanceof Function ?
|
||||
options.sort
|
||||
: undefined)
|
||||
}
|
||||
|
||||
changed
|
||||
&& changed(lst)
|
||||
|
||||
// update the list data...
|
||||
//dialog.options.data = lst.concat(new_button ? [ new_button ] : [])
|
||||
|
||||
// update list and select new value...
|
||||
dialog.update()
|
||||
.done(function(){
|
||||
dialog.select('"'+txt+'"')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// make the list...
|
||||
make.List(lst, options)
|
||||
var res = make.List(lst, options).toArray()
|
||||
|
||||
// new button...
|
||||
var new_button = options.new_button || true
|
||||
new_button = new_button === true ? 'New...' : new_button
|
||||
make(new_button)
|
||||
// make editable...
|
||||
// XXX check signature...
|
||||
.on('select', function(evt, p, e){
|
||||
_makeEditable(e)
|
||||
res.push(make.Editable(
|
||||
new_button,
|
||||
{
|
||||
action: true,
|
||||
clear_on_edit: true,
|
||||
})
|
||||
// update list on edit done...
|
||||
.on('edit-done', function(evt, text){
|
||||
var txt = $(this).text()
|
||||
|
||||
// dialog handlers...
|
||||
dialog
|
||||
.open(function(evt, path){
|
||||
// we clicked the 'New' button -- select it...
|
||||
if(new_button && (path == new_button || path == '')){
|
||||
dialog.select(new_button)
|
||||
|
||||
} else if(options.callback){
|
||||
options.callback.call(dialog, path)
|
||||
}
|
||||
})
|
||||
// update the striked-out items (to_remove)...
|
||||
.on('update', function(){
|
||||
to_remove.forEach(function(e){
|
||||
dialog.filter('"'+ e +'"')
|
||||
.toggleClass('strike-out')
|
||||
})
|
||||
})
|
||||
// clear the to_remove items + save list...
|
||||
.on('close', function(){
|
||||
// prevent editing non-arrays...
|
||||
if(!editable){
|
||||
// invalid format...
|
||||
if(options.check && !options.check(txt)){
|
||||
dialog.update()
|
||||
return
|
||||
}
|
||||
|
||||
// remove items...
|
||||
to_remove.forEach(function(e){
|
||||
lst.splice(lst.indexOf(e), 1)
|
||||
})
|
||||
// list length limit
|
||||
if(options.length_limit
|
||||
&& (lst.length >= options.length_limit)){
|
||||
|
||||
options.overflow
|
||||
&& options.overflow.call(dialog, txt)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// prevent editing non-arrays...
|
||||
if(!editable || !lst){
|
||||
return
|
||||
}
|
||||
|
||||
// add new value and sort list...
|
||||
lst.push(txt)
|
||||
|
||||
// unique...
|
||||
if(options.unique == null || options.unique === true){
|
||||
lst = lst.unique()
|
||||
|
||||
// unique normalized...
|
||||
} else if(options.unique instanceof Function){
|
||||
lst = lst.unique(options.unique)
|
||||
}
|
||||
|
||||
// sort...
|
||||
if(options.sort){
|
||||
lst.sort(options.sort !== true ? options.sort : undefined)
|
||||
lst = lst
|
||||
.sort(options.sort instanceof Function ?
|
||||
options.sort
|
||||
: undefined)
|
||||
}
|
||||
|
||||
write
|
||||
&& write(lst)
|
||||
})
|
||||
write(list, lst)
|
||||
|
||||
// update list and select new value...
|
||||
dialog.update()
|
||||
.done(function(){
|
||||
dialog.select('"'+txt+'"')
|
||||
})
|
||||
}))
|
||||
|
||||
|
||||
// dialog handlers...
|
||||
// NOTE: we bind these only once per dialog...
|
||||
if(dialog.__editable_list_handlers == null){
|
||||
dialog.__editable_list_handlers = true
|
||||
dialog
|
||||
// update the striked-out items (to_remove)...
|
||||
.on('update', function(){
|
||||
to_remove.forEach(function(e){
|
||||
dialog.filter('"'+ e +'"')
|
||||
.toggleClass('strike-out')
|
||||
})
|
||||
})
|
||||
// clear the to_remove items + save list...
|
||||
.on('close', function(){
|
||||
// prevent editing non-arrays...
|
||||
if(!editable){
|
||||
return
|
||||
}
|
||||
|
||||
// remove items...
|
||||
to_remove.forEach(function(e){
|
||||
lst.splice(lst.indexOf(e), 1)
|
||||
})
|
||||
|
||||
// sort...
|
||||
if(options.sort){
|
||||
lst.sort(options.sort !== true ? options.sort : undefined)
|
||||
}
|
||||
|
||||
write(list, lst)
|
||||
})
|
||||
}
|
||||
|
||||
return $(res)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Browse item buttons (button constructors)...
|
||||
|
||||
@ -348,6 +410,7 @@ module.buttons = {
|
||||
|
||||
|
||||
|
||||
|
||||
/*********************************************************************/
|
||||
|
||||
// NOTE: the widget itself does not need a title, that's the job for
|
||||
@ -655,16 +718,17 @@ var BrowserPrototype = {
|
||||
// XXX should we have things like ctrl-<number> for fast selection
|
||||
// in filter mode???
|
||||
keybindings: {
|
||||
// XXX this is the same as FullPathEdit, should we combine the two?
|
||||
ItemEdit: {
|
||||
pattern: '.list .text[contenteditable]',
|
||||
|
||||
// keep text editing action from affecting the selection...
|
||||
drop: '*',
|
||||
|
||||
// XXX not sure about this...
|
||||
Up: 'NEXT',
|
||||
Down: 'NEXT',
|
||||
// XXX this does not seem to work...
|
||||
Up: 'NEXT!',
|
||||
Down: 'NEXT!',
|
||||
Tab: 'NEXT!',
|
||||
shift_Tab: 'NEXT!',
|
||||
|
||||
Enter: 'push!',
|
||||
Esc: 'update!',
|
||||
@ -686,8 +750,10 @@ var BrowserPrototype = {
|
||||
// keep text editing action from affecting the selection...
|
||||
drop: '*',
|
||||
|
||||
Up: 'NEXT',
|
||||
Down: 'NEXT',
|
||||
Up: 'NEXT!',
|
||||
Down: 'NEXT!',
|
||||
Tab: 'NEXT!',
|
||||
shift_Tab: 'NEXT!',
|
||||
|
||||
Enter: 'push!',
|
||||
Esc: 'stopFilter!',
|
||||
@ -1390,6 +1456,9 @@ var BrowserPrototype = {
|
||||
.append(p)
|
||||
|
||||
res.addClass([
|
||||
// XXX use the same algorithm as .select(..)
|
||||
selection && res.text() == selection ? 'selected' : '',
|
||||
|
||||
!traversable ? 'not-traversable' : '',
|
||||
disabled ? 'disabled' : '',
|
||||
hidden ? 'hidden' : '',
|
||||
@ -1523,7 +1592,6 @@ var BrowserPrototype = {
|
||||
|
||||
// select the item...
|
||||
if(selection){
|
||||
//that.select(selection)
|
||||
that.select('"'+ selection +'"')
|
||||
}
|
||||
|
||||
@ -2715,13 +2783,13 @@ var BrowserPrototype = {
|
||||
parent.append(dom)
|
||||
}
|
||||
|
||||
// load the initial state...
|
||||
that.update(options.path || that.path || '/')
|
||||
|
||||
// Select the default path...
|
||||
//
|
||||
// NOTE: this may not work when the dialog is loaded async...
|
||||
setTimeout(function(){
|
||||
// load the initial state...
|
||||
that.update(options.path || that.path || '/')
|
||||
|
||||
// in case we have a manually selected item but that was
|
||||
// not aligned...
|
||||
that.selected && that.select()
|
||||
@ -2855,7 +2923,7 @@ ListPrototype.options = {
|
||||
}
|
||||
}
|
||||
|
||||
var e = make(n, null, disable)
|
||||
var e = make(n, {disabled: disable})
|
||||
|
||||
if(data !== keys && that.options.data[k] != null){
|
||||
e.on('open', function(){
|
||||
@ -3131,187 +3199,16 @@ module.makePathList = makeBrowserMaker(PathList)
|
||||
|
||||
// Make an list/Array editor...
|
||||
//
|
||||
// Options format:
|
||||
// {
|
||||
// new_button: <text>|<bool>,
|
||||
//
|
||||
// length_limit: <number>,
|
||||
//
|
||||
// // check input value...
|
||||
// check: function(value){ ... },
|
||||
//
|
||||
// // if true only unique values will be stored...
|
||||
// // if a function this will be used to normalize the values before
|
||||
// // uniqueness check is performed...
|
||||
// unique: <bool>|function(value){ ... },
|
||||
//
|
||||
// // if true sort values...
|
||||
// // if function will be used as cmp for sorting...
|
||||
// sort: <bool> || function(a, b){ ... },
|
||||
//
|
||||
// // this is called when a new value is added via new_button but
|
||||
// // list length limit is reached...
|
||||
// callback: function(selected){ ... },
|
||||
//
|
||||
// // see: itemButtons doc in browse.js for more info...
|
||||
// itemButtons: [..]
|
||||
// }
|
||||
//
|
||||
// XXX add sort buttons: up/down/top/bottom...
|
||||
// XXX this is generic, move to browse...
|
||||
// For options format see: List.EditableList(..)
|
||||
var makeListEditor =
|
||||
module.makeListEditor =
|
||||
function(list, options){
|
||||
options = options || {}
|
||||
|
||||
var new_button = options.new_button || true
|
||||
new_button = new_button === true ? 'New...' : new_button
|
||||
|
||||
var _makeEditable = function(elem){
|
||||
return $(elem).find('.text')
|
||||
.makeEditable({
|
||||
activate: true,
|
||||
clear_on_edit: true,
|
||||
blur_on_abort: false,
|
||||
blur_on_commit: false,
|
||||
})
|
||||
.on('edit-aborted', function(){
|
||||
dialog.select(null)
|
||||
dialog.update()
|
||||
})
|
||||
.on('edit-done', function(evt, text){
|
||||
var txt = $(this).text()
|
||||
|
||||
// invalid format...
|
||||
if(options.check && !options.check(txt)){
|
||||
dialog.update()
|
||||
return
|
||||
}
|
||||
|
||||
// list length limit
|
||||
if(options.length_limit
|
||||
&& (lst.length >= options.length_limit)){
|
||||
|
||||
options.callback && options.callback.call(dialog, txt)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// prevent editing non-arrays...
|
||||
if(!editable || !lst){
|
||||
return
|
||||
}
|
||||
|
||||
// add new value and sort list...
|
||||
lst.push(txt)
|
||||
|
||||
// unique...
|
||||
if(options.unique == null || options.unique === true){
|
||||
lst = lst.unique()
|
||||
|
||||
// unique normalized...
|
||||
} else if(typeof(options.unique) == typeof(function(){})){
|
||||
lst = lst.unique(options.unique)
|
||||
}
|
||||
|
||||
// sort...
|
||||
if(options.sort){
|
||||
lst = lst
|
||||
.sort(typeof(options.sort) == typeof(function(){}) ?
|
||||
options.sort
|
||||
: undefined)
|
||||
}
|
||||
|
||||
_write(lst)
|
||||
|
||||
// update the list data...
|
||||
dialog.options.data = lst.concat(new_button ? [ new_button ] : [])
|
||||
|
||||
// update list and select new value...
|
||||
dialog.update()
|
||||
.done(function(){
|
||||
dialog.select('"'+txt+'"')
|
||||
})
|
||||
})
|
||||
}
|
||||
var _write = function(lst){
|
||||
// write back the list...
|
||||
return list instanceof Function ?
|
||||
// call the writer...
|
||||
list(lst)
|
||||
// in-place replace list elements...
|
||||
// NOTE: this is necessary as not everything we do with lst
|
||||
// is in-place...
|
||||
: list.splice.apply(list, [0, list.length].concat(lst))
|
||||
}
|
||||
|
||||
var to_remove = []
|
||||
|
||||
var lst = list instanceof Function ?
|
||||
list()
|
||||
: list
|
||||
var editable = lst instanceof Array
|
||||
|
||||
// view objects...
|
||||
lst = !editable ? Object.keys(lst) : lst.slice()
|
||||
|
||||
var dialog = makeList(null,
|
||||
lst.concat(new_button ? [ new_button ] : []),
|
||||
{
|
||||
path: options.path,
|
||||
itemButtons: options.itemButtons || [
|
||||
// mark for removal...
|
||||
Buttons.markForRemoval(to_remove),
|
||||
// XXX add shift up/down/top/bottom and other buttons (optional)...
|
||||
]
|
||||
})
|
||||
// select the new_button item...
|
||||
.on('select', function(evt, elem){
|
||||
if(new_button && $(elem).find('.text').text() == new_button){
|
||||
_makeEditable(elem)
|
||||
}
|
||||
})
|
||||
.open(function(evt, path){
|
||||
// we clicked the 'New' button -- select it...
|
||||
if(new_button && (path == new_button || path == '')){
|
||||
dialog.select(new_button)
|
||||
|
||||
} else {
|
||||
options.callback && options.callback.call(dialog, path)
|
||||
}
|
||||
})
|
||||
// restore striked-out items...
|
||||
.on('update', function(){
|
||||
to_remove.forEach(function(e){
|
||||
dialog.filter('"'+ e +'"')
|
||||
.toggleClass('strike-out')
|
||||
})
|
||||
})
|
||||
.on('close', function(){
|
||||
// prevent editing non-arrays...
|
||||
if(!editable){
|
||||
return
|
||||
}
|
||||
|
||||
// remove striked items...
|
||||
to_remove.forEach(function(e){
|
||||
lst.splice(lst.indexOf(e), 1)
|
||||
|
||||
_write(lst)
|
||||
})
|
||||
|
||||
// sort...
|
||||
if(options.sort){
|
||||
lst.sort(options.sort !== true ? options.sort : undefined)
|
||||
|
||||
_write(lst)
|
||||
}
|
||||
})
|
||||
|
||||
// XXX
|
||||
new_button && dialog.dom.addClass('tail-action')
|
||||
|
||||
return dialog
|
||||
return makeLister(null,
|
||||
function(path, make){
|
||||
make.EditableList(list, options)
|
||||
},
|
||||
options)
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user