make hash_handler more useful
This commit is contained in:
parent
c431f6a550
commit
6381f3e048
2 changed files with 106 additions and 168 deletions
|
|
@ -1,131 +1,21 @@
|
||||||
define(function(require, exports, module) {
|
define(function(require, exports, module) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var keyUtil = require("../lib/keys");
|
var oop = require("../lib/oop");
|
||||||
|
var HashHandler = require("../keyboard/hash_handler").HashHandler;
|
||||||
|
|
||||||
var CommandManager = function(platform, commands) {
|
var CommandManager = function(platform, commands) {
|
||||||
if (typeof platform !== "string")
|
|
||||||
throw new TypeError("'platform' argument must be either 'mac' or 'win'");
|
|
||||||
|
|
||||||
this.platform = platform;
|
this.platform = platform;
|
||||||
this.commands = {};
|
this.commands = {};
|
||||||
this.commmandKeyBinding = {};
|
this.commmandKeyBinding = {};
|
||||||
|
|
||||||
if (commands)
|
this.addCommands(commands);
|
||||||
commands.forEach(this.addCommand, this);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
oop.inherits(CommandManager, HashHandler);
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
this.addCommand = function(command) {
|
|
||||||
if (this.commands[command.name])
|
|
||||||
this.removeCommand(command);
|
|
||||||
|
|
||||||
this.commands[command.name] = command;
|
|
||||||
|
|
||||||
if (command.bindKey) {
|
|
||||||
this._buildKeyHash(command);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.removeCommand = function(command) {
|
|
||||||
var name = (typeof command === 'string' ? command : command.name);
|
|
||||||
command = this.commands[name];
|
|
||||||
delete this.commands[name];
|
|
||||||
|
|
||||||
// exaustive search is brute force but since removeCommand is
|
|
||||||
// not a performance critical operation this should be OK
|
|
||||||
var ckb = this.commmandKeyBinding;
|
|
||||||
for (var hashId in ckb) {
|
|
||||||
for (var key in ckb[hashId]) {
|
|
||||||
if (ckb[hashId][key] == command)
|
|
||||||
delete ckb[hashId][key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.addCommands = function(commands) {
|
|
||||||
Object.keys(commands).forEach(function(name) {
|
|
||||||
var command = commands[name];
|
|
||||||
if (typeof command === "string")
|
|
||||||
return this.bindKey(command, name);
|
|
||||||
|
|
||||||
if (typeof command === "function")
|
|
||||||
command = { exec: command };
|
|
||||||
|
|
||||||
if (!command.name)
|
|
||||||
command.name = name;
|
|
||||||
|
|
||||||
this.addCommand(command);
|
|
||||||
}, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.removeCommands = function(commands) {
|
|
||||||
Object.keys(commands).forEach(function(name) {
|
|
||||||
this.removeCommand(commands[name]);
|
|
||||||
}, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.bindKey = function(key, command) {
|
|
||||||
if(!key)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var ckb = this.commmandKeyBinding;
|
|
||||||
key.split("|").forEach(function(keyPart) {
|
|
||||||
var binding = parseKeys(keyPart, command);
|
|
||||||
var hashId = binding.hashId;
|
|
||||||
(ckb[hashId] || (ckb[hashId] = {}))[binding.key] = command;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
this.bindKeys = function(keyList) {
|
|
||||||
Object.keys(keyList).forEach(function(key) {
|
|
||||||
this.bindKey(key, keyList[key]);
|
|
||||||
}, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
this._buildKeyHash = function(command) {
|
|
||||||
var binding = command.bindKey;
|
|
||||||
if (!binding)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var key = typeof binding == "string" ? binding: binding[this.platform];
|
|
||||||
this.bindKey(key, command);
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseKeys(keys, val, ret) {
|
|
||||||
var key;
|
|
||||||
var hashId = 0;
|
|
||||||
var parts = splitSafe(keys);
|
|
||||||
|
|
||||||
for (var i=0, l = parts.length; i < l; i++) {
|
|
||||||
if (keyUtil.KEY_MODS[parts[i]])
|
|
||||||
hashId = hashId | keyUtil.KEY_MODS[parts[i]];
|
|
||||||
else
|
|
||||||
key = parts[i] || "-"; //when empty, the splitSafe removed a '-'
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
key: key,
|
|
||||||
hashId: hashId
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function splitSafe(s, separator) {
|
|
||||||
return (s.toLowerCase()
|
|
||||||
.trim()
|
|
||||||
.split(new RegExp("[\\s ]*\\-[\\s ]*", "g"), 999));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.findKeyCommand = function findKeyCommand(hashId, textOrKey) {
|
|
||||||
// Convert keyCode to the string representation.
|
|
||||||
if (typeof textOrKey == "number") {
|
|
||||||
textOrKey = keyUtil.keyCodeToString(textOrKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
var ckbr = this.commmandKeyBinding;
|
|
||||||
return ckbr[hashId] && ckbr[hashId][textOrKey.toLowerCase()];
|
|
||||||
}
|
|
||||||
|
|
||||||
this.exec = function(command, editor, args) {
|
this.exec = function(command, editor, args) {
|
||||||
if (typeof command === 'string')
|
if (typeof command === 'string')
|
||||||
|
|
|
||||||
|
|
@ -41,76 +41,124 @@ define(function(require, exports, module) {
|
||||||
|
|
||||||
var keyUtil = require("../lib/keys");
|
var keyUtil = require("../lib/keys");
|
||||||
|
|
||||||
function HashHandler(config) {
|
function HashHandler(config, platform) {
|
||||||
this.setConfig(config);
|
this.platform = platform;
|
||||||
}
|
this.commands = {};
|
||||||
|
this.commmandKeyBinding = {};
|
||||||
|
|
||||||
|
this.addCommands(config);
|
||||||
|
};
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
function splitSafe(s, separator, limit, bLowerCase) {
|
|
||||||
return (bLowerCase && s.toLowerCase() || s)
|
this.addCommand = function(command) {
|
||||||
.replace(/(?:^\s+|\n|\s+$)/g, "")
|
if (this.commands[command.name])
|
||||||
.split(new RegExp("[\\s ]*" + separator + "[\\s ]*", "g"), limit || 999);
|
this.removeCommand(command);
|
||||||
|
|
||||||
|
this.commands[command.name] = command;
|
||||||
|
|
||||||
|
if (command.bindKey) {
|
||||||
|
this._buildKeyHash(command);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.removeCommand = function(command) {
|
||||||
|
var name = (typeof command === 'string' ? command : command.name);
|
||||||
|
command = this.commands[name];
|
||||||
|
delete this.commands[name];
|
||||||
|
|
||||||
|
// exhaustive search is brute force but since removeCommand is
|
||||||
|
// not a performance critical operation this should be OK
|
||||||
|
var ckb = this.commmandKeyBinding;
|
||||||
|
for (var hashId in ckb) {
|
||||||
|
for (var key in ckb[hashId]) {
|
||||||
|
if (ckb[hashId][key] == command)
|
||||||
|
delete ckb[hashId][key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.addCommands = function(commands) {
|
||||||
|
commands && Object.keys(commands).forEach(function(name) {
|
||||||
|
var command = commands[name];
|
||||||
|
if (typeof command === "string")
|
||||||
|
return this.bindKey(command, name);
|
||||||
|
|
||||||
|
if (typeof command === "function")
|
||||||
|
command = { exec: command };
|
||||||
|
|
||||||
|
if (!command.name)
|
||||||
|
command.name = name;
|
||||||
|
|
||||||
|
this.addCommand(command);
|
||||||
|
}, this);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.removeCommands = function(commands) {
|
||||||
|
Object.keys(commands).forEach(function(name) {
|
||||||
|
this.removeCommand(commands[name]);
|
||||||
|
}, this);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.bindKey = function(key, command) {
|
||||||
|
if(!key)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var ckb = this.commmandKeyBinding;
|
||||||
|
key.split("|").forEach(function(keyPart) {
|
||||||
|
var binding = parseKeys(keyPart, command);
|
||||||
|
var hashId = binding.hashId;
|
||||||
|
(ckb[hashId] || (ckb[hashId] = {}))[binding.key] = command;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
this.bindKeys = function(keyList) {
|
||||||
|
Object.keys(keyList).forEach(function(key) {
|
||||||
|
this.bindKey(key, keyList[key]);
|
||||||
|
}, this);
|
||||||
|
};
|
||||||
|
|
||||||
|
this._buildKeyHash = function(command) {
|
||||||
|
var binding = command.bindKey;
|
||||||
|
if (!binding)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var key = typeof binding == "string" ? binding: binding[this.platform];
|
||||||
|
this.bindKey(key, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseKeys(keys, val, ret) {
|
function parseKeys(keys, val, ret) {
|
||||||
var key,
|
var key;
|
||||||
hashId = 0,
|
var hashId = 0;
|
||||||
parts = splitSafe(keys, "\\-", null, true),
|
var parts = splitSafe(keys.toLowerCase());
|
||||||
i = 0,
|
|
||||||
l = parts.length;
|
|
||||||
|
|
||||||
for (; i < l; ++i) {
|
for (var i = 0, l = parts.length; i < l; i++) {
|
||||||
if (keyUtil.KEY_MODS[parts[i]])
|
if (keyUtil.KEY_MODS[parts[i]])
|
||||||
hashId = hashId | keyUtil.KEY_MODS[parts[i]];
|
hashId = hashId | keyUtil.KEY_MODS[parts[i]];
|
||||||
else
|
else
|
||||||
key = parts[i] || "-"; //when empty, the splitSafe removed a '-'
|
key = parts[i] || "-"; //when empty, the splitSafe removed a '-'
|
||||||
}
|
}
|
||||||
|
|
||||||
(ret[hashId] || (ret[hashId] = {}))[key] = val;
|
return {
|
||||||
return ret;
|
key: key,
|
||||||
}
|
hashId: hashId
|
||||||
|
|
||||||
function objectReverse(obj, keySplit) {
|
|
||||||
var i, j, l, key,
|
|
||||||
ret = {};
|
|
||||||
for (i in obj) {
|
|
||||||
key = obj[i];
|
|
||||||
if (keySplit && typeof key == "string") {
|
|
||||||
key = key.split(keySplit);
|
|
||||||
for (j = 0, l = key.length; j < l; ++j)
|
|
||||||
parseKeys.call(this, key[j], i, ret);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
parseKeys.call(this, key, i, ret);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setConfig = function(config) {
|
function splitSafe(s, separator) {
|
||||||
this.$config = config;
|
return (s.trim()
|
||||||
if (typeof this.$config.reverse == "undefined")
|
.split(new RegExp("[\\s ]*\\-[\\s ]*", "g"), 999));
|
||||||
this.$config.reverse = objectReverse.call(this, this.$config, "|");
|
}
|
||||||
|
|
||||||
|
this.findKeyCommand = function findKeyCommand(hashId, keyString) {
|
||||||
|
var ckbr = this.commmandKeyBinding;
|
||||||
|
return ckbr[hashId] && ckbr[hashId][keyString.toLowerCase()];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.handleKeyboard = function(data, hashId, keyString, keyCode) {
|
||||||
|
return this.findKeyCommand(hashId, keyString)
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* This function is called by keyBinding.
|
|
||||||
*/
|
|
||||||
this.handleKeyboard = function(data, hashId, textOrKey, keyCode) {
|
|
||||||
// Figure out if a commandKey was pressed or just some text was insert.
|
|
||||||
if (hashId != 0 || keyCode != 0) {
|
|
||||||
return {
|
|
||||||
command: (this.$config.reverse[hashId] || {})[textOrKey]
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
command: "inserttext",
|
|
||||||
args: {
|
|
||||||
text: textOrKey
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).call(HashHandler.prototype)
|
}).call(HashHandler.prototype)
|
||||||
|
|
||||||
exports.HashHandler = HashHandler;
|
exports.HashHandler = HashHandler;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue