diff --git a/ui (gen4)/lib/widget/browse2.html b/ui (gen4)/lib/widget/browse2.html
index acf3d1b9..0646d7bb 100755
--- a/ui (gen4)/lib/widget/browse2.html
+++ b/ui (gen4)/lib/widget/browse2.html
@@ -56,6 +56,11 @@ body {
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... */
.browse-widget>.list {
box-shadow:
@@ -183,6 +188,16 @@ requirejs([
//browser.items.DisplayFocusedPath,
//null,
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.group(
make('$group item 0 (open event)',
diff --git a/ui (gen4)/lib/widget/browse2.js b/ui (gen4)/lib/widget/browse2.js
index 3e7bfdfd..ffaccd7c 100755
--- a/ui (gen4)/lib/widget/browse2.js
+++ b/ui (gen4)/lib/widget/browse2.js
@@ -149,6 +149,19 @@ Items.group = function(...items){
// 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){
options = options || {}
//options = Object.assign(Object.create(this.options || {}), options || {})
@@ -157,7 +170,9 @@ Items.nest = function(item, list, options){
collectItems(this, list)
: list },
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.Separator = 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.Action = function(value, options){}
Items.ConfirmAction = function(value){}
@@ -263,6 +287,22 @@ Items.EditablePinnedList = function(values){}
//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...
@@ -286,7 +326,7 @@ Items.makeDisplayItem = function(text, options){
// 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){
return this.makeDisplayItem(message, {
buttons: [
@@ -3148,6 +3188,9 @@ var BaseBrowserPrototype = {
default_item: function(){ return this.get(0) },
options: function(){
return {
+ // XXX this messes up focusing by index, e.g. .focus(0)
+ // if a header is available...
+ // XXX SECTION_FOCUS
section: '*',
skipDisabled: !(this.options || {}).focusDisabledItems,
} },
@@ -4277,6 +4320,7 @@ var HTMLBrowserPrototype = {
// XXX handle .options.focusDisabledItems correctly...
// - tabindex -- DONE
// - ???
+ // XXX show button global/local keys...
renderItem: function(item, i, context){
var that = this
var options = (context || {}).options || this.options || {}
@@ -4306,6 +4350,14 @@ var HTMLBrowserPrototype = {
value.appendTo(target)
: (target.innerHTML = value)
return target }
+ var doTextKeys = function(text, doKey){
+ return text.replace(/\$\w/g,
+ function(k){
+ // forget the '$'...
+ k = k[1]
+ return (doKey && doKey(k)) ?
+ `${k}`
+ : k }) }
// special-case: item.html...
if(item.html){
@@ -4368,16 +4420,15 @@ var HTMLBrowserPrototype = {
item.value
: [item.value])
// handle $keys and other stuff...
+ // NOTE: the actual key setup is done in .__preRender__(..)
+ // see that for more info...
.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)) ?
- `${k}`
- : k })
+ doTextKeys(v,
+ function(k){
+ return (item.keys || [])
+ .includes(that.keyboard.normalizeKey(k)) })
: v
var value = document.createElement('span')
@@ -4474,8 +4525,19 @@ var HTMLBrowserPrototype = {
&& button.setAttribute('alt', alt)
// button content...
+ var text_keys = []
+ var v = resolveValue(html, Items.buttons, {item})
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...
if(force instanceof Function ?
@@ -4546,6 +4608,8 @@ var HTMLBrowserPrototype = {
if(k in button_keys){
evt.preventDefault()
evt.stopPropagation()
+ button_keys[k].focus()
+ // XXX should this be optional???
button_keys[k].click() } })
item.dom = elem
@@ -4558,6 +4622,8 @@ var HTMLBrowserPrototype = {
// Events extensions...
//
// NOTE: this will also kill any user-set keys for disabled/hidden items...
+ //
+ // XXX also handle global button keys...
__preRender__: function(){
var that = this
// reset item shortcuts...
@@ -4590,7 +4656,9 @@ var HTMLBrowserPrototype = {
k = that.keyboard.normalizeKey(k[1])
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 || []
keys.includes(k)