mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-28 18:00:09 +00:00
refactoring .walk(..)...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
fa40e6a2cf
commit
ad47d8036c
@ -798,7 +798,6 @@ var BaseBrowserPrototype = {
|
|||||||
// Walk tree passign each node to func(..) and handle nested browser
|
// Walk tree passign each node to func(..) and handle nested browser
|
||||||
// walking in recursion(..) optionally testing if walkable with walkable(..)
|
// walking in recursion(..) optionally testing if walkable with walkable(..)
|
||||||
// .walk2(func(..), recursion(..)[, options])
|
// .walk2(func(..), recursion(..)[, options])
|
||||||
// .walk2(func(..), recursion(..), walkable(..)[, options])
|
|
||||||
// -> list
|
// -> list
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
@ -812,12 +811,12 @@ var BaseBrowserPrototype = {
|
|||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Handle walkable node children (recursively)...
|
// Handle walkable node children (recursively)...
|
||||||
// recursion(children, index, path, func(..), stop(..), walk(), options)
|
// recursion(children, index, path, options, context, func(..), stop(..), walk())
|
||||||
// -> list
|
// -> list
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Prepare arguments for call of name function on nested browser...
|
// Prepare arguments for call of name function on nested browser...
|
||||||
// args(...list)
|
// args(list, index, path, options, context, func(..), stop(..))
|
||||||
// -> list
|
// -> list
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
@ -826,6 +825,9 @@ var BaseBrowserPrototype = {
|
|||||||
// -> bool
|
// -> bool
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
// For examples see: .text(..), .paths(..) and .map(..)
|
||||||
|
//
|
||||||
|
//
|
||||||
// NOTE: if recursion(..) is not given then .walk2(..) is used to
|
// NOTE: if recursion(..) is not given then .walk2(..) is used to
|
||||||
// handle nested children...
|
// handle nested children...
|
||||||
// NOTE: if walkable(..) is not given then we check for .walk2(..)
|
// NOTE: if walkable(..) is not given then we check for .walk2(..)
|
||||||
@ -859,30 +861,29 @@ var BaseBrowserPrototype = {
|
|||||||
&& args[0] instanceof Function) ?
|
&& args[0] instanceof Function) ?
|
||||||
args.shift()
|
args.shift()
|
||||||
: null
|
: null
|
||||||
var walkable = (args[0] instanceof Function
|
|
||||||
|| args[0] == null) ?
|
|
||||||
args.shift()
|
|
||||||
: null
|
|
||||||
options = args.shift() || {}
|
|
||||||
|
|
||||||
// sanity check...
|
// sanity check...
|
||||||
if(formArgs == null && typeof(recursion) == typeof('str')){
|
if(formArgs == null && typeof(recursion) == typeof('str')){
|
||||||
throw new Error(`.walk2(func, name, formArgs, ..): `
|
throw new Error(`.walk2(func, name, formArgs, ..): `
|
||||||
+`expected function as third argument, got: ${formArgs}.`) }
|
+`expected function as third argument, got: ${formArgs}.`) }
|
||||||
|
var walkable = (!formArgs
|
||||||
|
&& (args[0] instanceof Function
|
||||||
|
|| args[0] == null)) ?
|
||||||
|
args.shift()
|
||||||
|
: null
|
||||||
|
options = args.shift() || {}
|
||||||
|
|
||||||
// recursion-threaded args...
|
// recursion context...
|
||||||
var i = args.shift() || 0
|
var context = args.shift()
|
||||||
var path = args.shift() || []
|
var path = context instanceof Array ?
|
||||||
var stopParent = args.shift() || null
|
context
|
||||||
|
: ((context && context.path) || [])
|
||||||
|
context = context instanceof Array ?
|
||||||
|
{path: path}
|
||||||
|
: (context || {})
|
||||||
|
context.root = context.root || this
|
||||||
|
var i = context.index = context.index || 0
|
||||||
|
|
||||||
// options specifics...
|
// options specifics...
|
||||||
options = !options.root ?
|
|
||||||
Object.assign({},
|
|
||||||
this.options || {},
|
|
||||||
options,
|
|
||||||
// set call context...
|
|
||||||
{ root: this })
|
|
||||||
: options
|
|
||||||
var iterateNonIterable = options.iterateAll || options.iterateNonIterable
|
var iterateNonIterable = options.iterateAll || options.iterateNonIterable
|
||||||
var iterateCollapsed = options.iterateAll || options.iterateCollapsed
|
var iterateCollapsed = options.iterateAll || options.iterateCollapsed
|
||||||
var skipNested = !options.iterateAll && options.skipNested
|
var skipNested = !options.iterateAll && options.skipNested
|
||||||
@ -923,7 +924,15 @@ var BaseBrowserPrototype = {
|
|||||||
: list
|
: list
|
||||||
|
|
||||||
var useWalk = function(){
|
var useWalk = function(){
|
||||||
return list.walk2(func, recursion, walkable, options, i, p, stop) }
|
return list.walk2(
|
||||||
|
func,
|
||||||
|
recursion,
|
||||||
|
...(formArgs instanceof Function ?
|
||||||
|
[formArgs]
|
||||||
|
: []),
|
||||||
|
walkable,
|
||||||
|
options,
|
||||||
|
context) }
|
||||||
|
|
||||||
// XXX can we add a simpler default case option where:
|
// XXX can we add a simpler default case option where:
|
||||||
// - we call the target method name (given in recursion as string)
|
// - we call the target method name (given in recursion as string)
|
||||||
@ -937,11 +946,11 @@ var BaseBrowserPrototype = {
|
|||||||
next('do', state, ...(reverse ? list.slice().reverse() : list))
|
next('do', state, ...(reverse ? list.slice().reverse() : list))
|
||||||
// user-defined recursion...
|
// user-defined recursion...
|
||||||
: recursion instanceof Function ?
|
: recursion instanceof Function ?
|
||||||
recursion.call(that, list, i, p, func, stop, useWalk, options)
|
recursion.call(that, list, i, p, options, context, func, stop, useWalk)
|
||||||
// method with arg forming...
|
// method with arg forming...
|
||||||
: formArgs instanceof Function
|
: formArgs instanceof Function
|
||||||
&& list[recursion] ?
|
&& list[recursion] ?
|
||||||
list[recursion](...(formArgs(list, i, p, func, stop, options) || []))
|
list[recursion](...(formArgs(list, i, p, options, context, func, stop) || []))
|
||||||
: useWalk())
|
: useWalk())
|
||||||
.run(function(){
|
.run(function(){
|
||||||
// normalize...
|
// normalize...
|
||||||
@ -959,7 +968,8 @@ var BaseBrowserPrototype = {
|
|||||||
|
|
||||||
// prepare context...
|
// prepare context...
|
||||||
var id = node.id || node.value
|
var id = node.id || node.value
|
||||||
path = this.path = this.path || path
|
// XXX this is all over the place -- revise path handling...
|
||||||
|
path = context.path = this.path = this.path || path
|
||||||
var [inline, p, children] =
|
var [inline, p, children] =
|
||||||
// inline...
|
// inline...
|
||||||
isWalkable(node) ?
|
isWalkable(node) ?
|
||||||
@ -968,7 +978,7 @@ var BaseBrowserPrototype = {
|
|||||||
: (!skipNested && isWalkable(node.children)) ?
|
: (!skipNested && isWalkable(node.children)) ?
|
||||||
[false,
|
[false,
|
||||||
// prepare context for nested items...
|
// prepare context for nested items...
|
||||||
this.path = path.concat([id]),
|
context.path = this.path = path.concat([id]),
|
||||||
node.children]
|
node.children]
|
||||||
// leaf...
|
// leaf...
|
||||||
: [false, path.concat([id]), undefined]
|
: [false, path.concat([id]), undefined]
|
||||||
@ -999,10 +1009,10 @@ var BaseBrowserPrototype = {
|
|||||||
function(state, mode){
|
function(state, mode){
|
||||||
// if we stopped, thread the stop up...
|
// if we stopped, thread the stop up...
|
||||||
mode == 'stopped'
|
mode == 'stopped'
|
||||||
&& stopParent instanceof Function
|
&& context.stop instanceof Function
|
||||||
&& stopParent(state)
|
&& context.stop(state)
|
||||||
// normalize the result...
|
// normalize the result...
|
||||||
return (options.root === that
|
return (context.root === that
|
||||||
&& state instanceof Array) ?
|
&& state instanceof Array) ?
|
||||||
state.flat()
|
state.flat()
|
||||||
: state },
|
: state },
|
||||||
@ -1018,49 +1028,38 @@ 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, base){
|
text: function(options, context){
|
||||||
var that = this
|
var that = this
|
||||||
options = options || {}
|
|
||||||
options = !options.root ?
|
|
||||||
Object.assign({},
|
|
||||||
this.options || {},
|
|
||||||
options,
|
|
||||||
// set call context...
|
|
||||||
{ root: this })
|
|
||||||
: options
|
|
||||||
base = base || []
|
|
||||||
|
|
||||||
return this
|
return this
|
||||||
.walk2(
|
.walk2(
|
||||||
function(node, i, path){
|
function(node, i, path){
|
||||||
return node ?
|
return node ?
|
||||||
base
|
path.slice(1)
|
||||||
.concat(path)
|
.map(e => ' ')
|
||||||
.slice(1)
|
.join('') + (node.value || node)
|
||||||
.map(e => ' ')
|
|
||||||
.join('') + (node.value || node)
|
|
||||||
: [] },
|
: [] },
|
||||||
'text',
|
'text',
|
||||||
function(func, i, path){
|
function(func, i, path, options, context){
|
||||||
return [options, base.concat(path)] },
|
return [options, context] },
|
||||||
options)
|
options,
|
||||||
.run(function(){
|
context)
|
||||||
return options.root === that ?
|
.join('\n') },
|
||||||
this.join('\n')
|
paths: function(options, context){
|
||||||
: this }) },
|
|
||||||
|
|
||||||
paths: function(options, base){
|
|
||||||
base = base || []
|
|
||||||
return this.walk2(
|
return this.walk2(
|
||||||
function(n, i, p){
|
function(n, i, p){
|
||||||
return n
|
return n
|
||||||
&& [(options || {}).joinPaths !== false ?
|
&& [(options || {}).joinPaths !== false ?
|
||||||
base.concat(p).join('/')
|
p.join('/')
|
||||||
: base.concat(p)] },
|
: p] },
|
||||||
'paths',
|
'paths',
|
||||||
function(children, i, path){
|
function(_, i, path, options, context){
|
||||||
return [options, base.concat(path)] },
|
// NOTE: for paths and indexes to be consistent between
|
||||||
options) },
|
// levels we need to thread the context on, here and
|
||||||
|
// into the base .walk2(..) call below...
|
||||||
|
return [options, context] },
|
||||||
|
options,
|
||||||
|
context) },
|
||||||
|
|
||||||
|
|
||||||
// Extended map...
|
// Extended map...
|
||||||
@ -1101,56 +1100,39 @@ var BaseBrowserPrototype = {
|
|||||||
// - support for options
|
// - support for options
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//
|
|
||||||
// XXX should we move the defaults to .config???
|
// XXX should we move the defaults to .config???
|
||||||
// XXX make item access by index lazy...
|
|
||||||
// - index nested stuff and lengths... (.sublist_length)
|
|
||||||
// - stop when target reached... (control callback???)
|
|
||||||
// XXX Q: should we have an option to treat groups as elements???
|
// XXX Q: should we have an option to treat groups as elements???
|
||||||
map: function(func, options){
|
map: function(func, options){
|
||||||
var that = this
|
var that = this
|
||||||
|
|
||||||
// parse args...
|
// parse args...
|
||||||
//
|
|
||||||
// NOTE: in addition to the user signatures documented above this
|
|
||||||
// also supports two variants used internally:
|
|
||||||
// .map(func, path[, options])
|
|
||||||
// .map(func, i, path[, options])
|
|
||||||
// these set the "base" path and index passed to func...
|
|
||||||
var args = [...arguments]
|
var args = [...arguments]
|
||||||
func = (args[0] instanceof Function
|
func = (args[0] instanceof Function
|
||||||
|| args[0] === undefined) ?
|
|| args[0] === undefined) ?
|
||||||
args.shift()
|
args.shift()
|
||||||
: undefined
|
: undefined
|
||||||
options = args[args.length-1] || {}
|
options = args.shift() || {}
|
||||||
options = !(typeof(options) == typeof(123)
|
|
||||||
|| options instanceof Array) ?
|
|
||||||
(args.pop() || {})
|
|
||||||
: {}
|
|
||||||
options = !options.defaultReverse ?
|
options = !options.defaultReverse ?
|
||||||
Object.assign({},
|
Object.assign({},
|
||||||
options,
|
options,
|
||||||
{ defaultReverse: 'flat' })
|
{ defaultReverse: 'flat' })
|
||||||
: options
|
: options
|
||||||
|
var context = args.shift()
|
||||||
|
|
||||||
|
return this.walk2(
|
||||||
return this.walk(
|
function(elem, i, path){
|
||||||
function(i, path, elem, doNested){
|
|
||||||
return elem != null ?
|
return elem != null ?
|
||||||
[func === undefined ?
|
[func === undefined ?
|
||||||
elem
|
elem
|
||||||
// XXX should this pass the current or the root
|
// XXX should this pass the current or the root
|
||||||
// container to func???
|
// container to func???
|
||||||
: func.call(that, elem, i, path, that)]
|
: func.call(that, elem, i, path, that)]
|
||||||
: [] },
|
: [] },
|
||||||
function(_, i, path, children, options){
|
'map',
|
||||||
// NOTE: this needs to call the actual func that the user
|
function(_, i, p, options, context){
|
||||||
// gave us and not the constructed function that we
|
return [func, options, context] },
|
||||||
// pass to .walk(..) above...
|
options,
|
||||||
return children.map(func, i, path, options) },
|
context) },
|
||||||
...args,
|
|
||||||
options)
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
// XXX EXPERIMENTAL...
|
// XXX EXPERIMENTAL...
|
||||||
@ -1209,7 +1191,6 @@ var BaseBrowserPrototype = {
|
|||||||
//
|
//
|
||||||
//
|
//
|
||||||
// XXX use diff
|
// XXX use diff
|
||||||
// XXX add options.ignoreKeywords ???
|
|
||||||
// XXX add support for 'next'/'prev', ... keywords... (here or in .get(..)???)
|
// XXX add support for 'next'/'prev', ... keywords... (here or in .get(..)???)
|
||||||
// XXX do we actually need to stop this as soon as we find something,
|
// XXX do we actually need to stop this as soon as we find something,
|
||||||
// i.e. options.firstOnly???
|
// i.e. options.firstOnly???
|
||||||
@ -1219,18 +1200,23 @@ var BaseBrowserPrototype = {
|
|||||||
// parse args...
|
// parse args...
|
||||||
var args = [...arguments]
|
var args = [...arguments]
|
||||||
pattern = args.shift()
|
pattern = args.shift()
|
||||||
|
pattern = pattern === undefined ?
|
||||||
|
true
|
||||||
|
: pattern
|
||||||
func = (args[0] instanceof Function
|
func = (args[0] instanceof Function
|
||||||
|| args[0] === undefined) ?
|
|| args[0] === undefined) ?
|
||||||
args.shift()
|
args.shift()
|
||||||
: undefined
|
: undefined
|
||||||
options = args[args.length-1] || {}
|
options = args.shift() || {}
|
||||||
options = !(typeof(options) == typeof(123)
|
|
||||||
|| options instanceof Array) ?
|
|
||||||
(args.pop() || {})
|
|
||||||
: {}
|
|
||||||
|
|
||||||
// handle pattern keywords...
|
var context = args.pop()
|
||||||
pattern = pattern == 'first' ?
|
|
||||||
|
// pattern -- normalize and pattern keywords...
|
||||||
|
pattern = options.ignoreKeywords ?
|
||||||
|
pattern
|
||||||
|
: (pattern === 'all' || pattern == '*') ?
|
||||||
|
true
|
||||||
|
: pattern == 'first' ?
|
||||||
0
|
0
|
||||||
: pattern == 'last' ?
|
: pattern == 'last' ?
|
||||||
-1
|
-1
|
||||||
@ -1247,7 +1233,9 @@ var BaseBrowserPrototype = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// normalize/build the test predicate...
|
// normalize/build the test predicate...
|
||||||
|
// XXX add diff support...
|
||||||
var test = (
|
var test = (
|
||||||
|
// all...
|
||||||
pattern === true ?
|
pattern === true ?
|
||||||
pattern
|
pattern
|
||||||
// predicate...
|
// predicate...
|
||||||
@ -1302,26 +1290,28 @@ var BaseBrowserPrototype = {
|
|||||||
// && elem[key] instanceof pattern)
|
// && elem[key] instanceof pattern)
|
||||||
) }, true) } )
|
) }, true) } )
|
||||||
|
|
||||||
return this.walk(
|
return this.walk2(
|
||||||
function(i, path, elem, doNested){
|
function(elem, i, path, _, stop){
|
||||||
|
console.log('---', path.join('/'))
|
||||||
// match...
|
// match...
|
||||||
// XXX should this use that???
|
var res = (elem
|
||||||
if(elem && (test === true || test.call(this, elem, i, path))){
|
&& (test === true
|
||||||
// XXX i is not logical when getting items from the
|
|| test.call(this, elem, i, path))) ?
|
||||||
// tail of the list...
|
[ func ?
|
||||||
// ...need to either set it to the negative index
|
func.call(this, elem, i, path)
|
||||||
// or .length - i (expensive?)
|
: elem ]
|
||||||
return func ?
|
: []
|
||||||
[func.call(this, elem, i, path)]
|
return ((options.firstMatch
|
||||||
: [[
|
|| typeof(pattern) == typeof(123))
|
||||||
elem,
|
&& res.length > 0) ?
|
||||||
i,
|
// XXX BUG: from nested browsers this does not stop
|
||||||
path,
|
// the current level...
|
||||||
]]
|
stop(res)
|
||||||
}
|
: res },
|
||||||
return []
|
'search',
|
||||||
},
|
function(_, i, p, options, context){
|
||||||
options)
|
return [pattern, func, options, context] },
|
||||||
|
options, context)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user