Alex A. Naanou 89869f12c4 some cleanup...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
2015-12-09 02:28:38 +03:00

446 lines
8.9 KiB
HTML
Executable File

<!DOCTYPE html>
<html>
<link rel="stylesheet" href="../../css/widget/browse.css">
<style>
.browse-widget .list {
max-height: 50vh;
}
/* scrollbar setup... */
::-webkit-scrollbar {
width: 10px;
height: 10px;
}
::-webkit-scrollbar-button {
display: none;
}
::-webkit-scrollbar-track {
}
::-webkit-scrollbar-track-piece {
background: transparent;
}
::-webkit-scrollbar-track-piece {
background: rgba(0, 0, 0, 0.05);
}
::-webkit-scrollbar-thumb {
background: rgba(0, 0, 0, 0.15);
}
::-webkit-scrollbar-thumb:hover {
background: rgba(0, 0, 0, 0.3);
}
::-webkit-scrollbar-corner {
}
::-webkit-resizer {
}
/* testbed... */
.container {
display: inline-block;
position: absolute;
top: 100px;
left: 300px;
box-shadow: rgba(0,0,0,0.5) 0.1em 0.1em 0.4em;
/* make the container expand only to a certain size, then scroll */
/* XXX need to:
- shorten path to fit width
i.e. manage width manually when at max-width...
*/
max-height: 60vh;
max-width: 60vw;
height: auto;
width: auto;
overflow-y: auto;
overflow-x: hidden;
}
.container.flat {
left: 700px;
}
.container.flat2 {
left: 700px;
top: 400px;
}
.container.pathlist {
left: 700px;
top: 600px;
}
/* theaming... */
body.dark {
background: black;
color: white;
}
.dark ::-webkit-scrollbar-track-piece {
background: rgba(255, 255, 255, 0.05);
}
.dark ::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.15);
}
.dark ::-webkit-scrollbar-thumb:hover {
background: rgba(255, 255, 255, 0.3);
}
.dark .container {
border: solid 1px rgba(255, 255, 255, 0.2);
}
</style>
<script src="../../ext-lib/jquery.js"></script>
<script src="../../ext-lib/jquery-ui.js"></script>
<script src="../jli.js"></script>
<script src="../toggler.js"></script>
<script src="../../ext-lib/require.js"></script>
<!--script src="browse-dialog.js"></script-->
<script>
var TREE = {
dir_a: {},
'dir b': {
file1: 'this is a file',
file2: 'this is a file',
file3: 'this is a file',
},
dir_c: {
file1: 'this is a file',
dir_b: {
file1: 'this is a file',
},
dir_c: {},
dir_d: {},
dir_e: {},
dir_f: {},
dir_g: {},
dir_h: {},
dir_i: {},
dir_j: {},
dir_k: {},
dir_l: {},
dir_m: {},
dir_o: {},
dir_p: {},
dir_q: {},
dir_r: {},
dir_s: {},
dir_t: {},
dir_u: {},
},
file: 'this is a file',
}
// add some recursion for testing...
TREE.dir_d = TREE.dir_c.dir_b
TREE.dir_a.tree = TREE
TREE.dir_c.tree = TREE
TREE.dir_c.dir_b.tree = TREE
//---
var use_disabled = true
var show_files = false
requirejs(['../keyboard', '../object', './browse'], function(k, o, br){
keyboard = k
object = o
browser = br
// Tree demo...
b = browser.Browser($('.container.tree'), {
path: '/dir_a/tree/dir_c/',
actionButton: 'o',
list: function(path, make){
var cur = TREE
this.path2list(path).forEach(function(p){
cur = cur[p]
})
return Object.keys(cur)
// remove all strings...
.filter(function(k){
return show_files || typeof(cur[k]) != typeof('str')
})
.map(function(k){
// make the element...
var e = make(k, typeof(cur[k]) != typeof('str'))
// disable dir_b...
if(use_disabled && k == 'dir_b'){
e.addClass('disabled')
}
return k
})
},
open: function(path){
console.log('OPEN:', path)
},
})
.focus()
// Custom flat list demo...
f = browser.Browser($('.container.flat'), {
data: [
'option 1',
'option 2',
'option 3',
'option 4',
'option 5',
'option 6',
'option 7',
],
path: 'option 5',
fullPathEdit: false,
traversable: false,
flat: true,
list: function(path, make){
return this.options.data
.map(function(k){
// make the element...
var e = make(k)
// disable dir_b...
if(use_disabled && k == 'option 4'){
e.addClass('disabled')
}
if(k == 'option 3'){
e.on('open', function(){ alert('openning: option 3!') })
}
return k
})
},
open: function(path){
console.log('OPEN:', path)
},
})
// Default flat list demo...
f2 = browser.makeList($('.container.flat2'), {
'option 1': function(_, p){ console.log('option:', p) },
'option 2': function(_, p){ console.log('option:', p) },
'option 3': function(_, p){ console.log('option:', p) },
'option 4': function(_, p){ console.log('option:', p) },
})
// another way to handle the opening of items...
.open(function(evt, text){
alert('>>> ' + text)
})
// path list demo...
f3 = browser.makePathList($('.container.pathlist'), {
// build a basic tree...
// XXX need a way to trigger open events with touch/mouse...
'/dir 1': function(_, p){ console.log('dir:', p) },
'dir 1/option 1': function(_, p){ console.log('option:', p) },
// add an element to two paths...
'dir 1|dir 2|dir 3/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) },
// 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...
'bug demo': function(_, p){
console.log('option:', p)
f3.update(p + '/', function(){ return [
'not traversable?!',
'traversable!',
'also traversable!'] })
},
// render a custom sub-tree...
//'dynamic/*': function(path, make){
'dynamic/*': function(path, make){
console.log('listing:', path)
return [1,2,3]
.map(function(e){
make(e, true)
return e
})
},
// this will override the 'dynamic/*' in case of longer
// matches...
// NOTE: this will make more sence when path patterns are
// supported...
'dynamic/1/*/*': function(path, make){
make('mooo!/')
make('fooo!')
},
// include another list...
// NOTE: we need to trim the path before passing it to the
// list to avoid confusing it...
// NOTE: this will lose any instance data and works here
// befause b references TREE in a closure...
// Thus, it is recommended to avoid storing state in
// the browser object.
// ...also note that internally nothing is stored in the
// browser object, other than the options.
'browser/*': function(path, make){
var list = b.options.list
// trim off the base path...
path = this.path2list(path).slice(1)
return list.call(this, path, make)
},
})
})
$(function(){
$('.container').first().remove()
$('.container').draggable({
cancel: ".path .dir, .list div"
})
})
var themeToggler = CSSClassToggler('body',
[
'none',
'light',
'dark',
],
function(state){
$('#theme').text(state)
})
function toggleDisabled(){
use_disabled = !use_disabled
use_disabled ? b.disableElements('_b') : b.enableElements('_b')
use_disabled ? f.disableElements('4') : f.enableElements('4')
}
function toggleFiles(){
show_files = !show_files
// NOTE: we need to update only because .list(..) does not show
// files at all and we need to re-render them, another way
// would be render everything but hide and show files via CSS
// class...
b.update()
}
</script>
<body>
<button onclick="b.pop()">&lt;</button>
<button onclick="b.push()">&gt;</button>
<button onclick="b.prev()">^</button>
<button onclick="b.next()">v</button>
<br>
<br>
Theme: <button id="theme" onclick="themeToggler()">none</button>
<br>
Disabled: <button id="theme" onclick="toggleDisabled()">toggle</button>
<br>
Files: <button id="theme" onclick="toggleFiles()">toggle</button>
<br>
<br>
Basic key bindings:
<ul>
<li><code>ctrl-a<code> - edit full path </li>
<li><code>ctrl-left<code> / <code>ctrl-Backspace<code> - go to root </li>
</ul>
<div class="container">
<div class="browse-widget">
<!-- title, optional -->
<div class="v-block title">
[title]
</div>
<!-- current path -->
<div class="v-block path">
<div class="dir">
[dir]
</div>
<div class="dir">
[dir]
</div>
<div class="dir">
[dir]
</div>
</div>
<!-- path list -->
<div class="v-block list">
<div>
[dir]
</div>
<div>
[dir]
</div>
<div>
[dir]
</div>
</div>
<!-- info, optional -->
<div class="v-block info">
[info]
</div>
<!-- buttons, optional -->
<div class="v-block actions">
[actions]
</div>
</div>
</div>
<div class="container tree">
</div>
<div class="container flat">
</div>
<div class="container flat2">
</div>
<div class="container pathlist">
</div>
</body>
</html>
<!-- vim:set ts=4 sw=4 : -->