<commit_before>jsio('from shared.javascript import Class, bind')
jsio('import fan.ui.Component')

exports = Class(fan.ui.Component, function(supr) {
	
	this._className = 'KeyboardFocus'
	this._borderWidth = 7
	
	this.init = function() {
		supr(this, 'init')
		this._on(document, 'keydown', bind(this, '_onKeyDown'))
		
		this._focusIndex = -1
		this._panelIndex = -1
		this._keyMap = {}

		var keys = this.keys,
			keyMap = this._keyMap
		
		keyMap[keys['j']] = bind(this, '_moveFocus', 1) 
		keyMap[keys['k']] = bind(this, '_moveFocus', -1) 
		keyMap[keys['up arrow']] = this._keyMap[keys['j']]
		keyMap[keys['down arrow']] = this._keyMap[keys['k']]
		keyMap[keys['enter']] = bind(this, '_selectFocusedItem'),
		keyMap[keys['tab']] = bind(this, '_movePanel', 1)
		keyMap[keys['`']] = bind(this, '_movePanel', -1)
	}
	
	this.grabFocus = function(uiComponent) { this._focusedUIComponent = uiComponent }
	this.releaseFocus = function(uiComponent) {
		if (uiComponent != this._focusedUIComponent) { return }
		delete this._focusedUIComponent
	}

	this._onKeyDown = function(e) {
		if (this._focusedUIComponent) { return }
		var callback = this._keyMap[e.keyCode]
		if (callback) {
			e.cancel()
			callback()
		} 
	}
	
	this._movePanel = function(steps) {
		var newPanelIndex = this._panelIndex + steps
		if (newPanelIndex < 0 || newPanelIndex >= gPanels.length) { return }
		this._focusIndex = -1
		this._panelIndex = newPanelIndex
		this._moveFocus(1)
	}
	
	this._moveFocus = function(steps) {
		var panel = gPanels[this._panelIndex];
		if (!panel) { return }
		<commit_msg>Make right/left arrows mmic tab/` keystrokes, and make sure to call the keyboard select callback for a UI component in a timeout such that the event can complete first<commit_after>jsio('from shared.javascript import Class, bind')
jsio('import fan.ui.Component')

exports = Class(fan.ui.Component, function(supr) {
	
	this._className = 'KeyboardFocus'
	this._borderWidth = 7
	
	this.init = function() {
		supr(this, 'init')
		this._on(document, 'keydown', bind(this, '_onKeyDown'))
		
		this._focusIndex = -1
		this._panelIndex = -1
		this._keyMap = {}

		var keys = this.keys,
			keyMap = this._keyMap
		
		keyMap[keys['j']] = bind(this, '_moveFocus', 1) 
		keyMap[keys['k']] = bind(this, '_moveFocus', -1) 
		keyMap[keys['tab']] = bind(this, '_movePanel', 1)
		keyMap[keys['`']] = bind(this, '_movePanel', -1)

		keyMap[keys['up arrow']] = keyMap[keys['j']]
		keyMap[keys['down arrow']] = keyMap[keys['k']]
		keyMap[keys['right arrow']] = keyMap[keys['tab']]
		keyMap[keys['left arrow']] = keyMap[keys['`']]

		keyMap[keys['enter']] = bind(this, '_selectFocusedItem')
	}
	
	this.grabFocus = function(uiComponent) { this._focusedUIComponent = uiComponent }
	this.releaseFocus = function(uiComponent) {
		if (uiComponent != this._focusedUIComponent) { return }
		delete this._focusedUIComponent
	}

	this._onKeyDown = function(e) {
		if (this._focusedUIComponent) { return }
		var callback = this._keyMap[e.keyCode]
		if (callback) {
			e.cancel()
			setTimeout(callback)
		} 
	}
	
	this._movePanel = function(steps) {
		var newPanelIndex = this._panelIndex + steps
		if (newPanelIndex < 0 || newPanelIndex >= gPanels.length) { return }
		this._focusIndex = -1
		this._panelIndex = newPanelIndex
		this._moveFocus(1)
	}
	
	this._moveFocus = function(steps) {
		var panel = gPanels[this._panelIndex];
		if (!panel) { return }
		
{'fraction_non_alphanumeric': 0.1564705882352941, 'fraction_numerical': 0.0058823529411764705, 'mean_word_length': 4.339089481946624, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '89809', 'n_tokens_mistral': 1302, 'n_tokens_neox': 1180, 'n_words': 246}