diff --git a/ui (gen4)/experiments/browse-dialog.html b/ui (gen4)/experiments/browse-dialog.html
index 3dbd5f8c..cef7f87f 100755
--- a/ui (gen4)/experiments/browse-dialog.html
+++ b/ui (gen4)/experiments/browse-dialog.html
@@ -247,11 +247,36 @@ requirejs(['../lib/keyboard', '../object', './browse-dialog'], function(k, o, br
// XXX need a way to trigger open ecents with touch/mouse...
'/dir 1': function(_, p){ console.log('dir:', p) },
'dir 1/option 1': function(_, p){ console.log('option:', p) },
- 'dir 1/option 2': function(_, p){ console.log('option:', p) },
+ 'dir 1/option 2/': function(_, p){ console.log('option:', p) },
'dir 2/option 3': function(_, p){ console.log('option:', p) },
'option 4': function(_, p){ console.log('option:', p) },
- 'option 5': function(_, p){ console.log('option:', p) },
- 'option 6': function(_, p){ console.log('option:', p) },
+
+ // XXX this is the wrong way to do this, but it shows a bug...
+ // XXX BUG: for some reason 2 and 3 are set to traversable while
+ // 1 is not...
+ 'option 5': function(_, p){
+ console.log('option:', p)
+
+ f3.update(p + '/', function(){ return [1, 2, 3] })
+ },
+
+ // render a custom sub-tree...
+ 'dynamic/*': function(path, make){
+ console.log('option:', path)
+
+ return [1,2,3]
+ .map(function(e){
+ make(e, true)
+ return e
+ })
+ },
+
+ // this will override the 'dynamic/*' in case of longer
+ // matches...
+ 'dynamic/1/1/*': function(path, make){
+ make('mooo!/')
+ make('fooo!')
+ },
})
})
diff --git a/ui (gen4)/experiments/browse-dialog.js b/ui (gen4)/experiments/browse-dialog.js
index c48030e6..685d1321 100755
--- a/ui (gen4)/experiments/browse-dialog.js
+++ b/ui (gen4)/experiments/browse-dialog.js
@@ -503,11 +503,12 @@ var BrowserPrototype = {
// path due to an error, we need to be able to render the new
// path both in the path and list sections...
// NOTE: current behaviour is not wrong, it just not too flexible...
- update: function(path){
+ update: function(path, list){
path = path || this.path
var browser = this.dom
var that = this
var focus = browser.find(':focus').length > 0
+ list = list || this.list
// string path and terminated with '/' -- no selection...
if(typeof(path) == typeof('str') && !/[\\\/]/.test(path.trim().slice(-1))){
@@ -519,7 +520,7 @@ var BrowserPrototype = {
var selection = null
}
-
+ // clear the ui...
var p = browser.find('.path').empty()
var l = browser.find('.list').empty()
@@ -583,11 +584,18 @@ var BrowserPrototype = {
}
// fill the children list...
+ // NOTE: this will be set to true if make(..) is called at least once...
var interactive = false
var make = function(p, traversable){
- traversable = traversable == null ? true : traversable
+ p = p + ''
+ var dir = /[\\\/]\s*$/
+ traversable = dir.test(p) && traversable == null ? true : traversable
+ traversable = traversable == null ? false : traversable
+ p = p.replace(dir, '')
+
interactive = true
+
var res = $('
')
// handle clicks ONLY when not disabled...
.click(function(){
@@ -603,8 +611,11 @@ var BrowserPrototype = {
return res
}
- var res = this.list(path, make)
+ // build the list...
+ var res = list.call(this, path, make)
+ // second API: make is not called and .list(..) returns an Array
+ // that will get loaded as list items...
if(!interactive){
res.forEach(make)
}
@@ -665,7 +676,7 @@ var BrowserPrototype = {
// every element that was rejected by the predicate / not matching
// the pattern.
//
- // By default, is false, thus this will ignore
+ // By default, is true, thus this will ignore
// disabled elements. If is false then disabled
// elements will be searched too.
//
@@ -1640,22 +1651,65 @@ module.makeList = function(elem, list){
/*********************************************************************/
-// This full compatible with List(..) but will parse paths in keys...
+// This is similar to List(..) but will parse paths in keys...
//
-// For example:
+// Format:
// {
-// 'a/b': ..,
-// 'a/c': ..,
-// 'd': ..,
+// // basic 'file' path...
+// // NOTE: this path is non-traversable by default, but if a
+// // sub-path handler is defined (e.g. 'dir/file/x') then this
+// // will be set traversable...
+// 'dir/file': function(evt, path){ .. },
//
+// // file object at the tree root...
+// // NOTE: the leading '/' is optional...
+// 'file': function(evt, path){ .. },
+//
+// // a directory handler is defined by path ending with '/',
+// // set traversable...
+// 'dir/dir/': function(evt, path){ .. },
+//
+//
+// // path lister...
+// 'dynamic/*': function(path, make){ .. }
// }
//
-// will translate into:
-// a/
-// b
-// c
-// d
+// The above definition will be interpreted into the following tree:
//
+// /
+// dir/
+// file
+// dir/
+// file
+// dynamic/
+// ..
+//
+// Here the contents of the '/dynamic/' path are generated by the matching
+// lister for that pattern path...
+//
+// NOTE: there may be multiple matching patterns/listers or a given path
+// the one used is the longest match.
+//
+//
+// Handler format:
+// function(evt, path){ .. }
+//
+// This function will be called on the 'open' event for the defined
+// item.
+//
+//
+// Lister format:
+// function(path, make){ .. } -> list
+//
+// This function will get called on .update(..) of the matching path.
+//
+// make(text, traversable) is a list item constructor.
+// for more docs see: Browser.list(..)
+//
+//
+// NOTE: currently only trailing '*' are supported.
+//
+// XXX add support for '*' and '**' glob patterns...
var PathListPrototype = Object.create(BrowserPrototype)
PathListPrototype.options = {
@@ -1670,48 +1724,71 @@ PathListPrototype.options = {
var visited = []
- return keys
- .map(function(k){
- var kp = k.split(/[\\\/]+/g)
- kp[0] == '' && kp.shift()
+ // get the '*' listers...
+ var lister = keys
+ .filter(function(k){ return k.trim().slice(-1) == '*' })
+ .filter(function(k){
+ return k
+ .split(/[\\\/]+/)
+ // remove the '*'...
+ .slice(0, -1)
+ // do the match...
+ .filter(function(e, i){ return e != path[i] }).length == 0 })
+ .sort(function(a, b){ return a.length - b.length})
+ .pop()
- // get and check current path, continue if relevant...
- var p = kp.splice(0, path.length)
- if(kp.length == 0
- || p.length < path.length
- || p.filter(function(e, i){ return e != path[i] }).length > 0){
- return false
- }
+ // use the custom lister (defined by trailing '*')...
+ if(data !== keys && lister){
+ return data[lister].call(this, '/' + path.join('/'), make)
+ // list via provided paths...
+ } else {
+ return keys
+ .map(function(k){
+ var kp = k.split(/[\\\/]+/g)
+ kp[0] == '' && kp.shift()
- // get current path element if one exists and we did not create it already...
- cur = kp.shift()
- if(cur == undefined){
- return false
- }
+ // see if we have a star...
+ var star = kp.slice(-1)[0] == '*'
+ star && kp.pop()
- if(visited.indexOf(cur) >= 0){
- // set element to traversable...
- if(kp.length > 0){
- that.filter(cur).removeClass('not-traversable')
+ // get and check current path, continue if relevant...
+ var p = kp.splice(0, path.length)
+ if(kp.length == 0
+ || p.length < path.length
+ || p.filter(function(e, i){ return e != path[i] }).length > 0){
+ return false
}
- return false
- }
- visited.push(cur)
- // build the element....
- var e = make(cur, kp.length > 0)
+ // get current path element if one exists and we did not create it already...
+ cur = kp.shift()
+ if(cur == undefined){
+ return false
+ }
- // setup handlers...
- if(data !== keys && kp.length == 0){
- e.on('open', function(){
- return that.options.data[k].apply(this, arguments)
- })
- }
+ if(visited.indexOf(cur) >= 0){
+ // set element to traversable...
+ if(kp.length > 0){
+ that.filter(cur).removeClass('not-traversable')
+ }
+ return false
+ }
+ visited.push(cur)
- return cur
- })
- .filter(function(e){ return e !== false })
+ // build the element....
+ var e = make(cur, star || kp.length > 0)
+
+ // setup handlers...
+ if(!star && data !== keys && kp.length == 0){
+ e.on('open', function(){
+ return that.options.data[k].apply(this, arguments)
+ })
+ }
+
+ return cur
+ })
+ .filter(function(e){ return e !== false })
+ }
},
}
PathListPrototype.options.__proto__ = BrowserPrototype.options
diff --git a/ui (gen4)/object.js b/ui (gen4)/object.js
index baaceb55..32280256 100755
--- a/ui (gen4)/object.js
+++ b/ui (gen4)/object.js
@@ -64,6 +64,13 @@ function makeConstructor(name, a, b){
}
+// super equivalent...
+var parent =
+module.parent =
+function parent(obj){
+ return obj.__proto__.__proto__
+}
+
/**********************************************************************
* vim:set ts=4 sw=4 : */