mirror of
				https://github.com/flynx/ImageGrid.git
				synced 2025-10-31 03:10:07 +00:00 
			
		
		
		
	moving to keyboard gen2...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									6730ec2f24
								
							
						
					
					
						commit
						ebb3fcdc39
					
				| @ -335,7 +335,7 @@ body { | |||||||
| 	font-weight: bold; | 	font-weight: bold; | ||||||
| 	font-style: italic; | 	font-style: italic; | ||||||
| } | } | ||||||
| .browse-widget.key-bindings .list>.ignored .text:first-child { | .browse-widget.key-bindings .list>.special-action .text:first-child { | ||||||
| 	font-style: italic; | 	font-style: italic; | ||||||
| 	font-weight: bold; | 	font-weight: bold; | ||||||
| } | } | ||||||
| @ -359,6 +359,15 @@ body { | |||||||
| 	margin-right: 0em; | 	margin-right: 0em; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /* key doc... */ | ||||||
|  | .browse-widget.key-bindings .list>.key[doc]:after { | ||||||
|  | 	display: inline; | ||||||
|  | 	content: " -- " attr(doc); | ||||||
|  | 	font-style: italic; | ||||||
|  | 	opacity: 0.5; | ||||||
|  | 	margin-left: 0.5em; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| .browse-widget.key-bindings .list>.new { | .browse-widget.key-bindings .list>.new { | ||||||
| 	font-style: italic; | 	font-style: italic; | ||||||
|  | |||||||
| @ -37,8 +37,9 @@ function customScale(n){ | |||||||
| // XXX might be a good idea to be able ignore actions rather than keys...
 | // XXX might be a good idea to be able ignore actions rather than keys...
 | ||||||
| // XXX add this to the global doc...
 | // XXX add this to the global doc...
 | ||||||
| var GLOBAL_KEYBOARD = | var GLOBAL_KEYBOARD = | ||||||
|  | window.GLOBAL_KEYBOARD = | ||||||
| module.GLOBAL_KEYBOARD = { | module.GLOBAL_KEYBOARD = { | ||||||
| 	'Global':{ | 	'Global': { | ||||||
| 		doc: 'Global bindings that take priority over other sections.', | 		doc: 'Global bindings that take priority over other sections.', | ||||||
| 		pattern: '*', | 		pattern: '*', | ||||||
| 
 | 
 | ||||||
| @ -409,6 +410,7 @@ var keyboard2 = require('lib/keyboard2') | |||||||
| // XXX do we want to add sub-sections to better organize keys for 
 | // XXX do we want to add sub-sections to better organize keys for 
 | ||||||
| // 		documentation???
 | // 		documentation???
 | ||||||
| var GLOBAL_KEYBOARD2 = | var GLOBAL_KEYBOARD2 = | ||||||
|  | window.GLOBAL_KEYBOARD2 = | ||||||
| module.GLOBAL_KEYBOARD2 = { | module.GLOBAL_KEYBOARD2 = { | ||||||
| 	'Global': { | 	'Global': { | ||||||
| 		doc: 'Global bindings that take priority over other sections.', | 		doc: 'Global bindings that take priority over other sections.', | ||||||
| @ -452,13 +454,9 @@ module.GLOBAL_KEYBOARD2 = { | |||||||
| 		], | 		], | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 		// NOTE: these are here so as to enable handling via the next 
 | 		// handle in next section...
 | ||||||
| 		// 		block, i.e. the Viewer
 | 		'(': 'NEXT_SECTION', | ||||||
| 		// 		...if not given, then the ignore above will shadow the 
 | 		')': 'NEXT_SECTION', | ||||||
| 		// 		keys...
 |  | ||||||
| 		// NOTE: the 'nop' action does not exist, this it will get ignored
 |  | ||||||
| 		'(': 'nop', |  | ||||||
| 		')': 'nop', |  | ||||||
| 
 | 
 | ||||||
| 		// zooming...
 | 		// zooming...
 | ||||||
| 		'#1': 'fitScreen', | 		'#1': 'fitScreen', | ||||||
| @ -503,8 +501,8 @@ module.GLOBAL_KEYBOARD2 = { | |||||||
| 
 | 
 | ||||||
| 		// ignore sorting and reversing...
 | 		// ignore sorting and reversing...
 | ||||||
| 		// XXX not sure about these yet, especially reversing...
 | 		// XXX not sure about these yet, especially reversing...
 | ||||||
| 		shift_R: 'IGNORE', | 		shift_R: 'DROP', | ||||||
| 		shift_S: 'IGNORE', | 		shift_S: 'DROP', | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	// XXX add "save as collection..."
 | 	// XXX add "save as collection..."
 | ||||||
| @ -749,6 +747,7 @@ module.GLOBAL_KEYBOARD2 = { | |||||||
| 		// NOTE: this stops the default: handler from getting the ctrl:
 | 		// NOTE: this stops the default: handler from getting the ctrl:
 | ||||||
| 		// 		key case...
 | 		// 		key case...
 | ||||||
| 		ctrl_C: '', | 		ctrl_C: '', | ||||||
|  | 		ctrl_V: '', | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 		// sort...
 | 		// sort...
 | ||||||
| @ -771,8 +770,8 @@ module.GLOBAL_KEYBOARD2 = { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| //keyboard = keyboard2
 | keyboard = keyboard2 | ||||||
| //GLOBAL_KEYBOARD = GLOBAL_KEYBOARD2
 | GLOBAL_KEYBOARD = GLOBAL_KEYBOARD2 | ||||||
| 
 | 
 | ||||||
| window.kb = keyboard2.Keyboard(GLOBAL_KEYBOARD2, keyboard2.checkGlobalMode) | window.kb = keyboard2.Keyboard(GLOBAL_KEYBOARD2, keyboard2.checkGlobalMode) | ||||||
| 
 | 
 | ||||||
| @ -808,8 +807,11 @@ var KeyboardActions = actions.Actions({ | |||||||
| 		'keyboard-event-source': 'window', | 		'keyboard-event-source': 'window', | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	get keyboard(){ | 	// XXX do we need these as wrappers???
 | ||||||
|  | 	get keybindigs(){ | ||||||
| 		return this.__keyboard_config }, | 		return this.__keyboard_config }, | ||||||
|  | 	get keyboard(){ | ||||||
|  | 		return this.__keyboard_object }, | ||||||
| 
 | 
 | ||||||
| 	pauseKeyboardRepeat: ['- Interface/', | 	pauseKeyboardRepeat: ['- Interface/', | ||||||
| 		function(){  | 		function(){  | ||||||
| @ -839,6 +841,25 @@ var KeyboardActions = actions.Actions({ | |||||||
| 				return true | 				return true | ||||||
| 			}).bind(this) | 			}).bind(this) | ||||||
| 
 | 
 | ||||||
|  | 			//* XXX gen2
 | ||||||
|  | 			var kb = this.__keyboard_object =  | ||||||
|  | 				this.__keyboard_object  | ||||||
|  | 					|| keyboard.Keyboard( | ||||||
|  | 						function(){ return that.__keyboard_config }, | ||||||
|  | 						function(mode, keyboard, context){  | ||||||
|  | 							var pattern = keyboard[mode].pattern || mode | ||||||
|  | 							var target = that.ribbons.viewer | ||||||
|  | 							return !pattern  | ||||||
|  | 								|| pattern == '*'  | ||||||
|  | 								// XXX legacy...
 | ||||||
|  | 								//|| $(pattern).length > 0
 | ||||||
|  | 								// XXX can we join these into one search???
 | ||||||
|  | 								|| target.is(pattern) | ||||||
|  | 								|| target.find(pattern).length > 0 | ||||||
|  | 						}) | ||||||
|  | 			kb.service_fields = kb.constructor.service_fields.concat(['pattern']) | ||||||
|  | 			//*/
 | ||||||
|  | 
 | ||||||
| 			// start/reset keyboard handling...
 | 			// start/reset keyboard handling...
 | ||||||
| 			if(state == 'on'){ | 			if(state == 'on'){ | ||||||
| 				var that = this | 				var that = this | ||||||
| @ -866,7 +887,8 @@ var KeyboardActions = actions.Actions({ | |||||||
| 					this.__keyboard_handler = | 					this.__keyboard_handler = | ||||||
| 						keyboard.stoppableKeyboardRepeat( | 						keyboard.stoppableKeyboardRepeat( | ||||||
| 							keyboard.makeKeyboardHandler( | 							keyboard.makeKeyboardHandler( | ||||||
| 								function(){ return that.__keyboard_config }, | 								this.keyboard, | ||||||
|  | 								//function(){ return that.__keyboard_config },
 | ||||||
| 								function(k){ window.DEBUG && console.log('KEY:', k) },  | 								function(k){ window.DEBUG && console.log('KEY:', k) },  | ||||||
| 								this), | 								this), | ||||||
| 							check) | 							check) | ||||||
| @ -879,7 +901,8 @@ var KeyboardActions = actions.Actions({ | |||||||
| 						keyboard.stoppableKeyboardRepeat( | 						keyboard.stoppableKeyboardRepeat( | ||||||
| 							keyboard.dropRepeatingkeys( | 							keyboard.dropRepeatingkeys( | ||||||
| 								keyboard.makeKeyboardHandler( | 								keyboard.makeKeyboardHandler( | ||||||
| 									function(){ return that.__keyboard_config }, | 									this.keyboard, | ||||||
|  | 									//function(){ return that.__keyboard_config },
 | ||||||
| 									function(k){ window.DEBUG && console.log(k) }, | 									function(k){ window.DEBUG && console.log(k) }, | ||||||
| 									this),  | 									this),  | ||||||
| 								function(){  | 								function(){  | ||||||
| @ -896,6 +919,7 @@ var KeyboardActions = actions.Actions({ | |||||||
| 					&& this.__keyboard_event_source | 					&& this.__keyboard_event_source | ||||||
| 						.off('keydown', this.__keyboard_handler) | 						.off('keydown', this.__keyboard_handler) | ||||||
| 
 | 
 | ||||||
|  | 				//delete this.__keyboard_object
 | ||||||
| 				delete this.__keyboard_handler | 				delete this.__keyboard_handler | ||||||
| 				delete this.__keyboard_event_source | 				delete this.__keyboard_event_source | ||||||
| 			} | 			} | ||||||
| @ -914,54 +938,46 @@ var KeyboardActions = actions.Actions({ | |||||||
| 	// XXX this does not check overloading between modes...
 | 	// XXX this does not check overloading between modes...
 | ||||||
| 	getKeysForAction: ['- Interface/', | 	getKeysForAction: ['- Interface/', | ||||||
| 		function(actions, modes){ | 		function(actions, modes){ | ||||||
|  | 			var that = this | ||||||
| 			actions = actions == '*' ? null : actions | 			actions = actions == '*' ? null : actions | ||||||
| 			actions = !actions || actions instanceof Array ? actions : [actions] | 			actions = !actions || actions instanceof Array ? actions : [actions] | ||||||
| 
 | 
 | ||||||
| 			modes = modes || null | 			modes = modes || null | ||||||
| 			modes = !modes || modes instanceof Array ? modes : [modes] | 			modes = !modes || modes instanceof Array ? modes : [modes] | ||||||
| 			modes = modes || this.getKeyboardModes() | 			modes = modes || this.keyboard.modes() | ||||||
|  | 
 | ||||||
|  | 			var keys = this.keyboard.keys('*') | ||||||
| 			 | 			 | ||||||
| 			// XXX does this handle overloading???
 |  | ||||||
| 			var help = keyboard.buildKeybindingsHelp( |  | ||||||
| 				this.keyboard,  |  | ||||||
| 				null,  |  | ||||||
| 				this, |  | ||||||
| 				// get full doc compatible with get path...
 |  | ||||||
| 				function(action, args){ |  | ||||||
| 					// NOTE: we do not care about the actual args 
 |  | ||||||
| 					// 		here, all we need is for this to mismatch
 |  | ||||||
| 					// 		if args exist...
 |  | ||||||
| 					//return args.length == 0 ? Object.keys(this.getPath(action))[0] : '--' })
 |  | ||||||
| 					return args.length == 0 ? action : '--' }) |  | ||||||
| 			var res = {} | 			var res = {} | ||||||
| 
 | 
 | ||||||
| 			// build the result...
 | 			// build the result...
 | ||||||
| 			Object.keys(help) | 			Object.keys(keys) | ||||||
| 				// filter modes...
 | 				// filter modes...
 | ||||||
| 				.filter(function(mode){ return modes.indexOf(mode) >= 0 }) | 				.filter(function(mode){ return modes.indexOf(mode) >= 0 }) | ||||||
| 				.forEach(function(mode){ | 				.forEach(function(mode){ | ||||||
| 					Object.keys(help[mode]) | 					Object.keys(keys[mode]) | ||||||
|  | 						// parse the actions...
 | ||||||
|  | 						// NOTE: this will ignore the no_defaults flag...
 | ||||||
|  | 						.map(function(action){  | ||||||
|  | 							action = keyboard.parseActionCall(action.doc || action) | ||||||
|  | 					   		return (action.arguments.length == 0  | ||||||
|  | 									&& action.action in that) ?  | ||||||
|  | 								action.action  | ||||||
|  | 								: '--'}) | ||||||
| 						// keep only the actions given...
 | 						// keep only the actions given...
 | ||||||
| 						.filter(function(action){ | 						.filter(function(action){ | ||||||
| 							return action != '--' | 							return action != '--' | ||||||
| 								&& action != 'doc'  |  | ||||||
| 								&& (!actions  | 								&& (!actions  | ||||||
| 									|| actions.indexOf(action) >= 0) | 									|| actions.indexOf(action) >= 0) | ||||||
| 						}) | 						}) | ||||||
| 						.forEach(function(action){ | 						.forEach(function(action){ | ||||||
| 							res[action] = (res[action] || []).concat(help[mode][action]) | 							res[action] = (res[action] || []).concat(keys[mode][action]) | ||||||
| 						}) | 						}) | ||||||
| 				}) | 				}) | ||||||
| 
 | 
 | ||||||
| 			return res | 			return res | ||||||
| 		}], | 		}], | ||||||
| 
 | 
 | ||||||
| 	// XXX argument #3 is not yet used (see: lib/keyboard.js)...
 |  | ||||||
| 	getKeyboardModes: ['- Interface/', |  | ||||||
| 		function(){ |  | ||||||
| 			return this.__keyboard_event_source ? |  | ||||||
| 				keyboard.getApplicableModes(this.keyboard, null, this.__keyboard_event_source) |  | ||||||
| 	   			: [] }], |  | ||||||
| 
 | 
 | ||||||
| 	// XXX need to pre-process the docs...
 | 	// XXX need to pre-process the docs...
 | ||||||
| 	// 		- remove the path component...
 | 	// 		- remove the path component...
 | ||||||
| @ -1008,37 +1024,19 @@ var KeyboardActions = actions.Actions({ | |||||||
| 	browseKeyboardBindings: ['Interface/Keyboard bindings...', | 	browseKeyboardBindings: ['Interface/Keyboard bindings...', | ||||||
| 		widgets.makeUIDialog(function(path, edit){ | 		widgets.makeUIDialog(function(path, edit){ | ||||||
| 			var actions = this | 			var actions = this | ||||||
|  | 			var keybindigs = this.keybindigs | ||||||
| 
 | 
 | ||||||
| 			// Format:
 | 			var keys = this.keyboard.keys('*') | ||||||
| 			// 	{
 |  | ||||||
| 			// 		<mode>: {
 |  | ||||||
| 			// 			<action-code>: [ <key>, ... ],
 |  | ||||||
| 			// 			...
 |  | ||||||
| 			// 		},
 |  | ||||||
| 			// 		...
 |  | ||||||
| 			// 	}
 |  | ||||||
| 			var keys = keyboard.buildKeybindingsHelp( |  | ||||||
| 				this.keyboard,  |  | ||||||
| 				null,  |  | ||||||
| 				this, |  | ||||||
| 				// get full doc compatible with get path...
 |  | ||||||
| 				function(action, args, no_default, doc){ |  | ||||||
| 					return action |  | ||||||
| 						+ (no_default ? '!' : '') |  | ||||||
| 						+ (args.length > 0 ? |  | ||||||
| 							': '+ args.map(JSON.stringify).join(' ') |  | ||||||
| 							: '')  |  | ||||||
| 				}) |  | ||||||
| 
 | 
 | ||||||
| 			var dialog = browse.makeLister(null,  | 			var dialog = browse.makeLister(null,  | ||||||
| 				function(path, make){ | 				function(path, make){ | ||||||
| 					Object.keys(keys) | 					Object.keys(keybindigs) | ||||||
| 						.forEach(function(mode){ | 						.forEach(function(mode){ | ||||||
| 							var ignored = actions.keyboard[mode].ignore || [] | 							var dropped = keybindigs[mode].drop || [] | ||||||
| 							var bound_ignored = [] | 							var bound_ignored = [] | ||||||
| 
 | 
 | ||||||
| 							// section heading...
 | 							// section heading...
 | ||||||
| 							make(keys[mode].doc ?  | 							make(keybindigs[mode].doc ?  | ||||||
| 									$('<span>') | 									$('<span>') | ||||||
| 										// NOTE: at this time adding a br
 | 										// NOTE: at this time adding a br
 | ||||||
| 										// 		is faster and simpler than
 | 										// 		is faster and simpler than
 | ||||||
| @ -1047,7 +1045,7 @@ var KeyboardActions = actions.Actions({ | |||||||
| 										.html(mode + '<br>') | 										.html(mode + '<br>') | ||||||
| 										.append($('<span>') | 										.append($('<span>') | ||||||
| 											.addClass('doc') | 											.addClass('doc') | ||||||
| 											.html(keys[mode].doc)) | 											.html(keybindigs[mode].doc)) | ||||||
| 									: mode,  | 									: mode,  | ||||||
| 									{  | 									{  | ||||||
| 										not_filtered_out: true, | 										not_filtered_out: true, | ||||||
| @ -1058,30 +1056,45 @@ var KeyboardActions = actions.Actions({ | |||||||
| 
 | 
 | ||||||
| 							// bindings...
 | 							// bindings...
 | ||||||
| 							var c = 0 | 							var c = 0 | ||||||
| 							Object.keys(keys[mode]).forEach(function(action){ | 							Object.keys(keys[mode] || {}).forEach(function(action){ | ||||||
| 								action != 'doc'  | 
 | ||||||
| 									// NOTE: wee need the button spec to be
 | 								var o = keyboard.parseActionCall(action) | ||||||
| 									// 		searchable, thus we are not using 
 | 								var doc = o.doc | ||||||
| 									// 		the keys attr as in .browseActions(..)
 | 								var code = o.action  | ||||||
| 									&& make([action, ' ', '$BUTTONS'] | 									+ (o.no_default ? '!' : '')  | ||||||
| 											.concat($('<span>') | 									+ (o.arguments.length > 0 ?  | ||||||
| 												.addClass('text') | 										(': '+ o.arguments.map(JSON.stringify).join(' ')) | ||||||
| 												.html(keys[mode][action] | 										: '') | ||||||
| 													// mark key if it is in ignored...
 | 
 | ||||||
| 													.map(function(s){  | 								// NOTE: wee need the button spec to be
 | ||||||
| 														s = s.split('+') | 								// 		searchable, thus we are not using 
 | ||||||
| 														var k = s.pop()  | 								// 		the keys attr as in .browseActions(..)
 | ||||||
| 														var i = ignored.indexOf(k) | 								make([code, ' ', '$BUTTONS'] | ||||||
| 														i >= 0  | 										.concat($('<span>') | ||||||
| 															&& bound_ignored | 											.addClass('text') | ||||||
| 																.push(ignored[i]) | 											.html(keys[mode][action] | ||||||
| 														s.push(k  | 												// mark key if it is in dropped...
 | ||||||
| 															+ (i >= 0 ?  '<sup>*</sup>' : '')) | 												.map(function(s){  | ||||||
| 														return s.join('+') }) | 													s = s.split('+') | ||||||
| 													.join(' / ')))) | 													var k = s.pop()  | ||||||
| 										.addClass('key ' | 													var i = dropped.indexOf(k) | ||||||
| 											+ (action == 'IGNORE' ? 'ignored' : '')) | 													i >= 0  | ||||||
| 									&& c++ | 														&& bound_ignored | ||||||
|  | 															.push(dropped[i]) | ||||||
|  | 													s.push(k  | ||||||
|  | 														+ (i >= 0 ?  '<sup>*</sup>' : '')) | ||||||
|  | 													return s.join('+') }) | ||||||
|  | 												.join(' / ')))) | ||||||
|  | 									.attr('doc',  | ||||||
|  | 										doc.trim() != '' ?  | ||||||
|  | 											doc  | ||||||
|  | 											: (actions.keyboard.special_handlers[action]  | ||||||
|  | 												|| null)) | ||||||
|  | 									.addClass('key ' | ||||||
|  | 										+ (action in actions.keyboard.special_handlers ? | ||||||
|  | 										   	'special-action'  | ||||||
|  | 											: '')) | ||||||
|  | 								c++ | ||||||
| 							}) | 							}) | ||||||
| 
 | 
 | ||||||
| 							// no keys in view mode...
 | 							// no keys in view mode...
 | ||||||
| @ -1102,7 +1115,7 @@ var KeyboardActions = actions.Actions({ | |||||||
| 									// 		together in path...
 | 									// 		together in path...
 | ||||||
| 									' ', | 									' ', | ||||||
| 									'$BUTTONS', | 									'$BUTTONS', | ||||||
| 									ignored | 									dropped | ||||||
| 										.filter(function(k){  | 										.filter(function(k){  | ||||||
| 											return bound_ignored.indexOf(k) == -1 }) | 											return bound_ignored.indexOf(k) == -1 }) | ||||||
| 										.join(' / ')]) | 										.join(' / ')]) | ||||||
| @ -1211,8 +1224,8 @@ var KeyboardActions = actions.Actions({ | |||||||
| 					: shift_modifiers +'+'+ shift_key | 					: shift_modifiers +'+'+ shift_key | ||||||
| 
 | 
 | ||||||
| 				var any = modes == 'any' | 				var any = modes == 'any' | ||||||
| 				modes = any ? this.getKeyboardModes() | 				modes = any ? this.keyboard.modes() | ||||||
| 					: modes == '*' ? Object.keys(this.keyboard)  | 					: modes == '*' ? Object.keys(this.keybindigs)  | ||||||
| 					: modes | 					: modes | ||||||
| 				modes = modes instanceof Array ? modes : [modes] | 				modes = modes instanceof Array ? modes : [modes] | ||||||
| 
 | 
 | ||||||
| @ -1225,7 +1238,7 @@ var KeyboardActions = actions.Actions({ | |||||||
| 								return false | 								return false | ||||||
| 							} | 							} | ||||||
| 
 | 
 | ||||||
| 							var i = that.keyboard[mode].ignore || [] | 							var i = that.keybindigs[mode].ignore || [] | ||||||
| 
 | 
 | ||||||
| 							ignore = i.indexOf(full_key) >= 0 | 							ignore = i.indexOf(full_key) >= 0 | ||||||
| 								|| i.indexOf(key) >= 0 | 								|| i.indexOf(key) >= 0 | ||||||
| @ -1250,7 +1263,7 @@ var KeyboardActions = actions.Actions({ | |||||||
| 						return false | 						return false | ||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 					var bindings = that.keyboard[mode] | 					var bindings = that.keybindigs[mode] | ||||||
| 
 | 
 | ||||||
| 					if(action){ | 					if(action){ | ||||||
| 						var match = 'direct' | 						var match = 'direct' | ||||||
| @ -1322,7 +1335,7 @@ var KeyboardActions = actions.Actions({ | |||||||
| 							res[mode] = handler | 							res[mode] = handler | ||||||
| 						} | 						} | ||||||
| 
 | 
 | ||||||
| 						ignore = any && handler == 'IGNORE' | 						ignore = any && handler == 'DROP' | ||||||
| 					} | 					} | ||||||
| 				}) | 				}) | ||||||
| 
 | 
 | ||||||
| @ -1343,7 +1356,7 @@ var KeyboardActions = actions.Actions({ | |||||||
| 					+ (args.length > 0 ?  | 					+ (args.length > 0 ?  | ||||||
| 						': '+ args.map(JSON.stringify).join(' ') | 						': '+ args.map(JSON.stringify).join(' ') | ||||||
| 						: '') | 						: '') | ||||||
| 			var bindings = this.keyboard[mode] | 			var bindings = this.keybindigs[mode] | ||||||
| 
 | 
 | ||||||
| 			var alias = code in bindings ? code : key | 			var alias = code in bindings ? code : key | ||||||
| 			var handler = bindings[key] || bindings[code] | 			var handler = bindings[key] || bindings[code] | ||||||
| @ -1391,7 +1404,7 @@ module.Keyboard = core.ImageGridFeatures.Feature({ | |||||||
| 		['start', | 		['start', | ||||||
| 			function(){ | 			function(){ | ||||||
| 				var that = this | 				var that = this | ||||||
| 				this.__keyboard_config = this.keyboard || GLOBAL_KEYBOARD | 				this.__keyboard_config = this.keybindigs || GLOBAL_KEYBOARD | ||||||
| 
 | 
 | ||||||
| 				this.toggleKeyboardHandling('on') | 				this.toggleKeyboardHandling('on') | ||||||
| 			}], | 			}], | ||||||
|  | |||||||
| @ -945,6 +945,7 @@ var BrowseActionsActions = actions.Actions({ | |||||||
| 			}).bind(this) | 			}).bind(this) | ||||||
| 
 | 
 | ||||||
| 			// Tree builder...
 | 			// Tree builder...
 | ||||||
|  | 			// XXX normalize actions -- whitespace, '!', args...
 | ||||||
| 			var buildTree = function(path, leaf, action, mode, tree){ | 			var buildTree = function(path, leaf, action, mode, tree){ | ||||||
| 				path = path.slice() | 				path = path.slice() | ||||||
| 				// build leaf...
 | 				// build leaf...
 | ||||||
| @ -1062,7 +1063,8 @@ var BrowseActionsActions = actions.Actions({ | |||||||
| 								disabled: mode == 'hidden' || mode == 'disabled', | 								disabled: mode == 'hidden' || mode == 'disabled', | ||||||
| 								hidden: mode == 'hidden', | 								hidden: mode == 'hidden', | ||||||
| 							}) | 							}) | ||||||
| 							.attr('keys', getKeys(action)) | 							// XXX need to normalize state -- comments, whitespace, etc...
 | ||||||
|  | 							.attr('keys', getKeys(action +': "'+ state +'"')) | ||||||
| 							.addClass([ | 							.addClass([ | ||||||
| 									state == cur_state ? 'selected highlighted' : '', | 									state == cur_state ? 'selected highlighted' : '', | ||||||
| 									mode == 'hidden' ? mode : '' | 									mode == 'hidden' ? mode : '' | ||||||
|  | |||||||
| @ -310,6 +310,10 @@ var KeyboardHandlerClassPrototype = { | |||||||
| 
 | 
 | ||||||
| var KeyboardHandlerPrototype = { | var KeyboardHandlerPrototype = { | ||||||
| 	//service_fields: ['doc', 'drop'],
 | 	//service_fields: ['doc', 'drop'],
 | ||||||
|  | 	special_handlers: { | ||||||
|  | 		DROP: 'drop key',  | ||||||
|  | 		NEXT_SECTION: 'handle key in next section', | ||||||
|  | 	}, | ||||||
| 
 | 
 | ||||||
| 	// Format:
 | 	// Format:
 | ||||||
| 	// 	{
 | 	// 	{
 | ||||||
| @ -384,16 +388,26 @@ var KeyboardHandlerPrototype = { | |||||||
| 	// NOTE: to match several compatible handlers, pass a list of handlers,
 | 	// NOTE: to match several compatible handlers, pass a list of handlers,
 | ||||||
| 	// 		the result for each will be merged into one common list.
 | 	// 		the result for each will be merged into one common list.
 | ||||||
| 	//
 | 	//
 | ||||||
| 	// XXX passing a list of handlers will yield a single list of kyes...
 | 	// Format:
 | ||||||
| 	// 		...should this list be split into handlers???
 | 	// 	{
 | ||||||
|  | 	// 		<mode>: {
 | ||||||
|  | 	// 			<handler>: [ <key>, ... ],
 | ||||||
|  | 	// 			...
 | ||||||
|  | 	// 		},
 | ||||||
|  | 	// 		...
 | ||||||
|  | 	// 	}
 | ||||||
|  | 	//
 | ||||||
| 	keys: function(handler){ | 	keys: function(handler){ | ||||||
| 		var that = this | 		var that = this | ||||||
| 		var res = {} | 		var res = {} | ||||||
| 		var keyboard = this.keyboard | 		var keyboard = this.keyboard | ||||||
| 		var key_separators = KEY_SEPARATORS  | 		var key_separators = KEY_SEPARATORS  | ||||||
| 		handler = arguments.length > 1 ? [].slice.call(arguments) | 		handler = arguments.length > 1 ? [].slice.call(arguments) | ||||||
|  | 			: handler == '*' || handler instanceof Function ? handler | ||||||
| 			: handler instanceof Array ? handler  | 			: handler instanceof Array ? handler  | ||||||
| 			: [handler] | 			: [handler] | ||||||
|  | 		var service_fields = this.service_fields  | ||||||
|  | 			|| this.constructor.service_fields | ||||||
| 
 | 
 | ||||||
| 		var walkAliases = function(res, rev, bindings, key, mod){ | 		var walkAliases = function(res, rev, bindings, key, mod){ | ||||||
| 			mod = mod || [] | 			mod = mod || [] | ||||||
| @ -415,36 +429,123 @@ var KeyboardHandlerPrototype = { | |||||||
| 
 | 
 | ||||||
| 			// build a reverse index...
 | 			// build a reverse index...
 | ||||||
| 			var rev = {} | 			var rev = {} | ||||||
| 			// XXX this will not work for handlers that are not strings...
 | 			// NOTE: this will not work for handlers that are not strings 
 | ||||||
| 			Object.keys(bindings).forEach(function(key){ | 			// 		and have no .doc...
 | ||||||
| 				rev[bindings[key]] = (rev[bindings[key]] || []).concat([key])  | 			Object.keys(bindings) | ||||||
| 			}) | 				.filter(function(key){  | ||||||
|  | 					return service_fields.indexOf(key) < 0 }) | ||||||
|  | 				.forEach(function(key){ | ||||||
|  | 					var h = bindings[key] | ||||||
|  | 					h = typeof(h) == typeof('str') ? h | ||||||
|  | 						: (h.doc || h.name) | ||||||
|  | 					rev[h] = (rev[h] || []) | ||||||
|  | 						.concat((rev[bindings[key]] || []).concat([key])) | ||||||
|  | 						.unique() | ||||||
|  | 				}) | ||||||
| 
 | 
 | ||||||
| 			var keys = [] | 			var seen = [] | ||||||
| 			handler.forEach(function(h){ | 			var handlers = handler == '*' ?  Object.keys(rev)  | ||||||
| 				keys = keys.concat((rev[h] || []).map(that.normalizeKey.bind(that))) | 				: handler instanceof Function ?  | ||||||
| 			}) | 					Object.keys(rev) | ||||||
|  | 						.filter(handler) | ||||||
|  | 				: handler | ||||||
| 
 | 
 | ||||||
| 			// find all reachable keys from the ones we just found in reverse...
 | 			handlers | ||||||
| 			keys.slice().forEach(function(key){ | 				.forEach(function(h){ | ||||||
| 				walkAliases(keys, rev, bindings, key) | 					var keys = (rev[h] || []).map(that.normalizeKey.bind(that)) | ||||||
| 
 | 
 | ||||||
| 				var mod = that.splitKey(key) | 					// find all reachable keys from the ones we just found in reverse...
 | ||||||
| 				var k = mod.pop() | 					keys.slice() | ||||||
|  | 						.filter(function(key){ return seen.indexOf(key) < 0 }) | ||||||
|  | 						.forEach(function(key){ | ||||||
|  | 							// direct aliases...
 | ||||||
|  | 							walkAliases(keys, rev, bindings, key) | ||||||
| 
 | 
 | ||||||
| 				k != key  | 							var mod = that.splitKey(key) | ||||||
| 					&& walkAliases(keys, rev, bindings, k, mod) | 							var k = mod.pop() | ||||||
| 			}) |  | ||||||
| 
 | 
 | ||||||
| 			if(keys.length > 0){ | 							// aliases with modifiers...
 | ||||||
| 				res[mode] = keys | 							k != key  | ||||||
| 			} | 								&& walkAliases(keys, rev, bindings, k, mod) | ||||||
|  | 
 | ||||||
|  | 							seen.push(seen) | ||||||
|  | 						}) | ||||||
|  | 
 | ||||||
|  | 					if(keys.length > 0){ | ||||||
|  | 						var m = res[mode] = res[mode] || {} | ||||||
|  | 						m[h] = keys | ||||||
|  | 					} | ||||||
|  | 				}) | ||||||
| 		}) | 		}) | ||||||
| 
 | 
 | ||||||
| 		return res | 		return res | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	// get/set handler for key...
 | 	// Get/set/unset handler for key...
 | ||||||
|  | 	//
 | ||||||
|  | 	// In general if handler is not passed this will get the handlers,
 | ||||||
|  | 	// if a handler is given this will set the handler, if the passed 
 | ||||||
|  | 	// handler is either null or '' then it will be unbound.
 | ||||||
|  | 	//
 | ||||||
|  | 	// 	Get handler for key in all modes...
 | ||||||
|  | 	// 	.handler(key)
 | ||||||
|  | 	// 	.handler('*', key)
 | ||||||
|  | 	// 		-> key-spec
 | ||||||
|  | 	//
 | ||||||
|  | 	// 	Get handlers for key in applicable modes...
 | ||||||
|  | 	// 	.handler('?', key)
 | ||||||
|  | 	// 	.handler('test', key)
 | ||||||
|  | 	// 		-> key-spec
 | ||||||
|  | 	//
 | ||||||
|  | 	// 	Get handler for key in a specific mode...
 | ||||||
|  | 	// 	.handler(mode, key)
 | ||||||
|  | 	// 		-> key-spec
 | ||||||
|  | 	//
 | ||||||
|  | 	// 	Get handler for key in a specific list of modes...
 | ||||||
|  | 	// 	.handler([mode, ..], key)
 | ||||||
|  | 	// 		-> key-spec
 | ||||||
|  | 	//
 | ||||||
|  | 	//
 | ||||||
|  | 	// 	Bind handler to key in specific mode...
 | ||||||
|  | 	// 	.handler(mode, key, handler)
 | ||||||
|  | 	// 		-> this
 | ||||||
|  | 	//
 | ||||||
|  | 	// 	Bind handler to key in all modes...
 | ||||||
|  | 	// 	.handler('*', key, handler)
 | ||||||
|  | 	// 		-> this
 | ||||||
|  | 	//
 | ||||||
|  | 	// 	Bind handler to key in applicable modes...
 | ||||||
|  | 	// 	.handler('?', key, handler)
 | ||||||
|  | 	// 	.handler('test', key, handler)
 | ||||||
|  | 	// 		-> this
 | ||||||
|  | 	//
 | ||||||
|  | 	// 	Bind handler to key in a specific list of modes...
 | ||||||
|  | 	// 	.handler([mode, ..], key, handler)
 | ||||||
|  | 	// 		-> this 
 | ||||||
|  | 	//
 | ||||||
|  | 	//
 | ||||||
|  | 	// 	Unbind handler from key in specific mode...
 | ||||||
|  | 	// 	.handler(mode, key, null)
 | ||||||
|  | 	// 	.handler(mode, key, '')
 | ||||||
|  | 	// 		-> this
 | ||||||
|  | 	//
 | ||||||
|  | 	// 	Unbind handler from key in all modes...
 | ||||||
|  | 	// 	.handler('*', key, null)
 | ||||||
|  | 	// 	.handler('*', key, '')
 | ||||||
|  | 	// 		-> this
 | ||||||
|  | 	//
 | ||||||
|  | 	// 	Unbind handler from key in applicable modes...
 | ||||||
|  | 	// 	.handler('?', key, null)
 | ||||||
|  | 	// 	.handler('?', key, '')
 | ||||||
|  | 	// 	.handler('test', key, null)
 | ||||||
|  | 	// 	.handler('test', key, '')
 | ||||||
|  | 	// 		-> this
 | ||||||
|  | 	//
 | ||||||
|  | 	// 	Unbind handler from key in a specific list of modes...
 | ||||||
|  | 	// 	.handler([mode, ..], key, null)
 | ||||||
|  | 	// 	.handler([mode, ..], key, '')
 | ||||||
|  | 	// 		-> this 
 | ||||||
|  | 	//
 | ||||||
| 	//
 | 	//
 | ||||||
| 	// Search order:
 | 	// Search order:
 | ||||||
| 	// 	- search for full key
 | 	// 	- search for full key
 | ||||||
| @ -456,11 +557,21 @@ var KeyboardHandlerPrototype = { | |||||||
| 	// 		- if an alias is found it is first checked with and then 
 | 	// 		- if an alias is found it is first checked with and then 
 | ||||||
| 	// 			without modifiers
 | 	// 			without modifiers
 | ||||||
| 	//
 | 	//
 | ||||||
|  | 	// XXX getting '(' yields a different result from 'shift-#9'
 | ||||||
| 	handler: function(mode, key, handler){ | 	handler: function(mode, key, handler){ | ||||||
| 		var that = this | 		var that = this | ||||||
| 		var keyboard = this.keyboard | 		var keyboard = this.keyboard | ||||||
| 		var key_separators = KEY_SEPARATORS   | 		var key_separators = KEY_SEPARATORS   | ||||||
| 
 | 
 | ||||||
|  | 		if(arguments.length == 0){ | ||||||
|  | 			return null | ||||||
|  | 		} | ||||||
|  | 		if(arguments.length == 1 && this.isKey(mode)){ | ||||||
|  | 			key = mode | ||||||
|  | 			mode = '*' | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 		var genKeys = function(key, shift_key){ | 		var genKeys = function(key, shift_key){ | ||||||
| 			// match candidates...
 | 			// match candidates...
 | ||||||
| 			return key_separators | 			return key_separators | ||||||
| @ -506,7 +617,7 @@ var KeyboardHandlerPrototype = { | |||||||
| 
 | 
 | ||||||
| 		// get modes...
 | 		// get modes...
 | ||||||
| 		var modes = mode == '*' ? Object.keys(keyboard) | 		var modes = mode == '*' ? Object.keys(keyboard) | ||||||
| 			: mode == 'applicable' || mode == '?' ? this.modes() | 			: mode == 'test' || mode == '?' ? this.modes() | ||||||
| 			: mode instanceof Array ? mode | 			: mode instanceof Array ? mode | ||||||
| 			: [mode] | 			: [mode] | ||||||
| 
 | 
 | ||||||
| @ -524,7 +635,7 @@ var KeyboardHandlerPrototype = { | |||||||
| 			//	.concat([k, c])
 | 			//	.concat([k, c])
 | ||||||
| 				.unique() | 				.unique() | ||||||
| 
 | 
 | ||||||
| 			var drop = mode == 'applicable' || mode == '?' | 			var drop = mode == 'test' || mode == '?' | ||||||
| 			for(var i=0; i < modes.length; i++){ | 			for(var i=0; i < modes.length; i++){ | ||||||
| 				var m = modes[i] | 				var m = modes[i] | ||||||
| 
 | 
 | ||||||
| @ -543,8 +654,8 @@ var KeyboardHandlerPrototype = { | |||||||
| 						mod) | 						mod) | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				// handle explicit IGNORE...
 | 				// handle explicit DROP...
 | ||||||
| 				if(drop && handler == 'IGNORE'){ | 				if(drop && handler == 'DROP'){ | ||||||
| 					break | 					break | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| @ -555,6 +666,8 @@ var KeyboardHandlerPrototype = { | |||||||
| 
 | 
 | ||||||
| 				// if key in .drop then ignore the rest...
 | 				// if key in .drop then ignore the rest...
 | ||||||
| 				if(drop  | 				if(drop  | ||||||
|  | 						// explicit go to next section...
 | ||||||
|  | 						&& handler != 'NEXT_SECTION' | ||||||
| 						&& (bindings.drop == '*' | 						&& (bindings.drop == '*' | ||||||
| 							// XXX should this be more flexible by adding a
 | 							// XXX should this be more flexible by adding a
 | ||||||
| 							// 		specific key combo?
 | 							// 		specific key combo?
 | ||||||
| @ -567,7 +680,7 @@ var KeyboardHandlerPrototype = { | |||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			return (typeof(mode) == typeof('str')  | 			return (typeof(mode) == typeof('str')  | ||||||
| 					&& ['*', 'applicable', '?'].indexOf(mode) < 0) ?  | 					&& ['*', 'test', '?'].indexOf(mode) < 0) ?  | ||||||
| 				res[mode] | 				res[mode] | ||||||
| 				: res | 				: res | ||||||
| 
 | 
 | ||||||
| @ -638,7 +751,7 @@ function makeKeyboardHandler(keyboard, unhandled, actions){ | |||||||
| 		var did_handling = false | 		var did_handling = false | ||||||
| 
 | 
 | ||||||
| 		var key = kb.event2key(evt) | 		var key = kb.event2key(evt) | ||||||
| 		var handlers = kb.handler('applicable', key) | 		var handlers = kb.handler('test', key) | ||||||
| 
 | 
 | ||||||
| 		Object.keys(handlers).forEach(function(mode){ | 		Object.keys(handlers).forEach(function(mode){ | ||||||
| 			if(res === false){ | 			if(res === false){ | ||||||
| @ -669,6 +782,7 @@ function makeKeyboardHandler(keyboard, unhandled, actions){ | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| //---------------------------------------------------------------------
 | //---------------------------------------------------------------------
 | ||||||
|  | // handler wrappers...
 | ||||||
| 
 | 
 | ||||||
| // Event handler wrapper to stop handling keys if check callback does 
 | // Event handler wrapper to stop handling keys if check callback does 
 | ||||||
| // not pass (returns false)...
 | // not pass (returns false)...
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user