pull/1395/head
gedoor 3 years ago
parent 287fcf0481
commit 728c02db25
  1. 36
      app/src/main/assets/web/bookSource/index.html
  2. 56
      app/src/main/assets/web/bookSource/index.js
  3. 2
      app/src/main/assets/web/rssSource/index.html

@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>阅读3.0源编辑器_V4.0</title> <title>阅读3.0源编辑器_V4.0</title>
<link rel="icon" href="favicon.ico"> <link rel="icon" href="favicon.ico">
<link rel="stylesheet" type="text/css" href="index.css"/> <link rel="stylesheet" type="text/css" href="index.css"/>
</head> </head>
@ -30,22 +30,22 @@
<div> <div>
<div>源名称 :</div> <div>源名称 :</div>
<textarea rows="1" id="bookSourceName" class="base" title="bookSourceName" <textarea rows="1" id="bookSourceName" class="base" title="bookSourceName"
placeholder="&lt;必填&gt;会显示在源列表"></textarea> placeholder="&lt;必填&gt;会显示在源列表"></textarea>
</div> </div>
<div> <div>
<div>源分组 :</div> <div>源分组 :</div>
<textarea rows="1" id="bookSourceGroup" class="base" title="bookSourceGroup" <textarea rows="1" id="bookSourceGroup" class="base" title="bookSourceGroup"
placeholder="&lt;选填&gt;描述源的特征信息"></textarea> placeholder="&lt;选填&gt;描述源的特征信息"></textarea>
</div> </div>
<div> <div>
<div>源注释 :</div> <div>源注释 :</div>
<textarea rows="1" id="bookSourceComment" class="base" title="bookSourceComment" <textarea rows="1" id="bookSourceComment" class="base" title="bookSourceComment"
placeholder="&lt;选填&gt;描述源作者和状态"></textarea> placeholder="&lt;选填&gt;描述源作者和状态"></textarea>
</div> </div>
<div> <div>
<div>登录地址:</div> <div>登录地址:</div>
<textarea rows="1" id="loginUrl" class="base" title="loginUrl" <textarea rows="1" id="loginUrl" class="base" title="loginUrl"
placeholder="&lt;选填&gt;填写网站登录网址,仅在需要登录的源有用"></textarea> placeholder="&lt;选填&gt;填写网站登录网址,仅在需要登录的源有用"></textarea>
</div> </div>
<div> <div>
<div>登录界面:</div> <div>登录界面:</div>
@ -337,19 +337,19 @@
</div> </div>
<div class="menu"> <div class="menu">
<svg class="button"> <svg class="button">
<text x="50%" y="55%">⇈推送</text> <text x="50%" y="55%">⇈推送源</text>
<rect id="push"></rect> <rect id="push"></rect>
</svg> </svg>
<svg class="button"> <svg class="button">
<text x="50%" y="55%">⇊拉取</text> <text x="50%" y="55%">⇊拉取源</text>
<rect id="pull"></rect> <rect id="pull"></rect>
</svg> </svg>
<svg class="button"> <svg class="button">
<text x="50%" y="55%">⋘编辑</text> <text x="50%" y="55%">⋘编辑源</text>
<rect id="editor"></rect> <rect id="editor"></rect>
</svg> </svg>
<svg class="button"> <svg class="button">
<text x="50%" y="55%">⋙生成</text> <text x="50%" y="55%">⋙生成源</text>
<rect id="conver"></rect> <rect id="conver"></rect>
</svg> </svg>
<svg class="button"> <svg class="button">
@ -365,20 +365,20 @@
<rect id="redo"></rect> <rect id="redo"></rect>
</svg> </svg>
<svg class="button"> <svg class="button">
<text x="50%" y="55%">⇏调试</text> <text x="50%" y="55%">⇏调试源</text>
<rect id="debug"></rect> <rect id="debug"></rect>
</svg> </svg>
<svg class="button"> <svg class="button">
<text x="50%" y="55%">✓保存</text> <text x="50%" y="55%">✓保存源</text>
<rect id="accept"></rect> <rect id="accept"></rect>
</svg> </svg>
</div> </div>
<div class="outbox"> <div class="outbox">
<div class="tabbox"> <div class="tabbox">
<div class="tabtitle"> <div class="tabtitle">
<div name="编辑源" class="tab1 this">编辑</div> <div name="编辑源" class="tab1 this">编辑源</div>
<div name="调试源" class="tab2">调试</div> <div name="调试源" class="tab2">调试源</div>
<div name="源列表" class="tab3">源列表</div> <div name="源列表" class="tab3">源列表</div>
<div name="帮助信息" class="tab4">帮助信息</div> <div name="帮助信息" class="tab4">帮助信息</div>
</div> </div>
<div class="tabbody"> <div class="tabbody">
@ -394,10 +394,10 @@
<input type="text" class="inputbox" id="Filter" <input type="text" class="inputbox" id="Filter"
placeholder="输入筛选关键词(源名称、源URL或源分组)后按回车筛选源"> placeholder="输入筛选关键词(源名称、源URL或源分组)后按回车筛选源">
<div class="titlebar"> <div class="titlebar">
<button id="Import">导入源文件</button> <button id="Import">导入源文件</button>
<button id="Export">导出源文件</button> <button id="Export">导出源文件</button>
<button id="Delete">删除选中</button> <button id="Delete">删除选中源</button>
<button id="ClrAll">清空当前列表</button> <button id="ClrAll">清空列表</button>
</div> </div>
<div class="context" id="RuleList"></div> <div class="context" id="RuleList"></div>
</div> </div>

@ -17,7 +17,7 @@ function hashParam(key, val) {
} }
} }
} }
// 创建源规则容器对象 // 创建源规则容器对象
function Container() { function Container() {
let ruleJson = {}; let ruleJson = {};
let searchJson = {}; let searchJson = {};
@ -64,7 +64,7 @@ function showTab(tabName) {
$(`.tabtitle>*[name=${tabName}]`).className += ' this'; $(`.tabtitle>*[name=${tabName}]`).className += ' this';
hashParam('tab', tabName); hashParam('tab', tabName);
} }
// 源列表列表标签构造函数 // 源列表列表标签构造函数
function newRule(rule) { function newRule(rule) {
return `<label for="${rule.bookSourceUrl}"><input type="radio" name="rule" id="${rule.bookSourceUrl}"><div>${rule.bookSourceName}<br>${rule.bookSourceUrl}</div></label>`; return `<label for="${rule.bookSourceUrl}"><input type="radio" name="rule" id="${rule.bookSourceUrl}"><div>${rule.bookSourceName}<br>${rule.bookSourceUrl}</div></label>`;
} }
@ -99,7 +99,7 @@ function HttpPost(url, data) {
}) })
}).then(res => res.json()).catch(err => console.error('Error:', err)); }).then(res => res.json()).catch(err => console.error('Error:', err));
} }
// 将源表单转化为源对象 // 将源表单转化为源对象
function rule2json() { function rule2json() {
let RuleJSON = Container(); let RuleJSON = Container();
// 转换base // 转换base
@ -157,7 +157,7 @@ function rule2json() {
RuleJSON.enabledExplore = RuleJSON.enabledExplore == '' || String(RuleJSON.enabledExplore).toLocaleLowerCase().replace(/^\s*|\s*$/g, '') == 'true'; RuleJSON.enabledExplore = RuleJSON.enabledExplore == '' || String(RuleJSON.enabledExplore).toLocaleLowerCase().replace(/^\s*|\s*$/g, '') == 'true';
return RuleJSON; return RuleJSON;
} }
// 将源对象填充到源表单 // 将源对象填充到源表单
function json2rule(RuleEditor) { function json2rule(RuleEditor) {
let RuleJSON = Container(); let RuleJSON = Container();
// 转换base // 转换base
@ -285,23 +285,23 @@ $('.menu').addEventListener('click', e => {
if (okData.find(x => x.bookSourceUrl == item.bookSourceUrl)) { } if (okData.find(x => x.bookSourceUrl == item.bookSourceUrl)) { }
else { $(`#RuleList #${item.bookSourceUrl}+*`).className += 'isError'; } else { $(`#RuleList #${item.bookSourceUrl}+*`).className += 'isError'; }
}); });
failMsg = '\n推送失败的源将用红色字体标注!'; failMsg = '\n推送失败的源将用红色字体标注!';
} }
alert(`批量推送源到「阅读3.0APP」\n共计: ${RuleSources.length}\n成功: ${okData.length}\n失败: ${RuleSources.length - okData.length}${failMsg}`); alert(`批量推送源到「阅读3.0APP」\n共计: ${RuleSources.length}\n成功: ${okData.length}\n失败: ${RuleSources.length - okData.length}${failMsg}`);
} }
else { else {
alert(`批量推送源到「阅读3.0APP」成功!\n共计: ${RuleSources.length}`); alert(`批量推送源到「阅读3.0APP」成功!\n共计: ${RuleSources.length}`);
} }
} }
else { else {
alert(`批量推送源失败!\nErrorMsg: ${json.errorMsg}`); alert(`批量推送源失败!\nErrorMsg: ${json.errorMsg}`);
} }
}).catch(err => { alert(`批量推送源失败,无法连接到「阅读3.0APP」!\n${err}`); }); }).catch(err => { alert(`批量推送源失败,无法连接到「阅读3.0APP」!\n${err}`); });
thisNode.setAttribute('class', ''); thisNode.setAttribute('class', '');
})(); })();
return; return;
case 'pull': case 'pull':
showTab('源列表'); showTab('源列表');
(async () => { (async () => {
await HttpGet(`/getBookSources`).then(json => { await HttpGet(`/getBookSources`).then(json => {
if (json.isSuccess) { if (json.isSuccess) {
@ -310,12 +310,12 @@ $('.menu').addEventListener('click', e => {
RuleSources.forEach(item => { RuleSources.forEach(item => {
$('#RuleList').innerHTML += newRule(item); $('#RuleList').innerHTML += newRule(item);
}); });
alert(`成功拉取 ${RuleSources.length}`); alert(`成功拉取 ${RuleSources.length} 条源`);
} }
else { else {
alert(`批量拉取源失败!\nErrorMsg: ${json.errorMsg}`); alert(`批量拉取源失败!\nErrorMsg: ${json.errorMsg}`);
} }
}).catch(err => { alert(`批量拉取源失败,无法连接到「阅读3.0APP」!\n${err}`); }); }).catch(err => { alert(`批量拉取源失败,无法连接到「阅读3.0APP」!\n${err}`); });
thisNode.setAttribute('class', ''); thisNode.setAttribute('class', '');
})(); })();
return; return;
@ -330,7 +330,7 @@ $('.menu').addEventListener('click', e => {
} }
break; break;
case 'conver': case 'conver':
showTab('编辑源'); showTab('编辑源');
$('#RuleJsonString').value = JSON.stringify(rule2json(), null, 4); $('#RuleJsonString').value = JSON.stringify(rule2json(), null, 4);
break; break;
case 'initial': case 'initial':
@ -344,7 +344,7 @@ $('.menu').addEventListener('click', e => {
redo() redo()
break; break;
case 'debug': case 'debug':
showTab('调试源'); showTab('调试源');
let wsOrigin = (hashParam('domain') || location.origin).replace(/^.*?:/, 'ws:').replace(/\d+$/, (port) => (parseInt(port) + 1)); let wsOrigin = (hashParam('domain') || location.origin).replace(/^.*?:/, 'ws:').replace(/\d+$/, (port) => (parseInt(port) + 1));
let DebugInfos = $('#DebugConsole'); let DebugInfos = $('#DebugConsole');
function DebugPrint(msg) { DebugInfos.value += `\n${msg}`; DebugInfos.scrollTop = DebugInfos.scrollHeight; } function DebugPrint(msg) { DebugInfos.value += `\n${msg}`; DebugInfos.scrollTop = DebugInfos.scrollHeight; }
@ -352,7 +352,7 @@ $('.menu').addEventListener('click', e => {
HttpPost(`/saveBookSources`, saveRule).then(sResult => { HttpPost(`/saveBookSources`, saveRule).then(sResult => {
if (sResult.isSuccess) { if (sResult.isSuccess) {
let sKey = DebugKey.value ? DebugKey.value : '我的'; let sKey = DebugKey.value ? DebugKey.value : '我的';
$('#DebugConsole').value = `源《${saveRule[0].bookSourceName}》保存成功!使用搜索关键字“${sKey}”开始调试...`; $('#DebugConsole').value = `源《${saveRule[0].bookSourceName}》保存成功!使用搜索关键字“${sKey}”开始调试...`;
let ws = new WebSocket(`${wsOrigin}/sourceDebug`); let ws = new WebSocket(`${wsOrigin}/sourceDebug`);
ws.onopen = () => { ws.onopen = () => {
ws.send(`{"tag":"${saveRule[0].bookSourceUrl}", "key":"${sKey}"}`); ws.send(`{"tag":"${saveRule[0].bookSourceUrl}", "key":"${sKey}"}`);
@ -378,9 +378,9 @@ $('.menu').addEventListener('click', e => {
(async () => { (async () => {
let saveRule = [rule2json()]; let saveRule = [rule2json()];
await HttpPost(`/saveBookSources`, saveRule).then(json => { await HttpPost(`/saveBookSources`, saveRule).then(json => {
alert(json.isSuccess ? `源《${saveRule[0].bookSourceName}》已成功保存到「阅读3.0APP」` : `源《${saveRule[0].bookSourceName}》保存失败!\nErrorMsg: ${json.errorMsg}`); alert(json.isSuccess ? `源《${saveRule[0].bookSourceName}》已成功保存到「阅读3.0APP」` : `源《${saveRule[0].bookSourceName}》保存失败!\nErrorMsg: ${json.errorMsg}`);
setRule(saveRule[0]); setRule(saveRule[0]);
}).catch(err => { alert(`保存源失败,无法连接到「阅读3.0APP」!\n${err}`); }); }).catch(err => { alert(`保存源失败,无法连接到「阅读3.0APP」!\n${err}`); });
thisNode.setAttribute('class', ''); thisNode.setAttribute('class', '');
})(); })();
return; return;
@ -447,7 +447,7 @@ $('.tab3>.titlebar').addEventListener('click', e => {
let fileJson = JSON.parse(fileText); let fileJson = JSON.parse(fileText);
let newSources = []; let newSources = [];
newSources.push(...fileJson); newSources.push(...fileJson);
if (window.confirm(`如何处理导入的源?\n"确定": 覆盖当前列表(不会删除APP源)\n"取消": 插入列表尾部(自动忽略重复源)`)) { if (window.confirm(`如何处理导入的源?\n"确定": 覆盖当前列表(不会删除APP源)\n"取消": 插入列表尾部(自动忽略重复源)`)) {
localStorage.setItem('BookSources', JSON.stringify(RuleSources = newSources)); localStorage.setItem('BookSources', JSON.stringify(RuleSources = newSources));
$('#RuleList').innerHTML = '' $('#RuleList').innerHTML = ''
RuleSources.forEach(item => { RuleSources.forEach(item => {
@ -462,10 +462,10 @@ $('.tab3>.titlebar').addEventListener('click', e => {
$('#RuleList').innerHTML += newRule(item); $('#RuleList').innerHTML += newRule(item);
}); });
} }
alert(`成功导入 ${newSources.length}`); alert(`成功导入 ${newSources.length} 条源`);
} }
catch (err) { catch (err) {
alert(`导入源文件失败!\n${err}`); alert(`导入源文件失败!\n${err}`);
} }
} }
}; };
@ -483,13 +483,13 @@ $('.tab3>.titlebar').addEventListener('click', e => {
case 'Delete': case 'Delete':
let selectRule = $('#RuleList input:checked'); let selectRule = $('#RuleList input:checked');
if (!selectRule) { if (!selectRule) {
alert(`没有源被选中!`); alert(`没有源被选中!`);
return; return;
} }
if (confirm(`确定要删除选定源吗?\n(同时删除APP内源)`)) { if (confirm(`确定要删除选定源吗?\n(同时删除APP内源)`)) {
let selectRuleUrl = selectRule.id; let selectRuleUrl = selectRule.id;
let deleteSources = RuleSources.filter(item => item.bookSourceUrl == selectRuleUrl); // 提取待删除的 let deleteSources = RuleSources.filter(item => item.bookSourceUrl == selectRuleUrl); // 提取待删除的源
let laveSources = RuleSources.filter(item => !(item.bookSourceUrl == selectRuleUrl)); // 提取待留下的 let laveSources = RuleSources.filter(item => !(item.bookSourceUrl == selectRuleUrl)); // 提取待留下的源
HttpPost(`/deleteBookSources`, deleteSources).then(json => { HttpPost(`/deleteBookSources`, deleteSources).then(json => {
if (json.isSuccess) { if (json.isSuccess) {
let selectNode = document.getElementById(selectRuleUrl).parentNode; let selectNode = document.getElementById(selectRuleUrl).parentNode;
@ -500,13 +500,13 @@ $('.tab3>.titlebar').addEventListener('click', e => {
todo(); todo();
} }
console.log(deleteSources); console.log(deleteSources);
console.log(`以上源已删除!`) console.log(`以上源已删除!`)
} }
}).catch(err => { alert(`删除源失败,无法连接到「阅读3.0APP」!\n${err}`); }); }).catch(err => { alert(`删除源失败,无法连接到「阅读3.0APP」!\n${err}`); });
} }
break; break;
case 'ClrAll': case 'ClrAll':
if (confirm(`确定要清空当前源列表吗?\n(不会删除APP内源)`)) { if (confirm(`确定要清空当前源列表吗?\n(不会删除APP内源)`)) {
localStorage.setItem('BookSources', JSON.stringify(RuleSources = [])); localStorage.setItem('BookSources', JSON.stringify(RuleSources = []));
$('#RuleList').innerHTML = '' $('#RuleList').innerHTML = ''
} }

@ -211,7 +211,7 @@
<button id="Import">导入源文件</button> <button id="Import">导入源文件</button>
<button id="Export">导出源文件</button> <button id="Export">导出源文件</button>
<button id="Delete">删除选中源</button> <button id="Delete">删除选中源</button>
<button id="ClrAll">清空当前列表</button> <button id="ClrAll">清空列表</button>
</div> </div>
<div class="context" id="RuleList"></div> <div class="context" id="RuleList"></div>
</div> </div>

Loading…
Cancel
Save