/* eslint-disable no-multi-spaces */ /* eslint-disable no-loop-func */ /* eslint-disable no-return-assign */ // ==UserScript== // @name 轻小说文库+ (重制) // @namespace Wenku8+_re // @version 0.1.2 // @description 轻小说文库+的重置,写好了就作为一个更新直接发上去,所以到时候记得改name、namespace和描述 // @author PY-DNG // @license GPL-3.0-or-later // @match http*://www.wenku8.net/* // @match http*://www.wenku8.cc/* // @match http*://wenku8.net/* // @match http*://wenku8.cc/* // @connect wenku8.com // @connect wenku8.net // @connect wenku8.cc // @connect p.sda1.dev // @connect image.sogou.com // @connect * // @require https://greasyfork.org/scripts/456034-basic-functions-for-userscripts/code/script.js?version=1282804 // @require https://greasyfork.org/scripts/449583-configmanager/code/script.js?version=1326639 // @require https://greasyfork.org/scripts/471280-url-encoder/code/URL%20Encoder.js?version=1247074 // @require https://greasyfork.org/scripts/460385-gm-web-hooks/code/script.js?version=1221394 // @require https://greasyfork.org/scripts/445697-greasy-fork-api/code/Greasy%20Fork%20API.js?version=1055543 // @require https://fastly.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js // @require https://fastly.jsdelivr.net/npm/tippy.js@6.3.7/dist/tippy.umd.min.js // @require https://fastly.jsdelivr.net/npm/alertifyjs@1.13.1/build/alertify.min.js // @require https://fastly.jsdelivr.net/npm/@shopify/draggable@1.0.0-beta.8/lib/sortable.js // @require https://fastly.jsdelivr.net/gh/vkiryukhin/vkBeautify@0a238953acf12ac2f366fd63998514e1ac9db042/vkbeautify.js // @require https://fastly.jsdelivr.net/npm/darkmode-js@1.5.7/lib/darkmode-js.min.js // @require https://fastly.jsdelivr.net/npm/crypto-js@4.1.1/crypto-js.min.js // @resource tippy-css https://cdn.jsdelivr.net/npm/tippy.js@6.3.7/dist/tippy.css // @resource alertify-css https://fastly.jsdelivr.net/npm/alertifyjs@1.13.1/build/css/alertify.min.css // @resource alertify-theme https://fastly.jsdelivr.net/npm/alertifyjs@1.13.1/build/css/themes/default.min.css // @icon data:image/vnd.microsoft.icon;base64,AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAD/igD//4oA//+KAP//igD//4oA//+KAP//igD//4oA//+KAP//igD//4oA//+KAP//igD//4oA//+KAP//igD//4oA//+KAP//igD//4oA//+KAP//igD//4oA//+KAP//igD//4oA//+KAP//igD//4oA//+KAP//igD//4oA//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw///igD//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//+KAP/858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//4oA//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw///igD//OfD//znw//858P//OfD//znw//858P//rlB//3HaP/858P//OfD//znw//858P//OfD//znw//858P//OfD//zitv/91Y///dWP//3Vj//9y3X//cdo//3HaP/9x2j//cdo//zitv/858P//OfD//znw//858P//OfD//+KAP/858P//OfD//znw//858P//OfD//znw///ogD//6IA//znw//858P//OfD//znw//9x2j//6IA//+iAP//ogD//6IA//+iAP//ogD//6IA//+iAP//ogD//6IA//+iAP//ogD//6cN//znw//858P//OfD//znw//858P//4oA//znw//858P//OfD//3ZnP//ogD//6IA//+iAP//ogD//sJb//3HaP/83qn//OfD//zeqf//pw3//6IA//+iAP//ogD//6IA//+iAP//ogD//6IA//+iAP//ogD//6IA//+rGv/90IL//OfD//znw//858P//OfD//znw///igD//OfD//znw//858P//cdo//+iAP//ogD//6IA//+iAP//ogD//6IA//+iAP//ogD//OfD//znw//858P//OfD//znw//858P//6IA//+iAP/84rb//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//+KAP/858P//OfD//znw//858P//rQ0//60NP//ogD//6IA//+iAP//ogD//6IA//+iAP/858P//OfD//znw//858P//OfD//znw///ogD//6IA//3Vj//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//4oA//znw//858P//OfD//znw//858P//OfD//6wJ///ogD//6sa//3HaP/92Zz//OfD//znw//858P//OfD//znw//858P//OfD//+iAP//ogD//rQ0//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw///igD//OfD//znw//858P//OfD//zitv/+vk7//6IA//+iAP//ogD//6IA//+iAP/+tDT//OfD//znw//858P//OfD//znw//858P//rAn//+iAP//ogD//ct1//3HaP/+tDT//rQ0//6+Tv/858P//OfD//znw//858P//OfD//+KAP/858P//OfD//znw//858P//6IA//+iAP//ogD//6IA//+iAP//ogD//6IA//+iAP//ogD//ct1//7CW///ogD//6IA//+iAP//ogD//6IA//+iAP//ogD//6IA//+iAP//ogD//6IA//znw//858P//OfD//znw//858P//4oA//znw//858P//OfD//znw///ogD//6IA//65Qf//ogD//6IA//3HaP/9x2j//6cN//+iAP//ogD//r5O//+iAP//ogD//6IA//+iAP//ogD//6IA//+iAP//ogD//6IA//60NP/9x2j//OfD//znw//858P//OfD//znw///igD//OfD//znw//858P//OfD//+iAP//ogD//OfD//65Qf//ogD//6cN//znw//858P//6IA//+iAP/92Zz//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//+KAP/858P//OfD//znw//858P//6IA//+iAP/858P//cdo//+iAP//ogD//dWP//3Vj///pw3//6IA//7CW//858P//rQ0//+iAP/92Zz//OfD//3Ldf/+tDT//OK2//znw//858P//N6p//znw//858P//OfD//znw//858P//4oA//znw//858P//OfD//znw///ogD//6IA//+iAP//ogD//6IA//+iAP//ogD//6IA//7CW///ogD//6IA//6+Tv//ogD//6IA//6+Tv/91Y///6IA//+iAP/+vk7//OfD//+iAP//ogD//6IA//znw//858P//OfD//znw///igD//OfD//znw//858P//OfD//+iAP//ogD//6IA//+iAP//ogD//6IA//+iAP//ogD//dWP//+iAP//ogD//6IA//+iAP//ogD//OK2//+rGv//ogD//6IA//3ZnP/858P//6IA//+iAP//qxr//OfD//znw//858P//OfD//+KAP/858P//OfD//znw//858P//sJb//+iAP//pw3//rQ0//+iAP//ogD//OfD//znw//+wlv//6IA//+iAP//ogD//6cN//3ZnP/+vk7//6IA//+iAP/90IL//OfD//60NP//ogD//6IA//znw//858P//OfD//znw//858P//4oA//znw//858P//OfD//znw//84rb//rAn//+iAP//ogD//6IA//+iAP/+sCf//rQ0//+iAP//ogD//6IA//+iAP/9x2j//OfD//65Qf//ogD//rAn//znw//858P//rQ0//+iAP/+uUH//OfD//znw//858P//OfD//znw///igD//OfD//znw//858P//OfD//znw//858P//r5O//60NP//ogD//6IA//+iAP//ogD//6IA//+iAP/9x2j//6IA//+iAP/9x2j//OfD//6+Tv//ogD//6IA//znw//84rb//6IA//+iAP/84rb//OfD//znw//858P//OfD//+KAP/858P//OfD//znw//858P//OfD//znw//858P//OfD//+nDf//ogD//6cN//60NP/+vk7//ct1//znw//+wlv//6IA//+iAP/858P//OK2//+iAP//ogD//dmc//znw///pw3//6IA//6wJ//83qn//OfD//znw//858P//4oA//znw//858P//OfD//znw//858P//OfD//znw//858P//cdo//+iAP//ogD//dmc//znw//858P//OfD//znw///pw3//6IA//+nDf/83qn//dmc//+nDf//ogD//6sa//znw//92Zz//6IA//+iAP/858P//OfD//znw///igD//OfD//znw//858P//OfD//znw//858P//N6p//3HaP/+sCf//6IA//+iAP//ogD//6IA//+iAP//qxr//dmc//3ZnP//pw3//6IA//6+Tv/858P//dmc//+iAP//ogD//OfD//znw//9x2j//sJb//znw//858P//OfD//+KAP/858P//OfD//znw//858P//OfD//znw///ogD//6IA//+iAP//ogD//6IA//+iAP//ogD//6IA//+iAP/+vk7//OfD//znw//91Y///OK2//znw//858P//dWP//3Vj//9x2j//rlB//+nDf//pw3//OfD//znw//858P//4oA//znw//858P//OfD//znw//858P//OfD//3Ldf//ogD//6IA//+iAP//ogD//6IA//60NP/+tDT//cdo//zitv/+tDT//rQ0//+iAP//ogD//6IA//+iAP//ogD//6IA//+iAP//ogD//6IA//+iAP/83qn//OfD//znw///igD//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//dmc//+iAP/+sCf//OfD//znw//858P//dWP//+iAP//ogD//6IA//+iAP//ogD//6IA//+iAP//ogD//6IA//+iAP//ogD//6IA//znw//858P//OfD//+KAP/858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//cdo//zeqf/858P//OfD//znw//858P//rQ0//60NP/+tDT//rQ0//60NP/9x2j//cdo//3HaP/91Y///dWP//zeqf/858P//OfD//znw//858P//4oA//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw///igD//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//+KAP/858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//4oA//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw//858P//OfD//znw///igD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= // @grant GM_getValue // @grant GM_setValue // @grant GM_listValues // @grant GM_deleteValue // @grant GM_xmlhttpRequest // @grant GM_getResourceText // @run-at document-start // @downloadURL none // ==/UserScript== /* global require FuncInfo isWenkuFunction Messager FL_listFunctions FL_getFunction FL_enableFunction FL_disableFunction FL_loadSetting FL_getDebug FL_postMessage FL_recieveMessage */ /* global LogLevel DoLog Err $ $All $CrE $AEL $$CrE addStyle detectDom destroyEvent copyProp copyProps parseArgs escJsStr replaceText getUrlArgv dl_browser dl_GM AsyncManager */ /* global ConfigManager $URL GMXHRHook GMDLHook GreasyFork */ /* global tippy alertify Sortable vkbeautify Darkmode CryptoJS*/ /* 开发进度 [x]: 已完成 [-]: 正在施工 [?]: 等待测试 [o]: 待完善 [ ]: 待开发 [D]: 暂时搁置,后期计划开发 *: 代表相对于旧版有bug修复/优化/新功能 [x] 功能加载器 [x] 加载功能 [x] 启用/禁用功能 [x] 功能存储隔离 [x] 账号存储隔离 [o] 功能日志记录 [o] 设置界面* [o] 功能设置 [x] 独立功能管理界面 [x] 界面框架 [x] 启用/停用 [o] 存储管理 [x] 查看存储 [x] 修改存储 [x] 导出存储 [x] 导入存储 [ ] 导出导入全局配置 [o] 功能设置界面框架 [x] 功能设置界面 [x] 功能设置界面表格对齐 [ ] 脚本设置 [x] 设置界面 [x] 检查更新 [x] 自动检查更新 [ ] 导出配置 [x] 导出日志 [x] 防止设置界面同时打开多次 [x] wenku8.cc域名支持 [o] 在线阅读解锁 [ ] 兼容haoa的轻小说文库下载 [x] 下载解锁 [x] 下载panel [x] 下载页面* [x] “本书公告” [x] 繁体版页面支持 [x] 不用iframe [x] 下载增强* [x] txt* [x] txtfull* [x] jar* [x] umd* [x] 繁体版页面支持 [x] 修复文库下载带html字符编码问题* [x] txt分卷 [x] txt全本 [x] 全部插图下载 [ ] 多格式下载器 [ ] 下载器框架 [ ] txt全本 [ ] txt分卷 [ ] epub全本 [ ] epub分卷 [ ] 插图 [o] 单章节下载* [x] 文本下载 [o] 图片下载 [D] 下载失败时,点击最终提示信息框,可显示详细下载状态信息 [x] 繁体版页面支持 [x] 书架增强 [x] 书架整合 [x] 书架重命名 [x] 自动推书界面整合 [x] 自动推书界面 [x] 自动推书功能未启用时不显示其界面 [o] 自动推书 [o] 页面美化* [x] 通用页面美化* [x] 背景图 [x] 半透明遮罩层 [x] 遮罩层高斯模糊 [x] 兼容深色模式,深色模式和浅色模式分别存储两套遮罩颜色、模糊程度、不透明度 [o] 书评页面美化 [x] 书评页面内容宽度平齐* [D] 书评页面美化后保留美化前scroll状态 [o] 阅读页美化* [x] 阅读页美化正文居中(可选)* [x] 双击alertify和SidePanel不再自动滚屏* [D] 阅读页美化正文宽度可调* [x] 繁体版页面支持 [D] 页面内调节面板,实时应用修改 [x] 阅读增强 [x] 更多字体颜色 [x] 更多字体大小 [x] 更多字体 [x] 繁体版页面支持 [x] 翻页键支持 [x] 去广告 [x] 繁体版页面支持 [x] 未登录自动跳转首页 [o] 图床* [o] 图床加载框架 [x] 基础框架 [x] 图床自动选择机制 [x] 上传时评分排序 [x] 上传后记录结果 [x] 图床返回url自动encodeURI [D] 用户手动选择图床机制 [x] 设置图片上传组件 [x] 选择图片 [x] 上传图片 [x] 清空图片 [o] 图床 [x] 搜狗图床 [D] 360图床 [x] 流浪图床 [x] 稍后再读* [x] 首页稍后再读书籍列表* [x] 书介绍页加入/移出按钮 [x] 用户手动顺序调整* [x] 繁体版页面支持 [x] 首页点击X移除稍后再读* [x] 书籍信息复制 [x] 书籍tag跳转 [o] 侧边栏 [x] 侧边栏框架 [o] 侧边栏默认svg* [D] svg一直展示到fa显示出来再隐藏 [x] 深色模式* [x] 主页 [x] 书架 [x] 书页 [x] 阅读 [x] 目录 [x] 评论 [x] bbcode [x] 评论编辑 [x] 评论列表 [x] 排行榜 [x] tags [x] 书评吐槽 [x] 用户页面 [x] 用户主页 [x] 用户面板 [x] 用户编辑 [x] 修改密码 [x] 设置头像 [x] 用户好友 [x] 用户链接 [x] 短消息 [x] 收件箱 [x] 发件箱 [x] 写新消息 [x] 登录页面 [x] 跳转api页面 [x] 设置界面 [x] UBBEditor menu [x] 右上角提示框 [x] 文库dialog弹窗 [x] 其他页面 [x] https://www.wenku8.net/other/jubao.php [x] https://www.wenku8.net/other/help.php [x] tippy适配 [x] 页面美化适配 [D] 在线阅读历史记录 [o] 账号切换 [x] 顶栏账号切换 [x] 账号自动录入 [x] 账号管理 [o] 书评草稿 [x] 书评草稿自动保存和加载 [x] 书评草稿管理 [o] 书评增强 [x] 引用 [x] 引用 [x] 仅引用楼号 [D] @ [x] 链接图片增强* [x] 支持https链接 [x] 自动encodeuri [x] 格式检查 [x] 本地图片插入 [x] 界面点击上传 [x] 拖动上传 [x] 粘贴上传 [x] 插入图片保持光标位置* [x] 自适应高度的编辑器* [x] 书评回复标题 [o] 书评下载保存 [x] 基本书评下载 [x] BBCode书评下载 [x] json格式导出* [D] 保存书评为带图片的格式* [o] 书评收藏* [x] 收藏/取消收藏 [o] 首页展示 [o] 防止文本溢出 [x] 拖动调整顺序 [ ] “更多”按钮和管理界面 [ ] 备注 [x] 默认收藏:文库导航姬 [x] 换页不刷新* [x] 页面内书评编辑 [x] UBBEditor编辑器支持* [x] 应用UBBEditor增强功能* [x] 链接跳转 [D] 旧版页面[img]*.(jpg|png)[/img]加载* [x] 繁体版页面支持 [x] 自动刷新* [x] 页面回复后仍在当前页面* [x] 后台提交回复并根据文库返回页面热更新当前页面 [x] 返回没有重定向的错误页面,显示错误信息并保留编辑器内容 [x] 返回带重定向的书评编辑成功页面,更新页面内容到当前page [x] 返回书评第一页,更新页面内容到last page [x] Ctrl+Enter提交表单 [x] Ctrl+Enter提交表单 [x] Command+Enter提交表单 [x] 去除Windows+Enter提交表单 [x] 按钮提示文本 [x] 表单格式检查 [x] 不要空回复 [x] 内容长度≥7 [ ] tag搜索 [x] 脚本执行时间提前 [-] X浏览器支持 [ ] 旧版配置自动导入 */ (function __MAIN__() { 'use strict'; // Constances const CONST = { TextAllLang: { DEFAULT: 'zh-CN', 'zh-CN': { Loader: { CheckerError: 'Checker Error', CheckerInvalid: 'Checker Invalid' } } }, Config_Ruleset: { 'version-key': 'config-version', 'ignores': ["LOCAL-CDN"], 'defaultValues': { //'config-key': {}, funcs: {}, debug: [] }, 'updaters': { /*'config-key': [ function() { // This function contains updater for config['config-key'] from v0 to v1 }, function() { // This function contains updater for config['config-key'] from v1 to v2 } ]*/ }, 'globalUpdaters': [ function(config) { //config } ] } }; // Init language const i18n = Object.keys(CONST.TextAllLang).includes(navigator.language) ? navigator.language : CONST.TextAllLang.DEFAULT; CONST.Text = CONST.TextAllLang[i18n]; // Functions const Functions = [ // Test { name: '测试函数', description: '用于调试功能加载器以及脚本环境是否正常', id: 'test', system: false, data: { load: false, storage: false, manager: false, makeerror: false, errortype: 'setTimeout', log: [], allowdebug: unsafeWindow.isPY_DNG && unsafeWindow.userscriptDebugging, Config_Ruleset: { 'version-key': 'config-version', 'ignores': ["LOCAL-CDN"], 'defaultValues': {}, 'updaters': { /*'config-key': [ function() { // This function contains updater for config['config-key'] from v0 to v1 }, function() { // This function contains updater for config['config-key'] from v1 to v2 } ]*/ } } }, checker: { type: 'switch', value: true }, func: function() { //['message', 'success', 'warning', 'error'].forEach(type => alertify.notify(type, type, 0)); // alertify notifier test // Function load if (FuncInfo.data.load) { DoLog(LogLevel.Success, '测试函数启动了!'); } // Basic storage if (FuncInfo.data.storage) { GM_setValue('test', true); DoLog(`读取test存储项的结果为${GM_getValue('test', 'default text')}`); DoLog(`读取unset存储项的结果为${GM_getValue('unset', 'default text')}`); } // Config Manager if (FuncInfo.data.manager) { const CM = new ConfigManager(FuncInfo.data.Config_Ruleset); const CONFIG = CM.Config; GM_setValue('testobj', {prop: 'value'}); DoLog(`Object.keys(CONFIG).length = ${Object.keys(CONFIG).length}`); DoLog(`Object.keys(CONFIG.testobj) = ${Object.keys(CONFIG.testobj)}`); } // Error dealing if (FuncInfo.data.makeerror) { switch (FuncInfo.data.errortype) { case 'error': Err('An error occured!'); break; case 'setTimeout': setTimeout(function() {Err('An error occured!')}, 0); break; case 'setTimeout_arrow': setTimeout(() => Err('An error occured!'), 0); break; } } if (FuncInfo.data.log && FuncInfo.data.log.length) { FuncInfo.data.log.forEach(v => console.log(v)); } // Debug object if (FuncInfo.data.allowdebug) { Object.defineProperty(unsafeWindow, 'wd', { get: function() { // Leave a reference here so debugger a will be able to access them [require, FuncInfo, isWenkuFunction, Messager, FL_listFunctions, FL_getFunction, FL_enableFunction, FL_disableFunction, FL_loadSetting, FL_postMessage, FL_recieveMessage]; [LogLevel, DoLog, Err, $, $All, $CrE, $AEL, $$CrE, addStyle, detectDom, destroyEvent, copyProp, copyProps, parseArgs, escJsStr, replaceText, getUrlArgv, dl_browser, dl_GM, AsyncManager]; [ConfigManager, $URL, GreasyFork]; [tippy, alertify, Sortable, vkbeautify, Darkmode, CryptoJS]; debugger; return 'wenku8+ debugger: just hit "wd" and return'; }, configurable: true, enumerable: false, }); } return { log() {DoLog('Debug function log')}, number: 1, boolean: true, 'null': null, 'NaN': NaN, 'undefined': undefined, arr: [0, 1, 2], obj: {} } } }, // Common Style { name: 'CommonStyle', description: '基本组件 - 样式管理器', id: 'CommonStyle', system: true, checker: { type: 'switch', value: false }, func: function() { const Assets = { ClassName: { Button: 'plus_button', Text: 'plus_text', TextLight: 'plus_text_light', Disabled: 'plus_disabled' }, Color: { Text: 'rgb(30, 100, 220)', TextLight: 'rgb(70, 150, 230)', Button: 'rgb(0, 160, 0)', ButtonHover: 'rgb(0, 100, 0)', ButtonFocus: 'color: rgb(0, 100, 0)', ButtonDisabled: 'rgba(150, 150, 150)', } }; // Add assets style Assets.ElmStyle = addStyle( `.${Assets.ClassName.Text} {color: ${Assets.Color.Text} !important;}` + `.${Assets.ClassName.TextLight} {color: ${Assets.Color.TextLight} !important;}` + `.${Assets.ClassName.Button} {color: ${Assets.Color.Button} !important; fill: ${Assets.Color.Button} !important; cursor: pointer !important; user-select: none;}` + `.${Assets.ClassName.Button}:hover {color: ${Assets.Color.ButtonHover} !important; fill: ${Assets.Color.ButtonHover} !important;}` + `.${Assets.ClassName.Button}:focus {${Assets.Color.ButtonFocus} !important; fill: ${Assets.Color.ButtonFocus} !important;}` + `.${Assets.ClassName.Button}.${Assets.ClassName.Disabled} {color: ${Assets.Color.ButtonDisabled} !important; fill: ${Assets.Color.ButtonDisabled} !important; cursor: not-allowed !important;}` + `.tippy-box[data-theme~="wenku_tip"] {background-color: #f0f7ff;color: black;border: 1px solid #a3bee8;}.tippy-box[data-theme~="wenku_tip"][data-placement^="top"]>.tippy-arrow::before {border-top-color: #a3bee8;}.tippy-box[data-theme~="wenku_tip"][data-placement^="left"]>.tippy-arrow::before {border-left-color: #a3bee8;}.tippy-box[data-theme~="wenku_tip"][data-placement^="right"]>.tippy-arrow::before {border-right-color: #a3bee8;}.tippy-box[data-theme~="wenku_tip"][data-placement^="bottom"]>.tippy-arrow::before {border-bottom-color: #a3bee8;}` , 'plus-commonstyle-assets' ); // Add common style addStyle(`#dialog{z-index: 1600 !important;} #mask{z-index: 1500 !important;}`, 'plus-commonstyle-style'); return Assets; } }, // FontAwesome { name: 'FontAwesome', description: '基本组件 - FontAwesome(图标)', id: 'FontAwesome', system: true, func: function() { const urls = [ 'https://fastly.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.5.1/css/all.min.css', 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css', 'https://bowercdn.net/c/Font-Awesome-6.4.0/css/all.min.css', 'https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.5.1/css/all.min.css', ]; const timeout = 15 * 1000; let i = 0, loaded = false, tid; const link = $$CrE({ tagName: 'link', props: { href: urls[i], rel: 'stylesheet' }, listeners: [ ['error', changeSource], ['load', onload] ] }); tid = setTimeout(changeSource, timeout); document.head.appendChild(link); return {link, get loaded() {return loaded;}} function changeSource() { if (++i < urls.length) { clearTimeout(tid); tid = setTimeout(changeSource, timeout); link.href = urls[i]; } else { Err('FontAwesome loading error'); } } function onload(e) { clearTimeout(tid); loaded = true; FL_postMessage('FontAwesomeLoaded'); } } }, // Alertify { name: 'alertify', description: '基本组件 - alertify(对话框/信息栏)', id: 'alertify', system: true, func: function() { addStyle(GM_getResourceText('alertify-css'), 'plus-alertify-css'); addStyle(GM_getResourceText('alertify-theme'), 'plus-alertify-theme'); alertify.set('notifier','position', 'top-right'); } }, // Tippy { name: 'tippy', description: '基本组件 - tippy(浮动提示框)', id: 'tippy', system: true, func: function() { addStyle(GM_getResourceText('tippy-css'), 'plus-tippy-css'); } }, // Utils { name: '常用函数库', description: '脚本常用函数库', id: 'utils', system: true, checker: { type: 'switch', value: false }, func: function() { return {getLang, getDocument, parseDocument, downloadText, setPageUrl, htmlEncode, htmlDecode, detectDom, randstr, randint, insertText, openDialog, refreshPage, testChecker, submitForm, formEncode, loadFuncs, encrypt, decrypt, getOS, getTime, deepClone}; // Get language: 0 for simplyfied chinese and others, 1 for traditional chinese function getLang() { const match = document.cookie.match(/(; *)?jieqiUserCharset=(.+?)( *;|$)/); const nvgtLang = ({'zh-CN': 0, 'zh-TW': 1})[navigator.language] || 0; return match && match[2] ? (match[2].toLowerCase() === 'big5' ? 1 : 0) : nvgtLang; } // Download and parse a url page into a html document(dom). // when xhr onload: callback.apply(null, [dom, ...args]) // Usage: getDocument({url, callback[, onerror][, args]}) | getDocument(url, callback) | getDocument(url, callback, args) | getDocument(url, callback, onerror, args) function getDocument() { const [url, callback, onerror, args] = parseArgs([...arguments], [ function(args, defaultValues) { const arg = args[0]; return ['url', 'callback', 'onerror', 'args'].map((prop, i) => arg.hasOwnProperty(prop) ? arg[prop] : defaultValues[i]); }, [1, 2], [1, 2, 4], [1, 2, 3, 4] ], ['', function() {}, logError, []]); GM_xmlhttpRequest({ method : 'GET', url : url, responseType : 'blob', timeout : 15 * 1000, onload : function(response) { const htmlblob = response.response; parseDocument(htmlblob, callback, args); }, onerror : onerror, ontimeout : onerror }); function logError(e) { DoLog(LogLevel.Error, 'getDocument: Request Error'); DoLog(LogLevel.Error, e, 'error'); } } function parseDocument(htmlblob, callback, args=[]) { const reader = new FileReader(); reader.onload = function(e) { const htmlText = reader.result; const dom = new DOMParser().parseFromString(htmlText, 'text/html'); args = [dom].concat(args); callback.apply(null, args); //callback(dom, htmlText); } const charset = ['GBK', 'BIG5'][getLang()]; reader.readAsText(htmlblob, charset); } // Save text to textfile function downloadText(text, name) { if (!text || !name) {return false;}; // Get blob url const blob = new Blob([text],{type:"text/plain;charset=utf-8"}); const url = URL.createObjectURL(blob); // Create and download const a = $CrE('a'); a.href = url; a.download = name; a.click(); } // Change location.href without reloading using history.pushState/replaceState // Usage: setPageUrl(url) | setPageUrl(win, url) | setPageUrl(win, url, push) function setPageUrl() { const [win, url, push] = parseArgs([...arguments], [ [2], [1,2], [1,2,3] ], [window, '', false]); return win.history[push ? 'pushState' : 'replaceState']({modified: true, ...history.state}, '', url); } // Encode text into html text format function htmlEncode(text) { const span = $CrE('div'); span.innerText = text; return span.innerHTML; } // Decode html format text into pure text function htmlDecode(text) { const span = $CrE('div'); span.innerHTML = text; return span.innerText; } // Returns a random string function randstr(length=16, cases=true, aviod=[]) { const all = 'abcdefghijklmnopqrstuvwxyz0123456789' + (cases ? 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' : ''); while (true) { let str = ''; for (let i = 0; i < length; i++) { str += all.charAt(randint(0, all.length-1)); } if (!aviod.includes(str)) {return str;}; } } function randint(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } // Insert into