mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 18:30:09 +00:00
refactored .walk(..) order and index manipulation + fixes and docs...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
0a5e6617c3
commit
1deb1e939f
@ -485,32 +485,55 @@ var BaseBrowserPrototype = {
|
|||||||
+ Date.now() },
|
+ Date.now() },
|
||||||
|
|
||||||
|
|
||||||
|
// Walk the browser...
|
||||||
//
|
//
|
||||||
// .walk(handleItem[, options])
|
// .walk(handleItem[, options])
|
||||||
// -> result
|
// -> result
|
||||||
//
|
//
|
||||||
// .walk(handleItem, handleNested[, options])
|
// .walk(handleItem, handleRecursion[, options])
|
||||||
// -> result
|
// -> result
|
||||||
//
|
//
|
||||||
// .walk(handleItem, handleNested, isWalkable[, options])
|
// .walk(handleItem, handleRecursion, isWalkable[, options])
|
||||||
// -> result
|
// -> result
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
//
|
||||||
// handleItem(path, elem, index, doNested, sublist)
|
// handleItem(path, elem, index, doNested, sublist)
|
||||||
// -> array
|
// -> items
|
||||||
//
|
//
|
||||||
|
// Trigger nested item handling...
|
||||||
|
// doNested([options])
|
||||||
// doNested(list[, options])
|
// doNested(list[, options])
|
||||||
|
// doNested(index[, options])
|
||||||
|
// doNested(list, index[, options])
|
||||||
|
// -> items
|
||||||
|
//
|
||||||
|
// Disable automatic nested item handling...
|
||||||
|
// doNested(false)
|
||||||
|
// -> undefined
|
||||||
|
//
|
||||||
|
// Force nested item handling...
|
||||||
|
// doNested(true, ..)
|
||||||
|
// -> items
|
||||||
|
//
|
||||||
|
// NOTE: doNested(..) has no effect of options.reverseIteration is
|
||||||
|
// set to 'flat'...
|
||||||
|
// NOTE: only the first call to doNested(..) as any effect, all
|
||||||
|
// consecutive calls will return cached results of the first
|
||||||
|
// call...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Handle recursion down...
|
||||||
|
// handleRecursion(func, index, path, sublist, options)
|
||||||
// -> items
|
// -> items
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// XXX
|
|
||||||
// handleNested(..)
|
|
||||||
// ->
|
|
||||||
//
|
//
|
||||||
|
// Test if item is walkable...
|
||||||
|
// isWalkable(item)
|
||||||
|
// -> bool
|
||||||
//
|
//
|
||||||
// Request manual iteration...
|
|
||||||
// doNested(false)
|
|
||||||
// -> undefined
|
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// options format:
|
// options format:
|
||||||
@ -529,11 +552,19 @@ var BaseBrowserPrototype = {
|
|||||||
// // If true skip iterating nested items...
|
// // If true skip iterating nested items...
|
||||||
// skipNested: <bool>,
|
// skipNested: <bool>,
|
||||||
//
|
//
|
||||||
// // If true, reverse iteration order...
|
// // Reverse iteration order...
|
||||||
// // NOTE: containing items will still precede the contained,
|
// //
|
||||||
// // i.e. this will reverse the level order but not
|
// // modes:
|
||||||
// // nesting order...
|
// // false | null - normal order (default)
|
||||||
// reverseIteration: <bool>,
|
// // true - reverse order of levels but keep
|
||||||
|
// // topology order, i.e. containers
|
||||||
|
// // will precede contained elements.
|
||||||
|
// // 'flat' - full flat reverse
|
||||||
|
// //
|
||||||
|
// // NOTE: in 'flat' mode the client loses control over the
|
||||||
|
// // order of processing via doNested(..) as it will be
|
||||||
|
// // called before handleItem(..)
|
||||||
|
// reverseIteration: <bool> | 'flat',
|
||||||
//
|
//
|
||||||
// // If true include inlined parent id in path...
|
// // If true include inlined parent id in path...
|
||||||
// // XXX not implemented yet -- can we implement this???...
|
// // XXX not implemented yet -- can we implement this???...
|
||||||
@ -542,9 +573,7 @@ var BaseBrowserPrototype = {
|
|||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// XXX add 'flat' reverseIteration mode...
|
|
||||||
// XXX revise protocol...
|
// XXX revise protocol...
|
||||||
// XXX make sublist test customizable...
|
|
||||||
walk: function(func, options){
|
walk: function(func, options){
|
||||||
var that = this
|
var that = this
|
||||||
|
|
||||||
@ -557,11 +586,9 @@ var BaseBrowserPrototype = {
|
|||||||
|| typeof(args[0]) == typeof('str')) ?
|
|| typeof(args[0]) == typeof('str')) ?
|
||||||
args.shift()
|
args.shift()
|
||||||
: undefined
|
: undefined
|
||||||
var isWalkable = args[0] instanceof Function ?
|
var userIsWalkable = args[0] instanceof Function ?
|
||||||
args.shift()
|
args.shift()
|
||||||
// XXX revise...
|
: null
|
||||||
: function(elem){
|
|
||||||
return elem instanceof Browser }
|
|
||||||
var i = typeof(args[0]) == typeof(123) ?
|
var i = typeof(args[0]) == typeof(123) ?
|
||||||
args.shift()
|
args.shift()
|
||||||
: 0
|
: 0
|
||||||
@ -579,6 +606,14 @@ var BaseBrowserPrototype = {
|
|||||||
var skipNested = !options.iterateAll && options.skipNested
|
var skipNested = !options.iterateAll && options.skipNested
|
||||||
var reverse = options.reverseIteration
|
var reverse = options.reverseIteration
|
||||||
|
|
||||||
|
var isWalkable = userIsWalkable ?
|
||||||
|
function(elem){
|
||||||
|
return elem instanceof Array
|
||||||
|
|| userIsWalkable(elem) }
|
||||||
|
: function(elem){
|
||||||
|
return elem instanceof Array
|
||||||
|
|| elem instanceof Browser }
|
||||||
|
|
||||||
// level walk function...
|
// level walk function...
|
||||||
var walk = function(i, path, list){
|
var walk = function(i, path, list){
|
||||||
return list
|
return list
|
||||||
@ -601,13 +636,33 @@ var BaseBrowserPrototype = {
|
|||||||
var p
|
var p
|
||||||
|
|
||||||
// nested browser/list handler...
|
// nested browser/list handler...
|
||||||
var nested_called = false
|
var nested = false
|
||||||
var doNested = function(list, opts){
|
var doNested = function(list, j, opts){
|
||||||
list = (!iterateCollapsed && elem.collapsed) ?
|
// this can be called only once...
|
||||||
|
if(nested !== false){
|
||||||
|
return nested
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse args...
|
||||||
|
var args = [...arguments]
|
||||||
|
list = (args[0] === true
|
||||||
|
|| args[0] === false
|
||||||
|
|| isWalkable(args[0])) ?
|
||||||
|
args.shift()
|
||||||
|
: undefined
|
||||||
|
j = typeof(args[0]) == typeof(123) ?
|
||||||
|
args.shift()
|
||||||
|
: undefined
|
||||||
|
opts = args.shift() || options
|
||||||
|
|
||||||
|
// normalize list...
|
||||||
|
list = list === true ?
|
||||||
|
sublist
|
||||||
|
:(!iterateCollapsed && elem.collapsed) ?
|
||||||
[]
|
[]
|
||||||
: (list || sublist)
|
: (list || sublist)
|
||||||
list = list === true ? sublist : list
|
// adjust index...
|
||||||
nested_called = true
|
i = j != null ? j : i
|
||||||
|
|
||||||
return (
|
return (
|
||||||
// request manual iteration...
|
// request manual iteration...
|
||||||
@ -617,41 +672,59 @@ var BaseBrowserPrototype = {
|
|||||||
walk(i, p, list)
|
walk(i, p, list)
|
||||||
// user-defined recursion...
|
// user-defined recursion...
|
||||||
: recursion instanceof Function ?
|
: recursion instanceof Function ?
|
||||||
recursion.call(that, func, i, p, list, opts || options)
|
recursion.call(that, func, i, p, list, opts)
|
||||||
: list[recursion || 'walk'](func, i, p, opts || options))
|
: list[recursion || 'walk'](func, i, p, opts))
|
||||||
.run(function(){
|
.run(function(){
|
||||||
var res = this instanceof Array ?
|
var res = this instanceof Array ?
|
||||||
this
|
this
|
||||||
: [this]
|
: [this]
|
||||||
i += this.length
|
i += this.length
|
||||||
|
nested = res
|
||||||
return res
|
return res
|
||||||
})}
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup some context...
|
||||||
|
var inline = false
|
||||||
|
// inline browser or array...
|
||||||
|
if(isWalkable(elem)){
|
||||||
|
inline = true
|
||||||
|
p = path
|
||||||
|
sublist = elem
|
||||||
|
|
||||||
|
// nested browser / array...
|
||||||
|
} else if(!skipNested
|
||||||
|
&& isWalkable(elem.sublist)){
|
||||||
|
p = path.concat([elem_id])
|
||||||
|
sublist = elem.sublist
|
||||||
|
|
||||||
|
// normal element...
|
||||||
|
} else {
|
||||||
|
p = path.concat([elem_id])
|
||||||
|
sublist = null
|
||||||
|
doNested = null
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
// inline browser or array...
|
// prepend nested elements on flat reverse...
|
||||||
(elem instanceof Array
|
(sublist && options.reverseIteration == 'flat' ?
|
||||||
|| isWalkable(elem)) ?
|
doNested(sublist)
|
||||||
|
: [])
|
||||||
|
// append the actual element...
|
||||||
|
.concat(
|
||||||
func.call(that,
|
func.call(that,
|
||||||
i, p = path,
|
// NOTE: for inline elements we do not need to
|
||||||
null, doNested,
|
// count the header...
|
||||||
sublist = elem)
|
inline ? i : i++,
|
||||||
// nested browser / array...
|
p,
|
||||||
: (!skipNested
|
// NOTE: inlined sets have no header...
|
||||||
&& (elem.sublist instanceof Array
|
inline ? null : elem,
|
||||||
|| isWalkable(elem.sublist))) ?
|
doNested,
|
||||||
func.call(that,
|
sublist))
|
||||||
i++, p = path.concat([elem_id]),
|
// append nested elements if not done so...
|
||||||
elem, doNested,
|
.concat((!sublist || nested !== false) ?
|
||||||
sublist = elem.sublist)
|
|
||||||
// normal element...
|
|
||||||
: func.call(that,
|
|
||||||
i++, p = path.concat([elem_id]),
|
|
||||||
elem, null,
|
|
||||||
sublist = null) )
|
|
||||||
// append nested elements...
|
|
||||||
.concat((!sublist || nested_called) ?
|
|
||||||
[]
|
[]
|
||||||
: doNested(sublist))
|
: doNested(sublist)) )
|
||||||
})
|
})
|
||||||
.flat() }
|
.flat() }
|
||||||
|
|
||||||
@ -664,11 +737,8 @@ var BaseBrowserPrototype = {
|
|||||||
// This is mainly here for doc/debug purposes...
|
// This is mainly here for doc/debug purposes...
|
||||||
//
|
//
|
||||||
// XXX rename this??
|
// XXX rename this??
|
||||||
text: function(options, renderer){
|
text: function(options, base){
|
||||||
var that = this
|
var that = this
|
||||||
// XXX Q: should options and context be distinguished only via
|
|
||||||
// the .options attr as is the case now???
|
|
||||||
// ...see no reason why not, though it does not feel right...
|
|
||||||
var context = (options == null || options.options == null) ?
|
var context = (options == null || options.options == null) ?
|
||||||
{
|
{
|
||||||
root: this,
|
root: this,
|
||||||
@ -678,15 +748,12 @@ var BaseBrowserPrototype = {
|
|||||||
options: Object.assign(
|
options: Object.assign(
|
||||||
Object.create(this.options || {}),
|
Object.create(this.options || {}),
|
||||||
// defaults...
|
// defaults...
|
||||||
// XXX is this the correct way to setup defaults???
|
{ iterateNonIterable: true },
|
||||||
{
|
|
||||||
iterateNonIterable: true,
|
|
||||||
},
|
|
||||||
options || {}),
|
options || {}),
|
||||||
}
|
}
|
||||||
: options
|
: options
|
||||||
options = context.options
|
options = context.options
|
||||||
renderer = renderer || this
|
base = base || []
|
||||||
|
|
||||||
var getValue = function(item){
|
var getValue = function(item){
|
||||||
return item.value || item }
|
return item.value || item }
|
||||||
@ -694,28 +761,16 @@ var BaseBrowserPrototype = {
|
|||||||
var items = this
|
var items = this
|
||||||
.walk(
|
.walk(
|
||||||
function(i, path, item, nested, sublist){
|
function(i, path, item, nested, sublist){
|
||||||
var indent = path.map(e => ' ').join('')
|
var indent = base
|
||||||
return (
|
.concat(path)
|
||||||
// inline...
|
.slice(1)
|
||||||
(item == null && sublist) ?
|
.map(e => ' ')
|
||||||
// NOTE: here we are forcing rendering of the
|
.join('')
|
||||||
// inline browser/list, i.e. ignoring
|
return item ?
|
||||||
// options.skipNested for inline stuff...
|
indent + getValue(item)
|
||||||
nested(true)
|
: [] },
|
||||||
.map(function(e){
|
|
||||||
return indent + getValue(e) })
|
|
||||||
// nested...
|
|
||||||
: sublist ?
|
|
||||||
[item.value]
|
|
||||||
.concat(
|
|
||||||
nested()
|
|
||||||
.map(function(e){
|
|
||||||
return indent + getValue(e) }))
|
|
||||||
// single item...
|
|
||||||
: [getValue(item)]
|
|
||||||
) },
|
|
||||||
function(func, i, path, sublist, options){
|
function(func, i, path, sublist, options){
|
||||||
return sublist.text(context) },
|
return sublist.text(context, base.concat(path)) },
|
||||||
options)
|
options)
|
||||||
|
|
||||||
return context.root === this ?
|
return context.root === this ?
|
||||||
@ -781,7 +836,7 @@ var BaseBrowserPrototype = {
|
|||||||
var options = args.pop() || {}
|
var options = args.pop() || {}
|
||||||
|
|
||||||
return this.walk(
|
return this.walk(
|
||||||
function(i, path, elem){
|
function(i, path, elem, doNested){
|
||||||
return elem != null ?
|
return elem != null ?
|
||||||
[func === undefined ?
|
[func === undefined ?
|
||||||
elem
|
elem
|
||||||
@ -931,8 +986,9 @@ var BaseBrowserPrototype = {
|
|||||||
// XXX do we need to support negative indexes???
|
// XXX do we need to support negative indexes???
|
||||||
var Stop = new Error('.get(..): Result found exception.')
|
var Stop = new Error('.get(..): Result found exception.')
|
||||||
var i = 0
|
var i = 0
|
||||||
|
// reverse indexing...
|
||||||
options = Object.assign(
|
options = Object.assign(
|
||||||
{reverseIteration: key < 0},
|
{reverseIteration: key < 0 && 'flat'},
|
||||||
options || {})
|
options || {})
|
||||||
key = key < 0 ?
|
key = key < 0 ?
|
||||||
-key - 1
|
-key - 1
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user