轻小说文库+

章节批量下载,版权限制小说TXT简繁全本下载,书名/作者名双击复制,Ctrl+Enter快捷键发表书评

目前為 2021-01-14 提交的版本,檢視 最新版本

// ==UserScript==
// @name         轻小说文库+
// @namespace    Wenku8+
// @version      0.7.1
// @description  章节批量下载,版权限制小说TXT简繁全本下载,书名/作者名双击复制,Ctrl+Enter快捷键发表书评
// @author       PY-DNG
// @match        http*://www.wenku8.net/*
// @connect      dl.wenku8.com
// @connect      dl2.wenku8.com
// @connect      dl3.wenku8.com
// @grant        GM_download
// @grant        GM_xmlhttpRequest
// ==/UserScript==

(function() {
    'use strict';

    // CONSTS
    const HTML_DOWNLOAD_CONTENER = '<div id="dctn" style=\"margin:0px auto;overflow:hidden;\">\n<fieldset style=\"width:820px;height:35px;margin:0px auto;padding:0px;\">\n<legend><b>《{BOOKNAME}》小说TXT简繁全本下载</b></legend>\n</fieldset>\n</div>';
    const HTML_DOWNLOAD_LINKS = '<div class="even">\n<span>简体(G)(<a class="dlink" href="http://dl.wenku8.com/down.php?type=txt&amp;id={BOOKID}" target="_black">载点一</a> \n<a class="dlink" href="http://dl.wenku8.com/down.php?type=txt&amp;id={BOOKID}&amp;fname=%B0%B2%B4%EF%D3%EB%B5%BA%B4%E5" target="_black">载点二</a>)</span>\n\n<span>简体(U)(<a class="dlink" href="http://dl.wenku8.com/down.php?type=utf8&amp;id={BOOKID}" target="_black">载点一</a> \n<a class="dlink" href="http://dl.wenku8.com/down.php?type=utf8&amp;id={BOOKID}&amp;fname=%B0%B2%B4%EF%D3%EB%B5%BA%B4%E5" target="_black">载点二</a>)</span>\n\n<span>繁体(U)(<a class="dlink" href="http://dl.wenku8.com/down.php?type=big5&amp;id={BOOKID}" target="_black">载点一</a> \n<a class="dlink" href="http://dl.wenku8.com/down.php?type=big5&amp;id={BOOKID}&amp;fname=%B0%B2%B4%EF%D3%EB%B5%BA%B4%E5" target="_black">载点二</a>)</span>\n  </div>';
    const HTML_DOWNLOAD_BOARD = '[轻小说文库+] 为您提供《{BOOKNAME}》的TXT简繁全本下载!</br>由此产生的一切法律及其他问题均由脚本用户承担</br>—— PY-DNG';
    const CSS_DOWNLOAD = '.even {display: grid; grid-template-columns: repeat(3, 1fr); text-align: center;} .dlink {text-align: center;}';

    const TEXT_TIP_COPY = '双击复制';

    // Get tab url api part
    const API = window.location.href.replace(/https?:\/\/www\.wenku8\.net\//, '').replace(/\?.*/, '').replace(/^book\/\d+\.html?/, 'book');
    switch (API) {
        // Dwonload page
        case 'modules/article/packshow.php':
            pageDownload();
            break;
        case 'modules/article/reviews.php':
        case 'modules/article/reviewshow.php':
            pageReview();
            break;
        // Index page
        case 'index.php':
            pageIndex();
            break;
        // Book page
        case 'book':
            pageBook();
            break;
        // Other pages
        default:
            console.log(API);
    }

    // Book page add-on
    function pageBook() {
        const bookIdText = location.href.match(/\/(\d+)\.htm/)[1];
        const bookNameElement = document.querySelector('#content > div:nth-child(1) > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(1) > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(1) > span:nth-child(1) > b:nth-child(1)');
        const bookName = bookNameElement.innerText;
        const authorNameElement = document.querySelector('#content > div:nth-child(1) > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(2) > td:nth-child(2)');
        const authorName = authorNameElement.innerText.substr(authorNameElement.innerText.indexOf(':') + 1);
        const downloadEnabled = document.querySelector('#content > div:nth-child(1) > div > fieldset:nth-child(1) > legend:nth-child(1) > b:nth-child(1)') !== null;
        const commentArea = document.querySelector('#pcontent');
        const commentForm = document.querySelector('form[action^="https://www.wenku8.net/modules/article/reviews.php"]');
        const commentSbmt = document.querySelector('td > input[name="Submit"]');

        // Ctrl+Enter comment submit
        commentSbmt.value = '发表书评(Ctrl+Enter)';
        commentSbmt.style.padding = '0.3em 0.4em 0.3em 0.4em';
        commentSbmt.style.height= 'auto';
        commentArea.addEventListener('keydown', function() {
            let keycode = event.keyCode;
            if (keycode === 13 && event.ctrlKey && !event.altKey) {
                commentForm.submit();
            }
        })

        // Provide book & author name doubleclick copy
        bookNameElement.title = TEXT_TIP_COPY;
        authorNameElement.title = TEXT_TIP_COPY;
        bookNameElement.addEventListener('dblclick', function() {copyText(bookName);});
        authorNameElement.addEventListener('dblclick', function() {copyText(authorName);});

        // Provide txtfull download for book which download is disabled
        if (!downloadEnabled) {
            // Append download html model
            const modelContainer = document.createElement('div');
            document.querySelector('#content div').appendChild(modelContainer);
            modelContainer.outerHTML = HTML_DOWNLOAD_CONTENER.replaceAll('{BOOKNAME}', bookName);
            //document.querySelector('#content div').innerHTML += HTML_DOWNLOAD_CONTENER.replaceAll('{BOOKNAME}', bookName);
            document.querySelector('#content div').lastChild.querySelector('fieldset').innerHTML += HTML_DOWNLOAD_LINKS.replaceAll('{BOOKID}', bookIdText);
            // Append CSS
            addStyle(CSS_DOWNLOAD);
            // Write textboard
            let textBoard = document.querySelector('#content > div:nth-child(1) > table:nth-child(4) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(2) > span:nth-child(1) > b:nth-child(2)');
            textBoard.innerHTML = HTML_DOWNLOAD_BOARD.replaceAll('{BOOKNAME}', bookName);
            textBoard.style.color = 'green';
        }
    }

    // Review page add-on
    function pageReview() {
        const commentArea = document.querySelector('#pcontent');
        const commentForm = document.querySelector('form[action^="https://www.wenku8.net/modules/article/review"]');
        const commentSbmt = document.querySelector('td > input[name="Submit"]');

        // Ctrl+Enter comment submit
        commentSbmt.value = '发表书评(Ctrl+Enter)';
        commentSbmt.style.padding = '0.3em 0.4em 0.3em 0.4em';
        commentSbmt.style.height= 'auto';
        commentArea.addEventListener('keydown', function() {
            let keycode = event.keyCode;
            if (keycode === 13 && event.ctrlKey && !event.altKey) {
                commentForm.submit();
            }
        })
    }

    // Index page add-on
    function pageIndex() {
    }

    // Download page add-on
    function pageDownload() {
        let i;
        /* ******************* GUI ******************* */
        // Create left operation GUI
        let downloadGUI = document.querySelectorAll('#left div.block')[1].cloneNode(true);
        // Rename title
        downloadGUI.querySelector('.blocktitle .txt').innerHTML = '下载全部章节';
        // Remove content
        downloadGUI.removeChild(downloadGUI.querySelector('.blockcontent'));
        // Create operation ul list
        let optionButtonsForm = document.querySelector('#left div.block div.blockcontent div ul[style]').cloneNode(true);
        // Reset lis
        const NAMES = ['本地简体(G)', '本地简体(U)', '本地繁体(U)', '地址二简体(G)', '地址二简体(U)', '地址二繁体(U)'];
        let lis = optionButtonsForm.querySelectorAll('li');
        let li = lis[0].cloneNode(true);
        let newli;
        li.querySelector('a').href = 'javascript:void(0);';
        li.querySelector('a').className = '';
        li.querySelector('a').innerHTML = '默认按钮文本';
        for (i = 0; i < 6; i++) {
            // If li exist, remove it
            if (lis[i]) {
                optionButtonsForm.removeChild(lis[i]);
            };
            // Create a new one
            newli = li.cloneNode(true);
            // Modify name
            newli.querySelector('a').innerHTML = NAMES[i];
            // Mark i
            newli.i = i;
            // Append it
            optionButtonsForm.appendChild(newli);
            // Add event listener
            newli.addEventListener('click',
            function() { // i refers to its current value in loop by marking on the li element
                downloadAll(this.i);
            })
        }
        // Create a container
        let blockcontent = document.createElement('div');
        blockcontent.classList.add('blockcontent');
        blockcontent.style.paddingLeft = '10px';
        // Append ul
        blockcontent.appendChild(optionButtonsForm);
        // Append container
        downloadGUI.appendChild(blockcontent);
        // Append GUI
        document.querySelector('#left').appendChild(downloadGUI);

        /* ******************* Code ******************* */
        // Get novel name
        const novelName = document.querySelector('html body div.main div#centerm div#content table.grid caption a').innerText;
        let downloadAll = function(type) {
            // GUI display
            downloadGUI.querySelector('.blocktitle .txt').innerHTML = '下载中...';
            // Name customize
            let NAME = novelName + ' {j}.';
            let allNames = getAllNames();
            if (window.location.href.indexOf('txt') != -1) {
                NAME += 'txt';
            } else {
                NAME += document.querySelector('html body div.main div#centerm div#content table.grid tbody tr td.even a').innerText.replace(/[^\w]+/, '').toLowerCase();
            }
            let i,j = 0;
            const allA = document.querySelectorAll('.even a');
            for (i = type; i < allA.length; i = i + 6) {
                /*GM_download({
                    url: allA[i].href,
                    name: NAME.replace('{j}', (window.location.href.indexOf('txtfull') === -1 ? allNames[j] : ''))
                });*/
                download(
                    allA[i].href,
                    NAME.replace('{j}', (window.location.href.indexOf('txtfull') === -1 ? allNames[j] : '')),
                    allA[i].parentElement.parentElement.querySelector('td.odd')
                )
                j += 1;
            }
            downloadGUI.querySelector('.blocktitle .txt').innerHTML = '下载全部章节';
        }

        function getAllNames() {
            let all = document.querySelectorAll('.grid tbody tr .odd');
            let names = [];
            for (let i = 0; i < all.length; i++) {
                names[i] = all[i].innerText;
            }
            return names;
        }

        // File download function
        function download(url, name, displayElement) {
            // Check
            if (!url || !name) {
                return false;
            }

            // Display
            let text = '';
            if (displayElement) {
                if (displayElement.innerText) {text = displayElement.innerText;};
                displayElement.innerText = text + ' 下载中...';
            }

            // xmlHTTPRequest
            GM_xmlhttpRequest({
                method:       'GET',
                url:          url,
                responseType: 'blob',
                onload:       function(request) {
                    // DataURL
                    let objURL = URL.createObjectURL(request.response);

                    // Create <a>
                    const a = document.createElement('a');
                    //a.style.display = 'none';
                    a.href = objURL;
                    a.download = name;
                    //document.body.appendChild(a);
                    a.click();
                    //document.body.removeChild(a);

                    // Display
                    if (displayElement) {
                        displayElement.innerText = '下载完毕';
                        if (text) {displayElement.innerText = text + ' (下载完毕)';};
                    }
                }
            })

            return true;
        }
    }

    function addStyle(css) {
        document.head.appendChild(document.createElement("style")).textContent = css;
    }

    function copyText(text) {
        // Create a new input for copying
        const newInput = document.createElement('input');
        document.body.appendChild(newInput);
        newInput.value = text;
        newInput.select();
        document.execCommand('copy');
        document.body.removeChild(newInput);
    }
})();