/**
* @file teclado.js Librería para el porcesado y control del teclado
* @author José Luis Molina Soria
* @version 20130508
*/
if ( typeof module !== 'undefined' ) {
var MM = require('./MindMapJS.js');
}
/**
* Espacio de nombre para el proceso y control del teclado
* @namespace MM.teclado
* @property {MM.teclado.tecla} tecla - Funciones y constantes de tecla
* @property {MM.teclado.atajos} atajos - Manejador de atajos de teclado. P.E.: "Ctrl+Alt+i"
*/
MM.teclado = {};
/**
* Espacio de nombre para funciones y constantes de teclas
* @namespace MM.teclado.tecla
*/
MM.teclado.tecla = {
// teclas de función
f1 : 112,
f2 : 113,
f3 : 114,
f4 : 115,
f5 : 116,
f6 : 117,
f7 : 118,
f8 : 119,
f9 : 120,
f10 : 121,
f11 : 122,
f12 : 123,
// modificadores
shift : 16,
ctrl : 17,
alt : 18,
leftMeta : 91,
rightMeta : 92,
// bloqueos
scrolllock : 145,
numlock : 144,
capslock : 20,
// teclas de navegación y edición
pageup : 33,
pagedown : 34,
left : 37,
up : 38,
right :39,
down : 40,
ins : 45,
home : 36,
del : 46,
end : 35,
// otras
backspace : 8,
tab : 9,
enter : 13,
esc : 27,
escape : 27,
space : 32
};
// Cada navegador tiene mapeado el teclado de forma diferente
// para ajustarse a esta excepciones utlizamos las siguiente
MM.teclado.tecla.excepciones = {
// Firefox Chrome Safari Teclado Numérico
171: '+', 187: '+', 221: '+', 107: '+',
173: '-', 189: '-', 191: '-', 109: '-',
96: '0'
};
/**
* @desc Manejador de teclado para el evento keyDown
* @param {event} e Instancia de evento de teclado
*/
MM.teclado.keyDown = function (e){
if ( !MM.teclado.atajos.activo ) {
return true;
}
var evt = e ? e : window.event;
var key = window.Event ? evt.which : evt.keyCode;
var nombre = MM.teclado.tecla.nombre(key, evt);
if ( MM.teclado.tecla.esModificador(key) ) {
evt = key = nombre = null;
return true;
} else {
var nombreAtajo = MM.teclado.atajos.calcular(nombre, evt);
var a = MM.teclado.atajos.definidos[nombreAtajo];
if ( a && a.activo ) {
evt.preventDefault();
evt.stopPropagation();
MM.teclado.atajos.lanzar(nombreAtajo);
a = evt = key = nombre = nombreAtajo = null;
return false;
}
a = evt = key = nombre = nombreAtajo = null;
return true;
}
evt = key = nombre = null;
return true;
};
/**
* @desc Dado un valor devuelve el nombre de la tecla
* @param {integer} key valor númerico de una tecla
* @return {string} nombre asociado a una tecla
**/
MM.teclado.tecla.nombre = function ( key ) {
if ( this.excepciones[key]) {
return this.excepciones[key];
}
for (var name in this) {
if ( key === this[name] ) {
return name;
}
}
return String.fromCharCode(key);
};
/**
* @desc Dado un nombre nos devuelve su valor
* @param {string} nombre Nombre de una tecla
* @return {integer} valor asociado al nombre
**/
MM.teclado.tecla.valor = function ( nombre ) {
return this[nombre];
};
/**
* @desc Test para saber si una tecla es un modificador o no. Se trata de un
* modificador si la tecla es Ctrl o Alt o Shift o Meta
* @param {integer} key Tecla a comprobar
* @return {boolean} true si es un modificador y false en otro caso
**/
MM.teclado.tecla.esModificador = function ( key ) {
return key === this.ctrl || key === this.alt || key === this.shift ||
key === this.leftMeta || key === this.rightMeta;
};
/**
* @desc Comprueba si latecla es Ctrl
* @param {integer} key Tecla a comprobar
* @return {boolean} true si la tecla es Ctrl
**/
MM.teclado.tecla.esControl = function ( key ) {
return key === this.ctrl;
};
/**
* @desc Comprueba si la tecla es Alt
* @param {integer} key Tecla a comprobar
* @return {boolean} true si la tecla es Alt
**/
MM.teclado.tecla.esAlt = function ( key ) {
return key === this.alt;
};
/**
* @desc Comprueba si la una tecla es Shift (Mayúsculas)
* @param {integer} key Tecla a comprobar
* @return {boolean} true si la tecla es Shift (Mayúsculas)
**/
MM.teclado.tecla.esShift = function ( key ) {
return key === this.shift;
};
/**
* @desc Comprueba si la una tecla es Window
* @param {integer} key Tecla a comprobar
* @return {boolean} true si la tecla es Window
**/
MM.teclado.tecla.esMeta = function ( key ) {
return key === this.leftMeta || key === this.rightMeta;
};
/**
* Espacio de nombre manejos de atajos de teclado. P.E.: "Ctrl+Alt+i"
* @namespace MM.teclado.atajos
*/
MM.teclado.atajos = {
activo : true,
definidos : {},
ctrl : false,
shift : false,
alt : false,
window : false
};
/**
* @desc Añade una definición de atajo de teclado
* @param {string} atajo Nombre del atajo de teclado a añadir al control de atajos
* @param {function} f Función a ejecutar cuando se de el atajo
**/
MM.teclado.atajos.add = function ( atajo, f, contexto ) {
this.definidos[atajo] = { funcion : f,
contexto : contexto || this,
activo : true
};
};
/**
* @desc Calcula si existe una atajo para el estado actual de los modficiadores y una tecla dada
* @param {string} nombre Nombre de tecla pulsada
* @param {object} evt Evento de teclado
* @return {string | null} Nombre del atajo de teclado o null si no existe
**/
MM.teclado.atajos.calcular = function ( nombre, evt ) {
var reKey = new RegExp("\\+" + nombre + "$", "i" );
var reCtrl = /ctrl\+/i;
var reAlt = /alt\+/i;
var reShift = /shift\+/i;
var reWindow = /meta\+/i;
for (var name in this.definidos) {
if ( nombre === name ) { return name; }
if( reKey.test(name) &&
( evt.ctrlKey?reCtrl.test(name):!reCtrl.test(name)) &&
( (evt.altKey || evt.altGraphKey)?reAlt.test(name):!reAlt.test(name)) &&
( evt.shiftKey?reShift.test(name):!reShift.test(name)) &&
( evt.metaKey?reWindow.test(name):!reWindow.test(name)) ) {
return name;
}
}
reKey = reCtrl = reAlt = reShift = reWindow = null;
return null;
};
/**
* @desc Lanza la función asociada al atajo de teclado
* @param {string} atajo Nombre del atajo de teclado
**/
MM.teclado.atajos.lanzar = function (atajo) {
var a = this.definidos[atajo];
if ( a ) {
a.funcion.apply(a.contexto, []);
}
a = null;
};
/**
* @desc Lanza la función asociada al atajo de teclado
* @param {string} atajo Nombre del atajo de teclado
**/
MM.teclado.atajos.activar = function (atajo, valor) {
var a = this.definidos[atajo];
if ( a ) {
a.activo = valor;
}
a = null;
};
if ( typeof module !== 'undefined' ) {
module.exports = MM.teclado;
}
if ( window ) {
window.addEventListener ("keydown", MM.teclado.keyDown, true);
}