mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-11-01 11:50:07 +00:00
split out the browser widget and started testing...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
17b75ed30c
commit
a620e60af5
@ -122,6 +122,9 @@
|
|||||||
|
|
||||||
<script src="../ext-lib/require.js"></script>
|
<script src="../ext-lib/require.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
<script src="browse-dialog.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
var TREE = {
|
var TREE = {
|
||||||
@ -399,317 +402,6 @@ var KB = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//---
|
|
||||||
|
|
||||||
// XXX NOTE: the widget itself does not need a title, that's the job for
|
|
||||||
// a container widget (dialog, field, ...)
|
|
||||||
// ...it can be implemented trivially via an attribute and a :before
|
|
||||||
// CSS class...
|
|
||||||
var BrowserClassPrototype = {
|
|
||||||
// construct the dom...
|
|
||||||
make: function(options){
|
|
||||||
var browser = $('<div>')
|
|
||||||
.addClass('browse')
|
|
||||||
// make thie widget focusable...
|
|
||||||
// NOTE: tabindex 0 means automatic tab indexing and -1 means
|
|
||||||
// focusable bot not tabable...
|
|
||||||
//.attr('tabindex', -1)
|
|
||||||
.attr('tabindex', 0)
|
|
||||||
// focus the widget if something inside is clicked...
|
|
||||||
.click(function(){
|
|
||||||
$(this).focus()
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
if(options.path == null || options.show_path){
|
|
||||||
browser
|
|
||||||
.append($('<div>')
|
|
||||||
.addClass('v-block path'))
|
|
||||||
}
|
|
||||||
|
|
||||||
browser
|
|
||||||
.append($('<div>')
|
|
||||||
.addClass('v-block list'))
|
|
||||||
|
|
||||||
return browser
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX Q: should we make a base list dialog and build this on that or
|
|
||||||
// simplify this to implement a list (removing the path and disbling
|
|
||||||
// traversal)??
|
|
||||||
// XXX need a search/filter field...
|
|
||||||
// XXX need base events:
|
|
||||||
// - opne
|
|
||||||
// - update
|
|
||||||
// - select (???)
|
|
||||||
var BrowserPrototype = {
|
|
||||||
dom: null,
|
|
||||||
|
|
||||||
options: {
|
|
||||||
//path: null,
|
|
||||||
//show_path: null,
|
|
||||||
},
|
|
||||||
|
|
||||||
// XXX this should prevent event handler deligation...
|
|
||||||
keyboard: {
|
|
||||||
'.browse':{
|
|
||||||
Up: 'prev',
|
|
||||||
Backspace: 'Up',
|
|
||||||
Down: 'next',
|
|
||||||
Left: 'pop',
|
|
||||||
Right: 'push',
|
|
||||||
|
|
||||||
Enter: 'action',
|
|
||||||
Esc: 'close',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// base api...
|
|
||||||
// NOTE: to avoid duplicating and syncing data, the actual path is
|
|
||||||
// stored in DOM...
|
|
||||||
// XXX does the path includes the currently selected element?
|
|
||||||
get path(){
|
|
||||||
var skip = false
|
|
||||||
return this.dom.find('.path .dir')
|
|
||||||
.map(function(i, e){ return $(e).text() })
|
|
||||||
.toArray()
|
|
||||||
},
|
|
||||||
set path(value){
|
|
||||||
// XXX normalize path...
|
|
||||||
return this.update(path)
|
|
||||||
},
|
|
||||||
|
|
||||||
// update path...
|
|
||||||
// XXX trigger an "update" event...
|
|
||||||
update: function(path){
|
|
||||||
var browser = this.dom
|
|
||||||
|
|
||||||
var p = browser.find('.path').empty()
|
|
||||||
var l = browser.find('.list').empty()
|
|
||||||
|
|
||||||
// fill the path field...
|
|
||||||
path.forEach(function(e){
|
|
||||||
p.append($('<div>')
|
|
||||||
.addClass('dir')
|
|
||||||
.click(popDir)
|
|
||||||
.text(e))
|
|
||||||
})
|
|
||||||
|
|
||||||
// fill the children list...
|
|
||||||
this.list(path)
|
|
||||||
.forEach(function(e){
|
|
||||||
l.append($('<div>')
|
|
||||||
.click(pushDir)
|
|
||||||
.text(e))
|
|
||||||
})
|
|
||||||
|
|
||||||
return this
|
|
||||||
},
|
|
||||||
|
|
||||||
// internal actions...
|
|
||||||
|
|
||||||
// Select a list element...
|
|
||||||
//
|
|
||||||
// Select first/last child
|
|
||||||
// .select('first')
|
|
||||||
// .select('last')
|
|
||||||
// -> elem
|
|
||||||
//
|
|
||||||
// Select previous/lext child
|
|
||||||
// .select('prev')
|
|
||||||
// .select('next')
|
|
||||||
// -> elem
|
|
||||||
//
|
|
||||||
// Deselect
|
|
||||||
// .select('none')
|
|
||||||
// -> elem
|
|
||||||
//
|
|
||||||
// Get selected element if it exists, null otherwise...
|
|
||||||
// .select('!')
|
|
||||||
// -> elem
|
|
||||||
// -> $()
|
|
||||||
//
|
|
||||||
// Select element by sequence number
|
|
||||||
// .select(<number>)
|
|
||||||
// -> elem
|
|
||||||
//
|
|
||||||
// Select element by its text...
|
|
||||||
// .select('"<text>"')
|
|
||||||
// -> elem
|
|
||||||
//
|
|
||||||
// .select(<elem>)
|
|
||||||
// -> elem
|
|
||||||
//
|
|
||||||
// This will return a jQuery object.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// XXX revise return values...
|
|
||||||
// XXX Q: should this trigger a "select" event???
|
|
||||||
select: function(elem){
|
|
||||||
var browser = this.dom
|
|
||||||
var elems = browser.find('.list div')
|
|
||||||
|
|
||||||
if(elems.length == 0){
|
|
||||||
return $()
|
|
||||||
}
|
|
||||||
|
|
||||||
elem = elem || this.select('!')
|
|
||||||
// if none selected get the first...
|
|
||||||
elem = elem.length == 0 ? 'first' : elem
|
|
||||||
|
|
||||||
// first/last...
|
|
||||||
if(elem == 'first' || elem == 'last'){
|
|
||||||
return this.select(elems[elem]())
|
|
||||||
|
|
||||||
// prev/next...
|
|
||||||
} else if(elem == 'prev' || elem == 'next'){
|
|
||||||
var to = this.select('!', browser)[elem]('.list div')
|
|
||||||
if(to.length == 0){
|
|
||||||
return this.select(elem == 'prev' ? 'last' : 'first', browser)
|
|
||||||
}
|
|
||||||
this.select('none')
|
|
||||||
return this.select(to)
|
|
||||||
|
|
||||||
// deselect...
|
|
||||||
} else if(elem == 'none'){
|
|
||||||
return elems
|
|
||||||
.filter('.selected')
|
|
||||||
.removeClass('selected')
|
|
||||||
|
|
||||||
// strict...
|
|
||||||
} else if(elem == '!'){
|
|
||||||
return elems.filter('.selected')
|
|
||||||
|
|
||||||
// number...
|
|
||||||
} else if(typeof(elem) == typeof(123)){
|
|
||||||
return this.select($(elems[elem]))
|
|
||||||
|
|
||||||
// string...
|
|
||||||
} else if(typeof(elem) == typeof('str')
|
|
||||||
&& /^'.*'$|^".*"$/.test(elem.trim())){
|
|
||||||
elem = elem.trim().slice(1, -1)
|
|
||||||
return this.select(browser.find('.list div')
|
|
||||||
.filter(function(i, e){
|
|
||||||
return $(e).text() == elem
|
|
||||||
}))
|
|
||||||
|
|
||||||
// element...
|
|
||||||
} else {
|
|
||||||
this.select('none')
|
|
||||||
return elem.addClass('selected')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// XXX check if we need to do the ,action when the element id not traversable...
|
|
||||||
push: function(elem){
|
|
||||||
var browser = this.dom
|
|
||||||
var elem = this.select(elem || '!')
|
|
||||||
|
|
||||||
// nothing selected, select first and exit...
|
|
||||||
if(elem.length == 0){
|
|
||||||
this.select()
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
var path = this.path.push(elem.text())
|
|
||||||
|
|
||||||
// if not traversable call the action...
|
|
||||||
if(this.isTraversable && ! this.isTraversable(path)){
|
|
||||||
return this.action(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
this
|
|
||||||
.update(path)
|
|
||||||
.select()
|
|
||||||
|
|
||||||
return this
|
|
||||||
},
|
|
||||||
// pop an element off the path / go up one level...
|
|
||||||
pop: function(){
|
|
||||||
var browser = this.dom
|
|
||||||
var path = this.path
|
|
||||||
var dir = path.pop()
|
|
||||||
|
|
||||||
this.update(path)
|
|
||||||
|
|
||||||
this.select('"'+dir+'"')
|
|
||||||
|
|
||||||
return this
|
|
||||||
},
|
|
||||||
next: function(elem){
|
|
||||||
if(elem != null){
|
|
||||||
this.select(elem)
|
|
||||||
}
|
|
||||||
this.select('next')
|
|
||||||
return this
|
|
||||||
},
|
|
||||||
prev: function(elem){
|
|
||||||
if(elem != null){
|
|
||||||
this.select(elem)
|
|
||||||
}
|
|
||||||
this.select('prev')
|
|
||||||
return this
|
|
||||||
},
|
|
||||||
|
|
||||||
// XXX think about the API...
|
|
||||||
// XXX trigger an "open" event...
|
|
||||||
action: function(){
|
|
||||||
var elem = this.select('!')
|
|
||||||
|
|
||||||
// nothing selected, select first and exit...
|
|
||||||
if(elem.length == 0){
|
|
||||||
this.select()
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
var path = this.path.push(elem.text())
|
|
||||||
|
|
||||||
var res = this.open(path)
|
|
||||||
|
|
||||||
return res
|
|
||||||
},
|
|
||||||
|
|
||||||
// extension methods...
|
|
||||||
open: function(){ },
|
|
||||||
list: function(){ },
|
|
||||||
isTraversable: null,
|
|
||||||
|
|
||||||
// XXX need to get a container....
|
|
||||||
// XXX prepare/merge options...
|
|
||||||
__init__: function(parent, options){
|
|
||||||
// XXX merge options...
|
|
||||||
// XXX
|
|
||||||
|
|
||||||
// build the dom...
|
|
||||||
var dom = this.dom = this.constructor.make(options)
|
|
||||||
|
|
||||||
// add keyboard handler...
|
|
||||||
dom.keydown(
|
|
||||||
keyboard.makeKeyboardHandler(
|
|
||||||
this.keyboard,
|
|
||||||
// XXX
|
|
||||||
function(k){ window.DEBUG && console.log(k) },
|
|
||||||
this))
|
|
||||||
|
|
||||||
// attach to parent...
|
|
||||||
if(parent != null){
|
|
||||||
parent.append(dom)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
var Browser =
|
|
||||||
//module.Browser =
|
|
||||||
object.makeConstructor('Browser',
|
|
||||||
BrowserClassPrototype,
|
|
||||||
BrowserPrototype)
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---
|
//---
|
||||||
|
|
||||||
|
|
||||||
@ -725,20 +417,45 @@ requirejs(['../lib/keyboard', '../object'], function(k, o){
|
|||||||
KB,
|
KB,
|
||||||
function(k){ window.DEBUG && console.log(k) }))
|
function(k){ window.DEBUG && console.log(k) }))
|
||||||
|
|
||||||
|
|
||||||
|
Browser = object.makeConstructor('Browser',
|
||||||
|
BrowserClassPrototype,
|
||||||
|
BrowserPrototype)
|
||||||
|
|
||||||
|
|
||||||
|
b = Browser($('.container').last(), {
|
||||||
|
list: function(path){
|
||||||
|
var cur = TREE
|
||||||
|
path.forEach(function(p){
|
||||||
|
cur = cur[p]
|
||||||
|
})
|
||||||
|
|
||||||
|
return Object.keys(cur)
|
||||||
|
.filter(function(k){
|
||||||
|
// XXX stub...
|
||||||
|
return typeof(cur[k]) != typeof('str')
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.focus()
|
||||||
})
|
})
|
||||||
|
|
||||||
$(function(){
|
$(function(){
|
||||||
|
/*
|
||||||
var browser = make()
|
var browser = make()
|
||||||
$('.container')
|
$('.container').first()
|
||||||
.empty()
|
.empty()
|
||||||
.append(browser)
|
.append(browser)
|
||||||
showPath(browser, '/', TREE)
|
showPath(browser, '/', TREE)
|
||||||
|
*/
|
||||||
|
|
||||||
|
$('.container').first().remove()
|
||||||
|
|
||||||
$('.container').draggable({
|
$('.container').draggable({
|
||||||
cancel: ".path .dir, .list div"
|
cancel: ".path .dir, .list div"
|
||||||
})
|
})
|
||||||
|
|
||||||
browser.focus()
|
//browser.focus()
|
||||||
})
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@ -796,6 +513,8 @@ $(function(){
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
346
ui (gen4)/experiments/browse-dialog.js
Executable file
346
ui (gen4)/experiments/browse-dialog.js
Executable file
@ -0,0 +1,346 @@
|
|||||||
|
/**********************************************************************
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
**********************************************************************/
|
||||||
|
|
||||||
|
//var DEBUG = DEBUG != null ? DEBUG : true
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************************************/
|
||||||
|
|
||||||
|
// XXX NOTE: the widget itself does not need a title, that's the job for
|
||||||
|
// a container widget (dialog, field, ...)
|
||||||
|
// ...it can be implemented trivially via an attribute and a :before
|
||||||
|
// CSS class...
|
||||||
|
var BrowserClassPrototype = {
|
||||||
|
// construct the dom...
|
||||||
|
make: function(options){
|
||||||
|
var browser = $('<div>')
|
||||||
|
.addClass('browse')
|
||||||
|
// make thie widget focusable...
|
||||||
|
// NOTE: tabindex 0 means automatic tab indexing and -1 means
|
||||||
|
// focusable bot not tabable...
|
||||||
|
//.attr('tabindex', -1)
|
||||||
|
.attr('tabindex', 0)
|
||||||
|
// focus the widget if something inside is clicked...
|
||||||
|
.click(function(){
|
||||||
|
$(this).focus()
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
if(options.path == null || options.show_path){
|
||||||
|
browser
|
||||||
|
.append($('<div>')
|
||||||
|
.addClass('v-block path'))
|
||||||
|
}
|
||||||
|
|
||||||
|
browser
|
||||||
|
.append($('<div>')
|
||||||
|
.addClass('v-block list'))
|
||||||
|
|
||||||
|
return browser
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX Q: should we make a base list dialog and build this on that or
|
||||||
|
// simplify this to implement a list (removing the path and disbling
|
||||||
|
// traversal)??
|
||||||
|
// XXX need a search/filter field...
|
||||||
|
// XXX need base events:
|
||||||
|
// - opne
|
||||||
|
// - update
|
||||||
|
// - select (???)
|
||||||
|
// XXX add "current selection" to the path...
|
||||||
|
var BrowserPrototype = {
|
||||||
|
dom: null,
|
||||||
|
|
||||||
|
options: {
|
||||||
|
//path: null,
|
||||||
|
//show_path: null,
|
||||||
|
},
|
||||||
|
|
||||||
|
// XXX this should prevent event handler deligation...
|
||||||
|
keyboard: {
|
||||||
|
'.browse':{
|
||||||
|
Up: 'prev',
|
||||||
|
Backspace: 'Up',
|
||||||
|
Down: 'next',
|
||||||
|
Left: 'pop',
|
||||||
|
Right: 'push',
|
||||||
|
|
||||||
|
Enter: 'action',
|
||||||
|
Esc: 'close',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// base api...
|
||||||
|
// NOTE: to avoid duplicating and syncing data, the actual path is
|
||||||
|
// stored in DOM...
|
||||||
|
// XXX does the path includes the currently selected element?
|
||||||
|
get path(){
|
||||||
|
var skip = false
|
||||||
|
return this.dom.find('.path .dir')
|
||||||
|
.map(function(i, e){ return $(e).text() })
|
||||||
|
.toArray()
|
||||||
|
},
|
||||||
|
set path(value){
|
||||||
|
console.log('!!!', value)
|
||||||
|
// XXX normalize path...
|
||||||
|
return this.update(value)
|
||||||
|
},
|
||||||
|
|
||||||
|
// update path...
|
||||||
|
// XXX trigger an "update" event...
|
||||||
|
update: function(path){
|
||||||
|
var browser = this.dom
|
||||||
|
var that = this
|
||||||
|
|
||||||
|
var p = browser.find('.path').empty()
|
||||||
|
var l = browser.find('.list').empty()
|
||||||
|
|
||||||
|
// fill the path field...
|
||||||
|
path.forEach(function(e){
|
||||||
|
p.append($('<div>')
|
||||||
|
.addClass('dir')
|
||||||
|
.click(function(){ that.pop() })
|
||||||
|
.text(e))
|
||||||
|
})
|
||||||
|
|
||||||
|
// fill the children list...
|
||||||
|
this.list(path)
|
||||||
|
.forEach(function(e){
|
||||||
|
l.append($('<div>')
|
||||||
|
.click(function(){ that.push() })
|
||||||
|
.text(e))
|
||||||
|
})
|
||||||
|
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
|
||||||
|
// internal actions...
|
||||||
|
|
||||||
|
// Select a list element...
|
||||||
|
//
|
||||||
|
// Select first/last child
|
||||||
|
// .select('first')
|
||||||
|
// .select('last')
|
||||||
|
// -> elem
|
||||||
|
//
|
||||||
|
// Select previous/lext child
|
||||||
|
// .select('prev')
|
||||||
|
// .select('next')
|
||||||
|
// -> elem
|
||||||
|
//
|
||||||
|
// Deselect
|
||||||
|
// .select('none')
|
||||||
|
// -> elem
|
||||||
|
//
|
||||||
|
// Get selected element if it exists, null otherwise...
|
||||||
|
// .select('!')
|
||||||
|
// -> elem
|
||||||
|
// -> $()
|
||||||
|
//
|
||||||
|
// Select element by sequence number
|
||||||
|
// .select(<number>)
|
||||||
|
// -> elem
|
||||||
|
//
|
||||||
|
// Select element by its text...
|
||||||
|
// .select('"<text>"')
|
||||||
|
// -> elem
|
||||||
|
//
|
||||||
|
// .select(<elem>)
|
||||||
|
// -> elem
|
||||||
|
//
|
||||||
|
// This will return a jQuery object.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// XXX revise return values...
|
||||||
|
// XXX Q: should this trigger a "select" event???
|
||||||
|
select: function(elem){
|
||||||
|
var browser = this.dom
|
||||||
|
var elems = browser.find('.list div')
|
||||||
|
|
||||||
|
if(elems.length == 0){
|
||||||
|
return $()
|
||||||
|
}
|
||||||
|
|
||||||
|
elem = elem || this.select('!')
|
||||||
|
// if none selected get the first...
|
||||||
|
elem = elem.length == 0 ? 'first' : elem
|
||||||
|
|
||||||
|
// first/last...
|
||||||
|
if(elem == 'first' || elem == 'last'){
|
||||||
|
return this.select(elems[elem]())
|
||||||
|
|
||||||
|
// prev/next...
|
||||||
|
} else if(elem == 'prev' || elem == 'next'){
|
||||||
|
var to = this.select('!', browser)[elem]('.list div')
|
||||||
|
if(to.length == 0){
|
||||||
|
return this.select(elem == 'prev' ? 'last' : 'first', browser)
|
||||||
|
}
|
||||||
|
this.select('none')
|
||||||
|
return this.select(to)
|
||||||
|
|
||||||
|
// deselect...
|
||||||
|
} else if(elem == 'none'){
|
||||||
|
return elems
|
||||||
|
.filter('.selected')
|
||||||
|
.removeClass('selected')
|
||||||
|
|
||||||
|
// strict...
|
||||||
|
} else if(elem == '!'){
|
||||||
|
return elems.filter('.selected')
|
||||||
|
|
||||||
|
// number...
|
||||||
|
} else if(typeof(elem) == typeof(123)){
|
||||||
|
return this.select($(elems[elem]))
|
||||||
|
|
||||||
|
// string...
|
||||||
|
} else if(typeof(elem) == typeof('str')
|
||||||
|
&& /^'.*'$|^".*"$/.test(elem.trim())){
|
||||||
|
elem = elem.trim().slice(1, -1)
|
||||||
|
return this.select(browser.find('.list div')
|
||||||
|
.filter(function(i, e){
|
||||||
|
return $(e).text() == elem
|
||||||
|
}))
|
||||||
|
|
||||||
|
// element...
|
||||||
|
} else {
|
||||||
|
this.select('none')
|
||||||
|
return elem.addClass('selected')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
push: function(elem){
|
||||||
|
var browser = this.dom
|
||||||
|
var elem = this.select(elem || '!')
|
||||||
|
|
||||||
|
// nothing selected, select first and exit...
|
||||||
|
if(elem.length == 0){
|
||||||
|
this.select()
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
var path = this.path
|
||||||
|
path.push(elem.text())
|
||||||
|
|
||||||
|
// if not traversable call the action...
|
||||||
|
if(this.isTraversable != null
|
||||||
|
&& (this.isTraversable !== false
|
||||||
|
|| ! this.isTraversable(path))){
|
||||||
|
return this.action(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.path = path
|
||||||
|
|
||||||
|
this.select()
|
||||||
|
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
// pop an element off the path / go up one level...
|
||||||
|
pop: function(){
|
||||||
|
var browser = this.dom
|
||||||
|
var path = this.path
|
||||||
|
var dir = path.pop()
|
||||||
|
|
||||||
|
this.update(path)
|
||||||
|
|
||||||
|
this.select('"'+dir+'"')
|
||||||
|
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
next: function(elem){
|
||||||
|
if(elem != null){
|
||||||
|
this.select(elem)
|
||||||
|
}
|
||||||
|
this.select('next')
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
prev: function(elem){
|
||||||
|
if(elem != null){
|
||||||
|
this.select(elem)
|
||||||
|
}
|
||||||
|
this.select('prev')
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
|
||||||
|
focus: function(){
|
||||||
|
this.dom.focus()
|
||||||
|
return thsi
|
||||||
|
},
|
||||||
|
|
||||||
|
// XXX think about the API...
|
||||||
|
// XXX trigger an "open" event...
|
||||||
|
action: function(){
|
||||||
|
var elem = this.select('!')
|
||||||
|
|
||||||
|
// nothing selected, select first and exit...
|
||||||
|
if(elem.length == 0){
|
||||||
|
this.select()
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
var path = this.path.push(elem.text())
|
||||||
|
|
||||||
|
var res = this.open(path)
|
||||||
|
|
||||||
|
return res
|
||||||
|
},
|
||||||
|
|
||||||
|
// extension methods...
|
||||||
|
open: function(path){
|
||||||
|
var m = this.options.list
|
||||||
|
return m ? m.call(this, path) : path
|
||||||
|
},
|
||||||
|
list: function(path){
|
||||||
|
var m = this.options.list
|
||||||
|
return m ? m.call(this, path) : path
|
||||||
|
},
|
||||||
|
isTraversable: null,
|
||||||
|
|
||||||
|
// XXX need to get a container....
|
||||||
|
// XXX prepare/merge options...
|
||||||
|
// XXX setup instance events...
|
||||||
|
__init__: function(parent, options){
|
||||||
|
// XXX merge options...
|
||||||
|
// XXX
|
||||||
|
this.options = options
|
||||||
|
|
||||||
|
// build the dom...
|
||||||
|
var dom = this.dom = this.constructor.make(options)
|
||||||
|
|
||||||
|
// add keyboard handler...
|
||||||
|
dom.keydown(
|
||||||
|
keyboard.makeKeyboardHandler(
|
||||||
|
this.keyboard,
|
||||||
|
// XXX
|
||||||
|
function(k){ window.DEBUG && console.log(k) },
|
||||||
|
this))
|
||||||
|
|
||||||
|
// attach to parent...
|
||||||
|
if(parent != null){
|
||||||
|
parent.append(dom)
|
||||||
|
}
|
||||||
|
|
||||||
|
// load the initial state...
|
||||||
|
this.update(this.path)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
var Browser =
|
||||||
|
//module.Browser =
|
||||||
|
object.makeConstructor('Browser',
|
||||||
|
BrowserClassPrototype,
|
||||||
|
BrowserPrototype)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* vim:set ts=4 sw=4 : */
|
||||||
Loading…
x
Reference in New Issue
Block a user