added button key shorthand + some tweaking + bugs...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2019-07-01 19:33:40 +03:00
parent 3634d40252
commit bf5fc8202e
2 changed files with 95 additions and 12 deletions

View File

@ -56,6 +56,11 @@ body {
text-decoration-skip-ink: none; text-decoration-skip-ink: none;
} }
/* show non-global key hint on buttons only when element is focused... */
.browse-widget .list .item:not(.focused) .button .key-hint:not(.global) {
text-decoration: none;
}
/* XXX foe some reason the shadows here are BELLOW the content... */ /* XXX foe some reason the shadows here are BELLOW the content... */
.browse-widget>.list { .browse-widget>.list {
box-shadow: box-shadow:
@ -183,6 +188,16 @@ requirejs([
//browser.items.DisplayFocusedPath, //browser.items.DisplayFocusedPath,
//null, //null,
function(make){ function(make){
make.nest(make.Heading('$Predefined Items'), [
make('Normal item'),
make.Heading('Heading'),
make.Confirm('Confirm',
function(){ console.log('confirm') },
function(){ console.log('reject') })
])
make.Separator()
make(['list', 'of', 'text']) make(['list', 'of', 'text'])
make.group( make.group(
make('$group item 0 (open event)', make('$group item 0 (open event)',

View File

@ -149,6 +149,19 @@ Items.group = function(...items){
// Place list in a sub-list of item... // Place list in a sub-list of item...
// //
// Examples:
// make.nest('literal header', [
// 'literal item',
// make('item'),
// ...
// ])
//
// make.nest(make('header'), [
// 'literal item',
// make('item'),
// ...
// ])
//
Items.nest = function(item, list, options){ Items.nest = function(item, list, options){
options = options || {} options = options || {}
//options = Object.assign(Object.create(this.options || {}), options || {}) //options = Object.assign(Object.create(this.options || {}), options || {})
@ -157,7 +170,9 @@ Items.nest = function(item, list, options){
collectItems(this, list) collectItems(this, list)
: list }, : list },
options) options)
return this(item, options) return item === this ?
((this.last().children = options.children), this)
: this(item, options)
} }
@ -247,7 +262,16 @@ Items.Item = function(value, options){ return this(...arguments) }
Items.Empty = function(value){} Items.Empty = function(value){}
Items.Separator = function(){ return this('---') } Items.Separator = function(){ return this('---') }
Items.Spinner = function(){ return this('...') } Items.Spinner = function(){ return this('...') }
Items.Heading = function(value, options){}
Items.Heading = function(value, options){
var cls = 'heading'
options = options || {}
options.cls = options.cls instanceof Array ?
options.cls.concat([cls])
: typeof(options.cls) == typeof('str') ?
options.cls +' '+ cls
: [cls]
return this(value, options) }
Items.Selected = function(value){} Items.Selected = function(value){}
Items.Action = function(value, options){} Items.Action = function(value, options){}
Items.ConfirmAction = function(value){} Items.ConfirmAction = function(value){}
@ -263,6 +287,22 @@ Items.EditablePinnedList = function(values){}
//Items.ListTitle = function(){} //Items.ListTitle = function(){}
// XXX EXPERIMENTAL...
// XXX get keys from options...
Items.Confirm = function(message, accept, reject, options){
return this(message,
Object.assign({
// XXX should the user be able to merge buttons from options???
buttons: [
...[reject instanceof Function ?
['$Cancel', reject]
: []],
...[accept instanceof Function ?
['$OK', accept]
: []], ], },
options || {})) }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Generators... // Generators...
@ -286,7 +326,7 @@ Items.makeDisplayItem = function(text, options){
// Make confirm item generator... // Make confirm item generator...
// //
// XXX see how this relates to Item.Confirm(..) // XXX move this to Item.Confirm(..) and reuse that...
Items.makeDisplayConfirm = function(message, accept, reject){ Items.makeDisplayConfirm = function(message, accept, reject){
return this.makeDisplayItem(message, { return this.makeDisplayItem(message, {
buttons: [ buttons: [
@ -3148,6 +3188,9 @@ var BaseBrowserPrototype = {
default_item: function(){ return this.get(0) }, default_item: function(){ return this.get(0) },
options: function(){ options: function(){
return { return {
// XXX this messes up focusing by index, e.g. .focus(0)
// if a header is available...
// XXX SECTION_FOCUS
section: '*', section: '*',
skipDisabled: !(this.options || {}).focusDisabledItems, skipDisabled: !(this.options || {}).focusDisabledItems,
} }, } },
@ -4277,6 +4320,7 @@ var HTMLBrowserPrototype = {
// XXX handle .options.focusDisabledItems correctly... // XXX handle .options.focusDisabledItems correctly...
// - tabindex -- DONE // - tabindex -- DONE
// - ??? // - ???
// XXX show button global/local 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 || {}
@ -4306,6 +4350,14 @@ var HTMLBrowserPrototype = {
value.appendTo(target) value.appendTo(target)
: (target.innerHTML = value) : (target.innerHTML = value)
return target } return target }
var doTextKeys = function(text, doKey){
return text.replace(/\$\w/g,
function(k){
// forget the '$'...
k = k[1]
return (doKey && doKey(k)) ?
`<u class="key-hint">${k}</u>`
: k }) }
// special-case: item.html... // special-case: item.html...
if(item.html){ if(item.html){
@ -4368,16 +4420,15 @@ var HTMLBrowserPrototype = {
item.value item.value
: [item.value]) : [item.value])
// handle $keys and other stuff... // handle $keys and other stuff...
// NOTE: the actual key setup is done in .__preRender__(..)
// see that for more info...
.map(function(v){ .map(function(v){
// handle key-shortcuts $K... // handle key-shortcuts $K...
v = typeof(v) == typeof('str') ? v = typeof(v) == typeof('str') ?
v.replace(/\$\w/g, doTextKeys(v,
function(k){ function(k){
k = k[1] return (item.keys || [])
return (item.keys || []) .includes(that.keyboard.normalizeKey(k)) })
.includes(that.keyboard.normalizeKey(k)) ?
`<u class="key-hint">${k}</u>`
: k })
: v : v
var value = document.createElement('span') var value = document.createElement('span')
@ -4474,8 +4525,19 @@ var HTMLBrowserPrototype = {
&& button.setAttribute('alt', alt) && button.setAttribute('alt', alt)
// button content... // button content...
var text_keys = []
var v = resolveValue(html, Items.buttons, {item})
setDOMValue(button, setDOMValue(button,
resolveValue(html, Items.buttons, {item})) typeof(v) == typeof('str') ?
doTextKeys(v,
function(k){
k = that.keyboard.normalizeKey(k)
return !text_keys.includes(k)
&& text_keys.push(k) })
: v)
keys = text_keys.length > 0 ?
(keys || []).concat(text_keys)
: keys
// non-disabled button... // non-disabled button...
if(force instanceof Function ? if(force instanceof Function ?
@ -4546,6 +4608,8 @@ var HTMLBrowserPrototype = {
if(k in button_keys){ if(k in button_keys){
evt.preventDefault() evt.preventDefault()
evt.stopPropagation() evt.stopPropagation()
button_keys[k].focus()
// XXX should this be optional???
button_keys[k].click() } }) button_keys[k].click() } })
item.dom = elem item.dom = elem
@ -4558,6 +4622,8 @@ var HTMLBrowserPrototype = {
// Events extensions... // Events extensions...
// //
// NOTE: this will also kill any user-set keys for disabled/hidden items... // NOTE: this will also kill any user-set keys for disabled/hidden items...
//
// XXX also handle global button keys...
__preRender__: function(){ __preRender__: function(){
var that = this var that = this
// reset item shortcuts... // reset item shortcuts...
@ -4590,7 +4656,9 @@ var HTMLBrowserPrototype = {
k = that.keyboard.normalizeKey(k[1]) k = that.keyboard.normalizeKey(k[1])
if(!shortcuts[k]){ if(!shortcuts[k]){
shortcuts[k] = function(){ that.focus(e) } shortcuts[k] = function(){
// XXX should this focus or open???
that.focus(e) }
var keys = e.keys = e.keys || [] var keys = e.keys = e.keys || []
keys.includes(k) keys.includes(k)