wk-settings

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

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

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