mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 10:20:08 +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;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
/* do not show top border if after another action or separator... */
|
/* 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>.action+.action,
|
||||||
.browse-widget .list>.separator+.action {
|
.browse-widget .list>.separator+.action {
|
||||||
border-top: none;
|
border-top: none;
|
||||||
|
|||||||
@ -884,17 +884,22 @@ var KeyboardActions = actions.Actions({
|
|||||||
.concat($('<span>')
|
.concat($('<span>')
|
||||||
.addClass('text')
|
.addClass('text')
|
||||||
.html(keys[mode][action]
|
.html(keys[mode][action]
|
||||||
// mark key if it is in dropped...
|
// mark key if it's dropped...
|
||||||
.map(function(s){
|
.map(function(s){
|
||||||
|
if(dropped == '*'){
|
||||||
|
s += '<sup>*</sup>'
|
||||||
|
} else {
|
||||||
s = s.split('+')
|
s = s.split('+')
|
||||||
var k = s.pop()
|
var k = s.pop()
|
||||||
var i = dropped.indexOf(k)
|
var i = dropped.indexOf(k)
|
||||||
i >= 0
|
i >= 0
|
||||||
&& bound_ignored
|
&& bound_ignored
|
||||||
.push(dropped[i])
|
.push(dropped[i])
|
||||||
s.push(k
|
s.push(k + (i >= 0 ? '<sup>*</sup>' : ''))
|
||||||
+ (i >= 0 ? '<sup>*</sup>' : ''))
|
s = s.join('+')
|
||||||
return s.join('+') })
|
}
|
||||||
|
return s
|
||||||
|
})
|
||||||
.join(' / '))),
|
.join(' / '))),
|
||||||
{
|
{
|
||||||
// hide stuff that is not an action...
|
// hide stuff that is not an action...
|
||||||
@ -940,7 +945,9 @@ var KeyboardActions = actions.Actions({
|
|||||||
// together in path...
|
// together in path...
|
||||||
' ',
|
' ',
|
||||||
'$BUTTONS',
|
'$BUTTONS',
|
||||||
|
dropped == '*' ?
|
||||||
dropped
|
dropped
|
||||||
|
: dropped
|
||||||
.filter(function(k){
|
.filter(function(k){
|
||||||
return bound_ignored.indexOf(k) == -1 })
|
return bound_ignored.indexOf(k) == -1 })
|
||||||
.join(' / ')],
|
.join(' / ')],
|
||||||
@ -974,6 +981,7 @@ var KeyboardActions = actions.Actions({
|
|||||||
.addClass('info')
|
.addClass('info')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
path: path,
|
||||||
cls: [
|
cls: [
|
||||||
'key-bindings',
|
'key-bindings',
|
||||||
'no-item-numbers',
|
'no-item-numbers',
|
||||||
@ -1107,7 +1115,13 @@ var KeyboardActions = actions.Actions({
|
|||||||
|
|
||||||
sub_dialog
|
sub_dialog
|
||||||
&& 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
|
return dialog
|
||||||
})],
|
})],
|
||||||
@ -1116,7 +1130,13 @@ var KeyboardActions = actions.Actions({
|
|||||||
editKeyBinding: ['- Interface/Key mapping...',
|
editKeyBinding: ['- Interface/Key mapping...',
|
||||||
widgets.makeUIDialog(function(mode, code){
|
widgets.makeUIDialog(function(mode, code){
|
||||||
var that = this
|
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,
|
var dialog = browse.makeLister(null,
|
||||||
function(path, make){
|
function(path, make){
|
||||||
// XXX make editable...
|
// XXX make editable...
|
||||||
@ -1126,39 +1146,24 @@ var KeyboardActions = actions.Actions({
|
|||||||
|
|
||||||
make('---')
|
make('---')
|
||||||
|
|
||||||
// list the keys...
|
|
||||||
var keys = that.keyboard.keys(code)
|
|
||||||
keys = mode in keys ?
|
|
||||||
(keys[mode][code] || [])
|
|
||||||
: []
|
|
||||||
|
|
||||||
var to_remove = []
|
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...')
|
make.EditableList(keys)
|
||||||
.on('open', function(){
|
|
||||||
widgets.editItem(dialog, new_button)
|
|
||||||
})
|
|
||||||
|
|
||||||
make('---')
|
make('---')
|
||||||
|
|
||||||
make.ConfirmAction('Delete', {
|
make.ConfirmAction('Delete', {
|
||||||
callback: function(){
|
callback: function(){ dialog.close() },
|
||||||
// XXX
|
|
||||||
dialog.close()
|
|
||||||
},
|
|
||||||
timeout: that.config['confirm-delete-timeout'] || 2000,
|
timeout: that.config['confirm-delete-timeout'] || 2000,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
cls: 'metadata-view',
|
cls: 'metadata-view',
|
||||||
})
|
})
|
||||||
|
// save the keys...
|
||||||
|
.on('close', function(){
|
||||||
|
// XXX
|
||||||
|
})
|
||||||
|
|
||||||
return dialog
|
return dialog
|
||||||
})],
|
})],
|
||||||
@ -1193,28 +1198,72 @@ var KeyboardActions = actions.Actions({
|
|||||||
|
|
||||||
return dialog
|
return dialog
|
||||||
})],
|
})],
|
||||||
// XXX need a way to abort edits...
|
// XXX revise...
|
||||||
// XXX need a way to set a special '*' key...
|
// - '*' toggle
|
||||||
|
// - done/cancel
|
||||||
editKeyboardModeDroppedKeys: ['- Interface/Dropped keys...',
|
editKeyboardModeDroppedKeys: ['- Interface/Dropped keys...',
|
||||||
widgets.makeUIDialog(function(mode){
|
widgets.makeUIDialog(function(mode){
|
||||||
var that = this
|
var that = this
|
||||||
|
//var abort = false
|
||||||
|
var abort = true
|
||||||
|
var drop = that.keybindings[mode].drop || []
|
||||||
|
|
||||||
// XXX need a way to set a special '*' key...
|
return browse.makeLister(null,
|
||||||
var dialog = browse.makeListEditor(function(keys){
|
function(path, make){
|
||||||
|
var drop_all
|
||||||
|
|
||||||
|
// '*' 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,
|
||||||
|
})
|
||||||
|
|
||||||
|
make('---')
|
||||||
|
|
||||||
|
// the list editor...
|
||||||
|
make.EditableList(function(keys){
|
||||||
// get...
|
// get...
|
||||||
if(keys === undefined){
|
if(keys === undefined){
|
||||||
return that.keybindings[mode].drop || []
|
return drop && drop != '*' ? drop : []
|
||||||
|
|
||||||
// set...
|
// set...
|
||||||
} else {
|
} else {
|
||||||
that.keybindings[mode].drop = keys
|
drop = drop_all ? '*' : keys
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
unique: true,
|
unique: true
|
||||||
})
|
})
|
||||||
|
|
||||||
return dialog
|
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){
|
function(text, options){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// make Editable on select element...
|
||||||
|
//
|
||||||
|
// options format:
|
||||||
|
// {
|
||||||
|
// clear_on_edit: true,
|
||||||
|
//
|
||||||
|
// editaborted:
|
||||||
|
// editdone:
|
||||||
|
//
|
||||||
|
// action: <bool>,
|
||||||
|
// }
|
||||||
// XXX
|
// XXX
|
||||||
Items.Editable =
|
Items.Editable =
|
||||||
function(text, options){
|
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
|
// XXX
|
||||||
@ -145,39 +179,87 @@ function(text, options){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Make list of elements...
|
||||||
|
//
|
||||||
Items.List =
|
Items.List =
|
||||||
function(list, options){
|
function(list, options){
|
||||||
var make = this
|
var make = this
|
||||||
|
var res = []
|
||||||
list.forEach(function(e){
|
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:
|
// options format:
|
||||||
// {
|
// {
|
||||||
|
// new_button: <text>|<bool>,
|
||||||
|
//
|
||||||
|
// // if true, disable delete item button...
|
||||||
// no_delete_button: <bool>,
|
// no_delete_button: <bool>,
|
||||||
//
|
//
|
||||||
// editdone: function(lst){ .. },
|
// length_limit: <number>,
|
||||||
// // XXX
|
//
|
||||||
// changed: function(lst){ .. },
|
// // 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,
|
// 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
|
// this can be disabled by setting .no_delete_button to false in
|
||||||
// options...
|
// options...
|
||||||
|
//
|
||||||
|
// XXX add sort buttons: up/down/top/bottom...
|
||||||
Items.EditableList =
|
Items.EditableList =
|
||||||
function(list, options){
|
function(list, options){
|
||||||
var make = this
|
var make = this
|
||||||
var dialog = make.dialog
|
var dialog = make.dialog
|
||||||
|
|
||||||
var editdone = options.editdone
|
var write = function(list, lst){
|
||||||
// XXX
|
// write back the list...
|
||||||
var changed = options.changed
|
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 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 ?
|
var lst = list instanceof Function ?
|
||||||
list()
|
list()
|
||||||
: list
|
: list
|
||||||
@ -185,23 +267,25 @@ function(list, options){
|
|||||||
// view objects...
|
// view objects...
|
||||||
lst = !editable ? Object.keys(lst) : lst.slice()
|
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
|
!options.no_delete_button
|
||||||
&& buttons.push(Buttons.markForRemoval(to_remove))
|
&& buttons.push(Buttons.markForRemoval(to_remove))
|
||||||
|
|
||||||
// XXX make this generic...
|
|
||||||
var _makeEditable = function(elem){
|
// make the list...
|
||||||
return $(elem).find('.text')
|
var res = make.List(lst, options).toArray()
|
||||||
.makeEditable({
|
|
||||||
activate: true,
|
// new button...
|
||||||
|
var new_button = options.new_button || true
|
||||||
|
new_button = new_button === true ? 'New...' : new_button
|
||||||
|
res.push(make.Editable(
|
||||||
|
new_button,
|
||||||
|
{
|
||||||
|
action: true,
|
||||||
clear_on_edit: true,
|
clear_on_edit: true,
|
||||||
blur_on_abort: false,
|
|
||||||
blur_on_commit: false,
|
|
||||||
})
|
|
||||||
.on('edit-aborted', function(){
|
|
||||||
dialog.select(null)
|
|
||||||
dialog.update()
|
|
||||||
})
|
})
|
||||||
|
// update list on edit done...
|
||||||
.on('edit-done', function(evt, text){
|
.on('edit-done', function(evt, text){
|
||||||
var txt = $(this).text()
|
var txt = $(this).text()
|
||||||
|
|
||||||
@ -215,7 +299,8 @@ function(list, options){
|
|||||||
if(options.length_limit
|
if(options.length_limit
|
||||||
&& (lst.length >= options.length_limit)){
|
&& (lst.length >= options.length_limit)){
|
||||||
|
|
||||||
options.callback && options.callback.call(dialog, txt)
|
options.overflow
|
||||||
|
&& options.overflow.call(dialog, txt)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -245,44 +330,21 @@ function(list, options){
|
|||||||
: undefined)
|
: undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
changed
|
write(list, lst)
|
||||||
&& changed(lst)
|
|
||||||
|
|
||||||
// update the list data...
|
|
||||||
//dialog.options.data = lst.concat(new_button ? [ new_button ] : [])
|
|
||||||
|
|
||||||
// update list and select new value...
|
// update list and select new value...
|
||||||
dialog.update()
|
dialog.update()
|
||||||
.done(function(){
|
.done(function(){
|
||||||
dialog.select('"'+txt+'"')
|
dialog.select('"'+txt+'"')
|
||||||
})
|
})
|
||||||
})
|
}))
|
||||||
}
|
|
||||||
|
|
||||||
// make the list...
|
|
||||||
make.List(lst, options)
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
})
|
|
||||||
|
|
||||||
// dialog handlers...
|
// dialog handlers...
|
||||||
|
// NOTE: we bind these only once per dialog...
|
||||||
|
if(dialog.__editable_list_handlers == null){
|
||||||
|
dialog.__editable_list_handlers = true
|
||||||
dialog
|
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)...
|
// update the striked-out items (to_remove)...
|
||||||
.on('update', function(){
|
.on('update', function(){
|
||||||
to_remove.forEach(function(e){
|
to_remove.forEach(function(e){
|
||||||
@ -307,15 +369,15 @@ function(list, options){
|
|||||||
lst.sort(options.sort !== true ? options.sort : undefined)
|
lst.sort(options.sort !== true ? options.sort : undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
write
|
write(list, lst)
|
||||||
&& write(lst)
|
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return $(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
// Browse item buttons (button constructors)...
|
// 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
|
// 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
|
// XXX should we have things like ctrl-<number> for fast selection
|
||||||
// in filter mode???
|
// in filter mode???
|
||||||
keybindings: {
|
keybindings: {
|
||||||
// XXX this is the same as FullPathEdit, should we combine the two?
|
|
||||||
ItemEdit: {
|
ItemEdit: {
|
||||||
pattern: '.list .text[contenteditable]',
|
pattern: '.list .text[contenteditable]',
|
||||||
|
|
||||||
// keep text editing action from affecting the selection...
|
// keep text editing action from affecting the selection...
|
||||||
drop: '*',
|
drop: '*',
|
||||||
|
|
||||||
// XXX not sure about this...
|
// XXX this does not seem to work...
|
||||||
Up: 'NEXT',
|
Up: 'NEXT!',
|
||||||
Down: 'NEXT',
|
Down: 'NEXT!',
|
||||||
|
Tab: 'NEXT!',
|
||||||
|
shift_Tab: 'NEXT!',
|
||||||
|
|
||||||
Enter: 'push!',
|
Enter: 'push!',
|
||||||
Esc: 'update!',
|
Esc: 'update!',
|
||||||
@ -686,8 +750,10 @@ var BrowserPrototype = {
|
|||||||
// keep text editing action from affecting the selection...
|
// keep text editing action from affecting the selection...
|
||||||
drop: '*',
|
drop: '*',
|
||||||
|
|
||||||
Up: 'NEXT',
|
Up: 'NEXT!',
|
||||||
Down: 'NEXT',
|
Down: 'NEXT!',
|
||||||
|
Tab: 'NEXT!',
|
||||||
|
shift_Tab: 'NEXT!',
|
||||||
|
|
||||||
Enter: 'push!',
|
Enter: 'push!',
|
||||||
Esc: 'stopFilter!',
|
Esc: 'stopFilter!',
|
||||||
@ -1390,6 +1456,9 @@ var BrowserPrototype = {
|
|||||||
.append(p)
|
.append(p)
|
||||||
|
|
||||||
res.addClass([
|
res.addClass([
|
||||||
|
// XXX use the same algorithm as .select(..)
|
||||||
|
selection && res.text() == selection ? 'selected' : '',
|
||||||
|
|
||||||
!traversable ? 'not-traversable' : '',
|
!traversable ? 'not-traversable' : '',
|
||||||
disabled ? 'disabled' : '',
|
disabled ? 'disabled' : '',
|
||||||
hidden ? 'hidden' : '',
|
hidden ? 'hidden' : '',
|
||||||
@ -1523,7 +1592,6 @@ var BrowserPrototype = {
|
|||||||
|
|
||||||
// select the item...
|
// select the item...
|
||||||
if(selection){
|
if(selection){
|
||||||
//that.select(selection)
|
|
||||||
that.select('"'+ selection +'"')
|
that.select('"'+ selection +'"')
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2715,13 +2783,13 @@ var BrowserPrototype = {
|
|||||||
parent.append(dom)
|
parent.append(dom)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// load the initial state...
|
||||||
|
that.update(options.path || that.path || '/')
|
||||||
|
|
||||||
// Select the default path...
|
// Select the default path...
|
||||||
//
|
//
|
||||||
// NOTE: this may not work when the dialog is loaded async...
|
// NOTE: this may not work when the dialog is loaded async...
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
// load the initial state...
|
|
||||||
that.update(options.path || that.path || '/')
|
|
||||||
|
|
||||||
// in case we have a manually selected item but that was
|
// in case we have a manually selected item but that was
|
||||||
// not aligned...
|
// not aligned...
|
||||||
that.selected && that.select()
|
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){
|
if(data !== keys && that.options.data[k] != null){
|
||||||
e.on('open', function(){
|
e.on('open', function(){
|
||||||
@ -3131,187 +3199,16 @@ module.makePathList = makeBrowserMaker(PathList)
|
|||||||
|
|
||||||
// Make an list/Array editor...
|
// Make an list/Array editor...
|
||||||
//
|
//
|
||||||
// Options format:
|
|
||||||
// {
|
|
||||||
// new_button: <text>|<bool>,
|
|
||||||
//
|
//
|
||||||
// length_limit: <number>,
|
// For options format see: List.EditableList(..)
|
||||||
//
|
|
||||||
// // 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...
|
|
||||||
var makeListEditor =
|
var makeListEditor =
|
||||||
module.makeListEditor =
|
module.makeListEditor =
|
||||||
function(list, options){
|
function(list, options){
|
||||||
options = options || {}
|
return makeLister(null,
|
||||||
|
function(path, make){
|
||||||
var new_button = options.new_button || true
|
make.EditableList(list, options)
|
||||||
new_button = new_button === true ? 'New...' : new_button
|
},
|
||||||
|
options)
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user