reworked the iterator...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2019-03-12 16:05:51 +03:00
parent 79dc989832
commit 15545f181c

View File

@ -378,6 +378,25 @@ var BaseBrowserPrototype = {
// //
// Each of the above structures is reset on each call to .make(..) // Each of the above structures is reset on each call to .make(..)
// //
// options format:
// {
// id: <string>,
// value: <string> | <array>,
//
// sublist: <browser> | <array>,
//
// focused: <bool>,
// selected: <bool>,
// disabled: <bool>,
// noniterable: <bool>,
//
// // Set automatically...
// parent: <browser>,
// // XXX move this to the appropriate object...
// dom: <dom>,
// }
//
//
// Example: // Example:
// XXX // XXX
// //
@ -526,12 +545,13 @@ var BaseBrowserPrototype = {
key = opts.id = k key = opts.id = k
// build the item... // build the item...
var item = Object.assign({}, var item = Object.assign(
Object.create(options || {}),
// get the old item values (only for non duplicate items)... // get the old item values (only for non duplicate items)...
id_changed ? id_changed ?
{} {}
: old_index[key] || {}, : old_index[key] || {},
options || {}, // XXX inherit from this...
opts, opts,
{ {
parent: this, parent: this,
@ -744,36 +764,91 @@ var BaseBrowserPrototype = {
}, },
// XXX pass path to handlers... //
iter: function(func, path){ // .iter([options])
// .iter(func[, options])
// .iter(func, path[, options])
// -> items
//
// options format:
// {
// // NOTE: this if true overrides all other iteration coverage
// // options...
// iterateAll: <bool>,
//
// iterateNonIterable: <bool>,
// iterateCollapsed: <bool>,
// skipNested: <bool>,
//
// inlinedPaths: <bool>,
// }
//
//
// By default this will not iterate items that are:
// - non-iterable (item.noniterable is true)
// - collapsed sub-items (item.collapsed is true)
//
//
// XXX make item access by index lazy...
// - index nested stuff and lengths... (.sublist_length)
// - stop when target reached... (control callback???)
// XXX rename this to .items... (???)
iter: function(func, path, options){
var that = this var that = this
path = path || []
// parse args...
var args = [...arguments]
func = args[0] instanceof Function ?
args.shift()
: undefined
path = (args[0] instanceof Array
|| typeof(args[0]) == typeof('str')) ?
args.shift()
: []
path = path instanceof Array ? path : [path]
options = args.pop() || {}
var iterateNonIterable = options.iterateAll || options.iterateNonIterable
var iterateCollapsed = options.iterateAll || options.iterateCollapsed
var skipNested = !options.iterateAll && options.skipNested
var doElem = function(elem){ var doElem = function(elem){
return [func ? return [func ?
func.call(that, elem, path.concat(elem.id)) func.call(that, elem, path.concat(elem.id))
: elem] } : elem] }
return this.items return this.items
.map(function(elem){ .map(function(elem){
return ( return (
// value is Browser (inline)... // item not iterable -- skip...
elem.value instanceof Browser ? (!iterateNonIterable && elem.noniterable) ?
// XXX do we include the path of the parent elem []
// in inlined browsers??? // value is Browser (inline) -- list browser items...
//elem.value.iter(func, path.concat(elem.id)) : elem.value instanceof Browser ?
elem.value.iter(func, path.slice()) elem.value.iter(func,
// .sublist is Browser (nested)... options.inlinedPaths ?
: elem.sublist instanceof Browser ? path.concat(elem.id)
: path.slice(),
options)
// .sublist is Browser (nested) -- list header then browser items...
: (!skipNested
&& elem.sublist instanceof Browser) ?
doElem(elem) doElem(elem)
.concat(elem.sublist.iter(func, path.concat(elem.id))) .concat((!iterateCollapsed && elem.collapsed) ?
// .sublist is Array (nested)... []
: elem.sublist instanceof Array ? : elem.sublist.iter(func, path.concat(elem.id), options))
// .sublist is Array (nested) -- list header then array content...
: (!skipNested
&& elem.sublist instanceof Array) ?
doElem(elem) doElem(elem)
.concat(func ? .concat((!iterateCollapsed && elem.collapsed) ?
// XXX reuse doElem(..) []
elem.sublist.map(function(e){ : (func ?
return func.call(that, e, path.concat(elem.id, e.id)) }) elem.sublist
: elem.sublist.slice()) .map(function(e){
// normal item... return func.call(that, e, path.concat(elem.id, e.id)) })
: elem.sublist.slice()))
// normal item -- list...
: doElem(elem) ) }) : doElem(elem) ) })
.flat() }, .flat() },
@ -1014,14 +1089,18 @@ var BrowserPrototype = {
// //
// NOTE: .class is optional... // NOTE: .class is optional...
// NOTE: set this to null to disable shorthands... // NOTE: set this to null to disable shorthands...
// NOTE: currently the options in the template will override
// anything explicitly given by item options... (XXX revise)
elementShorthand: { elementShorthand: {
'---': { '---': {
'class': 'separator', 'class': 'separator',
'html': '<hr>' 'html': '<hr>',
noniterable: true,
}, },
'...': { '...': {
'class': 'separator', 'class': 'separator',
'html': '<center><div class="loader"/></center>', 'html': '<center><div class="loader"/></center>',
noniterable: true,
}, },
}, },
}, },
@ -1226,15 +1305,16 @@ var BrowserPrototype = {
// special-case: item shorthands... // special-case: item shorthands...
if(item.value in options.elementShorthand){ if(item.value in options.elementShorthand){
var template = options.elementShorthand[item.value] // XXX need to merge and not overwrite -- revise...
Object.assign(item, options.elementShorthand[item.value])
// NOTE: this is a bit of a cheat, but it saves us from either // NOTE: this is a bit of a cheat, but it saves us from either
// parsing or restricting the format... // parsing or restricting the format...
var elem = item.dom = $(template.html)[0] var elem = item.dom = $(item.html)[0]
elem.classList.add( elem.classList.add(
...(template['class'] instanceof Array ? ...(item['class'] instanceof Array ?
template['class'] item['class']
: template['class'].split(/\s+/g))) : item['class'].split(/\s+/g)))
return elem return elem
} }