MÀJ_Citation_(réparé_V3)
Réparation du bouton de citation avec pseudo (nouvelle DOM de merde de JVC...) : ajout d'un espace après un smiley.unknown
javascript
8 days ago
7.0 kB
19
No Index
// ==UserScript==
// @name BOUTON CITATION QUI MET LES PSEUDOS
// @namespace http://tampermonkey.net/
// @version 2026-04-16(3.0)
// @description --- Mise à jour (pour Charlotte) du bouton citer pour qu'il précise le pseudo de l'auteur du message
// @author captain_cid31/CinedineCidane - Gemini
// @match https://www.jeuxvideo.com/forums/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=jeuxvideo.com
// @grant none
// ==/UserScript==
(function() {
'use strict' ;
// FONCTION DE PARSING COMPLÈTE
function reverseMessage(node, isInit, isUl) {
let quote = "" ;
let startsWithSpoil = false ;
for (let child of node.childNodes) {
let name = child.nodeName ;
switch (name) {
case "P" :
case "UL" :
case "OL" :
case "PRE" : {
let content = reverseMessage(child, false, (name === "UL")).trim() ;
if (content) quote += content + "\n\n" ;
break ;
}
case "LI" :
quote += (isUl === true ? "* " : "# ") + reverseMessage(child).trim() + "\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 "DIV" :
case "SPAN" : {
let classList = child.classList ;
if (classList.contains("message__spoil")) {
if (quote === "") startsWithSpoil = true ;
let isInline = classList.contains("message__spoil--inline") ;
let separator = isInline ? "" : "\n\n" ;
quote += "<spoil>" + reverseMessage(child).trim() + "</spoil>" + separator ;
} else if (classList.contains("message__spoilContent")) {
quote += reverseMessage(child) ;
} else if (classList.contains("message__noBlankline")) { /* <==================== IL ÉTAIT LÀ LE SOUCI : IL FALLAIT AJOUTER LE CAS DU message__noBlankline !!! */
quote += reverseMessage(child) + "\n" ;
}
break ;
}
case "LABEL" : break ;
case "INPUT" : break ;
//case "BUTTON" : break ; // On ignore les boutons "Voir la citation" dans le texte
case "IMG" : {
let smiley = child.title || child.alt || "" ;
quote += smiley + " " ; /* <======================== Ajout d'un espace après le smiley : sinon tout est collé... */
break ;
}
case "A" : {
let link = child.href || reverseMessage(child) ;
quote += link + " " ; /* <======================== ON AJOUTE L'ESPACE APRÈS LE LIEN : SINON PROBLÈME DE LIENS COLLÉS !!! */
break ;
}
case "CODE" : quote += "<code>" + child.textContent + "</code>" ; break ;
case "BLOCKQUOTE" : {
quote = quote.trimEnd() + "\n" + reverseMessage(child).trim().replace(/^/gm, '> ') + "\n\n" ;
break ;
}
case "#text" : {
let txt = child.textContent ;
// On ne garde le texte brut que s'il n'est pas juste un saut de ligne vide du HTML
if (txt.replace(/\s/g, '').length > 0) {
quote += txt ;
}
break ;
}
}
}
quote = quote.trim() ;
if (isInit) {
// On ajoute le chevron au début de chaque ligne
quote = quote.replace(/^/gm, '> ') ;
// On nettoie les lignes qui n'auraient qu'un chevron et des espaces
quote = quote.replace(/^> \s+$/gm, '>') ;
if (startsWithSpoil) quote = ">\n" + quote ;
}
return quote ;
}
// LOGIQUE D'INTERCEPTION ET D'INJECTION
async function intercepterCitation(e) {
const btn = e.target.closest('.icon-quotes') || (e.target.classList && e.target.classList.contains('messageUser__action') && e.target.title === "Citer le message") ;
if (!btn) return ;
e.preventDefault() ;
e.stopPropagation() ;
const card = btn.closest('.messageUser__card') ;
const pseudo = card.querySelector('.messageUser__label').textContent.trim() ;
const date = card.querySelector('.messageUser__date').textContent.trim() ;
const msgContent = card.querySelector('.messageUser__msg') ;
// Appel de la fonction de parsing
let quotedText = reverseMessage(msgContent, true) ;
let finalQuote = `> Le ${date} ${pseudo} a écrit :\n${quotedText}\n\n` ;
let textarea = document.querySelector('#message_reponse') ;
if (!textarea) {
const btnOuvrir = document.querySelector(".js-post-message, .btn-post-message") ;
if (btnOuvrir) {
btnOuvrir.click() ;
for (let i = 0 ; i < 20 ; i++) {
await new Promise(r => setTimeout(r, 50)) ;
textarea = document.querySelector('#message_reponse') ;
if (textarea) break ;
}
}
}
if (textarea) {
const start = textarea.selectionStart ;
const end = textarea.selectionEnd ;
const fullText = textarea.value.substring(0, start) + finalQuote + textarea.value.substring(end) ;
// Injection via le setter natif pour bypasser les verrous de l'éditeur
const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, "value").set ;
nativeInputValueSetter.call(textarea, fullText) ;
// On déclenche les events pour que l'interface JVC réagisse
textarea.dispatchEvent(new Event('input', { bubbles: true })) ;
textarea.dispatchEvent(new Event('change', { bubbles: true })) ;
textarea.focus() ;
textarea.setSelectionRange(start + finalQuote.length, start + finalQuote.length) ;
textarea.scrollIntoView({ behavior: 'smooth', block: 'center' }) ;
}
}
// Priorité absolue sur le clic
document.addEventListener('click', intercepterCitation, true) ;
})() ;Editor is loading...
Leave a Comment