Danbooru Ajax Interface

By VIPPER Last update Nov 7, 2011 — Installed 2,335 times.

There are 12 previous versions of this script.

Add Syntax Highlighting (this will take a few seconds, probably freezing your browser while it works)

// ==UserScript==
// @name           Danbooru Ajax Interface
// @namespace      http://danbooru.donmai.us
// @description    New interface to search images on Danbooru/Gelbooru.
// @include        http://danbooru.donmai.us/
// @include        http://danbooru.donmai.us/#*
// @include        http://gelbooru.com/
// @include        http://gelbooru.com/#*
// @version        0.2.2
// ==/UserScript==

const ratio = (1 + Math.sqrt(5)) / 2;
const btnclose = "data:image/gif;base64,R0lGODlhQgAWANUAAP////39/fr6+vj4+PX19fDw8Ovr6+np6ebm5uTk5N/f39zc3Nra2tfX19XV1dLS0svLy8jIyL6+vre3t7S0tLKysq+vr6ioqKOjo56enpubm5aWlpGRkY+Pj4yMjIeHh4KCgoCAgH19fXZ2dnNzc3FxcW5ubmlpaWdnZ2RkZGJiYl9fX11dXVpaWlVVVVNTU1BQUE5OTktLS0lJSUZGRgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAHAP8ALAAAAABCABYAAAb/QIBwSCwaj8ikcslsOp/QqLQZmFqvRAHngYxsBEaCw3EYHhwE5IFykZSLZ7RQPK4PBxzaimGEtGgcaXMZL4UvH0IXLw5HEoaFF0MEIo8RAA6PhUMWNC8xKw1EES0xLzQYQ5QfY2yJi0YRh2UKlBRCHC8XDhEZZZgcdYxCBiQzLzIqC0KjpTMhBUIULxlHisJEKCiCAAQoLEIvJEaYkUcGIzKeKAt+pTQgA0Pe20TWRQrTRYSMLyjjuUnOGYOBgtQxENsOHEJij4g0S6IA4gpEBJOICxjfEDmXDgaMYx/iDSHH8FU9kyMBTnrBguKlTNeIFCjx0ZMGMBUBVkPpKubL2XKXKLFQ8HNJgRM1Y3Qwgo9DSZ+ObBFxJKGIIxFFkywwUcrjMQ1ViLDwt9OnQkREcGkcQuJF1iMLUKSLkWLFRxlgTwK91NMIJaJC8GE14u1tkQUr0skgkSCCV7xhubUF5gCXJUUcMGJkpIAFCwkOKHgGnCHDmA/5LGoGyiCxCxkjDAiZ8DjvHEqFWFADoChTOQcoDKEADAC1od2YMglhwEIxCdlDKsjwSKMCnDFQFJAxEqdJgQ4yZjw3UiGGjBN8sKjP4mH8EQsnEKyfP0QAvSIB5NPfz7+/+iAAOw==";
const ajaxloading = "data:image/gif;base64,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";

const d = document;
const dan = /danbooru/.test(window.location.hostname);

d.documentElement.removeChild(d.documentElement.firstChild);
d.documentElement.removeChild(d.documentElement.firstChild);
d.documentElement.removeChild(d.documentElement.firstChild);
d.documentElement.appendChild(d.createElement("HEAD"));
d.documentElement.appendChild(d.createElement("BODY"));

d.documentElement.firstChild.appendChild(title = d.createElement("TITLE"));
title.textContent = dan ? "Danbooru" : "Gelbooru";

var tags, page, images, columns, postrating, deleted, login = "", passhash = "";

if(dan) {
    tags = GM_getValue("dtags", "");
    page = GM_getValue("dpage", 1);
    images = GM_getValue("dimages", 20);
    columns = GM_getValue("dcolumns", 5);
    postrating = GM_getValue("drating", "s");
    deleted = GM_getValue("deleted", false);
    login = (/login=(.*?)(;|$)/.test(d.cookie) ? btoa(d.cookie.match("login=(.*?)(;|$)")[1]) : GM_getValue("login", ""));
    passhash = (/pass_hash=(.*?)(;|$)/.test(d.cookie) ? btoa(d.cookie.match("pass_hash=(.*?)(;|$)")[1]) : GM_getValue("passhash", ""));

    GM_setValue("login", login);
    GM_setValue("passhash", passhash);
} else {
    tags = GM_getValue("gtags", "");
    page = GM_getValue("gpage", 1);
    images = GM_getValue("gimages", 20);
    columns = GM_getValue("gcolumns", 5);
    postrating = GM_getValue("grating", "s");
}

var queryUrl = (dan ? "http://danbooru.donmai.us/post/index.xml?login=" + atob(login) + "&passhash=" + atob(passhash) + "&tags=" : "http://gelbooru.com/index.php?page=dapi&s=post&q=index&tags=");
var noteUrl = (dan ? "http://danbooru.donmai.us/note/index.xml?post_id=" : "http://gelbooru.com/index.php?page=dapi&s=note&q=index&post_id=");

GM_addStyle("a { text-decoration: none; } img { border: 0px; } .thumb { border: 1px solid #EEE; text-align: center; vertical-align: middle; width: 150px; height: 150px; }");

d.body.appendChild(searchTable = d.createElement("TABLE"));
searchTable.appendChild(searchTr = d.createElement("TR"));
searchTr.setAttribute("style", "vertical-align: top;");
searchTr.appendChild(searchTd = d.createElement("TD"));
searchTd.setAttribute("style", "text-align: center; overflow-x: hidden;");

var searchForm = d.createElement("FORM");
searchForm.addEventListener("submit", function(event) {
    tags = aTags.value;
    page = Math.max(1, parseInt(aPage.value));
    images = Math.max(1, Math.min(parseInt(aImages.value), 100));
    columns = Math.max(1, parseInt(aColumns.value));
    postrating = (aRS.checked ? "s" : "") + (aRQ.checked ? "q" : "") + (aRE.checked ? "e" : "");
    deleted = aSD.checked;

    if(dan) {
        GM_setValue("dimages", images);
        GM_setValue("dcolumns", columns);
        GM_setValue("drating", postrating);
        GM_setValue("deleted", deleted);
    } else {
        GM_setValue("gimages", images);
        GM_setValue("gcolumns", columns);
        GM_setValue("grating", postrating);
    }

    search(tags, page);
    event.preventDefault();
}, false);

searchForm.appendChild(aTags = d.createElement("INPUT"));
aTags.setAttribute("type", "text");
aTags.setAttribute("cols", 25);
aTags.setAttribute("value", tags);
aTags.setAttribute("tabindex", "1");
aTags.addEventListener("change", function(event) {
    aPage.value = 1;
}, false);

searchForm.appendChild(d.createElement("P"));

searchForm.appendChild(aReply = d.createElement("SPAN"));
aReply.textContent = "Nobody here but us chickens!";

searchForm.appendChild(d.createElement("P"));

// Slider
var aTableBar = d.createElement("TABLE");
aTableBar.appendChild(d.createElement("TR"));
aTableBar.setAttribute("style", "border-collapse: collapse; border-spacing: 0px; width: 100%;");
var aLeftBar = d.createElement("TD");
aLeftBar.setAttribute("style", "border: 1px solid #000; padding: 1px 0px;");
aTableBar.firstChild.appendChild(aLeftBar);
var aCenterBar = d.createElement("TD");
aCenterBar.setAttribute("style", "border: 1px solid #000; padding: 1px 0px; background-color: #EEE;");
aTableBar.firstChild.appendChild(aCenterBar);
var aRightBar = d.createElement("TD");
aRightBar.setAttribute("style", "border: 1px solid #000; padding: 1px 0px; width: 100%;");
aTableBar.firstChild.appendChild(aRightBar);
searchForm.appendChild(aTableBar);

var aTable = d.createElement("TABLE");
var aTr1 = d.createElement("TR");
var aTd1 = d.createElement("TD");
aTd1.appendChild(d.createTextNode("Page:"));
aTr1.appendChild(aTd1);

var aTd2 = d.createElement("TD");
var aPage = d.createElement("INPUT");
aPage.setAttribute("type", "text");
aPage.setAttribute("size", "1");
aPage.setAttribute("value", page);
aPage.setAttribute("tabindex", "2");
aTd2.appendChild(aPage);
aTr1.appendChild(aTd2);

var aTd3 = d.createElement("TD");
aTd3.setAttribute("rowspan", "3");
aTd3.setAttribute("align", "left");

var aRS = d.createElement("INPUT");
aRS.setAttribute("type", "checkbox");
if(/s/.test(postrating)) aRS.setAttribute("checked", "checked");
aTd3.appendChild(aRS);
aTd3.appendChild(d.createTextNode("Safe"));
aTd3.appendChild(d.createElement("BR"));

var aRQ = d.createElement("INPUT");
aRQ.setAttribute("type", "checkbox");
if(/q/.test(postrating)) aRQ.setAttribute("checked", "checked");
aTd3.appendChild(aRQ);
aTd3.appendChild(d.createTextNode("Questionable"));
aTd3.appendChild(d.createElement("BR"));

var aRE = d.createElement("INPUT");
aRE.setAttribute("type", "checkbox");
if(/e/.test(postrating)) aRE.setAttribute("checked", "checked");
aTd3.appendChild(aRE);
aTd3.appendChild(d.createTextNode("Explicit"));
aTd3.appendChild(d.createElement("BR"));

var aSD = d.createElement("INPUT");
if(dan) {
    aSD.setAttribute("type", "checkbox");
    if(deleted) aSD.setAttribute("checked", "checked");
    aTd3.appendChild(aSD);
    aTd3.appendChild(d.createTextNode("Show Deleted"));
}

aTr1.appendChild(aTd3);
aTable.appendChild(aTr1);

var aTr2 = d.createElement("TR");
var aTd4 = d.createElement("TD");
aTd4.appendChild(d.createTextNode("Images:"));
aTr2.appendChild(aTd4);

var aTd5 = d.createElement("TD");
var aImages = d.createElement("INPUT");
aImages.setAttribute("type", "text");
aImages.setAttribute("size", "1");
aImages.setAttribute("value", images);
aImages.setAttribute("tabindex", "3");
aTd5.appendChild(aImages);
aTr2.appendChild(aTd5);
aTable.appendChild(aTr2);

var aTr3 = d.createElement("TR");
var aTd6 = d.createElement("TD");
aTd6.appendChild(d.createTextNode("Columns:"));
aTr3.appendChild(aTd6);

var aTd7 = d.createElement("TD");
var aColumns = d.createElement("INPUT");
aColumns.setAttribute("type", "text");
aColumns.setAttribute("size", "1");
aColumns.setAttribute("value", columns);
aColumns.setAttribute("tabindex", "4");
aTd7.appendChild(aColumns);
aTr3.appendChild(aTd7);
aTable.appendChild(aTr3);
searchForm.appendChild(aTable);

searchForm.appendChild(d.createElement("HR"));

searchForm.appendChild(aPrev = d.createElement("INPUT"));
aPrev.setAttribute("type", "button");
aPrev.setAttribute("value", "<");
aPrev.setAttribute("disabled", "disabled");
aPrev.addEventListener("click", function(event) {
    search(tags, --page);
}, false);

searchForm.appendChild(aSearch = d.createElement("INPUT"));
aSearch.setAttribute("type", "submit");
aSearch.setAttribute("value", "Search");

searchForm.appendChild(aNext = d.createElement("INPUT"));
aNext.setAttribute("type", "button");
aNext.setAttribute("value", ">");
aNext.setAttribute("disabled", "disabled");
aNext.addEventListener("click", function(event) {
    search(tags, ++page);
}, false);

searchForm.appendChild(d.createElement("HR"));

searchForm.appendChild(aTagsDisplay = d.createElement("DIV"));

searchTd.appendChild(searchForm);
searchTr.appendChild(imagesLayer = d.createElement("TD"));

searchTd.style.setProperty("min-width", window.getComputedStyle(searchTd, null).getPropertyValue("width"), "important");
searchTd.style.setProperty("max-width", window.getComputedStyle(searchTd, null).getPropertyValue("width"), "important");

// "Lightbox"
var overlay = d.createElement("DIV");
overlay.setAttribute("style", "opacity: 0.75; display: none; background-color: #000; width: 100%; height: 100%; position: fixed; top: 0px; left: 0px");
var display = d.createElement("TABLE");
display.setAttribute("style", "display: none; position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; text-align: center; vertical-align: middle");
var displayDiv = d.createElement("DIV");
displayDiv.setAttribute("style", "background: url('" + ajaxloading + "') #FFF no-repeat scroll center center; display: inline-block; padding: 10px; min-width: 200px; min-height: 200px; -moz-border-radius: 10px");

display.appendChild(d.createElement("TR"));
display.firstChild.appendChild(d.createElement("TD"));
display.firstChild.firstChild.appendChild(displayDiv);

d.body.insertBefore(display, d.body.firstChild);
d.body.insertBefore(overlay, d.body.firstChild);

if(window.location.hash) search(window.location.hash.split("#")[1], 1);

function search(newtags, newpage) {
    tags = newtags;
    aTags.value = newtags;
    page = newpage;
    aPage.value = newpage;

    if(dan) {
        GM_setValue("dtags", newtags);
        GM_setValue("dpage", newpage);
    } else {
        GM_setValue("gtags", newtags);
        GM_setValue("gpage", newpage);
    }

    aPrev.disabled = (newpage < 2);
    aRS.checked = /s/.test(postrating);
    aRQ.checked = /q/.test(postrating);
    aRE.checked = /e/.test(postrating);

    if(deleted) newtags += " status:any";
    if(/^s$/.test(postrating)) newtags += " rating:safe";
    if(/^q$/.test(postrating)) newtags += " rating:questionable";
    if(/^e$/.test(postrating)) newtags += " rating:explicit";
    if(/^qe$/.test(postrating)) newtags += " -rating:safe";
    if(/^se$/.test(postrating)) newtags += " -rating:questionable";
    if(/^sq$/.test(postrating)) newtags += " -rating:explicit";

    if(imagesLayer.hasChildNodes())
        imagesLayer.removeChild(imagesLayer.firstChild);
    imagesLayer.appendChild(d.createTextNode("Loading..."));

    GM_xmlhttpRequest({
        method : "GET",
        url : queryUrl + escape(newtags) + "&limit=" + images + (dan ? ("&page=" + newpage) : ("&pid=" + (newpage-1))),
        headers: {
            "User-agent" : navigator.userAgent,
            "Accept" : "application/xml",
        },
        overrideMimeType : "application/xml; charset=utf-8",
        onload : function(response) {
            showContent(new DOMParser().parseFromString(response.responseText, "application/xml"));
        }
    });
}

function showContent(xmldoc) {
    if(imagesLayer.hasChildNodes())
        imagesLayer.removeChild(imagesLayer.firstChild);

    aReply.textContent = "Nobody here but us chickens!";
    var posts = xmldoc.evaluate("posts", xmldoc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
    if(!posts) {
        reason = xmldoc.evaluate("response/@reason", xmldoc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
        if(reason)
            alert(reason.nodeValue);
        else
            alert("503 - Service Unavailable\nServer cannot currently handle the request, try again later.");
        return;
    }
    aReply.textContent = "Found " + posts.getAttribute("count") + ", showing " + (parseInt(posts.getAttribute("offset")) + 1) + "-" + Math.min(posts.getAttribute("count"), parseInt(posts.getAttribute("offset")) + images);

    var post = xmldoc.evaluate("posts/post", xmldoc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
    var totalpages = Math.ceil(posts.getAttribute("count") / images);

    aLeftBar.style.width = (posts.getAttribute("offset") / posts.getAttribute("count") * 100) + "%";
    aCenterBar.style.width = (images / posts.getAttribute("count") * 100) + "%";
    aNext.disabled = (page >= totalpages);

    imagesLayer.appendChild(table = d.createElement("TABLE"));
    table.setAttribute("style", "border-collapse: collapse; border-spacing: 0px;");

    var counter = 0;
    for(i = 0; i < Math.ceil(images / columns); i++) {
        table.appendChild(tr = d.createElement("TR"));
        for(j = 0; j < Math.min(columns, images); j++) {
            tr.appendChild(td = d.createElement("TD"));
            data = post.snapshotItem(counter++);
            if(data) {
                var image = d.createElement("IMG");
                image.setAttribute("src", data.getAttribute("preview_url"));
                image.setAttribute("alt", data.getAttribute("tags"));
                image.setAttribute("title", data.getAttribute("tags") + " rating:" + data.getAttribute("rating").replace(/e$/, "Explicit").replace(/s$/, "Safe").replace(/q$/, "Questionable") + " score:" + data.getAttribute("score"));
                image.setAttribute("width", data.getAttribute("preview_width"));
                image.setAttribute("height", data.getAttribute("preview_height"));
                image.setAttribute("id", data.getAttribute("id"));
                image.setAttribute("fullsize", data.getAttribute("file_url"));
                image.setAttribute("fullwidth", data.getAttribute("width"));
                image.setAttribute("fullheight", data.getAttribute("height"));
                image.setAttribute("notes", data.getAttribute("has_notes"));

                image.addEventListener("click", function(event) {
                    // Show tags on sidebar
                    if(aTagsDisplay.hasChildNodes())
                        aTagsDisplay.removeChild(aTagsDisplay.firstChild);
                    aTagsDisplay.appendChild(d.createElement("DIV"));
                    var tagnames = this.getAttribute("alt").split(" ");
                    for(t = 0; t < tagnames.length; t++) {
                        var taglink = d.createElement("A");
                        taglink.appendChild(d.createTextNode(tagnames[t]));
                        taglink.setAttribute("href", "#" + tagnames[t]);
                        taglink.addEventListener("click", function(event) {
                            aTags.value = this.textContent;
                            aPage.value = 1;
                            aSearch.click();
                            event.preventDefault();
                        }, false);
                        aTagsDisplay.firstChild.appendChild(taglink);
                        aTagsDisplay.firstChild.appendChild(document.createElement("BR"));
                    }

                    if(event.ctrlKey) return; // CTRL + click to show only the tags

                    // "Lightbox" by VIPPER (aka "How do I jQuery?")
                    while(displayDiv.hasChildNodes())
                        displayDiv.removeChild(displayDiv.firstChild);
                    close = d.createElement("IMG");
                    close.setAttribute("src", btnclose);
                    close.setAttribute("style", "float: right; cursor: pointer");
                    close.addEventListener("click", function(event) {
                        overlay.style.setProperty("display", "none", "");
                        display.style.setProperty("display", "none", "");
                    }, false);
                    displayDiv.addEventListener("dblclick", function(event) {
                        overlay.style.setProperty("display", "none", "");
                        display.style.setProperty("display", "none", "");
                    }, false);
                    displayDiv.appendChild(close);
                    displayDiv.appendChild(d.createElement("BR"));

                    if(/\.swf$/.test(this.getAttribute("fullsize"))) {
                        fullsize = d.createElement("EMBED");
                        fullsize.setAttribute("width", this.getAttribute("fullwidth"));
                        fullsize.setAttribute("height", this.getAttribute("fullheight"));
                    } else {
                        fullsize = d.createElement("IMG");
                        fullsize.addEventListener("click", function(event) {
                            noteDivs = d.evaluate("//DIV[starts-with(@id, 'note')]", d, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
                            for(i = 0, n = null; n = noteDivs.snapshotItem(i++); ) {
                                if(window.getComputedStyle(n, null).getPropertyValue("visibility") == "visible")
                                    n.style.setProperty("visibility", "hidden", "");
                                else
                                    n.style.setProperty("visibility", "visible", "");
                            }
                        }, false);
                    }
                    displayDiv.appendChild(fullsize);

                    fullsize.setAttribute("src", this.getAttribute("fullsize"));
                    fullsize.setAttribute("width", this.getAttribute("fullwidth"));
                    fullsize.setAttribute("height", this.getAttribute("fullheight"));
                    fullsize.setAttribute("id", this.getAttribute("id"));
                    fullsize.setAttribute("notes", this.getAttribute("notes"));

                    if(fullsize.getAttribute("notes") == "true")
                        GM_xmlhttpRequest({
                            method : "GET",
                            url : noteUrl + fullsize.getAttribute("id"),
                            headers: {
                                "User-agent" : navigator.userAgent,
                                "Accept" : "application/xml",
                            },
                            overrideMimeType : "application/xml; charset=utf-8",
                            onload : function(response) {
                                showNotes(new DOMParser().parseFromString(response.responseText, "application/xml"));
                            }
                        });

                    overlay.style.setProperty("display", "", "");
                    display.style.setProperty("display", "", "");
                }, false);

                var link = d.createElement("A");
                link.setAttribute("href", data.getAttribute("file_url"));
                link.appendChild(image);
                link.addEventListener("click", function(event) {
                    event.preventDefault();
                }, false);
                td.setAttribute("class", "thumb");
                td.appendChild(link);
            }
        }
    }
}

function showNotes(xmldoc) {
    var note = xmldoc.evaluate("notes/note[@is_active = 'true']", xmldoc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

    var width = parseInt(fullsize.getAttribute("width")) + 20; // 20 for padding
    var height = parseInt(fullsize.getAttribute("height")) + 42; // 20 for padding, 22 for close image
    var vp_width = Math.max(d.documentElement.clientWidth, width);
    var vp_height = Math.max(d.documentElement.clientHeight, height);
    var offsetx = 10 + (width < vp_width ? (vp_width - width) / 2 : 0);
    var offsety = 32 + (height < vp_height ? (vp_height - height) / 2 : 0);
    var vp_bottom = Math.max(window.innerHeight, height);

    for(i = 0, ndata = null; ndata = note.snapshotItem(i++); ) {
        nleft = parseInt(parseInt(ndata.getAttribute("x")) + offsetx);
        ntop = parseInt(ndata.getAttribute("y")) + offsety;

        noteDiv = d.createElement("DIV");
        noteDiv.setAttribute("id", "note" + i);
        noteDiv.setAttribute("style", "opacity: 0.5; border: 1px solid #000; background-color: #FFE; position: absolute");
        noteDiv.style.setProperty("left", nleft + "px", "");
        noteDiv.style.setProperty("top", ntop + "px", "");
        noteDiv.style.setProperty("width", ndata.getAttribute("width") + "px", "");
        noteDiv.style.setProperty("height", ndata.getAttribute("height") + "px", "");
        noteDiv.addEventListener("mouseover", function(event) {
            d.getElementById("body" + this.getAttribute("id")).style.setProperty("display", "", "");
        }, false);
        noteDiv.addEventListener("mouseout", function(event) {
            d.getElementById("body" + this.getAttribute("id")).style.setProperty("display", "none", "");
        }, false);
        displayDiv.appendChild(noteDiv);

        noteBody = d.createElement("DIV");
        noteBody.innerHTML = ndata.getAttribute("body");
        noteBody.setAttribute("id", "bodynote" + i);
        noteBody.setAttribute("style", "border: 1px solid #000; background-color: #FFE; position: absolute; color: #000; text-align: left; padding: 4px; z-index: 1" + i);
        noteBody.addEventListener("mouseover", function(event) {
            this.style.setProperty("display", "", "");
        }, false);
        noteBody.addEventListener("mouseout", function(event) {
            this.style.setProperty("display", "none", "");
        }, false);
        displayDiv.appendChild(noteBody);

        // this sucks, find another method!
        w = parseInt(ndata.getAttribute("width"));
        h = parseInt(ndata.getAttribute("height"));
        if(w < h) { w ^= h; h ^= w; w ^= h; }; // FUCK YEAH XOR SWAP
        while(w / h > ratio) {
            w -= 5;
            h += 5;
        }

        noteBody.style.setProperty("min-width", "-moz-min-content", "");
        noteBody.style.setProperty("max-width", w + "px", "");

        ntop = ntop + 5 + parseInt(ndata.getAttribute("height"));
        h = parseInt(window.getComputedStyle(noteBody, null).getPropertyValue("height"));
        if(ntop + h + 10 > vp_bottom)
            noteBody.style.setProperty("top", vp_bottom - h - 10 + "px", "");
        else
            noteBody.style.setProperty("top", ntop + "px", "");
        noteBody.style.setProperty("left", nleft + "px", "");
        noteBody.style.setProperty("display", "none", "");
    }
}