mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 18:30:09 +00:00
added state/event togglers... (not sure about implementation)
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
9499108401
commit
af686c3e56
@ -97,6 +97,10 @@
|
|||||||
|
|
||||||
// Make a generic toggler function/method...
|
// Make a generic toggler function/method...
|
||||||
//
|
//
|
||||||
|
// Toggler(elem, stateGettor, states, post_callback)
|
||||||
|
// Toggler(elem, stateGettor, states, pre_callback, post_callback)
|
||||||
|
// -> toggler
|
||||||
|
//
|
||||||
// state_accessor signature:
|
// state_accessor signature:
|
||||||
//
|
//
|
||||||
// Get current state:
|
// Get current state:
|
||||||
@ -107,7 +111,7 @@
|
|||||||
// state_accessor(<elem>, <new-state>)
|
// state_accessor(<elem>, <new-state>)
|
||||||
// -> <new-state>
|
// -> <new-state>
|
||||||
//
|
//
|
||||||
// `this' within state_accessor is set to toggler's context.
|
// state_accessor is calles in the toggler's context.
|
||||||
//
|
//
|
||||||
// The value returned by state_accessor is returned by the toggler. To pass
|
// The value returned by state_accessor is returned by the toggler. To pass
|
||||||
// control over the return value back to the Toggler logic when setting
|
// control over the return value back to the Toggler logic when setting
|
||||||
@ -131,6 +135,10 @@
|
|||||||
// the toggler's context...
|
// the toggler's context...
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
// Examples:
|
||||||
|
// XXX
|
||||||
|
//
|
||||||
|
//
|
||||||
// XXX technically we do not need both elem and state_accessor here, the
|
// XXX technically we do not need both elem and state_accessor here, the
|
||||||
// later is enough, but as strict mode is not stable enough (sometimes
|
// later is enough, but as strict mode is not stable enough (sometimes
|
||||||
// works and sometimes does not), we can not reliably pass the element
|
// works and sometimes does not), we can not reliably pass the element
|
||||||
|
|||||||
@ -224,6 +224,14 @@ object.makeConstructor('BrowserEvent',
|
|||||||
|
|
||||||
// Generate an event method...
|
// Generate an event method...
|
||||||
//
|
//
|
||||||
|
// Make and event method...
|
||||||
|
// makeEventMethod(event_name, handler[, options])
|
||||||
|
// -> event_method
|
||||||
|
//
|
||||||
|
// This will produce an event method that supports binding handlers to the
|
||||||
|
// event (shorthand to: .on(event, handler, ...)) and triggering the
|
||||||
|
// said event (similar to: .trigger(event, ..) )...
|
||||||
|
//
|
||||||
// Trigger an event
|
// Trigger an event
|
||||||
// .event()
|
// .event()
|
||||||
// .event(arg, ..)
|
// .event(arg, ..)
|
||||||
@ -283,8 +291,14 @@ var callItemEventHandlers = function(item, event, evt, ...args){
|
|||||||
|
|
||||||
// Generate item event method...
|
// Generate item event method...
|
||||||
//
|
//
|
||||||
|
// makeItemEventMethod(event_name, handler[, options])
|
||||||
|
// makeItemEventMethod(event_name, handler, default_getter[, options])
|
||||||
|
// -> event_method
|
||||||
|
//
|
||||||
|
//
|
||||||
// This extends makeEventMethod(..) by adding an option to pass an item
|
// This extends makeEventMethod(..) by adding an option to pass an item
|
||||||
// when triggering the event, the rest of the signature is identical.
|
// when triggering the event and if no item is passed to produce a default,
|
||||||
|
// the rest of the signature is identical...
|
||||||
//
|
//
|
||||||
// Trigger an event on item(s)...
|
// Trigger an event on item(s)...
|
||||||
// .event(item, ..)
|
// .event(item, ..)
|
||||||
@ -302,8 +316,6 @@ var callItemEventHandlers = function(item, event, evt, ...args){
|
|||||||
// NOTE: item events do not directly trigger the original caller's handlers
|
// NOTE: item events do not directly trigger the original caller's handlers
|
||||||
// those will get celled recursively when the events are propagated
|
// those will get celled recursively when the events are propagated
|
||||||
// up the tree.
|
// up the tree.
|
||||||
//
|
|
||||||
// XXX need reasonable default item selections...
|
|
||||||
var makeItemEventMethod = function(event, handler, default_item, options){
|
var makeItemEventMethod = function(event, handler, default_item, options){
|
||||||
options = default_item instanceof Function ?
|
options = default_item instanceof Function ?
|
||||||
options
|
options
|
||||||
@ -360,6 +372,115 @@ var makeItemEventMethod = function(event, handler, default_item, options){
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// XXX should this be a toggler.Toggler???
|
||||||
|
var makeItemEventToggler = function(get_state, set_state, unset_state, default_item, multi){
|
||||||
|
var _get_state = get_state instanceof Function ?
|
||||||
|
get_state
|
||||||
|
: function(e){ return !!e[get_state] }
|
||||||
|
var _set_state = set_state instanceof Function ?
|
||||||
|
set_state
|
||||||
|
: function(e){ return !!this[set_state](e) }
|
||||||
|
var _unset_state = unset_state instanceof Function ?
|
||||||
|
unset_state
|
||||||
|
: function(e){ return !this[unset_state](e) }
|
||||||
|
var _default_item = default_item instanceof Function ?
|
||||||
|
default_item
|
||||||
|
: function(){ return this[default_item] }
|
||||||
|
multi = multi !== false
|
||||||
|
var getter = multi ? 'search' : 'get'
|
||||||
|
|
||||||
|
// state normalization lookup table...
|
||||||
|
var states = {
|
||||||
|
true: true,
|
||||||
|
on: true,
|
||||||
|
false: false,
|
||||||
|
off: false,
|
||||||
|
// only two states, so next/prev are the same...
|
||||||
|
prev: 'next',
|
||||||
|
next: 'next',
|
||||||
|
'?': '?',
|
||||||
|
'??': '??',
|
||||||
|
'!': '!',
|
||||||
|
}
|
||||||
|
|
||||||
|
return function(item, state){
|
||||||
|
var that = this
|
||||||
|
// normalize/parse args...
|
||||||
|
state = item in states ?
|
||||||
|
item
|
||||||
|
: state
|
||||||
|
item = (state === item ?
|
||||||
|
null
|
||||||
|
: item)
|
||||||
|
|| _default_item.call(this)
|
||||||
|
state = state in states ?
|
||||||
|
states[state]
|
||||||
|
: 'next'
|
||||||
|
|
||||||
|
return [
|
||||||
|
state == '??' ?
|
||||||
|
[true, false]
|
||||||
|
: item == null ?
|
||||||
|
false
|
||||||
|
: state == '?' ?
|
||||||
|
[this[getter](item)]
|
||||||
|
.flat()
|
||||||
|
.map(_get_state)
|
||||||
|
: state === true ?
|
||||||
|
_set_state.call(this, item)
|
||||||
|
: state == false ?
|
||||||
|
_unset_state.call(this, item)
|
||||||
|
: [this[getter](item)]
|
||||||
|
.flat()
|
||||||
|
.map(function(e){
|
||||||
|
// NOTE: 'next' and '!' are opposites of each other...
|
||||||
|
return (state == 'next' ?
|
||||||
|
_get_state(e)
|
||||||
|
: !_get_state(e)) ?
|
||||||
|
_unset_state.call(that, e)
|
||||||
|
: _set_state.call(that, e) })
|
||||||
|
]
|
||||||
|
.flat()
|
||||||
|
// normalize for single item results -> return item and array...
|
||||||
|
.run(function(){
|
||||||
|
return this.length == 1 ?
|
||||||
|
this[0]
|
||||||
|
: this }) } }
|
||||||
|
// XXX this is incomplete...
|
||||||
|
var makeItemEventToggler2 = function(get_state, set_state, unset_state, default_item){
|
||||||
|
var _get_state = get_state instanceof Function ?
|
||||||
|
get_state
|
||||||
|
: function(e){ return !!e[get_state] }
|
||||||
|
var _set_state = set_state instanceof Function ?
|
||||||
|
set_state
|
||||||
|
: function(e){ return !!this[set_state](e) }
|
||||||
|
var _unset_state = unset_state instanceof Function ?
|
||||||
|
unset_state
|
||||||
|
: function(e){ return !this[unset_state](e) }
|
||||||
|
|
||||||
|
return toggler.Toggler(
|
||||||
|
default_item,
|
||||||
|
function(item, state){
|
||||||
|
if(item == null){
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return state == null ?
|
||||||
|
_get_state(item)
|
||||||
|
: state
|
||||||
|
},
|
||||||
|
[true, false],
|
||||||
|
function(state, item){
|
||||||
|
// if no item focused/given return false...
|
||||||
|
return item == null ?
|
||||||
|
false
|
||||||
|
// XXX add support for item lists...
|
||||||
|
: state ?
|
||||||
|
_set_state.call(this, item)
|
||||||
|
: _unset_state.call(this, item) })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
var BaseBrowserClassPrototype = {
|
var BaseBrowserClassPrototype = {
|
||||||
@ -1834,6 +1955,19 @@ var BaseBrowserPrototype = {
|
|||||||
// XXX
|
// XXX
|
||||||
__event_handlers: null,
|
__event_handlers: null,
|
||||||
|
|
||||||
|
// List events...
|
||||||
|
// XXX avoid going through expensive props...
|
||||||
|
get events(){
|
||||||
|
var that = this
|
||||||
|
return Object.deepKeys(this)
|
||||||
|
.map(function(key){
|
||||||
|
return (key != 'events'
|
||||||
|
&& that[key] instanceof Function
|
||||||
|
&& that[key].event) ?
|
||||||
|
that[key].event
|
||||||
|
: [] })
|
||||||
|
.flat() },
|
||||||
|
|
||||||
// Generic event infrastructure...
|
// Generic event infrastructure...
|
||||||
//
|
//
|
||||||
// Bind a handler to an event...
|
// Bind a handler to an event...
|
||||||
@ -1850,9 +1984,9 @@ var BaseBrowserPrototype = {
|
|||||||
//
|
//
|
||||||
// XXX need to design a means for this system to interact both
|
// XXX need to design a means for this system to interact both
|
||||||
// ways with DOM events...
|
// ways with DOM events...
|
||||||
// XXX need to bubble the event up through the nested browsers...
|
|
||||||
// XXX should we be able to trigger events from the item directly???
|
// XXX should we be able to trigger events from the item directly???
|
||||||
// i.e. .get(42).on('open', ...) instead of .get(42).open = ...
|
// i.e. .get(42).on('open', ...) instead of .get(42).open = ...
|
||||||
|
// XXX might be a good idea to create an item wrapper object...
|
||||||
on: function(evt, handler, tag){
|
on: function(evt, handler, tag){
|
||||||
var handlers = this.__event_handlers = this.__event_handlers || {}
|
var handlers = this.__event_handlers = this.__event_handlers || {}
|
||||||
handlers = handlers[evt] = handlers[evt] || []
|
handlers = handlers[evt] = handlers[evt] || []
|
||||||
@ -1961,7 +2095,6 @@ var BaseBrowserPrototype = {
|
|||||||
// - call parent's .trigger(<event-name>, ..)
|
// - call parent's .trigger(<event-name>, ..)
|
||||||
//
|
//
|
||||||
// for docs on <event-object> see BrowserEvent(..)
|
// for docs on <event-object> see BrowserEvent(..)
|
||||||
//
|
|
||||||
trigger: function(evt, ...args){
|
trigger: function(evt, ...args){
|
||||||
var that = this
|
var that = this
|
||||||
|
|
||||||
@ -2005,19 +2138,6 @@ var BaseBrowserPrototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
// List events...
|
|
||||||
// XXX avoid going through expensive props...
|
|
||||||
get events(){
|
|
||||||
var that = this
|
|
||||||
return Object.deepKeys(this)
|
|
||||||
.map(function(key){
|
|
||||||
return (key != 'events'
|
|
||||||
&& that[key] instanceof Function
|
|
||||||
&& that[key].event) ?
|
|
||||||
that[key].event
|
|
||||||
: [] })
|
|
||||||
.flat() },
|
|
||||||
|
|
||||||
// domain events/actions...
|
// domain events/actions...
|
||||||
//
|
//
|
||||||
// Bind a handler to an event...
|
// Bind a handler to an event...
|
||||||
@ -2043,32 +2163,38 @@ var BaseBrowserPrototype = {
|
|||||||
blur: makeItemEventMethod('blur', function(evt, items){
|
blur: makeItemEventMethod('blur', function(evt, items){
|
||||||
items.forEach(function(item){
|
items.forEach(function(item){
|
||||||
delete item.focused }) }),
|
delete item.focused }) }),
|
||||||
// XXX should we select .focused by default???
|
toggleFocus: makeItemEventToggler('focused', 'focus', 'blur', 'focused', false),
|
||||||
|
|
||||||
select: makeItemEventMethod('select',
|
select: makeItemEventMethod('select',
|
||||||
function(evt, items){
|
function(evt, items){
|
||||||
items.forEach(function(item){
|
items.forEach(function(item){
|
||||||
item.selected = true }) },
|
item.selected = true }) },
|
||||||
// XXX is this a good default???
|
// XXX is this a good default???
|
||||||
function(){ return this.focused }),
|
function(){ return this.focused }),
|
||||||
// XXX should we deselect .focused by default???
|
|
||||||
deselect: makeItemEventMethod('deselect',
|
deselect: makeItemEventMethod('deselect',
|
||||||
function(evt, items){
|
function(evt, items){
|
||||||
items.forEach(function(item){
|
items.forEach(function(item){
|
||||||
delete item.selected }) },
|
delete item.selected }) },
|
||||||
function(){ return this.focused }),
|
function(){ return this.focused }),
|
||||||
open: makeItemEventMethod('open',
|
// XXX use a real toggler or just emulate toggler API???
|
||||||
function(evt, item){},
|
// ...meke these two the same and select the simpler version...
|
||||||
function(){ return this.focused }),
|
toggleSelect: makeItemEventToggler('selected', 'select', 'deselect', 'focused'),
|
||||||
enter: makeItemEventMethod('enter',
|
toggleSelect2: makeItemEventToggler2('selected', 'select', 'deselect', 'focused'),
|
||||||
function(evt, item){},
|
|
||||||
function(){ return this.focused }),
|
|
||||||
// XXX can/should we unify these???
|
|
||||||
collapse: makeItemEventMethod('collapse',
|
collapse: makeItemEventMethod('collapse',
|
||||||
function(evt, item){},
|
function(evt, item){},
|
||||||
function(){ return this.focused }),
|
function(){ return this.focused }),
|
||||||
expand: makeItemEventMethod('expand',
|
expand: makeItemEventMethod('expand',
|
||||||
function(evt, item){},
|
function(evt, item){},
|
||||||
function(){ return this.focused }),
|
function(){ return this.focused }),
|
||||||
|
toggleCollapse: makeItemEventToggler('collapsed', 'collapse', 'expand', 'focused'),
|
||||||
|
|
||||||
|
open: makeItemEventMethod('open',
|
||||||
|
function(evt, item){},
|
||||||
|
function(){ return this.focused }),
|
||||||
|
enter: makeItemEventMethod('enter',
|
||||||
|
function(evt, item){},
|
||||||
|
function(){ return this.focused }),
|
||||||
|
|
||||||
// XXX target can be item or path...
|
// XXX target can be item or path...
|
||||||
load: makeEventMethod('load', function(evt, item){}),
|
load: makeEventMethod('load', function(evt, item){}),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user