您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
南+(south-plus)论坛使用体验优化脚本。
// ==UserScript== // @name 南× // @namespace npm/vite-plugin-monkey // @version 1.0.1 // @author monkey // @description 南+(south-plus)论坛使用体验优化脚本。 // @license MIT // @icon https://bbs.imoutolove.me/favicon.ico // @match *://*.imoutolove.me/* // @match *://imoutolove.me/* // @match *://*.east-plus.net/* // @match *://east-plus.net/* // @match *://*.south-plus.net/* // @match *://south-plus.net/* // @match *://*.south-plus.org/* // @match *://south-plus.org/* // @match *://*.north-plus.net/* // @match *://north-plus.net/* // @match *://*.soul-plus.net/* // @match *://soul-plus.net/* // @match *://*.white-plus.net/* // @match *://white-plus.net/* // @match *://*.level-plus.net/* // @match *://level-plus.net/* // @match *://*.spring-plus.net/* // @match *://spring-plus.net/* // @match *://*.summer-plus.net/* // @match *://summer-plus.net/* // @match *://*.snow-plus.net/* // @match *://snow-plus.net/* // @match *://*.blue-plus.net/* // @match *://blue-plus.net/* // @require https://cdn.jsdelivr.net/npm/[email protected] // @grant GM_addStyle // @grant GM_deleteValue // @grant GM_getValue // @grant GM_listValues // @grant GM_openInTab // @grant GM_registerMenuCommand // @grant GM_setValue // @grant GM_xmlhttpRequest // @grant unsafeWindow // @run-at document-start // ==/UserScript== (function ($) { 'use strict'; var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; function parseQueryParams(search) { var _a; const htmlString = (_a = search.match(/\?(.+)\.html$/)) == null ? void 0 : _a[1]; const queryParams = {}; if (htmlString) { const queryParamsPairs = htmlString.split("-"); for (let i = 0; i < queryParamsPairs.length; i += 2) queryParams[queryParamsPairs[i]] = queryParamsPairs[i + 1]; } else if (search) { const queryParamsPairs = search.slice(1).split("&"); queryParamsPairs.forEach((pair) => { const [key, value] = pair.split("="); queryParams[key] = value; }); } return queryParams; } function getMyInfo() { var _a, _b; const myUid = (_b = (_a = $('#menu_profile a[href^="u.php?action-show-uid-"]').attr("href")) == null ? void 0 : _a.match(/uid-(\d+)/)) == null ? void 0 : _b[1]; return { uid: myUid }; } function getPostInfo() { var _a, _b; const bodyText = document.body.textContent; const categoryId = (_a = bodyText.match(/fid = '(\d+)'/)) == null ? void 0 : _a[1]; const postId = (_b = bodyText.match(/tid = '(\d+)'/)) == null ? void 0 : _b[1]; const pagesResult = bodyText.match(/Pages: (\d+)\/(\d+)/); const currentPage = (pagesResult == null ? void 0 : pagesResult[1]) !== void 0 ? Number(pagesResult[1]) : void 0; const pages = (pagesResult == null ? void 0 : pagesResult[2]) !== void 0 ? Number(pagesResult[2]) : void 0; return { categoryId, postId, currentPage, pages }; } function getForumInfo() { const bodyText = document.body.textContent; const queryParams = parseQueryParams(document.location.search); const pagesResult = bodyText.match(/Pages: (\d+)\/(\d+)/); const currentPage = (pagesResult == null ? void 0 : pagesResult[1]) !== void 0 ? Number(pagesResult[1]) : void 0; const pages = (pagesResult == null ? void 0 : pagesResult[2]) !== void 0 ? Number(pagesResult[2]) : void 0; return { categoryId: queryParams.fid, type: queryParams.type, currentPage, pages }; } function getSearchInfo() { const bodyText = document.body.textContent; const queryParams = parseQueryParams(document.location.search); const pagesResult = bodyText.match(/Pages: (\d+)\/(\d+)/); const currentPage = (pagesResult == null ? void 0 : pagesResult[1]) !== void 0 ? Number(pagesResult[1]) : void 0; const pages = (pagesResult == null ? void 0 : pagesResult[2]) !== void 0 ? Number(pagesResult[2]) : void 0; return { keyword: queryParams.keyword, currentPage, pages }; } var _GM_addStyle = /* @__PURE__ */ (() => typeof GM_addStyle != "undefined" ? GM_addStyle : void 0)(); var _GM_deleteValue = /* @__PURE__ */ (() => typeof GM_deleteValue != "undefined" ? GM_deleteValue : void 0)(); var _GM_getValue = /* @__PURE__ */ (() => typeof GM_getValue != "undefined" ? GM_getValue : void 0)(); var _GM_listValues = /* @__PURE__ */ (() => typeof GM_listValues != "undefined" ? GM_listValues : void 0)(); var _GM_openInTab = /* @__PURE__ */ (() => typeof GM_openInTab != "undefined" ? GM_openInTab : void 0)(); var _GM_registerMenuCommand = /* @__PURE__ */ (() => typeof GM_registerMenuCommand != "undefined" ? GM_registerMenuCommand : void 0)(); var _GM_setValue = /* @__PURE__ */ (() => typeof GM_setValue != "undefined" ? GM_setValue : void 0)(); var _GM_xmlhttpRequest = /* @__PURE__ */ (() => typeof GM_xmlhttpRequest != "undefined" ? GM_xmlhttpRequest : void 0)(); var _unsafeWindow = /* @__PURE__ */ (() => typeof unsafeWindow != "undefined" ? unsafeWindow : void 0)(); const defaultStorage = { category_general_expanded: false, netdisk_check: false, auto_complete_tasks: false, daily_tasks_last_time: 0, weekly_tasks_last_time: 0, image_wall_default: false, image_wall_default_array: [], category_seamless_expanded: false, seamless_load_comment: false, seamless_load_post: false, seamless_load_search: false, category_sfw_expanded: false, replace_sfw_avatar: false, hide_post_image: false, category_redirect_expanded: false, force_desktop: false, domain_redirect: false, target_domain: "", category_about_expanded: false }; function setValue(key, value) { _GM_setValue(key, value); } function getValue(key, defaultValue) { return _GM_getValue(key, defaultValue); } function deleteAllValues() { _GM_listValues().forEach((key) => _GM_deleteValue(key)); } function getAllValues() { const values = {}; for (const key in defaultStorage) values[key] = getValue(key); return values; } function setAllValues(values) { for (const key in values) setValue(key, values[key]); } function initSettings() { for (const key in defaultStorage) { if (getValue(key) === void 0) setValue(key, defaultStorage[key]); } } function resetAllSettings() { if (confirm("你确定初始化所有设置吗?")) { deleteAllValues(); document.location.reload(); } } function createElement(tagName, attributes = {}) { const $element = $(`<${tagName}>`, attributes); return $element[0]; } function insertNewElement(parent, tagName, attributes = {}) { const element = createElement(tagName, attributes); $(parent).append(element); return element; } function exportSettings() { const settings = getAllValues(); const data = JSON.stringify(settings, null, 2); const blob = new Blob([data], { type: "application/json" }); const url = URL.createObjectURL(blob); $("<a>", { href: url, download: "settings.json" })[0].click(); URL.revokeObjectURL(url); } function validateSettings(settings) { for (const key in settings) { if (!(key in defaultStorage)) return false; if (typeof settings[key] !== typeof defaultStorage[key]) return false; } return true; } function importSettings() { if (!confirm("你确定要导入设置吗?当前设置将被覆盖!")) return; const input = $("<input>", { type: "file" }).on("change", function() { const file = this.files[0]; const reader = new FileReader(); reader.onload = function() { const data = reader.result; const settings = JSON.parse(data); if (!validateSettings(settings)) { alert("配置文件数据错误!"); return; } setAllValues(settings); }; reader.readAsText(file); document.location.reload(); })[0]; input.click(); } class Checkbox { constructor(lable, key) { __publicField(this, "label"); __publicField(this, "key"); __publicField(this, "_checked"); this.label = lable; this.key = key; this._checked = getValue(key, false); } get checked() { return this._checked; } set checked(value) { this._checked = value; setValue(this.key, value); } } class Input { constructor(label, key) { __publicField(this, "label"); __publicField(this, "key"); __publicField(this, "_value"); this.label = label; this.key = key; this._value = getValue(key, ""); } get value() { return this._value; } set value(value) { this._value = value; setValue(this.key, value); } } class Button { constructor(label, type, callback) { __publicField(this, "label"); __publicField(this, "type"); __publicField(this, "callback"); this.label = label; this.type = type; this.callback = callback; } } class Category { constructor(label, key, items) { __publicField(this, "label"); __publicField(this, "key"); __publicField(this, "items"); __publicField(this, "_expanded"); this.label = label; this.key = key; this.items = items; this._expanded = getValue(key, false); } get expanded() { return this._expanded; } set expanded(value) { this._expanded = value; setValue(this.key, value); } } function initCheckbox(parent, checkbox) { const checkboxItem = insertNewElement(parent, "div", { class: "category-item category-checkbox" }); const label = insertNewElement(checkboxItem, "label"); const checkboxMain = insertNewElement(label, "input", { type: "checkbox", checked: checkbox.checked }); checkboxMain.checked = checkbox.checked; insertNewElement(label, "span", { text: checkbox.label }); checkboxMain.addEventListener("change", () => { checkbox.checked = !checkbox.checked; checkboxMain.checked = checkbox.checked; }); } function initInput(parent, input) { const inputItem = insertNewElement(parent, "div", { class: "category-item category-input" }); const label = insertNewElement(inputItem, "label"); const span = insertNewElement(label, "span", { text: `${input.label}` }); const expandAnchor = insertNewElement(span, "a", { text: "编辑" }); const inputMain = insertNewElement(label, "textarea", { text: input.value }); const updateValue = () => { input.value = inputMain.value; }; expandAnchor.addEventListener("click", (e) => { e.preventDefault(); if (expandAnchor.textContent === "编辑") { expandAnchor.textContent = "收起"; inputMain.style.display = "block"; updateValue(); } else { expandAnchor.textContent = "编辑"; inputMain.style.display = "none"; } }); inputMain.addEventListener("input", () => { inputMain.style.height = "auto"; inputMain.style.height = `${inputMain.scrollHeight - 1}px`; }); inputMain.addEventListener("focusout", () => { updateValue(); }); } function initButton(parent, button) { const buttonItem = insertNewElement(parent, "div", { text: button.label, class: `category-item category-button ${button.type}` }); buttonItem.addEventListener("click", button.callback); } function initCategory(parent, category) { const categoryHeader = insertNewElement(parent, "div", { class: `category-header ${category.expanded ? "expanded" : ""}`, text: category.label }); const categoryContent = insertNewElement(parent, "div", { class: `category-content ${category.expanded ? "expanded" : ""}` }); categoryHeader.addEventListener("click", () => { category.expanded = !category.expanded; categoryHeader.classList.toggle("expanded"); categoryContent.classList.toggle("expanded"); }); category.items.forEach((item) => { if (item instanceof Checkbox) initCheckbox(categoryContent, item); else if (item instanceof Input) initInput(categoryContent, item); else if (item instanceof Button) initButton(categoryContent, item); }); } const categories = [ new Category("⚙️ 常规", "category_general_expanded", [ new Checkbox("网盘失效检查", "netdisk_check"), new Checkbox("自动完成任务", "auto_complete_tasks"), new Checkbox("默认进入图墙模式开关", "image_wall_default") ]), new Category("🔄 无缝加载", "category_seamless_expanded", [ new Checkbox("无缝加载评论", "seamless_load_comment"), new Checkbox("无缝加载帖子", "seamless_load_post"), new Checkbox("无缝加载搜索结果", "seamless_load_search") ]), new Category("🔞 SFW", "category_sfw_expanded", [ new Checkbox("替换帖子内用户头像", "replace_sfw_avatar"), new Checkbox("隐藏帖子内图片", "hide_post_image") ]), new Category("🔗 跳转", "category_redirect_expanded", [ new Checkbox("强制跳转桌面版", "force_desktop"), new Checkbox("重定向到指定域名", "domain_redirect"), new Input("指定域名", "target_domain") ]), new Category("ℹ️ 关于", "category_about_expanded", [ new Button("导出设置", "primary", exportSettings), new Button("导入设置", "primary", importSettings), new Button("初始化所有设置", "danger", resetAllSettings) ]) ]; function initSettingsPanel() { const contentMain = document.querySelector("#u-contentmain"); const settingsPanel = insertNewElement(contentMain, "div", { class: "settings-panel" }); const settingsPanelTilte = insertNewElement(settingsPanel, "h5", { class: "u-h5" }); insertNewElement(settingsPanelTilte, "span", { text: "插件设置" }); categories.forEach((category) => { initCategory(settingsPanel, category); }); } function initUI() { const { uid: myUid } = getMyInfo(); const queryParams = parseQueryParams(document.location.search); if (document.location.pathname === "/u.php" && (!document.location.search || !queryParams.action && queryParams.uid === myUid)) initSettingsPanel(); } async function domainRedirect() { if (!getValue("domain_redirect") || getValue("force_desktop")) return; const targetDomain = getValue("target_domain"); if (!targetDomain) return; const currentDomain = document.location.hostname; if (currentDomain !== targetDomain) document.location.href = `${document.location.protocol}//${targetDomain}${document.location.pathname}${document.location.search}`; } function forceDesktop() { if (!getValue("force_desktop")) return; if (document.location.pathname !== "/simple/index.php") return; const domain = getValue("domain_redirect") ? getValue("target_domain", document.location.hostname) : document.location.hostname; const origin = `${document.location.protocol}//${domain}`; if (document.location.search === "") { document.location.href = origin; return; } const match = document.location.search.match(/^\?t(\d+)(?:_(\d+))?\.html$/); if (match) { const postId = match[1]; const page = match[2] || "1"; document.location.href = `${origin}/read.php?tid-${postId}-fpage-0-toread--page-${page}.html`; } } function get(url, retries = 3, timeout = 5e3) { return new Promise((resolve, reject) => { const attempt = () => { _GM_xmlhttpRequest({ method: "GET", url, timeout, onload: (res) => { resolve(res.responseText); }, onerror: (err) => { if (retries > 0) { retries--; attempt(); } else { reject(err); } }, ontimeout: () => { if (retries > 0) { retries--; attempt(); } else { reject(new Error(`Request to ${url} timed out`)); } } }); }; attempt(); }); } function post(url, data, retries = 3, timeout = 5e3) { return new Promise((resolve, reject) => { const attempt = () => { _GM_xmlhttpRequest({ method: "POST", url, data, timeout, onload: (res) => { resolve(res.responseText); }, onerror: (err) => { if (retries > 0) { retries--; attempt(); } else { reject(err); } }, ontimeout: () => { if (retries > 0) { retries--; attempt(); } else { reject(new Error(`Request to ${url} timed out`)); } } }); }; attempt(); }); } async function getDocument(url, handler) { const html = await get(url); const parser = new DOMParser(); const doc = parser.parseFromString(html, "text/html"); handler == null ? void 0 : handler(doc); return doc; } function baiduNetdiskCheck() { $("a[href^='https://pan.baidu.com/s/']").each((_, anchor) => { const link = anchor.href; anchor.textContent = `${link} ⏳`; get(link).then((responseText) => { console.log(responseText); if (responseText.includes("过期时间") || responseText.includes("请输入提取码")) anchor.textContent = `${link} ✔️`; else anchor.textContent = `${link} ❌️`; }); }); } function quarkNetdiskCheck() { const checkUrl = "https://drive.quark.cn/1/clouddrive/share/sharepage/token?pr=ucpro&fr=pc"; $("a[href^='https://pan.quark.cn/s/']").each((_, anchor) => { var _a; const link = anchor.href; const shardId = (_a = link.match(/\/s\/([a-zA-Z0-9]+)(?=\?|$)/)) == null ? void 0 : _a[1]; anchor.textContent = `${link} ⏳`; post(checkUrl, JSON.stringify({ pwd_id: shardId, passcode: "" })).then((responseText) => { const responseParsed = JSON.parse(responseText); if (responseParsed.message === "ok" || responseParsed.message === "需要提取码") anchor.textContent = `${link} ✔️`; else anchor.textContent = `${link} ❌️`; }); }); } function netdiskCheck() { if (document.location.pathname !== "/read.php" || !getValue("netdisk_check")) return; baiduNetdiskCheck(); quarkNetdiskCheck(); } const DAILY_TASK_ACCEPT = "https://bbs.imoutolove.me/plugin.php?H_name=tasks&action=ajax&actions=job&cid=15&nowtime=1711814495907&verify=22a6d4b9"; const DAILY_TASK_COMPLETE = "https://bbs.imoutolove.me/plugin.php?H_name=tasks&action=ajax&actions=job2&cid=15&nowtime=1711814495907&verify=22a6d4b9"; const WEEKLY_TASK_ACCEPT = "https://bbs.imoutolove.me/plugin.php?H_name=tasks&action=ajax&actions=job&cid=14&nowtime=1711814495907&verify=22a6d4b9"; const WEEKLY_TASK_COMPLETE = "https://bbs.imoutolove.me/plugin.php?H_name=tasks&action=ajax&actions=job2&cid=14&nowtime=1711814495907&verify=22a6d4b9"; async function getTaskLastTime() { const domain = getValue("domain_redirect") && getValue("target_domain") ? getValue("target_domain") : document.location.hostname; const res = await get(`https://${domain}/plugin.php?H_name-tasks-actions-endtasks.html`); if (res.includes("您没有登录或者您没有权限访问此页面")) return false; $(res).find('table table td[valign="top"]').each((_, el) => { const text = $(el).text(); const match = text.match(/(\d{4}-\d{2}-\d{2}) (AM|PM):(\d{2}:\d{2}:\d{2})/); if (match) { const timestamp = (/* @__PURE__ */ new Date(`${match[1]} ${match[3]}`)).getTime(); if (text.includes("日常")) setValue("daily_tasks_last_time", timestamp); else if (text.includes("周常")) setValue("weekly_tasks_last_time", timestamp); } }); return true; } async function autoCompleteTasks() { if (!getValue("auto_complete_tasks")) return; if (getValue("daily_tasks_last_time") === 0 || getValue("weekly_tasks_last_time") === 0) getTaskLastTime(); if (getValue("daily_tasks_last_time") + 1e3 * 60 * 60 * 18 > Date.now() && getValue("weekly_tasks_last_time") + 1e3 * 60 * 60 * 158 > Date.now()) return; await get(DAILY_TASK_ACCEPT); await get(DAILY_TASK_COMPLETE); await get(WEEKLY_TASK_ACCEPT); await get(WEEKLY_TASK_COMPLETE); } function throttle(callback, delay) { let timer = null; return (...args) => { if (!timer) { callback(...args); timer = setTimeout(() => { timer = null; }, delay); } }; } function replaceSFWAvatar(img) { if (!getValue("replace_sfw_avatar")) return; if (document.location.pathname !== "/read.php") return; if (!img.closest(".user-pic")) return; const uid = $(img).parent().attr("href").match(/action-show-uid-(\d+).html/)[1]; const formatUid = (+uid % 2774).toString(); const sfwAvatarUrl = `https://api.dicebear.com/8.x/icons/svg?seed=${formatUid}`; const sourceAvatarUrl = $(img).attr("src"); const width = $(img).attr("width") || 150; const height = $(img).attr("height") || 150; const $avatarContainer = $("<div>", { class: "avatar-container" }); const $sfwAvatar = $("<img>", { src: sfwAvatarUrl, class: "sfw-avatar", style: `width: ${width}px; height: ${height}px;` }); const $sourceAvatar = $("<img>", { src: sourceAvatarUrl, class: "source-avatar", style: `width: ${width}px; height: ${height}px;` }); $avatarContainer.append($sourceAvatar, $sfwAvatar); $(img).replaceWith($avatarContainer); } function hidePostImage(img) { var _a; if (!getValue("hide_post_image")) return; if (document.location.pathname !== "/read.php") return; if (!img.closest(".tpc_content")) return; if ($(img).parent().hasClass("image-placeholder")) return; if ((_a = $(img).attr("src")) == null ? void 0 : _a.includes("images/post/smile/")) return; $(img).attr("data-src", $(img).attr("src")); $(img).attr("src", ""); const $placeholder = $(` <div class="image-placeholder"> <div class="hide-text">🙈</div> <div class="show-text">🙉</div> </div> `); $(img).replaceWith($placeholder); $placeholder.append(img); $placeholder.on("click", () => { $placeholder.toggleClass("show-image"); $placeholder.css("border", "solid"); if ($(img).attr("src") === "") $(img).attr("src", $(img).attr("data-src")); }); } function initSafeForWork() { $("img").each((_, img) => { replaceSFWAvatar(img); hidePostImage(img); }); } function isAtBottom() { return _unsafeWindow.innerHeight + _unsafeWindow.scrollY >= document.body.offsetHeight - 100; } function seamlessLoad(currentPage, pages, containerSelector, divider, dividerHandler, docPreprocess) { let nextPageUrl; let nextPageDoc; let requestLock = false; let $container = $(containerSelector).last(); let $divider = $(divider); const _handleEvent = throttle(async () => { if (!nextPageDoc && !requestLock) { if (currentPage >= pages) { $(document).off("scroll wheel keydown", handleEvent); return; } $container.after($divider); nextPageUrl = $(".pages b").parent().next().find("a").attr("href"); if (!nextPageUrl) return; dividerHandler.Loading($divider, currentPage + 1); try { requestLock = true; nextPageDoc = await getDocument(`${document.location.origin}/${nextPageUrl}`); docPreprocess && docPreprocess(nextPageDoc); dividerHandler.Loaded($divider, currentPage + 1); } catch (error) { console.error(error); dividerHandler.Failed($divider, currentPage + 1); nextPageDoc = void 0; } finally { requestLock = false; } } if (isAtBottom() && !requestLock && nextPageDoc) { dividerHandler.Showed($divider, currentPage + 1); const $nextPageContainer = $(nextPageDoc).find(containerSelector); $divider.after($nextPageContainer); const $pages = $(".pages"); const $nextPagePages = $(nextPageDoc).find(".pages"); for (let i = 0; i < $nextPagePages.length; i++) $pages[i].replaceWith($nextPagePages[i]); const url = `${document.location.origin}/${nextPageUrl}`; history.pushState({ [url]: true }, "", url); $container = $(containerSelector).last(); $divider = $(divider); nextPageDoc = void 0; currentPage++; } }, 500); function handleEvent(e) { if (e.originalEvent instanceof WheelEvent && e.originalEvent.deltaY > 0 || e.originalEvent instanceof KeyboardEvent && (e.originalEvent.key === "ArrowDown" || e.originalEvent.key === "PageDown") || isAtBottom()) _handleEvent(); } $(document).on("scroll wheel keydown", handleEvent); } async function seamlessLoadComment() { if (!getValue("seamless_load_comment")) return; if (document.location.pathname !== "/read.php") return; const { currentPage, pages } = getPostInfo(); if (!currentPage || !pages) return; const docPreprocess = (doc) => { $(doc).find("img").each((_, img) => { replaceSFWAvatar(img); hidePostImage(img); }); }; seamlessLoad(currentPage, pages, 'form[name="delatc"]', '<div class="h2 seamless-load-divider">分割线</div>', { Loading: (divider, nextPage) => { divider.text(`正在加载第${nextPage}页`); }, Loaded: (divider, nextPage) => { divider.text(`第${nextPage}页已加载,向下滚动以展示`); }, Showed: (divider, nextPage) => { divider.text(`第${nextPage}页已展示`); }, Failed: (divider, nextPage) => { divider.text(`第${nextPage}页加载失败`); } }, docPreprocess); } function seamlessLoadPost() { if (!getValue("seamless_load_post")) return; if (document.location.pathname !== "/thread.php") return; const { currentPage, pages } = getForumInfo(); if (!currentPage || !pages) return; seamlessLoad(currentPage, pages, 'tbody[style="table-layout:fixed;"]', '<tbody><tr><td colspan="5" class="h seamless-load-divider">分割线</td></tr></tbody>', { Loading: (divider, nextPage) => { divider.find("td").text(`正在加载第${nextPage}页`); }, Loaded: (divider, nextPage) => { divider.find("td").text(`第${nextPage}页已加载,向下滚动以展示`); }, Showed: (divider, nextPage) => { divider.find("td").text(`第${nextPage}页已展示`); }, Failed: (divider, nextPage) => { divider.find("td").text(`第${nextPage}页加载失败`); } }); } function seamlessLoadSearch() { if (!getValue("seamless_load_search")) return; if (document.location.pathname !== "/search.php") return; const { currentPage, pages } = getSearchInfo(); if (!currentPage || !pages) return; seamlessLoad(currentPage, pages, "#main .t table tbody", '<tbody><tr><td colspan="7" class="h seamless-load-divider">分割线</td></tr></tbody>', { Loading: (divider, nextPage) => { divider.find("td").text(`正在加载第${nextPage}页`); }, Loaded: (divider, nextPage) => { divider.find("td").text(`第${nextPage}页已加载,向下滚动以展示`); }, Showed: (divider, nextPage) => { divider.find("td").text(`第${nextPage}页已展示`); }, Failed: (divider, nextPage) => { divider.find("td").text(`第${nextPage}页加载失败`); } }); } function initImageWallDefaultButton(categoryId, type) { const $button = $('<span class="fr" style="margin-left:0.5em"><a href="#" style="color:rgb(255, 0, 255);font-weight:bold;">[默认进入图墙模式:❌️]</a></span>'); $('#breadcrumbs span[class="fr gray3"]').before($button); const defaultArray = getValue("image_wall_default_array"); if (defaultArray == null ? void 0 : defaultArray.includes(`${categoryId}-${type}`)) $button.find("a").text("[默认进入图墙模式:✔️]"); $button.on("click", (e) => { var _a; e.preventDefault(); if ((_a = e.target.textContent) == null ? void 0 : _a.includes("❌️")) { setValue("image_wall_default_array", [...getValue("image_wall_default_array"), `${categoryId}-${type}`]); document.location.href = document.location.href.replace(/\/thread.php/, "/thread_new.php"); } else { setValue("image_wall_default_array", getValue("image_wall_default_array").filter((item) => item !== `${categoryId}-${type}`)); document.location.href = document.location.href.replace(/\/thread_new.php/, "/thread.php"); } }); } function replaceCategoryUrl() { $('a[href*="thread.php"]').each((_, anchor) => { var _a; const queryParams = parseQueryParams($(anchor).attr("href")); const categoryId = queryParams.fid; const type = queryParams.type || (queryParams.search === "digest" ? "digest" : "0"); if ((_a = getValue("image_wall_default_array")) == null ? void 0 : _a.includes(`${categoryId}-${type}`)) $(anchor).attr("href", $(anchor).attr("href").replace(/thread.php/, "thread_new.php")); }); } function imageWallDefault() { var _a; if (!getValue("image_wall_default")) return; if (document.location.pathname === "/thread.php" || document.location.pathname === "/thread_new.php") { const queryParams = parseQueryParams(document.location.search); const categoryId = queryParams.fid; const type = queryParams.type || (queryParams.search === "digest" ? "digest" : "0"); if (((_a = getValue("image_wall_default_array")) == null ? void 0 : _a.includes(`${categoryId}-${type}`)) && document.location.pathname !== "/thread_new.php") document.location.href = document.location.href.replace(/\/thread.php/, "/thread_new.php"); initImageWallDefaultButton(categoryId, type); } replaceCategoryUrl(); } const settingsPanelCss = "html {\r\n margin-left: calc(100vw - 100%);\r\n}\r\n\r\n.category-header {\r\n margin: 0;\r\n padding: 0.7em;\r\n color: #333;\r\n background-color: #ccc;\r\n font-size: 1.25em;\r\n font-weight: bold;\r\n cursor: pointer;\r\n user-select: none;\r\n}\r\n\r\n.category-header:after {\r\n content: '🔽';\r\n float: right;\r\n font-size: 1.0em;\r\n}\r\n\r\n.category-header.expanded::after {\r\n content: '🔼';\r\n}\r\n\r\n.category-content {\r\n margin-bottom: 0.2em;\r\n background-color: #eee;\r\n color: #333;\r\n font-size: 1.2em;\r\n overflow: hidden;\r\n user-select: none;\r\n max-height: 0;\r\n}\r\n\r\n.category-content.expanded {\r\n max-height: 1000px;\r\n}\r\n\r\n.category-item {\r\n padding: 0.6em 1em;\r\n}\r\n\r\n.category-checkbox input {\r\n margin-top: -0.05em;\r\n vertical-align: middle;\r\n}\r\n\r\n.category-checkbox span {\r\n vertical-align: middle;\r\n}\r\n\r\n.category-input label {\r\n display: flex;\r\n flex-direction: column;\r\n}\r\n\r\n.category-input span {\r\n margin-left: 0.2em;\r\n}\r\n\r\n.category-input a {\r\n margin-left: 0.4em;\r\n cursor: pointer;\r\n text-decoration: underline;\r\n}\r\n\r\n.category-input a:not(:hover) {\r\n color: inherit;\r\n}\r\n\r\n.category-input textarea {\r\n margin-top: 0.1em;\r\n display: none;\r\n font-size: 1.2em;\r\n min-height: 1.3em;\r\n overflow: hidden;\r\n resize: none;\r\n outline: 0 none;\r\n}\r\n\r\n.category-button {\r\n cursor: pointer;\r\n text-align: center;\r\n font-size: 1.2em;\r\n}\r\n\r\n.category-button.primary {\r\n color: inherit;\r\n}\r\n\r\n.category-button.primary:hover {\r\n background-color: #ddd;\r\n}\r\n\r\n.category-button.warning {\r\n color: #e6a23c;\r\n}\r\n\r\n.category-button.warning:hover {\r\n color: white;\r\n background-color: #e6a23c;\r\n}\r\n\r\n.category-button.danger {\r\n color: #f56c6c;\r\n}\r\n\r\n.category-button.danger:hover {\r\n background-color: #f56c6c;\r\n color: white;\r\n}"; const safeForWorkCss = ".avatar-container .source-avatar {\r\n display: none;\r\n}\r\n\r\n.avatar-container:hover .source-avatar {\r\n display: block;\r\n}\r\n\r\n.avatar-container:hover .sfw-avatar {\r\n display: none;\r\n}\r\n\r\n.image-placeholder {\r\n cursor: pointer;\r\n border: dashed;\r\n user-select: none;\r\n}\r\n\r\n.image-placeholder div {\r\n font-size: 20px;\r\n text-align: center;\r\n width: 100%;\r\n height: 40px;\r\n line-height: 40px;\r\n}\r\n\r\n.image-placeholder div.show-text {\r\n display: none;\r\n}\r\n\r\n.image-placeholder img {\r\n display: none;\r\n width: 100%;\r\n}\r\n\r\n.image-placeholder.show-image .show-text {\r\n display: block;\r\n}\r\n\r\n.image-placeholder.show-image .hide-text {\r\n display: none;\r\n}\r\n\r\n.image-placeholder.show-image img {\r\n display: block;\r\n}"; const seamlessLoadCss = ".h2.seamless-load-divider {\r\n text-align: center;\r\n user-select: none;\r\n}\r\n.h.seamless-load-divider {\r\n text-align: center;\r\n user-select: none;\r\n}"; _GM_addStyle(settingsPanelCss); _GM_addStyle(safeForWorkCss); _GM_addStyle(seamlessLoadCss); _GM_registerMenuCommand("设置", () => { _GM_openInTab(`${document.location.origin}/u.php`, { active: true }); }); function init() { initSettings(); initUI(); netdiskCheck(); autoCompleteTasks(); imageWallDefault(); initSafeForWork(); seamlessLoadComment(); seamlessLoadPost(); seamlessLoadSearch(); forceDesktop(); domainRedirect(); } { document.addEventListener("DOMContentLoaded", () => { init(); }); } })(jQuery);