mirror of
				https://github.com/flynx/ImageGrid.git
				synced 2025-11-03 04:40:10 +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 })
 |