From bad5595204e1ca3681e2fd6c2dc23999141e9986 Mon Sep 17 00:00:00 2001 From: fofolee Date: Sun, 5 Jul 2020 10:58:19 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0quickcommand=E6=96=87?= =?UTF-8?q?=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/options.js | 44 ++--- src/helps/quickcommand.html | 320 ++++++++++++++++++++++++++++++++++++ src/helps/quickcommand.md | 306 ++++++++++++++++++++++++++++++++++ src/index.html | 10 +- 4 files changed, 655 insertions(+), 25 deletions(-) create mode 100644 src/helps/quickcommand.html create mode 100644 src/helps/quickcommand.md diff --git a/src/assets/options.js b/src/assets/options.js index d63a630..e357ad3 100644 --- a/src/assets/options.js +++ b/src/assets/options.js @@ -24,29 +24,29 @@ var options = file ? { type: 'file', argvs: file } : { type: 'dialog', argvs: { filters: [{ name: 'json', extensions: ['json'] }] } } options.readfile = true var fileinfo = getFileInfo(options) - if (!fileinfo) return + if (!fileinfo) return false try { var pushData = JSON.parse(fileinfo.data); } catch (error) { - Swal.fire({ icon: 'error', title: '啊嘞?!', text: '格式错误!', }) - return + quickcommand.showMessageBox("格式错误", "error") + return false } // 单个命令导入 if (typeof(pushData.features) == 'object') { var code = pushData.features.code; putDB(code, pushData, 'customFts'); - showOptions(); + return true // 多个命令导入 } else { if (typeof(Object.values(pushData)[0].features) == 'object') { for (var code of Object.keys(pushData)) { putDB(code, pushData[code], 'customFts'); } - showOptions(); - } else { - Swal.fire({ icon: 'error', title: '啊嘞?!', text: '格式错误!', }) + return true } } + quickcommand.showMessageBox("格式错误", "error") + return false } let exportAll = () => { @@ -329,13 +329,13 @@ - + ﹢动作 ﹢按键 - ?帮助 + ?文档 格式化

@@ -475,7 +475,7 @@ }) break; default: - message('暂不支持该语言的格式化') + quickcommand.showMessageBox('暂不支持该语言的格式化', 'error') break; } } @@ -583,7 +583,7 @@ break; case 'regex': blacklist = cmd.match(/{{SelectFile}}|{{WindowInfo}}|{{pwd}}|{{MatchedFiles}}/g) - if (/^(|\/)\.[*+](|\/)$/.test($('#rule').val())) return Swal.fire('正则匹配 .* 和 .+ 已被uTools禁用!') + if (/^(|\/)\.[*+](|\/)$/.test($('#rule').val())) return quickcommand.showMessageBox('正则匹配 .* 和 .+ 已被uTools禁用!', 'error') break; case 'window': blacklist = cmd.match(/{{input}}|{{MatchedFiles}}/g) @@ -595,7 +595,7 @@ break; } if (blacklist) { - Swal.fire(`当前模式无法使用${Array.from(new Set(blacklist)).join("、")}`) + quickcommand.showMessageBox(`当前模式无法使用${Array.from(new Set(blacklist)).join("、")}`, 'error') return false } else { return true @@ -619,7 +619,7 @@ case 'add': showCustomize(); $("#customize").animate({ top: '0px' }); break; - case 'import': importCommand(); + case 'import': importCommand() && showOptions(); break; case 'enableAll': $(".checked-switch:not(:checked)").click(); break; @@ -679,7 +679,7 @@ // 添加模拟按键 $("#options").on('click', '#addKey', function () { $("#addKey").text("▶ 录制中").addClass('record') - message('开始录制按键,可连续录制') + quickcommand.showMessageBox('开始录制按键,可连续录制', 'info') Mousetrap.record(sequence => { sequence.forEach(s => { var keys = s @@ -692,9 +692,7 @@ // quickCommand的帮助 $("#options").on('click', '#showHelp', function () { - $.get('./HELP.md', r => { - utools.ubrowser.goto(r).run() - }) + utools.createBrowserWindow('./helps/quickcommand.html') }) // 添加动作 @@ -799,7 +797,7 @@ rule = $('#rule').val(), cmd = window.editor.getValue(); if (tags && tags.includes("默认") && !fofoCommon.isDev()) return - if (type != "window" && !rule) return swal.fire(`${$('#ruleWord').text().replace(" ", "")} 不能留空!`) + if (type != "window" && !rule) return quickcommand.showMessageBox(`${$('#ruleWord').text().replace(" ", "")} 不能留空!`, 'error') if (!cmdCheck(type, cmd)) return if (!code) { // 生成唯一code @@ -1043,7 +1041,7 @@ - + 运 行 @@ -1052,7 +1050,7 @@ 格式化 ﹢动作 ﹢按键 - ?帮助 + ?文档 @@ -1152,12 +1150,16 @@ typeCheck(); }) + $("#options").on('change', '#customext', function () { + highlightIfKnown($('#customext').val()) + }) + // 平台按钮 $("#options").on('click', '.platform', function () { if ($(this).hasClass('disabled')){ $(this).removeClass('disabled') } else { - if ($('.disabled').length == 2) message('至少保留一个平台') + if ($('.disabled').length == 2) quickcommand.showMessageBox('至少保留一个平台', 'error') else $(this).addClass('disabled') } }) diff --git a/src/helps/quickcommand.html b/src/helps/quickcommand.html new file mode 100644 index 0000000..8d8461b --- /dev/null +++ b/src/helps/quickcommand.html @@ -0,0 +1,320 @@ + + + + +HELP + + +

quickcommand

showButtonBox(callback, buttons)

显示一个按钮对话框,用来接收用户的输入

示例

实例

showInputBox(callback, placeHolders)

显示一个输入框界面,用来接用户的输入

示例

实例

showSelectList(callback, selects, options)

显示一个支持搜索的选项列表,类似于列表模式,但原理不同

示例

实例

showTextAera(callback, placeholder)

显示一个文本框界面,用来接用户的输入

示例

实例

showMessageBox(message, icon, time)

显示一个自动消失的提示框

示例

sleep(ms)

由于setTimeout在electron中存在限制,在隐藏到后台时不会被执行,在vm2中也有bug,所以在quickcommand的环境下被禁用了,但对于模拟按键之类的场景,延迟是不可缺少的,所以提供了sleep函数来解决这个问题

示例

setTimeout(callback, ms)

用法和setTimeout一样,但实现原理不一样,sleep的异步版本

示例

htmlParse(html)

将给定的html字符串解析为DOM对象,用于快速编写爬虫脚本

示例

downloadFile(url, defaultPath, showDialog)

下载文件,也可单纯用于http请求,无论defaultPath是否定义,都将得到响应内容的Buffer,当showDialogfalse且定义了defaultPath时,会下载文件为`defaultPath,当showDialogtrue时,会弹出保存文件对话框,defaultPath为对话框默认显示的文件名

payload

当匹配模式为关键字时,返回进入插件的关键字;为正则时,返回匹配的文本;为窗口时,返回匹配的窗口信息;为文件时,返回匹配的文件信息

示例

kill(pid, signal)

signal 发送给 pid 标识的进程 , 默认为关闭进程,同process.kill

示例

simulateCopy()

模拟复制操作

simulatePaste()

模拟粘贴操作

上下文一览

 

+ + \ No newline at end of file diff --git a/src/helps/quickcommand.md b/src/helps/quickcommand.md new file mode 100644 index 0000000..e5b018b --- /dev/null +++ b/src/helps/quickcommand.md @@ -0,0 +1,306 @@ +[TOC] + +## quickcommand + +#### `showButtonBox(callback, buttons)` + +- callback: Function 回调函数 + - index: Integer 按钮的序号,从0开始 + - text: String 按钮的文本 +- buttons: Array 每一个元素对应一个按钮 + +显示一个按钮对话框,用来接收用户的输入 + +**示例** + +```js +quickcommand.showButtonBox(({index, text})=>{ + console.log(`选择了第${index+1}个按钮`) + console.log(`按钮的文本为${text}`) +},["按钮1", "按钮2", "按钮3"]) +``` +**实例** + +```js +# 截取自内置快捷命令: 文本处理 +quickcommand.showButtonBox(option => { + var i = option.index + console.log(textManipulation[i](text)) + message('结果已复制到剪贴板') +}, ["字数统计", "词频统计", "文本逆转", "\\和/互转", "全部大写", "全部小写", + "去除空格", "十六进制转字符", "字符转十六进制" +]) +textManipulation = [ ... ] +``` + +####`showInputBox(callback, placeHolders)` + +- callback: Function 回调函数 + - values: Array 所以输入框的值 +- placeHolders: Array 每一个占位符对应一个输入框 + +显示一个输入框界面,用来接用户的输入 + +**示例** + +```js +quickcommand.showInputBox(values => { + console.log(`输入的内容分别为${values}`) +},["输入框1", "输入框2", "输入框3"]) +``` +**实例** + +```js +# 截取自内置快捷命令: 文本替换 +quickcommand.showInputBox(inputs => { + var search = inputs[0] + var repl = inputs[1] + ... + utools.hideMainWindow() + quickcommand.sleep(300) + quickcommand.simulateCopy() + quickcommand.sleep(100) + var source = electron.clipboard.readText() + source = source.replace(search, repl) + ... +}, ["要替换的内容,两边加 / 使用正则", "替换为的内容"]) +``` +####`showSelectList(callback, selects, options)` + +- callback: Function 回调函数 + - index: Integer 选择的序号,从0开始 + - text: String 选择的文本 +- selects: Array 每一个元素对应一个列表选项 +- options: Array | undefined 列表的选项 + - placeholder: String 搜索框占位符 + - enableHTML: Boolean 选项是否支持html,默认为false + - closeOnSelect:Boolean 选择后是否关闭列表,默认为true + +显示一个支持搜索的选项列表,类似于列表模式,但原理不同 + +**示例** + +```js +var opt = [] +for (var i = 0; i < 15; i++) { + opt.push(`选项` + i) +} +quickcommand.showSelectList(choise => { + console.log(`选择的选项为${choise.text}`) +}, opt) +``` +**实例** + +```js +# 截取自内置快捷命令: 离线插件 +const api = 'https://api.u-tools.cn/Plugins/Developer/allPlugins' + axios(api).then(res => { + var document = quickcommand.htmlParse(res.data) + var doms = document.querySelectorAll('div[style]') + var divs = [] + doms.forEach(d => { + d.querySelector('a').style.display = 'none' + d.querySelector('h3+div').style.color = '#9e9e9e' + d.querySelector('h3').style = "margin: 0; font-weight: normal" + divs.push(d.innerHTML) + }) + quickcommand.showSelectList(x => { + var dom = quickcommand.htmlParse(x.text) + var href = dom.querySelector('a').href + var file = dom.querySelector('h3').innerText + '.upx' + var filepath = path.join(utools.getPath('downloads'), file) + quickcommand.downloadFile(href, filepath).then(() => { + utools.shellShowItemInFolder(filepath) + }) + }, divs, { enableHTML: true, closeOnSelect: false }) + }) +``` + +####`showTextAera(callback, placeholder)` + +- callback: Function 回调函数 + - text: String 文本框的文本 +- placeholder: String | undefined 文本框占位符 + +显示一个文本框界面,用来接用户的输入 + +**示例** + +```js +quickcommand.showTextAera(text=>{ + console.log(`输入的文本为${text}`) +}, "请输入文本") +``` + + **实例** + +```js +# 截取自内置快捷命令: vscode代码片段生成器 +var snippet = {} +quickcommand.showTextAera(code => { + snippet.body = code.split("\n") + quickcommand.showInputBox(inputs => { + snippet.prefix = inputs[1] + snippet.description = inputs[0] + var result = `"${inputs[0]}": ` + JSON.stringify(snippet, null, '\t') + console.log(result) + utools.copyText(result) + quickcommand.showMessageBox('已复制') + }, ["代码片段的描述", "触发代码片段的关键词"]) +}, ("请输入代码片段")) +``` +####`showMessageBox(message, icon, time)` + +- message: String 显示的消息内容 +- icon: String | undefined 图标,可为`success`、`error`、`warning`、`info`、`question`,默认为`success` +- time: Integer | undefined 多少毫秒后消失,默认为`3000` + +显示一个自动消失的提示框 + + **示例** + +```js +quickcommand.showMessageBox("这是一段3s后自动消失的成功提示") +quickcommand.showMessageBox("这是一段3s后自动消失的失败提示", "error") +``` + +####`sleep(ms)` + +- ms: Integer 等待的毫秒 + +由于`setTimeout`在electron中存在限制,在隐藏到后台时不会被执行,在vm2中也有bug,所以在quickcommand的环境下被禁用了,但对于模拟按键之类的场景,延迟是不可缺少的,所以提供了`sleep`函数来解决这个问题 + + **示例** + +```js +utools.simulateKeyboardTap('d', 'alt') +quickcommand.sleep(200) +utools.simulateKeyboardTap('c', 'ctrl') +``` + +####`setTimeout(callback, ms)` + +- callback: Function 回调函数 +- ms: Integer 延时的毫秒 + +用法和`setTimeout`一样,但实现原理不一样,`sleep`的异步版本 + + **示例** + +```js +quickcommand.setTimeout(()=>{ + console.log('2000毫秒后执行') +}, 2000) +``` +####`htmlParse(html)` +- html: String 需要解析的`html`文本 +- 返回: Object `DOM`对象 + +将给定的`html`字符串解析为`DOM`对象,用于快速编写爬虫脚本 + + **示例** + +```js +var html = `uTools` +var href = quickcommand.htmlParse(html).querySelector('a').href +console.log(`解析出来的a标签地址为${href}`) +``` + +#### `downloadFile(url, defaultPath, showDialog)` + +- url: String 地址 +- defaultPath: String | undefined 当`showDialog`为`false`时,表示下载文件的绝对路径,当`showDialog`为`true`时,表示对话框默认显示的文件名 +- showDialog: Boolean | undefined 是否弹出对话框 ,默认为`false` +- 返回: Promise + - content: Buffer 网络响应内容的`Buffer ` + +下载文件,也可单纯用于`http`请求,无论`defaultPath`是否定义,都将得到响应内容的`Buffer`,当`showDialog`为`false`且定义了`defaultPath`时,会下载文件为``defaultPath`,当`showDialog`为`true`时,会弹出保存文件对话框,`defaultPath`为对话框默认显示的文件名 + +```js +# 返回http响应内容 +quickcommand.downloadFile('https://www.baidu.com').then(r=>{ + console.log(r.toString()) +}) + +# 下载文件到D:/ +quickcommand.downloadFile('https://res.u-tools.cn/currentversion/uTools-1.1.3.exe', 'D:/') + +# 下载文件,并弹出对话框询问保存路径 +quickcommand.downloadFile('https://res.u-tools.cn/currentversion/uTools-1.1.3.exe', 'uTools.exe', true) +``` + +#### `payload` + +- String 对应`utools.onPluginEnter`的 `payload` + +当匹配模式为`关键字`时,返回进入插件的关键字;为`正则`时,返回匹配的文本;为`窗口`时,返回匹配的窗口信息;为`文件`时,返回匹配的文件信息 + + **示例** + +```js +# 匹配模式为正则/划词时 +var text = quickcommand.payload +console.log(`主输入框匹配的文本为${text}`) +``` + +#### `kill(pid, signal)` + +- pid: Integer 进程 ID +- signal: String | Integer | undefined 将发送的信号,默认为 `'SIGTERM'` + + 将 `signal` 发送给 `pid` 标识的进程 , 默认为关闭进程,同`process.kill` + + **示例** + +```js +quickcommand.kill(16084) +``` + +#### `simulateCopy()` + +模拟复制操作 + +#### `simulatePaste()` + +模拟粘贴操作 + +## 上下文一览 + +- nodejs [文档]( http://nodejs.cn/api/ ) + - require + - os + - fs + - path + - child_process + - util + - axios [文档]( https://github.com/axios/axios ) +- electron [文档]( http://www.electronjs.org/docs ) + - clipboard + - contextBridge + - crashReporter + - desktopCapturer + - ipcRenderer + - nativeImage + - shell + - webFrame +- utools [文档]( https://u.tools/docs/developer/api.html ) + - all except below + - ~~db~~ + - ~~removeFeature~~ + - ~~setFeature~~ +- quickcommand + - sleep: *ƒ (ms)* + - setTimeout: *ƒ (callback, ms)* + - showButtonBox: *ƒ (callback, buttons)* + - showInputBox: *ƒ (callback, placeHolders)* + - showMessageBox: *ƒ (title, icon = "success", time = 3000)* + - showSelectList: *ƒ (callback, selects, opt = {})* + - showTextAera: *ƒ (callback, placeholder = "")* + - simulateCopy: *ƒ ()* + - simulatePaste: *ƒ ()* + - downloadFile: *ƒ (url, defaultPath = '', showDialog = false)* + - htmlParse: *ƒ (html)* + - kill: *ƒ (pid)* + - payload + + diff --git a/src/index.html b/src/index.html index ee137e6..da827d1 100755 --- a/src/index.html +++ b/src/index.html @@ -18,10 +18,12 @@ -
-

-    
-    
+    
+
+

+        
+        
+    
\ No newline at end of file