organized the dom hierarchy (not final), started work on interactions...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2019-02-10 03:02:08 +03:00
parent f17030a5db
commit 09ce8a4073
3 changed files with 84 additions and 19 deletions

View File

@ -215,6 +215,7 @@
/*border: solid 1px rgba(255,255,255, 0.3);*/ /*border: solid 1px rgba(255,255,255, 0.3);*/
} }
.browse-widget .list .button:focus,
.browse-widget .list .button:hover { .browse-widget .list .button:hover {
opacity: 0.9; opacity: 0.9;
background-color: rgba(0, 0, 0, 0.2); background-color: rgba(0, 0, 0, 0.2);
@ -451,7 +452,7 @@
.browse-widget .list .list { .browse-widget .list .list {
padding-left: 20pt; padding-left: 20pt;
} }
.browse-widget .list .list .item:first-child { .browse-widget .list .list>.item:first-child {
margin-left: -20pt; margin-left: -20pt;
} }

View File

@ -101,9 +101,10 @@ requirejs([
browser = br browser = br
// XXX split this into several dialogues, show each and then combine...
dialog_1 = browser.Browser(function(make){ dialog_1 = browser.Browser(function(make){
make(123) make(123)
make(321) make([321, 321, 123])
make.group( make.group(
make('a'), make('a'),
'b') 'b')

View File

@ -182,6 +182,7 @@ Items.ListTitle = function(){}
var BaseBrowserClassPrototype = { var BaseBrowserClassPrototype = {
} }
// XXX need a way to identify items...
var BaseBrowserPrototype = { var BaseBrowserPrototype = {
// XXX should we mix item/list options or separate them into sub-objects??? // XXX should we mix item/list options or separate them into sub-objects???
options: null, options: null,
@ -299,7 +300,8 @@ var BaseBrowserPrototype = {
// XXX should this take an empty sublist??? // XXX should this take an empty sublist???
// ...this would make it simpler to expand/collapse without // ...this would make it simpler to expand/collapse without
// re-rendering the whole list... // re-rendering the whole list...
renderNested: function(header, sublist, item, options){ // XXX revise how the context is passed...
renderNested: function(header, sublist, context, item, options){
return header ? return header ?
this.renderGroup([ this.renderGroup([
header, header,
@ -367,6 +369,7 @@ var BaseBrowserPrototype = {
item.value.render(context) item.value.render(context)
// .sublist -- nested list... // .sublist -- nested list...
: item.sublist ? : item.sublist ?
// XXX revise how the context is passed...
that.renderNested( that.renderNested(
that.renderItem(item, i, options), that.renderItem(item, i, options),
// collapsed... // collapsed...
@ -377,6 +380,7 @@ var BaseBrowserPrototype = {
item.sublist.render(context) item.sublist.render(context)
// list of items... // list of items...
: item.sublist.map(_render)), : item.sublist.map(_render)),
context,
item, item,
options) options)
// basic item... // basic item...
@ -389,6 +393,8 @@ var BaseBrowserPrototype = {
// root context -> render list and return this... // root context -> render list and return this...
this.renderList(items, options) this.renderList(items, options)
// non-root context -> return items as-is... // non-root context -> return items as-is...
// XXX should this be a list of the return value of a
// renderer like .renderNested(..) ???
: items : items
}, },
@ -422,6 +428,7 @@ var BaseBrowserPrototype = {
reduce: function(){}, reduce: function(){},
// XXX should we update on on init....
__init__: function(func, options){ __init__: function(func, options){
this.__list__ = func this.__list__ = func
this.options = Object.assign( this.options = Object.assign(
@ -429,6 +436,7 @@ var BaseBrowserPrototype = {
this.options || {}, this.options || {},
options || {}) options || {})
// XXX should this be here or should this be optional???
//this.update() //this.update()
}, },
} }
@ -448,6 +456,10 @@ var BrowserClassPrototype = {
__proto__: BaseBrowser, __proto__: BaseBrowser,
} }
// XXX TODO:
// - event handler signature -- pass the item + optionally render...
// - keyboard handling...
// XXX render of nested lists does not affect the parent list(s)...
// XXX maintain expand/collapse state of nested lists in a natural way... // XXX maintain expand/collapse state of nested lists in a natural way...
// XXX should this use vanilla DOM or jQuery??? // XXX should this use vanilla DOM or jQuery???
var BrowserPrototype = { var BrowserPrototype = {
@ -458,11 +470,17 @@ var BrowserPrototype = {
renderHidden: false, renderHidden: false,
localEvents: [
'click',
],
}, },
// parent element (optional)... // parent element (optional)...
get parent(){ get parent(){
return this.__parent }, return this.__parent
|| (this.__dom ?
this.__dom.parentElement
: undefined) },
set parent(value){ set parent(value){
var dom = this.dom var dom = this.dom
this.__parent = value this.__parent = value
@ -472,13 +490,13 @@ var BrowserPrototype = {
// browser dom... // browser dom...
get dom(){ get dom(){
return this.parent ? return this.__dom },
this.parent.querySelector('.browse-widget')
: this.__dom },
set dom(value){ set dom(value){
this.parent ? this.parent
$(this.parent).empty().append($(value)) && (this.__dom ?
: (this.__dom = value) }, this.parent.replaceChild(value, this.__dom)
: this.parent.appendChild(value))
this.__dom = value },
// XXX instrument interactions... // XXX instrument interactions...
@ -522,23 +540,44 @@ var BrowserPrototype = {
return header return header
}, },
renderNested: function(header, sublist, item, options){ // XXX revise how the context is passed...
renderNested: function(header, sublist, context, item, options){
var that = this
// container...
var e = document.createElement('div') var e = document.createElement('div')
e.classList.add('list') e.classList.add('list')
// localize events...
;(options.localEvents || this.options.localEvents || [])
.forEach(function(evt){
e.addEventListener(evt, function(evt){ evt.stopPropagation() }) })
// header... // header...
if(header){ if(header){
header.classList.add('sub-list-header') header.classList.add('sub-list-header')
item.collapsed item.collapsed
&& header.classList.add('collapsed') && header.classList.add('collapsed')
e.appendChild(header) e.appendChild(header)
// XXX STUB...
// XXX BUG: nested list .render() when triggered without a
// context will render the header...
e.addEventListener('click', function(evt){
item.collapsed = !item.collapsed
// XXX need to pass the root context here...
that.render(context)
})
} }
// items... // items...
sublist instanceof Node ?
e.appendChild(sublist)
: sublist instanceof Array ?
sublist sublist
&& sublist
.forEach(function(item){ .forEach(function(item){
e.appendChild(item) }) e.appendChild(item) })
: null
item.dom = e item.dom = e
@ -554,6 +593,10 @@ var BrowserPrototype = {
.forEach(function(item){ .forEach(function(item){
e.appendChild(item) }) e.appendChild(item) })
return e }, return e },
// XXX add custom events:
// - open
// - select
// XXX add buttons...
renderItem: function(item, i, options){ renderItem: function(item, i, options){
if(options.hidden && !options.renderHidden){ if(options.hidden && !options.renderHidden){
return null return null
@ -578,7 +621,7 @@ var BrowserPrototype = {
item.attrs || {}, item.attrs || {},
{ {
tabindex: '0', tabindex: '0',
value: JSON.stringify(item.value), value: JSON.stringify(item.value || item),
})) }))
// value... // value...
// XXX handle $key shorthands... // XXX handle $key shorthands...
@ -587,8 +630,15 @@ var BrowserPrototype = {
return $('<span class="text"/>') return $('<span class="text"/>')
.html(v || item || '') })) .html(v || item || '') }))
// XXX buttons... // XXX buttons...
// XXX placeholder button... // XXX placeholder buttons...
.append($('<span class="button"/>').html('&square;')) // XXX things to work out:
// - order -- should be ltr and not rtl (???)
.append($('<span class="button"/>')
.attr('tabindex', '0')
.html('&square;'))
.append($('<span class="button"/>')
.attr('tabindex', '0')
.html('&#9675;'))
// events... // events...
.run(function(){ .run(function(){
var e = this var e = this
@ -661,13 +711,26 @@ var BrowserPrototype = {
// save the rendered state to .dom // save the rendered state to .dom
render: function(options){ render: function(options){
this.dom = object.parent(BrowserPrototype.render, this).call(this, ...arguments) //this.dom = object.parent(BrowserPrototype.render, this).call(this, ...arguments)
//return this.dom
var d = object.parent(BrowserPrototype.render, this).call(this, ...arguments)
// wrap the list (nested list) of nodes in a div...
if(d instanceof Array){
var c = document.createElement('div')
d.forEach(function(e){
c.appendChild(e) })
d = c
}
this.dom = d
return this.dom return this.dom
}, },
filter: function(){}, filter: function(){},
select: function(){},
get: function(){}, get: function(){},
focus: function(){}, focus: function(){},
@ -718,14 +781,14 @@ var TextBrowserPrototype = {
// visible in text... // visible in text...
renderList: function(items, options){ renderList: function(items, options){
var that = this var that = this
return this.renderNested(null, items, null, options) return this.renderNested(null, items, null, null, options)
.join('\n') }, .join('\n') },
renderItem: function(item, i, options){ renderItem: function(item, i, options){
var value = item.value || item var value = item.value || item
return item.current ? return item.current ?
`[ ${value} ]` `[ ${value} ]`
: value }, : value },
renderNested: function(header, sublist, item, options){ renderNested: function(header, sublist, context, item, options){
var that = this var that = this
var nested = sublist var nested = sublist
&& sublist && sublist