Danbooru tags buttons

Return +/- buttons to Danbooru

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey, Greasemonkey или Violentmonkey.

Для установки этого скрипта вам необходимо установить расширение, такое как Tampermonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Userscripts.

Чтобы установить этот скрипт, сначала вы должны установить расширение браузера, например Tampermonkey.

Чтобы установить этот скрипт, вы должны установить расширение — менеджер скриптов.

(у меня уже есть менеджер скриптов, дайте мне установить скрипт!)

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

(у меня уже есть менеджер стилей, дайте мне установить скрипт!)

// ==UserScript==
// @name         Danbooru tags buttons
// @namespace    danbooru
// @version      0.5
// @description  Return +/- buttons to Danbooru
// @author       Jallot
// @include      http*://*danbooru.donmai.us/posts*
// @grant        none
// @license MIT
// ==/UserScript==

(function() {
    'use strict';
    let currentTags = document.getElementById("tags").value.split(" ").filter(String);

    function addTagToSearch(tag, negative=false){
        var newTags = [...currentTags]
        if (negative){
            tag = "-" + tag;
        }
        newTags.push(tag);
        return newTags.join("+");
    };


    const tagList = document.querySelectorAll('ul li[class*="tag-type-"]');
    for (const tag of tagList) {
        const tagLinks = tag.querySelectorAll("a");
        const tagNameNode = tagLinks[1];
        const tagUrl = new URLSearchParams(tagNameNode.href.split('?')[1]);
        const tagName = tagUrl.get("tags");
        var plusLink = document.createElement('a');
        plusLink.href = '/posts?tags=' + addTagToSearch(tagName);
        plusLink.textContent = '+';
        var minusLink = document.createElement('a');
        minusLink.href = '/posts?tags=' + addTagToSearch(tagName, true);
        minusLink.textContent = '-';
        tagNameNode.parentNode.insertBefore(plusLink, tagNameNode);
        tagNameNode.parentNode.insertBefore(document.createTextNode(" "), tagNameNode);
        tagNameNode.parentNode.insertBefore(minusLink, tagNameNode);
        tagNameNode.parentNode.insertBefore(document.createTextNode(" "), tagNameNode);
    };

    const tagBox = document.getElementById("tag-box");
    if (tagBox) {
        const ageSection = document.createElement("section");
        ageSection.id = "age-filter-box";

        const heading = document.createElement("h2");
        heading.textContent = "Age Filter";
        ageSection.appendChild(heading);

        const customDiv = document.createElement("div");
        customDiv.style.cssText = "display:flex;flex-direction:column;gap:4px;";

        const rangeRow = document.createElement("div");
        rangeRow.style.cssText = "display:flex;align-items:center;gap:4px;";

        const fromLabel = document.createElement("span");
        fromLabel.textContent = "from";

        const fromInput = document.createElement("input");
        fromInput.type = "number";
        fromInput.min = "0";
        fromInput.placeholder = "0";
        fromInput.style.cssText = "width:50px;";

        const toLabel = document.createElement("span");
        toLabel.textContent = "to";

        const toInput = document.createElement("input");
        toInput.type = "number";
        toInput.min = "0";
        toInput.placeholder = "0";
        toInput.style.cssText = "width:50px;";

        rangeRow.appendChild(fromLabel);
        rangeRow.appendChild(fromInput);
        rangeRow.appendChild(toLabel);
        rangeRow.appendChild(toInput);

        const unitSelect = document.createElement("select");
        for (const [val, label] of [["d","days"],["w","weeks"],["mo","months"],["y","years"]]) {
            const opt = document.createElement("option");
            opt.value = val;
            opt.textContent = label;
            unitSelect.appendChild(opt);
        }

        // Restore saved age filter state
        const savedAge = sessionStorage.getItem("age-filter");
        if (savedAge) {
            const m = savedAge.match(/^age:(\d+)(\w+)\.\.(\d+)(\w+)$/);
            if (m) {
                fromInput.value = m[1];
                toInput.value = m[3];
                unitSelect.value = m[2];
            }
        }

        const addBtn = document.createElement("button");
        addBtn.textContent = "Search";
        addBtn.addEventListener("click", function() {
            const from = fromInput.value;
            const to = toInput.value;
            const unit = unitSelect.value;
            if (from === "" || to === "") return;
            const ageTag = "age:" + from + unit + ".." + to + unit;
            sessionStorage.setItem("age-filter", ageTag);
            const tagsWithoutAge = currentTags.filter(t => !t.startsWith("age:"));
            tagsWithoutAge.push(ageTag);
            window.location.href = "/posts?tags=" + tagsWithoutAge.join("+");
        });

        customDiv.appendChild(rangeRow);
        customDiv.appendChild(unitSelect);
        customDiv.appendChild(addBtn);
        ageSection.appendChild(customDiv);

        // Shift buttons — only shown when age filter is active
        if (savedAge) {
            const shiftDiv = document.createElement("div");
            shiftDiv.style.cssText = "display:flex;flex-wrap:wrap;gap:4px;margin-top:4px;";

            function shiftAge(direction) {
                const from = parseInt(fromInput.value);
                const to = parseInt(toInput.value);
                const unit = unitSelect.value;
                if (isNaN(from) || isNaN(to)) return;
                const span = to - from;
                const newFrom = Math.max(0, from + direction * span);
                const newTo = newFrom + span;
                const ageTag = "age:" + newFrom + unit + ".." + newTo + unit;
                sessionStorage.setItem("age-filter", ageTag);
                const tagsWithoutAge = currentTags.filter(t => !t.startsWith("age:"));
                tagsWithoutAge.push(ageTag);
                window.location.href = "/posts?tags=" + tagsWithoutAge.join("+");
            }

            const shiftLabel = document.createElement("span");
            shiftLabel.textContent = "Date shifting";
            shiftLabel.style.cssText = "width:100%;";
            shiftDiv.appendChild(shiftLabel);

            const prevBtn = document.createElement("button");
            prevBtn.textContent = "-1";
            prevBtn.addEventListener("click", () => shiftAge(-1));

            const nextBtn = document.createElement("button");
            nextBtn.textContent = "+1";
            nextBtn.addEventListener("click", () => shiftAge(+1));

            shiftDiv.appendChild(prevBtn);
            shiftDiv.appendChild(nextBtn);
            ageSection.appendChild(shiftDiv);
        }

        tagBox.after(ageSection);
    }
})();