457 lines
11 KiB
JavaScript
Raw Normal View History

/**********************************************************************
*
*
*
**********************************************************************/
define(function(require){ var module = {}
//var DEBUG = DEBUG != null ? DEBUG : true
var actions = require('lib/actions')
var features = require('lib/features')
var core = require('features/core')
var overlay = require('lib/widget/overlay')
var browse = require('lib/widget/browse')
/*********************************************************************/
// 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))
}
}
}],
setTopURLHistory: ['- History/',
function(url){
var data = this.url_history[url]
if(data == null){
return
}
delete this.url_history[url]
this.url_history[url] = data
}],
pushURLToHistory: ['- History/',
function(url, open, check){
var l = this.config['url-history-length'] || -1
if(l == 0){
return
}
url = url || this.location.path
open = open || this.location.method
check = check || 'checkPath'
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: ['- History/',
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: ['- History/',
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(typeof(check) == typeof('str')){
return this[check](url)
} else {
return check(url)
}
// no way to check so we do not know...
} else {
return true
}
}],
openURLFromHistory: ['- History/',
function(url, open){
this.url_history = this.url_history || {}
url = typeof(url) == typeof(123) ?
Object.keys(this.url_history).reverse().slice(url)[0]
: url
if(url && !open && this.url_history[url] && this.url_history[url].open){
open = this.url_history[url].open
}
if(url && open){
if(open instanceof Function){
return open(url)
} else {
return this[open](url)
}
}
}],
clearURLHistory: ['History/',
function(){ this.url_history = null }],
})
var URLHistory =
module.URLHistory = core.ImageGridFeatures.Feature({
title: '',
doc: '',
tag: 'url-history',
depends: [
'location',
],
actions: URLHistoryActions,
})
//---------------------------------------------------------------------
// XXX should this be responsible for saving and loading of .location???
// ...on one hand it's part of the history, on the other it's part
// of file loader...
var URLHistoryLocalStorageActions = actions.Actions({
config: {
'url-history-local-storage-key': 'url-history',
'url-history-loaded-local-storage-key': 'url-history-loaded',
},
__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){
try{
this.__url_history = JSON.parse(history)
} catch(e) {
delete localStorage[key]
}
}
}
}
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
res.config['url-history-loaded-local-storage-key'] = null
}
}],
saveURLHistory: ['History/',
function(){
var history = this.config['url-history-local-storage-key']
if(history != null){
localStorage[history] =
JSON.stringify(this.url_history)
}
this.saveLocation()
}],
saveLocation: ['History/',
function(){
var loaded = this.config['url-history-loaded-local-storage-key']
if(loaded != null){
localStorage[loaded] = JSON.stringify(this.location || {})
}
}],
loadLastSavedBasePath: ['- History/',
function(){
var loaded = this.config['url-history-loaded-local-storage-key']
if(loaded && localStorage[loaded]){
var l = JSON.parse(localStorage[loaded])
this.openURLFromHistory(l.path, l.method)
} else {
this.openURLFromHistory(0)
}
}]
})
var URLHistoryLocalStorage =
module.URLHistoryLocalStorage = core.ImageGridFeatures.Feature({
title: '',
doc: '',
tag: 'url-history-local-storage',
depends: [
'ui',
'url-history',
],
isApplicable: function(){ return localStorage != null },
actions: URLHistoryLocalStorageActions,
// NOTE: loading is done by the .url_history prop...
handlers: [
['start',
function(){ this.loadLastSavedBasePath() }],
['stop.pre',
function(){ this.saveURLHistory() }],
// save base_path...
['load loadURLs',
function(){ this.location && this.location.path && this.saveLocation() }],
// save...
['pushURLToHistory dropURLFromHistory setTopURLHistory',
function(){
this.saveURLHistory()
}],
// clear...
['clearURLHistory.pre',
function(){
delete this.__url_history
var history = this.config['url-history-local-storage-key']
if(history){
delete localStorage[history]
}
var loaded = this.config['url-history-loaded-local-storage-key']
if(loaded){
delete localStorage[loaded]
}
}],
],
})
//---------------------------------------------------------------------
var URLHistoryUIActions = actions.Actions({
config: {
// Indicate when to remove striked items from url history list
//
// Supported values:
// - true | undefined - always remove
// - flase - never remove
// - [ 'open', 'close' ] - explicitly select event
'url-history-list-clear': ['open', 'close'],
},
// XXX BUG: when running from action menu this breaks...
// ...possibly connected with restoring after .preventClosing(..)
// XXX need to check items...
// XXX use svg icons for buttons...
listURLHistory: ['History|File/Show history',
function(){
var that = this
var parent = this.preventClosing ? this.preventClosing() : null
var cur = this.location.path
var to_remove = []
// remove stirked out elements...
var removeStriked = function(evt){
var rem = that.config['url-history-list-clear']
if(rem == false || rem != null && rem.indexOf(evt) < 0){
return
}
to_remove.forEach(function(e){
that.dropURLFromHistory(e)
})
to_remove = []
}
var o = overlay.Overlay(this.ribbons.viewer,
browse.makeList(
null,
Object.keys(this.url_history).reverse(),
{
// add item buttons...
itemButtons: [
// move to top...
['&diams;',
function(p){
var top = this.filter('*', false).first()
var cur = this.filter('"'+p+'"', false)
if(!top.is(cur)){
top.before(cur)
that.setTopURLHistory(p)
}
}],
// mark for removal...
['&times;',
function(p){
var e = this.filter('"'+p+'"', false)
.toggleClass('strike-out')
if(e.hasClass('strike-out')){
to_remove.indexOf(p) < 0
&& to_remove.push(p)
} else {
var i = to_remove.indexOf(p)
if(i >= 0){
to_remove.splice(i, 1)
}
}
}],
],
})
.open(function(evt, path){
removeStriked('open')
o.close()
// close the parent ui...
parent
&& parent.close
&& parent.close()
that.openURLFromHistory(path)
}))
.close(function(){
removeStriked('close')
parent
&& parent.focus
&& parent.focus()
})
var list = o.client
Object.keys(this.url_history).reverse().forEach(function(p){
that.checkURLFromHistory(p) || list.filter(p).addClass('disabled')
})
// select and highlight current path...
cur && list
.select(cur)
.addClass('highlighted')
return o
}],
})
var URLHistoryUI =
module.URLHistoryUI = core.ImageGridFeatures.Feature({
title: '',
doc: '',
tag: 'ui-url-history',
depends: [
'ui',
'url-history',
],
actions: URLHistoryUIActions,
})
/**********************************************************************
* vim:set ts=4 sw=4 : */
return module })