mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
126 lines
3.6 KiB
JavaScript
126 lines
3.6 KiB
JavaScript
(function () {
|
|
var ns = $.namespace('pskl.service.keyboard');
|
|
|
|
ns.ShortcutService = function () {
|
|
this.shortcuts_ = {};
|
|
};
|
|
|
|
/**
|
|
* @public
|
|
*/
|
|
ns.ShortcutService.prototype.init = function() {
|
|
$(document.body).keydown($.proxy(this.onKeyUp_, this));
|
|
};
|
|
|
|
/**
|
|
* Add a keyboard shortcut
|
|
* @param {String} rawKey (case insensitive) key can be a meta (optional) + [a-z0-9] or
|
|
* a special key (check list of supported keys in KeycodeTranslator)
|
|
* eg. 'ctrl+A', 'del'
|
|
* @param {Function} callback should return true to let the original event perform its default action
|
|
*/
|
|
ns.ShortcutService.prototype.addShortcut = function (rawKey, callback) {
|
|
var parsedKey = this.parseKey_(rawKey.toLowerCase());
|
|
|
|
var key = parsedKey.key;
|
|
var meta = parsedKey.meta;
|
|
|
|
this.shortcuts_[key] = this.shortcuts_[key] || {};
|
|
|
|
if (this.shortcuts_[key][meta]) {
|
|
var keyStr = (meta !== 'normal' ? meta + ' + ' : '') + key;
|
|
console.error('[ShortcutService] >>> Shortcut [' + keyStr + '] already registered');
|
|
} else {
|
|
this.shortcuts_[key][meta] = callback;
|
|
}
|
|
};
|
|
|
|
ns.ShortcutService.prototype.addShortcuts = function (keys, callback) {
|
|
keys.forEach(function (key) {
|
|
this.addShortcut(key, callback);
|
|
}.bind(this));
|
|
};
|
|
|
|
ns.ShortcutService.prototype.removeShortcut = function (rawKey) {
|
|
var parsedKey = this.parseKey_(rawKey.toLowerCase());
|
|
var key = parsedKey.key;
|
|
var meta = parsedKey.meta;
|
|
|
|
this.shortcuts_[key] = this.shortcuts_[key] || {};
|
|
|
|
this.shortcuts_[key][meta] = null;
|
|
};
|
|
|
|
ns.ShortcutService.prototype.parseKey_ = function (key) {
|
|
var meta = this.getMetaKey_({
|
|
alt : key.indexOf('alt+') != -1,
|
|
shift : key.indexOf('shift+') != -1,
|
|
ctrl : key.indexOf('ctrl+') != -1
|
|
});
|
|
|
|
var parts = key.split(/\+(?!$)/);
|
|
key = parts[parts.length - 1];
|
|
return {meta : meta, key : key};
|
|
};
|
|
|
|
ns.ShortcutService.prototype.getMetaKey_ = function (meta) {
|
|
var keyBuffer = [];
|
|
['alt', 'ctrl', 'shift'].forEach(function (metaKey) {
|
|
if (meta[metaKey]) {
|
|
keyBuffer.push(metaKey);
|
|
}
|
|
});
|
|
|
|
if (keyBuffer.length > 0) {
|
|
return keyBuffer.join('+');
|
|
} else {
|
|
return 'normal';
|
|
}
|
|
};
|
|
/**
|
|
* @private
|
|
*/
|
|
ns.ShortcutService.prototype.onKeyUp_ = function(evt) {
|
|
if (!this.isInInput_(evt)) {
|
|
// jquery names FTW ...
|
|
var keycode = evt.which;
|
|
var targetTagName = evt.target.nodeName.toUpperCase();
|
|
var charkey = pskl.service.keyboard.KeycodeTranslator.toChar(keycode);
|
|
|
|
var keyShortcuts = this.shortcuts_[charkey];
|
|
if (keyShortcuts) {
|
|
var meta = this.getMetaKey_({
|
|
alt : this.isAltKeyPressed_(evt),
|
|
shift : this.isShiftKeyPressed_(evt),
|
|
ctrl : this.isCtrlKeyPressed_(evt)
|
|
});
|
|
var cb = keyShortcuts[meta];
|
|
|
|
if (cb) {
|
|
var bubble = cb(charkey);
|
|
if (bubble !== true) {
|
|
evt.preventDefault();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
ns.ShortcutService.prototype.isInInput_ = function (evt) {
|
|
var targetTagName = evt.target.nodeName.toUpperCase();
|
|
return targetTagName === 'INPUT' || targetTagName === 'TEXTAREA';
|
|
};
|
|
|
|
ns.ShortcutService.prototype.isCtrlKeyPressed_ = function (evt) {
|
|
return pskl.utils.UserAgent.isMac ? evt.metaKey : evt.ctrlKey;
|
|
};
|
|
|
|
ns.ShortcutService.prototype.isShiftKeyPressed_ = function (evt) {
|
|
return evt.shiftKey;
|
|
};
|
|
|
|
ns.ShortcutService.prototype.isAltKeyPressed_ = function (evt) {
|
|
return evt.altKey;
|
|
};
|
|
})();
|