lkarch.org/tools/astray/keyboard.js
Lucas Kent e39465ad2f Changes to be committed:
new file:   Files/flashplayer_32_sa.exe
	new file:   favicon.ico
	new file:   globe.gif
	new file:   imgs/download.png
	new file:   imgs/zuck.jpg
	new file:   index.html
	new file:   other.ico
	new file:   script.js
	new file:   site.webmanifest
	new file:   sitemap.html
	new file:   styles/backround.css
	new file:   styles/border.css
	new file:   styles/fonts/Titillium_Web/OFL.txt
	new file:   styles/fonts/Titillium_Web/TitilliumWeb-Black.ttf
	new file:   styles/fonts/Titillium_Web/TitilliumWeb-Bold.ttf
	new file:   styles/fonts/Titillium_Web/TitilliumWeb-BoldItalic.ttf
	new file:   styles/fonts/Titillium_Web/TitilliumWeb-ExtraLight.ttf
	new file:   styles/fonts/Titillium_Web/TitilliumWeb-ExtraLightItalic.ttf
	new file:   styles/fonts/Titillium_Web/TitilliumWeb-Italic.ttf
	new file:   styles/fonts/Titillium_Web/TitilliumWeb-Light.ttf
	new file:   styles/fonts/Titillium_Web/TitilliumWeb-LightItalic.ttf
	new file:   styles/fonts/Titillium_Web/TitilliumWeb-Regular.ttf
	new file:   styles/fonts/Titillium_Web/TitilliumWeb-SemiBold.ttf
	new file:   styles/fonts/Titillium_Web/TitilliumWeb-SemiBoldItalic.ttf
	new file:   styles/fonts/webfontkit-20221027-163353/generator_config.txt
	new file:   styles/fonts/webfontkit-20221027-163353/specimen_files/grid_12-825-55-15.css
	new file:   styles/fonts/webfontkit-20221027-163353/specimen_files/specimen_stylesheet.css
	new file:   styles/fonts/webfontkit-20221027-163353/stylesheet.css
	new file:   styles/fonts/webfontkit-20221027-163353/titilliumweb-extralight-demo.html
	new file:   styles/fonts/webfontkit-20221027-163353/titilliumweb-extralight-webfont.woff
	new file:   styles/fonts/webfontkit-20221027-163353/titilliumweb-extralight-webfont.woff2
	new file:   styles/fonts/webfontkit-20221027-165950/generator_config.txt
	new file:   styles/fonts/webfontkit-20221027-165950/specimen_files/grid_12-825-55-15.css
	new file:   styles/fonts/webfontkit-20221027-165950/specimen_files/specimen_stylesheet.css
	new file:   styles/fonts/webfontkit-20221027-165950/stylesheet.css
	new file:   styles/fonts/webfontkit-20221027-165950/titilliumweb-bold-demo.html
	new file:   styles/fonts/webfontkit-20221027-165950/titilliumweb-bold-webfont.woff
	new file:   styles/fonts/webfontkit-20221027-165950/titilliumweb-bold-webfont.woff2
	new file:   styles/style.css
	new file:   tools/2048/.gitignore
	new file:   tools/2048/.jshintrc
	new file:   tools/2048/CONTRIBUTING.md
	new file:   tools/2048/LICENSE.txt
	new file:   tools/2048/README.md
	new file:   tools/2048/Rakefile
	new file:   tools/2048/favicon.ico
	new file:   tools/2048/index.html
	new file:   tools/2048/js/animframe_polyfill.js
	new file:   tools/2048/js/application.js
	new file:   tools/2048/js/bind_polyfill.js
	new file:   tools/2048/js/classlist_polyfill.js
	new file:   tools/2048/js/game_manager.js
	new file:   tools/2048/js/grid.js
	new file:   tools/2048/js/html_actuator.js
	new file:   tools/2048/js/keyboard_input_manager.js
	new file:   tools/2048/js/local_storage_manager.js
	new file:   tools/2048/js/tile.js
    new file:   tools/2048/meta/apple-touch-icon.png
	new file:   tools/webretro/cores/neocd_libretro.js
	new file:   tools/webretro/cores/neocd_libretro.wasm
	new file:   tools/webretro/cores/nestopia_libretro.js
	new file:   tools/webretro/cores/nestopia_libretro.wasm
	new file:   tools/webretro/cores/o2em_libretro.js
	new file:   tools/webretro/cores/o2em_libretro.wasm
	new file:   tools/webretro/cores/opera_libretro.js
	new file:   tools/webretro/cores/opera_libretro.wasm
2022-11-02 08:40:01 -04:00

491 lines
12 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*!
* KeyboardJS
*
* Copyright 2011, Robert William Hurst
* Licenced under the BSD License.
* See https://raw.github.com/RobertWHurst/KeyboardJS/master/license.txt
*/
(function (context, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(factory);
} else {
// Browser globals
context.k = context.KeyboardJS = factory();
}
}(this, function() {
//polyfills for ms's peice o' shit browsers
function bind(target, type, handler) { if (target.addEventListener) { target.addEventListener(type, handler, false); } else { target.attachEvent("on" + type, function(event) { return handler.call(target, event); }); } }
[].indexOf||(Array.prototype.indexOf=function(a,b,c){for(c=this.length,b=(c+~~b)%c;b<c&&(!(b in this)||this[b]!==a);b++);return b^c?b:-1;});
//locals
var locals = {
'us': {
"backspace": 8,
"tab": 9,
"enter": 13,
"shift": 16,
"ctrl": 17,
"alt": 18,
"pause": 19, "break": 19,
"capslock": 20,
"escape": 27, "esc": 27,
"space": 32, "spacebar": 32,
"pageup": 33,
"pagedown": 34,
"end": 35,
"home": 36,
"left": 37,
"up": 38,
"right": 39,
"down": 40,
"insert": 45,
"delete": 46,
"0": 48, "1": 49, "2": 50, "3": 51, "4": 52, "5": 53, "6": 54, "7": 55, "8": 56, "9": 57,
"a": 65, "b": 66, "c": 67, "d": 68, "e": 69, "f": 70, "g": 71, "h": 72, "i": 73, "j": 74, "k": 75, "l": 76, "m": 77, "n": 78, "o": 79, "p": 80, "q": 81, "r": 82, "s": 83, "t": 84, "u": 85, "v": 86, "w": 87, "x": 88, "y": 89, "z": 90,
"meta": 91, "command": 91, "windows": 91, "win": 91,
"_91": 92,
"select": 93,
"num0": 96, "num1": 97, "num2": 98, "num3": 99, "num4": 100, "num5": 101, "num6": 102, "num7": 103, "num8": 104, "num9": 105,
"multiply": 106,
"add": 107,
"subtract": 109,
"decimal": 110,
"divide": 111,
"f1": 112, "f2": 113, "f3": 114, "f4": 115, "f5": 116, "f6": 117, "f7": 118, "f8": 119, "f9": 120, "f10": 121, "f11": 122, "f12": 123,
"numlock": 144, "num": 144,
"scrolllock": 145, "scroll": 145,
"semicolon": 186,
"equal": 187, "equalsign": 187,
"comma": 188,
"dash": 189,
"period": 190,
"slash": 191, "forwardslash": 191,
"graveaccent": 192,
"openbracket": 219,
"backslash": 220,
"closebracket": 221,
"singlequote": 222
}
//If you create a new local please submit it as a pull request or post it in the issue tracker at
// http://github.com/RobertWhurst/KeyboardJS/issues/
}
//keys
var keys = locals['us'],
activeKeys = [],
activeBindings = {},
keyBindingGroups = [];
//adds keys to the active keys array
bind(document, "keydown", function(event) {
//lookup the key pressed and save it to the active keys array
for (var key in keys) {
if(keys.hasOwnProperty(key) && event.keyCode === keys[key]) {
if(activeKeys.indexOf(key) < 0) {
activeKeys.push(key);
}
}
}
//execute the first callback the longest key binding that matches the active keys
return executeActiveKeyBindings(event);
});
//removes keys from the active array
bind(document, "keyup", function (event) {
//lookup the key released and prune it from the active keys array
for(var key in keys) {
if(keys.hasOwnProperty(key) && event.keyCode === keys[key]) {
var iAK = activeKeys.indexOf(key);
if(iAK > -1) {
activeKeys.splice(iAK, 1);
}
}
}
//execute the end callback on the active key binding
return pruneActiveKeyBindings(event);
});
//bind to the window blur event and clear all pressed keys
bind(window, "blur", function() {
activeKeys = [];
//execute the end callback on the active key binding
return pruneActiveKeyBindings(event);
});
/**
* Generates an array of active key bindings
*/
function queryActiveBindings() {
var bindingStack = [];
//loop through the key binding groups by number of keys.
for(var keyCount = keyBindingGroups.length; keyCount > -1; keyCount -= 1) {
if(keyBindingGroups[keyCount]) {
var KeyBindingGroup = keyBindingGroups[keyCount];
//loop through the key bindings of the same key length.
for(var bindingIndex = 0; bindingIndex < KeyBindingGroup.length; bindingIndex += 1) {
var binding = KeyBindingGroup[bindingIndex],
//assume the binding is active till a required key is found to be unsatisfied
keyBindingActive = true;
//loop through each key required by the binding.
for(var keyIndex = 0; keyIndex < binding.keys.length; keyIndex += 1) {
var key = binding.keys[keyIndex];
//if the current key is not in the active keys array the mark the binding as inactive
if(activeKeys.indexOf(key) < 0) {
keyBindingActive = false;
}
}
//if the key combo is still active then push it into the binding stack
if(keyBindingActive) {
bindingStack.push(binding);
}
}
}
}
return bindingStack;
}
/**
* Collects active keys, sets active binds and fires on key down callbacks
* @param event
*/
function executeActiveKeyBindings(event) {
if(activeKeys < 1) {
return true;
}
var bindingStack = queryActiveBindings(),
spentKeys = [],
output;
//loop through each active binding
for (var bindingIndex = 0; bindingIndex < bindingStack.length; bindingIndex += 1) {
var binding = bindingStack[bindingIndex],
usesSpentKey = false;
//check each of the required keys. Make sure they have not been used by another binding
for(var keyIndex = 0; keyIndex < binding.keys.length; keyIndex += 1) {
var key = binding.keys[keyIndex];
if(spentKeys.indexOf(key) > -1) {
usesSpentKey = true;
break;
}
}
//if the binding does not use a key that has been spent then execute it
if(!usesSpentKey) {
//fire the callback
if(typeof binding.callback === "function") {
if(!binding.callback(event, binding.keys, binding.keyCombo)) {
output = false
}
}
//add the binding's combo to the active bindings array
if(!activeBindings[binding.keyCombo]) {
activeBindings[binding.keyCombo] = binding;
}
//add the current key binding's keys to the spent keys array
for(var keyIndex = 0; keyIndex < binding.keys.length; keyIndex += 1) {
var key = binding.keys[keyIndex];
if(spentKeys.indexOf(key) < 0) {
spentKeys.push(key);
}
}
}
}
//if there are spent keys then we know a binding was fired
// and that we need to tell jQuery to prevent event bubbling.
if(spentKeys.length) {
return false;
}
return output;
}
/**
* Removes no longer active keys and fires the on key up callbacks for associated active bindings.
* @param event
*/
function pruneActiveKeyBindings(event) {
var bindingStack = queryActiveBindings();
var output;
//loop through the active combos
for(var bindingCombo in activeBindings) {
if(activeBindings.hasOwnProperty(bindingCombo)) {
var binding = activeBindings[bindingCombo],
active = false;
//loop thorugh the active bindings
for(var bindingIndex = 0; bindingIndex < bindingStack.length; bindingIndex += 1) {
var activeCombo = bindingStack[bindingIndex].keyCombo;
//check to see if the combo is still active
if(activeCombo === bindingCombo) {
active = true;
break;
}
}
//if the combo is no longer active then fire its end callback and remove it
if(!active) {
if(typeof binding.endCallback === "function") {
if(!binding.endCallback(event, binding.keys, binding.keyCombo)) {
output = false
}
}
delete activeBindings[bindingCombo];
}
}
}
return output;
}
/**
* Binds a on key down and on key up callback to a key or key combo. Accepts a string containing the name of each
* key you want to bind to comma separated. If you want to bind a combo the use the plus sign to link keys together.
* Example: 'ctrl + x, ctrl + c' Will fire if Control and x or y are pressed at the same time.
* @param keyCombo
* @param callback
* @param endCallback
*/
function bindKey(keyCombo, callback, endCallback) {
function clear() {
if(keys && keys.length) {
var keyBindingGroup = keyBindingGroups[keys.length];
if(keyBindingGroup.indexOf(keyBinding) > -1) {
var index = keyBindingGroups[keys.length].indexOf(keyBinding);
keyBindingGroups[keys.length].splice(index, 1);
}
}
}
//create an array of combos from the first argument
var bindSets = keyCombo.toLowerCase().replace(/\s/g, '').split(',');
//create a binding for each key combo
for(var i = 0; i < bindSets.length; i += 1) {
//split up the keys
var keys = bindSets[i].split('+');
//if there are keys in the current combo
if(keys.length) {
if(!keyBindingGroups[keys.length]) { keyBindingGroups[keys.length] = []; }
//define the
var keyBinding = {
"callback": callback,
"endCallback": endCallback,
"keyCombo": bindSets[i],
"keys": keys
};
//save the binding sorted by length
keyBindingGroups[keys.length].push(keyBinding);
}
}
return {
"clear": clear
}
}
/**
* Binds keys or key combos to an axis. The keys should be in the following order; up, down, left, right. If any
* of the the binded key or key combos are active the callback will fire. The callback will be passed an array
* containing two numbers. The first represents x and the second represents y. Both have a possible range of -1,
* 0, or 1 depending on the axis direction.
* @param up
* @param down
* @param left
* @param right
* @param callback
*/
function bindAxis(up, down, left, right, callback) {
function clear() {
if(typeof clearUp === 'function') { clearUp(); }
if(typeof clearDown === 'function') { clearDown(); }
if(typeof clearLeft === 'function') { clearLeft(); }
if(typeof clearRight === 'function') { clearRight(); }
if(typeof timer === 'function') { clearInterval(timer); }
}
var axis = [0, 0];
if(typeof callback !== 'function') {
return false;
}
//up
var clearUp = bindKey(up, function () {
if(axis[0] === 0) {
axis[0] = -1;
}
}, function() {
axis[0] = 0;
}).clear;
//down
var clearDown = bindKey(down, function () {
if(axis[0] === 0) {
axis[0] = 1;
}
}, function() {
axis[0] = 0;
}).clear;
//left
var clearLeft = bindKey(left, function () {
if(axis[1] === 0) {
axis[1] = -1;
}
}, function() {
axis[1] = 0;
}).clear;
//right
var clearRight = bindKey(right, function () {
if(axis[1] === 0) {
axis[1] = 1;
}
}, function() {
axis[1] = 0;
}).clear;
var timer = setInterval(function(){
//NO CHANGE
if(axis[0] === 0 && axis[1] === 0) {
return;
}
//run the callback
callback(axis);
}, 1);
return {
"clear": clear
}
}
/**
* Clears all key and key combo binds containing a given key or keys.
* @param keys
*/
function unbindKey(keys) {
if(keys === 'all') {
keyBindingGroups = [];
return;
}
keys = keys.replace(/\s/g, '').split(',');
//loop through the key binding groups.
for(var iKCL = keyBindingGroups.length; iKCL > -1; iKCL -= 1) {
if(keyBindingGroups[iKCL]) {
var KeyBindingGroup = keyBindingGroups[iKCL];
//loop through the key bindings.
for(var iB = 0; iB < KeyBindingGroup.length; iB += 1) {
var keyBinding = KeyBindingGroup[iB],
remove = false;
//loop through the current key binding keys.
for(var iKB = 0; iKB < keyBinding.keys.length; iKB += 1) {
var key = keyBinding.keys[iKB];
//loop through the keys to be removed
for(var iKR = 0; iKR < keys.length; iKR += 1) {
var keyToRemove = keys[iKR];
if(keyToRemove === key) {
remove = true;
break;
}
}
if(remove) { break; }
}
if(remove) {
keyBindingGroups[iKCL].splice(iB, 1); iB -= 1;
if(keyBindingGroups[iKCL].length < 1) {
delete keyBindingGroups[iKCL];
}
}
}
}
}
}
/**
* Gets an array of active keys
*/
function getActiveKeys() {
return activeKeys;
}
/**
* Adds a new keyboard local not supported by keyboard JS
* @param local
* @param keys
*/
function addLocale(local, keys) {
locals[local] = keys;
}
/**
* Changes the keyboard local
* @param local
*/
function setLocale(local) {
if(locals[local]) {
keys = locals[local];
}
}
return {
"bind": {
"key": bindKey,
"axis": bindAxis
},
"activeKeys": getActiveKeys,
"unbind": {
"key": unbindKey
},
"locale": {
"add": addLocale,
"set": setLocale
}
}
}));