Rule34 Save Search

Save search queries

As of 2023-04-27. See the latest version.

// ==UserScript==
// @name         Rule34 Save Search
// @namespace    http://tampermonkey.net/
// @version      0.4
// @description  Save search queries
// @author       User_314159
// @license      MIT
// @match        https://rule34.xxx/index.php?page=post&s=list*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=rule34.xxx
// @grant        none
// ==/UserScript==

// display logic
function get_search() {
    let contents = document.getElementById("content");
    if (contents.getElementsByClassName("image-list")[0] != undefined) {
        let search_bar = contents.querySelector('input[name="tags"]');
        if (search_bar.value != "") {
            console.log("Search bar not empty, should display");
            return [true, search_bar.value];
        }
    }
    return [false, ""];
}

//io
function getSavedSearches() { // gets the localstorage array and parses it into an actual array, creates a new one if there is no key in localStorage
    let artists;
    if (localStorage.getItem('rule34SavedSearches') === null) {
        console.log('generated new saved array');
        artists = [];
        saveSearches(artists);
    }
    else {
        artists = JSON.parse(localStorage.getItem('rule34SavedSearches'));
    }
    return artists;
}

function deleteSearch(search) { // deletes the specified search out of the array and saves it
    let artists = getSavedSearches();
    let target = artists.indexOf(search);
    artists.splice(target, 1);
    saveSearches(artists);
    console.log('Deleted ' + search);
}

function saveSearches(searches) { // saves an updated version of the searches to local storage
    localStorage.setItem('rule34SavedSearches', JSON.stringify(searches));
}
function addSearch(search) {
    let searches = getSavedSearches();
    searches.push(search);
    saveSearches(searches);
}

// function exportSearches() { // gets the local storage and logs it to the console as a string
//     let searches = localStorage.getItem('rule34SavedSearches');
//     console.log(searches); // Don't need to stringify here the localstorage got it stringified
//     navigator.clipboard.writeText(searches);
//     alert("Copied searches to clipboard");
// }

// function importSearches() { // takes an inputted array string and overwrites the local storage with it
//     let input = window.prompt("Enter previously exported searches"); // window.prompt seems to return a double-escaped string
//     let data = JSON.parse(input); // due to this, we need to de-escape twice to get the actual json
//     let current_searches = getSavedSearches();
//     for(let index = 0; index < data.length; index++) {
//         if(current_searches.includes(data[index])) {
//             continue;
//         } else {
//             current_searches.push(data[index]);
//             console.log("New artist: " + data[index]);
//         }
//     }
//     localStorage.setItem('rule34SavedSearches', JSON.stringify(current_searches));
// }

// button logic
function createA(target) {
    let href = createLink(target);
    let a = document.createElement("a");
    a.href = href;
    a.innerHTML = target;
    a.style.overflow = "hidden";
    return a;
}
function createLink(target) {
    return "index.php?page=post&s=list&tags=" + target + "&is_saved_search";
}
function createAddButton(search) {
    let button = document.createElement("button");
    button.innerHTML = "Save search";
    button.style.width = "100%";

    button.addEventListener("click", function() {addSearch(search)});
    return button;
}
function createDeleteButton(search) {
    let button = document.createElement("button");
    button.innerHTML = "Delete search";
    button.style.width = "100%";

    button.addEventListener("click", function() {
        deleteSearch(search);
        window.location.href = createLink(search).replace("&is_saved_search", "");
    });
    return button;
}


(function() {
    'use strict';
    let [search_not_empty, search_value] = get_search();
    let search_bar = document.getElementsByClassName("tag-search")[0];

    let collapsable = document.createElement("details");
    let collapsable_name = document.createElement("summary");
    collapsable_name.innerHTML = "Saved";
    collapsable.style.maxHeight = "50vh";
    collapsable.style.overflow = "hidden scroll";
    collapsable.style.textOverflow = "ellipsis";
    collapsable.style.whiteSpace = "nowrap";
    collapsable.style.scrollbarWidth = "thin";
    collapsable.appendChild(collapsable_name);

    let searches = getSavedSearches();
    let linebreak = document.createElement("br");
    for (let i = 0; i < searches.length; i++) {
        collapsable.appendChild(createA(searches[i]));
        collapsable.appendChild(linebreak.cloneNode());
    }

    if (search_not_empty) {
        let addButton = createAddButton(search_value);
        search_bar.append(addButton);
    }
    if (window.location.href.includes("&is_saved_search")) {
        let deleteButton = createDeleteButton(search_value);
        search_bar.append(deleteButton);
    }
    search_bar.append(collapsable);
})();