// ==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/jquery@3.7.1
// @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);