Topic de Blaff12 :

[Script] JVChat Premium

https://image.noelshack.com/fichiers/2016/24/1466366209-risitas24.png ledrob aç tnof sli tnemmoc

Le 05 juin 2025 à 10:29:30 :
https://image.noelshack.com/fichiers/2018/13/4/1522325846-jesusopti.png eyasser ecrire à le endroit

:rire: c'est galere

https://image.noelshack.com/fichiers/2016/26/1467335935-jesus1.png uv tuot arua no ofof ec niatup

'm tu etonne> Le 05 juin 2025 à 10:30:22 Bannipourspam a écrit :

Le 05 juin 2025 à 10:29:30 :
eyasser ecrire à le endroit

c'est galere

e

https://image.noelshack.com/fichiers/2017/18/1493933263-fou-rire-jesus.png riorrim nu ceva erircé riolaf av niatup ololor
https://image.noelshack.com/fichiers/2018/10/1/1520256134-risitasue2.png tiaf ne tpircs el tnavitcasédn e emem tiaf el aç siam niatup
C'est quoi ce délire ? https://image.noelshack.com/fichiers/2018/29/3/1531932855-risitas-louis-xv-lecteur-sticker.png
Sinon pour retourner tout un texte, mettez ‮ devant : ‮ voilà https://image.noelshack.com/fichiers/2018/29/3/1531932855-risitas-louis-xv-lecteur-sticker.png

Le 05 juin 2025 à 05:11:45 Clara a écrit :

Ligne 2219, le textarea.style.height = "250px"; est là pourquoi ? Il est pas antagoniste aux 7rem dans le let CSS plus haut ? https://image.noelshack.com/fichiers/2019/48/3/1574893100-ramechat.png

Non c'est juste pour la zone d'édition pas la zone de texte principale https://image.noelshack.com/fichiers/2024/02/7/1705254088-chat-tout-mignon-2.png

Ah tant mieux alors ça. :ok:

La correction au fait que quand on cite un message supprimé, les citations qu'il contient ne restent plus imbriquées les unes dans les autres et les stickers disparaissent, par exemple :

Ça c'est parce que le bouton citer utilise le bouton de base du site qui retourne normalement tout le truc, faudrait faire comme l'ancien script c'était moins casse gueule et les citations ne dépendaient pas de l'état des messages sur le forum https://image.noelshack.com/fichiers/2019/41/5/1570758522-1478646990-hooper-removebg-preview.png

Qu'est-ce qui a changé entre le citer d'avant et celui actuel ? C'est que maintenant ça envoie une requête AJAX alors qu'avant non, c'est ça ? https://image.noelshack.com/fichiers/2018/29/3/1531932855-risitas-louis-xv-lecteur-sticker.png

Bon bah j'essaierais après jvchat sur chrome vu que sur operagx c'est mort https://image.noelshack.com/fichiers/2024/18/3/1714584542-ikari-shinji-blas.jpeg

Le 05 juin 2025 à 14:10:46 captain_cid31 a écrit :
Qu'est-ce qui a changé entre le citer d'avant et celui actuel ? C'est que maintenant ça envoie une requête AJAX alors qu'avant non, c'est ça ? https://image.noelshack.com/fichiers/2018/29/3/1531932855-risitas-louis-xv-lecteur-sticker.png

Ouient, puis j'imagine que depuis les changements du site ça devait être plus chiant à mettre en place ou à refaire plutôt que d'utiliser le truc déjà existant, mais du coup ça pose des problèmes pour les messages supprimés.

Après est-ce grave ? Bof, c'est juste que ça fait une requête supplémentaire juste pour citer alors qu'avant non. https://image.noelshack.com/fichiers/2024/02/7/1705254088-chat-tout-mignon-2.png

Le 06 juin 2025 à 09:45:30 Clara a écrit :

Le 05 juin 2025 à 14:10:46 captain_cid31 a écrit :
Qu'est-ce qui a changé entre le citer d'avant et celui actuel ? C'est que maintenant ça envoie une requête AJAX alors qu'avant non, c'est ça ? https://image.noelshack.com/fichiers/2018/29/3/1531932855-risitas-louis-xv-lecteur-sticker.png

Ouient, puis j'imagine que depuis les changements du site ça devait être plus chiant à mettre en place ou à refaire plutôt que d'utiliser le truc déjà existant, mais du coup ça pose des problèmes pour les messages supprimés.

Après est-ce grave ? Bof, c'est juste que ça fait une requête supplémentaire juste pour citer alors qu'avant non. https://image.noelshack.com/fichiers/2024/02/7/1705254088-chat-tout-mignon-2.png

Est-ce que ça marcherait de faire un nouveau bouton citer qui remplace celui par défaut juste pour les posts supprimés ? https://image.noelshack.com/fichiers/2017/32/7/1502654958-sabri-said-h-ramzy-5.png

J'ai pu bricoler une solution pour réparer la mise en forme foireuse des citations de messages supprimés (à rajouter à la toute fin) :

function apposerNouveauBoutonCiterPourMessagesSupprimés(un_post) {
    if (un_post.dataset.leBoutonATIlEteAjoute) {
        return ;
    }
    un_post.dataset.leBoutonATIlEteAjoute = "oui" ;

    const ancien_bouton_citer = un_post.querySelector(".jvchat-picto.jvchat-quote") ;
    if (!ancien_bouton_citer) {
        return ;
    }
    const bouton_signaler = ancien_bouton_citer.nextSibling?.nextSibling ;
    if (!bouton_signaler || !bouton_signaler.parentNode) {
        return ;
    }
    const nouveau_bouton_citer = document.createElement("span") ;
    nouveau_bouton_citer.title = "Citer message supprimé" ;
    nouveau_bouton_citer.classList.add("jvchat-picto", "jvchat-quote") ;
    nouveau_bouton_citer.addEventListener("click", quoteDeleted) ;
    bouton_signaler.parentNode.insertBefore(nouveau_bouton_citer, bouton_signaler.previousSibling) ;
    ancien_bouton_citer.remove() ;
}

function quoteDeleted(targ) {
    const cible = targ.currentTarget ;
    const message = cible.closest(".jvchat-message") ; // ou ".jvchat-message-deleted"
    const citation = reverseQuote(message) ;
    const boîte_textuelle = document.querySelector("#message_topic") ;

    insertAtCursor(boîte_textuelle, citation) ;
    boîte_textuelle.focus() ;
}

const ID_CIBLE = "message_topic" ;
let zone_texte = document.getElementById(ID_CIBLE) ;
const PLACEHOLDER_JVCHAT = "Hop hop hop, le message ne va pas s'écrire tout seul !" ;

function est_ce_que_la_zone_texte_est_chargée() {
    return document.querySelector("#message_topic") !== null ; // plus sûr que return zone_texte !== null ; car zone_texte est fixe à ce stade
}

function est_ce_que_JVChat_est_activé() {
    if (!zone_texte) {
        return false ;
    }
    const placeholder = zone_texte.getAttribute("placeholder") || "" ;
    return placeholder === PLACEHOLDER_JVCHAT ;
}

let état_du_chargement = null ;

const détecteur_de_zone_texte = new MutationObserver(() => {
    const chargé = est_ce_que_la_zone_texte_est_chargée() ;
    if (chargé) {
        if (état_du_chargement !== chargé) {
            état_du_chargement = chargé ;
            console.log("ZONE CHARGÉE !") ;
        }

        zone_texte = document.getElementById(ID_CIBLE) ; // important car le premier document.getElementById(ID_CIBLE) (dans le let zone_texte) peut avoir foiré.

        const détecteur_de_jvchat = new MutationObserver(() => {
            if (!est_ce_que_JVChat_est_activé()) {
                console.log("Vous n'êtes pas encore en mode JVChat.") ;
            } else { // DÉBUT ELSE
                console.log("VOUS ÊTES BIEN EN MODE JVCHAT À PRÉSENT !") ;
                const container = document.getElementById("jvchat-main") ;

                function observeMessage(messageElem) {
                    const msgObserver = new MutationObserver(mutations => {
                        for (const mutation of mutations) {
                            if (mutation.type === "attributes" && mutation.attributeName === "class") {
                                if (messageElem.classList.contains("jvchat-message-deleted")) {
                                    apposerNouveauBoutonCiterPourMessagesSupprimés(messageElem) ;
                                }
                            }
                        }
                    }) ;
                    msgObserver.observe(messageElem, { attributes: true, attributeFilter: ["class"] }) ;
                }

                // Observer le container pour détecter les nouveaux messages
                const containerObserver = new MutationObserver(mutations => {
                    for (const mutation of mutations) {
                        if (mutation.type === "childList" && mutation.addedNodes.length) {
                            mutation.addedNodes.forEach(node => {
                                if (node.nodeType === 1 && node.classList.contains("jvchat-bloc-message")) {
                                    const msg = node.querySelector(".jvchat-message") ;
                                    if (msg) {
                                        observeMessage(msg) ;
                                        // Si déjà supprimé au moment de l'ajout
                                        if (msg.classList.contains("jvchat-message-deleted")) {
                                            apposerNouveauBoutonCiterPourMessagesSupprimés(msg) ;
                                        }
                                    }
                                }
                            }) ;
                        }
                    }
                }) ;

                // Démarrer observation sur container
                containerObserver.observe(container, { childList: true }) ;

                // Observer aussi tous les messages déjà existants
                container.querySelectorAll(".jvchat-message").forEach(msg => {
                    observeMessage(msg) ;
                    if (msg.classList.contains("jvchat-message-deleted")) {
                        apposerNouveauBoutonCiterPourMessagesSupprimés(msg) ;
                    }
                }) ;

            } // FIN ELSE
        }) ; // fin déclaration de la constante détecteur_de_jvchat

        détecteur_de_jvchat.observe(zone_texte, {
            attributes: true,
            attributeFilter: ["placeholder"]
        }) ;
    } // FIN if(chargé)
}) ;

const corps_de_page = document.body ;

détecteur_de_zone_texte.observe(corps_de_page, {
    childList: true,
    subtree: true
}) ;

Y a sûrement plus opti mais bon :(

Y a 4 fonctions importantes qui sont utilisées dedans et que j'ai pas reprécisées car elles y sont normalement encore, mais au cas où :( :d)

function setTextAreaValue(textarea, value) {
    const prototype = Object.getPrototypeOf(textarea);
    const nativeSetter = Object.getOwnPropertyDescriptor(prototype, 'value').set;
    nativeSetter.call(textarea, value);
    textarea.dispatchEvent(new Event('input', { bubbles: true }));
}

function insertAtCursor(input, textToInsert) {
    const value = input.value;
    const start = input.selectionStart;
    const end = input.selectionEnd;
    const newValue = value.slice(0, start) + textToInsert + value.slice(end);
    setTextAreaValue(input, newValue);
    input.selectionStart = input.selectionEnd = start + textToInsert.length;
}

function reverseQuote(blocMessage) {
    let author = blocMessage.getElementsByClassName("jvchat-author")[0].textContent.trim();
    let date = blocMessage.getElementsByClassName("jvchat-date")[0].getAttribute("to-quote");
    let header = `> Le ${date} ${author} a écrit :\n`;
    let quoted = reverseMessage(blocMessage.getElementsByClassName("txt-msg")[0], true);
    return header + quoted + '\n\n';
}
function reverseMessage(node, isInit, isUl) {
    let quote = "";
    let prevIsP = false;
    let startsWithSpoil = false;

    for (let child of node.childNodes) {
        let name = child.nodeName;

        switch (name) {
            case "P": {
                quote += reverseMessage(child) + "\n\n";
                break;
            }
            case "STRONG": {
                quote += "'''" + reverseMessage(child) + "'''";
                break;
            }
            case "U": {
                quote += "<u>" + reverseMessage(child) + "</u>";
                break;
            }
            case "S": {
                quote += "<s>" + reverseMessage(child) + "</s>";
                break;
            }
            case "EM": {
                quote += "''" + reverseMessage(child) + "''";
                break;
            }
            case "BR": {
                quote += "\n";
                break;
            }
            case "UL": {
                quote += reverseMessage(child, false, true) + "\n\n";
                break;
            }
            case "OL": {
                quote += reverseMessage(child, false, false) + "\n\n";
                break;
            }
            case "LI": {
                if (isUl === true) {
                    quote += "* " + reverseMessage(child) + "\n";
                } else {
                    quote += "# " + reverseMessage(child) + "\n";
                }
                break;
            }
            case "DIV": {
                let classList = child.classList;
                if (classList.contains("bloc-spoil-jv")) {
                    if (quote === "") {
                        startsWithSpoil = true;
                    }
                    quote += "< spoil>" + reverseMessage(child) + "</ spoil>\n\n"
                } else if (classList.contains("contenu-spoil")) {
                    quote += reverseMessage(child);
                }
                break;
            }
            case "SPAN": {
                let classList = child.classList;
                if (classList.contains("bloc-spoil-jv")) {
                    quote += "< spoil>" + reverseMessage(child) + "</ spoil>";
                } else if (classList.contains("contenu-spoil")) {
                    quote += reverseMessage(child);
                }
                break;
            }
            case "LABEL": {
                break;
            }
            case "INPUT": {
                break;
            }
            case "IMG": {
                quote += child.alt;
                break;
            }
            case "A": {
                if (child.href) {
                    quote += child.href;
                } else {
                    quote += reverseMessage(child);
                }
                break;
            }
            case "PRE": {
                quote += reverseMessage(child) + "\n\n";
                break;
            }
            case "CODE": {
                quote += "< code>" + child.textContent + "</ code>";
                break;
            }
            case "BLOCKQUOTE": {
                if (prevIsP) {
                    quote = quote.trimEnd() + "\n" + reverseMessage(child).replace(/^/gm, '> ') + "\n\n";
                } else {
                    quote += reverseMessage(child).replace(/^/gm, '> ') + "\n\n";
                }

                break;
            }
            case "#text": {
                // The "isInit" check is to prevent the empty text surroudning message
                // However, it may happen that the root node contains valid text child, so it need to be added somehow
                // For some reason, an "new line" may be missing in this case, so just add it
                if (!isInit || child.textContent.trim() !== "") {
                    quote += child.textContent;
                    if (isInit && !quote.endsWith("\n")) {
                        quote += "\n";
                    }
                }
                break;
            }
            default: {
                break;
            }
        }

        if (name == "P") {
            prevIsP = true;
        } else {
            prevIsP = false;
        }
    }

    quote = quote.replace(/(\n){3,}/g, '\n\n');

    if (startsWithSpoil && isInit) {
        quote = "\n" + quote.trimEnd();
    } else {
        quote = quote.trim();
    }

    if (isInit) {
        quote = quote.replace(/^/gm, '> ');
    }

    return quote;
}

Faudra juste faire gaffe en copiant-collant :

            case "CODE": {
                quote += "< code>" + child.textContent + "</ code>";

et :

            case "DIV": {
                    ...
                    quote += "< spoil>" + reverseMessage(child) + "</ spoil>\n\n"
            case "SPAN": {
                    ...
                    quote += "< spoil>" + reverseMessage(child) + "</ spoil>";

à bien enlever les espaces entre "<", "</" et "code", "spoil" etc (j'ai dû le faire pour que ça rentre bien dans le spoil et le code :( ).

Le 05 juin 2025 à 14:00:00 captain_cid31 a écrit :
C'est quoi ce délire ? https://image.noelshack.com/fichiers/2018/29/3/1531932855-risitas-louis-xv-lecteur-sticker.png
Sinon pour retourner tout un texte, mettez &#x202e; devant : ‮ voilà https://image.noelshack.com/fichiers/2018/29/3/1531932855-risitas-louis-xv-lecteur-sticker.png

Ce hacker bordel https://image.noelshack.com/fichiers/2018/29/6/1532128784-risitas33.png

Le 09 juin 2018 à 21:12:08 :
Bravo l'auteur il a l'air sympa je suis déçu et j'aime bien

Le 07 juin 2025 à 05:16:50 1MinutePasPlus a écrit :
Le 05 juin 2025 à 10:23:58 Chirak_laklak_2 a écrit :
ledrob iouq etropmi'"n tse'c niatup

Le 05 juin 2025 à 10:24:51 ElementaryMODO a écrit :
:erir: ? lues el sap sius ej aaaaaaaaaaaya

Le 05 juin 2025 à 10:25:11 ElementaryMODO a écrit :
? iom ed suof et ut srola uo

Le 05 juin 2025 à 10:25:28 Chirak_laklak_2 a écrit :
u> Le 05 juin 2025 à 10:24:51 ElementaryMODO a écrit :

:erir: ? lues el sap sius ej aaaaaaaaaaaya

uof ed curt ec niatp

Le 05 juin 2025 à 10:26:09 Chirak_laklak_2 a écrit :
niatup reuqinummoc ed tnedivé erte sap av aç puoc el ruop al

Le 05 juin 2025 à 10:27:46 Chirak_laklak_3 a écrit :
srevne'l à stircé stom sniatrec riov ed ologir tse'c spmet emem ne

Le 05 juin 2025 à 10:28:40 Bannipourspam a écrit :
...ocol rineved ed niart ne sius eJ

Le 05 juin 2025 à 10:29:11 ElementaryMODO a écrit :
liavart ertov eriaf neib à egaruo...CNE suov ej sodom seL

Le 05 juin 2025 à 10:29:40 ElementaryMODO a écrit :
modos tiaf aç srevne'l à sodom aaaaaaayA

Le 05 juin 2025 à 10:30:20 Chirak_laklak_3 a écrit :
ledrob aç tnof sli tnemmoc

Le 05 juin 2025 à 10:30:52 Chirak_laklak_3 a écrit :
uv tuot arua no ofof ec niatup

Les kheys deviennent fou depuis que PH est inaccessible https://image.noelshack.c
om/fichiers/2
020/51/2/1607997474-ayaoo.png.

Plaît-il ? https://image.noelshack.com/fichiers/2018/29/6/1532128784-risitas33.png

Données du topic

Auteur
Blaff12
Date de création
9 juin 2018 à 21:11:24
Nb. messages archivés
3251
Nb. messages JVC
3121
Voir le topic sur JVC

Afficher uniquement les messages de l'auteur du topic

En ligne sur JvArchive

JvArchive compagnon

Découvrez JvArchive compagnon , l'userscript combattant la censure abusive sur le 18-25 !