wk-settings

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

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

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.cn-greasyfork.org/scripts/450210/1085842/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.6
  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. const UMManager = new UserModuleManager();
  71. SPanel.add({
  72. faicon: 'fa-solid fa-gear',
  73. tip: CONST.Text.Button,
  74. onclick: UMManager.show
  75. });
  76.  
  77. exports = {
  78. isSettingPage: isSettingPage,
  79. insertLines: insertLines,
  80. registerSettings: UMManager.registerModuleSettings
  81. };
  82.  
  83. function main() {
  84. // Get elements
  85. const content = $('#content');
  86.  
  87. // Insert settings
  88. const title = [
  89. [{html: CONST.Text.Title, colSpan: 3, class: 'foot', key: 'settitle'}],
  90. [{html: CONST.Text.ModuleManage, colSpan: 1}, {html: CONST.Text.OpenModuleDialog, colSpan: 2, onclick: UMManager.show}],
  91. //[{html: CONST.Text.XXXX, colSpan: 1, key: 'xxxxxxxx'}, {html: CONST.Text.XXXX, colSpan: 2, key: 'xxxxxxxx'}],
  92. ]
  93. const elements = insertLines(title);
  94.  
  95. // scrollIntoView if need
  96. getUrlArgv('tosettings') === 'true' && elements.settitle.scrollIntoView();
  97. }
  98.  
  99. // Module manager user interface
  100. function UserModuleManager() {
  101. const UMM = this;
  102. const moduleSettingFuncs = {};
  103.  
  104. UMM.show = show;
  105.  
  106. UMM.registerModuleSettings = registerModuleSettings;
  107.  
  108. UMM.showModuleSettings = showModuleSettings;
  109.  
  110. function show() {
  111. //box.set('message', 'No implemented yet!').show();
  112. const modules = ML_listModules();
  113.  
  114. // Make panel
  115. const SetPanel = new SettingPanel.SettingPanel({
  116. header: CONST.Text.ModuleManage,
  117. tables: []
  118. });
  119.  
  120. // Make table
  121. const table = new SetPanel.PanelTable({});
  122.  
  123. // Make header
  124. table.appendRow({
  125. blocks: [{
  126. isHeader: true,
  127. colSpan: 1,
  128. width: '60%',
  129. innerText: CONST.Text.Module,
  130. },{
  131. isHeader: true,
  132. colSpan: 3,
  133. width: '40%',
  134. innerText: CONST.Text.Operation,
  135. }]
  136. });
  137.  
  138. // Make module rows
  139. for (const module of modules) {
  140. const row = new SetPanel.PanelRow({
  141. blocks: [{
  142. colSpan: 1,
  143. rowSpan: 1,
  144. innerText: module.displayname
  145. },{
  146. colSpan: 1,
  147. rowSpan: 1,
  148. children: [makeBtn(CONST.Text.ModuleSettings, showModuleSettings.bind(null, module.identifier))]
  149. },{
  150. colSpan: 1,
  151. rowSpan: 1,
  152. children: [makeBtn(CONST.Text.DisableModule, ML_disableModule.bind(null, module.identifier))]
  153. },{
  154. colSpan: 1,
  155. rowSpan: 1,
  156. children: [makeBtn(CONST.Text.EnableModule, ML_enableModule.bind(null, module.identifier))]
  157. },{
  158. colSpan: 1,
  159. rowSpan: 1,
  160. children: [makeBtn(CONST.Text.UninstallModule, ML_uninstallModule.bind(null, module.identifier))]
  161. }]
  162. });
  163. table.appendRow(row);
  164. }
  165. SetPanel.appendTable(table);
  166.  
  167. function makeBtn(text, onclick) {
  168. const span = $CrE('span');
  169. span.innerText = text;
  170. span.addEventListener('click', onclick);
  171. span.classList.add(ASSETS.ClassName.Button);
  172. return span;
  173. }
  174. }
  175.  
  176. function registerModuleSettings(id, func) {
  177. moduleSettingFuncs[id] = func;
  178. }
  179.  
  180. function showModuleSettings(id) {
  181. const func = moduleSettingFuncs[id];
  182. if (typeof func === 'function') {
  183. func();
  184. return true;
  185. } else {
  186. if (!ML_moduleLoaded(id)) {
  187. alertify.alert(CONST.Text.AlertTitle, CONST.Text.NoLoadNoSettings);
  188. } else {
  189. alertify.alert(CONST.Text.AlertTitle, CONST.Text.NoSettings);
  190. }
  191. return false;
  192. }
  193. }
  194. }
  195.  
  196. function insertLines(lines, tbody) {
  197. !tbody && (tbody = $(content, 'table>tbody'));
  198. const elements = {};
  199. for (const line of lines) {
  200. const tr = $CrE('tr');
  201. for (const item of line) {
  202. const td = $CrE('td');
  203. item.html && (td.innerHTML = item.html);
  204. item.colSpan && (td.colSpan = item.colSpan);
  205. item.class && (td.className = item.class);
  206. item.id && (td.id = item.id);
  207. item.tiptitle && mousetip.settip(td, item.tiptitle);
  208. item.key && (elements[item.key] = td);
  209. if (item.onclick) {
  210. td.style.color = 'grey';
  211. td.style.textAlign = 'center';
  212. td.addEventListener('click', item.onclick);
  213. }
  214. td.style.padding = '3px';
  215. tr.appendChild(td);
  216. }
  217. tbody.appendChild(tr);
  218. }
  219. return elements;
  220. }
  221.  
  222. function isSettingPage(callback) {
  223. const page = getAPI()[0] === 'userdetail.php';
  224. page && callback && callback();
  225. return page;
  226. }
  227.  
  228. // Change location.href without reloading using history.pushState/replaceState
  229. function setPageUrl() {
  230. let win, url, push;
  231. switch (arguments.length) {
  232. case 1:
  233. win = window;
  234. url = arguments[0];
  235. push = false;
  236. break;
  237. case 2:
  238. win = arguments[0];
  239. url = arguments[1];
  240. push = false;
  241. break;
  242. case 3:
  243. win = arguments[0];
  244. url = arguments[1];
  245. push = arguments[2];
  246. }
  247. return win.history[push ? 'pushState' : 'replaceState']({modified: true, ...history.state}, '', url);
  248. }
  249. })();