This commit is contained in:
fofolee
2019-05-03 09:20:31 +08:00
parent a07dd6f344
commit 821413e775
9 changed files with 1074 additions and 1068 deletions

BIN
assets/.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -22,6 +22,8 @@ checkUpdate = () => {
utools.db.put({ _id: p.version, data: "pass" })
}
})
} else {
console.log('当前已是最新版本!');
}
})
}

File diff suppressed because one or more lines are too long

View File

@@ -1,402 +1,402 @@
#out {
padding: 0px 10px;
font-size: 13px;
line-height: 26px;
font-family: Monaco, consolas;
white-space: pre-wrap;
}
#options {
font-size: 15px;
color: #595959;
font-family: consolas, monaco, "微软雅黑";
padding-bottom: 30px;
}
#options * {
box-sizing: border-box;
}
#options .switch-btn {
position: relative;
display: inline-block;
vertical-align: top;
width: 80px;
height: 30px;
border-radius: 5px;
cursor: pointer;
zoom: 0.7;
}
#options .checked-switch {
position: absolute;
top: 0;
left: 0;
opacity: 0;
}
#options .text-switch {
background-color: #cccccc;
border: 1px solid #dddddd;
border-radius: inherit;
color: #fff;
display: block;
font-size: 15px;
width: 60px;
height: inherit;
position: relative;
text-transform: uppercase;
}
#options .text-switch:before,
#options .text-switch:after {
position: absolute;
top: 50%;
margin-top: -.5em;
line-height: 1;
-webkit-transition: inherit;
-moz-transition: inherit;
-o-transition: inherit;
transition: inherit;
}
#options .text-switch:before {
content: 'OF';
right: 6px;
}
#options .text-switch:after {
content: 'ON';
left: 6px;
color: #FFFFFF;
opacity: 0;
}
#options .checked-switch:checked~.text-switch {
background-color: #00af2c;
border: 1px solid #068506;
}
#options .checked-switch:disabled~.text-switch {
cursor: no-drop;
}
#options .checked-switch:disabled~.text-switch~.toggle-btn {
cursor: no-drop;
}
#options .checked-switch:disabled~.text-switch:before {
content: '▬';
right: 11px;
}
#options .checked-switch:checked~.text-switch:before {
opacity: 0;
}
#options .checked-switch:checked~.text-switch:after {
opacity: 1;
}
#options .toggle-btn {
background: linear-gradient(#eee, #fafafa);
border-radius: 5px;
height: 28px;
left: 1px;
position: absolute;
top: 1px;
width: 28px;
}
#options .checked-switch:checked~.toggle-btn {
left: 30px;
}
#options .text-switch,
#options .toggle-btn {
transition: All 0.3s ease;
-webkit-transition: All 0.3s ease;
-moz-transition: All 0.3s ease;
-o-transition: All 0.3s ease;
}
#options .no-radius,
#options .no-radius .toggle-btn {
border-radius: 0;
}
#options .circle-style .toggle-btn::before {
background: linear-gradient(#dedede, #cacaca);
border-radius: 50%;
content: "";
height: 14px;
margin-top: 6px;
padding: 0;
width: 14px;
}
#options table {
border-collapse: collapse;
width: 100%;
}
#options table td {
border-collapse: collapse;
padding: 3px;
word-break: break-all;
}
#options table tr:nth-child(odd) {
background-color: #fff !important;
}
#options table tr:nth-child(even) {
background-color: #f8f8f8 !important;
}
#options .keyword {
display: inline-block;
font-size: 14px;
color: #333;
border: 1px solid #eee;
border-radius: 12px;
height: 24px;
line-height: 22px;
padding: 0 10px;
background-color: #f3f3f3;
margin-right: 5px
}
#options .logo {
width: 32px;
}
#options .footBtn {
float: right;
/* right: 5px;
bottom: 2px; */
border-radius: 4px;
background: #00af2c;
color: white;
padding: 2px 5px;
margin: 0px 5px;
cursor: pointer;
}
#options .footBtn:hover {
background: #068506;
transition: 0.5s;
}
#options .foot {
position: fixed;
height: 30px;
right: 0px;
bottom: 0px;
left: 0px;
background: #f3f3f3;
box-shadow: 0px 0px 9px 0px #00000030;
padding: 3px;
}
#options td span {
margin-right: 10px;
}
#options span.editBtn {
font-size: 16px;
cursor: pointer;
color: #00af2c;
}
#options span.delBtn {
font-size: 16px;
cursor: pointer;
color: #ed5b49
}
#options span.editBtn:hover {
color: #057205;
}
#options span.delBtn:hover {
color: #bd3523;
}
#options #customize {
position: fixed;
height: 100%;
top: 100%;
left: 0;
right: 0;
padding: 0px 30px;
box-shadow: 0px 0px 9px 0px #00000030;
color: black;
background: white;
}
#options #customize p {
line-height: 1.25rem;
}
#options #customize .word {
color: #2196F3;
display: inline-block;
font-size: 14px;
border: 1px solid #1E88E5;
height: 24px;
line-height: 22px;
padding: 0 5px;
background-color: #E3F2FD;
}
#options #customize input {
width: 90%;
height: 25px;
border-bottom: 1px solid #dbdbdb;
border-top: 0px;
border-left: 0px;
border-right: 0px;
font-size: 15px;
margin-left: 15px
}
#options #customize input:hover {
border-bottom-color: #9e9e9ec7;
transition: 0.25s;
}
#options #customize input:focus {
outline: none;
border-bottom-color: #0277BD;
transition: 0.5s;
}
input::-webkit-input-placeholder {
color: #999;
font-size: 15px
}
#options #customize .CodeMirror {
font-size: 13px;
font-family: "Monaco", "consolas";
width: 100%;
height: 23rem;
border: 1px solid #dbdbdb;
border-radius: 3px;
}
#options #customize .CodeMirror:hover {
border: 1px solid #9e9e9ec7;
transition: 0.25s;
}
#options #customize .CodeMirror-focused {
border: 1px solid #0277BD !important;
box-shadow: 0px 0px 2px 0px #0277BD;
transition: 0.25s;
}
#options #customize .CodeMirror-placeholder {
color: #999;
font-size: 15px
}
#options #customize select {
width: 40%;
height: 25px;
margin-left: 5px;
border-bottom: 1px solid #dbdbdb;
border-top: 0px;
border-left: 0px;
border-right: 0px;
background-color: #ffffff;
border-radius: 0px;
outline: none;
font-size: 15px;
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAJAgMAAAB71iXHAAAADFBMVEUAAAAqPz8rN0csOEgGlpD7AAAAA3RSTlMABvwYJ91vAAAAGklEQVQI12OAgQNAaMDMwMAjw8DAVAAWgAEAPFADDsXseo4AAAAASUVORK5CYII=") no-repeat scroll right center transparent;
-webkit-appearance: button
}
#options #customize select:hover {
border-bottom-color: #9e9e9ec7;
transition: 0.25s;
}
#options #customize select:focus {
border-bottom-color: #0277BD;
transition: 0.5s;
}
#options #customize select#vars {
color: #999;
}
#options #customize select option {
color: black;
}
#options #customize input#iconame {
width: 35%;
cursor: pointer;
}
#options #customize #icon {
float: right;
width: 28px;
cursor: pointer;
}
#options #customize .selectBtn {
padding: 4px 10px;
font-size: 11px;
color: #1E88C7;
background: #D0EEFF;
border: 1px solid #99D3F5;
border-radius: 4px;
cursor: pointer;
}
#options #customize .selectBtn:hover {
background: #AADFFD;
border-color: #78C3F3;
color: #004974;
transition: 0.5s;
}
#options #customize button {
width: 150px;
height: 30px;
border-width: 0px;
border-radius: 3px;
cursor: pointer;
outline: none;
color: white;
}
#options #customize button.cancelBtn {
float: right;
margin-right: 30px;
background: #808080c9;
}
#options #customize button.saveBtn {
float: right;
background: #1E90FF;
}
#options #customize button.saveBtn:hover {
background: #5599FF;
transition: 0.5s;
}
#options #customize button.cancelBtn:hover {
background: #a5a2a2c9;
transition: 0.5s;
}
::-webkit-scrollbar {
height: 0;
#out {
padding: 0px 10px;
font-size: 13px;
line-height: 26px;
font-family: Monaco, consolas;
white-space: pre-wrap;
}
#options {
font-size: 15px;
color: #595959;
font-family: consolas, monaco, "微软雅黑";
padding-bottom: 30px;
}
#options * {
box-sizing: border-box;
}
#options .switch-btn {
position: relative;
display: inline-block;
vertical-align: top;
width: 80px;
height: 30px;
border-radius: 5px;
cursor: pointer;
zoom: 0.7;
}
#options .checked-switch {
position: absolute;
top: 0;
left: 0;
opacity: 0;
}
#options .text-switch {
background-color: #cccccc;
border: 1px solid #dddddd;
border-radius: inherit;
color: #fff;
display: block;
font-size: 15px;
width: 60px;
height: inherit;
position: relative;
text-transform: uppercase;
}
#options .text-switch:before,
#options .text-switch:after {
position: absolute;
top: 50%;
margin-top: -.5em;
line-height: 1;
-webkit-transition: inherit;
-moz-transition: inherit;
-o-transition: inherit;
transition: inherit;
}
#options .text-switch:before {
content: 'OF';
right: 6px;
}
#options .text-switch:after {
content: 'ON';
left: 6px;
color: #FFFFFF;
opacity: 0;
}
#options .checked-switch:checked~.text-switch {
background-color: #00af2c;
border: 1px solid #068506;
}
#options .checked-switch:disabled~.text-switch {
cursor: no-drop;
}
#options .checked-switch:disabled~.text-switch~.toggle-btn {
cursor: no-drop;
}
#options .checked-switch:disabled~.text-switch:before {
content: '▬';
right: 11px;
}
#options .checked-switch:checked~.text-switch:before {
opacity: 0;
}
#options .checked-switch:checked~.text-switch:after {
opacity: 1;
}
#options .toggle-btn {
background: linear-gradient(#eee, #fafafa);
border-radius: 5px;
height: 28px;
left: 1px;
position: absolute;
top: 1px;
width: 28px;
}
#options .checked-switch:checked~.toggle-btn {
left: 30px;
}
#options .text-switch,
#options .toggle-btn {
transition: All 0.3s ease;
-webkit-transition: All 0.3s ease;
-moz-transition: All 0.3s ease;
-o-transition: All 0.3s ease;
}
#options .no-radius,
#options .no-radius .toggle-btn {
border-radius: 0;
}
#options .circle-style .toggle-btn::before {
background: linear-gradient(#dedede, #cacaca);
border-radius: 50%;
content: "";
height: 14px;
margin-top: 6px;
padding: 0;
width: 14px;
}
#options table {
border-collapse: collapse;
width: 100%;
}
#options table td {
border-collapse: collapse;
padding: 3px;
word-break: break-all;
}
#options table tr:nth-child(odd) {
background-color: #fff !important;
}
#options table tr:nth-child(even) {
background-color: #f8f8f8 !important;
}
#options .keyword {
display: inline-block;
font-size: 14px;
color: #333;
border: 1px solid #eee;
border-radius: 12px;
height: 24px;
line-height: 22px;
padding: 0 10px;
background-color: #f3f3f3;
margin-right: 5px
}
#options .logo {
width: 32px;
}
#options .footBtn {
float: right;
/* right: 5px;
bottom: 2px; */
border-radius: 4px;
background: #00af2c;
color: white;
padding: 2px 5px;
margin: 0px 5px;
cursor: pointer;
}
#options .footBtn:hover {
background: #068506;
transition: 0.5s;
}
#options .foot {
position: fixed;
height: 30px;
right: 0px;
bottom: 0px;
left: 0px;
background: #f3f3f3;
box-shadow: 0px 0px 9px 0px #00000030;
padding: 3px;
}
#options td span {
margin-right: 10px;
}
#options span.editBtn {
font-size: 16px;
cursor: pointer;
color: #00af2c;
}
#options span.delBtn {
font-size: 16px;
cursor: pointer;
color: #ed5b49
}
#options span.editBtn:hover {
color: #057205;
}
#options span.delBtn:hover {
color: #bd3523;
}
#options #customize {
position: fixed;
height: 100%;
top: 100%;
left: 0;
right: 0;
padding: 0px 30px;
box-shadow: 0px 0px 9px 0px #00000030;
color: black;
background: white;
}
#options #customize p {
line-height: 1.25rem;
}
#options #customize .word {
color: #2196F3;
display: inline-block;
font-size: 14px;
border: 1px solid #1E88E5;
height: 24px;
line-height: 22px;
padding: 0 5px;
background-color: #E3F2FD;
}
#options #customize input {
width: 90%;
height: 25px;
border-bottom: 1px solid #dbdbdb;
border-top: 0px;
border-left: 0px;
border-right: 0px;
font-size: 15px;
margin-left: 15px
}
#options #customize input:hover {
border-bottom-color: #9e9e9ec7;
transition: 0.25s;
}
#options #customize input:focus {
outline: none;
border-bottom-color: #0277BD;
transition: 0.5s;
}
input::-webkit-input-placeholder {
color: #999;
font-size: 15px
}
#options #customize .CodeMirror {
font-size: 13px;
font-family: "Monaco", "consolas";
width: 100%;
height: 23rem;
border: 1px solid #dbdbdb;
border-radius: 3px;
}
#options #customize .CodeMirror:hover {
border: 1px solid #9e9e9ec7;
transition: 0.25s;
}
#options #customize .CodeMirror-focused {
border: 1px solid #0277BD !important;
box-shadow: 0px 0px 2px 0px #0277BD;
transition: 0.25s;
}
#options #customize .CodeMirror-placeholder {
color: #999;
font-size: 15px
}
#options #customize select {
width: 40%;
height: 25px;
margin-left: 5px;
border-bottom: 1px solid #dbdbdb;
border-top: 0px;
border-left: 0px;
border-right: 0px;
background-color: #ffffff;
border-radius: 0px;
outline: none;
font-size: 15px;
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAJAgMAAAB71iXHAAAADFBMVEUAAAAqPz8rN0csOEgGlpD7AAAAA3RSTlMABvwYJ91vAAAAGklEQVQI12OAgQNAaMDMwMAjw8DAVAAWgAEAPFADDsXseo4AAAAASUVORK5CYII=") no-repeat scroll right center transparent;
-webkit-appearance: button
}
#options #customize select:hover {
border-bottom-color: #9e9e9ec7;
transition: 0.25s;
}
#options #customize select:focus {
border-bottom-color: #0277BD;
transition: 0.5s;
}
#options #customize select#vars {
color: #999;
}
#options #customize select option {
color: black;
}
#options #customize input#iconame {
width: 35%;
cursor: pointer;
}
#options #customize #icon {
float: right;
width: 28px;
cursor: pointer;
}
#options #customize .selectBtn {
padding: 4px 10px;
font-size: 11px;
color: #1E88C7;
background: #D0EEFF;
border: 1px solid #99D3F5;
border-radius: 4px;
cursor: pointer;
}
#options #customize .selectBtn:hover {
background: #AADFFD;
border-color: #78C3F3;
color: #004974;
transition: 0.5s;
}
#options #customize button {
width: 150px;
height: 30px;
border-width: 0px;
border-radius: 3px;
cursor: pointer;
outline: none;
color: white;
}
#options #customize button.cancelBtn {
float: right;
margin-right: 30px;
background: #808080c9;
}
#options #customize button.saveBtn {
float: right;
background: #1E90FF;
}
#options #customize button.saveBtn:hover {
background: #5599FF;
transition: 0.5s;
}
#options #customize button.cancelBtn:hover {
background: #a5a2a2c9;
transition: 0.5s;
}
::-webkit-scrollbar {
height: 0;
}

View File

@@ -1,326 +1,326 @@
getCustomFts = () => {
var db = utools.db.get("customFts"),
customFts = db ? db.data : {};
return customFts;
}
programs = {
shell: {
bin: 'bash',
argv: '',
ext: 'sh'
},
applescript: {
bin: 'osascript',
argv: '',
ext: 'scpt'
},
cmd: {
bin: '',
agrv: '',
ext: 'bat'
},
powershell: {
bin: 'powershell',
agrv: '-NoProfile -File',
ext: 'ps1'
},
python: {
bin: 'python',
agrv: '-u',
ext: 'py'
},
javascript: {
bin: 'node',
agrv: '',
ext: 'js'
},
ruby: {
bin: 'ruby',
agrv: '',
ext: 'rb'
},
php: {
bin: 'php',
agrv: '',
ext: 'php'
},
lua: {
bin: 'lua',
agrv: '',
ext: 'lua'
},
perl: {
bin: 'perl',
agrv: '',
ext: 'pl'
}
}
showOptions = () => {
var currentFts = utools.getFeatures(),
customFts = getCustomFts();
let featureList = '<table><tr><td></td><td>关键字</td><td>说明</td><td>启用</td></tr>';
for (var fts in customFts) {
let features = customFts[fts].features;
var cmds = '';
if (customFts[fts].noKeyword) {
cmds = '<span class="keyword">匹配主输入框文本进入</span>';
} else {
features.cmds.forEach(cmd => {
cmds += `<span class="keyword">${cmd}</span>`;
});
}
var isChecked = '';
for(var c of currentFts){
if (c.code == features.code) {
isChecked = 'checked';
break;
}
}
var iconpath = pjoin(dirname, features.icon),
base64Ico = customFts[fts].base64Ico;
if (!exists(iconpath) && base64Ico) saveBase64Ico(iconpath, base64Ico);
featureList += `<tr><td><img class="logo" src="${iconpath}"></td>
<td>${cmds}</td><td width="300px">${features.explain}</td><td>
<label class="switch-btn">
<input class="checked-switch" id="${features.code}" type="checkbox" ${isChecked}>
<span class="text-switch"></span>
<span class="toggle-btn"></span>
</label>
<span class="editBtn" code="${features.code}">✎</span>
<span class="delBtn" code="${features.code}">✘</span>
</td>`
};
featureList += `</tr></table><div class="foot">
<div id="add" class="footBtn">添加命令</div>
<div id="disableAll" class="footBtn">全部禁用</div>
<div id="enableAll" class="footBtn">全部启用</div>
</div>`
$("#options").html(featureList);
}
showCustomize = () => {
$("#customize").remove();
let options = `<option>${Object.keys(programs).join('</option><option>')}</option>`
customWindow = `<div id="customize">
<p><span class="word">关键字</span><input type="text" id="kw" placeholder="多个关键字用逗号隔开"></p>
<p><span class="word">说&#12288;明</span><input type="text" id="desc" placeholder="命令功能的描述"></p>
<p>
<span class="word">类&#12288;型</span>
<select id="program">
${options}
</select>
<span class="word">图&#12288;标</span><input type="text" readonly id="iconame" placeholder="更改图标">
<img id="icon" src="">
</p>
<p>
<span class="word">变&#12288;量</span>
<select id="vars">
<option value="" style="display:none">插入特殊变量</option>
<option value="{{isWin}}">是否Window系统</option>
<option value="{{input}}">主输入框的文本</option>
<option value="{{pwd}}">文件管理器当前目录</option>
<option value="{{ChromeUrl}}">Chrome当前链接</option>
<option value="{{ClipText}}">剪切板的文本</option>
<option value="{{SelectText}}">选中的文本</option>
<option value="{{SelectFile}}">选中的文件</option>
</select>
<span class="word">输&#12288;出</span>
<select id="output">
<option value="ignore">忽略输出</option>
<option value="text">显示纯文本输出</option>
<option value="html">显示html格式的输出</option>
<option value="clip">复制到剪贴板</option>
<option value="send">发送到活动窗口</option>
</select>
</p>
<p>
<span class="word">脚&#12288;本</span>
<select id="codec">
<option value="gbk">GBK 编码</option>
<option value="utf8">UTF8 编码</option>
</select>
</p>
<p><textarea id="cmd" placeholder="可以直接拖放脚本文件至此处"></textarea></p>
<p>
<button class="saveBtn">保存</button>
<button class="cancelBtn">取消</button>
</p>`
$("#options").append(customWindow)
if (window.isWin) {
var shell = 'cmd',
mode = 'powershell';
} else {
var shell = 'shell',
mode = 'shell';
$("#codec").hide();
}
$("#program").val(shell);
$("#icon").attr('src', `logo/${shell}.png`);
window.editor = CodeMirror.fromTextArea(document.getElementById("cmd"), {
lineNumbers: true,
lineWrapping: true
});
window.editor.setOption("mode", mode);
$("#customize").animate({ top: '0px' });
}
// 开关
$("#options").on('change', 'input[type=checkbox]', function () {
var customFts = getCustomFts(),
code = $(this).attr('id');
if (!utools.removeFeature(code)) {
utools.setFeature(customFts[code].features);
}
});
// 底部功能按钮
$("#options").on('click', '.footBtn', function () {
switch ($(this).attr('id')) {
case 'add': showCustomize();
break;
case 'enableAll': $(".checked-switch:not(:checked)").click();
break;
case 'disableAll': $(".checked-switch:checked").click();
break;
}
})
// 取消
$("#options").on('click', '.cancelBtn', function () {
$("#customize").animate({ top: '100%'});
})
// 编辑
$("#options").on('click', '.editBtn', function () {
var code = $(this).attr('code');
var data = utools.db.get("customFts").data[code];
showCustomize();
// 判断是通过关键词进入还是主输入框进入
if (data.noKeyword) {
$('#kw').val(data.features.code);
$('#kw').prop('disabled', true);
} else {
$('#kw').val(data.features.cmds.toString());
}
$('#kw').attr('edit', true);
$('#program').val(data.program);
$('#output').val(data.output);
$('#desc').val(data.features.explain);
$('#codec').val(data.codec);
$("#icon").attr('src', data.features.icon);
let mode = data.program;
let iconame = basename(data.features.icon);
if (iconame != `${mode}.png`) $('#iconame').val(iconame);
mode == 'applescript' && (mode = 'shell');
mode == 'cmd' && (mode = 'powershell');
window.editor.setOption("mode", mode);
window.editor.setValue(data.cmd);
})
// 删除
$("#options").on('click', '.delBtn', function () {
var code = $(this).attr('code'),
db = utools.db.get("customFts"),
data = db.data;
delete data[code];
utools.removeFeature(code);
utools.db.put({ _id: "customFts", data: data, _rev: db._rev });
showOptions();
})
// 选择图标
$("#options").on('click', '#icon, #iconame', function () {
let iconpath = window.openFolder()[0];
$("#iconame").val(basename(iconpath));
$("#icon").attr('src', iconpath);
})
// 保存
$("#options").on('click', '.saveBtn', function () {
var code = $('#kw').val().split(',')[0].trim()
var customFts = getCustomFts();
// 如果 code 重复, 编辑状态下不检测
if (code in customFts && !$('#kw').attr('edit')) {
$('#kw').css({ 'border-bottom-color': '#ec1212' })
window.messageBox({ type: 'error', icon: window.logo, message: "命令名称与现有的重复!", buttons: ['朕知道了'] })
} else {
var kw = $('#kw').val().split(','),
program = $('#program').val(),
desc = $('#desc').val(),
output = $('#output').val(),
codec = $('#codec').val(),
iconame = $("#iconame").val(),
iconpath = $("#icon").attr('src'),
cmd = window.editor.getValue(),
icon,
base64ico;
// 自定义了图标的情况下
if (iconame) {
icon = window.getIconPath(iconame);
if (iconpath == icon) {
base64ico = window.getBase64Ico(pjoin(dirname, iconpath));
} else {
base64ico = window.getBase64Ico(iconpath);
}
// 未自定义使用默认
} else {
icon = iconpath;
base64ico = '';
}
// 通过主输入框直接进入
if (cmd.includes('{{input}}')) {
kw = [{
"label": desc,
"type": "over",
"minNum": 1
}];
noKeyword = true;
} else {
noKeyword = false;
}
$("#customize").animate({ top: '100%' });
var pushData = {};
// 添加特性
pushData[code] = {
features: {
"code": code,
"explain": desc,
"cmds": kw,
"icon": icon
},
program: program,
cmd: cmd,
output: output,
codec: codec,
base64Ico: base64ico,
noKeyword: noKeyword
}
var db = utools.db.get("customFts");
if (db) {
var rev = db._rev
var data = db.data
data[code] = pushData[code];
utools.db.put({ _id: "customFts", data: data, _rev: rev });
} else {
utools.db.put({ _id: "customFts", data: pushData });
}
showOptions();
}
})
// 语言选项改变时
$("#options").on('change', '#program', function () {
let mode = $(this).val();
if (!$("#iconame").val()) $("#icon").attr('src', `logo/${mode}.png`);
mode == 'applescript' && (mode = 'shell');
mode == 'cmd' && (mode = 'powershell');
window.editor.setOption("mode", mode);
})
// 变量选项改变时
$("#options").on('change', '#vars', function () {
$("#vars").css({'color':'black'})
window.editor.replaceSelection($("#vars").val());
})
getCustomFts = () => {
var db = utools.db.get("customFts"),
customFts = db ? db.data : {};
return customFts;
}
programs = {
shell: {
bin: 'bash',
argv: '',
ext: 'sh'
},
applescript: {
bin: 'osascript',
argv: '',
ext: 'scpt'
},
cmd: {
bin: '',
agrv: '',
ext: 'bat'
},
powershell: {
bin: 'powershell',
agrv: '-NoProfile -File',
ext: 'ps1'
},
python: {
bin: 'python',
agrv: '-u',
ext: 'py'
},
javascript: {
bin: 'node',
agrv: '',
ext: 'js'
},
ruby: {
bin: 'ruby',
agrv: '',
ext: 'rb'
},
php: {
bin: 'php',
agrv: '',
ext: 'php'
},
lua: {
bin: 'lua',
agrv: '',
ext: 'lua'
},
perl: {
bin: 'perl',
agrv: '',
ext: 'pl'
}
}
showOptions = () => {
var currentFts = utools.getFeatures(),
customFts = getCustomFts();
let featureList = '<table><tr><td></td><td>关键字</td><td>说明</td><td>启用</td></tr>';
for (var fts in customFts) {
let features = customFts[fts].features;
var cmds = '';
if (customFts[fts].noKeyword) {
cmds = '<span class="keyword">匹配主输入框文本进入</span>';
} else {
features.cmds.forEach(cmd => {
cmds += `<span class="keyword">${cmd}</span>`;
});
}
var isChecked = '';
for(var c of currentFts){
if (c.code == features.code) {
isChecked = 'checked';
break;
}
}
var iconpath = pjoin(dirname, features.icon),
base64Ico = customFts[fts].base64Ico;
if (!exists(iconpath) && base64Ico) saveBase64Ico(iconpath, base64Ico);
featureList += `<tr><td><img class="logo" src="${iconpath}"></td>
<td>${cmds}</td><td width="300px">${features.explain}</td><td>
<label class="switch-btn">
<input class="checked-switch" id="${features.code}" type="checkbox" ${isChecked}>
<span class="text-switch"></span>
<span class="toggle-btn"></span>
</label>
<span class="editBtn" code="${features.code}">✎</span>
<span class="delBtn" code="${features.code}">✘</span>
</td>`
};
featureList += `</tr></table><div class="foot">
<div id="add" class="footBtn">添加命令</div>
<div id="disableAll" class="footBtn">全部禁用</div>
<div id="enableAll" class="footBtn">全部启用</div>
</div>`
$("#options").html(featureList);
}
showCustomize = () => {
$("#customize").remove();
let options = `<option>${Object.keys(programs).join('</option><option>')}</option>`
customWindow = `<div id="customize">
<p><span class="word">关键字</span><input type="text" id="kw" placeholder="多个关键字用逗号隔开"></p>
<p><span class="word">说&#12288;明</span><input type="text" id="desc" placeholder="命令功能的描述"></p>
<p>
<span class="word">类&#12288;型</span>
<select id="program">
${options}
</select>
<span class="word">图&#12288;标</span><input type="text" readonly id="iconame" placeholder="更改图标">
<img id="icon" src="">
</p>
<p>
<span class="word">变&#12288;量</span>
<select id="vars">
<option value="" style="display:none">插入特殊变量</option>
<option value="{{isWin}}">是否Window系统</option>
<option value="{{input}}">主输入框的文本</option>
<option value="{{pwd}}">文件管理器当前目录</option>
<option value="{{ChromeUrl}}">Chrome当前链接</option>
<option value="{{ClipText}}">剪切板的文本</option>
<option value="{{SelectText}}">选中的文本</option>
<option value="{{SelectFile}}">选中的文件</option>
</select>
<span class="word">输&#12288;出</span>
<select id="output">
<option value="ignore">忽略输出</option>
<option value="text">显示纯文本输出</option>
<option value="html">显示html格式的输出</option>
<option value="clip">复制到剪贴板</option>
<option value="send">发送到活动窗口</option>
</select>
</p>
<p>
<span class="word">脚&#12288;本</span>
<select id="codec">
<option value="gbk">GBK 编码</option>
<option value="utf8">UTF8 编码</option>
</select>
</p>
<p><textarea id="cmd" placeholder="可以直接拖放脚本文件至此处"></textarea></p>
<p>
<button class="saveBtn">保存</button>
<button class="cancelBtn">取消</button>
</p>`
$("#options").append(customWindow)
if (window.isWin) {
var shell = 'cmd',
mode = 'powershell';
} else {
var shell = 'shell',
mode = 'shell';
$("#codec").hide();
}
$("#program").val(shell);
$("#icon").attr('src', `logo/${shell}.png`);
window.editor = CodeMirror.fromTextArea(document.getElementById("cmd"), {
lineNumbers: true,
lineWrapping: true
});
window.editor.setOption("mode", mode);
$("#customize").animate({ top: '0px' });
}
// 开关
$("#options").on('change', 'input[type=checkbox]', function () {
var customFts = getCustomFts(),
code = $(this).attr('id');
if (!utools.removeFeature(code)) {
utools.setFeature(customFts[code].features);
}
});
// 底部功能按钮
$("#options").on('click', '.footBtn', function () {
switch ($(this).attr('id')) {
case 'add': showCustomize();
break;
case 'enableAll': $(".checked-switch:not(:checked)").click();
break;
case 'disableAll': $(".checked-switch:checked").click();
break;
}
})
// 取消
$("#options").on('click', '.cancelBtn', function () {
$("#customize").animate({ top: '100%'});
})
// 编辑
$("#options").on('click', '.editBtn', function () {
var code = $(this).attr('code');
var data = utools.db.get("customFts").data[code];
showCustomize();
// 判断是通过关键词进入还是主输入框进入
if (data.noKeyword) {
$('#kw').val(data.features.code);
$('#kw').prop('disabled', true);
} else {
$('#kw').val(data.features.cmds.toString());
}
$('#kw').attr('edit', true);
$('#program').val(data.program);
$('#output').val(data.output);
$('#desc').val(data.features.explain);
$('#codec').val(data.codec);
$("#icon").attr('src', data.features.icon);
let mode = data.program;
let iconame = basename(data.features.icon);
if (iconame != `${mode}.png`) $('#iconame').val(iconame);
mode == 'applescript' && (mode = 'shell');
mode == 'cmd' && (mode = 'powershell');
window.editor.setOption("mode", mode);
window.editor.setValue(data.cmd);
})
// 删除
$("#options").on('click', '.delBtn', function () {
var code = $(this).attr('code'),
db = utools.db.get("customFts"),
data = db.data;
delete data[code];
utools.removeFeature(code);
utools.db.put({ _id: "customFts", data: data, _rev: db._rev });
showOptions();
})
// 选择图标
$("#options").on('click', '#icon, #iconame', function () {
let iconpath = window.openFolder()[0];
$("#iconame").val(basename(iconpath));
$("#icon").attr('src', iconpath);
})
// 保存
$("#options").on('click', '.saveBtn', function () {
var code = $('#kw').val().split(',')[0].trim()
var customFts = getCustomFts();
// 如果 code 重复, 编辑状态下不检测
if (code in customFts && !$('#kw').attr('edit')) {
$('#kw').css({ 'border-bottom-color': '#ec1212' })
window.messageBox({ type: 'error', icon: window.logo, message: "命令名称与现有的重复!", buttons: ['朕知道了'] })
} else {
var kw = $('#kw').val().split(','),
program = $('#program').val(),
desc = $('#desc').val(),
output = $('#output').val(),
codec = $('#codec').val(),
iconame = $("#iconame").val(),
iconpath = $("#icon").attr('src'),
cmd = window.editor.getValue(),
icon,
base64ico;
// 自定义了图标的情况下
if (iconame) {
icon = window.getIconPath(iconame);
if (iconpath == icon) {
base64ico = window.getBase64Ico(pjoin(dirname, iconpath));
} else {
base64ico = window.getBase64Ico(iconpath);
}
// 未自定义使用默认
} else {
icon = iconpath;
base64ico = '';
}
// 通过主输入框直接进入
if (cmd.includes('{{input}}')) {
kw = [{
"label": desc,
"type": "over",
"minNum": 1
}];
noKeyword = true;
} else {
noKeyword = false;
}
$("#customize").animate({ top: '100%' });
var pushData = {};
// 添加特性
pushData[code] = {
features: {
"code": code,
"explain": desc,
"cmds": kw,
"icon": icon
},
program: program,
cmd: cmd,
output: output,
codec: codec,
base64Ico: base64ico,
noKeyword: noKeyword
}
var db = utools.db.get("customFts");
if (db) {
var rev = db._rev
var data = db.data
data[code] = pushData[code];
utools.db.put({ _id: "customFts", data: data, _rev: rev });
} else {
utools.db.put({ _id: "customFts", data: pushData });
}
showOptions();
}
})
// 语言选项改变时
$("#options").on('change', '#program', function () {
let mode = $(this).val();
if (!$("#iconame").val()) $("#icon").attr('src', `logo/${mode}.png`);
mode == 'applescript' && (mode = 'shell');
mode == 'cmd' && (mode = 'powershell');
window.editor.setOption("mode", mode);
})
// 变量选项改变时
$("#options").on('change', '#vars', function () {
$("#vars").css({'color':'black'})
window.editor.replaceSelection($("#vars").val());
})