Greasy Fork is available in English.

小説家になろう デザイン調整スクリプト

小説家になろうの表示の改善を目的としたTampermonkey用スクリプト

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください。
// ==UserScript==
// @name         小説家になろう デザイン調整スクリプト
// @namespace    https://github.com/todkuro/
// @author       todokuro
// @version      0.6
// @description  小説家になろうの表示の改善を目的としたTampermonkey用スクリプト
// @match        https://syosetu.com/*
// @run-at       document-start
// @require      https://code.jquery.com/jquery-3.7.1.min.js
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';
    const $ = jQuery;

    // ブクマのしおり・最新話ボタンの調整
    const adjustBookmarkEpButtons = (node) => {
        const buttonCombo = node.closest(".c-button-combo");
        // 最初から読む or bookmark
        if(node.is(".c-button-combo a.c-button:nth-child(odd)")) {
            node.removeClass("c-button--primary");
            node.addClass("c-button--outline");
            if(node.find("[class*='--siori']").length >= 1) {
                buttonCombo.addClass("__has_shiori");
            } else {
                buttonCombo.addClass("__none_shiori");
            }
        }
        // 最新ep
        if(node.is(".c-button-combo a.c-button:nth-child(even)")) {
            const unread = buttonCombo.find("a.c-button:nth-child(odd) .p-up-bookmark-item__unread,a.c-button:nth-child(odd) .p-up-activity-item__unread");
            if(unread.length) {
                node.append(unread.remove());
                buttonCombo.addClass("___has_unread");
                const cnt = parseInt(unread.find(".p-up-bookmark-item__unread-num,.p-up-activity-item__unread-num").text() || "0");
                if (cnt == 1) {
                    buttonCombo.addClass("__unread_one");
                } else if (cnt >= 2) {
                    buttonCombo.addClass("__unread_many");
                }
            }
        }
    };

    // ブクマの設定ボタンのメニューを単純なリンクに
    const adjustBookmarkSettingButton = (node) => {
        node.contents().each((idx,elm) => {
            if(elm.nodeType !== Element.TEXT_NODE) return;
            elm.remove();
        });
        node.removeClass("c-up-dropdown");
        node.removeClass("c-up-dropdown--hover");
        const settingLink = node.find("li.c-up-dropdown__item:nth-child(odd) a").remove();
        node.find("ul").remove();
        node.append(settingLink);
    };

    // カテゴリ内をプルダウンじゃなくリンクボタンにする
    const replaceBookmarkCategory = (node) => {
        const newDiv = $("<div>").attr("class", "___narou_bookmark");
        const current = node.wrapInner(newDiv).children(0).unwrap();
        const hasSelected = current.children("option[value][selected]").length >= 1;
        current.children("option[value]").each((idx, elm) => {
            const selected = hasSelected ? $(elm).is("[selected]") : idx === 0;
            const link = $(elm).wrapInner($("<a>").attr("href", $(elm).val())).children(0).unwrap();
            if(selected) link.addClass("___selected");
        });
    };

    const forEachNodes = (mutation, target, mutationHandler) => {
        mutation.addedNodes.forEach((node) => {
            if (!$(node).is(target)) return;
            mutationHandler($(node));
        });
    };

    let status = false
    let bookmarkCategory = undefined;
    // MutationObserver
    const observer = new MutationObserver((mutationsList, observer) => {
        for (let mutation of mutationsList) {
            if (mutation.type !== "childList") continue;
            if (mutation.target.className === "l-footer") {
                observer.disconnect();
            }
            if ($(mutation.target).is(".l-main .c-up-list-tools") && !isSmartPhone) {
                forEachNodes(mutation, ".p-up-bookmark-category", (elm) => {
                    bookmarkCategory = elm.remove();
                });
            }
            if (bookmarkCategory) {
                if ($(mutation.target).is(".l-container")) {
                    status = true;
                    forEachNodes(mutation, ".l-sidebar", (elm) => {
                        elm.append(bookmarkCategory);
                    });
                }
            }
            if ($(mutation.target).is(".c-form__group")) {
                forEachNodes(mutation, "select.js-bookmark_list_form_select", replaceBookmarkCategory);
            }
            if ($(mutation.target).is(".p-up-bookmark-item__button .c-button-combo,.p-up-activity-item__button .c-button-combo,.p-up-bookmark-item__header")) {
                forEachNodes(mutation, ".c-button", adjustBookmarkEpButtons);
                forEachNodes(mutation, ".p-up-bookmark-item__menu", adjustBookmarkSettingButton);
            }

            // 上とほぼ同じ処理。個別でなくbodyにまとめて入ってくることがある
            if ( !status && $(mutation.target).find(".l-main .c-up-list-tools").length >= 1 ) {
                const elm = $(mutation.target).find(".l-main .p-up-bookmark-category");
                bookmarkCategory = elm.remove();
                $(mutation.target).find(".l-container .l-sidebar").each((idx, elm) => {
                    $(elm).append(bookmarkCategory);
                });
                if ( !status.container && $(mutation.target).find(".l-container").length >= 1 ) {
                    forEachNodes(mutation, ".l-sidebar", (elm) => {
                        elm.append(bookmarkCategory);
                    });
                }
                if ($(mutation.target).find(".c-form__group").length >= 1) {
                    $(mutation.target).find(".c-form__group select.js-bookmark_list_form_select").each((idx,elm) => {
                        replaceBookmarkCategory($(elm));
                    });
                }

                const bookmarkItems = $(mutation.target).find(".p-up-bookmark-item__button .c-button-combo,.p-up-activity-item__button .c-button-combo,.p-up-bookmark-item__header");
                if (bookmarkItems.length >= 1) {
                    bookmarkItems.find(".c-button").each((idx,elm) => adjustBookmarkEpButtons($(elm)));
                    bookmarkItems.find(".p-up-bookmark-item__menu").each((idx,elm) => adjustBookmarkSettingButton($(elm)));
                }
            }
        }
    });
    observer.observe(document.documentElement, { childList: true, subtree: true });

    /*css*/
    const newCss = `
body {
    font-family: 'UD デジタル 教科書体 NP-B', 'Meiryo', 'MS PGothic', 'Hiragino Kaku Gothic ProN', 'ヒラギノ角ゴ ProN W3', sans-serif;
}
.c-up-tab__label {
    padding: 3px 0 0;
}
a,
a.c-button--outline,
.p-up-bookmark-item__title>a,
.p-up-activity-item__title>a,
.p-up-bookmark-item__name>a,
.p-up-activity-item__name>a,
.___narou_bookmark a {
    color: #0033cc;
}
.___narou_bookmark a:hover {
    background: #ddd !important;
}
.p-up-activity-item__button a:nth-child(even),
.p-up-bookmark-item__button a:nth-child(even) {
    background-color: #f3f3f3;
}
.p-up-activity-item__button a:nth-child(odd),
.p-up-bookmark-item__button a:nth-child(odd) {
    background-color: #f3f3f3;
}
.p-up-activity-item__button .__unread_one a:nth-child(even),
.p-up-bookmark-item__button .__unread_one a:nth-child(even) {
    background-color: #bfe6aa;
}
.p-up-activity-item__button .__unread_many a:nth-child(even),
.p-up-bookmark-item__button .__unread_many a:nth-child(even) {
    background-color: bisque;
}
.p-up-activity-item__button .__none_shiori a:nth-child(even),
.p-up-bookmark-item__button .__none_shiori a:nth-child(even) {
    background-color: #fdd;
}
.__unread_many .p-up-bookmark-item__unread {
    color: red !important;
}

.l-container {
    flex-direction: row-reverse;
}

.c-form .c-form__label {
    position: relative;
}
.c-form .c-form__label span.p-up-bookmark-category__setting {
    position: absolute;
    right: 0;
}
.l-content .c-form .c-form__label span.p-up-bookmark-category__setting {
    top: -15px;
}

.l-content .c-form .___narou_bookmark {
    text-align: center;
    background: #fff;
    line-height: 0;
}
.l-content .c-form .___narou_bookmark a {
    display: inline-block;
    width: calc(100% / 3.2);
    line-height: 2.5;
    border-bottom: 1px solid rgba(0, 0, 0, 0.1);
    text-align: center;
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
    font-size: 0.9em;
}
.l-sidebar .___narou_bookmark a {
    white-space: nowrap;
    line-height: 2em;
    display: block;
    border: 1px solid rgba(0, 0, 0, 0.1);
    padding: 5px 12px;
    margin-bottom: -1px;
    background: #fff;
}
.___narou_bookmark a.___selected {
    background: beige;
}

div.l-page-title,
div.c-up-page-description {
    display: none;
}
h3.c-up-headline {
    line-height: 0.5;
}
.c-up-chk-item__content {
    width: 90%;
}
.c-up-pager {
    background-color: #fff;
    border: 1px solid rgba(0, 0, 0, 0.1);
}
.c-up-filter {
    display: flex;
    flex-flow: row-reverse nowrap;
    margin-bottom: 5px !important;
}
.c-up-filter__hit-number {
    flex: 2 1 auto;
}
.c-up-filter__hit-number .c-up-hit-number {
    display: flex;
    flex-flow: row wrap;
}
.c-up-filter__tools {
    flex: 1 2 auto;
    display: flex;
    flex-flow: row wrap;
    align-items: flex-end;
    justify-content: right;
}
.c-up-filter__tools > * {
    width: 11em;
}
.c-up-filter__tools div.c-up-filter__item {
    margin: 0;
}

.c-up-panel__list-item.p-up-bookmark-item {
    position: relative;
}
div.p-up-bookmark-item__menu {
    font-size: 0.8em;
    color: #1b8ef3;
}
span.p-up-bookmark-item__setting {
    position: absolute;
    top: -1px;
    right: 56px;
    text-align: right;
}
.c-up-panel__header.c-up-panel__header--toolbar {
    background: #f1f3f5;
    padding-top: 0;
    z-index: 4;
}
.c-up-panel__header.c-up-panel__header--toolbar button.c-up-panel__button {
    background: #fff;
}

.p-up-bookmark-item__title {
    text-overflow: ellipsis;
    overflow: hidden;
    max-width: 100%;
    white-space: nowrap;
    display: inline-block;
    vertical-align: middle;
}

.p-up-bookmark-item__info {
    display: flex;
}
.p-up-bookmark-item__author {
    text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
    display: block;
    vertical-align: middle;
    flex-grow: 1;
    width: 7.5em;
}
.p-up-bookmark-item__status {
    text-align: right;
    display: block;
}
`;
    /*!css*/

    const styleLink = $('<style>');
    styleLink.text(newCss);
    $("head").append(styleLink);

})();