mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 02:10:08 +00:00
added item keyboard shortcuts + cleanup and some refactoring...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
5d35ae1fb0
commit
fc8c745ac3
@ -44,6 +44,12 @@ body {
|
|||||||
overflow: visible;
|
overflow: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.browse-widget .list .text .key-hint {
|
||||||
|
text-decoration-skip-ink: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* XXX stub...
|
/* XXX stub...
|
||||||
.browse-widget:not(.flat) .list .text:first-child:before {
|
.browse-widget:not(.flat) .list .text:first-child:before {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@ -186,7 +192,7 @@ requirejs([
|
|||||||
dialog = browser.Browser(function(make){
|
dialog = browser.Browser(function(make){
|
||||||
make(['list', 'of', 'text'])
|
make(['list', 'of', 'text'])
|
||||||
make.group(
|
make.group(
|
||||||
make('group item 0',
|
make('$group item 0',
|
||||||
function(){ console.log('###', ...arguments) }),
|
function(){ console.log('###', ...arguments) }),
|
||||||
'group item 1 (bare)')
|
'group item 1 (bare)')
|
||||||
// XXX Q: should we show only one if multiple lines are in sequence???
|
// XXX Q: should we show only one if multiple lines are in sequence???
|
||||||
@ -198,11 +204,11 @@ requirejs([
|
|||||||
make(2)
|
make(2)
|
||||||
}))
|
}))
|
||||||
// basic nested list...
|
// basic nested list...
|
||||||
make.nest('nested', [
|
make.nest('$nested', [
|
||||||
make('moo', {disabled: true}),
|
make('moo', {disabled: true}),
|
||||||
2,
|
2,
|
||||||
// XXX this is not supported by .map(..)...
|
// XXX this is not supported by .map(..)...
|
||||||
make.nest('nested', browser.Browser(function(make){
|
make.nest('$ne$sted', browser.Browser(function(make){
|
||||||
make('ab')
|
make('ab')
|
||||||
})),
|
})),
|
||||||
])
|
])
|
||||||
|
|||||||
@ -436,21 +436,16 @@ function(event, {handler, action, default_item, filter, options={}, getter='sear
|
|||||||
// Make event method edit item...
|
// Make event method edit item...
|
||||||
//
|
//
|
||||||
// XXX should this .update()
|
// XXX should this .update()
|
||||||
var makeItemOptionEventMethod =
|
var makeItemEditEventMethod =
|
||||||
module.makeItemOptionEventMethod =
|
module.makeItemEditEventMethod =
|
||||||
function(event, action, {handler, default_item, filter, options, update=true}={}){
|
function(event, edit, {handler, default_item, filter, options}={}){
|
||||||
return makeItemEventMethod(event, {
|
return makeItemEventMethod(event, {
|
||||||
handler: function(evt, items){
|
handler: function(evt, items){
|
||||||
var that = this
|
var that = this
|
||||||
var change = false
|
|
||||||
items.forEach(function(item){
|
items.forEach(function(item){
|
||||||
change = action(item) !== false
|
edit(item)
|
||||||
handler
|
handler
|
||||||
&& handler.call(that, item) })
|
&& handler.call(that, item) }) },
|
||||||
// need to update for changes to show up...
|
|
||||||
update
|
|
||||||
&& change
|
|
||||||
&& this.update() },
|
|
||||||
default_item:
|
default_item:
|
||||||
default_item
|
default_item
|
||||||
|| function(){ return this.focused },
|
|| function(){ return this.focused },
|
||||||
@ -461,20 +456,20 @@ function(event, action, {handler, default_item, filter, options, update=true}={}
|
|||||||
//
|
//
|
||||||
var makeItemOptionOnEventMethod =
|
var makeItemOptionOnEventMethod =
|
||||||
module.makeItemOptionOnEventMethod =
|
module.makeItemOptionOnEventMethod =
|
||||||
function(event, attr, {handler, default_item, filter, options, update=true}={}){
|
function(event, attr, {handler, default_item, filter, options}={}){
|
||||||
return makeItemOptionEventMethod(event,
|
return makeItemEditEventMethod(event,
|
||||||
function(item){
|
function(item){
|
||||||
return item[attr] = true },
|
return item[attr] = true },
|
||||||
{ handler, default_item, filter, options, update }) }
|
{ handler, default_item, filter, options }) }
|
||||||
var makeItemOptionOffEventMethod =
|
var makeItemOptionOffEventMethod =
|
||||||
module.makeItemOptionOffEventMethod =
|
module.makeItemOptionOffEventMethod =
|
||||||
function(event, attr, {handler, default_item, filter, options, update=true}={}){
|
function(event, attr, {handler, default_item, filter, options}={}){
|
||||||
return makeItemOptionEventMethod(event,
|
return makeItemEditEventMethod(event,
|
||||||
function(item){
|
function(item){
|
||||||
change = !!item[attr]
|
change = !!item[attr]
|
||||||
delete item[attr]
|
delete item[attr]
|
||||||
return change },
|
return change },
|
||||||
{ handler, default_item, filter, options, update }) }
|
{ handler, default_item, filter, options }) }
|
||||||
|
|
||||||
|
|
||||||
// Generate item event/state toggler...
|
// Generate item event/state toggler...
|
||||||
@ -638,6 +633,8 @@ var BaseBrowserPrototype = {
|
|||||||
options: {
|
options: {
|
||||||
// If true item keys must be unique...
|
// If true item keys must be unique...
|
||||||
uniqueKeys: false,
|
uniqueKeys: false,
|
||||||
|
|
||||||
|
//skipDisabledMode: 'node',
|
||||||
},
|
},
|
||||||
|
|
||||||
// parent widget object...
|
// parent widget object...
|
||||||
@ -779,6 +776,7 @@ var BaseBrowserPrototype = {
|
|||||||
.select(value) },
|
.select(value) },
|
||||||
|
|
||||||
|
|
||||||
|
// XXX should this return a list or a string???
|
||||||
// XXX should this be cached???
|
// XXX should this be cached???
|
||||||
// XXX should this set .options???
|
// XXX should this set .options???
|
||||||
// XXX need to normalizePath(..)
|
// XXX need to normalizePath(..)
|
||||||
@ -998,7 +996,8 @@ var BaseBrowserPrototype = {
|
|||||||
// // XXX not yet supported...
|
// // XXX not yet supported...
|
||||||
// skipInlined: <bool>,
|
// skipInlined: <bool>,
|
||||||
//
|
//
|
||||||
// skipDisabled: <bool>,
|
// skipDisabledMode: 'node' | 'branch',
|
||||||
|
// skipDisabled: <bool> | 'node' | 'branch',
|
||||||
//
|
//
|
||||||
// // Reverse iteration order...
|
// // Reverse iteration order...
|
||||||
// //
|
// //
|
||||||
@ -1079,7 +1078,9 @@ var BaseBrowserPrototype = {
|
|||||||
|| args[0] == null)) ?
|
|| args[0] == null)) ?
|
||||||
args.shift()
|
args.shift()
|
||||||
: null
|
: null
|
||||||
options = args.shift() || {}
|
options = Object.assign(
|
||||||
|
Object.create(this.options || {}),
|
||||||
|
args.shift() || {})
|
||||||
|
|
||||||
// get/build context...
|
// get/build context...
|
||||||
var context = args.shift()
|
var context = args.shift()
|
||||||
@ -1094,7 +1095,12 @@ var BaseBrowserPrototype = {
|
|||||||
var iterateCollapsed = options.iterateAll || options.iterateCollapsed
|
var iterateCollapsed = options.iterateAll || options.iterateCollapsed
|
||||||
var skipNested = !options.iterateAll && options.skipNested
|
var skipNested = !options.iterateAll && options.skipNested
|
||||||
var skipInlined = !options.iterateAll && options.skipInlined
|
var skipInlined = !options.iterateAll && options.skipInlined
|
||||||
|
|
||||||
var skipDisabled = !options.iterateAll && options.skipDisabled
|
var skipDisabled = !options.iterateAll && options.skipDisabled
|
||||||
|
skipDisabled = skipDisabled === true ?
|
||||||
|
(options.skipDisabledMode || 'node')
|
||||||
|
: skipDisabled
|
||||||
|
|
||||||
var reverse = options.reverse === true ?
|
var reverse = options.reverse === true ?
|
||||||
(options.defaultReverse || 'tree')
|
(options.defaultReverse || 'tree')
|
||||||
: options.reverse
|
: options.reverse
|
||||||
@ -1118,8 +1124,8 @@ var BaseBrowserPrototype = {
|
|||||||
// skip non-iterable items...
|
// skip non-iterable items...
|
||||||
if(!iterateNonIterable && node.noniterable){
|
if(!iterateNonIterable && node.noniterable){
|
||||||
return state }
|
return state }
|
||||||
// skip disabled...
|
// skip disabled branch...
|
||||||
if(skipDisabled && node.disabled){
|
if(skipDisabled == 'branch' && node.disabled){
|
||||||
return state }
|
return state }
|
||||||
|
|
||||||
// XXX BUG?: doNested(false) will not count any of the
|
// XXX BUG?: doNested(false) will not count any of the
|
||||||
@ -1224,19 +1230,22 @@ var BaseBrowserPrototype = {
|
|||||||
&& doNested()
|
&& doNested()
|
||||||
|| [],
|
|| [],
|
||||||
// do element...
|
// do element...
|
||||||
func ?
|
!(skipDisabled && node.disabled) ?
|
||||||
(func.call(that,
|
(func ?
|
||||||
...(inline ?
|
(func.call(that,
|
||||||
[null, context.index]
|
...(inline ?
|
||||||
: [node, context.index++]),
|
[null, context.index]
|
||||||
p,
|
: [node, context.index++]),
|
||||||
// NOTE: when calling this it is the
|
p,
|
||||||
// responsibility of the caller to return
|
// NOTE: when calling this it is the
|
||||||
// the result to be added to state...
|
// responsibility of the caller to return
|
||||||
doNested,
|
// the result to be added to state...
|
||||||
stop,
|
doNested,
|
||||||
children) || [])
|
stop,
|
||||||
: [node],
|
children) || [])
|
||||||
|
: [node])
|
||||||
|
// element is disabled -> handle children...
|
||||||
|
: [],
|
||||||
// normal order -> do children...
|
// normal order -> do children...
|
||||||
children
|
children
|
||||||
&& nested === false
|
&& nested === false
|
||||||
@ -1417,6 +1426,8 @@ var BaseBrowserPrototype = {
|
|||||||
|| args[0] === undefined) ?
|
|| args[0] === undefined) ?
|
||||||
args.shift()
|
args.shift()
|
||||||
: undefined
|
: undefined
|
||||||
|
// NOTE: we do not inherit options from this.options here is it
|
||||||
|
// will be done in .walk(..)
|
||||||
options = args.shift() || {}
|
options = args.shift() || {}
|
||||||
options = !options.defaultReverse ?
|
options = !options.defaultReverse ?
|
||||||
Object.assign({},
|
Object.assign({},
|
||||||
@ -1642,6 +1653,8 @@ var BaseBrowserPrototype = {
|
|||||||
|| args[0] === undefined) ?
|
|| args[0] === undefined) ?
|
||||||
args.shift()
|
args.shift()
|
||||||
: undefined
|
: undefined
|
||||||
|
// NOTE: we do not inherit options from this.options here is it
|
||||||
|
// will be done in .walk(..)
|
||||||
options = args.shift() || {}
|
options = args.shift() || {}
|
||||||
var context = args.shift()
|
var context = args.shift()
|
||||||
|
|
||||||
@ -1812,6 +1825,8 @@ var BaseBrowserPrototype = {
|
|||||||
args.shift()
|
args.shift()
|
||||||
// XXX return format...
|
// XXX return format...
|
||||||
: function(e, i, p){ return e }
|
: function(e, i, p){ return e }
|
||||||
|
// NOTE: we do not inherit options from this.options here is it
|
||||||
|
// will be done in .walk(..)
|
||||||
options = args.pop() || {}
|
options = args.pop() || {}
|
||||||
|
|
||||||
// special case: path pattern -> include collapsed elements...
|
// special case: path pattern -> include collapsed elements...
|
||||||
@ -2006,6 +2021,9 @@ var BaseBrowserPrototype = {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//__make__: function(item){
|
||||||
|
//},
|
||||||
|
|
||||||
// Make .items and .index...
|
// Make .items and .index...
|
||||||
//
|
//
|
||||||
// .make()
|
// .make()
|
||||||
@ -2040,7 +2058,9 @@ var BaseBrowserPrototype = {
|
|||||||
// : opts)
|
// : opts)
|
||||||
make: function(options){
|
make: function(options){
|
||||||
var that = this
|
var that = this
|
||||||
options = Object.assign(Object.create(this.options || {}), options || {})
|
options = Object.assign(
|
||||||
|
Object.create(this.options || {}),
|
||||||
|
options || {})
|
||||||
|
|
||||||
var items = this.items = []
|
var items = this.items = []
|
||||||
|
|
||||||
@ -2131,6 +2151,10 @@ var BaseBrowserPrototype = {
|
|||||||
&& (item.children.parent = this)
|
&& (item.children.parent = this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// user extended make...
|
||||||
|
this.__make__
|
||||||
|
&& this.__make__(item)
|
||||||
|
|
||||||
// store the item...
|
// store the item...
|
||||||
items.push(item)
|
items.push(item)
|
||||||
ids.add(key)
|
ids.add(key)
|
||||||
@ -2176,6 +2200,7 @@ var BaseBrowserPrototype = {
|
|||||||
&& Object.assign(e,
|
&& Object.assign(e,
|
||||||
old_index[id],
|
old_index[id],
|
||||||
e) })
|
e) })
|
||||||
|
|
||||||
return this
|
return this
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -2264,6 +2289,7 @@ var BaseBrowserPrototype = {
|
|||||||
// // NOTE: the only constrain on to/from is that from must be
|
// // NOTE: the only constrain on to/from is that from must be
|
||||||
// // less or equal to to, other than that it's fair game,
|
// // less or equal to to, other than that it's fair game,
|
||||||
// // i.e. overflowing values (<0 or >length) are allowed.
|
// // i.e. overflowing values (<0 or >length) are allowed.
|
||||||
|
// // NOTE: these are not inherited from .options...
|
||||||
// from: <index> | <query>,
|
// from: <index> | <query>,
|
||||||
// to: <index> | <query>,
|
// to: <index> | <query>,
|
||||||
// around: <index> | <query>,
|
// around: <index> | <query>,
|
||||||
@ -2665,24 +2691,14 @@ var BaseBrowserPrototype = {
|
|||||||
function(){ return this.focused || 0 },
|
function(){ return this.focused || 0 },
|
||||||
false),
|
false),
|
||||||
// selection...
|
// selection...
|
||||||
// XXX these should skip disabled... option???
|
select: makeItemOptionOnEventMethod('select', 'selected'),
|
||||||
select: makeItemEventMethod('select', {
|
deselect: makeItemOptionOffEventMethod('deselect', 'selected'),
|
||||||
handler: function(evt, items){
|
|
||||||
items.forEach(function(item){
|
|
||||||
item.selected = true }) },
|
|
||||||
// XXX is this a good default???
|
|
||||||
default_item: function(){ return this.focused } }),
|
|
||||||
deselect: makeItemEventMethod('deselect', {
|
|
||||||
handler: function(evt, items){
|
|
||||||
items.forEach(function(item){
|
|
||||||
delete item.selected }) },
|
|
||||||
default_item: function(){ return this.focused } }),
|
|
||||||
toggleSelect: makeItemEventToggler(
|
toggleSelect: makeItemEventToggler(
|
||||||
'selected',
|
'selected',
|
||||||
'select', 'deselect',
|
'select', 'deselect',
|
||||||
'focused'),
|
'focused'),
|
||||||
// topology...
|
// topology...
|
||||||
collapse: makeItemOptionOnEventMethod('expand', 'collapsed', {
|
collapse: makeItemOptionOnEventMethod('collapse', 'collapsed', {
|
||||||
filter: function(elem){ return elem.value && elem.children },
|
filter: function(elem){ return elem.value && elem.children },
|
||||||
options: {iterateCollapsed: true}, }),
|
options: {iterateCollapsed: true}, }),
|
||||||
expand: makeItemOptionOffEventMethod('expand', 'collapsed', {
|
expand: makeItemOptionOffEventMethod('expand', 'collapsed', {
|
||||||
@ -2748,9 +2764,15 @@ var BaseBrowserPrototype = {
|
|||||||
: full
|
: full
|
||||||
this
|
this
|
||||||
.run(function(){
|
.run(function(){
|
||||||
full && this.make(options) })
|
full
|
||||||
|
&& this.make(options)
|
||||||
|
this.preRender()
|
||||||
|
})
|
||||||
.render(options) }),
|
.render(options) }),
|
||||||
|
// this is triggered by .update() just before render...
|
||||||
|
preRender: makeEventMethod('preRender'),
|
||||||
|
|
||||||
|
|
||||||
// NOTE: if given a path that does not exist this will try and load
|
// NOTE: if given a path that does not exist this will try and load
|
||||||
// the longest existing sub-path...
|
// the longest existing sub-path...
|
||||||
// XXX should level drawing be a feature of the browser or the
|
// XXX should level drawing be a feature of the browser or the
|
||||||
@ -2799,13 +2821,14 @@ object.makeConstructor('BaseBrowser',
|
|||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
// Get actual .item DOM element...
|
// Get actual .item DOM element...
|
||||||
|
//
|
||||||
|
// XXX should this be a prop in the element???
|
||||||
var getElem = function(elem){
|
var getElem = function(elem){
|
||||||
elem = elem.dom || elem
|
elem = elem.dom || elem
|
||||||
return elem.classList.contains('list') ?
|
return elem.classList.contains('list') ?
|
||||||
elem.querySelector('.item')
|
elem.querySelector('.item')
|
||||||
: elem }
|
: elem }
|
||||||
|
|
||||||
|
|
||||||
// Make page navigation method...
|
// Make page navigation method...
|
||||||
//
|
//
|
||||||
// XXX this behaves in an odd way with .options.scrollBehavior = 'smooth'
|
// XXX this behaves in an odd way with .options.scrollBehavior = 'smooth'
|
||||||
@ -2826,14 +2849,38 @@ var focusPage = function(direction){
|
|||||||
// focus top of current page...
|
// focus top of current page...
|
||||||
: this.focus(target) } }
|
: this.focus(target) } }
|
||||||
|
|
||||||
|
// Update element class...
|
||||||
|
//
|
||||||
|
// XXX should we use .renderItem(...) for this???
|
||||||
|
var updateElemClass = function(action, cls, handler){
|
||||||
|
return function(evt, elem, ...args){
|
||||||
|
elem
|
||||||
|
&& getElem(elem).classList[action](cls)
|
||||||
|
return handler
|
||||||
|
&& handler.call(this, evt, elem, ...args)} }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
var KEYBOARD_CONFIG =
|
var KEYBOARD_CONFIG =
|
||||||
module.KEYBOARD_CONFIG = {
|
module.KEYBOARD_CONFIG = {
|
||||||
// XXX
|
ItemEdit: {
|
||||||
|
pattern: '.list .text[contenteditable]',
|
||||||
|
|
||||||
|
// XXX
|
||||||
|
},
|
||||||
|
|
||||||
|
PathEdit: {
|
||||||
|
pattern: '.path[contenteditable]',
|
||||||
|
|
||||||
|
// XXX
|
||||||
|
},
|
||||||
|
|
||||||
Filter: {
|
Filter: {
|
||||||
|
pattern: '.path div.cur[contenteditable]',
|
||||||
|
|
||||||
|
// XXX
|
||||||
},
|
},
|
||||||
|
|
||||||
General: {
|
General: {
|
||||||
@ -2851,6 +2898,17 @@ module.KEYBOARD_CONFIG = {
|
|||||||
Home: 'focus: "first"',
|
Home: 'focus: "first"',
|
||||||
End: 'focus: "last"',
|
End: 'focus: "last"',
|
||||||
|
|
||||||
|
'#1': 'focus: 0',
|
||||||
|
'#2': 'focus: 1',
|
||||||
|
'#3': 'focus: 2',
|
||||||
|
'#4': 'focus: 3',
|
||||||
|
'#5': 'focus: 4',
|
||||||
|
'#6': 'focus: 5',
|
||||||
|
'#7': 'focus: 6',
|
||||||
|
'#8': 'focus: 7',
|
||||||
|
'#9': 'focus: 8',
|
||||||
|
'#0': 'focus: 9',
|
||||||
|
|
||||||
|
|
||||||
Enter: 'open',
|
Enter: 'open',
|
||||||
|
|
||||||
@ -2861,7 +2919,15 @@ module.KEYBOARD_CONFIG = {
|
|||||||
|
|
||||||
// NOTE: do not bind this key, it is used to jump to buttons
|
// NOTE: do not bind this key, it is used to jump to buttons
|
||||||
// via tabindex...
|
// via tabindex...
|
||||||
Tab: 'NEXT',
|
Tab: 'NEXT!',
|
||||||
|
},
|
||||||
|
|
||||||
|
// XXX need to keep this local to each dialog instance...
|
||||||
|
ItemShortcuts: {
|
||||||
|
doc: 'Item shortcuts',
|
||||||
|
pattern: '*',
|
||||||
|
|
||||||
|
// this is where item-specific shortcuts will be set...
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2962,10 +3028,10 @@ var BrowserPrototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
__keyboard_config: KEYBOARD_CONFIG,
|
// Keyboard...
|
||||||
|
__keyboard_config: Object.assign({}, KEYBOARD_CONFIG),
|
||||||
get keybindings(){
|
get keybindings(){
|
||||||
return this.__keyboard_config },
|
return this.__keyboard_config },
|
||||||
|
|
||||||
__keyboard_object: null,
|
__keyboard_object: null,
|
||||||
get keyboard(){
|
get keyboard(){
|
||||||
var that = this
|
var that = this
|
||||||
@ -3009,7 +3075,7 @@ var BrowserPrototype = {
|
|||||||
: this.container.appendChild(value))
|
: this.container.appendChild(value))
|
||||||
this.__dom = value },
|
this.__dom = value },
|
||||||
|
|
||||||
// Extended .get(..) to support:
|
// Extended .search(..) to support:
|
||||||
// - 'pagetop'
|
// - 'pagetop'
|
||||||
// - 'pagebottom'
|
// - 'pagebottom'
|
||||||
// - searching for items via DOM / jQuery objects
|
// - searching for items via DOM / jQuery objects
|
||||||
@ -3017,14 +3083,14 @@ var BrowserPrototype = {
|
|||||||
// ...should we add containment search -- match closest item containing obj...
|
// ...should we add containment search -- match closest item containing obj...
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// .get('pagetop'[, offset] ..)
|
// .search('pagetop'[, offset] ..)
|
||||||
//
|
//
|
||||||
// .get('pagebottom'[, offset] ..)
|
// .search('pagebottom'[, offset] ..)
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// XXX add support for pixel offset...
|
// XXX add support for pixel offset...
|
||||||
// XXX
|
// XXX
|
||||||
get: function(pattern){
|
search: function(pattern){
|
||||||
var args = [...arguments].slice(1)
|
var args = [...arguments].slice(1)
|
||||||
var p = pattern
|
var p = pattern
|
||||||
|
|
||||||
@ -3050,9 +3116,12 @@ var BrowserPrototype = {
|
|||||||
&& Math.round(edom.offsetTop + edom.offsetHeight)
|
&& Math.round(edom.offsetTop + edom.offsetHeight)
|
||||||
- Math.max(0, st + H + offset) <= 0
|
- Math.max(0, st + H + offset) <= 0
|
||||||
&& stop(e) },
|
&& stop(e) },
|
||||||
{ reverse: pos == 'bottom' ?
|
{
|
||||||
'flat'
|
reverse: pos == 'bottom' ?
|
||||||
: false })
|
'flat'
|
||||||
|
: false,
|
||||||
|
skipDisabled: true,
|
||||||
|
})
|
||||||
.run(function(){
|
.run(function(){
|
||||||
return this instanceof Array ?
|
return this instanceof Array ?
|
||||||
undefined
|
undefined
|
||||||
@ -3079,7 +3148,7 @@ var BrowserPrototype = {
|
|||||||
: pattern
|
: pattern
|
||||||
|
|
||||||
// call parent...
|
// call parent...
|
||||||
return object.parent(BrowserPrototype.get, this).call(this, pattern, ...args) },
|
return object.parent(BrowserPrototype.search, this).call(this, pattern, ...args) },
|
||||||
|
|
||||||
|
|
||||||
// Element renderers...
|
// Element renderers...
|
||||||
@ -3312,6 +3381,7 @@ var BrowserPrototype = {
|
|||||||
//
|
//
|
||||||
// XXX should we trigger the DOM event or the browser event???
|
// XXX should we trigger the DOM event or the browser event???
|
||||||
// XXX should buttoms be active in disabled state???
|
// XXX should buttoms be active in disabled state???
|
||||||
|
// XXX replace $X with <u>X</u> but only where the X is in item.keys
|
||||||
renderItem: function(item, i, context){
|
renderItem: function(item, i, context){
|
||||||
var that = this
|
var that = this
|
||||||
var options = context.options || this.options
|
var options = context.options || this.options
|
||||||
@ -3320,7 +3390,7 @@ var BrowserPrototype = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// special-case: item shorthands...
|
// special-case: item shorthands...
|
||||||
if(item.value in options.elementShorthand){
|
if(item.value in (options.elementShorthand || {})){
|
||||||
// XXX need to merge and not overwrite -- revise...
|
// XXX need to merge and not overwrite -- revise...
|
||||||
Object.assign(item, options.elementShorthand[item.value])
|
Object.assign(item, options.elementShorthand[item.value])
|
||||||
|
|
||||||
@ -3368,6 +3438,17 @@ var BrowserPrototype = {
|
|||||||
&& (item.value instanceof Array ? item.value : [item.value])
|
&& (item.value instanceof Array ? item.value : [item.value])
|
||||||
// XXX handle $keys and other stuff...
|
// XXX handle $keys and other stuff...
|
||||||
.map(function(v){
|
.map(function(v){
|
||||||
|
// handle key-shortcuts $K...
|
||||||
|
v = typeof(v) == typeof('str') ?
|
||||||
|
v.replace(/\$\w/g,
|
||||||
|
function(k){
|
||||||
|
k = k[1]
|
||||||
|
return (item.keys || [])
|
||||||
|
.includes(that.keyboard.normalizeKey(k)) ?
|
||||||
|
`<u class="key-hint">${k}</u>`
|
||||||
|
: k })
|
||||||
|
: v
|
||||||
|
|
||||||
var value = document.createElement('span')
|
var value = document.createElement('span')
|
||||||
value.classList.add('text')
|
value.classList.add('text')
|
||||||
value.innerHTML = v != null ?
|
value.innerHTML = v != null ?
|
||||||
@ -3462,6 +3543,51 @@ var BrowserPrototype = {
|
|||||||
|
|
||||||
// Custom events handlers...
|
// Custom events handlers...
|
||||||
//
|
//
|
||||||
|
// NOTE: this will also kill any user-set keys for disabled/hidden items...
|
||||||
|
__preRender__: function(){
|
||||||
|
var that = this
|
||||||
|
// reset item shortcuts...
|
||||||
|
var shortcuts =
|
||||||
|
this.keybindings.ItemShortcuts =
|
||||||
|
Object.assign({}, KEYBOARD_CONFIG.ItemShortcuts)
|
||||||
|
|
||||||
|
var i = 0
|
||||||
|
this.map(function(e){
|
||||||
|
// shortcut number hint...
|
||||||
|
// NOTE: these are just hints, the actual keys are handled
|
||||||
|
// in .keybindings...
|
||||||
|
if(i < 10 && !e.disabled && !e.hidden){
|
||||||
|
var attrs = e.attrs = e.attrs || {}
|
||||||
|
attrs['shortcut-number'] = (++i) % 10
|
||||||
|
// cleanup...
|
||||||
|
} else {
|
||||||
|
delete (e.attrs || {})['shortcut-number']
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle item keys...
|
||||||
|
if(!e.disabled && !e.hidden){
|
||||||
|
;((e.value instanceof Array ?
|
||||||
|
e.value
|
||||||
|
: [e.value])
|
||||||
|
.join(' ')
|
||||||
|
// XXX this does not include non-English chars...
|
||||||
|
.match(/\$\w/g) || [])
|
||||||
|
.map(function(k){
|
||||||
|
k = that.keyboard.normalizeKey(k[1])
|
||||||
|
if(!shortcuts[k]){
|
||||||
|
shortcuts[k] = function(){ that.focus(e) }
|
||||||
|
var keys = e.keys = e.keys || []
|
||||||
|
keys.push(k)
|
||||||
|
} })
|
||||||
|
|
||||||
|
// cleanup...
|
||||||
|
// NOTE: this will also kill any user-set keys for disabled/hidden items...
|
||||||
|
} else {
|
||||||
|
delete e.keys
|
||||||
|
}
|
||||||
|
}, {skipDisabled: false})
|
||||||
|
},
|
||||||
|
|
||||||
// NOTE: element alignment is done via the browser focus mechanics...
|
// NOTE: element alignment is done via the browser focus mechanics...
|
||||||
__focus__: function(evt, elem){
|
__focus__: function(evt, elem){
|
||||||
var that = this
|
var that = this
|
||||||
@ -3471,15 +3597,8 @@ var BrowserPrototype = {
|
|||||||
// NOTE: we will not remove this class on blur as it keeps
|
// NOTE: we will not remove this class on blur as it keeps
|
||||||
// the selected element indicated...
|
// the selected element indicated...
|
||||||
.run(function(){
|
.run(function(){
|
||||||
// XXX scroll to element if it's out of bounds...
|
|
||||||
// XXX
|
|
||||||
|
|
||||||
that.dom
|
|
||||||
&& that.dom.querySelectorAll('.focused')
|
|
||||||
.forEach(function(e){
|
|
||||||
e.classList.remove('focused') })
|
|
||||||
this.classList.add('focused')
|
this.classList.add('focused')
|
||||||
|
// take care of visibility...
|
||||||
this.scrollIntoView({
|
this.scrollIntoView({
|
||||||
behavior: (that.options || {}).scrollBehavior || 'auto',
|
behavior: (that.options || {}).scrollBehavior || 'auto',
|
||||||
block: 'nearest',
|
block: 'nearest',
|
||||||
@ -3493,29 +3612,36 @@ var BrowserPrototype = {
|
|||||||
&& getElem(elem)
|
&& getElem(elem)
|
||||||
.run(function(){
|
.run(function(){
|
||||||
this.classList.remove('focused')
|
this.classList.remove('focused')
|
||||||
//this.blur()
|
// refocus the dialog...
|
||||||
that.dom
|
that.dom
|
||||||
&& that.dom.focus() }) },
|
&& that.dom.focus() }) },
|
||||||
|
|
||||||
// NOTE: these simply update the state...
|
// XXX should we only update the current elem???
|
||||||
__select__: function(){
|
__expand__: function(){ this.update() },
|
||||||
var selected = new Set(this.selected.map(getElem))
|
__collapse__: function(){ this.update() },
|
||||||
this.dom
|
|
||||||
&& this.dom.querySelectorAll('.selected')
|
__select__: updateElemClass('add', 'selected'),
|
||||||
.forEach(function(e){
|
__deselect__: updateElemClass('remove', 'selected'),
|
||||||
selected.has(e)
|
__disable__: updateElemClass('add', 'disabled'),
|
||||||
|| e.classList.remove('selected') })
|
__enable__: updateElemClass('remove', 'disabled'),
|
||||||
selected
|
__hide__: updateElemClass('add', 'hidden'),
|
||||||
.forEach(function(e){
|
__show__: updateElemClass('remove', 'hidden'),
|
||||||
e.classList.add('selected') }) },
|
|
||||||
__deselect__: function(evt, elem){
|
|
||||||
this.__select__() },
|
|
||||||
|
|
||||||
// Custom events...
|
// Custom events...
|
||||||
//
|
//
|
||||||
// XXX make this different from html event...
|
// XXX make this different from html event???
|
||||||
// XXX trigger this from kb handler...
|
// XXX trigger this from kb handler...
|
||||||
keyhandled: makeEventMethod('keyhandled', function(){
|
keyPress: makeEventMethod('keypress', function(){
|
||||||
|
}),
|
||||||
|
// XXX
|
||||||
|
menu: makeEventMethod('menu', function(){
|
||||||
|
}),
|
||||||
|
// XXX
|
||||||
|
copy: makeEventMethod('copy', function(){
|
||||||
|
}),
|
||||||
|
// XXX
|
||||||
|
paste: makeEventMethod('paste', function(){
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user