mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-11-02 12:20:08 +00:00
browser dialog filter/search now mostly works...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
eb23b632f7
commit
3dbd5367e5
@ -115,6 +115,14 @@
|
|||||||
background: rgba(0,0,0, 0.05);
|
background: rgba(0,0,0, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XXX need to make the next two different... */
|
||||||
|
.browse .list div.filtered-out {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.browse .list div.disabled {
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
.browse:focus .list div.selected {
|
.browse:focus .list div.selected {
|
||||||
background: rgba(0,0,0, 0.1);
|
background: rgba(0,0,0, 0.1);
|
||||||
box-shadow: rgba(0,0,0,0.2) 0.1em 0.1em 0.2em;
|
box-shadow: rgba(0,0,0,0.2) 0.1em 0.1em 0.2em;
|
||||||
@ -125,6 +133,30 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 10px;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-button {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-track-piece {
|
||||||
|
background: gray;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-corner {
|
||||||
|
}
|
||||||
|
::-webkit-resizer {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script src="../ext-lib/jquery.js"></script>
|
<script src="../ext-lib/jquery.js"></script>
|
||||||
@ -238,7 +270,7 @@ $(function(){
|
|||||||
[title]
|
[title]
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- the actual list -->
|
<!-- current path -->
|
||||||
<div class="v-block path">
|
<div class="v-block path">
|
||||||
<div class="dir">
|
<div class="dir">
|
||||||
[dir]
|
[dir]
|
||||||
@ -251,7 +283,7 @@ $(function(){
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- the actual list -->
|
<!-- path list -->
|
||||||
<div class="v-block list">
|
<div class="v-block list">
|
||||||
<div>
|
<div>
|
||||||
[dir]
|
[dir]
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
|
|
||||||
|
// XXX add a hook to render the content of an element...
|
||||||
// XXX NOTE: the widget itself does not need a title, that's the job for
|
// XXX NOTE: the widget itself does not need a title, that's the job for
|
||||||
// a container widget (dialog, field, ...)
|
// a container widget (dialog, field, ...)
|
||||||
// ...it can be implemented trivially via an attribute and a :before
|
// ...it can be implemented trivially via an attribute and a :before
|
||||||
@ -70,7 +71,26 @@ var BrowserPrototype = {
|
|||||||
|
|
||||||
// XXX this should prevent event handler deligation...
|
// XXX this should prevent event handler deligation...
|
||||||
keyboard: {
|
keyboard: {
|
||||||
'.browse':{
|
// filter mappings...
|
||||||
|
Filter: {
|
||||||
|
pattern: '.browse .path div.cur[contenteditable]',
|
||||||
|
|
||||||
|
// keep text edeting action from affecting the seelction...
|
||||||
|
ignore: [
|
||||||
|
'Backspace',
|
||||||
|
'Left',
|
||||||
|
'Right',
|
||||||
|
'Enter',
|
||||||
|
'Esc',
|
||||||
|
],
|
||||||
|
|
||||||
|
Enter: 'action!',
|
||||||
|
Esc: 'stopFilter!',
|
||||||
|
},
|
||||||
|
|
||||||
|
General: {
|
||||||
|
pattern: '.browse',
|
||||||
|
|
||||||
Up: 'prev',
|
Up: 'prev',
|
||||||
Backspace: 'Up',
|
Backspace: 'Up',
|
||||||
Down: 'next',
|
Down: 'next',
|
||||||
@ -79,6 +99,8 @@ var BrowserPrototype = {
|
|||||||
|
|
||||||
Enter: 'action',
|
Enter: 'action',
|
||||||
Esc: 'close',
|
Esc: 'close',
|
||||||
|
|
||||||
|
'/': 'startFilter!',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -130,21 +152,10 @@ var BrowserPrototype = {
|
|||||||
// add current selction indicator...
|
// add current selction indicator...
|
||||||
p.append($('<div>')
|
p.append($('<div>')
|
||||||
.addClass('dir cur')
|
.addClass('dir cur')
|
||||||
// XXX start search/filter...
|
|
||||||
// - on click / letter set content editable
|
|
||||||
// - triger filterig on modified
|
|
||||||
// - disable nav in favor of editing
|
|
||||||
// - enter/blur to exit edit mode
|
|
||||||
// - esc to cancel and reset
|
|
||||||
// XXX add a filter mode...
|
// XXX add a filter mode...
|
||||||
.click(function(){
|
.click(function(){
|
||||||
|
that.startFilter()
|
||||||
//that.update(path.concat($(this).text()))
|
//that.update(path.concat($(this).text()))
|
||||||
$(this)
|
|
||||||
.text('')
|
|
||||||
.attr('contenteditable', true)
|
|
||||||
.keyup(function(){
|
|
||||||
that.filter($(this).text())
|
|
||||||
})
|
|
||||||
}))
|
}))
|
||||||
|
|
||||||
// fill the children list...
|
// fill the children list...
|
||||||
@ -152,7 +163,9 @@ var BrowserPrototype = {
|
|||||||
.forEach(function(e){
|
.forEach(function(e){
|
||||||
l.append($('<div>')
|
l.append($('<div>')
|
||||||
.click(function(){
|
.click(function(){
|
||||||
that.update(that.path.concat([$(this).text()]))
|
if(!$(this).hasClass('disabled')){
|
||||||
|
that.update(that.path.concat([$(this).text()]))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.text(e))
|
.text(e))
|
||||||
})
|
})
|
||||||
@ -160,9 +173,8 @@ var BrowserPrototype = {
|
|||||||
return this
|
return this
|
||||||
},
|
},
|
||||||
|
|
||||||
// XXX should have two non_matched modes:
|
// internal actions...
|
||||||
// - hide - hide non-matching content
|
|
||||||
// - shadow - shadow non-matching content
|
|
||||||
// XXX pattern modes:
|
// XXX pattern modes:
|
||||||
// - lazy match
|
// - lazy match
|
||||||
// abc -> *abc* -> ^.*abc.*$
|
// abc -> *abc* -> ^.*abc.*$
|
||||||
@ -172,27 +184,34 @@ var BrowserPrototype = {
|
|||||||
// XXX sort:
|
// XXX sort:
|
||||||
// - as-is
|
// - as-is
|
||||||
// - best match
|
// - best match
|
||||||
filter: function(pattern, mode, non_matched, sort){
|
filter: function(pattern, non_matched, sort){
|
||||||
var that = this
|
var that = this
|
||||||
var browser = this.dom
|
var browser = this.dom
|
||||||
|
|
||||||
// show all...
|
// show all...
|
||||||
if(pattern == null || pattern.trim() == '*'){
|
if(pattern == null || pattern.trim() == '*'){
|
||||||
this.update()
|
browser.find('.filtered-out')
|
||||||
|
.removeClass('filtered-out')
|
||||||
|
// clear the highlighing...
|
||||||
|
browser.find('.list b')
|
||||||
|
.replaceWith(function() { return this.innerHTML })
|
||||||
|
|
||||||
// basic filter...
|
// basic filter...
|
||||||
} else {
|
} else {
|
||||||
var l = browser.find('.list>div')
|
var l = browser.find('.list>div:not(disabled)')
|
||||||
|
|
||||||
l.each(function(i, e){
|
l.each(function(i, e){
|
||||||
e = $(e)
|
e = $(e)
|
||||||
var t = e.text()
|
var t = e.text()
|
||||||
var i = t.search(pattern)
|
var i = t.search(pattern)
|
||||||
if(i < 0){
|
if(i < 0){
|
||||||
e.remove()
|
e
|
||||||
|
.addClass('filtered-out')
|
||||||
|
.removeClass('selected')
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
e.html(t.replace(pattern, pattern.bold()))
|
e.html(t.replace(pattern, pattern.bold()))
|
||||||
|
.removeClass('filtered-out')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -200,7 +219,49 @@ var BrowserPrototype = {
|
|||||||
return this
|
return this
|
||||||
},
|
},
|
||||||
|
|
||||||
// internal actions...
|
// XXX start search/filter...
|
||||||
|
// - set content editable
|
||||||
|
// - triger filterig on modified
|
||||||
|
// - disable nav in favor of editing
|
||||||
|
// - enter/blur to exit edit mode
|
||||||
|
// - esc to cancel and reset
|
||||||
|
// XXX BUG: when starting with '/' key the '/' gets appended to the
|
||||||
|
// field...
|
||||||
|
startFilter: function(){
|
||||||
|
var range = document.createRange()
|
||||||
|
var selection = window.getSelection()
|
||||||
|
|
||||||
|
var that = this
|
||||||
|
var e = this.dom.find('.path .dir.cur')
|
||||||
|
.text('')
|
||||||
|
.attr('contenteditable', true)
|
||||||
|
.keyup(function(){
|
||||||
|
that.filter($(this).text())
|
||||||
|
})
|
||||||
|
.focus()
|
||||||
|
|
||||||
|
// place the cursor...
|
||||||
|
range.setStart(e[0], 0)
|
||||||
|
range.collapse(true)
|
||||||
|
// XXX
|
||||||
|
selection.removeAllRanges()
|
||||||
|
selection.addRange(range)
|
||||||
|
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
stopFilter: function(){
|
||||||
|
this.filter('*')
|
||||||
|
this.dom.find('.path .dir.cur')
|
||||||
|
.text('')
|
||||||
|
.removeAttr('contenteditable')
|
||||||
|
this
|
||||||
|
.focus()
|
||||||
|
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
get filtering(){
|
||||||
|
return this.dom.find('.path .dir.cur[contenteditable]').length > 0
|
||||||
|
},
|
||||||
|
|
||||||
// Select a list element...
|
// Select a list element...
|
||||||
//
|
//
|
||||||
@ -257,9 +318,12 @@ var BrowserPrototype = {
|
|||||||
// XXX revise return values...
|
// XXX revise return values...
|
||||||
// XXX Q: should this trigger a "select" event???
|
// XXX Q: should this trigger a "select" event???
|
||||||
// XXX on string/regexp mismatch this will select the first, is this correct???
|
// XXX on string/regexp mismatch this will select the first, is this correct???
|
||||||
select: function(elem){
|
select: function(elem, filtering){
|
||||||
|
var pattern = '.list div:not(.disabled):not(.filtered-out)'
|
||||||
var browser = this.dom
|
var browser = this.dom
|
||||||
var elems = browser.find('.list div')
|
var elems = browser.find(pattern)
|
||||||
|
|
||||||
|
filtering = filtering == null ? this.filtering : filtering
|
||||||
|
|
||||||
if(elems.length == 0){
|
if(elems.length == 0){
|
||||||
return $()
|
return $()
|
||||||
@ -272,20 +336,22 @@ var BrowserPrototype = {
|
|||||||
|
|
||||||
// first/last...
|
// first/last...
|
||||||
if(elem == 'first' || elem == 'last'){
|
if(elem == 'first' || elem == 'last'){
|
||||||
return this.select(elems[elem]())
|
return this.select(elems[elem](), filtering)
|
||||||
|
|
||||||
// prev/next...
|
// prev/next...
|
||||||
} else if(elem == 'prev' || elem == 'next'){
|
} else if(elem == 'prev' || elem == 'next'){
|
||||||
var to = this.select('!', browser)[elem]('.list div')
|
var to = this.select('!', filtering)[elem + 'All'](pattern).first()
|
||||||
if(to.length == 0){
|
if(to.length == 0){
|
||||||
return this.select(elem == 'prev' ? 'last' : 'first', browser)
|
return this.select(elem == 'prev' ? 'last' : 'first', filtering)
|
||||||
}
|
}
|
||||||
this.select('none')
|
this.select('none', filtering)
|
||||||
return this.select(to)
|
return this.select(to, filtering)
|
||||||
|
|
||||||
// deselect...
|
// deselect...
|
||||||
} else if(elem == 'none'){
|
} else if(elem == 'none'){
|
||||||
browser.find('.path .dir.cur').empty()
|
if(!filtering){
|
||||||
|
browser.find('.path .dir.cur').empty()
|
||||||
|
}
|
||||||
return elems
|
return elems
|
||||||
.filter('.selected')
|
.filter('.selected')
|
||||||
.removeClass('selected')
|
.removeClass('selected')
|
||||||
@ -297,7 +363,7 @@ var BrowserPrototype = {
|
|||||||
// number...
|
// number...
|
||||||
// NOTE: on overflow this will get the first/last element...
|
// NOTE: on overflow this will get the first/last element...
|
||||||
} else if(typeof(elem) == typeof(123)){
|
} else if(typeof(elem) == typeof(123)){
|
||||||
return this.select($(elems.slice(elem)[0] || elems.slice(-1)[0] ))
|
return this.select($(elems.slice(elem)[0] || elems.slice(-1)[0] ), filtering)
|
||||||
|
|
||||||
// string...
|
// string...
|
||||||
// XXX on mismatch this will select the first, is this correct???
|
// XXX on mismatch this will select the first, is this correct???
|
||||||
@ -305,29 +371,32 @@ var BrowserPrototype = {
|
|||||||
if(/^'.*'$|^".*"$/.test(elem.trim())){
|
if(/^'.*'$|^".*"$/.test(elem.trim())){
|
||||||
elem = elem.trim().slice(1, -1)
|
elem = elem.trim().slice(1, -1)
|
||||||
}
|
}
|
||||||
return this.select(browser.find('.list div')
|
return this.select(browser.find(pattern)
|
||||||
.filter(function(i, e){
|
.filter(function(i, e){
|
||||||
return $(e).text() == elem
|
return $(e).text() == elem
|
||||||
}))
|
}), filtering)
|
||||||
|
|
||||||
// regexp...
|
// regexp...
|
||||||
// XXX on mismatch this will select the first, is this correct???
|
// XXX on mismatch this will select the first, is this correct???
|
||||||
} else if(elem.constructor === RegExp){
|
} else if(elem.constructor === RegExp){
|
||||||
return this.select(browser.find('.list div')
|
return this.select(browser.find(pattern)
|
||||||
.filter(function(i, e){
|
.filter(function(i, e){
|
||||||
return elem.test($(e).text())
|
return elem.test($(e).text())
|
||||||
}))
|
}), filtering)
|
||||||
|
|
||||||
// element...
|
// element...
|
||||||
} else {
|
} else {
|
||||||
elem = $(elem).first()
|
elem = $(elem).first()
|
||||||
|
|
||||||
if(elem.length == 0){
|
if(elem.length == 0){
|
||||||
this.select()
|
this.select(null, filtering)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
this.select('none')
|
|
||||||
browser.find('.path .dir.cur').text(elem.text())
|
this.select('none', filtering)
|
||||||
|
if(!filtering){
|
||||||
|
browser.find('.path .dir.cur').text(elem.text())
|
||||||
|
}
|
||||||
return elem.addClass('selected')
|
return elem.addClass('selected')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user