mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 18:30:09 +00:00
more work on .walk2(..) and friends...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
7a56564835
commit
c045d67a89
@ -724,6 +724,17 @@ var BrowserViewMixin = {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var viewWrap =
|
||||||
|
function(context, lst, options){
|
||||||
|
return context.view(
|
||||||
|
'as-is',
|
||||||
|
lst,
|
||||||
|
{
|
||||||
|
__proto__: context.options || {},
|
||||||
|
skipNested: 'skipNested' in (options || {}) ?
|
||||||
|
options.skipNested
|
||||||
|
: true,
|
||||||
|
}) }
|
||||||
//
|
//
|
||||||
// options format:
|
// options format:
|
||||||
// {
|
// {
|
||||||
@ -745,15 +756,16 @@ function(options){
|
|||||||
false
|
false
|
||||||
: (options.wrapper
|
: (options.wrapper
|
||||||
|| function(res){
|
|| function(res){
|
||||||
return this.view(
|
return viewWrap(this, res, options) }) }
|
||||||
'as-is',
|
|
||||||
res,
|
|
||||||
{
|
var makeFlatRunViewWrapper =
|
||||||
__proto__: this.options || {},
|
function(context, options){
|
||||||
skipNested: 'skipNested' in (options || {}) ?
|
return function(){
|
||||||
options.skipNested
|
return (options || {}).rawResults === true ?
|
||||||
: true,
|
this
|
||||||
}) }) }
|
: viewWrap(context, this, options) } }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1920,33 +1932,82 @@ var BaseBrowserPrototype = {
|
|||||||
|
|
||||||
// XXX EXPERIMENTAL -- an attempt to simplify walking...
|
// XXX EXPERIMENTAL -- an attempt to simplify walking...
|
||||||
//
|
//
|
||||||
// .walk(func, options)
|
// .walk(func[, options])
|
||||||
// -> res???
|
// -> list
|
||||||
|
// -> res
|
||||||
|
//
|
||||||
//
|
//
|
||||||
// func(elem, i, path, next(..), stop(..))
|
// func(elem, i, path, next(..), stop(..))
|
||||||
// -> res???
|
// -> [item, ..]
|
||||||
|
// -> item
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// NOTE: when options.reverse is set to true, func(..) for a parent
|
// Ignore current .children...
|
||||||
// item is still called BEFORE it is called for the children but
|
// next()
|
||||||
// its return value is placed after, i.e. the func(..) call order
|
//
|
||||||
// is different to the result order.
|
// Explicitly pass the children to handle...
|
||||||
|
// next(browser)
|
||||||
|
// next([elem, ...])
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Stop walking (returning undefined)...
|
||||||
|
// stop()
|
||||||
|
//
|
||||||
|
// Stop walking and return res...
|
||||||
|
// stop(res)
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// If func(..) returns an array it's content is merged (.flat()) into
|
||||||
|
// .walk(..)'s return value, this enables it to:
|
||||||
|
// - return more than one value per item by returning an array of values
|
||||||
|
// - return no values for an item by returning []
|
||||||
|
//
|
||||||
|
// NOTE: to explicitly return an array wrap it in another array.
|
||||||
|
//
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// options format:
|
// options format:
|
||||||
// {
|
// {
|
||||||
|
// // reverse walking...
|
||||||
|
// //
|
||||||
|
// // modes:
|
||||||
|
// // true - use .defaultReverse
|
||||||
|
// // 'mixed' - results reversed,
|
||||||
|
// // handlers called topologically
|
||||||
|
// // (i.e. container handled before children
|
||||||
|
// // but its return value is placed after)
|
||||||
|
// // 'full' - results reversed
|
||||||
|
// // (i.e. container handled after children)
|
||||||
|
// // 'tree' - results reversed topologically
|
||||||
|
// // (i.e. container handled after children)
|
||||||
|
// //
|
||||||
|
// // NOTE: in 'full' mode, next(..) has no effect, as when the
|
||||||
|
// // container handler is called the children have already
|
||||||
|
// // been processed...
|
||||||
|
// reverse: <bool> | 'mixed' | 'full' | 'tree',
|
||||||
//
|
//
|
||||||
// reverse: <bool> | 'full',
|
// defaultReverse: 'mixed',
|
||||||
//
|
//
|
||||||
// iterateNonIterable: <bool>,
|
// // if true iterate collapsed children...
|
||||||
// iterateCollapsed: <bool>,
|
// iterateCollapsed: <bool>,
|
||||||
//
|
//
|
||||||
|
// // if true iterate non-iterable elements...
|
||||||
|
// iterateNonIterable: <bool>,
|
||||||
|
//
|
||||||
|
//
|
||||||
// // shorthand for:
|
// // shorthand for:
|
||||||
// // iterateCollapsed: true, iterateNonIterable: true
|
// // iterateCollapsed: true, iterateNonIterable: true
|
||||||
// iterateAll: <bool>,
|
// iterateAll: <bool>,
|
||||||
//
|
//
|
||||||
// // XXX ???
|
// // if true call func(..) on inline block containers...
|
||||||
// //includeInlinedBlocks: <bool>,
|
// includeInlinedBlocks: <bool>,
|
||||||
|
//
|
||||||
|
// skipDisabledMode: 'node' | 'branch',
|
||||||
|
// skipDisabled: <bool> | 'node' | 'branch',
|
||||||
|
//
|
||||||
|
// // skip nested/inlined elements (children)...
|
||||||
|
// skipNested: <bool>,
|
||||||
|
// skipInlined: <bool>,
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// // list of sections to iterate...
|
// // list of sections to iterate...
|
||||||
@ -1961,6 +2022,8 @@ var BaseBrowserPrototype = {
|
|||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
// XXX should we implement next(true) to synchronously process the
|
||||||
|
// children and return the result to the caller???
|
||||||
walk2: function(func, options){
|
walk2: function(func, options){
|
||||||
var that = this
|
var that = this
|
||||||
var [func, options={}, path=[], context={}] = [...arguments]
|
var [func, options={}, path=[], context={}] = [...arguments]
|
||||||
@ -1974,8 +2037,11 @@ var BaseBrowserPrototype = {
|
|||||||
Object.create(this.options || {}),
|
Object.create(this.options || {}),
|
||||||
options)
|
options)
|
||||||
// options.reverse...
|
// options.reverse...
|
||||||
|
var reverse = options.reverse === true ?
|
||||||
|
(options.defaultReverse || 'mixed')
|
||||||
|
: options.reverse
|
||||||
var handleReverse = function(lst){
|
var handleReverse = function(lst){
|
||||||
return options.reverse ?
|
return reverse ?
|
||||||
lst.slice().reverse()
|
lst.slice().reverse()
|
||||||
: lst }
|
: lst }
|
||||||
// options.section...
|
// options.section...
|
||||||
@ -1991,8 +2057,10 @@ var BaseBrowserPrototype = {
|
|||||||
// iteration filtering...
|
// iteration filtering...
|
||||||
var iterateNonIterable = !!(options.iterateAll || options.iterateNonIterable)
|
var iterateNonIterable = !!(options.iterateAll || options.iterateNonIterable)
|
||||||
var iterateCollapsed = !!(options.iterateAll || options.iterateCollapsed)
|
var iterateCollapsed = !!(options.iterateAll || options.iterateCollapsed)
|
||||||
// XXX
|
var includeInlinedBlocks = !!options.includeInlinedBlocks
|
||||||
//var includeInlinedBlocks = !!options.includeInlinedBlocks
|
var skipDisabled = options.skipDisabled === true ?
|
||||||
|
options.skipDisabledMode || 'node'
|
||||||
|
: options.skipDisabled
|
||||||
|
|
||||||
// stopping mechanics...
|
// stopping mechanics...
|
||||||
var res, StopException
|
var res, StopException
|
||||||
@ -2009,45 +2077,50 @@ var BaseBrowserPrototype = {
|
|||||||
return function(elem){
|
return function(elem){
|
||||||
var p = path
|
var p = path
|
||||||
|
|
||||||
var children =
|
// item...
|
||||||
// skip collapsed...
|
var skipItem =
|
||||||
(!iterateCollapsed && elem.collapsed) ?
|
(skipDisabled && elem.disabled)
|
||||||
|
|| (!iterateNonIterable && elem.noniterable)
|
||||||
|
|| (!includeInlinedBlocks
|
||||||
|
&& (elem instanceof Array || elem instanceof BaseBrowser))
|
||||||
|
var p = !skipItem ?
|
||||||
|
path.concat(elem.id)
|
||||||
|
: p
|
||||||
|
var item
|
||||||
|
// NOTE: this will handle the item once and then re-return its value...
|
||||||
|
var getItem = function(){
|
||||||
|
return (item =
|
||||||
|
item !== undefined ?
|
||||||
|
item
|
||||||
|
: !skipItem ?
|
||||||
|
[ func.call(that, elem, context.index++, p, next, stop) ].flat()
|
||||||
|
: []) }
|
||||||
|
// pre-call the item if reverse is not 'full'...
|
||||||
|
reverse == 'full'
|
||||||
|
|| getItem()
|
||||||
|
|
||||||
|
// children...
|
||||||
|
var children = (
|
||||||
|
// skip...
|
||||||
|
((!iterateCollapsed && elem.collapsed)
|
||||||
|
|| (skipDisabled == 'branch')) ?
|
||||||
[]
|
[]
|
||||||
// inlined...
|
// inlined...
|
||||||
: (elem instanceof BaseBrowser
|
: !options.skipInlined
|
||||||
|| elem instanceof Array) ?
|
&& (elem instanceof BaseBrowser || elem instanceof Array) ?
|
||||||
elem
|
elem
|
||||||
// nested...
|
// nested...
|
||||||
: (elem.children || [])
|
: (!options.skipNested && elem.children) )
|
||||||
|
|| []
|
||||||
var next = function(elems){
|
var next = function(elems){
|
||||||
children = elems == null ?
|
children = elems == null ?
|
||||||
[]
|
[]
|
||||||
: elems }
|
: elems }
|
||||||
|
|
||||||
// handle item...
|
// build the result...
|
||||||
// skip non-iterable and inlined block items...
|
|
||||||
var handleItem = !((!iterateNonIterable && elem.noniterable)
|
|
||||||
|| (elem instanceof Array || elem instanceof BaseBrowser))
|
|
||||||
var p = handleItem ?
|
|
||||||
path.concat(elem.id)
|
|
||||||
: p
|
|
||||||
var item
|
|
||||||
// NOTE: this will handle the item once and then re-return the value...
|
|
||||||
var getItem = function(){
|
|
||||||
return (item =
|
|
||||||
item !== undefined ?
|
|
||||||
item
|
|
||||||
: handleItem ?
|
|
||||||
[ func.call(that, elem, context.index++, p, next, stop) ].flat()
|
|
||||||
: []) }
|
|
||||||
// pre-call the item if options.reverse is not set to 'full'...
|
|
||||||
options.reverse == 'full'
|
|
||||||
|| getItem()
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
// item...
|
// item (normal order)...
|
||||||
...!options.reverse ?
|
...!(reverse && reverse != 'tree') ?
|
||||||
getItem()
|
getItem()
|
||||||
: [],
|
: [],
|
||||||
// children...
|
// children...
|
||||||
@ -2060,12 +2133,10 @@ var BaseBrowserPrototype = {
|
|||||||
.walk2(func, options, p, context)
|
.walk2(func, options, p, context)
|
||||||
: [],
|
: [],
|
||||||
// item (in reverse)...
|
// item (in reverse)...
|
||||||
...options.reverse ?
|
...(reverse && reverse != 'tree') ?
|
||||||
getItem()
|
getItem()
|
||||||
: [], ] } }
|
: [], ] } }
|
||||||
|
|
||||||
|
|
||||||
// do the handling...
|
|
||||||
try {
|
try {
|
||||||
return handleReverse(
|
return handleReverse(
|
||||||
sections
|
sections
|
||||||
@ -2075,12 +2146,64 @@ var BaseBrowserPrototype = {
|
|||||||
.map(makeMap(path))
|
.map(makeMap(path))
|
||||||
.flat()
|
.flat()
|
||||||
|
|
||||||
// handle StopException and errors...
|
// handle stop(..) and propagate errors...
|
||||||
} catch(e){
|
} catch(e){
|
||||||
if(e === StopException){
|
if(e === StopException){
|
||||||
return res }
|
return res }
|
||||||
throw e } },
|
throw e } },
|
||||||
|
|
||||||
|
// basic iteration...
|
||||||
|
map2: function(func, options){
|
||||||
|
var that = this
|
||||||
|
options = !(options || {}).defaultReverse ?
|
||||||
|
Object.assign({},
|
||||||
|
options || {},
|
||||||
|
{ defaultReverse: 'full' })
|
||||||
|
: options
|
||||||
|
return this.walk2(
|
||||||
|
function(e, i, p){
|
||||||
|
return [func ?
|
||||||
|
func.call(that, e, i, p)
|
||||||
|
: e] },
|
||||||
|
options)
|
||||||
|
.run(makeFlatRunViewWrapper(this, options)) },
|
||||||
|
filter2: function(func, options){
|
||||||
|
var that = this
|
||||||
|
options = !(options || {}).defaultReverse ?
|
||||||
|
Object.assign({},
|
||||||
|
options || {},
|
||||||
|
{ defaultReverse: 'full' })
|
||||||
|
: options
|
||||||
|
return this.walk2(
|
||||||
|
function(e, i, p){
|
||||||
|
return func.call(that, e, i, p) ? [e] : [] },
|
||||||
|
options)
|
||||||
|
.run(makeFlatRunViewWrapper(this, options)) },
|
||||||
|
reduce2: function(func, start, options){
|
||||||
|
var that = this
|
||||||
|
options = !(options || {}).defaultReverse ?
|
||||||
|
Object.assign({},
|
||||||
|
options || {},
|
||||||
|
{ defaultReverse: 'full' })
|
||||||
|
: options
|
||||||
|
this.walk2(
|
||||||
|
function(e, i, p){
|
||||||
|
start = func.call(that, start, e, i, p) },
|
||||||
|
options)
|
||||||
|
return start },
|
||||||
|
forEach2: function(func, options){
|
||||||
|
this.map2(...arguments)
|
||||||
|
return this },
|
||||||
|
|
||||||
|
toArray2: function(options){
|
||||||
|
return this.map2(null,
|
||||||
|
Object.assign({},
|
||||||
|
options || {},
|
||||||
|
{rawResults: true})) },
|
||||||
|
|
||||||
|
// XXX search(..), get(..), ...
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Data access and iteration...
|
// Data access and iteration...
|
||||||
|
|
||||||
@ -2142,9 +2265,9 @@ var BaseBrowserPrototype = {
|
|||||||
// // Partial walking...
|
// // Partial walking...
|
||||||
// //
|
// //
|
||||||
// // XXX not implemented yet...
|
// // XXX not implemented yet...
|
||||||
// start: <index> | <path>,
|
// //start: <index> | <path>,
|
||||||
// count: <number>,
|
// //count: <number>,
|
||||||
// end: <index> | <path>,
|
// //end: <index> | <path>,
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// // Iterate ALL items...
|
// // Iterate ALL items...
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user