mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-28 18:00:09 +00:00
migrated some code to ig-types...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
7e2714198e
commit
b23e9777b7
@ -26,6 +26,7 @@ var requirejs_cfg = {
|
|||||||
//'ext-lib/preact': './node_modules/preact/dist/preact.dev',
|
//'ext-lib/preact': './node_modules/preact/dist/preact.dev',
|
||||||
|
|
||||||
'lib/object': 'node_modules/ig-object/object',
|
'lib/object': 'node_modules/ig-object/object',
|
||||||
|
'lib/types': 'node_modules/ig-types/',
|
||||||
'lib/actions': 'node_modules/ig-actions/actions',
|
'lib/actions': 'node_modules/ig-actions/actions',
|
||||||
'lib/features': 'node_modules/ig-features/features',
|
'lib/features': 'node_modules/ig-features/features',
|
||||||
//'lib/keyboard': './node_modules/ig-keyboard/keyboard',
|
//'lib/keyboard': './node_modules/ig-keyboard/keyboard',
|
||||||
@ -39,6 +40,7 @@ var requirejs_cfg = {
|
|||||||
// ...these enable the npm modules reference each other in
|
// ...these enable the npm modules reference each other in
|
||||||
// a cross-platform manner....
|
// a cross-platform manner....
|
||||||
'ig-object': 'lib/object',
|
'ig-object': 'lib/object',
|
||||||
|
'ig-types': 'lib/types',
|
||||||
'ig-actions': 'lib/actions',
|
'ig-actions': 'lib/actions',
|
||||||
'ig-features': 'lib/features',
|
'ig-features': 'lib/features',
|
||||||
|
|
||||||
@ -47,6 +49,9 @@ var requirejs_cfg = {
|
|||||||
'generic-walk': 'lib/walk',
|
'generic-walk': 'lib/walk',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
packages: [
|
||||||
|
'lib/types',
|
||||||
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -34,6 +34,8 @@ var overlay = require('lib/widget/overlay')
|
|||||||
var browse = require('lib/widget/browse')
|
var browse = require('lib/widget/browse')
|
||||||
var browseWalk = require('lib/widget/browse-walk')
|
var browseWalk = require('lib/widget/browse-walk')
|
||||||
|
|
||||||
|
var containers = require('lib/types/containers')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
@ -2562,50 +2564,6 @@ module.FileSystemWriter = core.ImageGridFeatures.Feature({
|
|||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
// Writer UI...
|
// Writer UI...
|
||||||
|
|
||||||
var object = require('lib/object')
|
|
||||||
|
|
||||||
// XXX move this to browse2 and use it as an option/basis for list...
|
|
||||||
// XXX BUG: UniqueKeyMap([['a', 123], ...]) breaks...
|
|
||||||
var UniqueKeyMap = object.Constructor('UniqueKeyMap', Map, {
|
|
||||||
// Format:
|
|
||||||
// Map([
|
|
||||||
// [ <elem>, <original-name> ],
|
|
||||||
// ...
|
|
||||||
// ])
|
|
||||||
//
|
|
||||||
// XXX make this a non-enumerable prop...
|
|
||||||
__names: null,
|
|
||||||
|
|
||||||
__name_pattern__: '$NAME ($COUNT)',
|
|
||||||
|
|
||||||
// XXX problem: non unique elems will override each other in .__names...
|
|
||||||
set: function(key, elem){
|
|
||||||
// elem already in index -> rename...
|
|
||||||
// XXX should we have the restriction of requiring unique elements???
|
|
||||||
if(this.__names.has(elem)){
|
|
||||||
return this.rename(this.__names.get(elem), key) }
|
|
||||||
this.__names[elem] = key
|
|
||||||
var n = key
|
|
||||||
var i = 0
|
|
||||||
while(this.has(n)){
|
|
||||||
i++
|
|
||||||
n = this.__name_pattern__
|
|
||||||
.replace(/\$NAME/, key)
|
|
||||||
.replace(/\$COUNT/, i) }
|
|
||||||
return object.parentCall(UniqueKeyMap.prototype, 'set', this, n, elem) },
|
|
||||||
delete: function(key){
|
|
||||||
delete this.__names[this.get(key)]
|
|
||||||
return object.parentCall(UniqueKeyMap.prototype, 'delete', this, key) },
|
|
||||||
rename: function(from, to){
|
|
||||||
var e = this.get(from)
|
|
||||||
this.delete(from)
|
|
||||||
return this.set(to, e) },
|
|
||||||
|
|
||||||
__init__: function(){
|
|
||||||
this.__names = new Map() },
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
// XXX add writer UI feature...
|
// XXX add writer UI feature...
|
||||||
// - save as.. (browser)
|
// - save as.. (browser)
|
||||||
// - save if not base path present (browser)
|
// - save if not base path present (browser)
|
||||||
@ -3177,90 +3135,10 @@ var FileSystemWriterUIActions = actions.Actions({
|
|||||||
var that = this
|
var that = this
|
||||||
var logger = this.logger && this.logger.push('exportPresets')
|
var logger = this.logger && this.logger.push('exportPresets')
|
||||||
|
|
||||||
// XXX need a way for index to support unique names and to do it
|
|
||||||
// in a stable manner:
|
|
||||||
// - getName(..) must generate the same title for
|
|
||||||
// the same item, i.e. 'abc' -> 'abc (3)' -> 'abc (3)' ...
|
|
||||||
// ...this may be done like this:
|
|
||||||
// - index format (buildIndex(..)):
|
|
||||||
// {
|
|
||||||
// <title>: [ <index>, ... ],
|
|
||||||
// ...
|
|
||||||
// }
|
|
||||||
// - title format (used by getPreset(..)):
|
|
||||||
// "<title>" -> index = 0
|
|
||||||
// "<title> (<index>)" -> index = <index>
|
|
||||||
// - cache name with index in a Map(..) with preset as key
|
|
||||||
//
|
|
||||||
// Format:
|
|
||||||
// Map([
|
|
||||||
// [<preset>, {
|
|
||||||
// base: <base-name>,
|
|
||||||
// index: <index>,
|
|
||||||
// name: "<base-name> (<index>)",
|
|
||||||
// }],
|
|
||||||
// ...
|
|
||||||
// ])
|
|
||||||
var getName = function(elem, index){
|
|
||||||
// add to index...
|
|
||||||
if(index){
|
|
||||||
var data = index.get(elem) || {}
|
|
||||||
index.has(elem)
|
|
||||||
|| index.set(elem, data) }
|
|
||||||
|
|
||||||
// generate base name...
|
|
||||||
// NOTE: we always do this unconditionally so as not to
|
|
||||||
// mess with keeping things in sync...
|
|
||||||
var date = preset.date
|
|
||||||
&& Date.fromTimeStamp(preset.date).toShortDate()
|
|
||||||
date = date ?
|
|
||||||
date + ' - '
|
|
||||||
: ''
|
|
||||||
var clean = preset['clean-target'] ?
|
|
||||||
''
|
|
||||||
: ' (merge)'
|
|
||||||
var base = data.base =
|
|
||||||
date
|
|
||||||
+ (preset.name
|
|
||||||
|| ( preset.mode == 'Images only' ?
|
|
||||||
// XXX might be a good idea to move name patterns to .config
|
|
||||||
`${ preset.mode }: `
|
|
||||||
+`"${ preset['preview-name-pattern'] }" → "${ preset.path }"${ clean }`
|
|
||||||
: `${ preset.mode }: → "${ preset.path }"${ clean }`))
|
|
||||||
// generate a unique name...
|
|
||||||
var name = base
|
|
||||||
var i = 0
|
|
||||||
while(name in index.names){
|
|
||||||
data.index = ++i
|
|
||||||
// XXX might be a good idea to move name patterns to .config
|
|
||||||
name = `${ base } (${ i })` }
|
|
||||||
data.name = name
|
|
||||||
index.names[name] = elem
|
|
||||||
return name }
|
|
||||||
var getElem = function(title, index){
|
|
||||||
return index.names[title] }
|
|
||||||
var delElem = function(title, index){
|
|
||||||
var e = index.names[title]
|
|
||||||
delete index.names[title]
|
|
||||||
index.delete(e)
|
|
||||||
return index }
|
|
||||||
var renameElem = function(from, to, index){
|
|
||||||
var e = getElem(from, index)
|
|
||||||
if(to.trim() == ''){
|
|
||||||
delete e.name
|
|
||||||
} else {
|
|
||||||
e.name = to.trim() }
|
|
||||||
delete index.names[from]
|
|
||||||
getName(e, index)
|
|
||||||
return index }
|
|
||||||
var buildCache = function(list){
|
|
||||||
//var index = new Map()
|
|
||||||
//var index.names = {}
|
|
||||||
// populate the index...
|
|
||||||
list
|
|
||||||
.forEach(function(e){ getName(e, index) })
|
|
||||||
return index }
|
|
||||||
|
|
||||||
|
// XXX use this as index...
|
||||||
|
// XXX use this in browse2...
|
||||||
|
var index = containers.UniqueKeyMap()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -7,436 +7,8 @@
|
|||||||
(function(require){ var module={} // make module AMD/node compatible...
|
(function(require){ var module={} // make module AMD/node compatible...
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
|
|
||||||
require('object-run')
|
var types = require('lib/types')
|
||||||
|
module.patchDate = types.patchDate
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
// Object...
|
|
||||||
|
|
||||||
// Get all the accessible keys...
|
|
||||||
//
|
|
||||||
// This is different to Object.keys(..) in that this will return keys
|
|
||||||
// from all the prototypes in the inheritance chain while .keys(..) will
|
|
||||||
// only return the keys defined in the current object only.
|
|
||||||
Object.deepKeys = function(obj){
|
|
||||||
var res = []
|
|
||||||
while(obj != null){
|
|
||||||
res = res.concat(Object.keys(obj))
|
|
||||||
obj = obj.__proto__
|
|
||||||
}
|
|
||||||
return res.unique() }
|
|
||||||
|
|
||||||
|
|
||||||
// Make a full key set copy of an object...
|
|
||||||
//
|
|
||||||
// NOTE: this will not deep-copy the values...
|
|
||||||
Object.flatCopy = function(obj){
|
|
||||||
var res = {}
|
|
||||||
Object.deepKeys(obj).forEach(function(key){
|
|
||||||
res[key] = obj[key]
|
|
||||||
})
|
|
||||||
return res }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
// Array...
|
|
||||||
|
|
||||||
// Array.prototype.flat polyfill...
|
|
||||||
//
|
|
||||||
// NOTE: .flat(..) is not yet supported in IE/Edge...
|
|
||||||
Array.prototype.flat
|
|
||||||
|| (Array.prototype.flat = function(depth){
|
|
||||||
depth = typeof(depth) == typeof(123) ? depth : 1
|
|
||||||
return this.reduce(function(res, e){
|
|
||||||
return res.concat(e instanceof Array && depth > 0 ?
|
|
||||||
e.flat(depth-1)
|
|
||||||
: [e]) }, []) })
|
|
||||||
|
|
||||||
|
|
||||||
// Array.prototype.includes polyfill...
|
|
||||||
//
|
|
||||||
Array.prototype.includes
|
|
||||||
|| (Array.prototype.includes = function(value){
|
|
||||||
return this.indexOf(value) >= 0 })
|
|
||||||
|
|
||||||
|
|
||||||
// first/last element access short-hands...
|
|
||||||
//
|
|
||||||
// .first()
|
|
||||||
// .last()
|
|
||||||
// -> elem
|
|
||||||
//
|
|
||||||
// .first(value)
|
|
||||||
// .last(value)
|
|
||||||
// -> array
|
|
||||||
//
|
|
||||||
// NOTE: setting a value will overwrite an existing first/last value.
|
|
||||||
// NOTE: for an empty array both .first(..)/.last(..) will return undefined
|
|
||||||
// when getting a value and set the 0'th value when setting...
|
|
||||||
Array.prototype.first
|
|
||||||
|| (Array.prototype.first = function(value){
|
|
||||||
return arguments.length > 0 ?
|
|
||||||
((this[0] = value), this)
|
|
||||||
: this[0]})
|
|
||||||
Array.prototype.last
|
|
||||||
|| (Array.prototype.last = function(value){
|
|
||||||
return arguments.length > 0 ?
|
|
||||||
((this[this.length - 1 || 0] = value), this)
|
|
||||||
: this[this.length - 1]})
|
|
||||||
|
|
||||||
|
|
||||||
/*/ XXX not yet sure should these be funcs or props...
|
|
||||||
'first' in Array.prototype
|
|
||||||
|| Object.defineProperty(Array.prototype, 'first', {
|
|
||||||
enumerable: false,
|
|
||||||
get : function () {
|
|
||||||
return this[0] },
|
|
||||||
set : function(value){
|
|
||||||
this[0] = value
|
|
||||||
return this }, })
|
|
||||||
|
|
||||||
'last' in Array.prototype
|
|
||||||
|| Object.defineProperty(Array.prototype, 'last', {
|
|
||||||
enumerable: false,
|
|
||||||
get : function () {
|
|
||||||
return this[this.length - 1] },
|
|
||||||
set : function(value){
|
|
||||||
this[this.length - 1 || 0] = value
|
|
||||||
return this }, })
|
|
||||||
//*/
|
|
||||||
|
|
||||||
|
|
||||||
// Compact a sparse array...
|
|
||||||
//
|
|
||||||
// NOTE: this will not compact in-place.
|
|
||||||
Array.prototype.compact = function(){
|
|
||||||
return this.filter(function(){ return true }) }
|
|
||||||
|
|
||||||
|
|
||||||
// like .length but for sparse arrays will return the element count...
|
|
||||||
'len' in Array.prototype
|
|
||||||
|| Object.defineProperty(Array.prototype, 'len', {
|
|
||||||
get : function () {
|
|
||||||
return Object.keys(this).length
|
|
||||||
},
|
|
||||||
set : function(val){},
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
// Convert an array to object...
|
|
||||||
//
|
|
||||||
// Format:
|
|
||||||
// {
|
|
||||||
// <item>: <index>,
|
|
||||||
// ...
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// NOTE: items should be strings, other types will get converted to
|
|
||||||
// strings and thus may mess things up.
|
|
||||||
// NOTE: this will forget repeating items...
|
|
||||||
// NOTE: normalize will slow things down...
|
|
||||||
Array.prototype.toKeys = function(normalize){
|
|
||||||
return normalize ?
|
|
||||||
this.reduce(function(r, e, i){
|
|
||||||
r[normalize(e)] = i
|
|
||||||
return r }, {})
|
|
||||||
: this.reduce(function(r, e, i){
|
|
||||||
r[e] = i
|
|
||||||
return r }, {}) }
|
|
||||||
|
|
||||||
|
|
||||||
// Convert an array to a map...
|
|
||||||
//
|
|
||||||
// This is similar to Array.prototype.toKeys(..) but does not restrict
|
|
||||||
// value type to string.
|
|
||||||
//
|
|
||||||
// Format:
|
|
||||||
// Map([
|
|
||||||
// [<item>, <index>],
|
|
||||||
// ...
|
|
||||||
// ])
|
|
||||||
//
|
|
||||||
// NOTE: this will forget repeating items...
|
|
||||||
// NOTE: normalize will slow things down...
|
|
||||||
Array.prototype.toMap = function(normalize){
|
|
||||||
return normalize ?
|
|
||||||
this
|
|
||||||
.reduce(function(m, e, i){
|
|
||||||
m.set(normalize(e), i)
|
|
||||||
return m }, new Map())
|
|
||||||
: this
|
|
||||||
.reduce(function(m, e, i){
|
|
||||||
m.set(e, i)
|
|
||||||
return m }, new Map()) }
|
|
||||||
|
|
||||||
|
|
||||||
// Return an array with duplicate elements removed...
|
|
||||||
//
|
|
||||||
// NOTE: order is preserved...
|
|
||||||
Array.prototype.unique = function(normalize){
|
|
||||||
return normalize ?
|
|
||||||
[...new Map(this.map(function(e){ return [normalize(e), e] })).values()]
|
|
||||||
: [...new Set(this)] }
|
|
||||||
Array.prototype.tailUnique = function(normalize){
|
|
||||||
return this
|
|
||||||
.slice()
|
|
||||||
.reverse()
|
|
||||||
.unique(normalize)
|
|
||||||
.reverse() }
|
|
||||||
|
|
||||||
// Compare two arrays...
|
|
||||||
//
|
|
||||||
Array.prototype.cmp = function(other){
|
|
||||||
if(this === other){
|
|
||||||
return true }
|
|
||||||
if(this.length != other.length){
|
|
||||||
return false }
|
|
||||||
for(var i=0; i<this.length; i++){
|
|
||||||
if(this[i] != other[i]){
|
|
||||||
return false } }
|
|
||||||
return true }
|
|
||||||
|
|
||||||
|
|
||||||
// Compare two Arrays as sets...
|
|
||||||
//
|
|
||||||
// This will ignore order
|
|
||||||
//
|
|
||||||
// XXX should we use Set(..) here???
|
|
||||||
Array.prototype.setCmp = function(other){
|
|
||||||
return this === other
|
|
||||||
|| this
|
|
||||||
.unique()
|
|
||||||
.sort()
|
|
||||||
.cmp(other
|
|
||||||
.unique()
|
|
||||||
.sort()) }
|
|
||||||
|
|
||||||
|
|
||||||
Array.prototype.sortAs = function(other){
|
|
||||||
return this.sort(function(a, b){
|
|
||||||
var i = other.indexOf(a)
|
|
||||||
var j = other.indexOf(b)
|
|
||||||
return i < 0 && j < 0 ? 0
|
|
||||||
: i < 0 ? 1
|
|
||||||
: j < 0 ? -1
|
|
||||||
: i - j }) }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Equivalent to .map(..) / .filter(..) / .reduce(..) / .forEach(..) that
|
|
||||||
// process the contents in chunks asynchronously...
|
|
||||||
//
|
|
||||||
// .mapChunks(func)
|
|
||||||
// .mapChunks(chunk_size, func)
|
|
||||||
// .mapChunks([item_handler, chunk_handler])
|
|
||||||
// .mapChunks(chunk_size, [item_handler, chunk_handler])
|
|
||||||
// -> promise(list)
|
|
||||||
//
|
|
||||||
// .filterChunks(func)
|
|
||||||
// .filterChunks(chunk_size, func)
|
|
||||||
// .filterChunks([item_handler, chunk_handler])
|
|
||||||
// .filterChunks(chunk_size, [item_handler, chunk_handler])
|
|
||||||
// -> promise(list)
|
|
||||||
//
|
|
||||||
// .reduceChunks(func, res)
|
|
||||||
// .reduceChunks(chunk_size, func, res)
|
|
||||||
// .reduceChunks([item_handler, chunk_handler], res)
|
|
||||||
// .reduceChunks(chunk_size, [item_handler, chunk_handler], res)
|
|
||||||
// -> promise(res)
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// chunk_handler(chunk, result, offset)
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// chunk_size can be:
|
|
||||||
// 20 - chunk size
|
|
||||||
// '20' - chunk size
|
|
||||||
// '20C' - number of chunks
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// The main goal of this is to not block the runtime while processing a
|
|
||||||
// very long array by interrupting the processing with a timeout...
|
|
||||||
//
|
|
||||||
var makeChunkIter = function(iter, wrapper){
|
|
||||||
wrapper = wrapper
|
|
||||||
|| function(res, func, array, e){
|
|
||||||
return func.call(this, e[1], e[0], array) }
|
|
||||||
return function(size, func, ...rest){
|
|
||||||
var that = this
|
|
||||||
var args = [...arguments]
|
|
||||||
size = (args[0] instanceof Function
|
|
||||||
|| args[0] instanceof Array) ?
|
|
||||||
(this.CHUNK_SIZE || 50)
|
|
||||||
: args.shift()
|
|
||||||
size = typeof(size) == typeof('str') ?
|
|
||||||
// number of chunks...
|
|
||||||
(size.trim().endsWith('c') || size.trim().endsWith('C') ?
|
|
||||||
Math.round(this.length / (parseInt(size) || 1)) || 1
|
|
||||||
: parseInt(size))
|
|
||||||
: size
|
|
||||||
var postChunk
|
|
||||||
func = args.shift()
|
|
||||||
;[func, postChunk] = func instanceof Array ? func : [func]
|
|
||||||
rest = args
|
|
||||||
var res = []
|
|
||||||
var _wrapper = wrapper.bind(this, res, func, this)
|
|
||||||
|
|
||||||
return new Promise(function(resolve, reject){
|
|
||||||
var next = function(chunks){
|
|
||||||
setTimeout(function(){
|
|
||||||
var chunk, val
|
|
||||||
res.push(
|
|
||||||
val = (chunk = chunks.shift())[iter](_wrapper, ...rest))
|
|
||||||
postChunk
|
|
||||||
&& postChunk.call(that,
|
|
||||||
chunk.map(function([i, v]){ return v }),
|
|
||||||
val,
|
|
||||||
chunk[0][0])
|
|
||||||
// stop condition...
|
|
||||||
chunks.length == 0 ?
|
|
||||||
resolve(res.flat(2))
|
|
||||||
: next(chunks) }, 0) }
|
|
||||||
next(that
|
|
||||||
// split the array into chunks...
|
|
||||||
.reduce(function(res, e, i){
|
|
||||||
var c = res.slice(-1)[0]
|
|
||||||
c.length >= size ?
|
|
||||||
// initial element in chunk...
|
|
||||||
res.push([[i, e]])
|
|
||||||
// rest...
|
|
||||||
: c.push([i, e])
|
|
||||||
return res }, [[]])) }) } }
|
|
||||||
|
|
||||||
Array.prototype.CHUNK_SIZE = 50
|
|
||||||
Array.prototype.mapChunks = makeChunkIter('map')
|
|
||||||
Array.prototype.filterChunks = makeChunkIter('map',
|
|
||||||
function(res, func, array, e){
|
|
||||||
return !!func.call(this, e[1], e[0], array) ? [e[1]] : [] })
|
|
||||||
Array.prototype.reduceChunks = makeChunkIter('reduce',
|
|
||||||
function(total, func, array, res, e){
|
|
||||||
return func.call(this,
|
|
||||||
total.length > 0 ?
|
|
||||||
total.pop()
|
|
||||||
: res,
|
|
||||||
e[1], e[0], array) })
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
// Set...
|
|
||||||
|
|
||||||
// Set set operation shorthands...
|
|
||||||
Set.prototype.unite = function(other){
|
|
||||||
return new Set([...this, ...other]) }
|
|
||||||
Set.prototype.intersect = function(other){
|
|
||||||
var test = other.has ? 'has' : 'includes'
|
|
||||||
return new Set([...this]
|
|
||||||
.filter(function(e){ return other[test](e) })) }
|
|
||||||
Set.prototype.subtract = function(other){
|
|
||||||
other = new Set(other)
|
|
||||||
return new Set([...this]
|
|
||||||
.filter(function(e){ return !other.has(e) })) }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
// RegExp...
|
|
||||||
|
|
||||||
// Quote a string and convert to RegExp to match self literally.
|
|
||||||
var quoteRegExp =
|
|
||||||
RegExp.quoteRegExp =
|
|
||||||
module.quoteRegExp =
|
|
||||||
function(str){
|
|
||||||
return str.replace(/([\.\\\/\(\)\[\]\$\*\+\-\{\}\@\^\&\?\<\>])/g, '\\$1') }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
// String...
|
|
||||||
|
|
||||||
String.prototype.capitalize = function(){
|
|
||||||
return this == '' ?
|
|
||||||
this
|
|
||||||
: this[0].toUpperCase() + this.slice(1) }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
// Date...
|
|
||||||
|
|
||||||
// NOTE: repatching a date should not lead to any side effects as this
|
|
||||||
// does not add any state...
|
|
||||||
var patchDate =
|
|
||||||
module.patchDate = function(date){
|
|
||||||
date = date || Date
|
|
||||||
|
|
||||||
date.prototype.toShortDate = function(show_ms){
|
|
||||||
return ''
|
|
||||||
+ this.getFullYear()
|
|
||||||
+'-'+ ('0'+(this.getMonth()+1)).slice(-2)
|
|
||||||
+'-'+ ('0'+this.getDate()).slice(-2)
|
|
||||||
+' '+ ('0'+this.getHours()).slice(-2)
|
|
||||||
+':'+ ('0'+this.getMinutes()).slice(-2)
|
|
||||||
+':'+ ('0'+this.getSeconds()).slice(-2)
|
|
||||||
+ (show_ms ?
|
|
||||||
':'+(('000'+this.getMilliseconds()).slice(-3))
|
|
||||||
: '') }
|
|
||||||
date.prototype.getTimeStamp = function(show_ms){
|
|
||||||
return ''
|
|
||||||
+ this.getFullYear()
|
|
||||||
+ ('0'+(this.getMonth()+1)).slice(-2)
|
|
||||||
+ ('0'+this.getDate()).slice(-2)
|
|
||||||
+ ('0'+this.getHours()).slice(-2)
|
|
||||||
+ ('0'+this.getMinutes()).slice(-2)
|
|
||||||
+ ('0'+this.getSeconds()).slice(-2)
|
|
||||||
+ (show_ms ?
|
|
||||||
('000'+this.getMilliseconds()).slice(-3)
|
|
||||||
: '') }
|
|
||||||
date.prototype.setTimeStamp = function(ts){
|
|
||||||
ts = ts.replace(/[^0-9]*/g, '')
|
|
||||||
this.setFullYear(ts.slice(0, 4))
|
|
||||||
this.setMonth(ts.slice(4, 6)*1-1)
|
|
||||||
this.setDate(ts.slice(6, 8))
|
|
||||||
this.setHours(ts.slice(8, 10))
|
|
||||||
this.setMinutes(ts.slice(10, 12))
|
|
||||||
this.setSeconds(ts.slice(12, 14))
|
|
||||||
this.setMilliseconds(ts.slice(14, 17) || 0)
|
|
||||||
return this }
|
|
||||||
date.timeStamp = function(...args){
|
|
||||||
return (new this()).getTimeStamp(...args) }
|
|
||||||
date.fromTimeStamp = function(ts){
|
|
||||||
return (new this()).setTimeStamp(ts) }
|
|
||||||
// convert string time period to milliseconds...
|
|
||||||
date.str2ms = function(str, dfl){
|
|
||||||
dfl = dfl || 'ms'
|
|
||||||
|
|
||||||
if(typeof(str) == typeof(123)){
|
|
||||||
var val = str
|
|
||||||
str = dfl
|
|
||||||
|
|
||||||
} else {
|
|
||||||
var val = parseFloat(str)
|
|
||||||
str = str.trim()
|
|
||||||
|
|
||||||
// check if a unit is given...
|
|
||||||
str = str == val ? dfl : str
|
|
||||||
}
|
|
||||||
|
|
||||||
var c = /(m(illi)?(-)?s(ec(ond(s)?)?)?)$/i.test(str) ? 1
|
|
||||||
: /s(ec(ond(s)?)?)?$/i.test(str) ? 1000
|
|
||||||
: /m(in(ute(s)?)?)?$/i.test(str) ? 1000*60
|
|
||||||
: /h(our(s)?)?$/i.test(str) ? 1000*60*60
|
|
||||||
: /d(ay(s)?)?$/i.test(str) ? 1000*60*60*24
|
|
||||||
: null
|
|
||||||
|
|
||||||
return c ? val * c : NaN
|
|
||||||
}
|
|
||||||
|
|
||||||
return date
|
|
||||||
}
|
|
||||||
// patch the root date...
|
|
||||||
patchDate()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -449,12 +21,8 @@ module.chainCmp = function(cmp_chain){
|
|||||||
for(var i=0; i < cmp_chain.length; i++){
|
for(var i=0; i < cmp_chain.length; i++){
|
||||||
res = cmp_chain[i](a, b, get, data)
|
res = cmp_chain[i](a, b, get, data)
|
||||||
if(res != 0){
|
if(res != 0){
|
||||||
return res
|
return res } }
|
||||||
}
|
return res } }
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// XXX do we need to quote anything else???
|
// XXX do we need to quote anything else???
|
||||||
@ -463,8 +31,7 @@ module.path2url =
|
|||||||
function(path){
|
function(path){
|
||||||
// test if we have a schema, and if yes return as-is...
|
// test if we have a schema, and if yes return as-is...
|
||||||
if(/^(data|http|https|file|[\w-]*):[\\\/]{2}/.test(path)){
|
if(/^(data|http|https|file|[\w-]*):[\\\/]{2}/.test(path)){
|
||||||
return path
|
return path }
|
||||||
}
|
|
||||||
// skip encoding windows drives...
|
// skip encoding windows drives...
|
||||||
path = path
|
path = path
|
||||||
.split(/[\\\/]/g)
|
.split(/[\\\/]/g)
|
||||||
@ -479,8 +46,7 @@ function(path){
|
|||||||
// NOTE: keep '%' the first...
|
// NOTE: keep '%' the first...
|
||||||
.replace(/%/g, '%25')
|
.replace(/%/g, '%25')
|
||||||
.replace(/#/g, '%23')
|
.replace(/#/g, '%23')
|
||||||
.replace(/&/g, '%26'))
|
.replace(/&/g, '%26')) }
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// NOTE: we are not using node's path module as we need this to work in
|
// NOTE: we are not using node's path module as we need this to work in
|
||||||
@ -501,8 +67,7 @@ function(path){
|
|||||||
// take care of ..
|
// take care of ..
|
||||||
.replace(/\/[^\/]+\/\.\.\//g, '/')
|
.replace(/\/[^\/]+\/\.\.\//g, '/')
|
||||||
.replace(/\/[^\/]+\/\.\.$/, '')
|
.replace(/\/[^\/]+\/\.\.$/, '')
|
||||||
: path
|
: path }
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
17
Viewer/package-lock.json
generated
17
Viewer/package-lock.json
generated
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ImageGrid.Viewer.g4",
|
"name": "ImageGrid.Viewer.g4",
|
||||||
"version": "4.0.0a",
|
"version": "4.0.0-a",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -1111,6 +1111,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/ig-object/-/ig-object-5.2.8.tgz",
|
"resolved": "https://registry.npmjs.org/ig-object/-/ig-object-5.2.8.tgz",
|
||||||
"integrity": "sha512-EzT4CP6d6lI8bnknNgT3W8mUQhSVXflO0yPbKD4dKsFcINiC6npjoEBz+8m3VQmWJhc+36pXD4JLwNxUEgzi+Q=="
|
"integrity": "sha512-EzT4CP6d6lI8bnknNgT3W8mUQhSVXflO0yPbKD4dKsFcINiC6npjoEBz+8m3VQmWJhc+36pXD4JLwNxUEgzi+Q=="
|
||||||
},
|
},
|
||||||
|
"ig-types": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ig-types/-/ig-types-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-CUxqit6W4vjf3fnxVq1KGITRhI6//PiJcaha0CbHZqKutAvPXPjYOzlPdx9HL00LvmU7iNnOcyzWLrCnYd3Myw==",
|
||||||
|
"requires": {
|
||||||
|
"ig-object": "^5.2.8",
|
||||||
|
"object-run": "^1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"image-size": {
|
"image-size": {
|
||||||
"version": "0.5.5",
|
"version": "0.5.5",
|
||||||
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
|
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
|
||||||
@ -1411,9 +1420,9 @@
|
|||||||
"integrity": "sha1-jrbgqZ+HrTT/8YJzMRBJadjFBP4="
|
"integrity": "sha1-jrbgqZ+HrTT/8YJzMRBJadjFBP4="
|
||||||
},
|
},
|
||||||
"moment": {
|
"moment": {
|
||||||
"version": "2.28.0",
|
"version": "2.29.0",
|
||||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.28.0.tgz",
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.0.tgz",
|
||||||
"integrity": "sha512-Z5KOjYmnHyd/ukynmFd/WwyXHd7L4J9vTI/nn5Ap9AVUgaAE15VvQ9MOGmJJygEUklupqIrFnor/tjTwRU+tQw=="
|
"integrity": "sha512-z6IJ5HXYiuxvFTI6eiQ9dm77uE0gyy1yXNApVHqTcnIKfY9tIwEjlzsZ6u1LQXvVgKeTnv9Xm7NDvJ7lso3MtA=="
|
||||||
},
|
},
|
||||||
"ms": {
|
"ms": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
|
|||||||
@ -31,7 +31,8 @@
|
|||||||
"ig-argv": "^2.15.0",
|
"ig-argv": "^2.15.0",
|
||||||
"ig-features": "^3.4.2",
|
"ig-features": "^3.4.2",
|
||||||
"ig-object": "^5.2.8",
|
"ig-object": "^5.2.8",
|
||||||
"moment": "^2.28.0",
|
"ig-types": "^2.0.0",
|
||||||
|
"moment": "^2.29.0",
|
||||||
"object-run": "^1.0.1",
|
"object-run": "^1.0.1",
|
||||||
"requirejs": "^2.3.6",
|
"requirejs": "^2.3.6",
|
||||||
"requirejs-plugins": "^1.0.2",
|
"requirejs-plugins": "^1.0.2",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user