// ==UserScript== // @name 【移动端】MT论坛优化 // @namespace https://github.com/WhiteSevs/TamperMonkeyScript // @version 2025.10.21 // @author WhiteSevs // @description MT论坛效果增强,如自动签到、自动展开帖子、滚动加载评论、显示UID、自定义屏蔽、手机版小黑屋、编辑器优化、在线用户查看、便捷式图床、自定义用户标签、积分商城商品上架提醒等 // @license GPL-3.0-only // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAAAXNSR0IArs4c6QAADptJREFUeF7tnQtwVNUZx/9nN5CQgCG8QoAdE3lFeWQDGAK+ikKCQGtHBHlJQeVRrTICJQUrgggkUhiRdIRgyBahpThWEHAob6mCVCApCIUQGiDKK0ACEUMMe2/n3E1Ckt279557d+8mN+fMMJlhv/Od7/vO737ncc+eJdBRLuRfSAbwa0JIogjRrkNVvapKQA6JEL8iVrLSZrPl1SvjaxlLtBp/Pv/8LEJImtb6ZqlHCHnddr9tRX31RxMA+fn5v7AS69766rSv7XaKzgExMTH7fK3XCH3MAJw6dapZaHDoYRB0McLAetGGiFxbtK0HIeTnemFvNSOZAfDV03/rjgWzt7RFeIgTc5IK0TRYMDR2RaVWLNrRGoJAMOPJa2gXXq6rfafojImJiTmnS0kAKjMDcOHchRkA/qTX1vzrjfHHbZGSmqcfKsG4PsV6VTLV/+DLljh0PlSq89rj15EY/RNT/drCFlj6d4jucFCXkgBUZgbgfP75eYSQt/XaKorA/O1tcKYwGFaLiN8+cgP9YvR1glqbjn7fBEv3tJLEI0KdWDjsMsJD9GWg+joPCBgANPh3BYJpn0ahuNSKmJY/45VHbyim4uu3rbh2OwiVf0MbCWgZ5kSrsLvS39DG3jvy8q0g/GFLW5Q7Ce4LEfD6E9fwYGSZWnZk5TgAGkN4pKAJlu11PY2Pd7yNKY/cqKHp++JGOH4xBMcq/ik1Q8fy3rZSdI8qQ2xkGYIsYo0qqbtaS/poGdunGEMeKlFSqepzDoCqMHkWchyKwM7TTaUPX3i4GIMfLMGXeWHYk9sUedcaa9Yc3sSJPrZSJMX+iA7Ny7ExOxybj98n6esf8xNefey6Zt21K3IAdIZy5qYoXLoVhLDGAlqFOXG+qJFOjfeqBweJUprP+cH15EfddxcLhl5Bk0b6xv3qBnIAdHYXTcs0PRtRUgYWome7Oz5tigOgI5wFxY2Qvr8l6HhvRHms421MrTXX0NsuB0BjBOlanK7JjS50srjkmcs+a5YDoCGUW080w9+ONNdQ0zdV6HwjY9QPPlFGAYg+E1MMCy6RgbjiE6UGKAnYPgCd5WccaGGAi96bSLi/FNOeuKbbjjYFY38MLv3atZQRcQwWfI5ywUGG4Kxu5X5UEBAAvrsUgrRdrSHUXKL70U3vqod1K8Ho3vq2otsUjEJw6Tc1GxJRAoIsEMFBBiE7YA56aTggANB3APRdQF0qLyUW4ckuP2o2ySMANbU5AMFBkvCl5kb8UNFwAOjmTuY3EbKuPB4LJHYCmoYAl4uBHceBPI0jarf2wFPdAVtL4FwhsOUocEFm74duRb87VGNDAFQAUOGz+BlESxZJdm7xQ38yqzQcAG9P//AEYBo9ZFatOAXgpdXA/66y+dbDBvx5Qs065U5gdDpw9ZZnXXqygHoAKtsWd8NiySIDnevZPPOttKEAKD39ayYDnVxviGuUj78CVjOeP0r5JTDUwynFVXuA9V97DqKeLMAOQKUN5FuIogPNhCzSH6W+7V5lbYYC8PYXkV739jdPByLC3I3+IgdIZUyYaaOAfp3ddX36LbB8u3xgXnn0Oh55gP21tHYAKmwhOA0BDliFLCOXkYYBQHf5Uj5v6xXJzElAZw8ia/8FfMR44k4uA2TsAdbJZABqHO18CgFr0Q3AvQYvAXBIS8ihyGW1g1XeMAB2nGqKv/xbfvJHDX+mNzBjSE0X7pQDL38EXGBcqneMdM0BQqstNgpLgEkfATe8TPbp0bRVz7NvDvkQgMoA3JZAcK0cDrN2rFp5wwB4959t8N8rwYp20RVA344Vq4CbwM7j8jN3JWVRzYHBcS4pQQA2HQFuqsjuWl4W+QGA6u59DNHiIMl39yj5zPq5IQDQ0zcT1ndgtS1g8r/qfgvP97rJ1L6fAXDZQsTNECgIzk1MxnkRNgQAegxrxqYoX9nsdz1aDosYAkCV5+I+EEsWGeRcqzcYhgBAt34X7zTmXb/egND6XduUYe5gto0HYwGo8FLEUViQhSDBQQZA0zamIQDUlRc/auGgh0s/GH5RrbgkFxAA7lmYBxEOECGLJIHJcEMAUDsBZIq4n4XXjy9gaiHAAFTaStOWA6KQRZJxSo0DHgHo2bNnDCHEwzYKMHny5Bc6tO8wTo3ySpl//CccuYX+efkjlpcAZUWwtn4YljAbYPHNqaJ6CkBlyOl5NwqCgyTjkLe+qgGA3W5/GcBqls6tU7LWEDR+YCSCe7yh26x6DsA9/0X8FZCWkDs9BaUKALvdvhXAUN2RqwMKLOGdEfbkBoBYNFtjGgDurRw+hyj+jiSjxtgmAWC326cBeF9ztOpgRWubRIT2/0DzkGA+ACo6ySJ0IwNxsrLLKgGoI2dzfEtSUNQTaJKQClhd3wdgKaYFADhBkoTuVQDExcUlEEK8ThRYAlfXZIPaPoqQhFSQIA+vGb0Ya2IA6JnF+SRZmEfdJ3FxcS8SQjLrWsf50p6gyH4uCBq5vhamppgaAIK1ZJDwmwYDAHXU2joBTRLSQILVHUM3NQAQ95EkcUCDAkCCoFVvFwQhyl9EMTUADW0IqJ7yrS3tLgiatPE6EpgaAJBnSZLzswaXASp73NqiB0IS0mAJlX9DaWIAvkMjIZ4MwN0GC4A0HEQ85IIgzPM5BdMCIOL3JFmouuOpQawC5HK9pdkDCI5LgSWsvZvI+8/So3nqS8tLr6PxnTr55R/JifYtpBvsvq94+qsO2DVoANR3rzkku9t+OvldQeirOTk5VUdsOQDm6FsmLwgh6dnZ2a816DkAU8RMKEwIGZ2dnb2BZwATdq5Klw7l5OQkUgDmEkLmq6zExUwUAUEQYikAmYSQF03kF3dFZQQIIWMoAGsIIRNV1uFiJoqAKIovcABM1KGsrnAAWCNmMnkOgMk6lNUdDgBrxEwmzwEwWYeyusMBYI2YyeQ5ACbrUFZ3OACsETOZvF8AWL3a+zfLrl69ijfffFNzKMeMGYMBA6TzjLJl0qRJmvV7q6jkm18araV01apVOHzYNzfG+AWA7GzlQxFvvfUWtm6l30RjK507d8bGjRsVK8XHxyvKaBFQ45sWvSx1KNz1HoCSkhI899xzoNmApWRmZqJXr16KVTgAiiGSBAKWAWjjO3bsQEpKijpLAUydOhVTpkxRJc8BUBWmwAJATZw3bx42b96saG3fvn2xcuVKRblKAQ6AulAFNANQE0tLS0EndefOyf/iarNmzZCVlYWOHTuq8woAB0BdqAIOADVz9+7dmDlzpqzFdJgYNWqUOo8qpIwGQGlS1qdPHzf7tdShSkwxCawdjbS0NGzYsMEtSEOGDMHChQuZOp8KGw0AHZ7o8sxToUtHOQDklqt0rkPnPJ5KvQWgrKwMwcGebwotLy/HhAkTcPJk1b0FiI6ORkZGBlq39ny9nDd9HAB1z4yhQwB9SuSopubu378f06bRi0pcJTU1FcnJtX48oJpf3vT5C4Bt27ahXbt2btGdP38+Nm3yfHmnlgwwduxY2WFx9OjROHVK1QVgihQYDkCLFi0wcuRIWcNWrFiBNWvWYPz48XjjDfmLnuhm0I0bN2SB8hcAnuYjd+7cwcSJE2U7RQsAiYmJ+PDDD93idPHiRQwfPhy0TV8UwwGg4+Qnn3yCTp06ebRfEARprZ+eni47XOTl5WHEiBGSnFxG8RcAbdu2xZIlS9C9e9UNK9LyVG78p05qAYDWq+0fXSktX74c+/Yx3pvvhZSAANCtWzesW7dO1iw6O/Y0aaqsMG7cOJw4cSIgAFAb6DyGDk0RERE4c+YMDhw44PVh1AoAVdq/f3/Q7e+ioiJpiCwu1vfLZrUNDQgA1AjaiTNmzGDOYkuXLq2CJxAZgNlgHRlAS1usdQIGADV02bJlim/1qju0d+9eTJ8+veq/OACs3e0uH1AAbDYb1q5di+bNle/soamPTgwLCu7dccgBqOcAUPOHDRuGBQsWKHri6fUxB0AxbIoCAc0AldbNmTNHmtXLFbpqWLRokdvHHADF/lUUqBMAhIeHSzt+Xbp0cTM4NzeX3k6Omzfdf76FA6DYv4oCdQIAaqWWpRIHQLF/FQU4AIoh0i+gBW79rarTUGcAoO8A6Mug2sXhcEi7X54KzwDqOtmbVJ0BgBrp6cClty1dDoDJAKDu0N3B2NhY6cUK3fXzVjgAJgSAxSUOAEu0PMvWqSGA1R0OAGvE3OU5APpjqKiBrwIqQqT03lwxkrUEeAZgjRjPAPojpkEDzwA8AzCfCtbAmaYqfA6gKWxslXgG4BmAZwDKAJ8E1swc9Oyjv+4xUJuj+BCgNlI65PgQwIcAPgTwIcDzl0P5EKAjtfKNIB3Bq6jK5wD6Y6iogc8B+ByAzwH4HIDPAfg+QK3Bgu8DKI6e3gX4JFBnAI2+Jo7vBPKdQK/fo2flmWcA1ojx8wD6I6ZBA18G8mUgXwbyZSBfBvJlIF8Ger9MiXV45ZNA1ogZNAmkN3527drVrbXZs2dj+/bt+q2u0DB48GAsXrzYTd/p06eZr5b1mVEeFMlddUvjRG9IDWTxy8sgT09mYWEhkpKSfO4rvXK+9k2ivt5v0Gs0vfHM0y+N+PLKV602+gUAasygQYOka9wiIyNx8OBBzJo1S6uNivXee+899OvXD1euXJH2GXbu3KlYx2gBetP53Llz0bNnTxw7dgzvvPMOzp49a7QZbu35DYCAe8YNUBUBDoCqMJlXiANg3r5V5RkHQFWYzCvEATBv36ryjAOgKkzmFeIAmLdvVXnGAVAVJvMKcQDM27eqPOMAqAqTeYU4AObtW1WecQBUhcm8QhIAdrs9HcCr5nWTeyYXAULICBIfH/+UKIq7eJgaXgQIIdGEum2324sAKP92S8OLkZk93pWTkzNIAiAuLm4+IWSumb3lvtWMgMViefro0aPbJQBoiY+P3y6KovxvtfIImiYChJDZ2dnZqdShKgAqMsEAQgg9aNcbQJBpPOaO0AicB/B3q9WaceTIkarjSP8HC+OZoHXD4j8AAAAASUVORK5CYII= // @supportURL https://github.com/WhiteSevs/TamperMonkeyScript/issues // @match *://bbs.binmt.cc/* // @exclude /^http(s|)://bbs.binmt.cc/uc_server.*$/ // @require https://fastly.jsdelivr.net/gh/WhiteSevs/TamperMonkeyScript@86be74b83fca4fa47521cded28377b35e1d7d2ac/lib/CoverUMD/index.js // @require https://fastly.jsdelivr.net/gh/WhiteSevs/TamperMonkeyScript@79fb4d854f1e2cdf606339b0dac18d50104e2ebe/lib/js-watermark/index.js // @require https://fastly.jsdelivr.net/npm/@whitesev/utils@2.9.4/dist/index.umd.js // @require https://fastly.jsdelivr.net/npm/@whitesev/domutils@1.7.4/dist/index.umd.js // @require https://fastly.jsdelivr.net/npm/@whitesev/pops@2.6.0/dist/index.umd.js // @require https://fastly.jsdelivr.net/npm/qmsg@1.5.0/dist/index.umd.js // @require https://fastly.jsdelivr.net/npm/viewerjs@1.11.7/dist/viewer.min.js // @require https://fastly.jsdelivr.net/npm/@highlightjs/cdn-assets@11.11.1/highlight.min.js // @resource HljsCSS https://fastly.jsdelivr.net/npm/highlight.js@11.11.1/styles/github-dark.min.css // @resource ViewerCSS https://fastly.jsdelivr.net/npm/viewerjs@1.11.7/dist/viewer.min.css // @connect * // @connect helloimg.com // @connect z4a.net // @connect kggzs.cn // @connect woozooo.com // @grant GM.cookie // @grant GM_deleteValue // @grant GM_getResourceText // @grant GM_getValue // @grant GM_info // @grant GM_listValues // @grant GM_registerMenuCommand // @grant GM_setValue // @grant GM_setValues // @grant GM_unregisterMenuCommand // @grant GM_xmlhttpRequest // @grant unsafeWindow // @run-at document-start // ==/UserScript== (function (Qmsg, DOMUtils, Utils, pops, hljs, Viewer) { "use strict"; var _GM = (() => (typeof GM != "undefined" ? GM : void 0))(); var _GM_deleteValue = (() => (typeof GM_deleteValue != "undefined" ? GM_deleteValue : void 0))(); var _GM_getResourceText = (() => (typeof GM_getResourceText != "undefined" ? GM_getResourceText : void 0))(); var _GM_getValue = (() => (typeof GM_getValue != "undefined" ? GM_getValue : void 0))(); var _GM_info = (() => (typeof GM_info != "undefined" ? GM_info : void 0))(); var _GM_listValues = (() => (typeof GM_listValues != "undefined" ? GM_listValues : void 0))(); var _GM_registerMenuCommand = (() => typeof GM_registerMenuCommand != "undefined" ? GM_registerMenuCommand : void 0)(); var _GM_setValue = (() => (typeof GM_setValue != "undefined" ? GM_setValue : void 0))(); var _GM_setValues = (() => (typeof GM_setValues != "undefined" ? GM_setValues : void 0))(); var _GM_unregisterMenuCommand = (() => typeof GM_unregisterMenuCommand != "undefined" ? GM_unregisterMenuCommand : void 0)(); var _GM_xmlhttpRequest = (() => (typeof GM_xmlhttpRequest != "undefined" ? GM_xmlhttpRequest : void 0))(); var _unsafeWindow = (() => (typeof unsafeWindow != "undefined" ? unsafeWindow : void 0))(); var _monkeyWindow = (() => window)(); const CommonUtil = { waitRemove(...args) { args.forEach((selector) => { if (typeof selector !== "string") { return; } DOMUtils.waitNodeList(selector).then((nodeList) => { nodeList.forEach(($el) => $el.remove()); }); }); }, createBlockCSSNode(...args) { let selectorList = []; if (args.length === 0) { return; } if (args.length === 1 && typeof args[0] === "string" && args[0].trim() === "") { return; } args.forEach((selector) => { if (Array.isArray(selector)) { selectorList = selectorList.concat(selector); } else { selectorList.push(selector); } }); return DOMUtils.createElement("style", { type: "text/css", innerHTML: `${selectorList.join(",\n")}{display: none !important;}`, }); }, addBlockCSS(...args) { let selectorList = []; if (args.length === 0) { return; } if (args.length === 1 && typeof args[0] === "string" && args[0].trim() === "") { return; } args.forEach((selector) => { if (Array.isArray(selector)) { selectorList = selectorList.concat(selector); } else { selectorList.push(selector); } }); return addStyle(`${selectorList.join(",\n")}{display: none !important;}`); }, setGMResourceCSS(resourceMapData) { const cssText = typeof _GM_getResourceText === "function" ? _GM_getResourceText(resourceMapData.keyName) : null; if (typeof cssText === "string" && cssText) { return addStyle(cssText); } else { return CommonUtil.loadStyleLink(resourceMapData.url); } }, async loadStyleLink(url) { let $link = document.createElement("link"); $link.rel = "stylesheet"; $link.type = "text/css"; $link.href = url; return new Promise((resolve) => { DOMUtils.ready(() => { document.head.appendChild($link); resolve($link); }); }); }, async loadScript(url) { let $script = document.createElement("script"); $script.src = url; return new Promise((resolve) => { $script.onload = () => { resolve(null); }; (document.head || document.documentElement).appendChild($script); }); }, fixUrl(url) { url = url.trim(); if (url.startsWith("data:")) { return url; } if (url.match(/^http(s|):\/\//i)) { return url; } else if (url.startsWith("//")) { if (url.startsWith("///")); else { url = window.location.protocol + url; } return url; } else { if (!url.startsWith("/")) { url += "/"; } url = window.location.origin + url; return url; } }, fixHttps(url) { if (url.startsWith("https://")) { return url; } if (!url.startsWith("http://")) { return url; } try { let urlInstance = new URL(url); urlInstance.protocol = "https:"; return urlInstance.toString(); } catch { return url; } }, lockScroll(...args) { let $hidden = document.createElement("style"); $hidden.innerHTML = ` .pops-overflow-hidden-important { overflow: hidden !important; } `; let $elList = [document.documentElement, document.body].concat(...(args || [])); $elList.forEach(($el) => { $el.classList.add("pops-overflow-hidden-important"); }); (document.head || document.documentElement).appendChild($hidden); return { recovery() { $elList.forEach(($el) => { $el.classList.remove("pops-overflow-hidden-important"); }); $hidden.remove(); }, }; }, async getClipboardText() { function readClipboardText(resolve) { navigator.clipboard .readText() .then((clipboardText) => { resolve(clipboardText); }) .catch((error) => { log.error("读取剪贴板内容失败👉", error); resolve(""); }); } function requestPermissionsWithClipboard(resolve) { navigator.permissions .query({ name: "clipboard-read", }) .then((permissionStatus) => { readClipboardText(resolve); }) .catch((error) => { log.error("申请剪贴板权限失败,尝试直接读取👉", error.message ?? error.name ?? error.stack); readClipboardText(resolve); }); } function checkClipboardApi() { if (typeof navigator?.clipboard?.readText !== "function") { return false; } if (typeof navigator?.permissions?.query !== "function") { return false; } return true; } return new Promise((resolve) => { if (!checkClipboardApi()) { resolve(""); return; } if (document.hasFocus()) { requestPermissionsWithClipboard(resolve); } else { window.addEventListener( "focus", () => { requestPermissionsWithClipboard(resolve); }, { once: true, } ); } }); }, escapeHtml(unsafe) { return unsafe .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'") .replace(/©/g, "©") .replace(/®/g, "®") .replace(/™/g, "™") .replace(/→/g, "→") .replace(/←/g, "←") .replace(/↑/g, "↑") .replace(/↓/g, "↓") .replace(/—/g, "—") .replace(/–/g, "–") .replace(/…/g, "…") .replace(/ /g, " ") .replace(/\r\n/g, "
") .replace(/\r/g, "
") .replace(/\n/g, "
") .replace(/\t/g, "    "); }, interval(fn, intervalTime, timeout = 5e3) { let timeId; let maxTimeout = timeout - intervalTime; let intervalTimeCount = intervalTime; let loop = async (isTimeout) => { let result = await fn(isTimeout); if ((typeof result === "boolean" && !result) || isTimeout) { utils.workerClearTimeout(timeId); return; } intervalTimeCount += intervalTime; if (intervalTimeCount > maxTimeout) { loop(true); return; } timeId = utils.workerSetTimeout(() => { loop(false); }, intervalTime); }; loop(false); }, findParentNode($el, selector, parentSelector) { if (parentSelector) { let $parent = DOMUtils.closest($el, parentSelector); if ($parent) { let $target = $parent.querySelector(selector); return $target; } } else { if (DOMUtils.matches($el, selector)) { return $el; } let $parent = DOMUtils.closest($el, selector); return $parent; } }, toStr(data) { const undefinedReplacedStr = `__undefined__placeholder__replaced__str__`; const dataStr = JSON.stringify( data, (key, value) => { return value === void 0 ? undefinedReplacedStr : value; }, 2 ).replace(new RegExp(`"${undefinedReplacedStr}"`, "g"), "undefined"); return dataStr; }, }; const GM_RESOURCE_MAPPING = { Viewer: { keyName: "ViewerCSS", url: "https://fastly.jsdelivr.net/npm/viewerjs@latest/dist/viewer.min.css", }, Hljs: { keyName: "HljsCSS", url: "https://fastly.jsdelivr.net/npm/highlight.js@latest/styles/github-dark.min.css", }, }; const PanelSettingConfig = { qmsg_config_position: { key: "qmsg-config-position", defaultValue: "bottom", }, qmsg_config_maxnums: { key: "qmsg-config-maxnums", defaultValue: 3, }, qmsg_config_showreverse: { key: "qmsg-config-showreverse", defaultValue: false, }, httpx_cookie_manager_enable: { key: "httpx-use-cookie-enable", defaultValue: false, }, httpx_cookie_manager_use_document_cookie: { key: "httpx-use-document-cookie", defaultValue: false, }, }; const utils = Utils.noConflict(); const domUtils = DOMUtils.noConflict(); const __pops = pops; const log = new utils.Log(_GM_info, _unsafeWindow.console || _monkeyWindow.console); let SCRIPT_NAME = _GM_info?.script?.name || void 0; const AnyTouch = pops.config.Utils.AnyTouch(); const DEBUG = false; log.config({ debug: false, logMaxCount: 250, autoClearConsole: true, tag: true, }); Qmsg.config({ isHTML: true, autoClose: true, showClose: false, consoleLogContent(qmsgInst) { const qmsgType = qmsgInst.getSetting().type; if (qmsgType === "loading") { return false; } const content = qmsgInst.getSetting().content; if (qmsgType === "warning") { log.warn(content); } else if (qmsgType === "error") { log.error(content); } else { log.info(content); } return true; }, get position() { return Panel.getValue( PanelSettingConfig.qmsg_config_position.key, PanelSettingConfig.qmsg_config_position.defaultValue ); }, get maxNums() { return Panel.getValue( PanelSettingConfig.qmsg_config_maxnums.key, PanelSettingConfig.qmsg_config_maxnums.defaultValue ); }, get showReverse() { return Panel.getValue( PanelSettingConfig.qmsg_config_showreverse.key, PanelSettingConfig.qmsg_config_showreverse.defaultValue ); }, get zIndex() { let maxZIndex = Utils.getMaxZIndex(); let popsMaxZIndex = pops.config.InstanceUtils.getPopsMaxZIndex().zIndex; return Utils.getMaxValue(maxZIndex, popsMaxZIndex) + 100; }, }); __pops.GlobalConfig.setGlobalConfig({ zIndex: () => { let maxZIndex = Utils.getMaxZIndex(void 0, void 0, ($ele) => { if ($ele?.classList?.contains("qmsg-shadow-container")) { return false; } if ($ele?.closest("qmsg") && $ele.getRootNode() instanceof ShadowRoot) { return false; } }); let popsMaxZIndex = pops.config.InstanceUtils.getPopsMaxZIndex().zIndex; return Utils.getMaxValue(maxZIndex, popsMaxZIndex) + 100; }, mask: { enable: true, clickEvent: { toClose: false, toHide: false, }, }, drag: true, }); const GM_Menu = new utils.GM_Menu({ GM_getValue: _GM_getValue, GM_setValue: _GM_setValue, GM_registerMenuCommand: _GM_registerMenuCommand, GM_unregisterMenuCommand: _GM_unregisterMenuCommand, }); const httpx = new utils.Httpx({ xmlHttpRequest: _GM_xmlhttpRequest, logDetails: DEBUG, }); httpx.interceptors.request.use((data) => { return data; }); httpx.interceptors.response.use(void 0, (data) => { log.error("拦截器-请求错误", data); if (data.type === "onabort") { Qmsg.warning("请求取消", { consoleLogContent: true }); } else if (data.type === "onerror") { Qmsg.error("请求异常", { consoleLogContent: true }); } else if (data.type === "ontimeout") { Qmsg.error("请求超时", { consoleLogContent: true }); } else { Qmsg.error("其它错误", { consoleLogContent: true }); } return data; }); ({ Object: { defineProperty: _unsafeWindow.Object.defineProperty, }, Function: { apply: _unsafeWindow.Function.prototype.apply, call: _unsafeWindow.Function.prototype.call, }, Element: { appendChild: _unsafeWindow.Element.prototype.appendChild, }, setTimeout: _unsafeWindow.setTimeout, }); const addStyle = domUtils.addStyle.bind(domUtils); const $ = DOMUtils.selector.bind(DOMUtils); const $$ = DOMUtils.selectorAll.bind(DOMUtils); new utils.GM_Cookie(); const KEY = "GM_Panel"; const ATTRIBUTE_INIT = "data-init"; const ATTRIBUTE_KEY = "data-key"; const ATTRIBUTE_DEFAULT_VALUE = "data-default-value"; const ATTRIBUTE_INIT_MORE_VALUE = "data-init-more-value"; const PROPS_STORAGE_API = "data-storage-api"; const PanelSizeUtil = { get width() { return globalThis.innerWidth; }, get height() { return globalThis.innerHeight; }, }; const PanelUISize = { setting: { get width() { if (PanelSizeUtil.width < 550) { return "88vw"; } else if (PanelSizeUtil.width < 700) { return "550px"; } else { return "700px"; } }, get height() { if (PanelSizeUtil.height < 450) { return "70vh"; } else if (PanelSizeUtil.height < 550) { return "450px"; } else { return "550px"; } }, }, settingMiddle: { get width() { return PanelSizeUtil.width < 350 ? "88vw" : "350px"; }, }, info: { get width() { return PanelSizeUtil.width < 350 ? "88vw" : "350px"; }, get height() { return PanelSizeUtil.height < 250 ? "88vh" : "250px"; }, }, }; class StorageUtils { storageKey; listenerData; constructor(key) { if (typeof key === "string") { const trimKey = key.trim(); if (trimKey == "") { throw new Error("key参数不能为空字符串"); } this.storageKey = trimKey; } else { throw new Error("key参数类型错误,必须是字符串"); } this.listenerData = new Utils.Dictionary(); this.getLocalValue = this.getLocalValue.bind(this); this.set = this.set.bind(this); this.get = this.get.bind(this); this.getAll = this.getAll.bind(this); this.delete = this.delete.bind(this); this.has = this.has.bind(this); this.keys = this.keys.bind(this); this.values = this.values.bind(this); this.clear = this.clear.bind(this); this.addValueChangeListener = this.addValueChangeListener.bind(this); this.removeValueChangeListener = this.removeValueChangeListener.bind(this); this.triggerValueChangeListener = this.triggerValueChangeListener.bind(this); } getLocalValue() { let localValue = _GM_getValue(this.storageKey); if (localValue == null) { localValue = {}; this.setLocalValue(localValue); } return localValue; } setLocalValue(value) { _GM_setValue(this.storageKey, value); } set(key, value) { const oldValue = this.get(key); const localValue = this.getLocalValue(); Reflect.set(localValue, key, value); this.setLocalValue(localValue); this.triggerValueChangeListener(key, oldValue, value); } get(key, defaultValue) { const localValue = this.getLocalValue(); return Reflect.get(localValue, key) ?? defaultValue; } getAll() { const localValue = this.getLocalValue(); return localValue; } delete(key) { const oldValue = this.get(key); const localValue = this.getLocalValue(); Reflect.deleteProperty(localValue, key); this.setLocalValue(localValue); this.triggerValueChangeListener(key, oldValue, void 0); } has(key) { const localValue = this.getLocalValue(); return Reflect.has(localValue, key); } keys() { const localValue = this.getLocalValue(); return Reflect.ownKeys(localValue); } values() { const localValue = this.getLocalValue(); return Reflect.ownKeys(localValue).map((key) => Reflect.get(localValue, key)); } clear() { _GM_deleteValue(this.storageKey); } addValueChangeListener(key, callback) { const listenerId = Math.random(); const listenerData = this.listenerData.get(key) || []; listenerData.push({ id: listenerId, key, callback, }); this.listenerData.set(key, listenerData); return listenerId; } removeValueChangeListener(listenerId) { let flag = false; for (const [key, listenerData] of this.listenerData.entries()) { for (let index = 0; index < listenerData.length; index++) { const value = listenerData[index]; if ( (typeof listenerId === "string" && value.key === listenerId) || (typeof listenerId === "number" && value.id === listenerId) ) { listenerData.splice(index, 1); index--; flag = true; } } this.listenerData.set(key, listenerData); } return flag; } async triggerValueChangeListener(...args) { const [key, oldValue, newValue] = args; if (!this.listenerData.has(key)) { return; } let listenerData = this.listenerData.get(key); for (let index = 0; index < listenerData.length; index++) { const data = listenerData[index]; if (typeof data.callback === "function") { let value = this.get(key); let __newValue; let __oldValue; if (typeof oldValue !== "undefined" && args.length >= 2) { __oldValue = oldValue; } else { __oldValue = value; } if (typeof newValue !== "undefined" && args.length > 2) { __newValue = newValue; } else { __newValue = value; } await data.callback(key, __oldValue, __newValue); } } } } const PopsPanelStorageApi = new StorageUtils(KEY); const PanelContent = { $data: { __contentConfig: null, get contentConfig() { if (this.__contentConfig == null) { this.__contentConfig = new utils.Dictionary(); } return this.__contentConfig; }, __defaultBottomContentConfig: [], }, addContentConfig(configList) { if (!Array.isArray(configList)) { configList = [configList]; } let index = this.$data.contentConfig.keys().length; this.$data.contentConfig.set(index, configList); }, getAllContentConfig() { return this.$data.contentConfig.values().flat(); }, getConfig(index = 0) { return this.$data.contentConfig.get(index) ?? []; }, getDefaultBottomContentConfig() { if (this.$data.__defaultBottomContentConfig.length) { return this.$data.__defaultBottomContentConfig; } let isDoubleClick = false; let timer = void 0; const exportToFile = (fileName, fileData) => { if (typeof fileData !== "string") { fileData = CommonUtil.toStr(fileData); } const blob = new Blob([fileData]); const blobUrl = globalThis.URL.createObjectURL(blob); const $anchor = domUtils.createElement("a", { href: blobUrl, download: fileName, }); $anchor.click(); utils.workerSetTimeout(() => { globalThis.URL.revokeObjectURL(blobUrl); }, 500); }; const dbclick_callback = () => { const importConfig = (importEndCallBack) => { const $alert = __pops.alert({ title: { text: "请选择导入方式", position: "center", }, content: { text: `
本地导入
网络导入
剪贴板导入
`, html: true, }, btn: { ok: { enable: false }, close: { enable: true, callback(details, event) { details.close(); }, }, }, drag: true, mask: { enable: true, }, width: PanelUISize.info.width, height: PanelUISize.info.height, style: ` .btn-control{ display: inline-block; margin: 10px; padding: 10px; border: 1px solid #ccc; border-radius: 5px; cursor: pointer; } .btn-control:hover{ color: #409eff; border-color: #c6e2ff; background-color: #ecf5ff; }`, }); const $local = $alert.$shadowRoot.querySelector(".btn-control[data-mode='local']"); const $network = $alert.$shadowRoot.querySelector(".btn-control[data-mode='network']"); const $clipboard = $alert.$shadowRoot.querySelector(".btn-control[data-mode='clipboard']"); const updateConfigToStorage = async (data) => { const clearLocalStorage = confirm("是否清空脚本存储的配置?(如果点击取消按钮,则仅做配置覆盖处理)"); if (clearLocalStorage) { if (typeof _GM_listValues === "function") { if (typeof _GM_deleteValue === "function") { const localStorageKeys = _GM_listValues(); localStorageKeys.forEach((key) => { _GM_deleteValue(key); }); Qmsg.success("已清空脚本存储的配置"); } else { Qmsg.error("不支持GM_deleteValue函数,无法执行删除脚本配置"); } } else { Qmsg.error("不支持GM_listValues函数,无法清空脚本存储的配置"); } } if (typeof _GM_setValues === "function") { _GM_setValues(data); } else { const keys = Object.keys(data); keys.forEach((key) => { const value = data[key]; _GM_setValue(key, value); }); } Qmsg.success("配置导入完毕"); }; const importFile = (configText) => { return new Promise(async (resolve) => { const data = utils.toJSON(configText); if (Object.keys(data).length === 0) { Qmsg.warning("解析为空配置,不导入"); } else { await updateConfigToStorage(data); } resolve(true); }); }; domUtils.on($local, "click", (event) => { domUtils.preventEvent(event); $alert.close(); const $input = domUtils.createElement("input", { type: "file", accept: ".json", }); domUtils.on($input, ["propertychange", "input"], (event2) => { if (!$input.files?.length) { return; } const uploadFile = $input.files[0]; const fileReader = new FileReader(); fileReader.onload = () => { importFile(fileReader.result); }; fileReader.readAsText(uploadFile, "UTF-8"); }); $input.click(); }); domUtils.on($network, "click", (event) => { domUtils.preventEvent(event); $alert.close(); const $prompt = __pops.prompt({ title: { text: "网络导入", position: "center", }, content: { text: "", placeholder: "请填写URL", focus: true, }, btn: { close: { enable: true, callback(details, event2) { details.close(); }, }, ok: { text: "导入", callback: async (details, event2) => { const url = details.text; if (utils.isNull(url)) { Qmsg.error("请填入完整的url"); return; } const $loading = Qmsg.loading("正在获取配置..."); const response = await httpx.get(url, { allowInterceptConfig: false, }); $loading.close(); if (!response.status) { log.error(response); Qmsg.error("获取配置失败", { consoleLogContent: true }); return; } const flag = await importFile(response.data.responseText); if (!flag) { return; } details.close(); }, }, cancel: { enable: false, }, }, drag: true, mask: { enable: true, }, width: PanelUISize.info.width, height: "auto", }); const $promptInput = $prompt.$shadowRoot.querySelector("input"); const $promptOk = $prompt.$shadowRoot.querySelector(".pops-prompt-btn-ok"); domUtils.on($promptInput, ["input", "propertychange"], (event2) => { const value = domUtils.val($promptInput); if (value === "") { domUtils.attr($promptOk, "disabled", "true"); } else { domUtils.removeAttr($promptOk, "disabled"); } }); domUtils.listenKeyboard($promptInput, "keydown", (keyName, keyValue, otherCodeList) => { if (keyName === "Enter" && otherCodeList.length === 0) { const value = domUtils.val($promptInput); if (value !== "") { domUtils.trigger($promptOk, "click"); } } }); domUtils.trigger($promptInput, "input"); }); domUtils.on($clipboard, "click", async (event) => { domUtils.preventEvent(event); $alert.close(); let clipboardText = await CommonUtil.getClipboardText(); if (clipboardText.trim() === "") { Qmsg.warning("获取到的剪贴板内容为空"); return; } const flag = await importFile(clipboardText); if (!flag) { return; } }); }; const exportConfig = ( fileName = `${SCRIPT_NAME}_panel-setting-${utils.formatTime(Date.now(), "yyyy_MM_dd_HH_mm_ss")}.json`, fileData ) => { const $alert = __pops.alert({ title: { text: "请选择导出方式", position: "center", }, content: { text: `
导出至文件
导出至剪贴板
`, html: true, }, btn: { ok: { enable: false }, close: { enable: true, callback(details, event) { details.close(); }, }, }, drag: true, mask: { enable: true, }, width: PanelUISize.info.width, height: PanelUISize.info.height, style: ` .btn-control{ display: inline-block; margin: 10px; padding: 10px; border: 1px solid #ccc; border-radius: 5px; cursor: pointer; } .btn-control:hover{ color: #409eff; border-color: #c6e2ff; background-color: #ecf5ff; }`, }); const $exportToFile = $alert.$shadowRoot.querySelector(".btn-control[data-mode='export-to-file']"); const $exportToClipboard = $alert.$shadowRoot.querySelector(".btn-control[data-mode='export-to-clipboard']"); domUtils.on($exportToFile, "click", (event) => { domUtils.preventEvent(event); try { exportToFile(fileName, fileData); $alert.close(); } catch (error) { Qmsg.error(error.toString(), { consoleLogContent: true }); } }); domUtils.on($exportToClipboard, "click", async (event) => { const result = await utils.copy(fileData); if (result) { Qmsg.success("复制成功"); $alert.close(); } else { Qmsg.error("复制失败"); } }); }; const $dialog = __pops.confirm({ title: { text: "配置", position: "center", }, content: { text: ` `, html: true, }, btn: { ok: { enable: true, type: "primary", text: "导入", callback(eventDetails, event) { importConfig(); }, }, cancel: { enable: true, text: "导出", callback(eventDetails, event) { exportConfig(void 0, configDataStr); }, }, }, width: PanelSizeUtil.width < 450 ? "90vw" : "450px", height: "auto", style: ` .pops-content textarea { --textarea-bd-color: #dcdfe6; display: inline-block; resize: vertical; padding: 5px 15px; margin: 0; line-height: normal; box-sizing: border-box; color: #606266; border: 0; border-radius: 0; outline: none; -webkit-appearance: none; -moz-appearance: none; appearance: none; background: none; width: 100%; height: 100%; appearance: none; resize: none; } .pops-content textarea{ height: 500px; } .pops-content textarea:focus { --textarea-bd-color: #3677f0; } .pops-content textarea:hover { --textarea-bd-color: #c0c4cc; } `, }); const $textarea = $dialog.$shadowRoot.querySelector("textarea"); const configData = {}; if (typeof _GM_listValues === "function") { const LocalKeys = _GM_listValues(); LocalKeys.forEach((key) => { const value = _GM_getValue(key); Reflect.set(configData, key, value); }); } else { Qmsg.warning("不支持函数GM_listValues,仅导出菜单配置"); const panelLocalValue = _GM_getValue(KEY); Reflect.set(configData, KEY, panelLocalValue); } const configDataStr = CommonUtil.toStr(configData); $textarea.value = configDataStr; }; const click_callback = () => { let supportURL = _GM_info?.script?.supportURL || _GM_info?.script?.namespace; if (typeof supportURL === "string" && utils.isNotNull(supportURL)) { window.open(supportURL, "_blank"); } }; return [ { id: "script-version", title: `版本:${_GM_info?.script?.version || "未知"}`, isBottom: true, forms: [], clickFirstCallback() { return false; }, afterRender(config) { const anyTouch = new AnyTouch(config.$asideLiElement); anyTouch.on("tap", function (event) { clearTimeout(timer); timer = void 0; if (isDoubleClick) { isDoubleClick = false; dbclick_callback(); } else { timer = setTimeout(() => { isDoubleClick = false; click_callback(); }, 200); isDoubleClick = true; } }); }, }, ]; }, setDefaultBottomContentConfig(config) { this.$data.__defaultBottomContentConfig = config; }, }; const PanelMenu = { $data: { __menuOption: [ { key: "show_pops_panel_setting", text: "⚙ 设置", autoReload: false, isStoreValue: false, showText(text) { return text; }, callback: () => { Panel.showPanel(PanelContent.getConfig(0)); }, }, ], get menuOption() { return this.__menuOption; }, }, init() { this.initExtensionsMenu(); }, initExtensionsMenu() { if (!Panel.isTopWindow()) { return; } GM_Menu.add(this.$data.menuOption); }, addMenuOption(option) { if (!Array.isArray(option)) { option = [option]; } this.$data.menuOption.push(...option); }, updateMenuOption(option) { if (!Array.isArray(option)) { option = [option]; } option.forEach((optionItem) => { let findIndex = this.$data.menuOption.findIndex((it) => { return it.key === optionItem.key; }); if (findIndex !== -1) { this.$data.menuOption[findIndex] = optionItem; } }); }, getMenuOption(index = 0) { return this.$data.menuOption[index]; }, deleteMenuOption(index = 0) { this.$data.menuOption.splice(index, 1); }, }; const Panel = { $data: { __contentConfigInitDefaultValue: null, __onceExecMenuData: null, __urlChangeReloadMenuExecOnce: null, __onceExecData: null, __panelConfig: {}, $panel: null, panelContent: [], get contentConfigInitDefaultValue() { if (this.__contentConfigInitDefaultValue == null) { this.__contentConfigInitDefaultValue = new utils.Dictionary(); } return this.__contentConfigInitDefaultValue; }, contentConfigInitDisabledKeys: [], get onceExecMenuData() { if (this.__onceExecMenuData == null) { this.__onceExecMenuData = new utils.Dictionary(); } return this.__onceExecMenuData; }, get urlChangeReloadMenuExecOnce() { if (this.__urlChangeReloadMenuExecOnce == null) { this.__urlChangeReloadMenuExecOnce = new utils.Dictionary(); } return this.__urlChangeReloadMenuExecOnce; }, get onceExecData() { if (this.__onceExecData == null) { this.__onceExecData = new utils.Dictionary(); } return this.__onceExecData; }, get scriptName() { return SCRIPT_NAME; }, get panelConfig() { return this.__panelConfig; }, set panelConfig(value) { this.__panelConfig = value; }, key: KEY, attributeKeyName: ATTRIBUTE_KEY, attributeDefaultValueName: ATTRIBUTE_DEFAULT_VALUE, }, init() { this.initContentDefaultValue(); PanelMenu.init(); }, isTopWindow() { return _unsafeWindow.top === _unsafeWindow.self; }, initContentDefaultValue() { const initDefaultValue = (config) => { if (!config.attributes) { return; } if (config.type === "button" || config.type === "forms" || config.type === "deepMenu") { return; } const attributes = config.attributes; let __attr_init__ = attributes[ATTRIBUTE_INIT]; if (typeof __attr_init__ === "function") { let __attr_result__ = __attr_init__(); if (typeof __attr_result__ === "boolean" && !__attr_result__) { return; } } let menuDefaultConfig = new Map(); let key = attributes[ATTRIBUTE_KEY]; if (key != null) { const defaultValue = attributes[ATTRIBUTE_DEFAULT_VALUE]; menuDefaultConfig.set(key, defaultValue); } let moreMenuDefaultConfig = attributes[ATTRIBUTE_INIT_MORE_VALUE]; if (typeof moreMenuDefaultConfig === "object" && moreMenuDefaultConfig) { Object.keys(moreMenuDefaultConfig).forEach((key2) => { menuDefaultConfig.set(key2, moreMenuDefaultConfig[key2]); }); } if (!menuDefaultConfig.size) { log.warn(["请先配置键", config]); return; } if (config.type === "switch") { let disabled = typeof config.disabled === "function" ? config.disabled() : config.disabled; if (typeof disabled === "boolean" && disabled) { this.$data.contentConfigInitDisabledKeys.push(...menuDefaultConfig.keys()); } } for (const [__key, __defaultValue] of menuDefaultConfig.entries()) { this.setDefaultValue(__key, __defaultValue); } }; const loopInitDefaultValue = (configList) => { for (let index = 0; index < configList.length; index++) { let configItem = configList[index]; initDefaultValue(configItem); let child_forms = configItem.forms; if (child_forms && Array.isArray(child_forms)) { loopInitDefaultValue(child_forms); } } }; const contentConfigList = [...PanelContent.getAllContentConfig()]; for (let index = 0; index < contentConfigList.length; index++) { let leftContentConfigItem = contentConfigList[index]; if (!leftContentConfigItem.forms) { continue; } const rightContentConfigList = leftContentConfigItem.forms; if (rightContentConfigList && Array.isArray(rightContentConfigList)) { loopInitDefaultValue(rightContentConfigList); } } this.$data.contentConfigInitDisabledKeys = [...new Set(this.$data.contentConfigInitDisabledKeys)]; }, setDefaultValue(key, defaultValue) { if (this.$data.contentConfigInitDefaultValue.has(key)) { log.warn("请检查该key(已存在): " + key); } this.$data.contentConfigInitDefaultValue.set(key, defaultValue); }, getDefaultValue(key) { return this.$data.contentConfigInitDefaultValue.get(key); }, setValue(key, value) { PopsPanelStorageApi.set(key, value); }, getValue(key, defaultValue) { const localValue = PopsPanelStorageApi.get(key); if (localValue == null) { if (this.$data.contentConfigInitDefaultValue.has(key)) { return this.$data.contentConfigInitDefaultValue.get(key); } return defaultValue; } return localValue; }, deleteValue(key) { PopsPanelStorageApi.delete(key); }, hasKey(key) { return PopsPanelStorageApi.has(key); }, addValueChangeListener(key, callback) { const listenerId = PopsPanelStorageApi.addValueChangeListener(key, (__key, __newValue, __oldValue) => { callback(key, __oldValue, __newValue); }); return listenerId; }, removeValueChangeListener(listenerId) { PopsPanelStorageApi.removeValueChangeListener(listenerId); }, triggerMenuValueChange(key, newValue, oldValue) { PopsPanelStorageApi.triggerValueChangeListener(key, oldValue, newValue); }, async exec(queryKey, callback, checkExec, once = true) { const that = this; let queryKeyFn; if (typeof queryKey === "string" || Array.isArray(queryKey)) { queryKeyFn = () => queryKey; } else { queryKeyFn = queryKey; } let isArrayKey = false; const queryKeyResult = queryKeyFn(); let keyList = []; if (Array.isArray(queryKeyResult)) { isArrayKey = true; keyList = queryKeyResult; } else { keyList.push(queryKeyResult); } const findNotInDataKey = keyList.find((it) => !this.$data.contentConfigInitDefaultValue.has(it)); if (findNotInDataKey) { log.warn(`${findNotInDataKey} 键不存在`); return; } const storageKey = JSON.stringify(keyList); if (once) { if (this.$data.onceExecMenuData.has(storageKey)) { return this.$data.onceExecMenuData.get(storageKey); } } let storeValueList = []; const listenerIdList = []; let destoryFnList = []; const addStoreValueCallback = (enableValue, args) => { let dynamicMenuStoreValueList = []; let dynamicDestoryFnList = []; let resultValueList = []; if (Array.isArray(args)) { resultValueList = resultValueList.concat(args); } else { if (typeof args === "object" && args != null) { if (args instanceof Element) { resultValueList.push(args); } else { const { $css, destory } = args; if ($css != null) { if (Array.isArray($css)) { resultValueList = resultValueList.concat($css); } else { resultValueList.push($css); } } if (typeof destory === "function") { resultValueList.push(destory); } } } else { resultValueList.push(args); } } for (const it of resultValueList) { if (it == null) { continue; } if (it instanceof Element) { dynamicMenuStoreValueList.push(it); continue; } if (typeof it === "function") { destoryFnList.push(it); continue; } } if (enableValue) { storeValueList = storeValueList.concat(dynamicMenuStoreValueList); destoryFnList = destoryFnList.concat(dynamicDestoryFnList); } else { execClearStoreStyleElements(); execDestory(); } }; const getMenuValue = (key) => { const value = this.getValue(key); return Boolean(value); }; const execClearStoreStyleElements = () => { for (let index = 0; index < storeValueList.length; index++) { const $css = storeValueList[index]; $css?.remove(); storeValueList.splice(index, 1); index--; } }; const execDestory = () => { for (let index = 0; index < destoryFnList.length; index++) { const destoryFnItem = destoryFnList[index]; destoryFnItem(); destoryFnList.splice(index, 1); index--; } }; const checkMenuExec = () => { let flag = false; if (typeof checkExec === "function") { flag = checkExec(keyList); } else { flag = keyList.every((key) => getMenuValue(key)); } return flag; }; const valueChangeCallback = async (valueOption) => { const execFlag = checkMenuExec(); if (execFlag) { const valueList = keyList.map((key) => this.getValue(key)); const callbackResult = await callback({ value: isArrayKey ? valueList : valueList[0], addStoreValue: (...args) => { return addStoreValueCallback(true, args); }, }); addStoreValueCallback(true, callbackResult); } else { addStoreValueCallback(false, []); } }; once && keyList.forEach((key) => { const listenerId = this.addValueChangeListener(key, (key2, newValue, oldValue) => { return valueChangeCallback(); }); listenerIdList.push(listenerId); }); await valueChangeCallback(); const result = { reload() { this.clearStoreStyleElements(); this.destory(); valueChangeCallback(); }, clear() { this.clearStoreStyleElements(); this.destory(); this.removeValueChangeListener(); this.clearOnceExecMenuData(); }, clearStoreStyleElements: () => { return execClearStoreStyleElements(); }, destory() { return execDestory(); }, removeValueChangeListener: () => { listenerIdList.forEach((listenerId) => { this.removeValueChangeListener(listenerId); }); }, clearOnceExecMenuData() { once && that.$data.onceExecMenuData.delete(storageKey); }, }; this.$data.onceExecMenuData.set(storageKey, result); return result; }, async execMenu(key, callback, isReverse = false, once = false) { return await this.exec( key, async (option) => { return await callback(option); }, (keyList) => { const execFlag = keyList.every((__key__) => { let flag = !!this.getValue(__key__); const disabled = Panel.$data.contentConfigInitDisabledKeys.includes(__key__); if (disabled) { flag = false; log.warn(`.execMenu${once ? "Once" : ""} ${__key__} 被禁用`); } isReverse && (flag = !flag); return flag; }); return execFlag; }, once ); }, async execMenuOnce(key, callback, isReverse = false, listenUrlChange = false) { const result = await this.execMenu(key, callback, isReverse, true); if (listenUrlChange) { if (result) { const urlChangeEvent = () => { result.reload(); }; this.removeUrlChangeWithExecMenuOnceListener(key); this.addUrlChangeWithExecMenuOnceListener(key, urlChangeEvent); } } return result; }, deleteExecMenuOnce(key) { key = this.transformKey(key); this.$data.onceExecMenuData.delete(key); this.$data.urlChangeReloadMenuExecOnce.delete(key); const flag = PopsPanelStorageApi.removeValueChangeListener(key); return flag; }, onceExec(key, callback) { key = this.transformKey(key); if (typeof key !== "string") { throw new TypeError("key 必须是字符串"); } if (this.$data.onceExecData.has(key)) { return; } callback(); this.$data.onceExecData.set(key, 1); }, deleteOnceExec(key) { key = this.transformKey(key); this.$data.onceExecData.delete(key); }, addUrlChangeWithExecMenuOnceListener(key, callback) { key = this.transformKey(key); this.$data.urlChangeReloadMenuExecOnce.set(key, callback); }, removeUrlChangeWithExecMenuOnceListener(key) { key = this.transformKey(key); this.$data.urlChangeReloadMenuExecOnce.delete(key); }, hasUrlChangeWithExecMenuOnceListener(key) { key = this.transformKey(key); return this.$data.urlChangeReloadMenuExecOnce.has(key); }, async triggerUrlChangeWithExecMenuOnceEvent(config) { const values = this.$data.urlChangeReloadMenuExecOnce.values(); for (const callback of values) { await callback(config); } }, showPanel( content, title = `${SCRIPT_NAME}-设置`, preventDefaultContentConfig = false, preventRegisterSearchPlugin = false ) { this.$data.$panel = null; this.$data.panelContent = []; let checkHasBottomVersionContentConfig = content.findIndex((it) => { let isBottom = typeof it.isBottom === "function" ? it.isBottom() : Boolean(it.isBottom); return isBottom && it.id === "script-version"; }) !== -1; if (!preventDefaultContentConfig && !checkHasBottomVersionContentConfig) { content.push(...PanelContent.getDefaultBottomContentConfig()); } let $panel = __pops.panel({ ...{ title: { text: title, position: "center", html: false, style: "", }, content, btn: { close: { enable: true, callback: (details, event) => { details.close(); this.$data.$panel = null; }, }, }, mask: { enable: true, clickEvent: { toClose: true, toHide: false, }, clickCallBack: (originalRun, config) => { originalRun(); this.$data.$panel = null; }, }, width: PanelUISize.setting.width, height: PanelUISize.setting.height, drag: true, only: true, }, ...this.$data.panelConfig, }); this.$data.$panel = $panel; this.$data.panelContent = content; if (!preventRegisterSearchPlugin) { this.registerConfigSearch({ $panel, content }); } }, registerConfigSearch(config) { const { $panel, content } = config; const asyncQueryProperty = async (target, handler) => { if (target == null) { return; } const handleResult = await handler(target); if (handleResult && typeof handleResult.isFind === "boolean" && handleResult.isFind) { return handleResult.data; } return await asyncQueryProperty(handleResult.data, handler); }; const scrollToElementAndListen = ($el, callback) => { const observer = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { callback?.(); observer.disconnect(); } }); }, { root: null, threshold: 1, } ); observer.observe($el); $el.scrollIntoView({ behavior: "smooth", block: "center" }); }; const addFlashingClass = ($el) => { const flashingClassName = "pops-flashing"; domUtils.animationend($el, () => { $el.classList.remove(flashingClassName); }); $el.classList.add(flashingClassName); }; const dbclick_callback = (evt) => { if (evt.type === "dblclick" && isMobileTouch) { return; } domUtils.preventEvent(evt); clickElement = null; const $alert = __pops.alert({ title: { text: "搜索配置", position: "center", }, content: { text: `
`, html: true, }, btn: { ok: { enable: false }, }, mask: { clickEvent: { toClose: true, }, }, width: PanelUISize.settingMiddle.width, height: "auto", drag: true, style: ` ${__pops.config.cssText.panelCSS} .search-wrapper{ border-bottom: 1px solid rgb(235, 238, 245, 1); } .pops-content:has(.search-result-wrapper:empty) .search-wrapper{ border-bottom: 0; } .search-config-text{ width: 100%; border: 0; height: 32px; padding: 0px 10px; outline: none; } .search-result-wrapper{ max-height: 400px; overflow: auto; } .search-result-item{ cursor: pointer; padding: 5px 10px; display: flex; flex-direction: column; } .search-result-item:hover{ background-color: #D8F1FD; } .search-result-item-path{ display: flex; align-items: center; } .search-result-item-description{ font-size: 0.8em; color: #6c6c6c; } ${config.searchDialogStyle ?? ""} `, }); $alert.$shadowRoot.querySelector(".search-wrapper"); const $searchInput = $alert.$shadowRoot.querySelector(".search-config-text"); const $searchResultWrapper = $alert.$shadowRoot.querySelector(".search-result-wrapper"); $searchInput.focus(); const clearSearchResult = () => { domUtils.empty($searchResultWrapper); }; const createSearchResultItem = (pathInfo) => { const searchPath = utils.queryProperty(pathInfo, (target) => { if (target?.next) { return { isFind: false, data: target.next, }; } else { return { isFind: true, data: target, }; } }); const $item = domUtils.createElement("div", { className: "search-result-item", innerHTML: `
${searchPath.matchedData?.path}
${searchPath.matchedData?.description ?? ""}
`, }); domUtils.on($item, "click", (clickItemEvent) => { const $asideItems2 = $panel.$shadowRoot.querySelectorAll( "aside.pops-panel-aside .pops-panel-aside-top-container li" ); const $targetAsideItem = $asideItems2[pathInfo.index]; if (!$targetAsideItem) { Qmsg.error(`左侧项下标${pathInfo.index}不存在`); return; } $targetAsideItem.scrollIntoView({ behavior: "smooth", block: "center", }); $targetAsideItem.click(); asyncQueryProperty(pathInfo.next, async (target) => { if (target?.next) { const $findDeepMenu = await domUtils.waitNode(() => { return Array.from($panel.$shadowRoot.querySelectorAll(".pops-panel-deepMenu-nav-item")).find( ($deepMenu) => { const __formConfig__ = Reflect.get($deepMenu, "__formConfig__"); return ( typeof __formConfig__ === "object" && __formConfig__ != null && __formConfig__.text === target.name ); } ); }, 2500); if ($findDeepMenu) { $findDeepMenu.click(); } else { Qmsg.error("未找到对应的二级菜单"); return { isFind: true, data: target, }; } return { isFind: false, data: target.next, }; } else { const $findTargetMenu = await domUtils.waitNode(() => { return Array.from($panel.$shadowRoot.querySelectorAll(`li:not(.pops-panel-deepMenu-nav-item)`)).find( ($menuItem) => { const __formConfig__ = Reflect.get($menuItem, "__formConfig__"); return __formConfig__ === target.matchedData?.formConfig; } ); }, 2500); if ($findTargetMenu) { scrollToElementAndListen($findTargetMenu); const $fold = $findTargetMenu.closest(`.pops-panel-forms-fold[data-fold-enable]`); if ($fold) { const $foldWrapper = $fold.querySelector(".pops-panel-forms-fold-container"); $foldWrapper.click(); await utils.sleep(500); } scrollToElementAndListen($findTargetMenu, () => { addFlashingClass($findTargetMenu); }); } else { Qmsg.error("未找到对应的菜单项"); } return { isFind: true, data: target, }; } }); }); return $item; }; const execSearch = (searchText) => { const searchTextRegExp = new RegExp(searchText, "i"); const searchConfigResult = []; const loopContentConfig = (configList, path) => { for (let index = 0; index < configList.length; index++) { const configItem = configList[index]; const child_forms = configItem.forms; if (child_forms && Array.isArray(child_forms)) { const deepMenuPath = utils.deepClone(path); if (configItem.type === "deepMenu") { const deepNext = utils.queryProperty(deepMenuPath, (target) => { if (target?.next) { return { isFind: false, data: target.next, }; } else { return { isFind: true, data: target, }; } }); deepNext.next = { name: configItem.text, }; } loopContentConfig(child_forms, deepMenuPath); } else { const text = Reflect.get(configItem, "text"); const description = Reflect.get(configItem, "description"); const delayMatchedTextList = [text, description]; const matchedIndex = delayMatchedTextList.findIndex((configText) => { if (typeof configText !== "string") { return; } return configText.match(searchTextRegExp); }); if (matchedIndex !== -1) { const matchedPath = utils.deepClone(path); const deepNext = utils.queryProperty(matchedPath, (target) => { if (target?.next) { return { isFind: false, data: target.next, }; } else { return { isFind: true, data: target, }; } }); deepNext.next = { name: text, matchedData: { path: "", formConfig: configItem, matchedText: delayMatchedTextList[matchedIndex], description, }, }; const pathList = []; utils.queryProperty(matchedPath, (target) => { const name = target?.name; if (typeof name === "string" && name.trim() !== "") { pathList.push(name); } if (target?.next) { return { isFind: false, data: target.next, }; } else { return { isFind: true, data: target, }; } }); const pathStr = pathList.join(CommonUtil.escapeHtml(" - ")); deepNext.next.matchedData.path = pathStr; searchConfigResult.push(matchedPath); } } } }; for (let index = 0; index < content.length; index++) { const leftContentConfigItem = content[index]; if (!leftContentConfigItem.forms) { continue; } if (leftContentConfigItem.isBottom && leftContentConfigItem.id === "script-version") { continue; } const rightContentConfigList = leftContentConfigItem.forms; if (rightContentConfigList && Array.isArray(rightContentConfigList)) { let text = leftContentConfigItem.title; if (typeof text === "function") { text = text(); } loopContentConfig(rightContentConfigList, { index, name: text, }); } } const fragment = document.createDocumentFragment(); for (const pathInfo of searchConfigResult) { let $resultItem = createSearchResultItem(pathInfo); fragment.appendChild($resultItem); } clearSearchResult(); $searchResultWrapper.append(fragment); }; domUtils.on( $searchInput, "input", utils.debounce((evt2) => { domUtils.preventEvent(evt2); let searchText = domUtils.val($searchInput).trim(); if (searchText === "") { clearSearchResult(); return; } execSearch(searchText); }, 200) ); }; const $asideItems = $panel.$shadowRoot.querySelectorAll( `aside.pops-panel-aside .pops-panel-aside-item:not(#script-version)` ); $asideItems.forEach(($asideItem) => { domUtils.on($asideItem, "dblclick", dbclick_callback); }); let clickElement = null; let isDoubleClick = false; let timer = void 0; let isMobileTouch = false; domUtils.on( $panel.$shadowRoot, "touchend", `aside.pops-panel-aside .pops-panel-aside-item:not(#script-version)`, (evt, selectorTarget) => { isMobileTouch = true; clearTimeout(timer); timer = void 0; if (isDoubleClick && clickElement === selectorTarget) { isDoubleClick = false; clickElement = null; dbclick_callback(evt); } else { timer = setTimeout(() => { isDoubleClick = false; }, 200); isDoubleClick = true; clickElement = selectorTarget; } }, { capture: true, } ); $panel.$shadowRoot.appendChild( domUtils.createElement("style", { type: "text/css", textContent: ` .pops-flashing{ animation: double-blink 1.5s ease-in-out; } @keyframes double-blink { 0% { background-color: initial; } 25% { background-color: yellow; } 50% { background-color: initial; } 75% { background-color: yellow; } 100% { background-color: initial; } } `, }) ); }, transformKey(key) { if (Array.isArray(key)) { const keyArray = key.sort(); return JSON.stringify(keyArray); } else { return key; } }, }; class HttpxCookieManager { $data = { get enable() { return Panel.getValue( PanelSettingConfig.httpx_cookie_manager_enable.key, PanelSettingConfig.httpx_cookie_manager_enable.defaultValue ); }, get useDocumentCookie() { return Panel.getValue( PanelSettingConfig.httpx_cookie_manager_use_document_cookie.key, PanelSettingConfig.httpx_cookie_manager_use_document_cookie.defaultValue ); }, cookieRule: [], }; constructor(cookieRule) { if (Array.isArray(cookieRule)) { this.$data.cookieRule = cookieRule; } } fixCookieSplit(str) { if (utils.isNotNull(str) && !str.trim().endsWith(";")) { str += ";"; } return str; } concatCookie(targetCookie, newCookie) { if (utils.isNull(targetCookie)) { return newCookie; } targetCookie = targetCookie.trim(); newCookie = newCookie.trim(); targetCookie = this.fixCookieSplit(targetCookie); if (newCookie.startsWith(";")) { newCookie = newCookie.substring(1); } return targetCookie.concat(newCookie); } handle(details) { if (details.fetch) { return; } if (!this.$data.enable) { return; } let ownCookie = ""; let url = details.url; if (url.startsWith("//")) { url = window.location.protocol + url; } let urlObj = new URL(url); if ( this.$data.useDocumentCookie && urlObj.hostname.endsWith(window.location.hostname.split(".").slice(-2).join(".")) ) { ownCookie = this.concatCookie(ownCookie, document.cookie.trim()); } for (let index = 0; index < this.$data.cookieRule.length; index++) { let rule = this.$data.cookieRule[index]; if (urlObj.hostname.match(rule.hostname)) { let cookie = Panel.getValue(rule.key); if (utils.isNull(cookie)) { break; } ownCookie = this.concatCookie(ownCookie, cookie); } } if (utils.isNotNull(ownCookie)) { if (details.headers && details.headers["Cookie"]) { details.headers.Cookie = this.concatCookie(details.headers.Cookie, ownCookie); } else { details.headers["Cookie"] = ownCookie; } log.info(["Httpx => 设置cookie:", details]); } if (details.headers && details.headers.Cookie != null && utils.isNull(details.headers.Cookie)) { delete details.headers.Cookie; } } } { CommonUtil.setGMResourceCSS(GM_RESOURCE_MAPPING.Viewer); } { CommonUtil.setGMResourceCSS(GM_RESOURCE_MAPPING.Hljs); } const httpxCookieManager = new HttpxCookieManager([ { key: "httpx-cookie-bbs.binmt.cc", hostname: /bbs.binmt.cc/g, }, ]); httpx.interceptors.request.use((data) => { httpxCookieManager.handle(data); return data; }); __pops.GlobalConfig.setGlobalConfig({ mask: { enable: true, }, drag: true, }); const ElementUtils = { registerLeftMenu(config) { domUtils.waitNode(".comiis_sidenv_box .sidenv_li .comiis_left_Touch", 1e4).then(($leftTouch) => { if (!$leftTouch) { log.error("注册左侧面板菜单失败,原因:该元素不存在"); return; } let $setting = domUtils.createElement("li", { className: "comiis_left_Touch", innerHTML: ` ${config.name} `, }); let $icon = $setting.querySelector(".comiis_font"); if (typeof config.style === "string") { $icon.style.cssText = config.style; } if (typeof config.icon === "string") { $icon.innerHTML = config.icon; } if (typeof config.iconColor === "string") { $icon.style.color = config.iconColor; } if (typeof config.iconSize === "string") { $icon.style.fontSize = config.iconSize; } domUtils.on($setting, "click", (event) => { domUtils.preventEvent(event); if (typeof config.callback === "function") { config.callback(); } }); domUtils.append($leftTouch, $setting); }); }, comiisForumList: () => { return document.querySelectorAll("li.forumlist_li"); }, comiisPostli: () => { return document.querySelectorAll("div.comiis_postli.comiis_list_readimgs.nfqsqi"); }, comiisMmlist: () => { return document.querySelectorAll(".comiis_mmlist"); }, }; const blackHomeCSS = ".pops-confirm-content {\r\n display: flex;\r\n flex-direction: column;\r\n}\r\n.blackhome-user-filter input {\r\n width: -moz-available;\r\n width: -webkit-fill-available;\r\n height: 30px;\r\n margin: 8px 20px;\r\n border: 0;\r\n border-bottom: 1px solid;\r\n text-overflow: ellipsis;\r\n overflow: hidden;\r\n white-space: nowrap;\r\n}\r\n.blackhome-user-filter input:focus-within {\r\n outline: none;\r\n}\r\n.blackhome-user-list {\r\n flex: 1;\r\n overflow-y: auto;\r\n}\r\n.blackhome-user-list .blackhome-user-item {\r\n margin: 15px 10px;\r\n padding: 10px;\r\n border-radius: 8px;\r\n box-shadow:\r\n 0 0 0.6rem #c8d0e7,\r\n -0.2rem -0.2rem 0.5rem #fff;\r\n}\r\n.blackhome-user {\r\n display: flex;\r\n}\r\n.blackhome-user img {\r\n width: 45px;\r\n height: 45px;\r\n border-radius: 45px;\r\n}\r\n.blackhome-user-info {\r\n margin-left: 10px;\r\n}\r\n.blackhome-user-info p:nth-child(1) {\r\n margin-bottom: 5px;\r\n}\r\n.blackhome-user-info p:nth-child(2) {\r\n font-size: 14px;\r\n}\r\n.blackhome-user-action {\r\n display: flex;\r\n margin: 10px 0;\r\n}\r\n.blackhome-user-action p:nth-child(1),\r\n.blackhome-user-action p:nth-child(2) {\r\n border: 1px solid red;\r\n color: red;\r\n border-radius: 4px;\r\n padding: 2px 4px;\r\n font-weight: 500;\r\n font-size: 14px;\r\n place-self: center;\r\n}\r\n.blackhome-user-action p:nth-child(2) {\r\n border: 1px solid #ff4b4b;\r\n color: #ff4b4b;\r\n margin-left: 8px;\r\n}\r\n.blackhome-user-uuid {\r\n border: 1px solid #ff7600;\r\n color: #ff7600;\r\n border-radius: 4px;\r\n padding: 2px 4px;\r\n font-weight: 500;\r\n font-size: 14px;\r\n width: fit-content;\r\n width: -moz-fit-content;\r\n margin: 10px 0;\r\n}\r\n.blackhome-operator {\r\n padding: 10px;\r\n background-color: #efefef;\r\n border-radius: 6px;\r\n}\r\n.blackhome-operator-user {\r\n display: flex;\r\n}\r\n.blackhome-operator-user img {\r\n width: 35px;\r\n height: 35px;\r\n border-radius: 35px;\r\n}\r\n.blackhome-operator-user p {\r\n align-self: center;\r\n margin-left: 10px;\r\n}\r\n.blackhome-operator-user-info {\r\n margin: 10px 0;\r\n font-weight: 500;\r\n}\r\n"; const MTRegExp = { formhash: /formhash=([0-9a-zA-Z]+)/, uid: /uid(=|-)(\d+)/, fontSpecial: /|<\/font>|||||align=".*?"|
[\s]*
[\s]*
/g, ptid: /&ptid=([\d]+)/i, pid: /&pid=([\d]+)/i, tid: /&tid=([\d]+)/i, }; const MTUtils = { getAvatar: (uid, size = "middle") => { return `/uc_server/avatar.php?uid=${uid}&size=${size}&ts=1`; }, getCurrentUID() { let discuz_uid = _unsafeWindow.discuz_uid; if (typeof discuz_uid === "string") { return discuz_uid; } let $exit = document.querySelector('.sidenv_exit a[href*="uid="]'); if ($exit) { let uidMatch = $exit.href.match(/uid=([0-9]+)/); if (uidMatch) { return uidMatch[uidMatch.length - 1]; } } }, async getFormHash() { let $inputFormHashList = Array.from((top || globalThis).document.querySelectorAll("input[name=formhash]")); for (let index = 0; index < $inputFormHashList.length; index++) { const $input = $inputFormHashList[index]; let formHash = $input.value; if (formHash) { return formHash; } } let $anchorFormHashList = Array.from((top || globalThis).document.querySelectorAll('a[href*="formhash="]')); for (let index = 0; index < $anchorFormHashList.length; index++) { const $anchorFormHash = $anchorFormHashList[index]; let anchorFormHashMatch = $anchorFormHash.href.match(MTRegExp.formhash); if (anchorFormHashMatch) { let formHash = anchorFormHashMatch[anchorFormHashMatch.length - 1]; if (formHash) { return formHash; } } } let homeResponse = await httpx.get("/home.php?mod=spacecp", { fetch: true, allowInterceptConfig: false, }); if (homeResponse.status) { let homeText = homeResponse.data.responseText; let homeDoc = domUtils.toElement(homeText, true, true); let $formhash = homeDoc.querySelector("input[name=formhash]"); if ($formhash) { let formHash = $formhash.value; if (utils.isNotNull(formHash)) { return formHash; } } } else { log.error("请求个人主页获取formhash失败", homeResponse); } }, envIsMobile() { return (_unsafeWindow.STYLEID || window.STYLEID || (typeof STYLEID !== "undefined" && STYLEID)) === "3"; }, getThreadId: (url) => { let urlMatch = url.match(/thread-([\d]+)-|&tid=([\d]+)/i); if (urlMatch) { let forumIdList = urlMatch.filter(Boolean); let forumId = forumIdList[forumIdList.length - 1]; return forumId; } }, getForumId(url) { let urlMatch = url.match(/&fid=([\d]+)/i); if (urlMatch) { return urlMatch[urlMatch.length - 1]; } }, getPostId(url) { let urlMatch = url.match(/&pid=([\d]+)/i); if (urlMatch) { return urlMatch[urlMatch.length - 1]; } }, getRepquote(url) { let urlMatch = url.match(/&repquote=([\d]+)/i); if (urlMatch) { return urlMatch[urlMatch.length - 1]; } }, }; const MTBlackHome = { $data: { cid: "", }, init() { this.registerMenu(); }, registerMenu() { ElementUtils.registerLeftMenu({ name: "小黑屋", iconColor: "#000000", icon: "", callback: () => { this.showBlackHome(); }, }); }, async showBlackHome() { let $loading = Qmsg.loading("正在获取小黑屋名单中..."); let blackListInfo = await this.getBlackListInfo(""); $loading.close(); if (!blackListInfo) { return; } if (blackListInfo.data.length === 0) { Qmsg.error("获取小黑屋名单为空"); return; } this.$data.cid = blackListInfo.next_cid; let $confirm = __pops.confirm({ title: { text: "小黑屋名单", position: "center", }, content: { text: `
`, html: true, }, btn: { ok: { text: "下一页", callback: async () => { let $loading2 = Qmsg.loading("正在获取小黑屋名单中..."); log.info("下一页的cid: ", this.$data.cid); let nextBlackListInfo2 = await this.getBlackListInfo(this.$data.cid); $loading2.close(); if (!nextBlackListInfo2) { return; } this.$data.cid = nextBlackListInfo2.next_cid; nextBlackListInfo2.data.forEach((item) => { let $item = this.createListViewItem(item); $list.appendChild($item); }); if (nextBlackListInfo2.data.length === 0) { Qmsg.error("获取小黑屋名单为空"); } else { Qmsg.success(`成功获取 ${nextBlackListInfo2.data.length}条数据`); } domUtils.trigger($filterInput, "input"); }, }, cancel: { text: "关闭", }, }, width: "88vw", height: "82vh", style: blackHomeCSS, }); let $list = $confirm.$shadowRoot.querySelector(".blackhome-user-list"); let $filterInput = $confirm.$shadowRoot.querySelector(".blackhome-user-filter input"); blackListInfo.data.forEach((item) => { let $item = this.createListViewItem(item); $list.appendChild($item); }); Qmsg.success(`成功获取 ${blackListInfo.data.length}条数据`); let isSeaching = false; domUtils.on( $filterInput, ["input", "propertychange"], utils.debounce(() => { let inputText = $filterInput.value.trim(); if (isSeaching) { return; } isSeaching = true; if (inputText == "") { $confirm.$shadowRoot.querySelectorAll(".blackhome-user-item").forEach((item) => { item.removeAttribute("style"); }); isSeaching = false; return; } $confirm.$shadowRoot.querySelectorAll(".blackhome-user-item").forEach((item) => { if ( item.getAttribute("data-name").match(new RegExp(inputText, "ig")) || item.getAttribute("data-uid").trim().match(new RegExp(inputText, "ig")) || item.getAttribute("data-operator").match(new RegExp(inputText, "ig")) ) { item.removeAttribute("style"); } else { item.setAttribute("style", "display:none;"); } }); isSeaching = false; }) ); let nextBlackListInfo = await this.getBlackListInfo(this.$data.cid); if (!nextBlackListInfo) { return; } this.$data.cid = nextBlackListInfo.next_cid; }, async getBlackListInfo(cid = "") { let searchParamsData = { mod: "misc", action: "showdarkroom", cid, ajaxdata: "json", }; let response = await httpx.get(`/forum.php?${utils.toSearchParamsStr(searchParamsData)}`, { headers: { "User-Agent": utils.getRandomPCUA(), }, responseType: "json", }); if (!response.status) { return; } let data = utils.toJSON(response.data.responseText); let cidSplit = data["message"].split("|"); let next_cid = cidSplit[cidSplit.length - 1]; let blackListData = utils.parseObjectToArray(data["data"]); let new_blackListData = []; let new_blackListData_noTime = []; blackListData.forEach((item) => { let date = item["dateline"].match(/([0-9]{4}-[0-9]{1,2}-[0-9]{1,2}[\s]*[0-9]{1,2}:[0-9]{1,2})/g); if (date == null) { let _time_ = parseInt((Date.now() / 1e3).toString()); let _time_after_count_ = 0; let sec_data = item["dateline"].match(/([0-9]+|半)[\s\S]*秒前/); let min_data = item["dateline"].match(/([0-9]+|半)[\s\S]*分钟前/); let hour_data = item["dateline"].match(/([0-9]+|半)[\s\S]*小时前/); let yesterday_time_data = item["dateline"].match(/昨天[\s\S]*(\d{2}):(\d{2})/); let before_yesterday_time_data = item["dateline"].match(/前天[\s\S]*(\d{2}):(\d{2})/); let day_data = item["dateline"].match(/([0-9]+|半)[\s\S]*天前/); if (sec_data) { sec_data = sec_data[sec_data.length - 1]; sec_data = sec_data.replace(/半/g, 0.5); sec_data = parseFloat(sec_data); _time_after_count_ = _time_ - sec_data; } else if (min_data) { min_data = min_data[min_data.length - 1]; min_data = min_data.replace(/半/g, 0.5); min_data = parseFloat(min_data); _time_after_count_ = _time_ - min_data * 60; } else if (hour_data) { hour_data = hour_data[hour_data.length - 1]; hour_data = hour_data.replace(/半/g, 0.5); hour_data = parseFloat(hour_data); _time_after_count_ = _time_ - hour_data * 60 * 60; } else if (yesterday_time_data) { let yesterday_hour_data = yesterday_time_data[1]; let yesterday_min_data = yesterday_time_data[2]; _time_after_count_ = _time_ - 86400 - parseInt(yesterday_hour_data) * 3600 - parseInt(yesterday_min_data) * 60; } else if (before_yesterday_time_data) { let before_yesterday_hour_data = before_yesterday_time_data[1]; let before_yesterday_min_data = before_yesterday_time_data[2]; _time_after_count_ = _time_ - 86400 * 2 - parseInt(before_yesterday_hour_data) * 3600 - parseInt(before_yesterday_min_data) * 60; } else if (day_data) { day_data = day_data[day_data.length - 1]; day_data = day_data.replace(/半/g, 0.5); day_data = parseFloat(day_data); _time_after_count_ = _time_ - day_data * 60 * 60 * 24; } item["time"] = parseInt(_time_after_count_.toString()) * 1e3; new_blackListData = new_blackListData.concat(item); return; } else { date = date[0]; } item["time"] = utils.formatToTimeStamp(date); new_blackListData = new_blackListData.concat(item); }); utils.sortListByProperty(new_blackListData, "time"); utils.sortListByProperty(new_blackListData_noTime, "time", false); new_blackListData = new_blackListData.concat(new_blackListData_noTime); return { next_cid, data: new_blackListData, }; }, createListViewItem(userInfo) { let $item = domUtils.createElement( "div", { className: "blackhome-user-item", innerHTML: `

${userInfo["action"]}

到期: ${userInfo["groupexpiry"]}

UID: ${userInfo["uid"]}

${userInfo["operator"]}

`, }, { "data-name": userInfo.username, "data-uid": userInfo.uid, "data-operator": userInfo.operator, "data-operator-uid": userInfo.operatorid, } ); domUtils.on($item, "click", ".blackhome-user img", function () { window.open(`home.php?mod=space&uid=${userInfo.uid}&do=profile`, "_blank"); }); domUtils.on($item, "click", ".blackhome-operator-user img", function () { window.open(`home.php?mod=space&uid=${userInfo.operatorid}&do=profile`, "_blank"); }); return $item; }, }; const onlineUserCSS = '.pops-alert-content {\r\n display: flex;\r\n flex-direction: column;\r\n}\r\n.pops-alert-content > .online-user-info {\r\n text-align: center;\r\n padding: 0px 6px;\r\n}\r\n.online-user-filter input {\r\n width: -webkit-fill-available;\r\n width: -moz-available;\r\n height: 30px;\r\n margin: 8px 20px;\r\n border: 0;\r\n border-bottom: 1px solid;\r\n}\r\n.online-user-filter input:focus-within {\r\n outline: none;\r\n}\r\n.online-user-list {\r\n flex: 1;\r\n overflow-y: auto;\r\n}\r\n.online-user-list li {\r\n margin: 18px 0;\r\n}\r\n.online-user {\r\n display: flex;\r\n margin: 2px 20px;\r\n align-items: center;\r\n}\r\n.online-user img[data-avatar] {\r\n width: 45px;\r\n height: 45px;\r\n border-radius: 45px;\r\n}\r\n.online-user-list .online-user-info {\r\n margin: 2px 14px;\r\n}\r\n.online-user-list .online-user-info p[data-name] {\r\n margin-bottom: 4px;\r\n}\r\n.online-user-list .online-user-info span[data-sf] {\r\n border-radius: 4px;\r\n padding: 2px 4px;\r\n font-weight: 500;\r\n font-size: 14px;\r\n}\r\n.online-user-list .online-user-info span[data-uid] {\r\n border: 1px solid #ff7600;\r\n color: #ff7600;\r\n border-radius: 4px;\r\n padding: 2px 4px;\r\n font-weight: 500;\r\n font-size: 14px;\r\n width: fit-content;\r\n width: -moz-fit-content;\r\n margin: 10px 0;\r\n}\r\n.online-user-list .online-user-info span[data-sf="会员"] {\r\n color: #88b500;\r\n border: 1px solid #88b500;\r\n}\r\n.online-user-list .online-user-info span[data-sf="版主"] {\r\n color: #2db5e3;\r\n border: 1px solid #2db5e3;\r\n}\r\n.online-user-list .online-user-info span[data-sf="超级版主"] {\r\n color: #e89e38;\r\n border: 1px solid #e89e38;\r\n}\r\n.online-user-list .online-user-info span[data-sf="管理员"] {\r\n color: #ff5416;\r\n border: 1px solid #ff5416;\r\n}\r\n'; const MTOnlineUser = { $data: {}, init() { this.registerMenu(); }, registerMenu() { ElementUtils.registerLeftMenu({ name: "在线用户", iconColor: "#2d92ff", icon: "", callback: () => { this.showOnlineUser(); }, }); }, async showOnlineUser() { let $loading = Qmsg.loading("正在获取在线用户名单中..."); let onlineUserInfo = await this.getOnlineUserListInfo(); $loading.close(); if (!onlineUserInfo) { return; } let $alert = __pops.alert({ title: { text: "在线用户", position: "center", }, content: { text: `
`, html: true, }, btn: { ok: { text: "关闭", type: "default", }, }, width: "88vw", height: "82vh", style: onlineUserCSS, }); let $list = $alert.$shadowRoot.querySelector(".online-user-list"); let $filterInput = $alert.$shadowRoot.querySelector(".online-user-filter input"); onlineUserInfo.data.forEach((item) => { let $item = this.createListViewItem(item); $list.appendChild($item); }); Qmsg.success(`成功获取 ${onlineUserInfo.data.length}条数据`); let isSeaching = false; DOMUtils.on( $filterInput, ["propertychange", "input"], utils.debounce(() => { let inputText = $filterInput.value.trim(); if (isSeaching) { return; } isSeaching = true; if (inputText == "") { $alert.$shadowRoot.querySelectorAll(".online-user-list .online-item").forEach((item) => { item.removeAttribute("style"); }); isSeaching = false; return; } $alert.$shadowRoot.querySelectorAll(".online-user-list .online-item").forEach((item) => { if ( item.getAttribute("data-name").match(new RegExp(inputText, "ig")) || item.getAttribute("data-sf").match(new RegExp(inputText, "ig")) || item.getAttribute("data-uid").match(new RegExp(inputText, "ig")) ) { item.removeAttribute("style"); } else { item.setAttribute("style", "display:none;"); } }); isSeaching = false; }) ); }, async getOnlineUserListInfo() { let searchParamsData = { showoldetails: "yes", }; let response = await httpx.get(`/forum.php?${utils.toSearchParamsStr(searchParamsData)}`, { headers: { "User-Agent": utils.getRandomPCUA(), }, }); if (!response.status) { return; } let pageHTML = utils.parseFromString(response.data.responseText, "text/html"); let result = { data: [], totalOnline: 0, onlineUser: 0, noRegisterUser: 0, invisibleUser: 0, }; let onlineList = pageHTML.querySelectorAll("#onlinelist ul li"); onlineList.forEach((item) => { let uid = item.querySelector("a").getAttribute("href").match("uid-(.+?).html")[1]; let avatar = MTUtils.getAvatar(uid, "middle"); let name = item.querySelector("a").innerText; let sf = ""; let space = item.querySelector("a").getAttribute("href"); let memberSrc = item.querySelector("img").src; if (memberSrc.indexOf("online_member") != -1) { sf = "会员"; } else if (memberSrc.indexOf("online_moderator") != -1) { sf = "版主"; } else if (memberSrc.indexOf("online_supermod") != -1) { sf = "超级版主"; } else if (memberSrc.indexOf("online_admin") != -1) { sf = "管理员"; } else { sf = "未知身份"; } result.data.push({ uid, avatar, name, sf, space, }); }); let onlineInfo = pageHTML.querySelector("#online div.bm_h span.xs1").textContent; result.totalOnline = utils.parseInt(onlineInfo.match(/([0-9]*)\s*人在线/i), 0); result.onlineUser = utils.parseInt(onlineInfo.match(/([0-9]*)\s*会员/i), 0); result.noRegisterUser = utils.parseInt(onlineInfo.match(/([0-9]*)\s*位游客/i), 0); result.invisibleUser = utils.parseInt(onlineInfo.match(/([0-9]*)\s*隐身/i), 0); return result; }, createListViewItem(userInfo) { let $item = DOMUtils.createElement( "div", { className: "online-item", innerHTML: `
`, }, { "data-name": userInfo.name, "data-uid": userInfo.uid, "data-sf": userInfo.sf, } ); DOMUtils.on($item, "click", ".online-user-avatar", (event) => { DOMUtils.preventEvent(event); window.open(`home.php?mod=space&uid=${userInfo.uid}&do=profile`, "_blank"); }); return $item; }, }; const MTIdentifyLinks = () => { const HANDLER_CLASS_NAME = "texttolink"; const url_regexp = /((https?:\/\/|www\.)[\x21-\x7e]+[\w\/]|(\w[\w._-]+\.(com|cn|org|net|info|tv|cc))(\/[\x21-\x7e]*[\w\/])?|ed2k:\/\/[\x21-\x7e]+\|\/|thunder:\/\/[\x21-\x7e]+=)/gi; const handleClearLink = function (event) { let targetElement = event.originalTarget ?? event.target; let url; if ( null != targetElement && "a" === targetElement.localName && -1 !== targetElement.className.indexOf(HANDLER_CLASS_NAME) && ((url = targetElement.getAttribute("href")), typeof url === "string" && 0 !== url.indexOf("http") && 0 !== url.indexOf("ed2k://") && 0 !== url.indexOf("thunder://")) ) { return targetElement.setAttribute("href", "http://" + targetElement); } }; const setLink = function (textNode) { if (typeof textNode != "object" || textNode == null) { return; } const textContent = textNode?.textContent; const $parent = textNode?.parentNode; if ($parent == null) { return; } if ( -1 === $parent?.className?.indexOf?.(HANDLER_CLASS_NAME) && "#cdata-section" !== textNode.nodeName && typeof textContent === "string" ) { const modifiedContent = textContent.replace( url_regexp, `$1` ); if (textContent.length !== modifiedContent.length) { const spanElement = document.createElement("span"); domUtils.html(spanElement, modifiedContent); const $url = spanElement.querySelector("a"); const url = $url.href; console.log(`识别: ${url}`); const isSpanParent = $parent.nodeName.toLowerCase() === "span"; if (isSpanParent) { return $parent.replaceChild($url, textNode); } else { return $parent.replaceChild(spanElement, textNode); } } } }; const excludedTags = "a svg canvas applet input button area pre embed frame frameset head iframe img option map meta noscript object script style textarea code".split( " " ); const xpath = `//text()[not(ancestor::${excludedTags.join(") and not(ancestor::")})]`; const filter = new RegExp(`^(${excludedTags.join("|")})$`, "i"); const processLinksInBatches = function (textNodesSnapshot, startIndex) { let currentIndex, endIndex; if (startIndex + 1e4 < textNodesSnapshot.snapshotLength) { let start = (currentIndex = startIndex); for ( endIndex = startIndex + 1e4; startIndex <= endIndex ? currentIndex <= endIndex : currentIndex >= endIndex; start = startIndex <= endIndex ? ++currentIndex : --currentIndex ) { setLink(textNodesSnapshot.snapshotItem(start)); } setTimeout(function () { return processLinksInBatches(textNodesSnapshot, startIndex + 1e4); }, 15); } else { let start; for ( start = currentIndex = startIndex, endIndex = textNodesSnapshot.snapshotLength; startIndex <= endIndex ? currentIndex <= endIndex : currentIndex >= endIndex; start = startIndex <= endIndex ? ++currentIndex : --currentIndex ) { setLink(textNodesSnapshot.snapshotItem(start)); } } }; const linkifyText = function (element) { const textNodesSnapshot = document.evaluate(xpath, element, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); return processLinksInBatches(textNodesSnapshot, 0); }; const observePageChanges = function (rootElement) { for ( const treeWalker = document.createTreeWalker(rootElement, NodeFilter.SHOW_TEXT, { acceptNode: function (node) { const localName = node?.parentNode?.localName; if (!filter.test(localName)) { return NodeFilter.FILTER_ACCEPT; } else { return NodeFilter.FILTER_SKIP; } }, }); treeWalker.nextNode(); ) { setLink(treeWalker.currentNode); } }; let lockFn = new utils.LockFunction((mutations) => { for (const mutation of mutations) { if ("childList" === mutation.type) { const addedNodes = mutation.addedNodes; for (let nodeIndex = 0; nodeIndex < addedNodes.length; nodeIndex++) { const node = addedNodes[nodeIndex]; observePageChanges(node); } } } }); const initLinkProcessing = function () { linkifyText(document.body); const mutationObserver = utils.mutationObserver(document.body, { config: { subtree: true, childList: true, }, callback: (mutations) => { lockFn.run(mutations); }, }); return mutationObserver; }; const clearLinkHelper = function (linkElement) { const url = linkElement.getAttribute("href"); if ( typeof url === "string" && 0 !== url.indexOf("http") && 0 !== url.indexOf("ed2k://") && 0 !== url.indexOf("thunder://") ) { return linkElement.setAttribute("href", "http://" + url); } }; const clearAllLinks = function () { const linkElements = Array.from(document.getElementsByClassName(HANDLER_CLASS_NAME)); for (const $link of linkElements) { clearLinkHelper($link); } }; document.addEventListener("mouseover", handleClearLink); setTimeout(clearAllLinks, 1500); setTimeout(initLinkProcessing, 100); }; const MTAutoSignIn = { $key: { sign: "mt-sign-time", }, init() { this.sign(); }, checkSignInfo() { let signInfo = this.getSignInfo(); let findValue = signInfo.find((it) => { return it.hostName === window.location.hostname; }); if (findValue) { if (utils.formatTime(Date.now(), "yyyyMMdd") !== utils.formatTime(findValue.time, "yyyyMMdd")) { return false; } return true; } return false; }, setSignInfo() { let signInfo = { hostName: window.location.hostname, time: Date.now(), }; let localSignInfo = this.getSignInfo(); let findIndex = localSignInfo.findIndex((it) => { return it.hostName === signInfo.hostName; }); if (findIndex !== -1) { localSignInfo.splice(findIndex, 1); } localSignInfo.push(signInfo); _GM_setValue(this.$key.sign, localSignInfo); }, getSignInfo() { let localSignInfo = _GM_getValue(this.$key.sign, []); if (!Array.isArray(localSignInfo)) { this.clearSignInfo(); return []; } return localSignInfo; }, getHostNameSignInfo(hostName = window.location.hostname) { let localSignInfo = this.getSignInfo(); return localSignInfo.find((it) => { return it.hostName === hostName; }); }, clearSignInfo(hostName) { if (typeof hostName === "string") { let signInfo = this.getSignInfo(); let findIndex = signInfo.findIndex((it) => { return it.hostName === hostName; }); if (findIndex !== -1) { signInfo.splice(findIndex, 1); } _GM_setValue(this.$key.sign, signInfo); } else { _GM_deleteValue(this.$key.sign); } }, checkLogin() { if (MTUtils.envIsMobile()) { let mobile_login_exitBtn = $("a[href*='member.php?mod=logging&action=logout']"); return Boolean(mobile_login_exitBtn); } else { let pc_login = $("#comiis_key"); return Boolean(pc_login); } }, async sign() { if (this.checkSignInfo()) { log.info("今日已签到"); return; } let formHash = await MTUtils.getFormHash(); if (formHash == null) { if ($("#comiis_picshowbox")) { log.info("当前为评论区的看图模式 "); return; } this.clearSignInfo(window.location.hostname); Qmsg.error("自动签到:获取账号formhash失败", { consoleLogContent: true, }); return; } let useFetch = Boolean(Panel.getValue("mt-auto-sign-useFetch")); let userAgent = utils.getRandomPCUA(); let signSuccessCallBack = () => { this.setSignInfo(); }; let signFailedCallBack = () => { this.clearSignInfo(window.location.hostname); }; let unknownSignContentCallback = (content) => { let $alert = pops.alert({ title: { text: "未知签到内容", position: "center", }, content: { text: "", html: false, }, width: "88vw", height: "300px", }); let $content = $alert.$shadowRoot.querySelector(".pops-alert-content"); $content.innerText = content; }; let sign_plugin = [ { checkPluginEnableUrl: "/plugin.php?id=k_misign:sign", async sign() { let searchParamsData = { operation: "qiandao", format: "button", formhash: formHash, inajax: 1, ajaxtarget: "midaben_sign", }; let response = await httpx.get(`/k_misign-sign.html?${utils.toSearchParamsStr(searchParamsData)}`, { fetch: useFetch, headers: { "User-Agent": userAgent, }, allowInterceptConfig: false, }); if (!response.status) { Qmsg.error("签到:网络异常,请求失败", { consoleLogContent: true, }); return; } signSuccessCallBack(); log.info("签到信息:", response); let responseText = response.data.responseText; let CDATA = utils.parseCDATA(responseText); let CDATAElement = domUtils.toElement(`
${CDATA}
`, true, false); let content = domUtils.text(CDATAElement); if (content.includes("需要先登录")) { Qmsg.error("签到:请先登录账号", { timeout: 3e3, consoleLogContent: true, }); signFailedCallBack(); return; } else if ( content.includes("请稍后再试") || content.includes("您已经被列入黑名单") || content.includes("绑定手机号后才可以签到") || content.includes("您所在用户组不允许使用") ) { Qmsg.error("签到:" + content, { timeout: 5e3, }); return; } else if (content.includes("今日已签") || content.includes("今日已经签到")) { Qmsg.info("签到:" + content); return; } else if (responseText.includes("您当前的访问请求当中含有非法字符,已经被系统拒绝")) { Qmsg.error("签到: 您当前的访问请求当中含有非法字符,已经被系统拒绝", { timeout: 6e3, }); return; } else if (useFetch && "location" in utils.toJSON(responseText)) { Qmsg.success("签到: 签到成功"); return; } let signIn_con = CDATAElement.querySelector(".con"); let signIn_line = CDATAElement.querySelector(".line"); if (signIn_con && signIn_line) { let conMatch = domUtils.text(signIn_con).match(/([0-9]+)金币/); let lineMatch = domUtils.text(signIn_line).match(/([0-9]+)/); let con = conMatch[conMatch.length - 1]; let line = lineMatch[lineMatch.length - 1]; log.success(`金币${con},排名${line}`); Qmsg.info( `
签到
排名 ${line}
金币 ${con}
`, { timeout: 4e3, isHTML: true, } ); return; } unknownSignContentCallback(responseText); }, }, { checkPluginEnableUrl: "/plugin.php?id=dsu_paulsign:sign", async sign() { let searchParamsData = { id: "dsu_paulsign:sign", operation: "qiandao", infloat: 1, inajax: 1, }; let response = await httpx.post(`/plugin.php?${utils.toSearchParamsStr(searchParamsData)}`, { data: { formhash: formHash, qdxq: "kx", qdmode: 3, todaysay: "", fastreply: 0, }, processData: true, fetch: useFetch, headers: { "User-Agent": userAgent, "Content-Type": "application/x-www-form-urlencoded", }, allowInterceptConfig: false, }); if (!response.status) { Qmsg.error("签到:网络异常,请求失败", { consoleLogContent: true, }); return; } signSuccessCallBack(); log.info("签到信息:", response); let responseText = response.data.responseText; if (responseText.includes("签到成功")) { Qmsg.success("签到:签到成功"); return; } if (responseText.includes("今日已经签到")) { Qmsg.info("签到:您今日已经签到,请明天再来!"); return; } unknownSignContentCallback(responseText); }, }, ]; for (let index = 0; index < sign_plugin.length; index++) { const signPluginItem = sign_plugin[index]; let checkResponse = await httpx.get(signPluginItem.checkPluginEnableUrl, { fetch: useFetch, headers: { "User-Agent": utils.getRandomPCUA(), }, allowInterceptConfig: false, }); if (!checkResponse.status) { log.error("签到:检查签到插件是否启用的请求失败", checkResponse); continue; } let pluginDoc = domUtils.toElement(checkResponse.data.responseText, true, true); if (pluginDoc.querySelector("#messagetext") || checkResponse.data.responseText.includes("插件不存在或已关闭")) { log.error(`插件:${signPluginItem.checkPluginEnableUrl} 未启用或不存在`); continue; } await signPluginItem.sign(); break; } }, }; const MTRouter = { isKMiSign() { return window.location.pathname.startsWith("/k_misign-sign.html"); }, isPost() { const searchParams = new URLSearchParams(window.location.search); return ( window.location.pathname.startsWith("/thread-") || (window.location.pathname.startsWith("/forum.php") && searchParams.has("mod", "viewthread")) ); }, isPage() { return Boolean(window.location.pathname.match(/^\/page-([0-9]+).html/g)); }, isGuide() { const searchParams = new URLSearchParams(window.location.search); return window.location.pathname.startsWith("/forum.php") && searchParams.has("mod", "guide"); }, isPlate() { return Boolean(window.location.pathname.match(/\/forum-[0-9]{1,2}-[0-9]{1,2}.html/g)); }, isSearch() { return window.location.pathname.startsWith("/search.php"); }, isSpace() { const searchParams = new URLSearchParams(window.location.search); return window.location.pathname.startsWith("/home.php") && searchParams.has("mod", "space"); }, isMySpace() { const searchParams = new URLSearchParams(window.location.search); return ( window.location.pathname.startsWith("/home.php") && searchParams.has("mod", "space") && searchParams.has("do", "profile") && searchParams.has("mycenter") ); }, isSpaceWithAt() { return window.location.pathname.startsWith("/space-uid-"); }, isForumList() { const searchParams = new URLSearchParams(window.location.search); return window.location.pathname.startsWith("/forum.php") && searchParams.has("forumlist"); }, isMessage() { const searchParams = new URLSearchParams(window.location.search); return ( window.location.pathname.startsWith("/home.php") && searchParams.has("mod", "space") && searchParams.has("do", "notice") ); }, isMessageList() { const searchParams = new URLSearchParams(window.location.search); return ( window.location.pathname.startsWith("/home.php") && searchParams.has("mod", "space") && searchParams.has("do", "pm") ); }, isPointsMall() { const searchParams = new URLSearchParams(window.location.search); return ( window.location.pathname.startsWith("/keke_integralmall-keke_integralmall.html") || (window.location.pathname.startsWith("/plugin.php") && searchParams.has("id", "keke_integralmal")) ); }, isPostPublish() { const searchParams = new URLSearchParams(window.location.search); return window.location.pathname.startsWith("/forum.php") && searchParams.has("mod", "post"); }, isPostPublish_voting() { const searchParams = new URLSearchParams(window.location.search); return ( (window.location.pathname.startsWith("/forum.php") && searchParams.has("special", "1")) || searchParams.has("fid", "42") ); }, isPostPublish_edit() { const searchParams = new URLSearchParams(window.location.search); return this.isPostPublish() && searchParams.has("action", "edit"); }, isPostPublish_newthread() { const searchParams = new URLSearchParams(window.location.search); return this.isPostPublish() && searchParams.has("action", "newthread"); }, isPostPublish_reply() { const searchParams = new URLSearchParams(window.location.search); return this.isPostPublish() && searchParams.has("action", "reply"); }, }; const optimizationCSS$1 = '#comiis_foot_menu_beautify {\r\n position: fixed;\r\n display: inline-flex;\r\n z-index: 90;\r\n left: 0;\r\n right: 0;\r\n bottom: 0;\r\n width: 100%;\r\n height: 48px;\r\n overflow: hidden;\r\n align-content: center;\r\n justify-content: center;\r\n align-items: center;\r\n}\r\n#comiis_foot_menu_beautify_big {\r\n position: fixed;\r\n display: inline-flex;\r\n flex-direction: column;\r\n z-index: 92;\r\n left: 0;\r\n right: 0;\r\n bottom: 0;\r\n width: 100%;\r\n min-height: 120px;\r\n overflow: hidden;\r\n align-content: center;\r\n justify-content: center;\r\n align-items: center;\r\n}\r\n#comiis_foot_menu_beautify input.bg_e.f_c::-webkit-input-placeholder {\r\n padding-left: 10px;\r\n color: #999;\r\n}\r\n#comiis_foot_menu_beautify input.bg_e.f_c::-moz-input-placeholder {\r\n padding-left: 10px;\r\n color: #999;\r\n}\r\n#comiis_foot_menu_beautify .reply_area ul li a {\r\n display: block;\r\n width: 22px;\r\n height: 22px;\r\n padding: 4px 8px;\r\n margin: 8px 0;\r\n position: relative;\r\n}\r\n#comiis_foot_menu_beautify .reply_area ul {\r\n display: inline-flex;\r\n align-content: center;\r\n align-items: center;\r\n justify-content: center;\r\n}\r\n#comiis_foot_menu_beautify .reply_area,\r\n#comiis_foot_menu_beautify .reply_area ul {\r\n width: 100%;\r\n}\r\n#comiis_foot_menu_beautify .reply_area li a i {\r\n width: 22px;\r\n height: 22px;\r\n line-height: 22px;\r\n font-size: 22px;\r\n}\r\n#comiis_foot_menu_beautify .reply_area li a span {\r\n position: absolute;\r\n display: block;\r\n font-size: 10px;\r\n height: 14px;\r\n line-height: 14px;\r\n padding: 0 6px;\r\n right: -8px;\r\n top: 4px;\r\n overflow: hidden;\r\n border-radius: 20px;\r\n}\r\n#comiis_foot_menu_beautify li[data-attr="回帖"] input {\r\n border: transparent;\r\n border-radius: 15px;\r\n height: 30px;\r\n width: 100%;\r\n}\r\n#comiis_foot_menu_beautify_big .comiis_smiley_box {\r\n padding: 6px 6px 0;\r\n}\r\n#comiis_foot_menu_beautify_big .reply_area {\r\n margin: 10px 0 5px 0;\r\n}\r\n#comiis_foot_menu_beautify_big .reply_area ul {\r\n display: inline-flex;\r\n align-content: center;\r\n justify-content: center;\r\n align-items: flex-end;\r\n}\r\n#comiis_foot_menu_beautify_big li[data-attr="回帖"] {\r\n width: 75vw;\r\n margin-right: 15px;\r\n}\r\n#comiis_foot_menu_beautify_big .reply_user_content {\r\n width: 75vw;\r\n word-wrap: break-word;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n margin: 8px 10px;\r\n}\r\n#comiis_foot_menu_beautify_big li[data-attr="发表"] .fastpostform_new {\r\n text-align: center;\r\n margin-bottom: 28px;\r\n}\r\n#comiis_foot_menu_beautify_big li[data-attr="发表"] .fastpostform_new i {\r\n font-size: 22px;\r\n}\r\n#comiis_foot_menu_beautify_big li[data-attr="发表"] input {\r\n width: 60px;\r\n height: 30px;\r\n border: transparent;\r\n color: #fff;\r\n background: #d1c9fc;\r\n border-radius: 30px;\r\n margin-bottom: 6px;\r\n}\r\n#comiis_foot_menu_beautify_big li[data-attr="发表"] input[data-text="true"] {\r\n background: #7a61fb;\r\n}\r\n#comiis_foot_menu_beautify_big li[data-attr="回帖"] textarea {\r\n padding: 10px 10px 10px 10px;\r\n border: transparent;\r\n border-radius: 6px;\r\n min-height: 70px;\r\n max-height: 180px;\r\n background: #e9e8ec;\r\n overflow-y: auto;\r\n width: -webkit-fill-available;\r\n width: -moz-available;\r\n}\r\n#comiis_foot_menu_beautify .reply_area li[data-attr="回帖"] {\r\n width: 65%;\r\n margin: 0 3%;\r\n text-align: center;\r\n}\r\n#comiis_foot_menu_beautify .reply_area li:not(first-child) {\r\n width: 7%;\r\n text-align: -webkit-center;\r\n text-align: center;\r\n}\r\n#comiis_foot_menu_beautify_big .other_area {\r\n width: 100%;\r\n text-align: center;\r\n}\r\n#comiis_foot_menu_beautify_big .other_area .menu_icon a {\r\n margin: 0 20px;\r\n}\r\n#comiis_foot_menu_beautify_big .other_area i {\r\n font-size: 24px;\r\n}\r\n#comiis_foot_menu_beautify_big .other_area #comiis_insert_ubb_tab i {\r\n font-size: 16px;\r\n}\r\n#comiis_foot_menu_beautify_big .other_area .menu_body {\r\n background: #f4f4f4;\r\n}\r\n#comiis_foot_menu_beautify_big .other_area .menu_body .comiis_smiley_box .comiis_optimization {\r\n max-height: 140px;\r\n overflow-y: auto;\r\n flex-direction: column;\r\n}\r\n#comiis_foot_menu_beautify_big .other_area .menu_body .comiis_smiley_box .bqbox_t {\r\n background: #fff;\r\n}\r\n#comiis_foot_menu_beautify_big\r\n .other_area\r\n .menu_body\r\n .comiis_smiley_box\r\n .bqbox_t\r\n ul#comiis_smilies_key\r\n li\r\n a.bg_f.b_l.b_r {\r\n background: #f4f4f4 !important;\r\n}\r\n#comiis_foot_menu_beautify_big .menu_body #comiis_pictitle_tab #comiis_pictitle_key {\r\n display: -webkit-box;\r\n top: 0;\r\n left: 0;\r\n height: 42px;\r\n line-height: 42px;\r\n overflow: hidden;\r\n overflow-x: auto;\r\n}\r\n#comiis_foot_menu_beautify_big .menu_body #comiis_pictitle_tab #comiis_pictitle_key li {\r\n padding: 0 10px;\r\n}\r\n#comiis_foot_menu_beautify_big .menu_body #comiis_insert_ubb_tab .comiis_input_style,\r\n#comiis_foot_menu_beautify_big .menu_body #comiis_pictitle_tab .comiis_upbox {\r\n height: 140px;\r\n overflow-y: auto;\r\n flex-direction: column;\r\n}\r\n#comiis_foot_menu_beautify_big .menu_body #comiis_pictitle_tab #filedata_hello,\r\n#comiis_foot_menu_beautify_big .menu_body #comiis_pictitle_tab #filedata_kggzs,\r\n#comiis_foot_menu_beautify_big .menu_body #comiis_pictitle_tab #filedata_mt,\r\n#comiis_foot_menu_beautify_big .menu_body #comiis_pictitle_tab #filedata_z4a {\r\n display: none;\r\n}\r\n@media screen and (max-width: 350px) {\r\n .comiis_bqbox .bqbox_c li {\r\n width: 14.5%;\r\n }\r\n}\r\n@media screen and (min-width: 350px) and (max-width: 400px) {\r\n .comiis_bqbox .bqbox_c li {\r\n width: 12.5%;\r\n }\r\n}\r\n@media screen and (min-width: 400px) and (max-width: 450px) {\r\n .comiis_bqbox .bqbox_c li {\r\n width: 11%;\r\n }\r\n}\r\n@media screen and (min-width: 450px) and (max-width: 500px) {\r\n .comiis_bqbox .bqbox_c li {\r\n width: 10%;\r\n }\r\n}\r\n@media screen and (min-width: 500px) and (max-width: 550px) {\r\n .comiis_bqbox .bqbox_c li {\r\n width: 9.5%;\r\n }\r\n}\r\n@media screen and (min-width: 550px) and (max-width: 600px) {\r\n .comiis_bqbox .bqbox_c li {\r\n width: 9%;\r\n }\r\n}\r\n@media screen and (min-width: 600px) and (max-width: 650px) {\r\n .comiis_bqbox .bqbox_c li {\r\n width: 8.5%;\r\n }\r\n}\r\n@media screen and (min-width: 650px) and (max-width: 700px) {\r\n .comiis_bqbox .bqbox_c li {\r\n width: 8%;\r\n }\r\n}\r\n@media screen and (min-width: 700px) and (max-width: 750px) {\r\n .comiis_bqbox .bqbox_c li {\r\n width: 7.5%;\r\n }\r\n}\r\n@media screen and (min-width: 750px) and (max-width: 800px) {\r\n .comiis_bqbox .bqbox_c li {\r\n width: 7%;\r\n }\r\n}\r\n@media screen and (min-width: 800px) and (max-width: 850px) {\r\n .comiis_bqbox .bqbox_c li {\r\n width: 6.5%;\r\n }\r\n}\r\n@media screen and (min-width: 850px) and (max-width: 1200px) {\r\n .comiis_bqbox .bqbox_c li {\r\n width: 6%;\r\n }\r\n}\r\n@media screen and (min-width: 1200px) {\r\n .comiis_bqbox .bqbox_c li {\r\n width: 4.5%;\r\n }\r\n}\r\n#imglist_settings button {\r\n font-size: 13.333px;\r\n color: #9baacf;\r\n outline: 0;\r\n border: none;\r\n height: 35px;\r\n width: 80px;\r\n border-radius: 10px;\r\n box-shadow:\r\n 0.3rem 0.3rem 0.6rem #c8d0e7,\r\n -0.2rem -0.2rem 0.5rem #fff;\r\n font-weight: 800;\r\n line-height: 40px;\r\n background: #efefef;\r\n padding: 0;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n}\r\n#imglist_settings button:active {\r\n box-shadow:\r\n inset 0.2rem 0.2rem 0.5rem #c8d0e7,\r\n inset -0.2rem -0.2rem 0.5rem #fff !important;\r\n color: #638ffb !important;\r\n}\r\n\r\n#comiis_head .header_y {\r\n display: flex;\r\n align-content: center;\r\n align-items: center;\r\n justify-content: flex-end;\r\n height: 100%;\r\n}\r\n#comiis_head .header_y input {\r\n border: transparent;\r\n background: 0 0;\r\n text-align: center;\r\n margin: 0 5px;\r\n}\r\n#comiis_head .header_y input[value="删除"] {\r\n color: #d00;\r\n}\r\n#comiis_head .header_y input[value="保存"] {\r\n color: #b0ff6a;\r\n}\r\n#comiis_head .header_y input[value="保存草稿"] {\r\n color: #f90;\r\n}\r\n#comiis_head .header_y input[value="发表"] {\r\n color: #b0ff6a;\r\n}\r\n#comiis_head .header_y input[value="回复"] {\r\n color: #b0ff6a;\r\n}\r\n#comiis_post_tab {\r\n color: #000;\r\n}\r\n#comiis_pictitle_tab #imglist input {\r\n display: none;\r\n}\r\n\r\n.comiis_post_imglist .delImg {\r\n position: absolute;\r\n top: -5px;\r\n left: -5px;\r\n}\r\n\r\n.comiis_post_imglist .p_img a {\r\n float: left;\r\n height: 36px;\r\n}\r\n#imglist .p_img a {\r\n float: left;\r\n height: 36px;\r\n}\r\n#imglist .del a {\r\n padding: 0;\r\n}\r\n'; const MTEditorSmilies = () => { return [ { "[呵呵]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq001.gif", "[撇嘴]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq002.gif", "[色]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq003.gif", "[发呆]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq004.gif", "[得意]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq005.gif", "[流泪]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq006.gif", "[害羞]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq007.gif", "[闭嘴]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq008.gif", "[睡]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq009.gif", "[大哭]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq010.gif", "[尴尬]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq011.gif", "[发怒]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq012.gif", "[调皮]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq013.gif", "[呲牙]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq014.gif", "[惊讶]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq015.gif", "[难过]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq016.gif", "[酷]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq017.gif", "[冷汗]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq018.gif", "[抓狂]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq019.gif", "[吐]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq020.gif", "[偷笑]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq021.gif", "[可爱]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq022.gif", "[白眼]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq023.gif", "[傲慢]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq024.gif", "[饥饿]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq025.gif", "[困]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq026.gif", "[惊恐]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq027.gif", "[流汗]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq028.gif", "[憨笑]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq029.gif", "[装逼]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq030.gif", "[奋斗]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq031.gif", "[咒骂]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq032.gif", "[疑问]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq033.gif", "[嘘]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq034.gif", "[晕]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq035.gif", "[折磨]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq036.gif", "[衰]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq037.gif", "[骷髅]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq038.gif", "[敲打]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq039.gif", "[再见]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq040.gif", "[擦汗]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq041.gif", "[抠鼻]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq042.gif", "[鼓掌]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq043.gif", "[糗大了]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq044.gif", "[坏笑]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq045.gif", "[左哼哼]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq046.gif", "[右哼哼]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq047.gif", "[哈欠]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq048.gif", "[鄙视]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq049.gif", "[委屈]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq050.gif", "[快哭了]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq051.gif", "[阴脸]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq052.gif", "[亲亲]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq053.gif", "[吓]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq054.gif", "[可怜]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq055.gif", "[眨眼睛]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq056.gif", "[笑哭]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq057.gif", "[dogeQQ]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq058.gif", "[泪奔]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq059.gif", "[无奈]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq060.gif", "[托腮]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq061.gif", "[卖萌]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq062.png", "[斜眼笑]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq063.gif", "[喷血]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq064.gif", "[惊喜]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq065.gif", "[骚扰]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq066.gif", "[小纠结]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq067.gif", "[我最美]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq068.gif", "[菜刀]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq069.gif", "[西瓜]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq070.gif", "[啤酒]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq071.gif", "[篮球]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq072.gif", "[乒乓]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq073.gif", "[咖啡]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq074.gif", "[饭]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq075.gif", "[猪]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq076.gif", "[玫瑰]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq077.gif", "[凋谢]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq078.gif", "[示爱]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq079.gif", "[爱心]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq080.gif", "[心碎]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq081.gif", "[蛋糕]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq082.gif", "[闪电]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq083.gif", "[炸弹]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq084.gif", "[刀]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq085.gif", "[足球]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq086.gif", "[瓢虫]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq087.gif", "[便便]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq088.gif", "[月亮]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq089.gif", "[太阳]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq090.gif", "[礼物]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq091.gif", "[抱抱]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq092.gif", "[喝彩]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq93.gif", "[祈祷]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq94.gif", "[棒棒糖]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq95.gif", "[药]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq96.gif", "[赞]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq097.gif", "[差劲]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq098.gif", "[握手]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq099.gif", "[胜利]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq100.gif", "[抱拳]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq101.gif", "[勾引]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq102.gif", "[拳头]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq103.gif", "[爱你]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq105.gif", "[NO]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq106.gif", "[OK]": "https://cdn-bbs.mt2.cn/static/image/smiley/qq/qq107.gif", }, { "[#呵呵]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_1.png", "[#滑稽]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_10.png", "[#吐舌]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_3.png", "[#哈哈]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_2.png", "[#啊]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_23.png", "[#酷]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_22.png", "[#怒]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_13.png", "[#开心]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_39.png", "[#汗]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_14.png", "[#泪]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_16.png", "[#黑线]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_15.png", "[#鄙视]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_21.png", "[#不高兴]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_12.png", "[#真棒]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_17.png", "[#钱]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_40.png", "[#疑问]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_26.png", "[#阴险]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_20.png", "[#吐]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_34.png", "[#咦]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_41.png", "[#委屈]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_29.png", "[#花心]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_6.png", "[#呼~]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_42.png", "[#激动]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_5.png", "[#冷]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_43.png", "[#可爱]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_4.png", "[#What?]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_25.png", "[#勉强]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_38.png", "[#狂汗]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_24.png", "[#酸爽]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_27.png", "[#乖]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_8.png", "[#雅美蝶]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_28.png", "[#睡觉]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_31.png", "[#惊哭]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_19.png", "[#哼]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_44.png", "[#笑尿]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_32.png", "[#惊讶]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_30.png", "[#小乖]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_7.png", "[#喷]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_18.png", "[#抠鼻]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_33.png", "[#捂嘴笑]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_9.png", "[#你懂的]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_11.png", "[#犀利]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_35.png", "[#小红脸]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_36.png", "[#懒得理]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_37.png", "[#爱心]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_45.png", "[#心碎]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_46.png", "[#玫瑰]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_47.png", "[#礼物]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_48.png", "[#彩虹]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_49.png", "[#太阳]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_50.png", "[#月亮]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_51.png", "[#钱币]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_52.png", "[#咖啡]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_53.png", "[#蛋糕]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_54.png", "[#大拇指]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_55.png", "[#胜利]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_56.png", "[#爱你]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_57.png", "[#OK]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_58.png", "[#弱]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_59.png", "[#沙发]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_60.png", "[#纸巾]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_61.png", "[#香蕉]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_62.png", "[#便便]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_63.png", "[#药丸]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_64.png", "[#红领巾]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_65.png", "[#蜡烛]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_66.png", "[#三道杠]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_67.png", "[#音乐]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_68.png", "[#灯泡]": "https://cdn-bbs.mt2.cn/static/image/smiley/comiis_tb/tb_69.png", }, { "[doge]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/1.png", "[doge思考]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/2.png", "[doge再见]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/3.png", "[doge生气]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/4.png", "[doge气哭]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/5.png", "[doge笑哭]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/7.png", "[doge调皮]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/6.png", "[doge啊哈]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/8.png", "[doge原谅TA]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/9.png", "[miao]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/10.png", "[miao思考]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/11.png", "[miao拜拜]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/12.png", "[miao生气]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/13.png", "[miao气哭]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/14.png", "[二哈]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/15.png", "[摊手]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/19.png", "[w并不简单]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/20.png", "[w滑稽]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/21.png", "[w色]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/22.png", "[w爱你]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/23.png", "[w拜拜]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/24.png", "[w悲伤]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/25.png", "[w鄙视]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/26.png", "[w馋嘴]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/27.png", "[w冷汗]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/28.png", "[w打哈欠]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/29.png", "[w打脸]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/30.png", "[w敲打]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/31.png", "[w生病]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/32.png", "[w闭嘴]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/33.png", "[w鼓掌]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/34.png", "[w哈哈]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/35.png", "[w害羞]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/36.png", "[w呵呵]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/37.png", "[w黑线]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/38.png", "[w哼哼]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/39.png", "[w调皮]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/40.png", "[w可爱]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/41.png", "[w可怜]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/42.png", "[w酷]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/43.png", "[w困]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/44.png", "[w懒得理你]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/45.png", "[w流泪]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/46.png", "[w怒]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/47.png", "[w怒骂]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/48.png", "[w钱]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/49.png", "[w亲亲]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/50.png", "[w傻眼]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/51.png", "[w便秘]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/52.png", "[w失望]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/53.png", "[w衰]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/54.png", "[w睡觉]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/55.png", "[w思考]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/56.png", "[w开心]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/57.png", "[w色舔]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/58.png", "[w偷笑]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/59.png", "[w吐]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/60.png", "[w抠鼻]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/61.png", "[w委屈]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/62.png", "[w笑哭]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/63.png", "[w嘻嘻]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/64.png", "[w嘘]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/65.png", "[w阴险]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/66.png", "[w疑问]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/67.png", "[w抓狂]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/70.png", "[w晕]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/69.png", "[w右哼哼]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/68.png", "[w左哼哼]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/71.png", "[w肥皂]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/77.png", "[w奥特曼]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/78.png", "[w草泥马]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/79.png", "[w兔子]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/80.png", "[w熊猫]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/81.png", "[w猪头]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/82.png", "[w→_→]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/83.png", "[w给力]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/84.png", "[w囧]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/85.png", "[w萌]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/86.png", "[w神马]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/87.png", "[w威武]": "https://cdn-bbs.mt2.cn/static/image/smiley/doge/88.png", }, ]; }; const GlobalImageDelete = []; class MTEditorImageBed { option; $data = { STORAGE_KEY: "mt-image-bed-upload-history", }; constructor(option) { this.option = option; GlobalImageDelete.push({ id: this.option.id, callback: this.option.delImageEvent.bind(this), }); this.addTab(); domUtils.on(`.comiis_post_imglist[data-chartbed="${this.option.name}"] .up_btn a`, "click", async (event) => { let result = await this.option.uploadBtnClickEvent(event); if (result) { $(`.comiis_post_imglist[data-chartbed="${this.option.name}"] input[type="file"]`).click(); } }); domUtils.on( `.comiis_post_imglist[data-chartbed="${this.option.name}"] input[type="file"]`, "change", async (event) => { let $file = event.target; let clear_input = () => { $file.value = ""; }; let upload_callback = async (uploadFiles) => { let uploadInfo = await this.option.fileChangeEvent(event, uploadFiles); clear_input(); if (uploadInfo.success) { uploadInfo.data.forEach((imageInfo) => { this.addImage(imageInfo); let $thumbImage = this.createImageBtnElement("插入", imageInfo.url); this.setImageBtnDeleteEvent($thumbImage, imageInfo); domUtils.append(`.comiis_post_imglist[data-chartbed="${this.option.name}"]`, $thumbImage); }); } }; if ($file.files && $file.files.length) { let chooseImage = $file.files; if (Panel.getValue("mt-image-bed-watermark-enable")) { let $loading = Qmsg.loading("处理水印中..."); let needUploadImageArray = []; let needUploadImageFileArray = []; await Promise.all( Array.from($file.files).map(async (item, index) => { if (item.type === "image/gif") { let image_base64 = await utils.parseFileToBase64(item); needUploadImageArray.push(image_base64); needUploadImageFileArray.push(item); } else { Qmsg.info(`添加水印 ${index + 1}/${chooseImage.length}`); var watermark = new window.Watermark(); await watermark.setFile(item); watermark.addText({ text: [Panel.getValue("mt-image-bed-watermark-text")], color: Panel.getValue("mt-image-bed-watermark-text-color"), fontSize: Panel.getValue("mt-image-bed-watermark-font-size"), globalAlpha: Panel.getValue("mt-image-bed-watermark-font-opacity"), xMoveDistance: Panel.getValue("mt-image-bed-watermark-left-right-margin"), yMoveDistance: Panel.getValue("mt-image-bed-watermark-top-bottom-margin"), rotateAngle: Panel.getValue("mt-image-bed-watermark-rotate"), }); needUploadImageArray.push(watermark.render("png")); needUploadImageFileArray.push( utils.parseBase64ToFile(watermark.render("png"), "WaterMark_" + item.name) ); } }) ); $loading.close(); chooseImage = needUploadImageFileArray; if (Panel.getValue("mt-image-bed-watermark-autoAddWaterMark")) { await upload_callback(chooseImage); } else { __pops.confirm({ title: { text: "水印预览", position: "center", }, content: { text: `
${needUploadImageArray .map((item) => { return ``; }) .join("\n")}
`, html: true, }, btn: { ok: { text: "继续上传", async callback(eventDetails, event2) { eventDetails.close(); await upload_callback(chooseImage); }, }, close: { callback(details, event2) { details.close(); clear_input(); }, }, cancel: { callback(eventDetails, event2) { eventDetails.close(); clear_input(); }, }, }, width: "88vw", height: "80vh", style: ` .upload-image-water { } .upload-image-water img{ width: 100%; } `, }); } } else { await upload_callback(chooseImage); } } } ); } addTab() { let $picture_key = $("#comiis_pictitle_key"); let $history = $picture_key.querySelector("a[data-type='history']"); let tabHTML = `
  • ${this.option.name}
  • `; if (!$history) { let $history_parent = domUtils.createElement("li"); $history = domUtils.createElement( "a", { href: "javascript:;", className: "comiis-picture-tab", innerHTML: `历史图片`, }, { "data-type": "history" } ); domUtils.on($history, "click", () => { this.initHistoryUploadImageList(); }); domUtils.append($history_parent, $history); domUtils.append($picture_key, $history_parent); } domUtils.before($history.parentElement, tabHTML); let $box = $("#comiis_pictitle_tab .bqbox_t"); let $historyBox = Array.from($$("#comiis_pictitle_tab .comiis_upbox")).find((item) => Boolean(item.querySelector("#imglist_history")) ); if (!$historyBox) { $historyBox = domUtils.createElement( "div", { className: "comiis_upbox bg_f cl", innerHTML: `
    `, }, { style: "display: none;", } ); domUtils.before($box, $historyBox); $historyBox = Array.from($$("#comiis_pictitle_tab .comiis_upbox")).find((item) => Boolean(item.querySelector("#imglist_history")) ); } domUtils.before( $historyBox, ` ` ); } createImageBtnElement(labelName, url) { let $li = domUtils.createElement("li", { innerHTML: ` ${labelName} `, }); return $li; } initHistoryUploadImageList() { let $imglist_history = $("#comiis_pictitle_tab #imglist_history"); $imglist_history.innerHTML = ""; let $fragment = document.createDocumentFragment(); this.getAllImage().forEach((item) => { let $thumbImage = this.createImageBtnElement(item.labelName, item.data.url); this.setHistoryImageBtnDeleteEvent($thumbImage, item); $fragment.appendChild($thumbImage); }); $imglist_history.appendChild($fragment); } setImageBtnDeleteEvent($ele, data) { let $delImg = $ele.querySelector(".delImg"); domUtils.on($delImg, "click", async (event) => { let result = await this.option.delImageEvent(event, data); if (result) { let deleteStorageStatus = this.deleteImage(this.option.id, data); if (deleteStorageStatus) { domUtils.remove($ele); } } }); } setHistoryImageBtnDeleteEvent($ele, data) { let $delImg = $ele.querySelector(".delImg"); domUtils.on($delImg, "click", async (event) => { let findValue = GlobalImageDelete.find((item) => item.id === data.id); if (!findValue) { return; } let result = await findValue.callback(event, data.data); if (result) { let deleteStorageStatus = this.deleteImage(data.id, data.data); if (deleteStorageStatus) { domUtils.remove($ele); } } }); } addImage(info) { let allData = _GM_getValue(this.$data.STORAGE_KEY, []); allData.push({ id: this.option.id, name: this.option.name, labelName: this.option.labelName, data: info, }); _GM_setValue(this.$data.STORAGE_KEY, allData); } getAllImage() { let allData = _GM_getValue(this.$data.STORAGE_KEY, []); return allData; } deleteImage(id, data) { let allData = this.getAllImage(); let findIndex = allData.findIndex((item) => item.id === id && JSON.stringify(item.data) === JSON.stringify(data)); if (findIndex != -1) { allData.splice(findIndex, 1); _GM_setValue(this.$data.STORAGE_KEY, allData); return true; } else { return false; } } } const MTEditorImageBed_Hello = { $data: { get account() { return Panel.getValue("mt-image-bed-hello-account"); }, get password() { return Panel.getValue("mt-image-bed-hello-password"); }, get token() { return Panel.getValue("mt-image-bed-hello-token"); }, }, $code: { 401: "未登录或授权失败", 403: "管理员关闭了接口功能或没有该接口权限", 429: "超出请求配额,请求受限", 500: "服务端出现异常", }, $config: { base_url: "https://www.helloimg.com/api/v1", TAG: "Hello图床:", }, $tabConfig: { id: "www.helloimg.com", name: "Hello图床", labelName: "hello", }, init() { const that = this; new MTEditorImageBed({ id: this.$tabConfig.id, name: this.$tabConfig.name, labelName: this.$tabConfig.labelName, async uploadBtnClickEvent(event) { return await that.checkLogin(); }, async fileChangeEvent(event, fileList) { let uploadList = []; let $loading = Qmsg.loading("上传中..."); let flag = true; for (let index = 0; index < Array.from(fileList).length; index++) { const file = Array.from(fileList)[index]; let result = await that.uploadImage(file); if (result) { uploadList.push({ url: result.data.links.url, data: result.data, }); flag = flag && true; } else { flag = flag && false; } } $loading.close(); return { success: flag, data: uploadList, }; }, storageSaveCallBack(data) { return data.data; }, async delImageEvent(event, data) { let isLogin = await that.checkLogin(); if (isLogin) { let $loading = Qmsg.loading("正在删除图片..."); let deleteResult = (await that.deleteImage(data.data.key)) ?? false; $loading.close(); return deleteResult; } else { return false; } }, }); }, async checkLogin() { if (!this.$data.account) { Qmsg.error(`${this.$config.TAG}请先配置账号`); return false; } if (!this.$data.password) { Qmsg.error(`${this.$config.TAG}请先配置密码`); return false; } if (!this.$data.token) { Qmsg.error(`${this.$config.TAG}请先配置token`); return false; } return true; }, async uploadImage(imageFile) { let formData = new FormData(); formData.append("file", imageFile); formData.append("permission", "0"); formData.append("strategy_id", "0"); formData.append("album_id", "0"); let response = await httpx.post(`${this.$config.base_url}/upload`, { data: formData, headers: { Accept: "application/json", Authorization: `Bearer ${this.$data.token}`, "User-Agent": utils.getRandomPCUA(), Referer: `${this.$config.base_url}/`, Origin: this.$config.base_url, }, allowInterceptConfig: false, }); if (!response.status) { log.error(response); Qmsg.error(this.$config.TAG + "网络异常,上传图片失败"); return; } if (response.data.status in this.$code) { log.error(response); Qmsg.error(this.$config.TAG + this.$code[response.data.status]); return; } let data = utils.toJSON(response.data.responseText); log.info(data); if (!data.status) { Qmsg.error(this.$config.TAG + data.message); return; } Qmsg.success(this.$config.TAG + "上传成功"); let file_reader = new FileReader(); file_reader.readAsDataURL(imageFile); return await new Promise((resolve) => { file_reader.onload = function () { let imageUri = this.result; let result = { imageUri, data: data.data, }; resolve(result); }; }); }, async deleteImage(imageKey) { let response = await httpx.delete(this.$config.base_url + "/images/" + imageKey, { timeout: 15e3, headers: { Accept: "application/json", Authorization: `Bearer ${this.$data.token}`, "User-Agent": utils.getRandomPCUA(), Referer: `${this.$config.base_url}/`, Origin: this.$config.base_url, }, allowInterceptConfig: false, }); if (response.data.status in this.$code) { Qmsg.error(this.$config.TAG + this.$code[response.data.status]); return false; } let data = utils.toJSON(response.data.responseText); if (!data.status) { Qmsg.error(this.$config.TAG + data.message); return false; } Qmsg.success(this.$config.TAG + "删除成功"); return true; }, }; const MTEditorImageBed_MT = { $data: { csrf_token: null, }, $config: { TAG: "MT图床:", base_url: "https://img.binmt.cc", }, $tabConfig: { id: "img.binmt.cc", name: "MT图床", labelName: "mt", }, init() { const that = this; new MTEditorImageBed({ id: this.$tabConfig.id, name: this.$tabConfig.name, labelName: this.$tabConfig.labelName, async uploadBtnClickEvent(event) { return await that.checkLogin(); }, async fileChangeEvent(event, fileList) { let uploadList = []; let $loading = Qmsg.loading("上传中..."); let flag = true; for (let index = 0; index < Array.from(fileList).length; index++) { const file = Array.from(fileList)[index]; let result = await that.uploadImage(file); if (result) { uploadList.push({ url: result.data.links.url, data: result.data, }); flag = flag && true; } else { flag = flag && false; } } $loading.close(); return { success: flag, data: uploadList, }; }, storageSaveCallBack(data) { return data.data; }, async delImageEvent(event, data) { return true; }, }); }, async checkLogin() { if (!this.$data.csrf_token) { let $loading = Qmsg.loading("正在获取CSRF Token中..."); let csrf_token = await this.getCSRFToken(); $loading.close(); if (!csrf_token) { return false; } this.$data.csrf_token = csrf_token; } return true; }, async getCSRFToken() { let response = await httpx.get(this.$config.base_url, { allowInterceptConfig: false, headers: { "User-Agent": utils.getRandomPCUA(), Referer: this.$config.base_url + "/", Origin: this.$config.base_url, }, }); if (!response.status) { Qmsg.error(this.$config.TAG + "获取CSRF Token失败,网络异常"); return; } let doc = domUtils.toElement(response.data.responseText, true, true); let metaCSRFToken = doc.querySelector('meta[name="csrf-token"]')?.getAttribute("content"); if (!metaCSRFToken) { return; } log.info("获取的CSRF token:", metaCSRFToken); Qmsg.success(this.$config.TAG + "获取CSRF Token成功"); return metaCSRFToken; }, async uploadImage(imageFile) { let formData = new FormData(); formData.append("strategy_id", "2"); formData.append("file", imageFile); let response = await httpx.post(`${this.$config.base_url}/upload`, { data: formData, headers: { Accept: "application/json, text/javascript, */*; q=0.01", "User-Agent": utils.getRandomAndroidUA(), Origin: this.$config.base_url, pragma: "no-cache", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6", Referer: this.$config.base_url + "/", Pragma: "no-cache", "x-csrf-token": this.$data.csrf_token, "X-Requested-With": "XMLHttpRequest", }, allowInterceptConfig: false, }); if (!response.status) { log.error(response); Qmsg.error(this.$config.TAG + "网络异常,上传图片失败"); return; } let data = utils.toJSON(response.data.responseText); log.info(data); if (!data.status) { log.error(response); Qmsg.error(this.$config.TAG + data.message || JSON.stringify(data)); return; } Qmsg.success(this.$config.TAG + "上传成功"); let file_reader = new FileReader(); file_reader.readAsDataURL(imageFile); return await new Promise((resolve) => { file_reader.onload = function () { let imageUri = this.result; let result = { imageUri, data: data.data, }; resolve(result); }; }); }, }; const MTQuickUBB = () => { return { rainbow1: { key: "转普通彩虹", value: "", isFunc: true, num: 1, }, rainbow2: { key: "转黑白彩虹", value: "", isFunc: true, num: 2, }, rainbow3: { key: "转黑红彩虹", value: "", isFunc: true, num: 3, }, rainbow4: { key: "转蓝绿彩虹", value: "", isFunc: true, num: 4, }, size: { key: "大小", value: "[size=][/size]", tagL: "=", tagR: "]", L: "[size=]", R: "[/size]", cursorL: "[size=", cursorLength: 6, quickUBBReplace: "[size=14]replace[/size]", }, color: { key: "颜色", value: "[color=][/color]", tagL: "=", tagR: "]", L: "[color=]", R: "[/color]", cursorL: "[color=", cursorLength: 7, quickUBBReplace: "[color=#000]replace[/color]", }, b: { key: "加粗", value: "[b][/b]", tagL: "]", tagR: "[", L: "[b]", R: "[/b]", cursorR: "[/b]", cursorLength: 4, quickUBBReplace: "[b]replace[/b]", }, u: { key: "下划线", value: "[u][/u]", tagL: "]", tagR: "[", L: "[u]", R: "[/u]", cursorR: "[/u]", cursorLength: 4, quickUBBReplace: "[u]replace[/u]", }, i: { key: "倾斜", value: "[i][/i]", tagL: "]", tagR: "[", L: "[i]", R: "[/i]", cursorR: "[/i]", cursorLength: 4, quickUBBReplace: "[i]replace[/i]", }, s: { key: "中划线", value: "[s][/s]", tagL: "]", tagR: "[", L: "[s]", R: "[/s]", cursorR: "[/s]", cursorLength: 4, quickUBBReplace: "[s]replace[/s]", }, lineFeed: { key: "换行", value: "[*]", L: "", R: "[*]", cursorL: "[*]", cursorLength: 3, quickUBBReplace: "replace[*]", }, longHorizontalLine: { key: "水平线", value: "[hr]", L: "", R: "[hr]", cursorL: "[hr]", cursorLength: 4, quickUBBReplace: "replace[hr]", }, link: { key: "链接", value: "[url=][/url]", tagL: "=", tagR: "]", L: "[url=]", R: "[/url]", cursorL: "[url=", cursorLength: 5, quickUBBReplace: "[url=replace]replace[/url]", }, hide: { key: "隐藏", value: "[hide]\n[/hide]", tagL: "]", tagR: "[", L: "[hide]", R: "[/hide]", cursorR: "[/hide]", cursorLength: 7, quickUBBReplace: "[hide]replace\n[/hide]", }, quote: { key: "引用", value: "[quote][/quote]", tagL: "]", tagR: "[", L: "[quote]", R: "[/quote]", cursorR: "[/quote]", cursorLength: 8, quickUBBReplace: "[quote]replace[/quote]", }, email: { key: "邮件", value: "[email=][/email]", tagL: "=", tagR: "]", L: "[email=]", R: "[/email]", cursorL: "[email=", cursorLength: 7, quickUBBReplace: "[email=replace]replace[/email]", }, }; }; const MTUBB_Rainbow = (num, text) => { if (text == "") { return ""; } var wr_text = text; var wr_code, wr_rgb, r, g, b, i, j, istep; r = 0; g = 0; b = 0; istep = 0; wr_code = ""; if (num == 1) { istep = 40; r = 255; i = 1; j = 0; do { if (wr_text.charCodeAt(j) != 32) { if (g + istep < 256) { if (i == 1) g += istep; } else if (i == 1) { i = 2; g = 255; } if (r - istep > -1) { if (i == 2) r -= istep; } else if (i == 2) { i = 3; r = 0; } if (b + istep < 256) { if (i == 3) b += istep; } else if (i == 3) { i = 4; b = 255; } if (g - istep > -1) { if (i == 4) g -= istep; } else if (i == 4) { i = 5; g = 0; } if (r + istep < 256) { if (i == 5) r += istep; } else if (i == 5) { i = 6; r = 255; } if (b - istep > -1) { if (i == 6) b -= istep; } else if (i == 6) { i = 1; b = 0; } wr_rgb = ""; wr_rgb += parseInt(r).toString(16).length == 1 ? 0 + parseInt(r).toString(16) : parseInt(r).toString(16); wr_rgb += parseInt(g).toString(16).length == 1 ? 0 + parseInt(g).toString(16) : parseInt(g).toString(16); wr_rgb += parseInt(b).toString(16).length == 1 ? 0 + parseInt(b).toString(16) : parseInt(b).toString(16); wr_rgb = wr_rgb.toUpperCase(); wr_code += `[color=#${wr_rgb}]${wr_text.charAt(j)}[/color]`; } else { wr_code += wr_text.charAt(j); } j++; } while (j < wr_text.length); } else if (num == 2) { istep = 255 / wr_text.length; for (i = 1; i < wr_text.length + 1; i++) { if (wr_text.charCodeAt(i - 1) != 32) { r += istep; g += istep; b += istep; if (r > 255) r = 255; if (g > 255) g = 255; if (b > 255) b = 255; wr_rgb = ""; wr_rgb += parseInt(r).toString(16).length == 1 ? 0 + parseInt(r).toString(16) : parseInt(r).toString(16); wr_rgb += parseInt(g).toString(16).length == 1 ? 0 + parseInt(g).toString(16) : parseInt(g).toString(16); wr_rgb += parseInt(b).toString(16).length == 1 ? 0 + parseInt(b).toString(16) : parseInt(b).toString(16); wr_rgb = wr_rgb.toUpperCase(); wr_code += `[color=#${wr_rgb}]${wr_text.charAt(i - 1)}[/color]`; } else { wr_code += wr_text.charAt(i - 1); } } } else if (num == 3) { istep = 255 / wr_text.length; for (i = 1; i < wr_text.length + 1; i++) { if (wr_text.charCodeAt(i - 1) != 32) { r += istep; g = 29; b = 36; if (r > 255) r = 255; if (g > 255) g = 255; if (b > 255) b = 255; wr_rgb = ""; wr_rgb += parseInt(r).toString(16).length == 1 ? 0 + parseInt(r).toString(16) : parseInt(r).toString(16); wr_rgb += parseInt(g).toString(16).length == 1 ? 0 + parseInt(g).toString(16) : parseInt(g).toString(16); wr_rgb += parseInt(b).toString(16).length == 1 ? 0 + parseInt(b).toString(16) : parseInt(b).toString(16); wr_rgb = wr_rgb.toUpperCase(); wr_code += `[color=#${wr_rgb}]${wr_text.charAt(i - 1)}[/color]`; } else { wr_code += wr_text.charAt(i - 1); } } } else if (num == 4) { istep = 255 / wr_text.length; for (i = 1; i < wr_text.length + 1; i++) { if (wr_text.charCodeAt(i - 1) != 32) { r = 0; g = 174; b += istep; if (r > 255) r = 255; if (g > 255) g = 255; if (b > 255) b = 255; wr_rgb = ""; wr_rgb += parseInt(r).toString(16).length == 1 ? 0 + parseInt(r).toString(16) : parseInt(r).toString(16); wr_rgb += parseInt(g).toString(16).length == 1 ? 0 + parseInt(g).toString(16) : parseInt(g).toString(16); wr_rgb += parseInt(255 - b).toString(16).length == 1 ? 0 + parseInt(255 - b).toString(16) : parseInt(255 - b).toString(16); wr_rgb = wr_rgb.toUpperCase(); wr_code += `[color=#${wr_rgb}]${wr_text.charAt(i - 1)}[/color]`; } else { wr_code += wr_text.charAt(i - 1); } } } return wr_code; }; const ExtendJQueryFn = function () { _unsafeWindow.$.fn.extend({ insertAtCaret: function (myValue) { var $t = _unsafeWindow.$(this)[0]; if (document.selection) { this.focus(); var sel = document.selection.createRange(); sel.text = myValue; this.focus(); } else if ($t.selectionStart || $t.selectionStart == "0") { var startPos = $t.selectionStart; var endPos = $t.selectionEnd; var scrollTop = $t.scrollTop; $t.value = $t.value.substring(0, startPos) + myValue + $t.value.substring(endPos, $t.value.length); this.focus(); $t.selectionStart = startPos + myValue.length; $t.selectionEnd = startPos + myValue.length; $t.scrollTop = scrollTop; } else { this.value += myValue; this.focus(); } }, selectRange: function (start, end) { if (end === void 0) { end = start; } return this.each(function () { if ("selectionStart" in this) { this.selectionStart = start; this.selectionEnd = end; } else if (this.setSelectionRange) { this.setSelectionRange(start, end); } else if (this.createTextRange) { var range = this.createTextRange(); range.collapse(true); range.moveEnd("character", end); range.moveStart("character", start); range.select(); } }); }, getCursorPosition: function () { var el = _unsafeWindow.$(this)[0]; var pos = 0; if ("selectionStart" in el) { pos = el.selectionStart; } else if ("selection" in document) { el.focus(); var Sel = document.selection.createRange(); var SelLength = document.selection.createRange().text.length; Sel.moveStart("character", -el.value.length); pos = Sel.text.length - SelLength; } return pos; }, moveCursorInCenterByText: function (leftTextFlag, rightTextFlag) { var el = _unsafeWindow.$(this)[0]; var el_text = el.value; for (let i = el.selectionStart - 1; i > 0; i--) { let LText = el_text[i - 1]; let currentText = el_text[i]; if (LText == leftTextFlag && currentText == rightTextFlag) { this.selectRange(i); break; } } }, moveCursorToCenterByTextWithLeft: function (leftMatchText, _length_) { var el = _unsafeWindow.$(this)[0]; var el_text = el.value; for (let index = el.selectionStart - 1; index > 0; index--) { let lTexts = el_text.substring(index - _length_, index); if (lTexts == leftMatchText) { this.selectRange(index); break; } } }, moveCursorToCenterByTextWithRight: function (rightMatchText, _length_) { var el = _unsafeWindow.$(this)[0]; var el_text = el.value; for (let i = el.selectionStart - 1; i > 0; i--) { let rTexts = el_text.substring(i, i + _length_); if (rTexts == rightMatchText) { this.selectRange(i + _length_); break; } } }, }); }; let error_code = { 1: { error_match: "抱歉,您填写的内容包含敏感词而无法提交", popup_text: "抱歉,您填写的内容包含敏感词而无法提交", }, 2: { error_match: "抱歉,管理员设置了本版块发表于 30 天以前的主题自动关闭,不再接受新回复", popup_text: "抱歉,管理员设置了本版块发表于 30 天以前的主题自动关闭,不再接受新回复", }, 3: { error_match: "抱歉,本主题已关闭,不再接受新内容", popup_text: "抱歉,本主题已关闭,不再接受新内容", }, 4: { error_match: "抱歉,管理员设置了本版块发表于 30 天以前的主题自动关闭,不再接受新回复", popup_text: "抱歉,管理员设置了本版块发表于 30 天以前的主题自动关闭,不再接受新回复", }, 5: { error_match: "抱歉,您的帖子小于 10 个字符的限制", popup_text: "抱歉,您的帖子小于 10 个字符的限制", }, }; let tempReplyBtnNode = null; const MTEditorOptimizationNormal = { $data: { isUBBCodeInsertClick: false, db: new Utils.indexedDB("mt_reply_record", "input_text"), forum_action: null, get tid() { return MTUtils.getThreadId(window.location.href); }, }, $el: { $like: null, $btn_submit: null, $input: null, $form: null, $fastpostsubmit: null, }, init() { log.info(`编辑器优化-简略版`); addStyle(optimizationCSS$1); this.overridePageEditor(); }, overridePageEditor() { let $old_commentIcon = document.querySelector("#comiis_foot_memu .comiis_flex li:nth-child(2)"); let $old_linkIcon = document.querySelector("#comiis_foot_memu .comiis_flex li:nth-child(3)"); let $old_collectIcon = document.querySelector("#comiis_foot_memu .comiis_flex li:nth-child(4)"); this.$el.$form = document.querySelector("#fastpostform"); this.$data.forum_action = this.$el.$form.getAttribute("action"); let forum_serialize = domUtils.serialize(this.$el.$form); let forum_url = document.querySelector("#fastpostform .header_y a").href; domUtils.remove("#needmessage[name='message']"); domUtils.remove("#imglist"); domUtils.remove("#fastpostsubmitline"); domUtils.remove("#fastpostsubmit"); let $footMenu = document.querySelector("#comiis_foot_memu"); domUtils.hide($footMenu, false); let smiliesList = MTEditorSmilies(); let first_smilies = Object.keys(smiliesList[0]).map((key) => { let smilies_url = smiliesList[0][key]; return `
  • `; }); let second_smilies = Object.keys(smiliesList[1]).map((key) => { let smilies_url = smiliesList[1][key]; return `
  • `; }); let third_smilies = Object.keys(smiliesList[2]).map((key) => { let smilies_url = smiliesList[2][key]; return `
  • `; }); domUtils.after( $footMenu, `
    • ${$old_commentIcon.innerHTML}
    • ${$old_linkIcon.innerHTML}
    • ${$old_collectIcon.innerHTML}