您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
得奇小说网, biqu33.cc,看单个章节免翻页,把小说伪装成代码
// ==UserScript== // @name Deqi Prefech // @namespace https://greasyfork.org/zh-CN/users/14997-lrh3321 // @version 2025-08-080 // @author LRH3321 // @description 得奇小说网, biqu33.cc,看单个章节免翻页,把小说伪装成代码 // @license MIT // @icon https://www.google.com/s2/favicons?sz=64&domain=deqixs.com // @homepageURL https://greasyfork.org/zh-CN/scripts/537588-deqi-prefech // @source https://github.com/lrh3321/deqi-prefetch // @supportURL https://github.com/lrh3321/deqi-prefetch/issues // @match *://www.deqixs.com/pifu/ // @match *://www.deqixs.com/xiaoshuo/*/*.html // @match *://www.deqixs.com/xiaoshuo/*/ // @match *://www.biqu33.cc/* // @require https://cdn.jsdelivr.net/npm/[email protected]/prism.min.js // @require https://cdn.jsdelivr.net/npm/[email protected]/plugins/match-braces/prism-match-braces.min.js // @require https://cdn.jsdelivr.net/npm/[email protected]/plugins/line-numbers/prism-line-numbers.min.js // @tag novels // @connect self // @grant GM_addElement // @grant GM_addStyle // @grant GM_getResourceURL // @grant GM_getValue // @grant GM_registerMenuCommand // @grant GM_setValue // @grant GM_xmlhttpRequest // @grant unsafeWindow // @run-at document-end // ==/UserScript== (e=>{if(typeof GM_addStyle=="function"){GM_addStyle(e);return}const t=document.createElement("style");t.textContent=e,document.head.append(t)})(' [data-comment=normal] span.token.comment{font-style:normal}img[alt],.menu,.header p,h2 a,div.footer,div.container>ul.list{display:none}h2.op a{display:block}body>div.container,body>div.header,#article_main{width:var(--container-width, "1200px")}span.token.comment{font-family:var(--novel-font-family)!important}body{-webkit-backdrop-filter:contrast(110%);backdrop-filter:contrast(110%)}form fieldset{display:block;min-inline-size:min-content;margin-inline:2px;margin-top:1rem;margin-bottom:1rem;border-width:2px;border-style:groove;border-color:gray;border-image:initial;padding-block:.35em .625em;padding-inline:.75em}fieldset label{display:flex;width:fit-content;gap:.4rem;white-space:nowrap}label input{padding-left:.5rem}editable-list li{width:fit-content;height:fit-content;display:flex;align-items:baseline;--list-display: none}editable-list li:hover{--list-display: block}editable-list li:hover .icon{top:0rem;right:3rem}editable-list .icon{border:none;cursor:pointer;position:relative;font-size:1.8rem;display:var(--list-display)}editable-list textarea{padding:.5rem;width:95%}editable-list ul{display:flex;max-width:80svw;flex-wrap:wrap;justify-content:flex-start;column-gap:1rem}#header,#main .container-fluid,#article_main .row{display:none}#article_main{background:transparent} '); (function () { 'use strict'; var _GM_addElement = /* @__PURE__ */ (() => typeof GM_addElement != "undefined" ? GM_addElement : void 0)(); var _GM_getValue = /* @__PURE__ */ (() => typeof GM_getValue != "undefined" ? GM_getValue : 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)(); let extendLanguageElement = null; function setupExtendLanguageSupport() { if (!coreLanguages.has(codeLang)) { console.log("loading language", codeLang); const src = `https://dev.prismjs.com/components/prism-${codeLang}.js`; if (extendLanguageElement?.src == src) { return; } extendLanguageElement?.remove(); extendLanguageElement = _GM_addElement("script", { src }); } } function disguiseToCode(container) { const fakeCodes = fakeCodeSnippet.split("===="); const getRandomCode = () => fakeCodes[Math.floor(Math.random() * fakeCodes.length)]; var lines = []; const paragraphs = Array.from(container.querySelectorAll("p")); let blockCommentStart = "/*"; let blockCommentEnd = "*/"; let shortCommnet = ""; switch (codeLang) { case "clike": case "javascript": case "c": case "csharp": case "cpp": case "go": case "java": case "kotlin": case "rust": case "php": shortCommnet = "// "; break; case "python": shortCommnet = "# "; break; case "markup": blockCommentStart = "<!--"; blockCommentEnd = "-->"; break; } const codeSegments = []; paragraphs.forEach((p) => { const textContent = p.textContent.trim(); let line = ""; while (line.trim() == "") { if (lines.length == 0) { lines.push(...getRandomCode().split(/[\r]?\n/)); } line = lines.shift(); if (line.trim().length === 1) { codeSegments.push(line); line = ""; } } const trimed = line.replace(/^[\s\t]+/, ""); if (trimed !== line) { const prefix = line.substring(0, line.length - trimed.length); if (textContent.length + shortCommnet.length + prefix.length < inlineLengthMax && shortCommnet != "") { codeSegments.push(`${prefix}${shortCommnet}${textContent}`); } else { codeSegments.push( `${prefix}${blockCommentStart} ${prefix} ${textContent} ${prefix}${blockCommentEnd}` ); } } else { if (textContent.length + shortCommnet.length < inlineLengthMax && shortCommnet != "") { codeSegments.push(`${shortCommnet}${textContent}`); } else { codeSegments.push(`${blockCommentStart} ${textContent} ${blockCommentEnd}`); } } codeSegments.push(line); p.remove(); }); codeSegments.push(...lines); const pre = createPreformattedCode(codeSegments.join("\n")); container.parentElement.replaceChild(pre, container); highlightElement(pre, false, (_) => { document.body.style.backgroundColor = getComputedStyle(pre).backgroundColor; }); return pre; } function disguiseParagraphs(container) { switch (disguiseMode) { case "none": container.style.fontSize = "var(--novel-font-size)"; container.style.fontFamily = "var(--novel-font-family)"; break; case "code": default: disguiseToCode(container); break; } } function createPreformattedCode(snippet) { const code = document.createElement("code"); code.className = `language-${codeLang} match-braces rainbow-braces`; code.innerHTML = snippet; const pre = document.createElement("pre"); pre.style.whiteSpace = "pre-wrap"; pre.style.textWrap = "pretty"; pre.style.overflowX = "auto"; pre.className = `language-${codeLang} match-braces rainbow-braces ${codeShowLineNumbers ? "line-numbers" : ""}`; if (pre.firstChild) { pre.replaceChild(code, pre.firstChild); } else { pre.appendChild(code); } return pre; } function highlightElement(el, async, callback) { if (el instanceof HTMLElement) { el.style.fontSize = "var(--novel-font-size)"; } const codes = Array.from(el.querySelectorAll("code")); const highlightAll = () => { codes.forEach((code) => { Prism.highlightElement(code, async, callback); }); }; if (coreLanguages.has(codeLang)) { highlightAll(); } else { let count = 0; const lazyHighlightElement = () => { count++; if (codeLang in Prism.languages) { highlightAll(); return; } if (count > 10) { return; } setTimeout(lazyHighlightElement, 200); }; setTimeout(lazyHighlightElement, 200); } } class EditableList extends HTMLElement { itemList = null; textInput = null; codeSnippetsStore; counter; constructor() { super(); this.addListItem = this.addListItem.bind(this); this.handleRemoveItemListeners = this.handleRemoveItemListeners.bind(this); this.removeListItem = this.removeListItem.bind(this); this.counter = 0; this.codeSnippetsStore = /* @__PURE__ */ new Map(); } lazyInit() { this.innerHTML = `<h3>伪装代码段</h3> <div> <label>输入代码片段:</label> <textarea rows="20" class="add-new-list-item-input"></textarea> <button class="editable-list-add-item icon">⊕</button> </div> <ul class="item-list"></ul>`; this.itemList = this.querySelector("ul.item-list"); this.textInput = this.querySelector(".add-new-list-item-input"); } // fires after the element has been attached to the DOM connectedCallback() { this.lazyInit(); const addElementButton = this.querySelector(".editable-list-add-item"); addElementButton?.addEventListener("click", this.addListItem, false); } // add items to the list addListItem() { const textInput = this.textInput; let snippet = textInput?.value; if (snippet) { this.counter++; const idx = this.counter.toString(); this.codeSnippetsStore.set(idx, snippet); snippet = this.trimSnippet(snippet); this.addCodeSnippet(idx, snippet); textInput.value = ""; this.dispatchEvent(new CustomEvent("add-item")); } } trimSnippet(s) { const lines = s.split(/[\r\n]+/).filter((l) => l.trim()); return lines.join("\n"); } updateCodeSnippets(snippets) { this.codeSnippetsStore.clear(); snippets.forEach((snippet) => { this.counter++; snippet = this.trimSnippet(snippet); this.codeSnippetsStore.set(this.counter.toString(), snippet); }); this.render(); } get codeSnippets() { return Array.from(this.codeSnippetsStore.values()); } render() { if (!this.itemList) { this.lazyInit(); } this.itemList.innerHTML = ``; this.codeSnippetsStore.forEach((snippet, idx) => { this.addCodeSnippet(idx, snippet); }); } addCodeSnippet(idx, snippet) { const li = document.createElement("li"); li.dataset.snippetId = idx; const button = document.createElement("button"); const pre = createPreformattedCode(snippet); button.classList.add("editable-list-remove-item", "icon"); button.innerHTML = "⊖"; li.appendChild(pre); li.appendChild(button); this.itemList?.appendChild(li); this.handleRemoveItemListeners([button]); highlightElement(pre, false); } handleRemoveItemListeners(arrayOfElements) { arrayOfElements.forEach((element) => { element.addEventListener("click", this.removeListItem, false); }); } removeListItem(e) { const parent = e.target?.parentNode; if (parent) { parent.remove(); this.codeSnippetsStore.delete(parent.dataset.snippetId || ""); this.dispatchEvent(new CustomEvent("remove-item")); } } } function setupEditableList() { customElements.define("editable-list", EditableList); } function getCodeThemeURL(theme) { const officialThemes = /* @__PURE__ */ new Set([ "prism", "prism-dark", "prism-funky", "prism-okaidia", "prism-twilight", "prism-coy", "prism-solarizedlight", "prism-tomorrow" ]); if (officialThemes.has(theme)) { return `https://dev.prismjs.com/themes/${theme}.min.css`; } return `https://cdnjs.cloudflare.com/ajax/libs/prism-themes/1.9.0/${theme}.min.css`; } function releaseCopy() { const $ = _unsafeWindow.$ || window.$; if ($) { const doc = $(document); doc.off("contextmenu"); doc.off("copy"); doc.off("cut"); } document.onclick = null; document.oncontextmenu = null; document.oncopy = null; document.oncut = null; } const isInIframe = window.self !== window.top; let disguiseDebug = _GM_getValue("disguiseDebug", false); let novelFontSize = _GM_getValue("novel-font-size", "16px"); let novelFontFamily = _GM_getValue( "novel-font-family", `system-ui, -apple-system, '微软雅黑', 'PingFang SC', BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif` ); let disguiseMode = _GM_getValue("disguise-mode", "none"); let codeLang = _GM_getValue("code-lang", "javascript"); const defaultCodeSnippet = `var x = 1; switch (x) { case 1: console.log('x 等于1'); case 2: console.log('x 等于2'); default: console.log('x 等于其他值'); } ==== switch (x) { case 1: console.log('x 等于1'); break; case 2: console.log('x 等于2'); break; default: console.log('x 等于其他值'); } ==== switch (1 + 3) { case 2 + 2: f(); break; default: neverHappens(); } ==== var x = 1; switch (x) { case true: console.log('x 发生类型转换'); break; default: console.log('x 没有发生类型转换'); } `; let fakeCodeSnippet = _GM_getValue("fake-codes", defaultCodeSnippet); if (fakeCodeSnippet.trim() == "") { fakeCodeSnippet = defaultCodeSnippet; } let codeTheme = _GM_getValue("code-theme", "prism"); let codeParagraphItalic = _GM_getValue("code-italic", true); let codeShowLineNumbers = _GM_getValue("line-numbers", false); let refreshInterval = _GM_getValue("refreshInterval", 15 * 6e4); const avalibleCodeThemes = [ { Name: "Default", code: "prism" }, { Name: "Dark", code: "prism-dark" }, { Name: "Funky", code: "prism-funky" }, { Name: "Okaidia", code: "prism-okaidia" }, { Name: "Twilight", code: "prism-twilight" }, { Name: "Coy", code: "prism-coy" }, { Name: "Solarized Light", code: "prism-solarizedlight" }, { Name: "Tomorrow Night", code: "prism-tomorrow" }, // A wider selection of Prism themes { Name: "CB", code: "prism-cb" }, { Name: "GHColors", code: "prism-ghcolors" }, { Name: "Pojoaque", code: "prism-pojoaque" }, { Name: "Xonokai", code: "prism-xonokai" }, { Name: "Ateliersulphurpool-light", code: "prism-base16-ateliersulphurpool.light" }, { Name: "Hopscotch", code: "prism-hopscotch" }, { Name: "Atom Dark", code: "prism-atom-dark" }, { Name: "Duotone Dark", code: "prism-duotone-dark" }, { Name: "Duotone Sea", code: "prism-duotone-sea" }, { Name: "Duotone Space", code: "prism-duotone-space" }, { Name: "Duotone Earth", code: "prism-duotone-earth" }, { Name: "Duotone Forest", code: "prism-duotone-forest" }, { Name: "Duotone Light", code: "prism-duotone-light" }, { Name: "VS", code: "prism-vs" }, { Name: "VS Code Dark+", code: "prism-vsc-dark-plus" }, { Name: "Darcula", code: "prism-darcula" }, { Name: "a11y Dark", code: "prism-a11y-dark" }, { Name: "Dracula", code: "prism-dracula" }, { Name: "Synthwave '84", code: "prism-synthwave84" }, { Name: "Shades of Purple", code: "prism-shades-of-purple" }, { Name: "Material Dark", code: "prism-material-dark" }, { Name: "Material Light", code: "prism-material-light" }, { Name: "Material Oceanic", code: "prism-oceanic" }, { Name: "Nord", code: "prism-nord" }, { Name: "Coldark Cold", code: "prism-coldark-cold" }, { Name: "Coldark Dark", code: "prism-coldark-dark" }, { Name: "Coy without shadows", code: "prism-coy-without-shadows" }, { Name: "Gruvbox Dark", code: "prism-gruvbox-dark" }, { Name: "Gruvbox Light", code: "prism-gruvbox-light" }, { Name: "Lucario", code: "prism-lucario" }, { Name: "Night Owl", code: "prism-night-owl" }, { Name: "Holi Theme", code: "prism-holi-theme" }, { Name: "Z-Touch", code: "prism-z-touch" }, { Name: "Solarized Dark Atom", code: "prism-solarized-dark-atom" }, { Name: "One Dark", code: "prism-one-dark" }, { Name: "One Light", code: "prism-one-light" }, { Name: "Laserwave", code: "prism-laserwave" } ]; const avalibleCodeLanguages = [ { Name: "Markup — markup, html, xml, svg, mathml, ssml, atom, rss", code: "markup" }, { Name: "CSS — css", code: "css" }, { Name: "C-like — clike", code: "clike" }, { Name: "JavaScript — javascript, js", code: "javascript" }, { Name: "C —c", code: "c" }, { Name: "C# —csharp, cs, dotnet", code: "csharp" }, { Name: "C++ —cpp", code: "cpp" }, { Name: "Go —go", code: "go" }, { Name: "Java —java", code: "java" }, { Name: "Kotlin —kotlin, kt, kts", code: "kotlin" }, { Name: "PHP —php", code: "php" }, { Name: "Python —python, py", code: "python" }, { Name: "Rust —rust", code: "rust" } ]; const coreLanguages = /* @__PURE__ */ new Set(["markup", "css", "clike", "javascript"]); function changeCodeTheme(theme) { _GM_setValue("code-theme", theme); codeTheme = theme; codeThemeElement?.remove(); codeThemeElement = _GM_addElement(document.head, "link", { href: getCodeThemeURL(theme), rel: "stylesheet", type: "text/css" }); } let codeThemeElement = null; function setupCodeTheme() { codeThemeElement = _GM_addElement(document.head, "link", { href: getCodeThemeURL(codeTheme), rel: "stylesheet", type: "text/css" }); if (!codeParagraphItalic) { document.body.dataset.comment = "normal"; } ["match-braces", "line-numbers"].forEach((pluginName) => { _GM_addElement(document.head, "link", { href: `https://cdn.jsdelivr.net/npm/[email protected]/plugins/${pluginName}/prism-${pluginName}.min.css`, rel: "stylesheet", type: "text/css" }); }); } let bookPageAccessKey = _GM_getValue("bookPageAccessKey", "h"); let previousChapterAccessKey = _GM_getValue("previousChapterAccessKey", "b"); let nextChapterAccessKey = _GM_getValue("nextChapterAccessKey", "n"); function createAccessKeysFieldset() { const accessKeysFieldset = document.createElement("fieldset"); accessKeysFieldset.innerHTML = `<legend>快捷键设置 <a href="https://developer.mozilla.org/zh-CN/docs/Web/HTML/Reference/Global_attributes/accesskey#%E5%B0%9D%E8%AF%95%E4%B8%80%E4%B8%8B" target="_blank" style="margin-left: 5rem;">快捷键使用帮助</a> </legend> <div style="display: flex;gap: 0.5rem;flex-wrap:wrap;"> <label>上一章: <select id="previousChapterAccessKey"></select> </label> <label>目录: <select id="bookPageAccessKey"></select> </label> <label>下一章: <select id="nextChapterAccessKey"></select> </label> </div>`; const previousChapterAccessKey2 = accessKeysFieldset.querySelector( "#previousChapterAccessKey" ); const bookPageAccessKey2 = accessKeysFieldset.querySelector("#bookPageAccessKey"); const nextChapterAccessKey2 = accessKeysFieldset.querySelector("#nextChapterAccessKey"); for (let i = 0; i < 10; i++) { const option = document.createElement("option"); const charCode = 48 + i; option.value = String.fromCharCode(charCode); option.text = String.fromCharCode(charCode); previousChapterAccessKey2.appendChild(option); bookPageAccessKey2.appendChild(option.cloneNode(true)); nextChapterAccessKey2.appendChild(option.cloneNode(true)); } for (let i = 0; i < 26; i++) { const option = document.createElement("option"); const charCode = 97 + i; option.value = String.fromCharCode(charCode); option.text = String.fromCharCode(charCode); previousChapterAccessKey2.appendChild(option); bookPageAccessKey2.appendChild(option.cloneNode(true)); nextChapterAccessKey2.appendChild(option.cloneNode(true)); } bookPageAccessKey2.value = _GM_getValue("bookPageAccessKey", "h"); previousChapterAccessKey2.value = _GM_getValue("previousChapterAccessKey", "b"); nextChapterAccessKey2.value = _GM_getValue("nextChapterAccessKey", "n"); previousChapterAccessKey2.onchange = () => { if (previousChapterAccessKey2.selectedOptions.length > 0) { _GM_setValue("previousChapterAccessKey", previousChapterAccessKey2.value); } }; bookPageAccessKey2.onchange = () => { if (bookPageAccessKey2.selectedOptions.length > 0) { _GM_setValue("bookPageAccessKey", bookPageAccessKey2.value); } }; nextChapterAccessKey2.onchange = () => { if (nextChapterAccessKey2.selectedOptions.length > 0) { _GM_setValue("nextChapterAccessKey", nextChapterAccessKey2.value); } }; return accessKeysFieldset; } let inlineLengthMax = _GM_getValue("inlineLengthMax", 40); function createDisguiseCodeFieldset() { setupExtendLanguageSupport(); const disguiseFieldset = document.createElement("fieldset"); const div = document.createElement("div"); div.style.display = "flex"; div.style.flexWrap = "wrap"; div.style.gap = "0.5rem"; disguiseFieldset.appendChild(div); const codeThemeInput = document.createElement("select"); codeThemeInput.name = "theme"; avalibleCodeThemes.forEach((theme) => { const option = document.createElement("option"); option.value = theme.code; option.text = theme.Name; codeThemeInput.appendChild(option); }); codeThemeInput.value = codeTheme; codeThemeInput.onchange = () => { console.log("change"); const theme = codeThemeInput.value; if (codeThemeInput.selectedIndex >= 0 && theme && theme != codeTheme) { console.log(`Change code theme to ${theme}`); changeCodeTheme(theme); } }; let editableList = null; const codeThemeLabel = document.createElement("label"); codeThemeLabel.innerText = "代码主题:"; codeThemeLabel.appendChild(codeThemeInput); div.appendChild(codeThemeLabel); const codeDemo = `<code class="language-javascript match-braces rainbow-braces">/* 让我们说中文 */ function foo(bar) { // 短的注释 var a = 42, b = 'Prism'; return a + bar(b); }</code>`; let preDemo = document.createElement("pre"); const renderDemo = () => { let newPre = document.createElement("pre"); newPre.innerHTML = codeDemo; newPre.className = `language-javascript match-braces ${codeShowLineNumbers ? "line-numbers" : ""}`; if (codeShowLineNumbers) { const codeDemo2 = newPre.querySelector("code"); codeDemo2.classList.add("line-numbers"); } highlightElement(newPre); disguiseFieldset.replaceChild(newPre, preDemo); preDemo = newPre; console.log("update demo"); }; const codeLangInput = document.createElement("select"); codeLangInput.name = "lang"; avalibleCodeLanguages.forEach((theme) => { const option = document.createElement("option"); option.value = theme.code; option.text = theme.Name; codeLangInput.appendChild(option); }); codeLangInput.value = codeLang; codeLangInput.onchange = () => { if (codeLangInput.selectedIndex >= 0) { codeLang = codeLangInput.value; _GM_setValue("code-lang", codeLang); setupExtendLanguageSupport(); editableList?.render(); renderDemo(); } }; const codeLangLabel = document.createElement("label"); codeLangLabel.innerText = "代码语言:"; codeLangLabel.appendChild(codeLangInput); div.appendChild(codeLangLabel); const codeShowLineNumbersInput = document.createElement("input"); codeShowLineNumbersInput.type = "checkbox"; codeShowLineNumbersInput.name = "line-numbers"; codeShowLineNumbersInput.checked = codeShowLineNumbers; codeShowLineNumbersInput.onchange = () => { codeShowLineNumbers = codeShowLineNumbersInput.checked; _GM_setValue("line-numbers", codeShowLineNumbers); console.log(`Change code show line numbers to ${codeShowLineNumbers}`, editableList); editableList?.render(); renderDemo(); }; const codeShowLineNumbersLabel = document.createElement("label"); codeShowLineNumbersLabel.appendChild(codeShowLineNumbersInput); codeShowLineNumbersLabel.append(" 显示行号"); div.appendChild(codeShowLineNumbersLabel); const codeItalicInput = document.createElement("input"); codeItalicInput.type = "checkbox"; codeItalicInput.name = "font-italic"; codeItalicInput.checked = codeParagraphItalic; codeItalicInput.onchange = () => { const checked = codeItalicInput.checked; _GM_setValue("code-italic", checked); if (checked) { document.body.dataset.comment = void 0; } else { document.body.dataset.comment = "normal"; } }; const codeItalicLabel = document.createElement("label"); codeItalicLabel.appendChild(codeItalicInput); codeItalicLabel.append(" 小说斜体"); div.appendChild(codeItalicLabel); const codeInlineLengthInput = document.createElement("input"); codeInlineLengthInput.name = "comment-lenth-limit"; codeInlineLengthInput.type = "number"; codeInlineLengthInput.min = "15"; codeInlineLengthInput.max = "200"; codeInlineLengthInput.valueAsNumber = inlineLengthMax; codeInlineLengthInput.onchange = () => { _GM_setValue("inlineLengthMax", codeInlineLengthInput.value); }; const codeInlineLengthLabel = document.createElement("label"); codeInlineLengthLabel.innerText = "单行注释长度限制:"; codeInlineLengthLabel.appendChild(codeInlineLengthInput); div.appendChild(codeInlineLengthLabel); const demoCodeTitle = document.createElement("h3"); demoCodeTitle.innerText = "主题效果:"; disguiseFieldset.appendChild(demoCodeTitle); disguiseFieldset.appendChild(preDemo); setupEditableList(); setTimeout(() => { editableList = document.createElement("editable-list"); disguiseFieldset.appendChild(editableList); editableList.updateCodeSnippets(fakeCodeSnippet.split("====\n")); renderDemo(); const onItemChange = () => { _GM_setValue("fake-codes", editableList?.codeSnippets.join("====\n")); }; editableList.addEventListener("add-item", onItemChange); editableList.addEventListener("remove-item", onItemChange); }, 500); return disguiseFieldset; } let containerWidth = _GM_getValue("container-width", "1200px"); function createContainerStyleFieldset() { const containerStyleFieldset = document.createElement("fieldset"); const legend = document.createElement("legend"); legend.innerText = "正文式样"; containerStyleFieldset.appendChild(legend); const div = document.createElement("div"); div.style = "display: flex; flex-wrap: wrap; gap: 0.5rem;"; const widthInput = document.createElement("input"); widthInput.value = containerWidth; widthInput.size = 10; widthInput.onchange = () => { containerWidth = widthInput.value; document.body.style.setProperty("--container-width", containerWidth); _GM_setValue("container-width", widthInput.value); }; const widthLabel = document.createElement("label"); widthLabel.innerText = "宽度:"; widthLabel.title = "单位可以是 rem, px, %, svw, vw"; widthLabel.appendChild(widthInput); div.appendChild(widthLabel); const fontSizeInput = document.createElement("input"); fontSizeInput.value = novelFontSize; fontSizeInput.size = 10; fontSizeInput.onchange = () => { novelFontSize = fontSizeInput.value; document.body.style.setProperty("--novel-font-size", novelFontSize); _GM_setValue("novel-font-size", fontSizeInput.value); }; const fontSizeLabel = document.createElement("label"); fontSizeLabel.innerText = "字体大小:"; fontSizeLabel.appendChild(fontSizeInput); div.appendChild(fontSizeLabel); const fontFamilyInput = document.createElement("input"); fontFamilyInput.value = novelFontFamily; fontFamilyInput.onchange = () => { novelFontFamily = fontFamilyInput.value; document.body.style.setProperty("--novel-font-family", novelFontFamily); _GM_setValue("novel-font-family", fontFamilyInput.value); }; const fontFamilyLabel = document.createElement("label"); fontFamilyLabel.innerText = "字体:"; fontFamilyLabel.appendChild(fontFamilyInput); div.appendChild(fontFamilyLabel); containerStyleFieldset.appendChild(div); return containerStyleFieldset; } function createSettingForm() { const form = document.createElement("form"); form.appendChild(createContainerStyleFieldset()); const intervalInput = document.createElement("input"); intervalInput.type = "number"; intervalInput.min = "0"; intervalInput.valueAsNumber = refreshInterval / 6e4; intervalInput.style.width = "4rem"; const intervalLabel = document.createElement("label"); intervalLabel.innerText = "刷新间隔(分钟):"; intervalLabel.appendChild(intervalInput); form.appendChild(intervalLabel); const button = document.createElement("button"); button.type = "submit"; button.innerText = "保存刷新设置"; button.style.marginLeft = "0.75rem"; form.appendChild(button); form.appendChild(createAccessKeysFieldset()); const disguiseCodeFieldset = createDisguiseCodeFieldset(); const updateFieldSetsState = (label) => { switch (label) { case "none": disguiseCodeFieldset.style.display = "none"; break; case "code": disguiseCodeFieldset.style.display = "block"; break; } }; updateFieldSetsState(disguiseMode); const radioDiv = document.createElement("div"); radioDiv.style.display = "flex"; radioDiv.innerHTML = `<p>伪装模式:</p>`; [ ["none", "无"], ["code", "代码"] ].forEach(([label, placeholder]) => { const disguiseInput = document.createElement("input"); disguiseInput.name = "disguise-radio"; disguiseInput.type = "radio"; disguiseInput.value = label; disguiseInput.checked = disguiseMode == label; disguiseInput.style.marginLeft = "0.5rem"; disguiseInput.style.marginRight = "0.5rem"; disguiseInput.onchange = () => { const disguiseEnabled = disguiseInput.checked; if (disguiseEnabled) { _GM_setValue("disguise-mode", label); updateFieldSetsState(label); } }; const disguiseLabel = document.createElement("label"); disguiseLabel.style.display = "flex"; disguiseLabel.style.alignItems = "center"; disguiseLabel.appendChild(disguiseInput); const disguiseP = document.createElement("p"); disguiseP.innerText = placeholder; disguiseLabel.appendChild(disguiseP); radioDiv.appendChild(disguiseLabel); }); form.appendChild(radioDiv); form.appendChild(disguiseCodeFieldset); form.onsubmit = (e) => { e.preventDefault(); const interval = parseInt(intervalInput.value) * 6e4; if (interval >= 0 && interval != refreshInterval) { _GM_setValue("refreshInterval", interval); refreshInterval = interval; } }; setTimeout(() => { const pre = document.querySelector("pre"); if (pre) { const computedStyle = getComputedStyle(pre); document.body.style.backgroundColor = computedStyle.backgroundColor; form.style.color = computedStyle.color; } }, 1e3); return form; } function setDefaultStyle() { document.body.style.setProperty("--container-width", containerWidth); document.body.style.setProperty("--novel-font-size", novelFontSize); document.body.style.setProperty("--novel-font-family", novelFontFamily); } function handleBookPage() { let finished = false; const itemtxt = document.querySelector(".itemtxt"); const spans = Array.from(itemtxt.querySelectorAll("p > span")); spans.forEach((span) => { if (span.textContent?.trim() == "已完结") { finished = true; } }); const settingAnchor = document.createElement("a"); settingAnchor.href = "/pifu/"; settingAnchor.style.float = "right"; settingAnchor.style.marginRight = "0.5rem"; settingAnchor.innerText = "脚本设置"; itemtxt.firstElementChild.appendChild(settingAnchor); if (!finished) { const title = itemtxt.querySelector("h1>a").textContent; const latestChapter = itemtxt.querySelector("ul>li>a").textContent; const current = document.createElement("p"); current.innerText = `当前时间:${(/* @__PURE__ */ new Date()).toTimeString()}`; itemtxt.appendChild(current); document.title = `${title} - ${latestChapter}`; if (refreshInterval > 0) { const next = document.createElement("p"); next.innerText = `刷新时间:${new Date(Date.now() + refreshInterval).toTimeString()}`; itemtxt.appendChild(next); setTimeout(() => { location.reload(); }, refreshInterval); } } } function handleSettingPage$1() { const settingForm = createSettingForm(); const container = document.querySelector("div.container"); container.appendChild(settingForm); } function handleChaperPage() { const container = document.querySelector("div.container"); if (location.pathname.includes("-") && container && isInIframe) { const con = container.querySelector("div.con"); let nextHref = ""; let nextChapter = ""; const prenexts2 = document.querySelectorAll("div.prenext a"); for (const element of prenexts2) { if (element instanceof HTMLAnchorElement) { if (element.textContent == "下一页") { nextHref = element.href; break; } if (element.textContent == "下一章") { nextChapter = element.href; break; } } } window.parent.postMessage({ con: con.innerHTML, next: nextHref, nextChapter, href: location.href }); return; } if (_GM_getValue("disguiseDebug", false)) { disguiseParagraphs(document.querySelector("div.container .con")); return; } const prenexts = container.querySelectorAll("div.prenext a"); window.addEventListener("message", (e) => { if (e.data.con) { const next = document.createElement("div"); next.className = "con"; next.innerHTML = e.data.con; const container2 = document.querySelector("div.container .con"); next.querySelectorAll("p").forEach((p) => container2.appendChild(p)); } if (e.data.next) { const iframe = document.querySelector("iframe"); if (iframe) { iframe.contentWindow.location.replace(e.data.next); } } else { console.debug("no next"); if (!isInIframe && disguiseMode != "none") { const container2 = document.querySelector("div.container .con"); disguiseParagraphs(container2); } const iframe = document.querySelector("iframe"); if (iframe) { iframe.remove(); } const nextChapter = e.data.nextChapter; if (nextChapter) { for (const element of prenexts) { if (element instanceof HTMLAnchorElement) { if (element.textContent == "下一页") { element.href = nextChapter; if (nextChapter.endsWith(".html")) { element.innerText = "下一章"; element.accessKey = nextChapterAccessKey; element.ariaKeyShortcuts = `Alt+${nextChapterAccessKey}`; } else { element.innerText = "返回目录"; } break; } } } } } }); for (const element of prenexts) { if (element instanceof HTMLAnchorElement) { if (element.textContent == "下一页") { const next = document.createElement("iframe"); next.src = element.href; next.style.display = "none"; container && container.appendChild(next); } else if (element.textContent == "上一章") { element.accessKey = previousChapterAccessKey; element.ariaKeyShortcuts = `Alt+${previousChapterAccessKey}`; } else if (element.textContent == "目录") { element.accessKey = bookPageAccessKey; element.ariaKeyShortcuts = `Alt+${bookPageAccessKey}`; } else if (element.textContent == "下一章") { element.accessKey = nextChapterAccessKey; element.ariaKeyShortcuts = `Alt+${nextChapterAccessKey}`; if (!isInIframe && disguiseMode != "none") { const container2 = document.querySelector("div.container .con"); disguiseParagraphs(container2); } } } } } function handleDeqiRoute() { if (location.pathname === "/pifu/") { setupCodeTheme(); setupExtendLanguageSupport(); handleSettingPage$1(); } else if (location.pathname.endsWith(".html")) { if (!isInIframe) { switch (disguiseMode) { case "code": setupCodeTheme(); setupExtendLanguageSupport(); break; } } handleChaperPage(); } else if (location.pathname.startsWith("/xiaoshuo/")) { handleBookPage(); } } function handleSettingPage() { const settingForm = createSettingForm(); const articleMain = document.createElement("div"); articleMain.id = "article_main"; articleMain.classList = "container"; const container = document.getElementById("main"); articleMain.appendChild(settingForm); container.appendChild(articleMain); } function handleChapterPage() { if (disguiseDebug) { disguiseParagraphs(document.getElementById("mainboxs")); return; } const nextLinks = Array.from( document.querySelectorAll("#page-links a.post-page-numbers") ); const netxDivs = new Array(nextLinks.length); let remainLinks = nextLinks.length; let hasCanvas = false; for (let index = 0; index < nextLinks.length; index++) { const element = nextLinks[index]; _GM_xmlhttpRequest({ method: "GET", url: element.href, responseType: "document", onload: (response) => { const doc = response.response; const div = doc.getElementById("mainboxs"); if (div.getElementsByTagName("p").length == 0) { hasCanvas = true; } netxDivs[index] = div.innerHTML; element.remove(); remainLinks--; if (remainLinks == 0) { const mainboxs = document.getElementById("mainboxs"); netxDivs.forEach((div2) => { const next = document.createElement("div"); next.innerHTML = div2; mainboxs.appendChild(next); }); const main = document.getElementById("article_main"); if (main) { main.appendChild(document.querySelector("div.page-links")); main.appendChild(mainboxs); main.appendChild(document.querySelector("div.prenext")); main.appendChild(document.querySelector("div.post-content")); main.querySelectorAll(".page-links, .post-content"); } if (hasCanvas) { document.body.append("章节不完整"); } disguiseParagraphs(mainboxs); } } }); } const prenexts = document.querySelectorAll("div.prenext a"); for (const element of prenexts) { if (element instanceof HTMLAnchorElement) { if (element.textContent == "上一章") { element.accessKey = previousChapterAccessKey; element.ariaKeyShortcuts = `Alt+${previousChapterAccessKey}`; } else if (element.textContent == "章节目录") { element.accessKey = bookPageAccessKey; element.ariaKeyShortcuts = `Alt+${bookPageAccessKey}`; } else if (element.textContent == "下一章") { element.accessKey = nextChapterAccessKey; element.ariaKeyShortcuts = `Alt+${nextChapterAccessKey}`; } } } } function handleBiqu33Route() { const segments = location.pathname.split("/").filter(Boolean); const lastSegment = segments[segments.length - 1]; switch (segments.length) { case 0: case 1: case 2: setupCodeTheme(); setupExtendLanguageSupport(); handleSettingPage(); break; case 3: if (/[\d\w]+_\d+$/.test(lastSegment)) { return; } switch (disguiseMode) { case "code": setupCodeTheme(); setupExtendLanguageSupport(); break; } handleChapterPage(); break; } } window.Prism = _unsafeWindow.Prism = _unsafeWindow.Prism || window.Prism; function handleRoute() { if (location.host.endsWith("deqixs.com")) { handleDeqiRoute(); _GM_registerMenuCommand("脚本设置", function() { open("/pifu/"); }); } else if (location.hostname == "www.biqu33.cc" || location.pathname.startsWith("/book/")) { handleBiqu33Route(); _GM_registerMenuCommand("脚本设置", function() { open("/"); }); } } setDefaultStyle(); handleRoute(); releaseCopy(); })();