reworked .walk2(..) to include one common use case + some docs...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2019-05-06 03:34:40 +03:00
parent 9e7c25ed47
commit 486f951b71

View File

@ -780,12 +780,25 @@ var BaseBrowserPrototype = {
// //
// Get list of nodes in tree...
// .walk2() // .walk2()
// -> list // -> list
// //
// .walk2(func[, options]) // Walk the tree passing each node to func(..)
// .walk2(func, recursion[, options]) // .walk2(func(..)[, options])
// .walk2(func, recursion, walkable[, options]) // -> list
//
// Walk tree passing each node to func(..) using method name to
// walk nested browsers...
// NOTE: 'walk2' is used as name if name is not present in the object...
// .walk2(func(..), name, args(..)[, options])
// .walk2(func(..), name, args(..), walkable(..)[, options])
// -> list
//
// Walk tree passign each node to func(..) and handle nested browser
// walking in recursion(..) optionally testing if walkable with walkable(..)
// .walk2(func(..), recursion(..)[, options])
// .walk2(func(..), recursion(..), walkable(..)[, options])
// -> list // -> list
// //
// //
@ -799,7 +812,12 @@ var BaseBrowserPrototype = {
// //
// //
// Handle walkable node children (recursively)... // Handle walkable node children (recursively)...
// recursion(children, index, path, func(..), stop(..), options) // recursion(children, index, path, func(..), stop(..), walk(), options)
// -> list
//
//
// Prepare arguments for call of name function on nested browser...
// args(...list)
// -> list // -> list
// //
// //
@ -820,6 +838,7 @@ var BaseBrowserPrototype = {
// function to func... // function to func...
// XXX this uses a slightly different signature to func(..) that .walk(..) does... // XXX this uses a slightly different signature to func(..) that .walk(..) does...
// XXX can this be simpler??? // XXX can this be simpler???
//walk2: function(func, name, formArgs, walkable, options){
walk2: function(func, recursion, walkable, options){ walk2: function(func, recursion, walkable, options){
var that = this var that = this
@ -834,12 +853,21 @@ var BaseBrowserPrototype = {
|| args[0] == null) ? || args[0] == null) ?
args.shift() args.shift()
: undefined : undefined
var formArgs = (typeof(recursion) == typeof('str')
&& args[0] instanceof Function) ?
args.shift()
: null
var walkable = (args[0] instanceof Function var walkable = (args[0] instanceof Function
|| args[0] == null) ? || args[0] == null) ?
args.shift() args.shift()
: null : null
options = args.shift() || {} options = args.shift() || {}
// sanity check...
if(formArgs == null && typeof(recursion) == typeof('str')){
throw new Error(`.walk2(func, name, formArgs, ..): `
+`expected function as third argument, got: ${formArgs}.`) }
// recursion-threaded args... // recursion-threaded args...
var i = args.shift() || 0 var i = args.shift() || 0
var path = args.shift() || [] var path = args.shift() || []
@ -864,7 +892,12 @@ var BaseBrowserPrototype = {
function(node){ function(node){
return node instanceof Array || walkable(node) } return node instanceof Array || walkable(node) }
: function(node){ : function(node){
return node && (node instanceof Array || node.walk2) } return node
&& (node instanceof Array
// requested method name is available...
|| (typeof(recursion) == typeof('str')
&& node[recursion])
|| node.walk2 ) }
return walk( return walk(
function(state, node, next, stop){ function(state, node, next, stop){
@ -887,6 +920,14 @@ var BaseBrowserPrototype = {
[] []
: list : list
var useWalk = function(){
return list.walk2(func, recursion, walkable, options, i, p, stop) }
// XXX can we add a simpler default case option where:
// - we call the target method name (given in recursion as string)
// - need a way to form the arguments, i.e. get the
// current state and form the args for the next call...
// - if above not available, call walk()
return (list === false ? return (list === false ?
[] []
: list instanceof Array ? : list instanceof Array ?
@ -894,8 +935,12 @@ 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, options) recursion.call(that, list, i, p, func, stop, useWalk, options)
: list.walk2(func, recursion, walkable, options, i, p, stop)) // method with arg forming...
: formArgs instanceof Function
&& list[recursion] ?
list[recursion](...(formArgs(list, i, p, func, stop, options) || []))
: useWalk())
.run(function(){ .run(function(){
// normalize... // normalize...
nested = this instanceof Array ? nested = this instanceof Array ?
@ -993,10 +1038,9 @@ var BaseBrowserPrototype = {
.map(e => ' ') .map(e => ' ')
.join('') + (node.value || node) .join('') + (node.value || node)
: [] }, : [] },
function(children, i, path){ 'text',
return children.text(options, base.concat(path)) }, function(func, i, path){
function(node){ return [options, base.concat(path)] },
return node && node.text instanceof Function },
options) options)
.run(function(){ .run(function(){
return options.root === that ? return options.root === that ?
@ -1014,18 +1058,10 @@ var BaseBrowserPrototype = {
&& [(options || {}).joinPaths !== false ? && [(options || {}).joinPaths !== false ?
base.concat(p).join('/') base.concat(p).join('/')
: base.concat(p)] }, : base.concat(p)] },
'paths',
function(children, i, path){ function(children, i, path){
return children.paths(options, base.concat(path)) }, return [options, base.concat(path)] },
function(node){
return node && node.paths instanceof Function },
options) }, options) },
paths2: function(options){
return this.walk2(
function(n, i, p){
return n
&& [ (options || {}).joinPaths !== false ?
p.join('/')
: p ] }, options) },
// Extended map... // Extended map...