mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-28 18:00:09 +00:00
298 lines
6.7 KiB
JavaScript
Executable File
298 lines
6.7 KiB
JavaScript
Executable File
/**********************************************************************
|
|
*
|
|
*
|
|
*
|
|
**********************************************************************/
|
|
((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define)
|
|
(function(require){ var module={} // make module AMD/node compatible...
|
|
/*********************************************************************/
|
|
|
|
var keyboard = require('../keyboard')
|
|
var object = require('../object')
|
|
|
|
|
|
|
|
/*********************************************************************/
|
|
// helpers...
|
|
|
|
var proxyToDom =
|
|
module.proxyToDom =
|
|
function(name){
|
|
return function(){
|
|
// proxy handler...
|
|
if(name in this.dom){
|
|
this.dom[name].apply(this.dom, arguments)
|
|
|
|
// on/trigger handlers...
|
|
} else {
|
|
arguments[0] instanceof Function ?
|
|
this.dom.on(name, arguments[0])
|
|
: this.dom.trigger(name, [].slice.call(arguments))
|
|
}
|
|
return this
|
|
}
|
|
}
|
|
|
|
var eventToDom =
|
|
module.eventToDom =
|
|
function(name, defaults){
|
|
return function(){
|
|
// register...
|
|
if(arguments[0] instanceof Function){
|
|
this.dom.trigger(name, [].slice.call(arguments))
|
|
|
|
// trigger...
|
|
} else {
|
|
var args = (arguments.length == 0 && defaults) ?
|
|
defaults.call(this)
|
|
: [].slice.call(arguments)
|
|
args = args instanceof Array ? args : [args]
|
|
|
|
this.dom.trigger(name, args)
|
|
}
|
|
return this
|
|
}
|
|
}
|
|
|
|
|
|
// XXX triggering events from here and from jQuery/dom has a
|
|
// different effect...
|
|
var triggerEventWithSource =
|
|
module.triggerEventWithSource =
|
|
function(){
|
|
var args = args2array(arguments)
|
|
var evt = args.shift()
|
|
|
|
if(typeof(evt) == typeof('str')){
|
|
evt = $.Event(evt)
|
|
}
|
|
|
|
evt.source = this
|
|
|
|
args.splice(0, 0, evt)
|
|
|
|
this.dom.trigger.apply(this.dom, args)
|
|
return this
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************/
|
|
|
|
var WidgetClassPrototype = {
|
|
make: function(obj, client, options){
|
|
console.error('Widget must define a .make method.')
|
|
},
|
|
}
|
|
|
|
|
|
var WidgetPrototype = {
|
|
// NOTE: this must have .data('widget-controller', this) set...
|
|
dom: null,
|
|
client: null,
|
|
|
|
options: {
|
|
keyboardRepeatPause: 100,
|
|
|
|
nonPropagatedEvents: [
|
|
'start',
|
|
|
|
'click',
|
|
'keydown',
|
|
|
|
'close',
|
|
],
|
|
},
|
|
|
|
keybindings: null,
|
|
keyboard: null,
|
|
|
|
// XXX triggering events from here and from jQuery/dom has a
|
|
// different effect...
|
|
trigger: triggerEventWithSource,
|
|
|
|
// proxy event api...
|
|
on: proxyToDom('on'),
|
|
one: proxyToDom('one'),
|
|
off: proxyToDom('off'),
|
|
bind: proxyToDom('bind'),
|
|
unbind: proxyToDom('unbind'),
|
|
deligate: proxyToDom('deligate'),
|
|
undeligate: proxyToDom('undeligate'),
|
|
|
|
// custom events...
|
|
//
|
|
start: function(handler){
|
|
handler ?
|
|
this.on('start', handler)
|
|
:this.trigger('start')
|
|
return this
|
|
},
|
|
// NOTE: this can be passed a string that can be used as a reason
|
|
// for closing...
|
|
close: function(a){
|
|
// trigger...
|
|
if(a == null || typeof(a) == typeof('str')){
|
|
a = a || 'accept'
|
|
this.parent.close
|
|
&& this.parent.close(a)
|
|
this.trigger('close', a)
|
|
|
|
// register new handler...
|
|
} else {
|
|
this.on('close', a)
|
|
}
|
|
return this
|
|
},
|
|
|
|
// XXX this will not:
|
|
// - attach dom to parent... (???)
|
|
// - handle focus... (???)
|
|
// XXX same as ContainerPrototype.__init__ but skips client...
|
|
__init__: function(parent, options){
|
|
var that = this
|
|
|
|
parent = this.parent = $(parent || 'body')
|
|
options = options || {}
|
|
|
|
this.keybindings = JSON.parse(JSON.stringify(this.keybindings))
|
|
|
|
// merge options...
|
|
var opts = Object.create(this.options)
|
|
Object.keys(options).forEach(function(n){ opts[n] = options[n] })
|
|
options = this.options = opts
|
|
|
|
// build the dom...
|
|
if(this.constructor.make){
|
|
this.dom = this.constructor.make(this, options)
|
|
|
|
this.dom.data('widget-controller', this)
|
|
}
|
|
|
|
// XXX do we do this here???
|
|
/*
|
|
if(parent && this.dom){
|
|
parent.append(this.dom)
|
|
}
|
|
*/
|
|
|
|
// add keyboard handler...
|
|
if(this.keybindings && this.dom){
|
|
this.keyboard =
|
|
this.keyboard || keyboard.KeyboardWithCSSModes(
|
|
function(){ return that.keybindings },
|
|
function(){ return that.dom })
|
|
this.dom
|
|
.keydown(
|
|
keyboard.makePausableKeyboardHandler(
|
|
this.keyboard,
|
|
options.logKeys,
|
|
this,
|
|
function(){ return this.options.keyboardRepeatPause }))
|
|
}
|
|
|
|
if(this.options.nonPropagatedEvents != null){
|
|
this.on(this.options.nonPropagatedEvents.join(' '),
|
|
function(evt){ evt.stopPropagation() })
|
|
}
|
|
|
|
return this
|
|
},
|
|
}
|
|
|
|
|
|
var Widget =
|
|
module.Widget =
|
|
object.makeConstructor('Widget',
|
|
WidgetClassPrototype,
|
|
WidgetPrototype)
|
|
|
|
|
|
|
|
/*********************************************************************/
|
|
|
|
var ContainerClassPrototype = {
|
|
}
|
|
|
|
|
|
var ContainerPrototype = {
|
|
// NOTE: this must have .data('widget-controller', this) set...
|
|
dom: null,
|
|
|
|
focus: function(handler){
|
|
if(handler != null){
|
|
this.on('focus', handler)
|
|
|
|
} else {
|
|
this.dom.focus()
|
|
this.client
|
|
&& this.client.focus
|
|
&& this.client.focus()
|
|
}
|
|
return this
|
|
},
|
|
|
|
// XXX this is the same as WidgetPrototype.__init__ but also handles
|
|
// the client...
|
|
__init__: function(parent, client, options){
|
|
var that = this
|
|
|
|
parent = this.parent = $(parent || 'body')
|
|
options = options || {}
|
|
|
|
this.keybindings = JSON.parse(JSON.stringify(this.keybindings))
|
|
|
|
this.client = client
|
|
client.parent = this
|
|
|
|
// merge options...
|
|
var opts = Object.create(this.options)
|
|
Object.keys(options).forEach(function(n){ opts[n] = options[n] })
|
|
options = this.options = opts
|
|
|
|
// build the dom...
|
|
if(this.constructor.make){
|
|
this.dom = this.constructor
|
|
.make(this, client.dom || client, options)
|
|
|
|
this.dom.data('widget-controller', this)
|
|
}
|
|
|
|
// add keyboard handler...
|
|
if(this.keybindings && this.dom){
|
|
this.keyboard =
|
|
this.keyboard || keyboard.KeyboardWithCSSModes(
|
|
function(){ return that.keybindings },
|
|
function(){ return that.dom })
|
|
this.dom
|
|
.keydown(
|
|
keyboard.makePausableKeyboardHandler(
|
|
this.keyboard,
|
|
options.logKeys,
|
|
this,
|
|
function(){ return this.options.keyboardRepeatPause }))
|
|
}
|
|
|
|
if(this.options.nonPropagatedEvents != null){
|
|
this.on(this.options.nonPropagatedEvents.join(' '),
|
|
function(evt){ evt.stopPropagation() })
|
|
}
|
|
|
|
return this
|
|
},
|
|
}
|
|
|
|
|
|
var Container =
|
|
module.Container =
|
|
object.makeConstructor('Container',
|
|
ContainerClassPrototype,
|
|
ContainerPrototype)
|
|
|
|
Container.prototype.__proto__ = Widget.prototype
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
* vim:set ts=4 sw=4 : */ return module })
|