several bugfixes and late migrations to new object.js

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2020-05-16 17:55:41 +03:00
parent b0f52c82f1
commit 55b9e8d811
5 changed files with 276 additions and 292 deletions

View File

@ -411,7 +411,9 @@ var MetadataUIActions = actions.Actions({
Object.assign( Object.assign(
this.graph this.graph
|| document.createElement('ig-image-graph'), || document.createElement('ig-image-graph'),
config) config,
// orientation....
{orientation: (that.images[gid] || {}).orientation || 0})
Object.assign(elem.style, { Object.assign(elem.style, {
width: '500px', width: '500px',
height: '200px', height: '200px',

View File

@ -39,11 +39,11 @@ module.Filters = {
} else { } else {
context.drawImage(img, 0, 0, w, h) context.drawImage(img, 0, 0, w, h)
} }
return context.getImageData(0,0,c.width,c.height) return context.getImageData(0, 0, c.width, c.height)
}, },
setPixels: function(c, data, w, h){ setPixels: function(c, data, w, h){
c.width = data.width w = c.width = w || data.width
c.height = data.height h = c.height = h || data.height
var context = c.getContext('2d') var context = c.getContext('2d')
context.putImageData(data, 0, 0) context.putImageData(data, 0, 0)
}, },
@ -74,8 +74,9 @@ module.Filters = {
color = color || 'fill' color = color || 'fill'
mode = mode || 'luminance' mode = mode || 'luminance'
var w = 255 var size = 255
var h = 255 var w = size
var h = size
// output buffer... // output buffer...
var out = this.getPixels(null, w, h) var out = this.getPixels(null, w, h)
@ -105,14 +106,14 @@ module.Filters = {
count[b*4+2] = (count[b*4+2] || 0) + 1 } } count[b*4+2] = (count[b*4+2] || 0) + 1 } }
} }
var m = 255 / Math.max(...count.filter(function(){ return true })) var m = size / Math.max(...count.filter(function(){ return true }))
var pos = function(i, value){ var pos = function(i, value){
return ( return (
// horizontal position... // horizontal position...
i*4 i*4
// value vertical offset... // value vertical offset...
+ (255-Math.round(value*m))*w*4) } + (size-Math.round(value*m))*w*4) }
// XXX would be nice to have an option to draw full columns... // XXX would be nice to have an option to draw full columns...
count.forEach(function(v, i){ count.forEach(function(v, i){
@ -228,9 +229,11 @@ module.Filters = {
var WAVEFORM_SIZE = var WAVEFORM_SIZE =
module.WAVEFORM_SIZE = 1000 module.WAVEFORM_SIZE = 1000
// XXX need to account for image rotation...
var waveform = var waveform =
module.waveform = module.waveform =
function(img, canvas, mode, color){ function(img, canvas, mode, color, rotation){
// XXX rotate...
var d = Filters.getPixels(img, WAVEFORM_SIZE) var d = Filters.getPixels(img, WAVEFORM_SIZE)
var w = Filters.waveform(d, mode, color) var w = Filters.waveform(d, mode, color)
Filters.setPixels(canvas, w) } Filters.setPixels(canvas, w) }
@ -334,8 +337,9 @@ object.Constructor('igImageGraph', HTMLElement, {
'src', 'src',
'mode', 'mode',
'color', 'color',
'nocontrols',
'graph', 'graph',
'orientation',
'nocontrols',
]}, ]},
attributeChangedCallback: function(name, from, to){ attributeChangedCallback: function(name, from, to){
name == 'nocontrols' name == 'nocontrols'
@ -387,6 +391,15 @@ object.Constructor('igImageGraph', HTMLElement, {
value === undefined value === undefined
&& this.removeAttribute('color') && this.removeAttribute('color')
this.update() }, this.update() },
get orientation(){
return this.getAttribute('orientation') || 0 },
set orientation(value){
;(['top', 'left', 'bottom', 'right'].includes(value)
|| typeof(value) == typeof(123))
&& this.setAttribute('orientation', value)
value == null
&& this.removeAttribute('orientation')
this.update() },
get nocontrols(){ get nocontrols(){
return this.getAttribute('nocontrols') != null }, return this.getAttribute('nocontrols') != null },
set nocontrols(value){ set nocontrols(value){
@ -477,7 +490,12 @@ object.Constructor('igImageGraph', HTMLElement, {
var canvas = this.__shadow.querySelector('canvas') var canvas = this.__shadow.querySelector('canvas')
if(this.image){ if(this.image){
graph(this.image, canvas, this.mode, this.color) var orientation = this.orientation
orientation = parseFloat(
{top: 180, left: 90, bottom: 0, right: 270}[orientation]
|| orientation)
graph(this.image, canvas, this.mode, this.color, orientation)
} else if(this.src){ } else if(this.src){
this.src = this.src this.src = this.src

View File

@ -97,9 +97,7 @@ function(path, make){
resolve(fs.statSync(path)) resolve(fs.statSync(path))
} catch(err){ } catch(err){
reject(err) reject(err)
} } }) }
})
}
/* /*
var stat = function(path){ var stat = function(path){
@ -129,9 +127,7 @@ function(path, make){
if(drive == 'Z'){ if(drive == 'Z'){
resolve() resolve()
} }
}) }) }) })
})
})
// list dirs... // list dirs...
} else { } else {
@ -150,8 +146,7 @@ function(path, make){
elem.attr('count', lst.length) elem.attr('count', lst.length)
}) })
} }
return elem return elem }
}
return new Promise(function(resolve, reject){ return new Promise(function(resolve, reject){
// XXX should this be a promise??? // XXX should this be a promise???
@ -291,9 +286,9 @@ var listDir = module.listDir = listDirfs
// XXX for some reason pop does not focus the container dir correctly... // XXX for some reason pop does not focus the container dir correctly...
// ...this is potentially due to the list not being ready yet... // ...this is potentially due to the list not being ready yet...
// XXX this should be smarter and support other URL schemes... // XXX this should be smarter and support other URL schemes...
var WalkPrototype = { var Walk =
__proto__: browse.Browser.prototype, module.Walk =
object.Constructor('Walk', browse.Browser, {
options: { options: {
__proto__: browse.Browser.prototype.options, __proto__: browse.Browser.prototype.options,
@ -346,33 +341,20 @@ var WalkPrototype = {
cur && this.select(cur) cur && this.select(cur)
return this return this
}, },
} })
var Walk =
module.Walk =
object.Constructor('Walk',
browse.Browser,
WalkPrototype)
var makeWalk = var makeWalk =
module.makeWalk = function(elem, path, fileCountPattern, rest){ module.makeWalk = function(elem, path, fileCountPattern, rest){
var opts = {} return Walk(elem,
if(rest){ Object.assign({},
for(var k in rest){ rest,
opts[k] = rest[k] {
} path: path,
} fileCountPattern: fileCountPattern == null ?
Walk.prototype.options.fileCountPattern
opts.path = path : fileCountPattern,
})) }
opts.fileCountPattern = fileCountPattern == null ?
WalkPrototype.options.fileCountPattern
: fileCountPattern
return Walk(elem, opts)
}

View File

@ -3284,21 +3284,18 @@ var BrowserPrototype = {
// Toggle filter view mode... // Toggle filter view mode...
toggleFilterViewMode: function(){ toggleFilterViewMode: function(){
this.dom.toggleClass('show-filtered-out') this.dom.toggleClass('show-filtered-out')
return this return this },
},
// XXX should this be a toggler??? // XXX should this be a toggler???
disableElements: function(pattern){ disableElements: function(pattern){
this.filter(pattern, false) this.filter(pattern, false)
.addClass('disabled') .addClass('disabled')
.removeClass('selected') .removeClass('selected')
return this return this },
},
enableElements: function(pattern){ enableElements: function(pattern){
this.filter(pattern, false) this.filter(pattern, false)
.removeClass('disabled') .removeClass('disabled')
return this return this },
},
// Select an element from current list... // Select an element from current list...
// //
@ -4040,15 +4037,17 @@ var BrowserPrototype = {
list: function(path, make){ list: function(path, make){
path = path || this.path path = path || this.path
var m = this.options.list var m = this.options.list
return m ? m.apply(this, arguments) : [] return m ?
}, m.apply(this, arguments)
: [] },
// Run a function in the context of the object... // Run a function in the context of the object...
// //
run: function(func){ run: function(func){
var res = func ? func.call(this) : undefined var res = func ? func.call(this) : undefined
return res === undefined ? this : res return res === undefined ?
}, this
: res },
// XXX need to get a container -- UI widget API.... // XXX need to get a container -- UI widget API....
// XXX paste does not work on IE yet... // XXX paste does not work on IE yet...
@ -4056,7 +4055,7 @@ var BrowserPrototype = {
__init__: function(parent, options){ __init__: function(parent, options){
var that = this var that = this
object.parent(BrowserPrototype.__init__, this).call(this, parent, options) object.parentCall(Browser.prototype.__init__, this, parent, options)
var dom = this.dom var dom = this.dom
options = this.options options = this.options
@ -4110,9 +4109,8 @@ var BrowserPrototype = {
*/ */
// attach to parent... // attach to parent...
if(parent != null){ parent != null
parent.append(dom) && parent.append(dom)
}
// load the initial state... // load the initial state...
// NOTE: path can be a number so simply or-ing here is a bad idea... // NOTE: path can be a number so simply or-ing here is a bad idea...
@ -4134,11 +4132,13 @@ var BrowserPrototype = {
// XXX not sure if we need this... // XXX not sure if we need this...
// ...currently this is used only when path is // ...currently this is used only when path is
// a list and we need to also select an item... // a list and we need to also select an item...
selected ? that.select(selected) selected ?
// we have a manually selected item but that was that.select(selected)
// not aligned... // we have a manually selected item but that was
: that.selected ? that.select() // not aligned...
: null }) : that.selected ?
that.select()
: null })
}, },
} }
@ -4146,40 +4146,31 @@ var BrowserPrototype = {
var Browser = var Browser =
module.Browser = module.Browser =
object.Constructor('Browser', object.Constructor('Browser',
widget.Widget,
BrowserClassPrototype, BrowserClassPrototype,
BrowserPrototype) BrowserPrototype)
// inherit from widget...
Browser.prototype.__proto__ = widget.Widget.prototype
/*********************************************************************/ /*********************************************************************/
var ListerPrototype = Object.create(Browser.prototype)
ListerPrototype.options = {
pathPrefix: '',
fullPathEdit: false,
traversable: false,
flat: true,
// XXX not sure if we need these...
skipDisabledItems: false,
// NOTE: to disable this set it to false or null
isItemDisabled: '^- ',
}
// XXX should we inherit or copy options???
// ...inheriting might pose problems with deleting values reverting
// them to default instead of nulling them and mutable options might
// get overwritten...
ListerPrototype.options.__proto__ = Browser.prototype.options
var Lister = var Lister =
module.Lister = module.Lister =
object.Constructor('Lister', object.Constructor('Lister', Browser, {
BrowserClassPrototype, options: {
ListerPrototype) __proto__: Browser.prototype.options,
pathPrefix: '',
fullPathEdit: false,
traversable: false,
flat: true,
// XXX not sure if we need these...
skipDisabledItems: false,
// NOTE: to disable this set it to false or null
isItemDisabled: '^- ',
},
})
// This is a shorthand for: new List(<elem>, { data: <list> }) // This is a shorthand for: new List(<elem>, { data: <list> })
@ -4217,49 +4208,46 @@ module.makeLister = function(elem, lister, options){
// //
// NOTE: this essentially a different default configuration of Browser... // NOTE: this essentially a different default configuration of Browser...
// NOTE: this is essentially a wrapper around make.List(...) // NOTE: this is essentially a wrapper around make.List(...)
var ListPrototype = Object.create(Browser.prototype)
ListPrototype.options = {
pathPrefix: '',
fullPathEdit: false,
traversable: false,
flat: true,
// XXX not sure if we need these...
skipDisabledItems: false,
// NOTE: to disable this set it to false or null
isItemDisabled: '^- ',
list: function(path, make){
var that = this
var data = this.options.data
var res = []
// this is here to get the modified titles...
var _make = function(txt){
res.push(txt)
return make.apply(make, arguments)
}
_make.__proto__ = make
// build the list...
_make
.List(data, {
isItemDisabled: this.options.isItemDisabled,
skipDisabledItems: this.options.skipDisabledItems,
})
return res
},
}
ListPrototype.options.__proto__ = Browser.prototype.options
var List = var List =
module.List = module.List =
object.Constructor('List', object.Constructor('List', Browser, {
BrowserClassPrototype, options: {
ListPrototype) __proto__: Browser.prototype.options,
pathPrefix: '',
fullPathEdit: false,
traversable: false,
flat: true,
// XXX not sure if we need these...
skipDisabledItems: false,
// NOTE: to disable this set it to false or null
isItemDisabled: '^- ',
list: function(path, make){
var that = this
var data = this.options.data
var res = []
// this is here to get the modified titles...
var _make = function(txt){
res.push(txt)
return make.apply(make, arguments)
}
_make.__proto__ = make
// build the list...
_make
.List(data, {
isItemDisabled: this.options.isItemDisabled,
skipDisabledItems: this.options.skipDisabledItems,
})
return res
},
},
})
// This is a shorthand for: new List(<elem>, { data: <list> }) // This is a shorthand for: new List(<elem>, { data: <list> })
@ -4378,151 +4366,149 @@ function(list, options){
// NOTE: currently only trailing '*' are supported. // NOTE: currently only trailing '*' are supported.
// //
// XXX add support for '*' and '**' glob patterns... // XXX add support for '*' and '**' glob patterns...
var PathListPrototype = Object.create(Browser.prototype)
PathListPrototype.options = {
fullPathEdit: true,
traversable: true,
flat: false,
// XXX not sure if we need these...
skipDisabledItems: false,
// NOTE: to disable this set it to false or null
isItemDisabled: '^- ',
list: function(path, make){
var that = this
var data = this.options.data
var keys = data.constructor == Array ? data : Object.keys(data)
var pattern = this.options.isItemDisabled
&& RegExp(this.options.isItemDisabled)
if(pattern && this.options.skipDisabledItems){
keys = keys.filter(function(k){ return !pattern.test(k) })
}
var visited = []
// match path elements accounting for patterns...
//
// Supported patterns:
// A - matches A exactly
// A|B - matches either A or B
// shortcut marker
// - see .options.itemShortcutMarker
//
// NOTE: only the second argument is checked for '|' patterns...
var match = function(a, path){
var marker = that.options.itemShortcutMarker
marker = marker && RegExp(marker, 'g')
path = marker ? path.replace(marker, '$1') : path
// NOTE: might be good to make this recursive when expanding
// pattern support...
return a
.split('|')
.map(function(e){
return marker ? e.replace(marker, '$1') : e })
.filter(function(e){
return e == path })
.length > 0 }
// get the '*' listers...
var lister = keys
.filter(function(k){
return k.trim().split(/[\\\/]+/g).pop() == '*' })
.filter(function(k){
k = k.split(/[\\\/]+/)
// remove the trailing '*'...
.slice(0, -1)
// do the match...
return k.length <= path.length
&& k.filter(function(e, i){
return e != '*' && !match(e, path[i])
}).length == 0 })
.sort(function(a, b){ return a.length - b.length})
.pop()
// use the custom lister (defined by trailing '*')...
if(data !== keys && lister){
return data[lister].call(this, this.options.pathPrefix + path.join('/'), make)
// list via provided paths...
} else {
return keys
.map(function(k){
var disable = null
if(pattern){
var n = k.replace(pattern, '')
disable = n != k
k = n
}
var kp = k.split(/[\\\/]+/g)
kp[0] == '' && kp.shift()
// see if we have a star...
var star = kp.slice(-1)[0] == '*'
star && kp.pop()
// get and check current path, continue if relevant...
var p = kp.splice(0, path.length)
if(kp.length == 0
|| p.length < path.length
|| p.filter(function(e, i){ return !match(e, path[i]) }).length > 0){
return false
}
// get current path element if one exists and we did not create it already...
cur = kp.shift()
if(cur == undefined){
return false
}
cur.split('|')
// skip empty path items...
// NOTE: this avoids creating empty items in cases
// of paths ending with '/' or containing '//'
.filter(function(e){ return e.trim() != '' })
.forEach(function(cur){
if(visited.indexOf(cur) >= 0){
// set element to traversable if we visit it again...
if(kp.length > 0){
that.filter(cur, false)
.removeClass('not-traversable')
//.removeClass('disabled')
}
return false
}
visited.push(cur)
// build the element....
var e = make(cur,
star || kp.length > 0,
// XXX this might still disable a dir...
!star && kp.length == 0 && disable)
// setup handlers...
if(!star && data !== keys && kp.length == 0 && data[k] != null){
e.on('open', function(){
return that.options.data[k].apply(this, arguments)
})
}
})
return cur
})
.filter(function(e){ return e !== false })
}
},
}
PathListPrototype.options.__proto__ = Browser.prototype.options
var PathList = var PathList =
module.PathList = module.PathList =
object.Constructor('PathList', object.Constructor('PathList', Browser, {
BrowserClassPrototype, options: {
PathListPrototype) __proto__: Browser.prototype.options,
fullPathEdit: true,
traversable: true,
flat: false,
// XXX not sure if we need these...
skipDisabledItems: false,
// NOTE: to disable this set it to false or null
isItemDisabled: '^- ',
list: function(path, make){
var that = this
var data = this.options.data
var keys = data.constructor == Array ? data : Object.keys(data)
var pattern = this.options.isItemDisabled
&& RegExp(this.options.isItemDisabled)
if(pattern && this.options.skipDisabledItems){
keys = keys.filter(function(k){ return !pattern.test(k) })
}
var visited = []
// match path elements accounting for patterns...
//
// Supported patterns:
// A - matches A exactly
// A|B - matches either A or B
// shortcut marker
// - see .options.itemShortcutMarker
//
// NOTE: only the second argument is checked for '|' patterns...
var match = function(a, path){
var marker = that.options.itemShortcutMarker
marker = marker && RegExp(marker, 'g')
path = marker ? path.replace(marker, '$1') : path
// NOTE: might be good to make this recursive when expanding
// pattern support...
return a
.split('|')
.map(function(e){
return marker ? e.replace(marker, '$1') : e })
.filter(function(e){
return e == path })
.length > 0 }
// get the '*' listers...
var lister = keys
.filter(function(k){
return k.trim().split(/[\\\/]+/g).pop() == '*' })
.filter(function(k){
k = k.split(/[\\\/]+/)
// remove the trailing '*'...
.slice(0, -1)
// do the match...
return k.length <= path.length
&& k.filter(function(e, i){
return e != '*' && !match(e, path[i])
}).length == 0 })
.sort(function(a, b){ return a.length - b.length})
.pop()
// use the custom lister (defined by trailing '*')...
if(data !== keys && lister){
return data[lister].call(this, this.options.pathPrefix + path.join('/'), make)
// list via provided paths...
} else {
return keys
.map(function(k){
var disable = null
if(pattern){
var n = k.replace(pattern, '')
disable = n != k
k = n
}
var kp = k.split(/[\\\/]+/g)
kp[0] == '' && kp.shift()
// see if we have a star...
var star = kp.slice(-1)[0] == '*'
star && kp.pop()
// get and check current path, continue if relevant...
var p = kp.splice(0, path.length)
if(kp.length == 0
|| p.length < path.length
|| p.filter(function(e, i){ return !match(e, path[i]) }).length > 0){
return false
}
// get current path element if one exists and we did not create it already...
cur = kp.shift()
if(cur == undefined){
return false
}
cur.split('|')
// skip empty path items...
// NOTE: this avoids creating empty items in cases
// of paths ending with '/' or containing '//'
.filter(function(e){ return e.trim() != '' })
.forEach(function(cur){
if(visited.indexOf(cur) >= 0){
// set element to traversable if we visit it again...
if(kp.length > 0){
that.filter(cur, false)
.removeClass('not-traversable')
//.removeClass('disabled')
}
return false
}
visited.push(cur)
// build the element....
var e = make(cur,
star || kp.length > 0,
// XXX this might still disable a dir...
!star && kp.length == 0 && disable)
// setup handlers...
if(!star && data !== keys && kp.length == 0 && data[k] != null){
e.on('open', function(){
return that.options.data[k].apply(this, arguments)
})
}
})
return cur
})
.filter(function(e){ return e !== false })
}
},
},
})
var makePathList = var makePathList =
module.makePathList = makeBrowserMaker(PathList) module.makePathList = makeBrowserMaker(PathList)

View File

@ -95,9 +95,9 @@ function(){
/*********************************************************************/ /*********************************************************************/
var WidgetClassPrototype = { var WidgetClassPrototype = {
make: function(obj, client, options){ //make: function(obj, client, options){
console.error('Widget must define a .make method.') // console.error('Widget must define a .make method.')
}, //},
} }
@ -168,14 +168,13 @@ var WidgetPrototype = {
var that = this var that = this
parent = this.parent = $(parent || 'body') parent = this.parent = $(parent || 'body')
options = options || {}
this.keybindings = JSON.parse(JSON.stringify(this.keybindings)) this.keybindings = JSON.parse(JSON.stringify(this.keybindings))
// merge options... // merge options...
var opts = Object.create(this.options) options = this.options = Object.assign(
Object.keys(options).forEach(function(n){ opts[n] = options[n] }) Object.create(this.options),
options = this.options = opts options || {})
// build the dom... // build the dom...
if(this.constructor.make){ if(this.constructor.make){
@ -203,13 +202,11 @@ var WidgetPrototype = {
this.keyboard, this.keyboard,
options.logKeys, options.logKeys,
this, this,
function(){ return this.options.keyboardRepeatPause })) function(){ return this.options.keyboardRepeatPause })) }
}
if(this.options.nonPropagatedEvents != null){ this.options.nonPropagatedEvents != null
this.on(this.options.nonPropagatedEvents.join(' '), && this.on(this.options.nonPropagatedEvents.join(' '),
function(evt){ evt.stopPropagation() }) function(evt){ evt.stopPropagation() })
}
return this return this
}, },
@ -253,7 +250,6 @@ var ContainerPrototype = {
var that = this var that = this
parent = this.parent = $(parent || 'body') parent = this.parent = $(parent || 'body')
options = options || {}
this.keybindings = JSON.parse(JSON.stringify(this.keybindings)) this.keybindings = JSON.parse(JSON.stringify(this.keybindings))
@ -261,9 +257,9 @@ var ContainerPrototype = {
client.parent = this client.parent = this
// merge options... // merge options...
var opts = Object.create(this.options) options = this.options = Object.assign(
Object.keys(options).forEach(function(n){ opts[n] = options[n] }) Object.create(this.options),
options = this.options = opts options || {})
// build the dom... // build the dom...
if(this.constructor.make){ if(this.constructor.make){
@ -301,10 +297,10 @@ var ContainerPrototype = {
var Container = var Container =
module.Container = module.Container =
object.Constructor('Container', object.Constructor('Container',
ContainerClassPrototype, Widget,
ContainerPrototype) ContainerClassPrototype,
ContainerPrototype)
Container.prototype.__proto__ = Widget.prototype