您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Version de Test. Met en évidence l'auteur (OP), les citations, les PEMT, vos messages et les DDB sur tous les forums JVC.
// ==UserScript== // @name Surlignage Post // @namespace http://tampermonkey.net/ // @version 0.8.7 // @description Version de Test. Met en évidence l'auteur (OP), les citations, les PEMT, vos messages et les DDB sur tous les forums JVC. // @author FaceDePet // @match *://www.jeuxvideo.com/forums/*-*-*-*-*-*-*-*.htm // @connect *.jeuxvideo.com // @icon https://cdn-icons-png.flaticon.com/512/4698/4698417.png // @grant GM_xmlhttpRequest // @run-at document-end // @license MIT // ==/UserScript== (function() { 'use strict'; class JVCTopicEnhancer { constructor() { this.CACHE_KEY_OP = 'jvcTopicEnhancerCacheOP'; this.CACHE_KEY_POSTS = 'jvcUserPostsCache'; this.CACHE_KEY_DDB = 'jvcDdbStatusCache'; this.MAX_CACHED_POSTS_PER_TOPIC = 20; this.pemtColors = ['#45a093', '#5c8fba', '#896a9e', '#c77e4d', '#c06158']; this.init(); } async init() { this.topicId = this.getTopicId(); if (!this.topicId) return; this.currentPage = this.getCurrentPageNumber(); this.currentUser = this.getCurrentUsername(); this.addPostListener(); try { const [opUsername, userMessages] = await Promise.all([ this.getOpUsername(), this.currentUser ? this.getAllUserMessageContents() : [] ]); this.opUsername = opUsername; this.currentUserMessages = userMessages; } catch (error) { console.error("JVC Enhancer: Erreur lors de la récupération des données.", error); return; } this.highlightRules = [ { name: 'Original Poster', condition: (author) => author === this.opUsername }, { name: 'User Mention', condition: (author, el) => this.isUserMentioned(author, el) }, { name: 'Self', condition: (author) => author === this.currentUser } ]; this.injectStyles(); this.processMessages(); this.checkFirstMessagesReportStatus(); } // --- Fonctions de Parsing et de Récupération --- getTopicId() { const match = window.location.href.match(/\/forums\/\d+-\d+-(\d+)-/); return match ? match[1] : null; } getCurrentPageNumber() { const match = window.location.href.match(/-(\d+)-0-1-0-/); return match ? parseInt(match[1], 10) : 1; } async getOpUsername() { const cache = JSON.parse(sessionStorage.getItem(this.CACHE_KEY_OP)) || {}; if (cache[this.topicId]) return cache[this.topicId]; let newOpUsername = (this.currentPage === 1) ? this.parseOpUsernameFromDocument(document) : await this.fetchOpUsernameFromPageOne(); if (newOpUsername) { cache[this.topicId] = newOpUsername; sessionStorage.setItem(this.CACHE_KEY_OP, JSON.stringify(cache)); } return newOpUsername; } parseOpUsernameFromDocument(doc, isApi = false) { const selector = isApi ? '.post .bloc-pseudo-msg' : '.bloc-message-forum .bloc-pseudo-msg'; return doc.querySelector(selector)?.textContent.trim() || null; } fetchOpUsernameFromPageOne() { return this.fetchApiPageContent(1).then(doc => this.parseOpUsernameFromDocument(doc, true)); } fetchApiPageContent(pageNumber) { return new Promise((resolve, reject) => { const url = window.location.href.replace(`-${this.currentPage}-0-1-0-`, `-${pageNumber}-0-1-0-`).replace('www.jeuxvideo.com', 'api.jeuxvideo.com'); GM_xmlhttpRequest({ method: "GET", url, onload: (res) => resolve(new DOMParser().parseFromString(res.responseText, "text/html")), onerror: (err) => reject(err) }); }); } fetchUrlContent(url) { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "GET", url, onload: (res) => resolve(res.responseText), onerror: (err) => reject(err) }); }); } async getAllUserMessageContents() { const cachedPosts = this.loadUserPostsFromCache(); let pagePosts = this.parseMessagesFromDocument(document); let prevPagePosts = []; if (this.currentPage > 1) { try { const prevPageDoc = await this.fetchApiPageContent(this.currentPage - 1); prevPagePosts = this.parseMessagesFromDocument(prevPageDoc, true); } catch (e) { console.error("JVC Enhancer: Impossible de charger la page N-1.", e); } } return [...new Set([...cachedPosts, ...pagePosts, ...prevPagePosts])]; } parseMessagesFromDocument(doc, isApi = false) { const messages = []; const sel = { msg: isApi ? '.post' : '.bloc-message-forum', pseudo: isApi ? '.bloc-pseudo-msg' : '.bloc-pseudo-msg', content: isApi ? '.message' : '.txt-msg' }; doc.querySelectorAll(sel.msg).forEach(msg => { if (msg.querySelector(sel.pseudo)?.textContent.trim() === this.currentUser) { const contentElement = msg.querySelector(sel.content); if (contentElement) { const clone = contentElement.cloneNode(true); clone.querySelectorAll('blockquote.blockquote-jv').forEach(bq => bq.remove()); const ownText = this.normalizeText(clone.textContent); if (ownText) messages.push(ownText); } } }); return messages; } // --- Fonctions de Cache et d'Événements --- addPostListener() { const postButton = document.querySelector('.postMessage'); if (postButton) { postButton.addEventListener('click', () => { const messageTextarea = document.querySelector('#message_topic, .messageEditor__edit'); if (messageTextarea && messageTextarea.value && this.topicId) { this.saveUserPostToCache(this.normalizeText(messageTextarea.value)); } }, true); } } saveUserPostToCache(normalizedText) { try { const cache = JSON.parse(localStorage.getItem(this.CACHE_KEY_POSTS)) || {}; if (!cache[this.topicId]) cache[this.topicId] = []; cache[this.topicId].unshift(normalizedText); cache[this.topicId] = cache[this.topicId].slice(0, this.MAX_CACHED_POSTS_PER_TOPIC); localStorage.setItem(this.CACHE_KEY_POSTS, JSON.stringify(cache)); } catch (e) { console.error("JVC Enhancer: Erreur de sauvegarde du cache.", e); } } loadUserPostsFromCache() { try { const cache = JSON.parse(localStorage.getItem(this.CACHE_KEY_POSTS)) || {}; return cache[this.topicId] || []; } catch (e) { console.error("JVC Enhancer: Erreur de lecture du cache.", e); return []; } } // --- Logique de Surlignage --- isUserMentioned(author, el) { if (!this.currentUser || author === this.currentUser) return false; const content = el.querySelector('.txt-msg'); if (!content) return false; const normText = this.normalizeText(content.textContent); if (normText.includes(this.normalizeText(this.currentUser))) return true; for (const quote of el.querySelectorAll('blockquote.blockquote-jv')) { const cleanQuote = this.normalizeText(quote.textContent.replace(/^Le .+? :/s, '')); if (cleanQuote && this.currentUserMessages.some(msg => cleanQuote.includes(msg))) return true; } return false; } normalizeText(text) { return text ? text.toLowerCase().replace(/\s+/g, ' ').trim() : ''; } getCurrentUsername() { return document.querySelector('.headerAccount__pseudo')?.textContent.trim() || null; } injectStyles() { const styles = ` /* Surlignages Importants */ .jvc-enhancer-mention { background-color: rgba(230, 195, 92, 0.07); border-left: 2px solid rgba(230, 195, 92, 0.75); } .jvc-enhancer-op-mention { background-color: rgba(157, 105, 212, 0.07); border-left: 2px solid rgba(157, 105, 212, 0.75); } /* Surlignages Discrets */ .jvc-enhancer-self { box-shadow: inset 0 0 0 1px rgba(128, 128, 128, 0.2); } html:not(.theme-light) .jvc-enhancer-self { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1); } .jvc-enhancer-pemt { border-right-width: 2px; border-right-style: solid; } /* Surlignages pour DDB */ .jvc-enhancer-ddb-reported { background-color: rgba(220, 53, 69, 0.07) !important; } .jvc-enhancer-ddb-administered { background-color: rgba(25, 135, 84, 0.07) !important; } /* Styles des Badges */ .bloc-avatar-msg { position: relative; } .jvc-enhancer-avatar-badge { position: absolute; bottom: -12px; left: 50%; transform: translateX(-50%); z-index: 2; padding: 2px 6px; font-size: 9px; font-weight: bold; border-radius: 5px; white-space: nowrap; text-transform: uppercase; letter-spacing: 0.5px; backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); border: 1px solid rgba(255, 255, 255, 0.1); box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); } .badge-mention { background-color: rgba(230, 195, 92, 0.4); color: #212529; } .badge-op-mention { background-color: rgba(157, 105, 212, 0.4); color: white; } .badge-op, .badge-self, .badge-pemt { background-color: rgba(80, 80, 80, 0.5); color: rgba(255, 255, 255, 0.8); } `; const styleSheet = document.createElement("style"); styleSheet.innerText = styles; document.head.appendChild(styleSheet); } processMessages() { const messages = Array.from(document.querySelectorAll('.bloc-message-forum')); messages.forEach(el => { const author = el.querySelector('.bloc-pseudo-msg')?.textContent.trim(); if (!author) return; const isOp = this.highlightRules[0].condition(author); const isMention = this.highlightRules[1].condition(author, el); const isSelf = this.highlightRules[2].condition(author); let hClass = '', bText = '', bClass = ''; if (isSelf) { hClass = 'jvc-enhancer-self'; bText = 'VOUS'; bClass = 'badge-self'; } else if (isOp && isMention) { hClass = 'jvc-enhancer-op-mention'; bText = 'OP (CITÉ)'; bClass = 'badge-op-mention'; } else if (isOp) { hClass = 'jvc-enhancer-op'; bText = 'OP'; bClass = 'badge-op'; } else if (isMention) { hClass = 'jvc-enhancer-mention'; bText = 'CITÉ'; bClass = 'badge-mention'; } if (hClass) el.classList.add(hClass); if (bText) this.createAvatarBadge(el, bText, bClass); }); this.processPEMT(messages); } processPEMT(messages) { let pemtGroupIndex = 0; for (let i = 0; i < messages.length - 1; i++) { const time = messages[i].querySelector('.bloc-date-msg a')?.textContent.match(/\d{2}:\d{2}:\d{2}$/)?.[0]; if (!time) continue; const group = [messages[i]]; for (let j = i + 1; j < messages.length; j++) { if (messages[j].querySelector('.bloc-date-msg a')?.textContent.match(/\d{2}:\d{2}:\d{2}$/)?.[0] === time) { group.push(messages[j]); } else { break; } } if (group.length > 1) { const color = this.pemtColors[pemtGroupIndex % this.pemtColors.length]; group.forEach(msg => { msg.classList.add('jvc-enhancer-pemt'); msg.style.borderRightColor = color; if (!msg.querySelector('.jvc-enhancer-avatar-badge')) { this.createAvatarBadge(msg, 'PEMT', 'badge-pemt'); } }); pemtGroupIndex++; i += group.length - 1; } } } createAvatarBadge(el, text, bClass, color = null) { if (el.querySelector(`.jvc-enhancer-avatar-badge`)) return; const container = el.querySelector('.bloc-avatar-msg'); if (!container) return; const badge = document.createElement('span'); badge.className = `jvc-enhancer-avatar-badge ${bClass}`; badge.textContent = text; if (color) badge.style.backgroundColor = `${color}66`; container.appendChild(badge); } async checkFirstMessagesReportStatus() { if (this.currentPage !== 1) return; const firstTwoMessages = Array.from(document.querySelectorAll('.bloc-message-forum')).slice(0, 2); const ddbCache = JSON.parse(sessionStorage.getItem(this.CACHE_KEY_DDB)) || {}; for (const messageElement of firstTwoMessages) { const reportIcon = messageElement.querySelector('.picto-msg-exclam'); const messageId = messageElement.dataset.id; if (!reportIcon || !messageId) continue; if (ddbCache[messageId]) { this.applyDdbHighlight(messageElement, ddbCache[messageId]); continue; } const selectorUrl = reportIcon.dataset.selector; if (!selectorUrl) continue; const reportUrl = new URL(selectorUrl, "https://www.jeuxvideo.com").href; try { const responseText = await this.fetchUrlContent(reportUrl); let status = 'clean'; //Vous avez déjà signalé ce contenu if ((responseText.includes("Ce contenu a déjà été signalé")) || (responseText.includes("Vous avez déjà signalé ce contenu"))){ status = 'reported'; } else if (responseText.includes("Ce contenu a déjà été modéré")) { status = 'administered'; } if (status !== 'clean') { ddbCache[messageId] = status; this.applyDdbHighlight(messageElement, status); } } catch (error) { console.error(`JVC Enhancer: Erreur DDB pour msg ${messageId}`, error); } } sessionStorage.setItem(this.CACHE_KEY_DDB, JSON.stringify(ddbCache)); } applyDdbHighlight(messageElement, status) { // Ne supprime que les classes de fond pour éviter les conflits messageElement.classList.remove('jvc-enhancer-mention', 'jvc-enhancer-op-mention'); if (status === 'reported') { messageElement.classList.add('jvc-enhancer-ddb-reported'); } else if (status === 'administered') { messageElement.classList.add('jvc-enhancer-ddb-administered'); } } } new JVCTopicEnhancer(); })();