mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 10:20:08 +00:00
.walk(..) experiment almost done...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
b5cf08f12e
commit
ed0c942676
@ -501,6 +501,7 @@ var BaseBrowserPrototype = {
|
|||||||
// calls for such items...
|
// calls for such items...
|
||||||
//
|
//
|
||||||
// XXX revise options handling for .__list__(..)
|
// XXX revise options handling for .__list__(..)
|
||||||
|
// XXX make(browser) should add a browser as-is without any options... (???)
|
||||||
make: function(options){
|
make: function(options){
|
||||||
options = Object.assign(Object.create(this.options || {}), options || {})
|
options = Object.assign(Object.create(this.options || {}), options || {})
|
||||||
|
|
||||||
@ -510,83 +511,112 @@ var BaseBrowserPrototype = {
|
|||||||
|
|
||||||
// item constructor...
|
// item constructor...
|
||||||
//
|
//
|
||||||
|
// Make an item...
|
||||||
// make(value[, options])
|
// make(value[, options])
|
||||||
// make(value, func[, options])
|
// make(value, func[, options])
|
||||||
// -> make
|
// -> make
|
||||||
//
|
//
|
||||||
|
// Inline a browser instance...
|
||||||
|
// make(browser)
|
||||||
|
// -> make
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// NOTE: when inlining a browser, options are ignored.
|
||||||
|
// NOTE: when inlining a browser it's .parent will be set this
|
||||||
|
// reusing the inlined object browser may mess up this
|
||||||
|
// property...
|
||||||
|
//
|
||||||
|
// XXX problem: make(Browser(..), ..) and make.group(...) produce
|
||||||
|
// different formats -- the first stores {value: browser, ...}
|
||||||
|
// while the latter stores a list of items.
|
||||||
|
// ...would be more logical to store the object (i.e. browser/list)
|
||||||
|
// directly as the element...
|
||||||
var make_called = false
|
var make_called = false
|
||||||
var make = function(value, opts){
|
var make = function(value, opts){
|
||||||
make_called = true
|
make_called = true
|
||||||
var args = [...arguments]
|
|
||||||
|
|
||||||
opts = opts || {}
|
// special-case: inlined browser...
|
||||||
// handle: make(.., func, ..)
|
//
|
||||||
opts = opts instanceof Function ?
|
// NOTE: we ignore opts here...
|
||||||
{open: opts}
|
// XXX not sure if this is the right way to go...
|
||||||
: opts
|
// ...for removal just remove the if statement and its
|
||||||
// handle trailing options...
|
// first branch...
|
||||||
opts = args.length > 2 ?
|
if(value instanceof Browser){
|
||||||
Object.assign({},
|
var item = value
|
||||||
args.pop(),
|
item.parent = this
|
||||||
opts)
|
|
||||||
: opts
|
|
||||||
opts = Object.assign(
|
|
||||||
{},
|
|
||||||
opts,
|
|
||||||
{value: value})
|
|
||||||
|
|
||||||
// item id...
|
// normal item...
|
||||||
var key = this.__key__(opts)
|
} else {
|
||||||
var id_changed = (old_index[key] || {}).id_changed
|
var args = [...arguments]
|
||||||
|
opts = opts || {}
|
||||||
|
// handle: make(.., func, ..)
|
||||||
|
opts = opts instanceof Function ?
|
||||||
|
{open: opts}
|
||||||
|
: opts
|
||||||
|
// handle trailing options...
|
||||||
|
opts = args.length > 2 ?
|
||||||
|
Object.assign({},
|
||||||
|
args.pop(),
|
||||||
|
opts)
|
||||||
|
: opts
|
||||||
|
opts = Object.assign(
|
||||||
|
{},
|
||||||
|
opts,
|
||||||
|
{value: value})
|
||||||
|
|
||||||
// handle duplicate ids -> err if found...
|
// item id...
|
||||||
if(opts.id && opts.id in new_index){
|
var key = this.__key__(opts)
|
||||||
throw new Error(`make(..): duplicate id "${key}": `
|
var id_changed = (old_index[key] || {}).id_changed
|
||||||
+`can't create multiple items with the same key.`) }
|
|
||||||
// handle duplicate keys...
|
// handle duplicate ids -> err if found...
|
||||||
// NOTE: we can't reuse an old copy when re-making the list
|
if(opts.id && opts.id in new_index){
|
||||||
// because there is now way to correctly identify an
|
throw new Error(`make(..): duplicate id "${key}": `
|
||||||
// object when it's id is tweaked (and we can not rely
|
|
||||||
// on item order)...
|
|
||||||
// ...for this reason all "persistent" state for such
|
|
||||||
// an element will be lost when calling .make(..) again
|
|
||||||
// and re-making the list...
|
|
||||||
// a solution to this would be to manually assign an .id
|
|
||||||
// to such elements in .__list__(..)...
|
|
||||||
// XXX can we go around this without requiring the user
|
|
||||||
// to manage ids???
|
|
||||||
var k = key
|
|
||||||
while(k in new_index){
|
|
||||||
// duplicate keys disabled...
|
|
||||||
if(options.noDuplicateValues){
|
|
||||||
throw new Error(`make(..): duplicate key "${key}": `
|
|
||||||
+`can't create multiple items with the same key.`) }
|
+`can't create multiple items with the same key.`) }
|
||||||
|
// handle duplicate keys...
|
||||||
|
// NOTE: we can't reuse an old copy when re-making the list
|
||||||
|
// because there is now way to correctly identify an
|
||||||
|
// object when it's id is tweaked (and we can not rely
|
||||||
|
// on item order)...
|
||||||
|
// ...for this reason all "persistent" state for such
|
||||||
|
// an element will be lost when calling .make(..) again
|
||||||
|
// and re-making the list...
|
||||||
|
// a solution to this would be to manually assign an .id
|
||||||
|
// to such elements in .__list__(..)...
|
||||||
|
// XXX can we go around this without requiring the user
|
||||||
|
// to manage ids???
|
||||||
|
var k = key
|
||||||
|
while(k in new_index){
|
||||||
|
// duplicate keys disabled...
|
||||||
|
if(options.noDuplicateValues){
|
||||||
|
throw new Error(`make(..): duplicate key "${key}": `
|
||||||
|
+`can't create multiple items with the same key.`) }
|
||||||
|
|
||||||
// mark both the current and the first items as id-mutated...
|
// mark both the current and the first items as id-mutated...
|
||||||
opts.id_changed = true
|
opts.id_changed = true
|
||||||
new_index[key].id_changed = true
|
new_index[key].id_changed = true
|
||||||
|
|
||||||
// create a new key...
|
// create a new key...
|
||||||
k = this.__id__(key)
|
k = this.__id__(key)
|
||||||
|
}
|
||||||
|
key = opts.id = k
|
||||||
|
|
||||||
|
// build the item...
|
||||||
|
var item = Object.assign(
|
||||||
|
Object.create(options || {}),
|
||||||
|
// get the old item values (only for non duplicate items)...
|
||||||
|
id_changed ?
|
||||||
|
{}
|
||||||
|
: old_index[key] || {},
|
||||||
|
// XXX inherit from this...
|
||||||
|
opts,
|
||||||
|
{
|
||||||
|
parent: this,
|
||||||
|
})
|
||||||
|
|
||||||
|
// XXX do we need both this and the above ref???
|
||||||
|
item.sublist instanceof Browser
|
||||||
|
&& (item.sublist.parent = this)
|
||||||
}
|
}
|
||||||
key = opts.id = k
|
|
||||||
|
|
||||||
// build the item...
|
|
||||||
var item = Object.assign(
|
|
||||||
Object.create(options || {}),
|
|
||||||
// get the old item values (only for non duplicate items)...
|
|
||||||
id_changed ?
|
|
||||||
{}
|
|
||||||
: old_index[key] || {},
|
|
||||||
// XXX inherit from this...
|
|
||||||
opts,
|
|
||||||
{
|
|
||||||
parent: this,
|
|
||||||
})
|
|
||||||
|
|
||||||
// XXX do we need both this and the above ref???
|
|
||||||
item.sublist instanceof Browser
|
|
||||||
&& (item.sublist.parent = this)
|
|
||||||
|
|
||||||
// store the item...
|
// store the item...
|
||||||
items.push(item)
|
items.push(item)
|
||||||
@ -1191,19 +1221,28 @@ var BaseBrowserPrototype = {
|
|||||||
: this })
|
: this })
|
||||||
.map(function(elem){
|
.map(function(elem){
|
||||||
return (
|
return (
|
||||||
// item not iterable -> skip...
|
|
||||||
(!iterateNonIterable && elem.noniterable) ?
|
|
||||||
[]
|
|
||||||
// group...
|
// group...
|
||||||
: elem instanceof Array ?
|
(elem instanceof Array ?
|
||||||
walk(path, elem)
|
walk(path, elem)
|
||||||
|
// item not iterable -> skip...
|
||||||
|
: !iterateNonIterable && elem.noniterable) ?
|
||||||
|
[]
|
||||||
|
// elem is Browser (inline)...
|
||||||
|
: elem instanceof Browser ?
|
||||||
|
elem.map(func,
|
||||||
|
options.inlinedPaths ?
|
||||||
|
path.concat(elem.id)
|
||||||
|
: path.slice(),
|
||||||
|
options)
|
||||||
// value is Browser (inline)...
|
// value is Browser (inline)...
|
||||||
|
/*/ XXX legacy...
|
||||||
: elem.value instanceof Browser ?
|
: elem.value instanceof Browser ?
|
||||||
elem.value.map(func,
|
elem.value.map(func,
|
||||||
options.inlinedPaths ?
|
options.inlinedPaths ?
|
||||||
path.concat(elem.id)
|
path.concat(elem.id)
|
||||||
: path.slice(),
|
: path.slice(),
|
||||||
options)
|
options)
|
||||||
|
//*/
|
||||||
// .sublist is Browser (nested)...
|
// .sublist is Browser (nested)...
|
||||||
: (!skipNested
|
: (!skipNested
|
||||||
&& elem.sublist instanceof Browser) ?
|
&& elem.sublist instanceof Browser) ?
|
||||||
@ -1228,7 +1267,106 @@ var BaseBrowserPrototype = {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// XXX EXPERIMENTAL...
|
||||||
|
//
|
||||||
|
// .walk(func[, options])
|
||||||
|
// -> result
|
||||||
|
//
|
||||||
|
// func(elem, nested, sublist)
|
||||||
|
// -> array
|
||||||
|
//
|
||||||
|
// nested(list[, options])
|
||||||
|
// -> items
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// XXX this should be just like .map(..) but add ability to handle
|
||||||
|
// node types in func...
|
||||||
|
// this can be done in several ways:
|
||||||
|
// - pass type info + control callback (do/skip)
|
||||||
|
// - pass a set of handlers
|
||||||
|
// (a-la how .render(..) uses node render methods)
|
||||||
walk: function(func, options){
|
walk: function(func, options){
|
||||||
|
var that = this
|
||||||
|
|
||||||
|
// parse args...
|
||||||
|
var args = [...arguments]
|
||||||
|
func = args[0] instanceof Function ?
|
||||||
|
args.shift()
|
||||||
|
: undefined
|
||||||
|
var path = (args[0] instanceof Array
|
||||||
|
|| typeof(args[0]) == typeof('str')) ?
|
||||||
|
args.shift()
|
||||||
|
: []
|
||||||
|
path = path instanceof Array ? path : [path]
|
||||||
|
var options = args.pop() || {}
|
||||||
|
|
||||||
|
var walk = function(path, list){
|
||||||
|
return list
|
||||||
|
// XXX add reversing support...
|
||||||
|
.map(function(elem){
|
||||||
|
var elem_id = elem.id || elem.value
|
||||||
|
|
||||||
|
// these will be set in the return expression below...
|
||||||
|
var sublist
|
||||||
|
var p
|
||||||
|
|
||||||
|
var nested_called = false
|
||||||
|
var nested = function(list, opts){
|
||||||
|
nested_called = true
|
||||||
|
return list instanceof Array ?
|
||||||
|
walk(p, list)
|
||||||
|
: list.walk(func, p, opts || options) }
|
||||||
|
|
||||||
|
return (
|
||||||
|
// inline browser or array...
|
||||||
|
(elem instanceof Array
|
||||||
|
|| elem instanceof Browser) ?
|
||||||
|
func.call(that,
|
||||||
|
p = path,
|
||||||
|
null,
|
||||||
|
nested,
|
||||||
|
sublist = elem)
|
||||||
|
// nested browser / array...
|
||||||
|
: (elem.sublist instanceof Browser
|
||||||
|
|| elem.sublist instanceof Array) ?
|
||||||
|
func.call(that,
|
||||||
|
p = path.concat([elem_id]),
|
||||||
|
elem,
|
||||||
|
nested,
|
||||||
|
// XXX handle elem.collapsed and friends...
|
||||||
|
sublist = elem.sublist)
|
||||||
|
// normal element...
|
||||||
|
: func.call(that,
|
||||||
|
p = path.concat([elem_id]),
|
||||||
|
elem,
|
||||||
|
null,
|
||||||
|
sublist = null) )
|
||||||
|
// append nested elements...
|
||||||
|
.concat((!sublist || nested_called) ?
|
||||||
|
[]
|
||||||
|
: nested(sublist))
|
||||||
|
})
|
||||||
|
.flat()
|
||||||
|
}
|
||||||
|
|
||||||
|
return walk(path, this.items)
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
map2: function(func, options){
|
||||||
|
var that = this
|
||||||
|
var args = [...arguments]
|
||||||
|
func = args[0] instanceof Function ?
|
||||||
|
args.shift()
|
||||||
|
: undefined
|
||||||
|
var options = args.pop() || {}
|
||||||
|
|
||||||
|
return this.walk(function(path, elem){
|
||||||
|
return elem != null ?
|
||||||
|
[func === undefined ?
|
||||||
|
elem
|
||||||
|
: func.call(that, elem, path)]
|
||||||
|
: [] }, options)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user