Path: blob/main/public/games/files/astray/keyboard.js
1036 views
/*!1* KeyboardJS2*3* Copyright 2011, Robert William Hurst4* Licenced under the BSD License.5* See https://raw.github.com/RobertWHurst/KeyboardJS/master/license.txt6*/7(function (context, factory) {8if (typeof define === 'function' && define.amd) {9// AMD. Register as an anonymous module.10define(factory);11} else {12// Browser globals13context.k = context.KeyboardJS = factory();14}15}(this, function() {1617//polyfills for ms's peice o' shit browsers18function bind(target, type, handler) { if (target.addEventListener) { target.addEventListener(type, handler, false); } else { target.attachEvent("on" + type, function(event) { return handler.call(target, event); }); } }19[].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;});2021//locals22var locals = {23'us': {24"backspace": 8,25"tab": 9,26"enter": 13,27"shift": 16,28"ctrl": 17,29"alt": 18,30"pause": 19, "break": 19,31"capslock": 20,32"escape": 27, "esc": 27,33"space": 32, "spacebar": 32,34"pageup": 33,35"pagedown": 34,36"end": 35,37"home": 36,38"left": 37,39"up": 38,40"right": 39,41"down": 40,42"insert": 45,43"delete": 46,44"0": 48, "1": 49, "2": 50, "3": 51, "4": 52, "5": 53, "6": 54, "7": 55, "8": 56, "9": 57,45"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,46"meta": 91, "command": 91, "windows": 91, "win": 91,47"_91": 92,48"select": 93,49"num0": 96, "num1": 97, "num2": 98, "num3": 99, "num4": 100, "num5": 101, "num6": 102, "num7": 103, "num8": 104, "num9": 105,50"multiply": 106,51"add": 107,52"subtract": 109,53"decimal": 110,54"divide": 111,55"f1": 112, "f2": 113, "f3": 114, "f4": 115, "f5": 116, "f6": 117, "f7": 118, "f8": 119, "f9": 120, "f10": 121, "f11": 122, "f12": 123,56"numlock": 144, "num": 144,57"scrolllock": 145, "scroll": 145,58"semicolon": 186,59"equal": 187, "equalsign": 187,60"comma": 188,61"dash": 189,62"period": 190,63"slash": 191, "forwardslash": 191,64"graveaccent": 192,65"openbracket": 219,66"backslash": 220,67"closebracket": 221,68"singlequote": 22269}7071//If you create a new local please submit it as a pull request or post it in the issue tracker at72// http://github.com/RobertWhurst/KeyboardJS/issues/73}7475//keys76var keys = locals['us'],77activeKeys = [],78activeBindings = {},79keyBindingGroups = [];8081//adds keys to the active keys array82bind(document, "keydown", function(event) {8384//lookup the key pressed and save it to the active keys array85for (var key in keys) {86if(keys.hasOwnProperty(key) && event.keyCode === keys[key]) {87if(activeKeys.indexOf(key) < 0) {88activeKeys.push(key);89}90}91}9293//execute the first callback the longest key binding that matches the active keys94return executeActiveKeyBindings(event);9596});9798//removes keys from the active array99bind(document, "keyup", function (event) {100101//lookup the key released and prune it from the active keys array102for(var key in keys) {103if(keys.hasOwnProperty(key) && event.keyCode === keys[key]) {104105var iAK = activeKeys.indexOf(key);106107if(iAK > -1) {108activeKeys.splice(iAK, 1);109}110}111}112113//execute the end callback on the active key binding114return pruneActiveKeyBindings(event);115116});117118//bind to the window blur event and clear all pressed keys119bind(window, "blur", function() {120activeKeys = [];121122//execute the end callback on the active key binding123return pruneActiveKeyBindings(event);124});125126/**127* Generates an array of active key bindings128*/129function queryActiveBindings() {130var bindingStack = [];131132//loop through the key binding groups by number of keys.133for(var keyCount = keyBindingGroups.length; keyCount > -1; keyCount -= 1) {134if(keyBindingGroups[keyCount]) {135var KeyBindingGroup = keyBindingGroups[keyCount];136137//loop through the key bindings of the same key length.138for(var bindingIndex = 0; bindingIndex < KeyBindingGroup.length; bindingIndex += 1) {139var binding = KeyBindingGroup[bindingIndex],140141//assume the binding is active till a required key is found to be unsatisfied142keyBindingActive = true;143144//loop through each key required by the binding.145for(var keyIndex = 0; keyIndex < binding.keys.length; keyIndex += 1) {146var key = binding.keys[keyIndex];147148//if the current key is not in the active keys array the mark the binding as inactive149if(activeKeys.indexOf(key) < 0) {150keyBindingActive = false;151}152}153154//if the key combo is still active then push it into the binding stack155if(keyBindingActive) {156bindingStack.push(binding);157}158}159}160}161162return bindingStack;163}164165/**166* Collects active keys, sets active binds and fires on key down callbacks167* @param event168*/169function executeActiveKeyBindings(event) {170171if(activeKeys < 1) {172return true;173}174175var bindingStack = queryActiveBindings(),176spentKeys = [],177output;178179//loop through each active binding180for (var bindingIndex = 0; bindingIndex < bindingStack.length; bindingIndex += 1) {181var binding = bindingStack[bindingIndex],182usesSpentKey = false;183184//check each of the required keys. Make sure they have not been used by another binding185for(var keyIndex = 0; keyIndex < binding.keys.length; keyIndex += 1) {186var key = binding.keys[keyIndex];187if(spentKeys.indexOf(key) > -1) {188usesSpentKey = true;189break;190}191}192193//if the binding does not use a key that has been spent then execute it194if(!usesSpentKey) {195196//fire the callback197if(typeof binding.callback === "function") {198if(!binding.callback(event, binding.keys, binding.keyCombo)) {199output = false200}201}202203//add the binding's combo to the active bindings array204if(!activeBindings[binding.keyCombo]) {205activeBindings[binding.keyCombo] = binding;206}207208//add the current key binding's keys to the spent keys array209for(var keyIndex = 0; keyIndex < binding.keys.length; keyIndex += 1) {210var key = binding.keys[keyIndex];211if(spentKeys.indexOf(key) < 0) {212spentKeys.push(key);213}214}215}216}217218//if there are spent keys then we know a binding was fired219// and that we need to tell jQuery to prevent event bubbling.220if(spentKeys.length) {221return false;222}223224return output;225}226227/**228* Removes no longer active keys and fires the on key up callbacks for associated active bindings.229* @param event230*/231function pruneActiveKeyBindings(event) {232var bindingStack = queryActiveBindings();233var output;234235//loop through the active combos236for(var bindingCombo in activeBindings) {237if(activeBindings.hasOwnProperty(bindingCombo)) {238var binding = activeBindings[bindingCombo],239active = false;240241//loop thorugh the active bindings242for(var bindingIndex = 0; bindingIndex < bindingStack.length; bindingIndex += 1) {243var activeCombo = bindingStack[bindingIndex].keyCombo;244245//check to see if the combo is still active246if(activeCombo === bindingCombo) {247active = true;248break;249}250}251252//if the combo is no longer active then fire its end callback and remove it253if(!active) {254255if(typeof binding.endCallback === "function") {256if(!binding.endCallback(event, binding.keys, binding.keyCombo)) {257output = false258}259}260261delete activeBindings[bindingCombo];262}263}264}265266return output;267}268269/**270* Binds a on key down and on key up callback to a key or key combo. Accepts a string containing the name of each271* key you want to bind to comma separated. If you want to bind a combo the use the plus sign to link keys together.272* Example: 'ctrl + x, ctrl + c' Will fire if Control and x or y are pressed at the same time.273* @param keyCombo274* @param callback275* @param endCallback276*/277function bindKey(keyCombo, callback, endCallback) {278279function clear() {280if(keys && keys.length) {281var keyBindingGroup = keyBindingGroups[keys.length];282283if(keyBindingGroup.indexOf(keyBinding) > -1) {284var index = keyBindingGroups[keys.length].indexOf(keyBinding);285keyBindingGroups[keys.length].splice(index, 1);286}287}288}289290//create an array of combos from the first argument291var bindSets = keyCombo.toLowerCase().replace(/\s/g, '').split(',');292293//create a binding for each key combo294for(var i = 0; i < bindSets.length; i += 1) {295296//split up the keys297var keys = bindSets[i].split('+');298299//if there are keys in the current combo300if(keys.length) {301if(!keyBindingGroups[keys.length]) { keyBindingGroups[keys.length] = []; }302303//define the304var keyBinding = {305"callback": callback,306"endCallback": endCallback,307"keyCombo": bindSets[i],308"keys": keys309};310311//save the binding sorted by length312keyBindingGroups[keys.length].push(keyBinding);313}314}315316return {317"clear": clear318}319}320321/**322* Binds keys or key combos to an axis. The keys should be in the following order; up, down, left, right. If any323* of the the binded key or key combos are active the callback will fire. The callback will be passed an array324* containing two numbers. The first represents x and the second represents y. Both have a possible range of -1,325* 0, or 1 depending on the axis direction.326* @param up327* @param down328* @param left329* @param right330* @param callback331*/332function bindAxis(up, down, left, right, callback) {333334function clear() {335if(typeof clearUp === 'function') { clearUp(); }336if(typeof clearDown === 'function') { clearDown(); }337if(typeof clearLeft === 'function') { clearLeft(); }338if(typeof clearRight === 'function') { clearRight(); }339if(typeof timer === 'function') { clearInterval(timer); }340}341342var axis = [0, 0];343344if(typeof callback !== 'function') {345return false;346}347348//up349var clearUp = bindKey(up, function () {350if(axis[0] === 0) {351axis[0] = -1;352}353}, function() {354axis[0] = 0;355}).clear;356357//down358var clearDown = bindKey(down, function () {359if(axis[0] === 0) {360axis[0] = 1;361}362}, function() {363axis[0] = 0;364}).clear;365366//left367var clearLeft = bindKey(left, function () {368if(axis[1] === 0) {369axis[1] = -1;370}371}, function() {372axis[1] = 0;373}).clear;374375//right376var clearRight = bindKey(right, function () {377if(axis[1] === 0) {378axis[1] = 1;379}380}, function() {381axis[1] = 0;382}).clear;383384var timer = setInterval(function(){385386//NO CHANGE387if(axis[0] === 0 && axis[1] === 0) {388return;389}390391//run the callback392callback(axis);393394}, 1);395396return {397"clear": clear398}399}400401/**402* Clears all key and key combo binds containing a given key or keys.403* @param keys404*/405function unbindKey(keys) {406407if(keys === 'all') {408keyBindingGroups = [];409return;410}411412keys = keys.replace(/\s/g, '').split(',');413414//loop through the key binding groups.415for(var iKCL = keyBindingGroups.length; iKCL > -1; iKCL -= 1) {416if(keyBindingGroups[iKCL]) {417var KeyBindingGroup = keyBindingGroups[iKCL];418419//loop through the key bindings.420for(var iB = 0; iB < KeyBindingGroup.length; iB += 1) {421var keyBinding = KeyBindingGroup[iB],422remove = false;423424//loop through the current key binding keys.425for(var iKB = 0; iKB < keyBinding.keys.length; iKB += 1) {426var key = keyBinding.keys[iKB];427428//loop through the keys to be removed429for(var iKR = 0; iKR < keys.length; iKR += 1) {430var keyToRemove = keys[iKR];431if(keyToRemove === key) {432remove = true;433break;434}435}436if(remove) { break; }437}438if(remove) {439keyBindingGroups[iKCL].splice(iB, 1); iB -= 1;440if(keyBindingGroups[iKCL].length < 1) {441delete keyBindingGroups[iKCL];442}443}444}445}446}447}448449/**450* Gets an array of active keys451*/452function getActiveKeys() {453return activeKeys;454}455456/**457* Adds a new keyboard local not supported by keyboard JS458* @param local459* @param keys460*/461function addLocale(local, keys) {462locals[local] = keys;463}464465/**466* Changes the keyboard local467* @param local468*/469function setLocale(local) {470if(locals[local]) {471keys = locals[local];472}473474}475476return {477"bind": {478"key": bindKey,479"axis": bindAxis480},481"activeKeys": getActiveKeys,482"unbind": {483"key": unbindKey484},485"locale": {486"add": addLocale,487"set": setLocale488}489}490}));491492