Danbooru tags buttons

Return +/- buttons to Danbooru

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey, Greasemonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

You will need to install an extension such as Tampermonkey to install this script.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला 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);
    }
})();