Quote specific images in a post.

Alt + Click on one or more images in a post to quote them.

Versione datata 10/04/2023. Vedi la nuova versione l'ultima versione.

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

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

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

// ==UserScript==
// @name         Quote specific images in a post.
// @author       Joshh
// @namespace    https://tljoshh.com
// @version      0.2.2
// @description  Alt + Click on one or more images in a post to quote them.
// @match        *://*.websight.blue/thread/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=websight.blue
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    let lastQuotedMsg = null;
    const replyBox = document.querySelector('#reply-content');
    const postsContainer = document.querySelector('#messages');
    const posts = document.querySelectorAll('.post');

    // Listen to all for an alt+click event
    for (const post of posts) {
        post.addEventListener('click', handleClick);
    };
    // Listen for new posts added by livelinks
    startMutationObserver(postsContainer);

    // Target event: alt+click on images in a post
    function handleClick(e) {
        const { altKey, target, currentTarget } = e;
        if (altKey && target.tagName === 'IMG') {
            e.preventDefault();
            handleImageClick(currentTarget, target);
        }
    };

    // Add the markdown formatted text for the quoted message identifier and the image to the reply textarea
    function handleImageClick(post, image) {
        // Append quoted message identifier
        const authorBoxNotAdded = !checkIfAuthorBoxAdded(post);
        if(authorBoxNotAdded) {
            addAuthorBox(post);
        }

        // Append quoted image to replybox
        addQuotedImage(image);
    }

    // Add an image to the reply textarea
    function addQuotedImage(img) {
        const { alt, src } = img;
        replyBox.value += `\n> ![${alt}](${src})`;
    };

    // Add quoted message identifier to reply textarea and store the permalink id
    function addAuthorBox(post) {
        const username = post.querySelector('.post-author').innerText;
        const messageTopLinks = post.querySelectorAll('.message-top > a');
        const filteredThreadPermalink = messageTopLinks[2].href;
        const date = messageTopLinks[1].querySelector('.desktop-only').innerText;
        const messagePermalink = messageTopLinks[1].href;
        if(lastQuotedMsg !== null && replyBox.value.length) {
            replyBox.value += `\n\n`;
        } else if(replyBox.value.length) {
            replyBox.value += `\n`;
        }
        replyBox.value += `> From: [${username}](${filteredThreadPermalink}) at [${date}](${messagePermalink})`;
        lastQuotedMsg = messagePermalink;
    };

    // Check what the last quoted message identifier was and determine if we need to add an author box.
    function checkIfAuthorBoxAdded(post) {
        const messageTopLinks = post.querySelectorAll('.message-top > a');
        const messagePermalink = messageTopLinks[1].href;
        console.log('lastQuotedMsg', lastQuotedMsg);
        console.log('messagePermalink', messagePermalink);
        return lastQuotedMsg === messagePermalink
    };

    // Add event listener to any posts added to DOM via livelinks
    function startMutationObserver(targetNode) {
        // Options for the observer (which mutations to observe)
        const config = { childList: true };

        // Callback function to execute when mutations are observed
        const callback = (mutationList, observer) => {
            // For all mutations made to the target node, check if any nodes were added...
            for (const mutation of mutationList) {
                handleMutation(mutation);
            }
        };

        // Create an observer instance linked to the callback function
        const observer = new MutationObserver(callback);

        // Start observing the target node for configured mutations
        observer.observe(targetNode, config);
    }

    // Handle any changes made to the messages container.
    function handleMutation(mutation) {
        // For all nodes that were added, check if any where posts made by a user and add a click event listener.
        if(mutation.addedNodes.length) {
            for (const addedNode of mutation.addedNodes) {
                if (!addedNode.tagName) continue; // Not an element
                if(addedNode.classList.contains('post')) {
                    addedNode.addEventListener('click', handleClick);
                }
            }
        }
    }
})();