added secion construction and rendering...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2019-06-29 07:11:30 +03:00
parent 3c7de1f2c3
commit 4e86290ec4
2 changed files with 151 additions and 105 deletions

View File

@ -172,34 +172,8 @@ requirejs([
// XXX split this into several dialogues, show each and then combine... // XXX split this into several dialogues, show each and then combine...
dialog = browser.Browser( dialog = browser.Browser(
function(make, options){ //browser.Browser.PATH_HEADER,
make('CURRENT_PATH', {
id: 'current_path',
cls: 'path',
buttons: (options || {}).headerButtons
|| (this.options || {}).headerButtons
|| [],
}) },
function(make){ function(make){
// XXX put this in the header...
// ways to do this:
// - a different handler
// .__header__(..) is like .__list__(..) but can be
// called less often...
// - a group like thing/constructor...
// make.Header(
// make(..),
// ..
// )
// - both???
make('path', {
id:'selected_path',
//cls: 'path sticky',
cls: 'path',
})
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)',
@ -278,11 +252,6 @@ requirejs([
'ToggleDisabled', 'ToggleDisabled',
], ],
}) })
// XXX EXPEREMENT -- need to wrap this into partial .update(..)
.focus(function(){
var e = this.get({id: 'selected_path'})
e.value = this.pathArray
this.renderItem(e) })
dialog.container = $('.container').first()[0] dialog.container = $('.container').first()[0]

View File

@ -1549,12 +1549,16 @@ var BaseBrowserPrototype = {
context.index = context.index || 0 context.index = context.index || 0
// options specifics... // options specifics...
// NOTE: we include header/footer only for the root context... var sections = options.section == '*' ?
var sections = context.root === this ? (options.sections
'items' || ['header', 'items', 'footer'])
: options.section == '*' ? : options.section
(options.sections || 'items') // NOTE: we include sections other than 'items' only for the root context...
: (options.section || 'items') sections = (sections instanceof Array
&& context.root !== this)
&& sections.includes('items') ?
'items'
: (sections || 'items')
sections = sections instanceof Array ? sections = sections instanceof Array ?
sections sections
: [sections] : [sections]
@ -2474,8 +2478,8 @@ var BaseBrowserPrototype = {
// Renderers... // Renderers...
// //
// .renderFinalize(items, context) // .renderFinalize(header, items, footer, context)
// .renderList(items, context) // .renderList(header, items, footer, context)
// .renderNested(header, children, item, context) // .renderNested(header, children, item, context)
// .renderNestedHeader(item, i, context) // .renderNestedHeader(item, i, context)
// .renderItem(item, i, context) // .renderItem(item, i, context)
@ -2485,9 +2489,9 @@ var BaseBrowserPrototype = {
// NOTE: there are not to be used directly... // NOTE: there are not to be used directly...
// XXX might be a good idea to move these into a separate renderer // XXX might be a good idea to move these into a separate renderer
// object (mixin or encapsulated)... // object (mixin or encapsulated)...
renderFinalize: function(items, context){ renderFinalize: function(header, items, footer, context){
return this.renderList(items, context) }, return this.renderList(header, items, footer, context) },
renderList: function(items, context){ renderList: function(header, items, footer, context){
return items }, return items },
// NOTE: to skip rendering an item/list return null... // NOTE: to skip rendering an item/list return null...
// XXX should this take an empty children??? // XXX should this take an empty children???
@ -2582,6 +2586,7 @@ var BaseBrowserPrototype = {
// XXX make partial render be lazy -- i.e. add/remove elements and // XXX make partial render be lazy -- i.e. add/remove elements and
// do not reconstruct the ones already present... // do not reconstruct the ones already present...
// XXX should from/to/around/count be a feature of this or of .walk(..)??? // XXX should from/to/around/count be a feature of this or of .walk(..)???
// XXX render all the sections at root... (???)
render: function(options, renderer, context){ render: function(options, renderer, context){
context = context || {} context = context || {}
renderer = renderer || this renderer = renderer || this
@ -2591,6 +2596,14 @@ var BaseBrowserPrototype = {
{ iterateNonIterable: true }, { iterateNonIterable: true },
options || {}) options || {})
var section = options.section || '*'
section = section == '*' ?
options.sections
: section
section = section instanceof Array && section.length == 1 ?
section[0]
: section
// build range bounds... // build range bounds...
// use .get(..) on full (non-partial) range... // use .get(..) on full (non-partial) range...
var get_options = Object.assign( var get_options = Object.assign(
@ -2652,48 +2665,69 @@ var BaseBrowserPrototype = {
from_path = from_path instanceof Array from_path = from_path instanceof Array
&& from_path && from_path
// do the walk... // root call -> build sections (calling .render(..) per section)...
var elems = this.walk( if(context.root == null && section instanceof Array){
function(elem, i, path, nested){ context.root = this
return ( var s= {}
// special case: nested <from> elem -> topology only... section
(from_path .forEach(function(name){
&& i < from s[name] = this.render(
// only for nested... Object.assign(
&& elem && elem.children Object.create(options),
// only sub-path... {
&& path.cmp(from_path.slice(0, path.length))) ? section: name,
[ renderer.renderNestedBlank(nested(), i, context) ] nonFinalized: true,
// out of range -> skip... }),
: ((from != null && i < from) renderer) }.bind(this))
|| (to != null && i >= to)) ?
[]
// inline...
: elem == null ?
// NOTE: here we are forcing rendering of the
// inline browser/list, i.e. ignoring
// options.skipNested for inline stuff...
[ renderer.renderGroup(nested(true), context) ]
// nested...
: elem.children ?
[ renderer.renderNested(
renderer.renderNestedHeader(elem, i, context),
nested(),
elem,
context) ]
// normal elem...
: [ renderer.renderItem(elem, i, context) ] ) },
'render',
function(_, i, p, options, context){
return [options, renderer, context] },
options, context)
// finalize depending on render mode... return (!options.nonFinalized && context.root === this) ?
return (!options.nonFinalized && context.root === this) ? renderer.renderFinalize(s.header, s.items, s.footer, context)
// root context -> render list and return this... : s
renderer.renderFinalize(elems, context)
// nested context -> return item list... // build specific sections...
: elems }, } else {
// do the walk...
var items = this.walk(
function(elem, i, path, nested){
return (
// special case: nested <from> elem -> topology only...
(from_path
&& i < from
// only for nested...
&& elem && elem.children
// only sub-path...
&& path.cmp(from_path.slice(0, path.length))) ?
[ renderer.renderNestedBlank(nested(), i, context) ]
// out of range -> skip...
: ((from != null && i < from)
|| (to != null && i >= to)) ?
[]
// inline...
: elem == null ?
// NOTE: here we are forcing rendering of the
// inline browser/list, i.e. ignoring
// options.skipNested for inline stuff...
[ renderer.renderGroup(nested(true), context) ]
// nested...
: elem.children ?
[ renderer.renderNested(
renderer.renderNestedHeader(elem, i, context),
nested(),
elem,
context) ]
// normal elem...
: [ renderer.renderItem(elem, i, context) ] ) },
'render',
function(_, i, p, options, context){
return [options, renderer, context] },
options, context)
// finalize depending on render mode...
return (!options.nonFinalized && context.root === this) ?
// root context -> render list and return this...
renderer.renderFinalize(null, items, null, context)
// nested context -> return item list...
: items } },
// Events... // Events...
@ -3381,6 +3415,25 @@ var updateElemClass = function(action, cls, handler){
var HTMLBrowserClassPrototype = { var HTMLBrowserClassPrototype = {
__proto__: BaseBrowser, __proto__: BaseBrowser,
// XXX move this into the browser2.js
// -> .options.defaultHeader
// -> Browser.PATH_HEADER
// XXX add search/filter field...
// XXX add
PATH_HEADER: function(make, options){
make('CURRENT_PATH', {
id: 'current_path',
cls: 'path',
buttons: (options || {}).headerButtons
|| (this.options || {}).headerButtons
|| [],
})
this.focus(function(){
var e = this.get({id: 'current_path'}, {section: 'header'})
e.value = this.pathArray
this.renderItem(e) })
},
} }
// XXX render of nested lists does not affect the parent list(s)... // XXX render of nested lists does not affect the parent list(s)...
@ -3395,6 +3448,9 @@ var HTMLBrowserPrototype = {
options: { options: {
__proto__: BaseBrowser.prototype.options, __proto__: BaseBrowser.prototype.options,
// XXX not used...
defaultHeader: 'PATH_HEADER',
// for more docs see: // for more docs see:
// https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView // https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
// //
@ -3730,9 +3786,9 @@ var HTMLBrowserPrototype = {
// </div> // </div>
// or same as .renderList(..) // or same as .renderList(..)
// //
renderFinalize: function(items, context){ renderFinalize: function(header, items, footer, context){
var that = this var that = this
var d = this.renderList(items, context) var d = this.renderList(header, items, footer, context)
var options = context.options || this.options || {} var options = context.options || this.options || {}
// wrap the list (nested list) of nodes in a div... // wrap the list (nested list) of nodes in a div...
@ -3789,9 +3845,12 @@ var HTMLBrowserPrototype = {
// <!-- items --> // <!-- items -->
// ... // ...
// </div> // </div>
//
// <!-- footer -->
// ...
// </div> // </div>
// //
renderList: function(items, context){ renderList: function(header, items, footer, context){
var that = this var that = this
var options = context.options || this.options || {} var options = context.options || this.options || {}
@ -3804,8 +3863,9 @@ var HTMLBrowserPrototype = {
function(evt){ evt.stopPropagation() }) function(evt){ evt.stopPropagation() })
// header... // header...
options.hideListHeader header
|| dialog.appendChild(this.renderListHeader(context)) && !options.hideListHeader
&& dialog.appendChild(this.renderListHeader(header, context))
// list... // list...
var list = document.createElement('div') var list = document.createElement('div')
@ -3820,30 +3880,35 @@ var HTMLBrowserPrototype = {
: item) }) : item) })
dialog.appendChild(list) dialog.appendChild(list)
// footer...
footer
&& !options.hideListFooter
&& dialog.appendChild(this.renderListFooter(footer, context))
return dialog return dialog
}, },
// //
// Foramt: // Foramt:
// <div class="path v-block"> // <div class="path v-block">
// <div class="dir" tabindex="0">dir</div> // <!-- list -->
// ... // <div class="list v-block header">
// <div class="dir cur" tabindex="0">dir</div> // <!-- items -->
// ...
// </div>
// </div> // </div>
// //
// XXX populate this... // XXX populate this...
// XXX make this an item??? // XXX make this an item???
renderListHeader: function(context){ renderListHeader: function(items, context){
var header = document.createElement('div') var elem = this.renderList(null, items, null, context).firstChild
header.classList.add('path', 'v-block') // XXX should we replace 'list' or add 'header'
elem.classList.add('header')
// XXX path/search... return elem },
var dir = document.createElement('div') renderListFooter: function(items, context){
dir.classList.add('dir', 'cur') var elem = this.renderList(null, items, null, context).firstChild
dir.setAttribute('tabindex', '0') // XXX should we replace 'list' or add 'footer'
header.appendChild(dir) elem.classList.add('footer')
return elem },
return header
},
// //
// Format: // Format:
// <div class="list"> // <div class="list">
@ -4377,6 +4442,18 @@ var HTMLBrowserPrototype = {
// Filtering/search mode... // Filtering/search mode...
// XXX // XXX
/*/ XXX this should only work on root...
__init__: function(func, options){
var args = [...arguments]
options = args[args.length-1] instanceof Function ?
{}
: args[args.length-1]
;(args[1] instanceof Function)
&& this.constructor[options.defaultHeader]
&& args.unshift(this.constructor[options.defaultHeader])
return object.parent(HTMLBrowserPrototype.__init__, this).call(this, ...args) },
//*/
} }
@ -4416,7 +4493,7 @@ var TextBrowserPrototype = {
// NOTE: we do not need .renderGroup(..) here as a group is not // NOTE: we do not need .renderGroup(..) here as a group is not
// visible in text... // visible in text...
renderList: function(items, options){ renderList: function(header, items, footer, options){
var that = this var that = this
return this.renderNested(null, items, null, null, options) return this.renderNested(null, items, null, null, options)
.join('\n') }, .join('\n') },