Rule34 Artist favorites

A simple script to add the possibility to favorite artists to rule34

// ==UserScript==
// @name         Rule34 Artist favorites
// @description  A simple script to add the possibility to favorite artists to rule34
// @namespace    User_314159_AFav
// @version      1.32
// @author       User_314159
// @license      MIT
// @match        https://rule34.xxx/index.php?page=account&s=home
// @match        https://rule34.xxx/index.php?page=post&s=view*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=rule34.xxx
// @grant        none
// ==/UserScript==

/* Functions used to interact with the local storage */
function getArtists() { // 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('rule34FavArtists') === null) {
        console.log('generated new artists array');
        artists = [];
        saveArtists(artists);
    }
    else {
        artists = JSON.parse(localStorage.getItem('rule34FavArtists'));
    }
    return artists;
}

function deleteArtist(artist) { // deletes the specified artist out of the array and saves it
    let artists = getArtists();
    let target = artists.indexOf(artist);
    artists.splice(target, 1);
    saveArtists(artists);
    console.log('Deleted ' + artist);
}

function saveArtists(artists) { // saves an updated version of the artists to local storage
    localStorage.setItem('rule34FavArtists', JSON.stringify(artists.sort()));
}

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

function importArtists() { // takes an inputted array string and overwrites the local storage with it
    let input = window.prompt("Enter previously exported artists"); // 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_artists = getArtists();
    for(let index = 0; index < data.length; index++) {
        if(current_artists.includes(data[index])) {
            continue;
        } else {
            current_artists.push(data[index]);
            console.log("New artist: " + data[index]);
        }
    }
    localStorage.setItem('rule34FavArtists', JSON.stringify(current_artists));
}

/* These are the functions for the Favorites displaying */
function generateArtistEntry(name) { // generates a container with a delete button calling the deleteArtist function and a link to the artist page
    let link = document.createElement('a');
    let deleteButton = document.createElement('button');
    let container = document.createElement('div');

    deleteButton.innerHTML = 'delete';
    deleteButton.setAttribute('id', 'artistFavDel');
    link.innerHTML = name;

    link.setAttribute('href', 'https://rule34.xxx/index.php?page=post&s=list&tags=' + name);
    deleteButton.setAttribute('name', name);

    deleteButton.addEventListener("click", function () {
        deleteArtist(name)
    }, false);

    container.appendChild(deleteButton);
    container.appendChild(link);

    return container;
}

/* Functions for the adding of artists to the favorites */
function generateAddButton(name) { // generates a button that is added to the bottom of the post to add an artist
    var button = document.createElement('button');
    button.innerHTML = ('Add ' + name + ' to favorites');
    button.addEventListener("click", function () {
        addArtist(name)
    }, false);
    return button;
}

function generateArtistAddable() { // adds the artists as single buttons to the bottom of the page, the buttons are generated in the generateAddButton function
    let possibles = document.getElementsByClassName('tag-type-artist tag');
    let artists = document.getElementsByClassName('link-list')[0];
    for (let i = 0; i < possibles.length; i++) {
        let artist = possibles[i].children[1].firstChild.data.split(' ').join('_'); // this hell of a selector is the name of the artist with the spaces replaced with underscores
        console.log(artist);
        artists.appendChild(generateAddButton(artist));
    }

}

function addArtist(artist) { // adds the name of the artist to the array and saves the array, cancels if the artist already is in the most recent save
    let artists = getArtists();
    if (artists.includes(artist)) {
        console.log(artist + ' already in favorites.');
        return;
    }
    artists.push(artist);
    saveArtists(artists);
    console.log('Added ' + artist + ' to favorites');

}

/* Main Function */
(function () {
    'use strict';

    let url = window.location.href;
    if (url.includes('page=post&s=view')) {
        generateArtistAddable();
    }; // this part checks if you are on a post and if so, the 'add to favorites' gets added
    if (url.includes('&s=home')) {
        let artists = getArtists(); // gets the artists and parses them from a string to an iterable
        let favoritesHeader = document.createElement('h4'); //header 4 element
        let favoritesCollapse = document.createElement('details'); // collapsible list of favorites
        let favoritesTitle = document.createElement('summary'); // title element of the collapsible
        let exp = document.createElement('button');
        let imp = document.createElement('button');
        // the two buttons are for import and export
        exp.addEventListener("click", function () {
            exportArtists();
        }, false);
        imp.addEventListener("click", function () {
            importArtists();
            location.reload();
        }, false);
        imp.innerHTML = 'Import';
        exp.innerHTML = 'Export';
        // the buttons values get declared and the onclick functions get set to the export / import functions

        favoritesTitle.innerHTML = 'Favorite Artists'; //setting the title
        for (let i = 0; i < artists.length; i++) {
            favoritesCollapse.appendChild(generateArtistEntry(artists[i]));
        } // this adds one link for each favorite artist to the collapsible

        let desc = document.createElement('p'); //description, paragraph element
        desc.innerHTML = 'View all of your favorite artists and remove them if you wish.';

        favoritesCollapse.appendChild(favoritesTitle); // the title of the collapsible gets added

        favoritesHeader.appendChild(favoritesCollapse); // the collapsible gets added to the main container

        let mainPosts = document.getElementById("user-index").lastElementChild; // the last child of the user-index div is gotten, which is the "To main post page"
        let space = document.getElementById('user-index'); // the space variable is the container element for the whole thing

        space.insertBefore(favoritesHeader, mainPosts); // main container for the artist entries
        space.insertBefore(desc, mainPosts); // the description
        space.insertBefore(exp, mainPosts); // export button
        space.insertBefore(imp, mainPosts); // import button
        if (artists.length > 0) { // this adds a button that resets the data if there is any data
            let delete_all_artists = document.createElement('button');
            delete_all_artists.addEventListener("click", function () {
                if(window.confirm("WARNING: This will delete all favourites and cannot be undone")) {
                    if(window.confirm("Are you sure?")) {
                        localStorage.removeItem('rule34FavArtists');
                        console.log("removed all favorites");
                        alert("To confirm reset, reload the page");
                        return;
                    }
                }
                console.log('cancelled reset'); // this only executes if one of the confirms were cancelled because of the return
            }, false);
            delete_all_artists.innerHTML = 'Reset';
            space.insertBefore(delete_all_artists, mainPosts);
        }
        // this block just adds all the objects to the page before the "To main post page" link
    }
})();