-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcommandServer.js
More file actions
executable file
·138 lines (127 loc) · 4.66 KB
/
Copy pathcommandServer.js
File metadata and controls
executable file
·138 lines (127 loc) · 4.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import i18n from "../i18n.js";
export default {
executeCommand, regisiterCommand, isCommand, executeCommandSlient, hook, regisiterCommandWithHotkey, regisiterHotkey
};
/**
* 命令列表
* @type {Map<String,Function>}
*/
export const regisiteredCommands = new Map([
["echo", (...args) => { return new String(args.join("")); }],
]);
/**
* 判断指定的命令是否存在
* @param {String} cmd
* @returns
*/
export function isCommand(cmd) {
if (!regisiteredCommands.has(cmd)) return false;
return (typeof (regisiteredCommands.get(cmd)) === "function");
}
/**
* 执行一个注册的命令
* @param {String} cmd 命令,忽略大小写和空白字符
* @param {...any} arg 命令参数
* @returns {*|Promise<*>} 该命令的返回值;
* @throws 命令不存在或者执行出错,会自动通知前端
*/
export function executeCommand(cmd, ...arg) {
try {
const cmdLowerCase = cmd.toLocaleLowerCase().replace(/\s+/g, "");
if (!isCommand(cmdLowerCase)) { throw new Error(i18n.parseSafe("panel.command.notFound", { cmd: cmd })); };
const v = regisiteredCommands.get(cmdLowerCase);
return v.apply(this, arg);
} catch (e) {
window.joyous.msg(i18n.parse("msg.command_failure", { msg: e.message }), i18n.parse("msg.done"), "error");
console.error(`无法执行命令 ${cmd} [${arg.join("|")}] :`, e);
throw e;
}
}
/**
* 执行一个注册的异步命令
* @param {String} cmd 命令,忽略大小写和空白字符
* @param {...any} arg 命令参数
* @param {boolean} [notify=true] 是否要通知前端
* @returns {不可能是Promise} 该命令的返回值;
* @throws 命令不存在或者执行出错
*/
export async function executeCommandAsync(cmd, notify = true, ...arg) {
try {
const cmdLowerCase = cmd.toLocaleLowerCase().replace(/\s+/g, "");
if (!isCommand(cmdLowerCase)) { throw new Error(i18n.parseSafe("panel.command.notFound", { cmd: cmd })); };
const v = regisiteredCommands.get(cmdLowerCase);
return await v.apply(this, arg);
} catch (e) {
if (notify) window.joyous.msg(i18n.parse("msg.command_failure", { msg: e.message }), i18n.parse("msg.done"), "error");
console.error(`无法执行命令 ${cmd} [${arg.join("|")}] :`, e);
throw e;
}
}
/**
* 静默执行一个注册的命令
* @param {String} cmd 命令,忽略大小写和空白字符
* @param {...any} arg 命令参数
* @returns 该命令的返回值;
* @throws 命令不存在或者执行出错,不会自动通知前端
*/
export function executeCommandSlient(cmd, ...arg) {
try {
const cmdLowerCase = cmd.toLowerCase().replace(/\s+/g, "");
if (!isCommand(cmdLowerCase)) { throw new Error(i18n.parseSafe("panel.command.notFound", { cmd: cmd })); };
const v = regisiteredCommands.get(cmdLowerCase);
return v.apply(this, arg);
} catch (e) {
console.error(`无法执行命令 ${cmd} [${arg.join("|")}] :`, e);
throw e;
}
}
// 挂载到全局
window.joyous.executeCommand = executeCommand;
window.joyous.executeCommandSlient = executeCommandSlient;
/**
* 注册一个命令
* @apinote 可以活用 this 判断上下文,例如 Event 通常是来自某个事件,而 window 可能来自命令面板
* @param {String} command 命令,忽略大小写和空白字符
* @param {Function} func
*/
export function regisiterCommand(command, func) {
regisiteredCommands.set(command.toLowerCase().replace(/\s+/g, ""), func);
}
/**
* 注册一个命令,顺便绑定快捷键
* @param {String} command
* @param {Function} func
* @param {string} key 快捷键
* @param {...*} args 快捷键触发时的参数
* @see {@link regisiterCommand(command, func)}
*/
export function regisiterCommandWithHotkey(command, func, key, ...args) {
regisiteredCommands.set(command.toLowerCase().replace(/\s+/g, ""), func);
if (key) {
hotkeys(key, () => { executeCommand(command, ...args); return false; });
};
}
/**
* 注册一个快捷键绑定命令
* 该快捷键被注册后会自动取消默认行为和冒泡,不能监听和影响浏览器保留按键
* @param {string} key 快捷键
* @param {String} command
* @param {...*} args 快捷键触发时的参数
*/
export function regisiterHotkey(key, command, ...args) {
if (!key || !command) { return; };
hotkeys(key, () => { executeCommand(command, ...args); return false; });
}
/**
* 注册某个元素下的声明式命令
* @param {Element} root
*/
export function hook(root = document.body) {
root.querySelectorAll("*[data-click]").forEach((e) => {
const cmd = e.dataset.click;
e.addEventListener("click", (event) => {
executeCommand.apply(event, cmd.split("|"));
});
e.removeAttribute("data-click"); // 移除以免重复绑定
});
}