mirror of
				https://github.com/flynx/ImageGrid.git
				synced 2025-10-31 11:20:09 +00:00 
			
		
		
		
	toggler now support accessor function on all args and uniformly (backwards incompatible) + some tweaking and cleanup...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									987a3f0ddb
								
							
						
					
					
						commit
						7c7777d745
					
				| @ -92,25 +92,40 @@ | |||||||
| // state_accessor signature:
 | // state_accessor signature:
 | ||||||
| //
 | //
 | ||||||
| // 	Get current state:
 | // 	Get current state:
 | ||||||
| // 	state_accessor()
 | // 	state_accessor(<elem>)
 | ||||||
| // 		-> <current-state>
 | // 		-> <current-state>
 | ||||||
| //
 | //
 | ||||||
| // 	Set new state:
 | // 	Set new state:
 | ||||||
| // 	state_accessor(<new-state>)
 | // 	state_accessor(<elem>, <new-state>)
 | ||||||
| // 		-> <new-state>
 | // 		-> <new-state>
 | ||||||
| //
 | //
 | ||||||
|  | // `this' within <state_accessor> is set to toggler's context.
 | ||||||
|  | //
 | ||||||
| // NOTE: for single state toggling, 'none' will get passed to 
 | // NOTE: for single state toggling, 'none' will get passed to 
 | ||||||
| // 		state_accessor to indicate an "empty" state...
 | // 		state_accessor to indicate an "empty" state...
 | ||||||
| // NOTE: if elem is a function it will be called in the same context as
 | // NOTE: if elem is a function it will be called in the same context as
 | ||||||
| // 		the toggler and is expected to return the element.
 | // 		the toggler and is expected to return the element.
 | ||||||
| //
 | //
 | ||||||
|  | //
 | ||||||
|  | // states can be:
 | ||||||
|  | // 	<state>				- state string, equivalent to ['none', <state>]
 | ||||||
|  | // 							this will produce a bool toggler that will toggle
 | ||||||
|  | // 							a single state on and off.
 | ||||||
|  | // 	[<state>, ...]		- list of string states that will be toggled 
 | ||||||
|  | // 							through, one special state 'none' is supported
 | ||||||
|  | // 	function(){ ... }	- function that will return either a state or 
 | ||||||
|  | // 							a list of states, `this' will be set to
 | ||||||
|  | // 							the toggler's context...
 | ||||||
|  | //
 | ||||||
|  | //
 | ||||||
| // 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
 | ||||||
| // 		via 'this'.
 | // 		via 'this'.
 | ||||||
| function Toggler(elem, state_accessor, states, callback_a, callback_b){ | function Toggler(elem, state_accessor, states, callback_a, callback_b){ | ||||||
| 	// normalize states...
 | 	// normalize states...
 | ||||||
| 	states = typeof(states) == typeof('str') ? ['none', states] : states | 	var states_getter = states | ||||||
|  | 	var state_set = typeof(states) == typeof('str') ? ['none', states] : states | ||||||
| 	// normalize the callbacks...
 | 	// normalize the callbacks...
 | ||||||
| 	if(callback_b === undefined){ | 	if(callback_b === undefined){ | ||||||
| 		var callback_pre = null | 		var callback_pre = null | ||||||
| @ -120,8 +135,6 @@ function Toggler(elem, state_accessor, states, callback_a, callback_b){ | |||||||
| 		var callback_post = callback_b | 		var callback_post = callback_b | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var bool_action = (states.length == 2 && states[0] == 'none') |  | ||||||
| 
 |  | ||||||
| 	// NOTE: this needs to be strict so as to be able to distinguish 
 | 	// NOTE: this needs to be strict so as to be able to distinguish 
 | ||||||
| 	// 		between a method and a root context in a simple manner...
 | 	// 		between a method and a root context in a simple manner...
 | ||||||
| 	var func = function(a, b){ | 	var func = function(a, b){ | ||||||
| @ -141,6 +154,17 @@ function Toggler(elem, state_accessor, states, callback_a, callback_b){ | |||||||
| 
 | 
 | ||||||
| 		e = e instanceof Function ? e.call(this) : e | 		e = e instanceof Function ? e.call(this) : e | ||||||
| 
 | 
 | ||||||
|  | 		// see if we got an explicit state list or need to use a getter...
 | ||||||
|  | 		var states = state_set | ||||||
|  | 		if(typeof(states_getter) == typeof(function(){})){ | ||||||
|  | 			// get the states...
 | ||||||
|  | 			var states = states_getter.call(this) | ||||||
|  | 			var states = typeof(states) == typeof('str') ?  | ||||||
|  | 				['none', states]  | ||||||
|  | 				: states | ||||||
|  | 		} | ||||||
|  | 		var bool_action = (state_set.length == 2 && state_set[0] == 'none') | ||||||
|  | 
 | ||||||
| 		// XXX is this correct???
 | 		// XXX is this correct???
 | ||||||
| 		var args = args2array(arguments).slice(2) | 		var args = args2array(arguments).slice(2) | ||||||
| 
 | 
 | ||||||
| @ -160,7 +184,7 @@ function Toggler(elem, state_accessor, states, callback_a, callback_b){ | |||||||
| 		// we need to get the current state...
 | 		// we need to get the current state...
 | ||||||
| 		if(action == null || action == '?' || action == '!'){ | 		if(action == null || action == '?' || action == '!'){ | ||||||
| 			// get current state...
 | 			// get current state...
 | ||||||
| 			var cur = state_accessor.call(e) | 			var cur = state_accessor.call(this, e) | ||||||
| 
 | 
 | ||||||
| 			// just asking for info...
 | 			// just asking for info...
 | ||||||
| 			if(action == '?'){ | 			if(action == '?'){ | ||||||
| @ -204,7 +228,7 @@ function Toggler(elem, state_accessor, states, callback_a, callback_b){ | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// update the element...
 | 		// update the element...
 | ||||||
| 		state_accessor.call(e, state) | 		state_accessor.call(this, e, state) | ||||||
| 
 | 
 | ||||||
| 		// post callback...
 | 		// post callback...
 | ||||||
| 		if(callback_post != null){ | 		if(callback_post != null){ | ||||||
| @ -217,21 +241,48 @@ function Toggler(elem, state_accessor, states, callback_a, callback_b){ | |||||||
| 		return action | 		return action | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	func.states = states | 	// XXX these are broken...
 | ||||||
| 	if(bool_action){ | 	//func.states = states
 | ||||||
| 		func.doc = 'With no arguments this will toggle between "on" and '+ | 	Object.defineProperty(func, 'states', { | ||||||
| 			'"off".\n'+ | 		get: function(){ | ||||||
| 			'If either "on" or "off" are given then this will switch '+ | 			return typeof(states_getter) == typeof(function(){}) ? | ||||||
| 			'to that mode.\n'+ | 				states_getter.apply(this) | ||||||
| 			'If "?" is given, this will return either "on" or "off" '+ | 				: state_set | ||||||
| 			'depending on the current state.' | 		}, | ||||||
| 	}else{ | 		set: function(value){ | ||||||
| 		func.doc = 'With no arguments this will toggle between '+ | 			state_set = states_getter = value | ||||||
| 			states +' in cycle.\n' +  | 		}, | ||||||
| 			'if any of the state names or its number is given then that '+ | 	}) | ||||||
| 			'state is switched on.'+ | 	Object.defineProperty(func, 'doc', { | ||||||
| 			'If "?" is given, this will return the current state.' | 		get: function(){ | ||||||
|  | 			if(func.__doc != null){ | ||||||
|  | 				return func.__doc | ||||||
| 			} | 			} | ||||||
|  | 			var states = typeof(states_getter) == typeof(function(){}) ? | ||||||
|  | 				states_getter.apply(this) | ||||||
|  | 				: state_set | ||||||
|  | 
 | ||||||
|  | 			// bool_action...
 | ||||||
|  | 			if(states.length == 2 && states[0] == 'none'){ | ||||||
|  | 				return 'With no arguments this will toggle between "on" and ' | ||||||
|  | 					+'"off".\n' | ||||||
|  | 					+'If either "on" or "off" are given then this will switch ' | ||||||
|  | 					+'to that mode.\n' | ||||||
|  | 					+'If "?" is given, this will return either "on" or "off" ' | ||||||
|  | 					+'depending on the current state.' | ||||||
|  | 
 | ||||||
|  | 			} else { | ||||||
|  | 				return 'With no arguments this will toggle between ' | ||||||
|  | 					+ states +' in cycle.\n'   | ||||||
|  | 					+'if any of the state names or its number is given then that ' | ||||||
|  | 					+'state is switched on.' | ||||||
|  | 					+'If "?" is given, this will return the current state.' | ||||||
|  | 			} | ||||||
|  | 		}, | ||||||
|  | 		set: function(value){ | ||||||
|  | 			func.__doc = value | ||||||
|  | 		}, | ||||||
|  | 	}) | ||||||
| 
 | 
 | ||||||
| 	func.__proto__ = Toggler.prototype | 	func.__proto__ = Toggler.prototype | ||||||
| 	func.constructor = Toggler | 	func.constructor = Toggler | ||||||
| @ -244,13 +295,20 @@ Toggler.prototype.__proto__ = Function.prototype | |||||||
| // XXX this should be drop-in compatible with createCSSClassToggler(..)
 | // XXX this should be drop-in compatible with createCSSClassToggler(..)
 | ||||||
| // 		test and replace...
 | // 		test and replace...
 | ||||||
| function CSSClassToggler(elem, classes, callback_a, callback_b){ | function CSSClassToggler(elem, classes, callback_a, callback_b){ | ||||||
| 	// normalize the states...
 | 	var classes_getter = classes | ||||||
|  | 	var classes_set = classes | ||||||
|  | 
 | ||||||
|  | 	var getClasses = function(){ | ||||||
|  | 		var classes = typeof(classes_getter) == typeof(function(){}) ?  | ||||||
|  | 				classes_getter.call(this) | ||||||
|  | 				: classes_set | ||||||
| 		classes = typeof(classes) == typeof('str') ? ['none', classes] : classes | 		classes = typeof(classes) == typeof('str') ? ['none', classes] : classes | ||||||
|  | 
 | ||||||
| 		// remove the dot from class names...
 | 		// remove the dot from class names...
 | ||||||
| 		// NOTE: this is here because I've made the error of including a 
 | 		// NOTE: this is here because I've made the error of including a 
 | ||||||
| 		// 		leading "." almost every time I use this after I forget 
 | 		// 		leading "." almost every time I use this after I forget 
 | ||||||
| 		// 		the UI...
 | 		// 		the UI...
 | ||||||
| 	classes = classes | 		return classes | ||||||
| 			.map(function(e){ | 			.map(function(e){ | ||||||
| 				return e.split(' ') | 				return e.split(' ') | ||||||
| 					.map(function(c){ | 					.map(function(c){ | ||||||
| @ -258,12 +316,25 @@ function CSSClassToggler(elem, classes, callback_a, callback_b){ | |||||||
| 						return c[0] == '.' ? c.slice(1) : c | 						return c[0] == '.' ? c.slice(1) : c | ||||||
| 					}).join(' ') | 					}).join(' ') | ||||||
| 			}) | 			}) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// normalize...
 | ||||||
|  | 	// NOTE: this happens here once if we got explicit classes, and on
 | ||||||
|  | 	// 		each access if we get a getter function...
 | ||||||
|  | 	classes_set = typeof(classes_getter) != typeof(function(){}) ? | ||||||
|  | 		getClasses.call(this) | ||||||
|  | 		: classes_set | ||||||
| 	 | 	 | ||||||
| 	var toggler = Toggler( | 	var toggler = Toggler( | ||||||
| 		elem, | 		elem, | ||||||
| 		function(state){ | 		function(e, state){ | ||||||
| 			'use strict' | 			'use strict' | ||||||
| 			var e = $(this == null ? elem : this) | 
 | ||||||
|  | 			var classes = classes_set.constructor === Array ? | ||||||
|  | 				classes_set | ||||||
|  | 				: getClasses.call(this) | ||||||
|  | 
 | ||||||
|  | 			e = $(e == null ? elem : e) | ||||||
| 			// get the state...
 | 			// get the state...
 | ||||||
| 			if(state == null){ | 			if(state == null){ | ||||||
| 				var cur = 'none' | 				var cur = 'none' | ||||||
| @ -286,7 +357,7 @@ function CSSClassToggler(elem, classes, callback_a, callback_b){ | |||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		},  | 		},  | ||||||
| 		classes,  | 		typeof(classes_getter) == typeof(function(){}) ? getClasses : classes_set, | ||||||
| 		callback_a,  | 		callback_a,  | ||||||
| 		callback_b) | 		callback_b) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ | |||||||
|     "height": 700, |     "height": 700, | ||||||
|     "min_width": 400, |     "min_width": 400, | ||||||
|     "min_height": 400, |     "min_height": 400, | ||||||
|     "frame": false, |     "frame": true, | ||||||
|     "toolbar": false, |     "toolbar": false, | ||||||
|     "show": false |     "show": false | ||||||
|   }, |   }, | ||||||
|  | |||||||
| @ -456,9 +456,9 @@ actions.Actions({ | |||||||
| 		function(all){ this.focusImage(all == null ? 'last' : -1) }], | 		function(all){ this.focusImage(all == null ? 'last' : -1) }], | ||||||
| 	// XXX these break if image at first/last position are not loaded (crop, group, ...)
 | 	// XXX these break if image at first/last position are not loaded (crop, group, ...)
 | ||||||
| 	// XXX do we actually need these???
 | 	// XXX do we actually need these???
 | ||||||
| 	firstGlobalImage: ['Navigate/First globally image', | 	firstGlobalImage: ['Navigate/First image globally', | ||||||
| 		function(){ this.firstImage(true) }], | 		function(){ this.firstImage(true) }], | ||||||
| 	lastGlobalImage: ['Navigate/Last globally image', | 	lastGlobalImage: ['Navigate/Last image globally', | ||||||
| 		function(){ this.lastImage(true) }], | 		function(){ this.lastImage(true) }], | ||||||
| 
 | 
 | ||||||
| 	// XXX skip unloaded images... (groups?)
 | 	// XXX skip unloaded images... (groups?)
 | ||||||
| @ -1160,14 +1160,8 @@ actions.Actions({ | |||||||
| 	toggleTheme: ['Interface/Toggle viewer theme',  | 	toggleTheme: ['Interface/Toggle viewer theme',  | ||||||
| 		CSSClassToggler( | 		CSSClassToggler( | ||||||
| 			function(){ return this.ribbons.viewer },  | 			function(){ return this.ribbons.viewer },  | ||||||
| 			// XXX how do we get this live from config???
 | 			function(){ return this.config.themes }, | ||||||
| 			//this.config.themes,
 | 			function(state){ this.config.theme = state }) ], | ||||||
| 			[ |  | ||||||
| 				'gray',  |  | ||||||
| 				'dark',  |  | ||||||
| 				'light', |  | ||||||
| 			], |  | ||||||
| 			function(state){ this.config['theme'] = state }) ], |  | ||||||
| 	setEmptyMsg: ['- Interface/Set message to be displayed when nothing is loaded.', | 	setEmptyMsg: ['- Interface/Set message to be displayed when nothing is loaded.', | ||||||
| 		function(msg, help){ this.ribbons.setEmptyMsg(msg, help) }], | 		function(msg, help){ this.ribbons.setEmptyMsg(msg, help) }], | ||||||
| 
 | 
 | ||||||
| @ -1717,7 +1711,11 @@ var ConfigLocalStorageActions = actions.Actions({ | |||||||
| 			key = key || this.config['config-local-storage-key'] | 			key = key || this.config['config-local-storage-key'] | ||||||
| 
 | 
 | ||||||
| 			if(key && localStorage[key]){ | 			if(key && localStorage[key]){ | ||||||
| 				this.config = JSON.parse(localStorage[key]) | 				var base = this.config | ||||||
|  | 				var loaded = JSON.parse(localStorage[key]) | ||||||
|  | 				loaded.__proto__ = base | ||||||
|  | 
 | ||||||
|  | 				this.config = loaded  | ||||||
| 			} | 			} | ||||||
| 		}], | 		}], | ||||||
| 
 | 
 | ||||||
| @ -3796,7 +3794,7 @@ var FileSystemLoaderActions = actions.Actions({ | |||||||
| 	// XXX add a symmetric equivalent to .prepareIndexForWrite(..) so as 
 | 	// XXX add a symmetric equivalent to .prepareIndexForWrite(..) so as 
 | ||||||
| 	// 		to enable features to load their data...
 | 	// 		to enable features to load their data...
 | ||||||
| 	// XXX look inside...
 | 	// XXX look inside...
 | ||||||
| 	loadIndex: ['File/Load index', | 	loadIndex: ['- File/Load index', | ||||||
| 		function(path, logger){ | 		function(path, logger){ | ||||||
| 			var that = this | 			var that = this | ||||||
| 
 | 
 | ||||||
| @ -3902,7 +3900,7 @@ var FileSystemLoaderActions = actions.Actions({ | |||||||
| 	// XXX add a recursive option...
 | 	// XXX add a recursive option...
 | ||||||
| 	// 		...might also be nice to add sub-dirs to ribbons...
 | 	// 		...might also be nice to add sub-dirs to ribbons...
 | ||||||
| 	// XXX make image pattern more generic...
 | 	// XXX make image pattern more generic...
 | ||||||
| 	loadImages: ['File/Load images', | 	loadImages: ['- File/Load images', | ||||||
| 		function(path, logger){ | 		function(path, logger){ | ||||||
| 			if(path == null){ | 			if(path == null){ | ||||||
| 				return | 				return | ||||||
| @ -3932,7 +3930,7 @@ var FileSystemLoaderActions = actions.Actions({ | |||||||
| 		}], | 		}], | ||||||
| 
 | 
 | ||||||
| 	// XXX auto-detect format or let the user chose...
 | 	// XXX auto-detect format or let the user chose...
 | ||||||
| 	loadPath: ['File/Load path (STUB)', | 	loadPath: ['- File/Load path (STUB)', | ||||||
| 		function(path, logger){ | 		function(path, logger){ | ||||||
| 			// XXX check if this.config['index-dir'] exists, if yes then
 | 			// XXX check if this.config['index-dir'] exists, if yes then
 | ||||||
| 			// 		.loadIndex(..) else .loadImages(..)
 | 			// 		.loadIndex(..) else .loadImages(..)
 | ||||||
| @ -4137,8 +4135,8 @@ var FileSystemLoaderUIActions = actions.Actions({ | |||||||
| 	// 		to start from.
 | 	// 		to start from.
 | ||||||
| 	// XXX should passing no path to this start browsing from the current
 | 	// XXX should passing no path to this start browsing from the current
 | ||||||
| 	// 		path or from the root?
 | 	// 		path or from the root?
 | ||||||
| 	loadIndex: [makeBrowseProxy('loadIndex')], | 	loadIndex: ['File/Load index', makeBrowseProxy('loadIndex')], | ||||||
| 	loadImages: [makeBrowseProxy('loadImages')], | 	loadImages: ['File/Load images', makeBrowseProxy('loadImages')], | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user