添加模拟按键的功能

This commit is contained in:
fofolee 2020-04-22 01:20:19 +08:00
parent bced863572
commit 6a21e11817
3 changed files with 209 additions and 66 deletions

View File

@ -10,6 +10,13 @@ utools.onPluginEnter( async ({ code, type, payload }) => {
$("#out").show().text(''); $("#out").show().text('');
var db = utools.db.get('customFts').data[code], var db = utools.db.get('customFts').data[code],
cmd = db.cmd; cmd = db.cmd;
if (db.robotjs) {
utools.setExpendHeight(0);
utools.hideMainWindow();
eval(cmd);
utools.outPlugin();
return;
}
if (db.program == "custom") { if (db.program == "custom") {
option = db.customOptions; option = db.customOptions;
} else { } else {
@ -68,9 +75,8 @@ utools.onPluginEnter( async ({ code, type, payload }) => {
function runCmd(cmd, option, codec, output) { function runCmd(cmd, option, codec, output) {
// 不需要输出的,提前关闭窗口 // 不需要输出的,提前关闭窗口
if (['ignore', 'clip', 'send', 'notice', 'terminal'].indexOf(output) !== -1){ if (['ignore', 'clip', 'send', 'notice', 'terminal'].indexOf(output) !== -1) {
utools.hideMainWindow() utools.hideMainWindow()
utools.outPlugin()
} }
var terminal = false; var terminal = false;
if(output == 'terminal') terminal = true; if(output == 'terminal') terminal = true;
@ -78,8 +84,24 @@ function runCmd(cmd, option, codec, output) {
window.run(cmd, option, codec, terminal, (stdout, stderr) => { window.run(cmd, option, codec, terminal, (stdout, stderr) => {
if (stderr) { if (stderr) {
// 报错 // 报错
window.messageBox({ type: 'error', icon: window.logo, message: stderr, buttons: ['啊嘞?!'] }) utools.showMainWindow()
utools.outPlugin() Swal.fire({
title: '啊嘞?!',
text: stderr,
icon: 'error',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: '转至脚本目录',
cancelButtonText: '退出',
}).then((result) => {
if (result.value) {
open(resolve(tmpdir, `QuickCommandTempScript.${option.ext}`));
}
copyTo(stderr);
utools.showNotification("已复制报错信息");
utools.outPlugin();
})
} else if (stdout) { } else if (stdout) {
// 有输出 // 有输出
switch (output) { switch (output) {
@ -91,6 +113,7 @@ function runCmd(cmd, option, codec, output) {
break; break;
case "clip": case "clip":
copyTo(stdout); copyTo(stdout);
utools.outPlugin();
break; break;
case "send": case "send":
// 暂存用户剪贴板 // 暂存用户剪贴板
@ -100,12 +123,16 @@ function runCmd(cmd, option, codec, output) {
setTimeout(() => { setTimeout(() => {
restoreClip(historyData); restoreClip(historyData);
}, 500); }, 500);
utools.outPlugin();
break; break;
case "notice": case "notice":
// 发送系统通知 // 发送系统通知
utools.showNotification(stdout, null, true); utools.showNotification(stdout);
utools.outPlugin();
break; break;
case "ignore": case "ignore":
utools.outPlugin();
break;
default: default:
break; break;
} }

View File

@ -180,16 +180,37 @@
color: rgb(48, 21, 122); color: rgb(48, 21, 122);
} }
#options .keyword.key {
color: rgb(122, 115, 21);
}
#options .logo { #options .logo {
width: 32px; width: 32px;
} }
#options #customize .robot{
display: none;
}
#options #customize .keys{
width: 10%;
}
#options #customize .robot.footBtn{
background:#3085d6;
float: none;
}
#options #customize .robot.footBtn:hover{
background:#55aafa;
}
#options .footBtn { #options .footBtn {
float: right;
/* right: 5px; /* right: 5px;
bottom: 2px; */ bottom: 2px; */
border-radius: 4px; float: right;
background: #00af2c; background: #00af2c;
border-radius: 4px;
color: white; color: white;
padding: 2px 5px; padding: 2px 5px;
margin: 0px 5px; margin: 0px 5px;
@ -262,11 +283,10 @@
color: #bd3523; color: #bd3523;
} }
#options #customize input#custombin, #options #customize input.customscript {
#options #customize input#customarg,
#options #customize input#customext {
margin-left: 5px; margin-left: 5px;
width: 200px; width: 200px;
display: none;
} }
#options #customize { #options #customize {

View File

@ -29,7 +29,11 @@ importCommand = () => {
try { try {
var pushData = JSON.parse(data); var pushData = JSON.parse(data);
} catch (error) { } catch (error) {
window.messageBox({ type: 'error', icon: window.logo, message: "格式错误!", buttons: ['朕知道了'] }) Swal.fire({
icon: 'error',
title: '啊嘞?!',
text: '格式错误!',
})
return return
} }
// 单个命令导入 // 单个命令导入
@ -45,7 +49,11 @@ importCommand = () => {
} }
showOptions(); showOptions();
} else { } else {
window.messageBox({ type: 'error', icon: window.logo, message: "格式错误!", buttons: ['朕知道了'] }) Swal.fire({
icon: 'error',
title: '啊嘞?!',
text: '格式错误!',
})
} }
} }
}) })
@ -65,13 +73,21 @@ window.saveFile(options, JSON.stringify(json));
clearAll = () => { clearAll = () => {
window.messageBox({ type: 'question', icon: window.logo, message: "将会清空所有命令,请确认!", buttons: ['手抖...', '确定!'] }, index => { Swal.fire({
if (index) { text: '将会清空所有命令,请确认!',
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: '确定!',
cancelButtonText: '手抖...',
}).then((result) => {
if (result.value) {
utools.db.remove('customFts'); utools.db.remove('customFts');
clearAllFeatures(); clearAllFeatures();
showOptions(); showOptions();
} }
}) })
} }
programs = { programs = {
@ -130,7 +146,7 @@ programs = {
argv: '', argv: '',
ext: '' ext: ''
} }
} }
showOptions = () => { showOptions = () => {
var currentFts = utools.getFeatures(), var currentFts = utools.getFeatures(),
@ -146,7 +162,11 @@ showOptions = () => {
} else if (features.cmds[0].type == 'window') { } else if (features.cmds[0].type == 'window') {
var app = features.cmds[0].match.app var app = features.cmds[0].match.app
if (app.length > 15) app = app.slice(0, 15) + '...'; if (app.length > 15) app = app.slice(0, 15) + '...';
cmds = `<span class="keyword win">窗口: ${app}</span>`; if (customFts[fts].robotjs) {
cmds = `<span class="keyword key">按键: ${app}</span>`;
} else {
cmds = `<span class="keyword win">窗口: ${app}</span>`;
}
} else { } else {
features.cmds.forEach(cmd => { features.cmds.forEach(cmd => {
cmds += `<span class="keyword">${cmd}</span>`; cmds += `<span class="keyword">${cmd}</span>`;
@ -178,6 +198,7 @@ showOptions = () => {
<div id="clear" class="footBtn danger">全部删除</div> <div id="clear" class="footBtn danger">全部删除</div>
<div id="disableAll" class="footBtn danger">全部禁用</div> <div id="disableAll" class="footBtn danger">全部禁用</div>
<div id="enableAll" class="footBtn">全部启用</div> <div id="enableAll" class="footBtn">全部启用</div>
<div id="sample" class="footBtn">下载命令</div>
</div>` </div>`
$("#options").html(featureList); $("#options").html(featureList);
} }
@ -192,6 +213,7 @@ showCustomize = () => {
<option value="key">通过输入关键字进入插件</option> <option value="key">通过输入关键字进入插件</option>
<option value="regex">通过正则匹配主输入框文本</option> <option value="regex">通过正则匹配主输入框文本</option>
<option value="window">通过呼出uTools前的活动窗口匹配</option> <option value="window">通过呼出uTools前的活动窗口匹配</option>
<option value="robotjs">匹配窗口后模拟按键</option>
</select> </select>
<span class="word" id="ruleWord">关键字</span><input type="text" id="rule" placeholder=""></p> <span class="word" id="ruleWord">关键字</span><input type="text" id="rule" placeholder=""></p>
<p><span class="word">&#12288;</span><input type="text" id="desc" placeholder=""></p> <p><span class="word">&#12288;</span><input type="text" id="desc" placeholder=""></p>
@ -232,9 +254,29 @@ showCustomize = () => {
<p> <p>
<span class="word">&#12288;</span> <span class="word">&#12288;</span>
<span> <span>
<input type="text" id="custombin" style="display: none;" placeholder="解释器绝对路径"> <select id="modifier1" class="robot keys">
<input type="text" id="customarg" style="display: none;" placeholder="参数"> <option value=""></option>
<input type="text" id="customext" style="display: none;" placeholder="脚本后缀,不含."> <option value="control">control</option>
<option value="alt">alt</option>
<option value="shift">shift</option>
<option value="command">/win</option>
</select>
<select id="modifier2" class="robot keys">
<option value=""></option>
<option value="control">control</option>
<option value="alt">alt</option>
<option value="shift">shift</option>
<option value="command">/win</option>
</select>
<input type="text" id="presskey" class="robot keys" placeholder="按键">
<span id="addKey" class="robot footBtn">添加</span>
<input type="text" id="keydelay" class="robot keys" placeholder="延时">
<span id="addDelay" class="robot footBtn">添加</span>
</span>
<span>
<input type="text" id="custombin" class="customscript" placeholder="解释器绝对路径">
<input type="text" id="customarg" class="customscript" placeholder="参数">
<input type="text" id="customext" class="customscript" placeholder="脚本后缀,不含.">
</span> </span>
</p> </p>
<p><textarea id="cmd" placeholder="可以直接拖放脚本文件至此处"></textarea></p> <p><textarea id="cmd" placeholder="可以直接拖放脚本文件至此处"></textarea></p>
@ -249,7 +291,6 @@ showCustomize = () => {
} else { } else {
var shell = 'shell', var shell = 'shell',
mode = 'shell'; mode = 'shell';
$("#codec").hide();
} }
$("#program").val(shell); $("#program").val(shell);
$("#icon").attr('src', `logo/${shell}.png`); $("#icon").attr('src', `logo/${shell}.png`);
@ -280,6 +321,8 @@ outputCheck = () => {
// 检查模式选项 // 检查模式选项
typeCheck = () => { typeCheck = () => {
var type = $("#type").val(); var type = $("#type").val();
$("#output, #program, #vars").prop("disabled", false);
$(".robot").hide()
switch (type) { switch (type) {
case 'key': case 'key':
$("#ruleWord").html("关键字"); $("#ruleWord").html("关键字");
@ -293,6 +336,14 @@ typeCheck = () => {
$(".var.window").hide() $(".var.window").hide()
$("#rule").prop("placeholder", '匹配的正则规则,如/\\w+/i'); $("#rule").prop("placeholder", '匹配的正则规则,如/\\w+/i');
break; break;
case 'robotjs':
$("#ruleWord").html("进&#12288;程");
$("#output, #program, #vars").prop("disabled", true).val('');
$("#rule").prop("placeholder", '窗口的进程名支持正则如explorer.exe');
$(".robot").show();
$('.customscript').hide();
window.editor.setOption("mode", 'javascript');
break;
case 'window': case 'window':
$("#ruleWord").html("进&#12288;程"); $("#ruleWord").html("进&#12288;程");
$(".var.regex").hide() $(".var.regex").hide()
@ -322,6 +373,8 @@ $("#options").on('change', 'input[type=checkbox]', function () {
// 底部功能按钮 // 底部功能按钮
$("#options").on('click', '.footBtn', function () { $("#options").on('click', '.footBtn', function () {
switch ($(this).attr('id')) { switch ($(this).attr('id')) {
case 'sample': visit('https://github.com/fofolee/uTools-QuickerCommand/tree/master/CommandCollections');
break;
case 'add': showCustomize(); case 'add': showCustomize();
break; break;
case 'import': importCommand(); case 'import': importCommand();
@ -347,12 +400,13 @@ $("#options").on('click', '.editBtn', function () {
var code = $(this).attr('code'); var code = $(this).attr('code');
var data = utools.db.get("customFts").data[code]; var data = utools.db.get("customFts").data[code];
showCustomize(); showCustomize();
var robotjs = data.robotjs;
var cmds = data.features.cmds[0] var cmds = data.features.cmds[0]
if (cmds.type == 'regex') { if (cmds.type == 'regex') {
$('#type').val('regex') $('#type').val('regex')
$('#rule').val(cmds.match); $('#rule').val(cmds.match);
} else if (cmds.type == 'window') { } else if (cmds.type == 'window') {
$('#type').val('window') robotjs ? $('#type').val('robotjs') : $('#type').val('window')
$('#rule').val(cmds.match.app); $('#rule').val(cmds.match.app);
} else { } else {
$('#type').val('key') $('#type').val('key')
@ -362,7 +416,6 @@ $("#options").on('click', '.editBtn', function () {
$('#program').val(data.program); $('#program').val(data.program);
$('#output').val(data.output); $('#output').val(data.output);
$('#desc').val(data.features.explain); $('#desc').val(data.features.explain);
$('#codec').val(data.codec);
$("#icon").attr('src', data.features.icon); $("#icon").attr('src', data.features.icon);
let mode = data.program; let mode = data.program;
if (mode == 'custom') { if (mode == 'custom') {
@ -379,6 +432,51 @@ $("#options").on('click', '.editBtn', function () {
outputCheck(); outputCheck();
}) })
// 添加模拟按键
$("#options").on('click', '#addKey', function () {
var m1 = $('#modifier1').val();
var m2 = $('#modifier2').val();
var k = $('#presskey').val();
var code = 'utools.robot.keyTap';
if (/^(\S|f1[0-2]|f[1-9]|backspace|delete|enter|tab|escape|up|down|right|left|home|end|pageup|pagedown|command|alt|control|shift|right_shift|space|printscreen|insert')$/.test(k)) {
if (!m1 && !m2) {
code += `('${k}');\n`;
} else if(m1 && m2){
code += `('${k}', ['${m1}', '${m2}']);\n`
} else {
code += `('${k}', '${m1}${m2}');\n`
}
window.editor.replaceSelection(code);
} else {
Swal.fire({
text: '请输入正确的按键',
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: '帮助',
cancelButtonText: '确定',
}).then((result) => {
if (result.value) {
visit('https://robotjs.io/docs/syntax#keys');
}
})
}
})
// 添加延时
$("#options").on('click', '#addDelay', function () {
var t = $('#keydelay').val();
if (/\d+/.test(t)) {
window.editor.replaceSelection(`utools.robot.setKeyboardDelay(${t});\n`)
} else {
Swal.fire({
icon: 'warning',
text: '请输入正确的时间, 单位 ms',
})
}
})
// 导出 // 导出
$("#options").on('click', '.exportBtn', function () { $("#options").on('click', '.exportBtn', function () {
var code = $(this).attr('code'), var code = $(this).attr('code'),
@ -431,40 +529,42 @@ $("#options").on('click', '.saveBtn', function () {
// 合规性校验 // 合规性校验
if (type == 'key' if (type == 'key'
&& ['{{input}}', '{{SelectFile}}', '{{pwd}}', '{{WindowInfo}}'].map(x => cmd.includes(x)).includes(true)) { && ['{{input}}', '{{SelectFile}}', '{{pwd}}', '{{WindowInfo}}'].map(x => cmd.includes(x)).includes(true)) {
window.messageBox({ Swal.fire({
type: 'error', icon: 'error',
icon: window.logo, title: '啊嘞?!',
message: "关键字模式无法使用{{input}}、{{SelectFile}}、{{WindowInfo}}、{{pwd}}!", text: '关键字模式无法使用{{input}}、{{SelectFile}}、{{WindowInfo}}、{{pwd}}!',
buttons: ['朕知道了'] })
})
} else if (type == 'regex' } else if (type == 'regex'
&& ['{{SelectFile}}', '{{WindowInfo}}','{{pwd}}'].map(x => cmd.includes(x)).includes(true)) { && ['{{SelectFile}}', '{{WindowInfo}}', '{{pwd}}'].map(x => cmd.includes(x)).includes(true)) {
window.messageBox({ Swal.fire({
type: 'error', icon: 'error',
icon: window.logo, title: '啊嘞?!',
message: "正则模式无法使用{{SelectFile}}、{{WindowInfo}}、{{pwd}}!", text: '正则模式无法使用{{SelectFile}}、{{WindowInfo}}、{{pwd}}!',
buttons: ['朕知道了'] })
})
} else if (type == 'window' && cmd.includes('{{input}}')) { } else if (type == 'window' && cmd.includes('{{input}}')) {
window.messageBox({ Swal.fire({
type: 'error', icon: 'error',
icon: window.logo, title: '啊嘞?!',
message: "窗口模式无法使用{{input}}!", text: '窗口模式无法使用{{input}}!',
buttons: ['朕知道了'] })
})
} else if (['text', 'html'].includes($('#output').val()) && cmd.includes('{{SelectText}}')) { } else if (['text', 'html'].includes($('#output').val()) && cmd.includes('{{SelectText}}')) {
window.messageBox({ Swal.fire({
type: 'error', icon: 'error',
icon: window.logo, title: '啊嘞?!',
message: "显示文本或html输出时无法使用{{SelectText}}!", text: '显示文本或html输出时无法使用{{SelectText}}!',
buttons: ['朕知道了'] })
}) } else if (type == 'robotjs' && /\{\{.*?\}\}/.test(cmd)) {
} else { Swal.fire({
icon: 'error',
title: '啊嘞?!',
text: '模拟按键模式无法使用特殊变量!',
})
}else {
var program = $('#program').val(), var program = $('#program').val(),
desc = $('#desc').val(), desc = $('#desc').val(),
codec = $('#codec').val(),
iconame = $("#iconame").val(), iconame = $("#iconame").val(),
iconpath = $("#icon").attr('src'), iconpath = $("#icon").attr('src'),
robotjs = false,
icon, icon,
base64ico, base64ico,
hasSubInput; hasSubInput;
@ -477,11 +577,9 @@ $("#options").on('click', '.saveBtn', function () {
} else { } else {
icon = iconpath; icon = iconpath;
} }
var noKeyword;
var rule = $('#rule').val(); var rule = $('#rule').val();
if (type == 'key') { if (type == 'key') {
cmds = rule.split(',') cmds = rule.split(',')
noKeyword = false;
} }
if (type == 'regex') { if (type == 'regex') {
cmds = [{ cmds = [{
@ -490,17 +588,15 @@ $("#options").on('click', '.saveBtn', function () {
"match": rule, "match": rule,
"minNum": 1 "minNum": 1
}]; }];
noKeyword = true;
} }
if (type == 'window') { if (type == 'window' || type == 'robotjs') {
cmds = [{ cmds = [{
"label": desc, "label": desc,
"type": "window", "type": "window",
"match": { "match": {
"app": rule "app": rule
}, }
}]; }];
noKeyword = true;
} }
// 需要子输入框 // 需要子输入框
if (cmd.includes('{{subinput}}')) { if (cmd.includes('{{subinput}}')) {
@ -509,6 +605,11 @@ $("#options").on('click', '.saveBtn', function () {
hasSubInput = false; hasSubInput = false;
} }
$("#customize").animate({ top: '100%' }); $("#customize").animate({ top: '100%' });
if (type == "robotjs") {
program = "";
output = "";
robotjs = true;
}
// 添加特性 // 添加特性
pushData = { pushData = {
features: { features: {
@ -520,9 +621,8 @@ $("#options").on('click', '.saveBtn', function () {
program: program, program: program,
cmd: cmd, cmd: cmd,
output: output, output: output,
codec: codec, hasSubInput: hasSubInput,
noKeyword: noKeyword, robotjs: robotjs
hasSubInput: hasSubInput
} }
if (program == 'custom') { if (program == 'custom') {
pushData.customOptions = { pushData.customOptions = {
@ -551,13 +651,9 @@ $("#options").on('change', '#program', function () {
let mode = $(this).val(); let mode = $(this).val();
if (!hasCustomIcon()) $("#icon").attr('src', `logo/${mode}.png`); if (!hasCustomIcon()) $("#icon").attr('src', `logo/${mode}.png`);
if (mode == 'custom') { if (mode == 'custom') {
$('#custombin').show(); $('.customscript').show();
$('#customarg').show();
$('#customext').show();
} else { } else {
$('#custombin').hide(); $('.customscript').hide();
$('#customarg').hide();
$('#customext').hide();
} }
mode == 'applescript' && (mode = 'shell'); mode == 'applescript' && (mode = 'shell');
mode == 'cmd' && (mode = 'powershell'); mode == 'cmd' && (mode = 'powershell');