added generic url-history + several features that use it + some fixing and tweaking...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2015-12-09 00:04:09 +03:00
parent 5704e829b8
commit 490d45c489
5 changed files with 387 additions and 29 deletions

View File

@ -187,6 +187,12 @@
overflow: hidden;
}
.browse-widget .list>div.highlighted {
font-style: italic;
}
.browse-widget .list>div.highlighted:after {
content: '*';
}
.browse-widget:not(.flat) .list div:not(.not-traversable) .text:after {
content: "/";
}

View File

@ -161,7 +161,7 @@ TREE.dir_c.dir_b.tree = TREE
var use_disabled = true
var show_files = false
requirejs(['../keyboard', '../../object', './browse'], function(k, o, br){
requirejs(['../keyboard', '../object', './browse'], function(k, o, br){
keyboard = k
object = o
browser = br
@ -207,11 +207,13 @@ requirejs(['../keyboard', '../../object', './browse'], function(k, o, br){
'option 2',
'option 3',
'option 4',
'option 5',
'option 5/moo',
'option 6',
'option 7',
],
path: 'option 5/moo',
fullPathEdit: false,
traversable: false,
flat: true,

View File

@ -376,7 +376,11 @@ var BrowserPrototype = {
// Call the constructor's .path2list(..)..
//
// See: BrowserClassPrototype.path2list(..) for docs...
path2list: function(){
path2list: function(path){
// if list is flat we do not need to split it, just format...
if(this.options.flat && path && path.constructor !== Array){
return path == '' || path.length == 0 ? [] : [path]
}
return this.constructor.path2list.apply(this, arguments)
},
@ -1941,6 +1945,7 @@ Browser.prototype.__proto__ = widget.Widget.prototype
var ListPrototype = Object.create(BrowserPrototype)
ListPrototype.options = {
pathPrefix: '',
fullPathEdit: false,
traversable: false,
flat: true,
@ -1978,8 +1983,11 @@ object.makeConstructor('List',
// This is a shorthand for: new List(<elem>, { data: <list> })
var makeList =
module.makeList = function(elem, list){
return List(elem, { data: list })
module.makeList = function(elem, list, path){
return List(elem, {
data: list,
path: path,
})
}

View File

@ -102,7 +102,10 @@ module.GLOBAL_KEYBOARD = {
'ctrl+shift': 'F5',
},
L: 'rotateCCW',
H: 'flipHorizontal',
H: {
default: 'flipHorizontal',
ctrl: 'listURLHistory',
},
V: 'flipVertical',
P: {
'ctrl+shift': 'F12',
@ -246,7 +249,7 @@ module.GLOBAL_KEYBOARD = {
$(function(){
// list all loaded modules...
console.log('LOADED:', requirejs.s.contexts._.defined)
console.log('MODULES:', requirejs.s.contexts._.defined)
// XXX stub action set -- this needs to be auto-generated...
window.a = actions.Actions()

View File

@ -1481,7 +1481,7 @@ module.Journal = ImageGridFeatures.Feature({
clone: [function(full){
return function(res){
res.journal = null
if(full && Object.hasOwnProperty(this, 'journal') && this.journal){
if(full && this.hasOwnProperty('journal') && this.journal){
res.journal = JSON.parse(JSON.stringify(this.journal))
}
}
@ -1490,7 +1490,7 @@ module.Journal = ImageGridFeatures.Feature({
// XXX might be good to add some kind of metadata to journal...
journalPush: ['Journal/Add an item to journal',
function(){
this.journal = (Object.hasOwnProperty(this, 'journal')
this.journal = (this.hasOwnProperty('journal')
|| this.journal) ?
this.journal
: []
@ -3449,15 +3449,15 @@ var FileSystemLoaderActions = actions.Actions({
},
clone: [function(full){
return function(res){
if(this.base_path){
res.base_path = this.base_path
}
if(this.loaded_paths){
res.loaded_paths = JSON.parse(JSON.stringify(this.loaded_paths))
}
return function(res){
if(this.base_path){
res.base_path = this.base_path
}
}],
if(this.loaded_paths){
res.loaded_paths = JSON.parse(JSON.stringify(this.loaded_paths))
}
}
}],
// NOTE: these will remove the trailing '/' (or '\') unless the path
// is root...
@ -3595,6 +3595,7 @@ var FileSystemLoaderActions = actions.Actions({
// XXX use the logger...
// XXX add a recursive option...
// ...might also be nice to add sub-dirs to ribbons...
// XXX make image pattern more generic...
loadImages: ['File/Load images',
function(path, logger){
if(path == null){
@ -3603,7 +3604,7 @@ var FileSystemLoaderActions = actions.Actions({
var that = this
glob(path + '/*+(jpg|png)')
glob(path + '/*+(jpg|jpeg|png|JPG|JPEG|PNG)')
.on('end', function(lst){
that.loadURLs(lst
.map(function(p){ return normalizePath(p) }), path)
@ -3638,7 +3639,7 @@ var FileSystemLoaderActions = actions.Actions({
var base_pattern = RegExp('^'+path)
// find images...
glob(path + '/*+(jpg|png)')
glob(path + '/*+(jpg|jpeg|png|JPG|JPEG|PNG)')
.on('end', function(lst){
// create a new images chunk...
lst = lst
@ -3830,7 +3831,7 @@ module.FileSystemLoaderUI = ImageGridFeatures.Feature({
title: '',
doc: '',
tag: 'fs-loader-ui',
tag: 'ui-fs-loader',
depends: ['fs-loader'],
actions: FileSystemLoaderUIActions,
@ -3838,6 +3839,340 @@ module.FileSystemLoaderUI = ImageGridFeatures.Feature({
//---------------------------------------------------------------------
// url history...
var URLHistoryActions = actions.Actions({
config: {
'url-history-push-up-on-open': false,
// values:
// -1 - no limit.
// 0 - disabled
// 1+ - length of history
'url-history-length': 100,
},
__url_history: null,
// Format:
// {
// url: {
// open: <action-name> | <function>,
// check: <action-name> | <function>,
// },
// ...
// }
//
// NOTE: last opened url is last...
// NOTE: though functions are supported they are not recommended as
// we can not stringify them to JSON...
get url_history(){
return this.hasOwnProperty('__url_history') ? this.__url_history : undefined
},
set url_history(value){
this.__url_history = value
},
clone: [function(full){
return function(res){
res.url_history = null
if(full && this.url_history){
res.url_history = JSON.parse(JSON.stringify(this.url_history))
}
}
}],
pushURLToHistory: ['',
function(url, open, check){
var l = this.config['url-history-length'] || -1
if(l == 0){
return
}
this.url_history = this.url_history || {}
// remove the old value...
if(url in this.url_history && this.config['url-history-push-up-on-open']){
delete this.url_history[url]
}
// push url to history...
this.url_history[url] = {
open: open,
check: check,
}
// update history length...
if(l > 0){
var k = Object.keys(this.url_history)
while(k.length > l){
// drop first url in order -- last added...
this.dropURLFromHistory(k[0])
var k = Object.keys(this.url_history)
}
}
}],
// NOTE: url can be an index, 0 being the last url added to history;
// negative values are also supported.
dropURLFromHistory: ['',
function(url){
this.url_history = this.url_history || {}
url = typeof(url) == typeof(123) ?
Object.keys(this.url_history).reverse().slice(url)[0]
: url
if(url){
delete this.url_history[url]
}
}],
checkURLFromHistory: ['',
function(url){
this.url_history = this.url_history || {}
url = typeof(url) == typeof(123) ?
Object.keys(this.url_history).reverse().slice(url)[0]
: url
// if we have a check action then use it...
if(url && this.url_history[url] && this.url_history[url].check){
var check = this.url_history[url].check
if(check instanceof Function){
return check(url)
} else {
return this[check](url)
}
// no way to check so we do not know...
} else {
return true
}
}],
openURLFromHistory: ['',
function(url){
this.url_history = this.url_history || {}
url = typeof(url) == typeof(123) ?
Object.keys(this.url_history).reverse().slice(url)[0]
: url
if(url && this.url_history[url] && this.url_history[url].open){
var open = this.url_history[url].open
if(open instanceof Function){
return open(url)
} else {
return this[open](url)
}
}
}],
clearURLHistory: ['',
function(){ this.url_history = null }],
})
var URLHistory =
module.URLHistory = ImageGridFeatures.Feature({
title: '',
doc: '',
tag: 'url-history',
actions: URLHistoryActions,
})
//---------------------------------------------------------------------
var URLHistoryLocalStorageActions = actions.Actions({
config: {
'url-history-local-storage-key': 'url-history',
},
__url_history: null,
// load url history...
get url_history(){
// get the attr value...
if(this.hasOwnProperty('__url_history') && this.__url_history){
return this.__url_history
}
var key = this.config['url-history-local-storage-key']
if(key){
// get the storage value...
// if not local __url_history and we are configured, load from storage...
if(this.config && key){
var history = localStorage[key]
if(history){
this.__url_history = JSON.parse(history)
}
}
}
return this.hasOwnProperty('__url_history') ? this.__url_history : null
},
set url_history(value){
this.__url_history = value
var key = this.config['url-history-local-storage-key']
if(key){
localStorage[key] = JSON.stringify(value)
}
},
// Disable localStorage in child...
clone: [function(){
return function(res){
res.config['url-history-local-storage-key'] = null
}
}],
saveURLHistory: ['',
function(){
var key = this.config['url-history-local-storage-key']
if(key == null){
return
}
localStorage[key] =
JSON.stringify(this.url_history)
}],
})
var URLHistoryLocalStorage =
module.URLHistoryLocalStorage = ImageGridFeatures.Feature({
title: '',
doc: '',
tag: 'url-history-local-storage',
depends: [
'url-history',
],
actions: URLHistoryLocalStorageActions,
// NOTE: loading is done by the .url_history prop...
handlers: [
// save...
['pushURLToHistory dropURLFromHistory',
function(){
this.saveURLHistory()
}],
// clear...
['clearURLHistory.pre',
function(){
delete this.__url_history
var key = this.config['url-history-local-storage-key']
if(key){
delete localStorage[this.config['url-history-local-storage-key']]
}
}],
],
})
//---------------------------------------------------------------------
var URLHistoryUIActions = actions.Actions({
// XXX BUG: when running from action menu this breaks...
// ...possibly connected with restoring after .preventClosing(..)
// XXX need to highlight/select current...
// XXX need to check items...
listURLHistory: ['File/History',
function(){
var that = this
var parent = this.preventClosing ? this.preventClosing() : null
var cur = this.base_path
var o = overlay.Overlay(this.ribbons.viewer,
browse.makeList(
null,
Object.keys(this.url_history).reverse(),
// XXX for some reason this is not selected...
cur)
.open(function(evt, path){
o.close()
// close the parent ui...
parent
&& parent.close
&& parent.close()
that.openURLFromHistory(path)
}))
.close(function(){
parent
&& parent.focus
&& parent.focus()
})
// XXX HACK: for some reason arg 3 in the constructor has
// no effect...
cur && o.client
.select(cur)
.addClass('highlighted')
}],
})
var URLHistoryUI =
module.URLHistoryUI = ImageGridFeatures.Feature({
title: '',
doc: '',
tag: 'ui-url-history',
depends: [
'ui',
'url-history',
],
actions: URLHistoryUIActions,
})
//---------------------------------------------------------------------
var pushToHistory = function(action){
return [action,
function(_, path){
if(path){
this.pushURLToHistory(normalizePath(path), action)
}
}]
}
// XXX add path checking...
var FileSystemURLHistory =
module.FileSystemLoaderURLHistory = ImageGridFeatures.Feature({
title: '',
doc: '',
tag: 'fs-url-history',
depends: [
'fs-loader',
'url-history',
],
handlers: [
pushToHistory('loadImages'),
pushToHistory('loadIndex'),
pushToHistory('loadPath'),
//pushToHistory('loadNewImages'),
],
})
//---------------------------------------------------------------------
// fs writer...
@ -3876,7 +4211,7 @@ var FileSystemWriterActions = actions.Actions({
clone: [function(full){
return function(res){
res.changes = null
if(full && Object.hasOwnProperty(this, 'changes') && this.changes){
if(full && this.hasOwnProperty('changes') && this.changes){
res.changes = JSON.parse(JSON.stringify(this.changes))
}
}
@ -3927,7 +4262,7 @@ var FileSystemWriterActions = actions.Actions({
function(json, full){
json = json || this.json('base')
var changes = full ? null
: Object.hasOwnProperty(this, 'changes') ? this.changes
: this.hasOwnProperty('changes') ? this.changes
: null
return {
raw: json,
@ -4121,7 +4456,7 @@ module.FileSystemWriter = ImageGridFeatures.Feature({
].join(' '),
function(_, target){
var changes = this.changes =
Object.hasOwnProperty(this, 'changes') ?
this.hasOwnProperty('changes') ?
this.changes
: {}
@ -4137,7 +4472,7 @@ module.FileSystemWriter = ImageGridFeatures.Feature({
].join(' '),
function(_, target){
var changes = this.changes =
Object.hasOwnProperty(this, 'changes') ?
this.hasOwnProperty('changes') ?
this.changes
: {}
var images = changes.images = changes.images || []
@ -4151,7 +4486,7 @@ module.FileSystemWriter = ImageGridFeatures.Feature({
['tag untag',
function(_, tags, gids){
var changes = this.changes =
Object.hasOwnProperty(this, 'changes') ?
this.hasOwnProperty('changes') ?
this.changes
: {}
var images = changes.images = changes.images || []
@ -4199,10 +4534,10 @@ module.FileSystemWriterUI = ImageGridFeatures.Feature({
title: '',
doc: '',
tag: 'fs-writer-ui',
tag: 'ui-fs-writer',
depends: [
'fs-writer',
'fs-loader-ui',
'ui-fs-loader',
],
actions: FileSystemWriterUIActions,
@ -4235,11 +4570,14 @@ ImageGridFeatures.Feature('viewer-testing', [
'image-marks',
'image-bookmarks',
'url-history-local-storage',
'fs-loader',
'fs-loader-ui',
'ui-fs-loader',
'fs-url-history',
'fs-writer',
'fs-writer-ui',
'ui-fs-writer',
'app-control',
@ -4253,6 +4591,7 @@ ImageGridFeatures.Feature('viewer-testing', [
'ui-image-state-indicator',
'ui-global-state-indicator',
'ui-action-tree',
'ui-url-history',
// experimental and optional features...
//'auto-single-image',