Deqi Prefech

得奇小说网,看单个章节免翻页

// ==UserScript==
// @name                  Deqi Prefech
// @namespace             https://greasyfork.org/zh-CN/users/14997-lrh3321
// @version               2025-07-17
// @description           得奇小说网,看单个章节免翻页
// @author                LRH3321
// @license               MIT
// @tag                   novels
// @match                 https://www.deqixs.com/pifu/
// @match                 https://www.deqixs.com/xiaoshuo/*/*.html
// @match                 https://www.deqixs.com/xiaoshuo/*/
// @icon                  https://www.google.com/s2/favicons?sz=64&domain=deqixs.com
// @require               https://cdn.jsdelivr.net/npm/[email protected]/dist/handsontable.full.min.js
// @resource              htcss https://cdn.jsdelivr.net/npm/handsontable/styles/handsontable.min.css
// @resource              ht_main_css https://cdn.jsdelivr.net/npm/handsontable/styles/ht-theme-main.min.css
// @resource              ht_horizon_css https://cdn.jsdelivr.net/npm/handsontable/styles/ht-theme-horizon.min.css
// @grant                 GM_setValue
// @grant                 GM_getValue
// @grant                 GM_getResourceURL
// @grant                 GM_addStyle
// @grant                 GM_addElement
// @grant                 unsafeWindow
// @run-at                document-end
// ==/UserScript==
(function () {
    // 'use strict';
    const isInIframe = window.self !== window.top;
    // 是否伪装成代码
    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);
    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' }
    ];
    const avalibleSheetThemes = [
        { Name: 'Main', code: 'ht-theme-main' },
        { Name: 'Main Dark', code: 'ht-theme-main-dark' },
        { Name: 'Main Dark Auto', code: 'ht-theme-main-dark-auto' },
        { Name: 'Horizon', code: 'ht-theme-horizon' },
        { Name: 'Horizon Dark', code: 'ht-theme-horizon-dark' },
        { Name: 'Horizon Dark Auto', code: 'ht-theme-horizon-dark-auto' }
    ];
    let codeTheme = GM_getValue('code-theme', 'prism');
    let sheetTheme = GM_getValue('sheet-theme', 'ht-theme-horizon-dark-auto');
    // console.log(codeTheme, sheetTheme);
    // let sheetTheme = GM_getValue('sheet-theme', 'ht-theme-horizon');
    let codeThemeElement = null;
    function getCodeThemeURL(theme) {
        const officialThemes = 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`;
    }
    let italicStyle = null;
    function disableItalicComment() {
        italicStyle = GM_addStyle(`span.token.comment { font-style: normal; }`);
    }
    if (!isInIframe) {
        codeThemeElement = GM_addElement(document.head, 'link', {
            href: getCodeThemeURL(codeTheme),
            rel: 'stylesheet',
            type: 'text/css'
        });
        GM_addElement(document.head, 'link', {
            href: GM_getResourceURL('htcss'),
            rel: 'stylesheet',
            type: 'text/css'
        });
        GM_addElement(document.head, 'link', {
            href: GM_getResourceURL('ht_main_css'),
            rel: 'stylesheet',
            type: 'text/css'
        });
        GM_addElement(document.head, 'link', {
            href: GM_getResourceURL('ht_horizon_css'),
            rel: 'stylesheet',
            type: 'text/css'
        });
        GM_addStyle(`.ht-wrapper div { margin: initial; }`);
        if (!GM_getValue('code-italic', true)) {
            disableItalicComment();
        }
    }
    let refreshInterval = GM_getValue('refreshInterval', 15 * 60000);
    function changeCodeTheme(theme) {
        GM_setValue('code-theme', theme);
        codeTheme = theme;
        codeThemeElement === null || codeThemeElement === void 0 ? void 0 : codeThemeElement.remove();
        codeThemeElement = GM_addElement(document.head, 'link', {
            href: getCodeThemeURL(theme),
            rel: 'stylesheet',
            type: 'text/css'
        });
        // document.body.style.backgroundColor = '';
    }
    function changeSheetTheme(theme) {
        GM_setValue('sheet-theme', theme);
        sheetTheme = theme;
        if (hot) {
            hot.useTheme(theme);
        }
    }
    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: 1rem;">
    <label>上一章:
        <select id="previousChapterAccessKey"></select>
    </label>
    <label>目录:
        <select id="bookPageAccessKey"></select>
    </label>
    <label>下一章:
        <select id="nextChapterAccessKey"></select>
    </label>
</div>`;
        const previousChapterAccessKey = accessKeysFieldset.querySelector('#previousChapterAccessKey');
        const bookPageAccessKey = accessKeysFieldset.querySelector('#bookPageAccessKey');
        const nextChapterAccessKey = accessKeysFieldset.querySelector('#nextChapterAccessKey');
        for (let i = 0; i < 10; i++) {
            const option = document.createElement('option');
            const charCode = 48 + i; // '0' is 97 in ASCII
            option.value = String.fromCharCode(charCode);
            option.text = String.fromCharCode(charCode);
            previousChapterAccessKey.appendChild(option);
            bookPageAccessKey.appendChild(option.cloneNode(true));
            nextChapterAccessKey.appendChild(option.cloneNode(true));
        }
        for (let i = 0; i < 26; i++) {
            const option = document.createElement('option');
            const charCode = 97 + i; // 'a' is 97 in ASCII
            option.value = String.fromCharCode(charCode);
            option.text = String.fromCharCode(charCode);
            previousChapterAccessKey.appendChild(option);
            bookPageAccessKey.appendChild(option.cloneNode(true));
            nextChapterAccessKey.appendChild(option.cloneNode(true));
        }
        bookPageAccessKey.value = GM_getValue('bookPageAccessKey', 'h');
        previousChapterAccessKey.value = GM_getValue('previousChapterAccessKey', 'b');
        nextChapterAccessKey.value = GM_getValue('nextChapterAccessKey', 'n');
        previousChapterAccessKey.onchange = (e) => {
            if (previousChapterAccessKey.selectedOptions.length > 0) {
                GM_setValue('previousChapterAccessKey', previousChapterAccessKey.value);
            }
        };
        bookPageAccessKey.onchange = (e) => {
            if (bookPageAccessKey.selectedOptions.length > 0) {
                GM_setValue('bookPageAccessKey', bookPageAccessKey.value);
            }
        };
        nextChapterAccessKey.onchange = (e) => {
            if (nextChapterAccessKey.selectedOptions.length > 0) {
                GM_setValue('nextChapterAccessKey', nextChapterAccessKey.value);
            }
        };
        return accessKeysFieldset;
    }
    function createDisguiseCodeFieldset() {
        const disguiseFieldset = document.createElement('fieldset');
        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);
            }
        };
        const codeThemeLabel = document.createElement('label');
        codeThemeLabel.innerText = '代码主题:';
        codeThemeLabel.appendChild(codeThemeInput);
        disguiseFieldset.appendChild(codeThemeLabel);
        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 = () => {
            console.log('change');
            if (codeLangInput.selectedIndex >= 0) {
                const lang = codeLangInput.value;
                GM_setValue('code-lang', lang);
            }
        };
        const codeLangLabel = document.createElement('label');
        codeLangLabel.innerText = '代码语言:';
        codeLangLabel.style.marginLeft = '0.5rem';
        codeLangLabel.appendChild(codeLangInput);
        disguiseFieldset.appendChild(codeLangLabel);
        const codeItalicInput = document.createElement('input');
        codeItalicInput.type = 'checkbox';
        codeItalicInput.name = 'font-italic';
        codeItalicInput.checked = GM_getValue('code-italic', true);
        codeItalicInput.onchange = () => {
            const checked = codeItalicInput.checked;
            GM_setValue('code-italic', checked);
            if (checked) {
                if (italicStyle) {
                    italicStyle.remove();
                    italicStyle = null;
                }
            }
            else {
                disableItalicComment();
            }
        };
        const codeItalicLabel = document.createElement('label');
        codeItalicLabel.style.marginLeft = '0.5rem';
        codeItalicLabel.appendChild(codeItalicInput);
        codeItalicLabel.append(' 小说斜体');
        disguiseFieldset.appendChild(codeItalicLabel);
        const demoCodeTitle = document.createElement('h3');
        demoCodeTitle.innerText = '主题效果:';
        disguiseFieldset.appendChild(demoCodeTitle);
        const preDemo = document.createElement('pre');
        preDemo.innerHTML = `<code class="language-javascript"><span class="token comment">/*
	让我们说中文
 */</span>
<span class="token keyword">function</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token parameter">bar</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token comment">// 短的注释</span>
	<span class="token keyword">var</span> a <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">,</span>
		b <span class="token operator">=</span> <span class="token string">'Prism'</span><span class="token punctuation">;</span>
	<span class="token keyword">return</span> a <span class="token operator">+</span> <span class="token function">bar</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code>`;
        preDemo.className = 'language-javascript';
        disguiseFieldset.appendChild(preDemo);
        const fakeCodeSnippetTitle = document.createElement('h3');
        fakeCodeSnippetTitle.innerText = '伪装用代码段(代码块间使用 “====” 分割):';
        disguiseFieldset.appendChild(fakeCodeSnippetTitle);
        const textarea = document.createElement('textarea');
        textarea.name = 'fake-code-snippet';
        textarea.placeholder = '伪装用代码段(代码块间使用 “====” 分割)';
        textarea.style.padding = '0.5rem';
        textarea.rows = 20;
        textarea.value = fakeCodeSnippet;
        textarea.style.width = '100%';
        disguiseFieldset.appendChild(textarea);
        textarea.onchange = () => {
            GM_setValue('fake-codes', textarea.value);
        };
        return disguiseFieldset;
    }
    function createDisguiseSheetFieldset() {
        const disguiseFieldset = document.createElement('fieldset');
        const sheetThemeInput = document.createElement('select');
        sheetThemeInput.name = 'sheet-theme';
        avalibleSheetThemes.forEach((theme) => {
            const option = document.createElement('option');
            option.value = theme.code;
            option.text = theme.Name;
            sheetThemeInput.appendChild(option);
        });
        sheetThemeInput.value = sheetTheme;
        sheetThemeInput.onchange = () => {
            console.log('change');
            const theme = sheetThemeInput.value;
            if (sheetThemeInput.selectedIndex >= 0 && theme && theme != sheetTheme) {
                console.log(`Change sheet theme to ${theme}`);
                changeSheetTheme(theme);
            }
        };
        const sheetThemeLabel = document.createElement('label');
        sheetThemeLabel.innerText = '表格主题:';
        sheetThemeLabel.appendChild(sheetThemeInput);
        disguiseFieldset.appendChild(sheetThemeLabel);
        return disguiseFieldset;
    }
    function createSettingForm() {
        const form = document.createElement('form');
        const intervalInput = document.createElement('input');
        intervalInput.type = 'number';
        intervalInput.min = '0';
        intervalInput.valueAsNumber = refreshInterval / 60000;
        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 disguiseSheetFieldset = createDisguiseSheetFieldset();
        const updateFieldSetsState = (label) => {
            switch (label) {
                case 'none':
                    disguiseCodeFieldset.style.display = 'none';
                    disguiseSheetFieldset.style.display = 'none';
                    break;
                case 'code':
                    disguiseCodeFieldset.style.display = 'block';
                    disguiseSheetFieldset.style.display = 'none';
                    break;
                case 'sheet':
                    disguiseCodeFieldset.style.display = 'none';
                    disguiseSheetFieldset.style.display = 'block';
                    break;
            }
        };
        updateFieldSetsState(disguiseMode);
        const radioDiv = document.createElement('div');
        radioDiv.style.display = 'flex';
        radioDiv.innerHTML = `<p>伪装模式:</p>`;
        [
            ['none', '无'],
            ['code', '代码'],
            ['sheet', '表格']
        ].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;
                // GM_setValue('disguise', disguiseEnabled);
                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.appendChild(disguiseSheetFieldset);
        form.onsubmit = (e) => {
            e.preventDefault();
            const interval = parseInt(intervalInput.value) * 60000;
            if (interval >= 0 && interval != refreshInterval) {
                GM_setValue('refreshInterval', interval);
                refreshInterval = interval;
            }
        };
        return form;
    }
    function handleBookPage() {
        let finished = false;
        const itemtxt = document.querySelector('.itemtxt');
        const spans = Array.from(itemtxt.querySelectorAll('p > span'));
        spans.forEach((span) => {
            var _a;
            if (((_a = span.textContent) === null || _a === void 0 ? void 0 : _a.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 = `当前时间:${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() {
        const settingForm = createSettingForm();
        const container = document.querySelector('div.container');
        container.appendChild(settingForm);
    }
    function disguiseToCode(container) {
        if (fakeCodeSnippet.trim() == '') {
            fakeCodeSnippet = defaultCodeSnippet;
        }
        const fakeCodes = fakeCodeSnippet.split('====');
        const getRandomCode = () => fakeCodes[Math.floor(Math.random() * fakeCodes.length)];
        var lines = [];
        const paragraphs = Array.from(container.querySelectorAll('p'));
        const code = document.createElement('code');
        code.className = `language-${codeLang}`;
        code.style.whiteSpace = 'pre-wrap';
        code.style.textWrap = 'pretty';
        code.style.overflowX = 'auto';
        let blockCommentStart = '/*';
        let blockCommentEnd = '*/';
        let shortCommnet = '';
        switch (codeLang) {
            case 'clike':
            case 'javascript':
                shortCommnet = '// ';
                break;
            default:
                break;
        }
        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();
            }
            const trimed = line.replace(/^[\s\t]+/, '');
            if (trimed !== line) {
                const prefix = line.substring(0, line.length - trimed.length);
                if (textContent.length < 20 && shortCommnet != '') {
                    code.append(`${prefix}${shortCommnet}${textContent}\n`);
                }
                else {
                    code.append(`${prefix}${blockCommentStart}\n${prefix}  ${textContent}\n${prefix}${blockCommentEnd}\n`);
                }
            }
            else {
                if (textContent.length < 20 && shortCommnet != '') {
                    code.append(`${shortCommnet}${textContent}\n`);
                }
                else {
                    code.append(`${blockCommentStart}\n  ${textContent}\n${blockCommentEnd}\n`);
                }
            }
            code.append(line);
            code.append('\n');
            p.remove();
        });
        lines.forEach((line) => {
            code.append(line);
            code.append('\n');
        });
        const pre = document.createElement('pre');
        pre.style.whiteSpace = 'pre-wrap';
        pre.style.textWrap = 'pretty';
        pre.style.overflowX = 'auto';
        pre.className = `language-${codeLang}`;
        pre.appendChild(code);
        container.parentElement.replaceChild(pre, container);
        GM_addElement('script', { src: 'https://dev.prismjs.com/prism.js' });
    }
    let hot;
    let sheetData = [['', 'Tesla', 'Volvo', 'Toyota', 'Ford']];
    function disguiseToSheet(container) {
        const paragraphs = Array.from(container.querySelectorAll('p'));
        paragraphs.forEach((p, i) => {
            var _a;
            const textContent = (_a = p.textContent) === null || _a === void 0 ? void 0 : _a.trim();
            sheetData.push([textContent, i, 11, 12, 13]);
            p.remove();
        });
        if (typeof hot === 'undefined') {
            const ele = document.createElement('div');
            hot = new Handsontable(ele, {
                data: sheetData,
                // rowHeaders: false,
                // colHeaders: false,
                rowHeaders: true,
                colHeaders: true,
                height: 'auto',
                width: 'auto',
                autoWrapRow: true,
                autoWrapCol: true,
                readOnly: true,
                themeName: sheetTheme,
                licenseKey: 'non-commercial-and-evaluation' // for non-commercial use only
            });
            container.parentElement.appendChild(ele);
        }
        else {
            hot.updateData(sheetData);
        }
        hot.refreshDimensions();
    }
    function disguiseParagraphs(container) {
        switch (disguiseMode) {
            case 'sheet':
                disguiseToSheet(container);
                break;
            case 'code':
            default:
                // 伪装成代码
                disguiseToCode(container);
                break;
        }
    }
    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 prenexts = document.querySelectorAll('div.prenext a');
            for (const element of prenexts) {
                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: nextChapter,
                href: location.href
            });
            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 container = document.querySelector('div.container .con');
                next.querySelectorAll('p').forEach((p) => container.appendChild(p));
            }
            if (e.data.next) {
                const iframe = document.querySelector('iframe');
                if (iframe) {
                    // iframe.src = e.data.next;
                    iframe.contentWindow.location.replace(e.data.next);
                }
            }
            else {
                console.debug('no next');
                if (!isInIframe && disguiseMode != 'none') {
                    const container = document.querySelector('div.container .con');
                    disguiseParagraphs(container);
                }
                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;
                                }
                                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;
                }
                else if (element.textContent == '目录') {
                    element.accessKey = bookPageAccessKey;
                }
            }
        }
    }
    if (location.pathname === '/pifu/') {
        handleSettingPage();
    }
    else if (location.pathname.endsWith('.html')) {
        handleChaperPage();
    }
    else {
        handleBookPage();
    }
})();