您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
修复因作者设定错误或网页设计问题等原因而无法点击的章节链接。
- // ==UserScript==
- // @name ESJ Zone: Repair Non-clickable Chapters
- // @name:zh-TW ESJ Zone:修復無法點擊的章節
- // @name:zh-CN ESJ Zone:修复无法点击的章节
- // @description Repair chapter links that were not-clickable due to for example, author misconfigured or by-designed.
- // @description:zh-TW 修復因作者設定錯誤或網頁設計問題等原因而無法點擊的章節連結。
- // @description:zh-CN 修复因作者设定错误或网页设计问题等原因而无法点击的章节链接。
- // @icon https://icons.duckduckgo.com/ip3/www.esjzone.cc.ico
- // @author Jason Kwok
- // @namespace https://jasonhk.dev/
- // @version 1.0.3
- // @license MIT
- // @match https://www.esjzone.cc/
- // @match https://www.esjzone.cc/update
- // @match https://www.esjzone.cc/update/
- // @match https://www.esjzone.cc/list
- // @match https://www.esjzone.cc/list/
- // @match https://www.esjzone.cc/list-*
- // @match https://www.esjzone.cc/tags/*
- // @match https://www.esjzone.cc/tags-*
- // @match https://www.esjzone.cc/my/favorite
- // @match https://www.esjzone.cc/my/favorite/*
- // @match https://www.esjzone.me/
- // @match https://www.esjzone.me/update
- // @match https://www.esjzone.me/update/
- // @match https://www.esjzone.me/list
- // @match https://www.esjzone.me/list/
- // @match https://www.esjzone.me/list-*
- // @match https://www.esjzone.me/tags/*
- // @match https://www.esjzone.me/tags-*
- // @match https://www.esjzone.me/my/favorite
- // @match https://www.esjzone.me/my/favorite/*
- // @run-at document-end
- // @grant none
- // @require https://update.greasyfork.org/scripts/482311/1296481/queue.js
- // @supportURL https://greasyfork.org/scripts/487645/feedback
- // ==/UserScript==
- let translateText;
- if (GM.info.scriptHandler === "Greasemonkey")
- {
- translateText = window.eval("getCookie(targetEncodingCookie)") ? window.eval("translateText") : ((text) => text);
- }
- else
- {
- translateText = getCookie(targetEncodingCookie) ? window.translateText : ((text) => (text));
- }
- async function findChapterUrl(novelUrl, chapterName)
- {
- const response = await fetch(novelUrl);
- if (response.status === 200)
- {
- const html = await response.text();
- const parser = new DOMParser();
- const page = parser.parseFromString(html, "text/html");
- return Array.from(page.querySelectorAll("#chapterList a"))
- .reverse()
- .find((chapter) => (translateText(chapter.innerText.trim()) === chapterName))?.href ?? null;
- }
- }
- let repaired = 0;
- const queue = new Queue({ autostart: true, concurrency: 4 });
- queue.addEventListener("error", (event) => console.error(event.detail.error));
- queue.addEventListener("end", () => console.info(`Repaired ${repaired} URL(s).`));
- const pathname = location.pathname;
- if (pathname === "/my/favorite" || pathname.startsWith("/my/favorite/"))
- {
- const novels = document.querySelectorAll(".product-item");
- for (const novel of novels)
- {
- const chapterWrapper = novel.querySelector(".book-ep div:nth-child(2)");
- const chapter = chapterWrapper.childNodes[0]?.splitText(5);
- if (chapter instanceof Text)
- {
- queue.push(async () =>
- {
- const url = await findChapterUrl(novel.querySelector(".product-title a").href, chapter.data);
- if (url)
- {
- const link = document.createElement("a");
- link.href = url;
- link.append(chapter);
- chapterWrapper.append(link);
- repaired++;
- }
- });
- }
- }
- }
- else
- {
- const novels = document.querySelectorAll(".card");
- for (const novel of novels)
- {
- const chapterWrapper = novel.querySelector(".card-ep");
- const chapter = chapterWrapper.childNodes[0];
- if (chapter instanceof Text)
- {
- queue.push(async () =>
- {
- const url = await findChapterUrl(novel.querySelector(".card-title a").href, chapter.data);
- if (url)
- {
- const link = document.createElement("a");
- link.href = url;
- link.append(chapter);
- chapterWrapper.append(link);
- repaired++;
- }
- });
- }
- }
- }