wk-settings

轻小说文库++的脚本设置界面

当前为 2022-08-26 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.cn-greasyfork.org/scripts/450210/1085839/wk-settings.js

  1. /* eslint-disable no-multi-spaces */
  2. /* eslint-disable no-implicit-globals */
  3. /* eslint-disable userscripts/no-invalid-headers */
  4. /* eslint-disable userscripts/no-invalid-grant */
  5.  
  6. // ==UserScript==
  7. // @name wk-settings
  8. // @displayname 设置界面
  9. // @namespace Wenku8++
  10. // @version 0.1.5
  11. // @description 轻小说文库++的脚本设置界面
  12. // @author PY-DNG
  13. // @license GPL-v3
  14. // @regurl https?://www\.wenku8\.net/.*
  15. // @require https://greasyfork.org/scripts/449412-basic-functions/code/Basic%20Functions.js?version=1085783
  16. // @require https://greasyfork.org/scripts/449583-configmanager/code/ConfigManager.js?version=1085836
  17. // @grant GM_getValue
  18. // @grant GM_setValue
  19. // @grant GM_deleteValue
  20. // @grant GM_listValues
  21. // @grant ML_listModules
  22. // @grant ML_disableModule
  23. // @grant ML_enableModule
  24. // @grant ML_uninstallModule
  25. // @grant ML_moduleLoaded
  26. // @protect
  27. // ==/UserScript==
  28.  
  29. (function __MAIN__() {
  30. const ASSETS = require('assets');
  31. const alertify = require('alertify');
  32. const SPanel = require('SidePanel');
  33. const SettingPanel = require('SettingPanel');
  34. const mousetip = require('mousetip');
  35. const CONST = {
  36. Text: {
  37. Button: '设置',
  38. Title: '脚本设置',
  39. ModuleManage: '模块管理',
  40. OpenModuleDialog: '点此打开管理面板',
  41. ModuleSettings: '模块设置',
  42. Module: '模块',
  43. Operation: '操作',
  44. DisableModule: '禁用模块',
  45. EnableModule: '启用模块',
  46. UninstallModule: '卸载模块',
  47. AlertTitle: '模块设置界面',
  48. NoLoadNoSettings: '模块并未在此页面上运行,无法获取设置',
  49. NoSettings: '该模块当前并没有提供设置选项',
  50. },
  51. Config_Ruleset: {
  52. 'version-key': 'config-version',
  53. 'ignores': ["LOCAL-CDN"],
  54. 'defaultValues': {
  55. //'config-key': {},
  56. },
  57. 'updaters': {
  58. /*'config-key': [
  59. function() {
  60. // This function contains updater for config['config-key'] from v0 to v1
  61. },
  62. function() {
  63. // This function contains updater for config['config-key'] from v1 to v2
  64. }
  65. ]*/
  66. }
  67. }
  68. };
  69.  
  70. SPanel.add({
  71. faicon: 'fa-solid fa-gear',
  72. tip: CONST.Text.Button,
  73. onclick: function() {
  74. const win = window.open('https://www.wenku8.net/userdetail.php');
  75. setPageUrl(win, 'https://www.wenku8.net/userdetail.php?tosettings=true');
  76. }
  77. });
  78.  
  79. const UMManager = new UserModuleManager();
  80. isSettingPage(main);
  81. exports = {
  82. isSettingPage: isSettingPage,
  83. insertLines: insertLines,
  84. registerSettings: UMManager.registerModuleSettings
  85. };
  86.  
  87. function main() {
  88. // Get elements
  89. const content = $('#content');
  90.  
  91. // Insert settings
  92. const title = [
  93. [{html: CONST.Text.Title, colSpan: 3, class: 'foot', key: 'settitle'}],
  94. [{html: CONST.Text.ModuleManage, colSpan: 1}, {html: CONST.Text.OpenModuleDialog, colSpan: 2, onclick: UMManager.show}],
  95. //[{html: CONST.Text.XXXX, colSpan: 1, key: 'xxxxxxxx'}, {html: CONST.Text.XXXX, colSpan: 2, key: 'xxxxxxxx'}],
  96. ]
  97. const elements = insertLines(title);
  98.  
  99. // scrollIntoView if need
  100. getUrlArgv('tosettings') === 'true' && elements.settitle.scrollIntoView();
  101. }
  102.  
  103. // Module manager user interface
  104. function UserModuleManager() {
  105. const UMM = this;
  106. const moduleSettingFuncs = {};
  107.  
  108. UMM.show = show;
  109.  
  110. UMM.registerModuleSettings = registerModuleSettings;
  111.  
  112. UMM.showModuleSettings = showModuleSettings;
  113.  
  114. function show() {
  115. //box.set('message', 'No implemented yet!').show();
  116. const modules = ML_listModules();
  117.  
  118. // Make panel
  119. const SetPanel = new SettingPanel.SettingPanel({
  120. header: CONST.Text.ModuleManage,
  121. tables: []
  122. });
  123.  
  124. // Make table
  125. const table = new SetPanel.PanelTable({});
  126.  
  127. // Make header
  128. table.appendRow({
  129. blocks: [{
  130. isHeader: true,
  131. colSpan: 1,
  132. width: '60%',
  133. innerText: CONST.Text.Module,
  134. },{
  135. isHeader: true,
  136. colSpan: 3,
  137. width: '40%',
  138. innerText: CONST.Text.Operation,
  139. }]
  140. });
  141.  
  142. // Make module rows
  143. for (const module of modules) {
  144. const row = new SetPanel.PanelRow({
  145. blocks: [{
  146. colSpan: 1,
  147. rowSpan: 1,
  148. innerText: module.displayname
  149. },{
  150. colSpan: 1,
  151. rowSpan: 1,
  152. children: [makeBtn(CONST.Text.ModuleSettings, showModuleSettings.bind(null, module.identifier))]
  153. },{
  154. colSpan: 1,
  155. rowSpan: 1,
  156. children: [makeBtn(CONST.Text.DisableModule, ML_disableModule.bind(null, module.identifier))]
  157. },{
  158. colSpan: 1,
  159. rowSpan: 1,
  160. children: [makeBtn(CONST.Text.EnableModule, ML_enableModule.bind(null, module.identifier))]
  161. },{
  162. colSpan: 1,
  163. rowSpan: 1,
  164. children: [makeBtn(CONST.Text.UninstallModule, ML_uninstallModule.bind(null, module.identifier))]
  165. }]
  166. });
  167. table.appendRow(row);
  168. }
  169. SetPanel.appendTable(table);
  170.  
  171. function makeBtn(text, onclick) {
  172. const span = $CrE('span');
  173. span.innerText = text;
  174. span.addEventListener('click', onclick);
  175. span.classList.add(ASSETS.ClassName.Button);
  176. return span;
  177. }
  178. }
  179.  
  180. function registerModuleSettings(id, func) {
  181. moduleSettingFuncs[id] = func;
  182. }
  183.  
  184. function showModuleSettings(id) {
  185. const func = moduleSettingFuncs[id];
  186. if (typeof func === 'function') {
  187. func();
  188. return true;
  189. } else {
  190. if (!ML_moduleLoaded(id)) {
  191. alertify.alert(CONST.Text.AlertTitle, CONST.Text.NoLoadNoSettings);
  192. } else {
  193. alertify.alert(CONST.Text.AlertTitle, CONST.Text.NoSettings);
  194. }
  195. return false;
  196. }
  197. }
  198. }
  199.  
  200. function insertLines(lines, tbody) {
  201. !tbody && (tbody = $(content, 'table>tbody'));
  202. const elements = {};
  203. for (const line of lines) {
  204. const tr = $CrE('tr');
  205. for (const item of line) {
  206. const td = $CrE('td');
  207. item.html && (td.innerHTML = item.html);
  208. item.colSpan && (td.colSpan = item.colSpan);
  209. item.class && (td.className = item.class);
  210. item.id && (td.id = item.id);
  211. item.tiptitle && mousetip.settip(td, item.tiptitle);
  212. item.key && (elements[item.key] = td);
  213. if (item.onclick) {
  214. td.style.color = 'grey';
  215. td.style.textAlign = 'center';
  216. td.addEventListener('click', item.onclick);
  217. }
  218. td.style.padding = '3px';
  219. tr.appendChild(td);
  220. }
  221. tbody.appendChild(tr);
  222. }
  223. return elements;
  224. }
  225.  
  226. function isSettingPage(callback) {
  227. const page = getAPI()[0] === 'userdetail.php';
  228. page && callback && callback();
  229. return page;
  230. }
  231.  
  232. // Change location.href without reloading using history.pushState/replaceState
  233. function setPageUrl() {
  234. let win, url, push;
  235. switch (arguments.length) {
  236. case 1:
  237. win = window;
  238. url = arguments[0];
  239. push = false;
  240. break;
  241. case 2:
  242. win = arguments[0];
  243. url = arguments[1];
  244. push = false;
  245. break;
  246. case 3:
  247. win = arguments[0];
  248. url = arguments[1];
  249. push = arguments[2];
  250. }
  251. return win.history[push ? 'pushState' : 'replaceState']({modified: true, ...history.state}, '', url);
  252. }
  253. })();