mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 10:20:08 +00:00
.walk2(..) done -- needs testing...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
bed990372b
commit
dffd66a8ae
@ -151,7 +151,7 @@ Items.group = function(...items){
|
||||
Items.nest = function(item, list, options){
|
||||
options = options || {}
|
||||
//options = Object.assign(Object.create(this.options || {}), options || {})
|
||||
options.sublist = list instanceof Array ?
|
||||
options.children = list instanceof Array ?
|
||||
collectItems(this, list)
|
||||
: list
|
||||
return this(item, options)
|
||||
@ -312,7 +312,7 @@ var BaseBrowserPrototype = {
|
||||
// XXX can we make the format here simpler with less level
|
||||
// of indirection??
|
||||
// ...currently to go down a path we need to:
|
||||
// this.item_key_index.A.sublist.item_key_index.B.sublist...
|
||||
// this.item_key_index.A.children.item_key_index.B.children...
|
||||
// would be nice to be closer to:
|
||||
// this.A.B...
|
||||
__item_index: null,
|
||||
@ -358,21 +358,21 @@ var BaseBrowserPrototype = {
|
||||
.reduce(function(res, e){
|
||||
return e.collapsed ?
|
||||
res + 1
|
||||
: res + e.sublist.length }, 0) },
|
||||
: res + e.children.length }, 0) },
|
||||
// tree -- ignores .collapsed...
|
||||
get lengthTree(){
|
||||
return this.map({skipNested: true}).length
|
||||
// XXX this is wrong as it will not account for nested nested elements...
|
||||
+ this.nested()
|
||||
.reduce(function(res, e){
|
||||
return res + e.sublist.length }, 0) },
|
||||
return res + e.children.length }, 0) },
|
||||
// full -- ignores .collapsed and .noniterable...
|
||||
get lengthAll(){
|
||||
return this.map({skipNested: true, iterateNonIterable: true}).length
|
||||
// XXX this is wrong as it will not account for nested nested elements...
|
||||
+ this.nested()
|
||||
.reduce(function(res, e){
|
||||
return res + (e.sublist.lengthAll || e.sublist.length) }, 0) },
|
||||
return res + (e.children.lengthAll || e.children.length) }, 0) },
|
||||
|
||||
|
||||
// Item list constructor...
|
||||
@ -418,7 +418,7 @@ var BaseBrowserPrototype = {
|
||||
// id: <string>,
|
||||
// value: <string> | <array>,
|
||||
//
|
||||
// sublist: <browser> | <array>,
|
||||
// children: <browser> | <array>,
|
||||
//
|
||||
// focused: <bool>,
|
||||
// selected: <bool>,
|
||||
@ -502,7 +502,7 @@ var BaseBrowserPrototype = {
|
||||
//
|
||||
//
|
||||
//
|
||||
// handleItem(path, elem, index, doNested, sublist)
|
||||
// handleItem(path, elem, index, doNested, children)
|
||||
// -> items
|
||||
//
|
||||
// Trigger nested item handling...
|
||||
@ -529,7 +529,7 @@ var BaseBrowserPrototype = {
|
||||
//
|
||||
//
|
||||
// Handle recursion down...
|
||||
// handleRecursion(func, index, path, sublist, options)
|
||||
// handleRecursion(func, index, path, children, options)
|
||||
// -> items
|
||||
//
|
||||
//
|
||||
@ -558,7 +558,7 @@ var BaseBrowserPrototype = {
|
||||
//
|
||||
// // If true do not skip items with .noniterable set to true...
|
||||
// iterateNonIterable: <bool>,
|
||||
// // If true do not skip item.sublist of items with .collapsed
|
||||
// // If true do not skip item.children of items with .collapsed
|
||||
// // set to true...
|
||||
// iterateCollapsed: <bool>,
|
||||
// // If true skip iterating nested items...
|
||||
@ -609,7 +609,7 @@ var BaseBrowserPrototype = {
|
||||
|| typeof(args[0]) == typeof('str')) ?
|
||||
args.shift()
|
||||
: undefined
|
||||
var userIsWalkable = args[0] instanceof Function ?
|
||||
var walkable = args[0] instanceof Function ?
|
||||
args.shift()
|
||||
: null
|
||||
var i = typeof(args[0]) == typeof(123) ?
|
||||
@ -623,16 +623,13 @@ var BaseBrowserPrototype = {
|
||||
options = args.pop() || {}
|
||||
|
||||
// set call context...
|
||||
// XXX revise this....
|
||||
options = !options.root ?
|
||||
Object.assign({},
|
||||
this.options,
|
||||
options,
|
||||
{root: this})
|
||||
: options
|
||||
|
||||
|
||||
// options...
|
||||
options = Object.assign(Object.create(this.options || {}), options)
|
||||
/*var start = options.start || 0
|
||||
var end = options.end
|
||||
|| (options.count >= 0 && start + (options.count))
|
||||
@ -645,9 +642,9 @@ var BaseBrowserPrototype = {
|
||||
(options.defaultReverse || 'tree')
|
||||
: options.reverse
|
||||
|
||||
var isWalkable = userIsWalkable ?
|
||||
var isWalkable = walkable ?
|
||||
function(elem){
|
||||
return elem instanceof Array || userIsWalkable(elem) }
|
||||
return elem instanceof Array || walkable(elem) }
|
||||
: function(elem){
|
||||
return elem instanceof Array || elem instanceof Browser }
|
||||
|
||||
@ -669,7 +666,7 @@ var BaseBrowserPrototype = {
|
||||
|
||||
var elem_id = elem.id || elem.value
|
||||
// these will be set in the return expression below...
|
||||
var sublist
|
||||
var children
|
||||
var p
|
||||
|
||||
// nested browser/list handler...
|
||||
@ -694,10 +691,12 @@ var BaseBrowserPrototype = {
|
||||
|
||||
// normalize...
|
||||
list = list === true ?
|
||||
sublist
|
||||
children
|
||||
: list === false ?
|
||||
list
|
||||
: (!iterateCollapsed && elem.collapsed) ?
|
||||
[]
|
||||
: (list || sublist)
|
||||
: (list || children)
|
||||
i = j != null ? j : i
|
||||
|
||||
return (
|
||||
@ -731,25 +730,25 @@ var BaseBrowserPrototype = {
|
||||
if(isWalkable(elem)){
|
||||
inline = true
|
||||
p = path
|
||||
sublist = elem
|
||||
children = elem
|
||||
|
||||
// nested browser / array...
|
||||
} else if(!skipNested
|
||||
&& isWalkable(elem.sublist)){
|
||||
&& isWalkable(elem.children)){
|
||||
p = path.concat([elem_id])
|
||||
sublist = elem.sublist
|
||||
children = elem.children
|
||||
|
||||
// normal element...
|
||||
} else {
|
||||
p = path.concat([elem_id])
|
||||
sublist = null
|
||||
children = null
|
||||
doNested = null
|
||||
}
|
||||
|
||||
return (
|
||||
// prepend nested elements on flat reverse...
|
||||
(sublist && reverse == 'flat' ?
|
||||
doNested(sublist)
|
||||
(children && reverse == 'flat' ?
|
||||
doNested(children)
|
||||
: [])
|
||||
// append the actual element...
|
||||
.concat(
|
||||
@ -762,11 +761,11 @@ var BaseBrowserPrototype = {
|
||||
// NOTE: inlined sets have no header...
|
||||
inline ? null : elem,
|
||||
doNested,
|
||||
sublist))
|
||||
children))
|
||||
// append nested elements if not done so...
|
||||
.concat((!sublist || nested !== false) ?
|
||||
.concat((!children || nested !== false) ?
|
||||
[]
|
||||
: doNested(sublist)) )
|
||||
: doNested(children)) )
|
||||
})
|
||||
// XXX this here loses the length information we need in doNested(..)
|
||||
// to calc indexes...
|
||||
@ -787,39 +786,139 @@ var BaseBrowserPrototype = {
|
||||
// - get a feeling of this running
|
||||
// - see if we need to change the API
|
||||
// - either embed into .walk(..) or reimplement...
|
||||
walk2: function(func, i, path, options){
|
||||
// XXX can this be simpler???
|
||||
walk2: function(func, recursion, walkable, options){
|
||||
var that = this
|
||||
|
||||
i = i || 0
|
||||
path = path || []
|
||||
// parse args...
|
||||
var args = [...arguments]
|
||||
func = args[0] instanceof Function ?
|
||||
args.shift()
|
||||
: undefined
|
||||
var recursion = (args[0] instanceof Function
|
||||
|| typeof(args[0]) == typeof('str')
|
||||
|| args[0] == null) ?
|
||||
args.shift()
|
||||
: undefined
|
||||
var walkable = (args[0] instanceof Function
|
||||
|| args[0] == null) ?
|
||||
args.shift()
|
||||
: null
|
||||
options = args.shift() || {}
|
||||
|
||||
// threaded args...
|
||||
var i = args.shift() || 0
|
||||
var path = args.shift() || []
|
||||
|
||||
// options specifics...
|
||||
options = !options.root ?
|
||||
Object.assign({},
|
||||
this.options,
|
||||
options,
|
||||
// set call context...
|
||||
{root: this})
|
||||
: options
|
||||
var iterateNonIterable = options.iterateAll || options.iterateNonIterable
|
||||
var iterateCollapsed = options.iterateAll || options.iterateCollapsed
|
||||
var skipNested = !options.iterateAll && options.skipNested
|
||||
var reverse = options.reverse === true ?
|
||||
(options.defaultReverse || 'tree')
|
||||
: options.reverse
|
||||
|
||||
var isWalkable = walkable ?
|
||||
function(node){
|
||||
return node instanceof Array || walkable(node) }
|
||||
: function(node){
|
||||
return node && (node instanceof Array || node.walk2) }
|
||||
|
||||
return walk(
|
||||
function(state, node, next, stop){
|
||||
node.value
|
||||
&& console.log('---', i++, path, node.value)
|
||||
// skip non-iterable items...
|
||||
if(!iterateNonIterable && node.noniterable){
|
||||
return state
|
||||
}
|
||||
|
||||
return (
|
||||
var nested = false
|
||||
var doNested = function(list){
|
||||
// this can be called only once...
|
||||
if(nested !== false){
|
||||
return nested
|
||||
}
|
||||
|
||||
// normalize...
|
||||
list = (list === true || list == null) ?
|
||||
children
|
||||
: (!iterateCollapsed && node.collapsed) ?
|
||||
[]
|
||||
: list
|
||||
|
||||
return (list === false ?
|
||||
[]
|
||||
: list instanceof Array ?
|
||||
next('do', state, ...(reverse ? list.slice().reverse() : list))
|
||||
// user-defined recursion...
|
||||
: recursion instanceof Function ?
|
||||
recursion.call(that, func, i, p, list, options)
|
||||
: list[recursion || 'walk2'](func, recursion, walkable, options, i, p))
|
||||
.run(function(){
|
||||
// normalize...
|
||||
nested = this instanceof Array ?
|
||||
this
|
||||
: [this]
|
||||
// merge recursion results into states...
|
||||
if(!(list === false || list instanceof Array)){
|
||||
state.splice(state.length, 0, ...nested)
|
||||
i += nested.length
|
||||
}
|
||||
return nested
|
||||
})
|
||||
}
|
||||
|
||||
// prepare context...
|
||||
var id = node.id || node.value
|
||||
path = this.path = this.path || path
|
||||
var [inline, p, children] =
|
||||
// inline...
|
||||
node instanceof Array ?
|
||||
next('do', state, ...node)
|
||||
: node.walk2 instanceof Function ?
|
||||
// XXX pass stop(..) to this...
|
||||
state.concat(node.walk2(func, i, path, options))
|
||||
|
||||
isWalkable(node) ?
|
||||
[true, path, node]
|
||||
// nested...
|
||||
// XXX add node to state...
|
||||
: node.sublist instanceof Array ?
|
||||
// XXX need to update path...
|
||||
next('do', state, ...node.sublist)
|
||||
: node.sublist && node.sublist.walk2 instanceof Function ?
|
||||
// XXX pass stop(..) to this...
|
||||
state.concat(node.sublist.walk2(func, i, path.concat([node.value]), options))
|
||||
: (!skipNested && isWalkable(node.children)) ?
|
||||
[false,
|
||||
// prepare context for nested items...
|
||||
this.path = path.concat([id]),
|
||||
node.children]
|
||||
// leaf...
|
||||
: [false, path.concat([id]), undefined]
|
||||
|
||||
: state)
|
||||
// reverse -> do children...
|
||||
reverse == 'flat'
|
||||
&& children
|
||||
&& doNested()
|
||||
// element...
|
||||
state.splice(state.length, 0,
|
||||
...[func.call(that,
|
||||
...(inline ? [null, i] : [node, i++]),
|
||||
p,
|
||||
doNested,
|
||||
stop,
|
||||
children) || []])
|
||||
// normal order -> do children...
|
||||
children
|
||||
&& (doNested(),
|
||||
// restore path context...
|
||||
this.path.pop())
|
||||
|
||||
return state
|
||||
},
|
||||
// XXX done(..)
|
||||
//function(state){ console.log('done:', state) },
|
||||
// normalize the root result...
|
||||
function(state){
|
||||
return options.root === that ?
|
||||
state.flat()
|
||||
: state },
|
||||
[],
|
||||
...this.items)
|
||||
...(reverse ?
|
||||
this.items.slice().reverse()
|
||||
: this.items))
|
||||
},
|
||||
|
||||
|
||||
@ -851,7 +950,7 @@ var BaseBrowserPrototype = {
|
||||
|
||||
var items = this
|
||||
.walk(
|
||||
function(i, path, item, nested, sublist){
|
||||
function(i, path, item, nested, children){
|
||||
var indent = base
|
||||
.concat(path)
|
||||
.slice(1)
|
||||
@ -860,8 +959,8 @@ var BaseBrowserPrototype = {
|
||||
return item ?
|
||||
indent + getValue(item)
|
||||
: [] },
|
||||
function(func, i, path, sublist, options){
|
||||
return sublist.text(context, base.concat(path)) },
|
||||
function(func, i, path, children, options){
|
||||
return children.text(context, base.concat(path)) },
|
||||
options)
|
||||
|
||||
return context.root === this ?
|
||||
@ -950,11 +1049,11 @@ var BaseBrowserPrototype = {
|
||||
// container to func???
|
||||
: func.call(that, elem, i, path, that)]
|
||||
: [] },
|
||||
function(_, i, path, sublist, options){
|
||||
function(_, i, path, children, options){
|
||||
// NOTE: this needs to call the actual func that the user
|
||||
// gave us and not the constructed function that we
|
||||
// pass to .walk(..) above...
|
||||
return sublist.map(func, i, path, options) },
|
||||
return children.map(func, i, path, options) },
|
||||
...args,
|
||||
options)
|
||||
},
|
||||
@ -1235,7 +1334,7 @@ var BaseBrowserPrototype = {
|
||||
//
|
||||
// XXX NOTE: these will return a sparse array... ???
|
||||
sublists: function(func, options){
|
||||
return this.search({sublist: true}, func, options) },
|
||||
return this.search({children: true}, func, options) },
|
||||
// XXX broken, needs support for options.skipInlined ...
|
||||
nested: function(func){
|
||||
return this.sublists(func, {skipInlined: true}) },
|
||||
@ -1319,7 +1418,7 @@ var BaseBrowserPrototype = {
|
||||
delete (cur.parent.item_key_index[cur.id]
|
||||
|| cur.parent.items
|
||||
.filter(function(e){
|
||||
return e.sublist === cur })
|
||||
return e.children === cur })
|
||||
.shift()).collapsed
|
||||
cur = cur.parent }
|
||||
|
||||
@ -1533,8 +1632,8 @@ var BaseBrowserPrototype = {
|
||||
})
|
||||
|
||||
// XXX do we need both this and the above ref???
|
||||
item.sublist instanceof Browser
|
||||
&& (item.sublist.parent = this)
|
||||
item.children instanceof Browser
|
||||
&& (item.children.parent = this)
|
||||
}
|
||||
|
||||
// store the item...
|
||||
@ -1569,7 +1668,7 @@ var BaseBrowserPrototype = {
|
||||
//
|
||||
// .renderFinalize(items, context)
|
||||
// .renderList(items, context)
|
||||
// .renderNested(header, sublist, item, context)
|
||||
// .renderNested(header, children, item, context)
|
||||
// .renderNestedHeader(item, i, context)
|
||||
// .renderItem(item, i, context)
|
||||
// .renderGroup(items, context)
|
||||
@ -1580,16 +1679,16 @@ var BaseBrowserPrototype = {
|
||||
renderList: function(items, context){
|
||||
return items },
|
||||
// NOTE: to skip rendering an item/list return null...
|
||||
// XXX should this take an empty sublist???
|
||||
// XXX should this take an empty children???
|
||||
// ...this would make it simpler to expand/collapse without
|
||||
// re-rendering the whole list...
|
||||
renderNested: function(header, sublist, item, context){
|
||||
renderNested: function(header, children, item, context){
|
||||
return header ?
|
||||
this.renderGroup([
|
||||
header,
|
||||
sublist,
|
||||
children,
|
||||
])
|
||||
: sublist },
|
||||
: children },
|
||||
renderNestedHeader: function(item, i, context){
|
||||
return this.renderItem(item, i, context) },
|
||||
// NOTE: to skip rendering an item/list return null...
|
||||
@ -1632,6 +1731,7 @@ var BaseBrowserPrototype = {
|
||||
//
|
||||
// XXX would be nice to add ability to do a full render but not
|
||||
// finalize the result...
|
||||
// XXX BUG: calling .render() removes all non-iterable items for some reason...
|
||||
render: function(options, renderer){
|
||||
var that = this
|
||||
// XXX Q: should options and context be distinguished only via
|
||||
@ -1648,9 +1748,7 @@ var BaseBrowserPrototype = {
|
||||
Object.create(this.options || {}),
|
||||
// defaults...
|
||||
// XXX is this the correct way to setup defaults???
|
||||
{
|
||||
iterateNonIterable: true,
|
||||
},
|
||||
{ iterateNonIterable: true },
|
||||
options || {}),
|
||||
}
|
||||
: options
|
||||
@ -1664,10 +1762,10 @@ var BaseBrowserPrototype = {
|
||||
// - arg threading
|
||||
var items = this
|
||||
.walk(
|
||||
function(i, path, item, nested, sublist){
|
||||
function(i, path, item, nested, children){
|
||||
return (
|
||||
// inline...
|
||||
(item == null && sublist) ?
|
||||
(item == null && children) ?
|
||||
// NOTE: here we are forcing rendering of the
|
||||
// inline browser/list, i.e. ignoring
|
||||
// options.skipNested for inline stuff...
|
||||
@ -1675,7 +1773,7 @@ var BaseBrowserPrototype = {
|
||||
// inlined lists and browsers... (XXX ???)
|
||||
[ renderer.renderGroup(nested(true), context) ]
|
||||
// nested...
|
||||
: sublist ?
|
||||
: children ?
|
||||
[ renderer.renderNested(
|
||||
renderer.renderNestedHeader(item, i, context),
|
||||
nested(),
|
||||
@ -1683,8 +1781,8 @@ var BaseBrowserPrototype = {
|
||||
context) ]
|
||||
// normal item...
|
||||
: [ renderer.renderItem(item, i, context) ] ) },
|
||||
function(func, i, path, sublist, options){
|
||||
return sublist.render(context, renderer, i, path) },
|
||||
function(func, i, path, children, options){
|
||||
return children.render(context, renderer, i, path) },
|
||||
// make the element render less strict...
|
||||
function(elem){
|
||||
return elem
|
||||
@ -2071,12 +2169,12 @@ var BrowserPrototype = {
|
||||
// <!-- header (optional) -->
|
||||
// ...
|
||||
//
|
||||
// <!-- sublist (optional) -->
|
||||
// <!-- children (optional) -->
|
||||
// ...
|
||||
// </div>
|
||||
//
|
||||
// XXX register event handlers...
|
||||
renderNested: function(header, sublist, item, context){
|
||||
renderNested: function(header, children, item, context){
|
||||
var that = this
|
||||
var options = context.options || this.options
|
||||
|
||||
@ -2095,11 +2193,11 @@ var BrowserPrototype = {
|
||||
&& e.appendChild(header)
|
||||
|
||||
// items...
|
||||
sublist instanceof Node ?
|
||||
e.appendChild(sublist)
|
||||
children instanceof Node ?
|
||||
e.appendChild(children)
|
||||
// XXX should this add the items to a container???
|
||||
: sublist instanceof Array ?
|
||||
sublist
|
||||
: children instanceof Array ?
|
||||
children
|
||||
.forEach(function(item){
|
||||
e.appendChild(item) })
|
||||
: null
|
||||
@ -2341,10 +2439,10 @@ var TextBrowserPrototype = {
|
||||
return item.current ?
|
||||
`[ ${value} ]`
|
||||
: value },
|
||||
renderNested: function(header, sublist, context, item, options){
|
||||
renderNested: function(header, children, context, item, options){
|
||||
var that = this
|
||||
var nested = sublist
|
||||
&& sublist
|
||||
var nested = children
|
||||
&& children
|
||||
.flat()
|
||||
.map(function(e){
|
||||
return e instanceof Array ?
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user