AO3: [Wrangling] Tag List to Clipboard

Mass-select tags in the bin and copy them to the clipboard as a list of HTML links

// ==UserScript==
// @name         AO3: [Wrangling] Tag List to Clipboard
// @namespace    https://greasyfork.org/en/users/906106-escctrl
// @description  Mass-select tags in the bin and copy them to the clipboard as a list of HTML links
// @author       escctrl
// @version      2.0
// @history      added option to copy link texts
// @match        *://*.archiveofourown.org/tags/*/wrangle?*
// @require      https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js
// @license      MIT
// ==/UserScript==

(function($) {
    'use strict';

    // add a button above the taglist
    $('#wrangulator p.submit.actions').prepend(`<button id="massCopyLinks" type="button" style="padding-left: 0.75em;">Copy Links</button> `);
    $('#wrangulator p.submit.actions').prepend(`<button id="massCopyTexts" type="button" style="padding-left: 0.75em;">Copy Texts</button> `);

    // add the event listener to the button with function to copy the list to the clipboard
    $('button#massCopyLinks, button#massCopyTexts').on("click", (e)=>{
        // based on which button is clicked, we'll later copy text only (if true), or links (if false)
        const TEXTONLY = e.target.id == "massCopyTexts" ? true : false;

        // grab the selected tags
        let selectedTags = $('input[name="selected_tags[]"]:checked');

        // check that we have the necessary info to start working
        if ($(selectedTags).length < 1) { alert("Please select at least one tag!"); return false; }

        // creates an array of links for every selected tag
        let tagHTML = $(selectedTags).map(function() {
            if (TEXTONLY) return $(this).parent().find('label').text();
            else return `<a href="${$(this).closest('tr').find('a[href$="/edit"]').prop('href').slice(0, -5)}">${$(this).parent().find('label').text()}</a>`;

        });
        // joins them together with HTML newlines and copies it to clipboard
        copy2Clipboard(e, $(tagHTML).toArray().join(`${(TEXTONLY) ? "\n" : "<br />\n"}`));
    });

})(jQuery);

// solution for setting richtext clipboard content found at https://jsfiddle.net/jdhenckel/km7prgv4/3/
// and https://stackoverflow.com/questions/34191780/javascript-copy-string-to-clipboard-as-text-html/74216984#74216984
function copy2Clipboard(e, str) {
    // trying first with the new Clipboard API
    try {
        const clipboardItem = new ClipboardItem({'text/html': new Blob([str], {type: 'text/html'}),
                                                 'text/plain': new Blob([str], {type: 'text/plain'})});
        navigator.clipboard.write([clipboardItem]);
    }
    // fallback method in case clipboard.write is not enabled - especially in Firefox it's disabled by default
    // to enable, go to about:config and turn dom.events.asyncClipboard.clipboardItem to true
    catch {
        console.log('Copy Tag to Clipboard: Clipboard API is not enabled in your browser - fallback option used');
        function listener(e) {
            e.clipboardData.setData("text/html", str);
            e.clipboardData.setData("text/plain", str);
            e.preventDefault();
        }
        document.addEventListener("copy", listener);
        document.execCommand("copy");
        document.removeEventListener("copy", listener);
    }
}