Самиздат (samlib.ru) как надо

Убирает рекламу, позволяет читать скрытые комментарии, постить комментарии там, где они отключены, смотреть отключенные оценки.

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        Самиздат (samlib.ru) как надо
// @namespace   Azazar's Scripts
// @description Убирает рекламу, позволяет читать скрытые комментарии, постить комментарии там, где они отключены, смотреть отключенные оценки.
// @match       *://samlib.ru/*
// @version     1.03
// @grant       none
// @license     MIT
// @license     MIT
// ==/UserScript==

(function() {
    var _$;
    var A$;

    function _(s) {
        A$ = document.querySelectorAll(s);
        _$ = A$.length > 0 ? A$[0] : null;
        return _$;
    }

    function findElementByText(s, text, partialMatch) {
        if (_(s) === null) {
            return null;
        }

        text = text.trim();

        for(var i = 0; i < A$.length; i++) {
            if (partialMatch) {
                if (A$[i].innerText.indexOf(text) !== -1) {
                    return A$[i];
                }
            }
            else {
                if (text === A$[i].innerText.trim()) {
                    return A$[i];
                }
            }
        }

        return null;
    }

    function C$(tagName, attrs, parent, children) {
        var e = document.createElement(tagName);

        if (attrs === undefined) {
        }
        else if (attrs !== null && typeof attrs === "object") {
            for(var n in attrs) {
                e.setAttribute(n, attrs[n]);
            }
        }
        else {
            console.warn("Bad attrs parameter:", attrs);
        }

        if (children === undefined) {
        }
        else if (children !== null) {
            if (typeof children === "object") {
                if (children.constructor.name === "Array") {
                    children.forEach(function(c) {
                        e.appendChild(c)
                    });
                }
                else {
                    e.appendChild(children);
                }
            }
            else if (typeof children === "string") {
                e.appendChild(document.createTextNode(children));
            }
            else {
                console.warn("Bad children parameter:", children);
            }
        }

        if (parent !== null) {
            parent.appendChild(e);
        }

        return e;
    }

    function removeNode() {
        var node = arguments.length === 0 ? _$ : arguments[0];

        if (node === null || node.parentNode === null) {
            return;
        }

        node.parentNode.removeChild(node);
    }

    // Реклама всё равно сделана бестолково, и вряд ли приносит прибыль.
    // Лучше бы пожертвования собирали.
    if (_("TD[BGCOLOR='#fbfafa']") !== null) {
        console.log("Реклама боковая:", _$);
        removeNode();
    }
    else if (_("TABLE[STYLE='border: solid #8e5373 2px; margin-bottom: 3px;']")) {
        console.log("Реклама в шапке:", _$);
        removeNode();
    }

    var section = null;
    var authorLetter = null;
    var authorId = null;
    var bookId = null;

    var authorUri = null;
    var bookUri = null;

    {
        var m;

        if ((m = /^\/([A-Za-z0-9]{1,2})\/([A-Za-z0-9_-]+)\/(?:([A-Za-z0-9_-]+)\.shtml)?(?:$|\?)/.exec(location.pathname)) !== null) {
            authorLetter = m[1];
            authorId = m[2];
            bookId = m[3];

            section = bookId ? "book" : "author";

            console.log("Совпал шаблон пути:", section, authorLetter, authorId, bookId);

        }
        else if ((m = /^\/(comment)\/([A-Za-z0-9-]{1,2})\/([A-Za-z0-9_-]+)\/([A-Za-z0-9_-]+)?(?:$|\?)/.exec(location.pathname)) !== null) {
            section = m[1];
            authorLetter = m[2];
            authorId = m[3];
            bookId = m[4];

            console.log("Совпал шаблон пути:", section, authorLetter, authorId, bookId);

        }
        else {
            console.log("Не совпал шаблон пути:", location.pathname);
        }

        if (authorId && authorLetter) {
            authorUri = "/" + authorLetter + "/" + authorId;
        }

        if (authorUri && bookId) {
            bookUri = authorUri + "/" + bookId;
        }

    }

    if ("book" === section) {
        if (_("FORM[ACTION='/cgi-bin/votecounter']") !== null) {
            if (_$.innerText === "") {
                console.log("Оценки отключены");

                _$.innerHTML = _$.innerHTML.replace(/<!--[\r\n\t ]+1/, "").replace(/1[\r\n\t ]+-->/, "");

                console.log("Но мы это исправили");
            }
            else if (/<!--[\t\r\n ]+1[\t\r\n ]+Оценка:/) {
                console.log("Отображение оценок отключено");

                _$.innerHTML = _$.innerHTML.replace(/<!--[\r\n\t ]+1/, "").replace(/1[\r\n\t ]+-->/, "");

                console.log("Но мы это исправили");
            }
        }

        if (_("UL>LI>A[HREF]") !== null) {
            var list = null;
            var addComments = true;

            for(var i = 0; i < A$.length; i++) {
                if (list === null) {
                    list = A$[i].parentNode.parentNode;
                }

                var href = A$[i].getAttribute("HREF");

                if (/^\/cgi-bin\/comment\?/.test(href)) {
                    addComments = false;
                    break;
                }
                else if (/^\/comment\//.test(href)) {
                    addComments = false;
                    break;
                }
            }

            console.log("Проверка комментов:", addComments, list);

            if (addComments) {
                console.log("Добавляем линки на комменты");
                C$("A", {"HREF": "/comment" + bookUri}, C$("LI", undefined, list), "Комментарии (отключены)");
                C$("A", {"HREF": "/cgi-bin/comment?COMMENT=" + bookUri}, C$("LI", undefined, list), "Оставить комментарий (хоть и отключены они)");
            }

            console.log("Перенос текста");

            var b = document.body;
            var s = null;
            var container = null;
            var lastComment = null;

            for(var i = 0; i < b.childNodes.length; i++) {
                var n = b.childNodes[i];

                //console.log(n);

                if (s === null) {
                    var startingComment = (n.nodeType === Node.COMMENT_NODE && n.textContent === "--------- Собственно произведение -------------");

                    if (startingComment) {
                        console.log("Стартовый коммент найден:", n);

                        container = document.createElement("DIV");
                        n.parentNode.insertBefore(container, b.childNodes[i + 1]);
                        i++;
                        s = "text";
                    }

                    continue;
                }

                if (s === "text") {
                    console.log(n);

                    if (n.nodeType === Node.COMMENT_NODE) {
                        lastComment = n;
                    }

                    var endingComment = (lastComment !== null && lastComment.nodeType === Node.COMMENT_NODE && lastComment.textContent === "-----------------------------------------------");
                    if (endingComment && n.tagName === "HR") {
                        console.log("Конец произведения найден:", n);

                        s = "end";
                        break;
                    }

                    n.parentNode.removeChild(n);
                    container.appendChild(n);
                    i--;

                    continue;
                }
            }

            if (container) {
                var style = "font-size: 2em; line-height: 1em";

                function applyStyles() {
                    var sw = window.innerWidth - 800;
                    if (sw <= 0) {
                        sw = 0;
                    }
                    var hsw = sw / 2;
                    container.setAttribute("style", style + '; padding: 0 ' + hsw + 'px 0 ' + hsw + 'px');
                }

                window.addEventListener("resize", function () {
                    applyStyles();
                });
                applyStyles();
            }

        }

        // Add download attribute for FB2 anchor
        let authorElement = _('div h3');
        let titleElement = _('center h2');
        let fb2AnchorElement = _('small ul li a[href$=".fb2.zip"]');

        if (authorElement && titleElement && fb2AnchorElement) {
            let author = authorElement.innerText.split(':')[0].trim();
            let title = titleElement.innerText.trim();
            let originalFileExtension = 'fb2.zip';

            fb2AnchorElement.setAttribute("download", `${title}. ${author}.${originalFileExtension}`);
        }

    }

    if ("comment" === section) {
        var addCommentElement = findElementByText("A", "Добавить комментарий");

        if (addCommentElement === null) {
            var addLinkBefore = findElementByText("BODY>CENTER>SMALL", "Отсортировано по:", true);

            console.log("Комменты отключены, но линк мы добавим перед этим:", addLinkBefore);

            if (addLinkBefore) {
                addLinkBefore.parentNode.insertBefore(C$("A", {"HREF": "/cgi-bin/comment?COMMENT=" + bookUri}, null, C$("B", null, null, "Добавить комментарий(они отключены как-бы)")), addLinkBefore);
            }
        }
    }

    console.log("Userscript для Самиздата отработал");
})();