您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Blacklist images sur JVC.
当前为
// ==UserScript== // @name JVC Image Blacklist // @namespace http://tampermonkey.net/ // @version 1.0 // @description Blacklist images sur JVC. // @match https://www.jeuxvideo.com/* // @grant none // @license MIT // ==/UserScript== (function () { 'use strict'; const STORAGE_KEY = 'jvcImageBlacklist'; const PANEL_ID = 'jvc-image-blacklist-panel'; const TOGGLE_ID = 'jvc-image-blacklist-toggle'; const STYLE_ID = 'jvc-image-blacklist-style'; const EXCEPTIONS = ['https://risibank.fr/logo.png']; // ---------- helpers ---------- const cssEscape = (s) => (window.CSS && CSS.escape ? CSS.escape(s) : String(s).replace(/(["\\])/g, '\\$1')); const basenameOf = (url) => { if (!url) return ''; try { const u = new URL(url, location.href); return (u.pathname.split('/').pop() || '').split('?')[0]; } catch { // parfois alt contient une URL "brute" const p = url.split('/'); return (p[p.length - 1] || '').split('?')[0]; } }; const loadBlacklist = () => { try { const data = JSON.parse(localStorage.getItem(STORAGE_KEY)); if (!data) return []; // rétrocompat if (typeof data[0] === 'string') { return data.map((url) => ({ original: url, display: url, basename: basenameOf(url) })); } return data; } catch { return []; } }; const saveBlacklist = (list) => { localStorage.setItem(STORAGE_KEY, JSON.stringify(list)); updateCSS(list); updateToggle(list); }; const addToBlacklist = ({ original, display, basename }) => { if (EXCEPTIONS.includes(display) || EXCEPTIONS.includes(original)) return; const list = loadBlacklist(); if (list.some((it) => it.basename === basename)) return; list.push({ original, display, basename }); saveBlacklist(list); }; const removeFromBlacklist = (bn) => { saveBlacklist(loadBlacklist().filter((it) => it.basename !== bn)); }; // ---------- CSS de masquage (limité aux posts) ---------- function updateCSS(list) { const styleEl = document.getElementById(STYLE_ID); if (!list.length) { if (styleEl) styleEl.textContent = ''; return; } const base = `.conteneur-message img:not([data-blacklist-preview="true"])`; const selectors = list.flatMap((it) => { const bn = cssEscape(it.basename); const disp = cssEscape(it.display); return [ `${base}[src="${disp}"]`, `${base}[src*="${bn}"]`, `${base}[data-src="${disp}"]`, `${base}[data-src*="${bn}"]`, `${base}[alt*="${bn}"]`, `${base}[risibank-original-src*="${bn}"]`, ]; }).join(','); styleEl.textContent = `${selectors}{display:none !important; pointer-events:none !important;}`; } function createStyle() { if (!document.getElementById(STYLE_ID)) { const s = document.createElement('style'); s.id = STYLE_ID; document.head.appendChild(s); } } // ---------- Panneau ---------- function createPanel() { if (document.getElementById(PANEL_ID)) return; const panel = document.createElement('div'); panel.id = PANEL_ID; Object.assign(panel.style, { position: 'fixed', top: '160px', right: '12px', backgroundColor: '#1e1e1e', color: '#fff', padding: '10px', borderRadius: '8px', border: '1px solid #333', maxHeight: '380px', overflowY: 'auto', width: '360px', zIndex: 999999, fontSize: '13px', display: 'none', boxSizing: 'border-box', }); const title = document.createElement('div'); title.textContent = 'Images blacklistées'; title.style.fontWeight = '700'; title.style.marginBottom = '8px'; const content = document.createElement('div'); content.id = PANEL_ID + '-content'; Object.assign(content.style, { display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '10px', justifyContent: 'flex-start', boxSizing: 'border-box', }); panel.appendChild(title); panel.appendChild(content); document.body.appendChild(panel); } function createToggle() { if (document.getElementById(TOGGLE_ID)) return; const btn = document.createElement('button'); btn.id = TOGGLE_ID; btn.textContent = '🗑 Blacklist'; Object.assign(btn.style, { position: 'fixed', bottom: '18px', right: '18px', zIndex: 999999, padding: '8px 12px', backgroundColor: '#2d2d2d', color: '#eee', borderRadius: '8px', border: '1px solid #444', cursor: 'pointer', display: 'none', }); btn.onclick = () => { const p = document.getElementById(PANEL_ID); if (!p) return; p.style.display = (p.style.display === 'block') ? 'none' : 'block'; renderPanel(); }; document.body.appendChild(btn); } function updateToggle(list) { const t = document.getElementById(TOGGLE_ID); if (t) t.style.display = list.length ? 'block' : 'none'; } function renderPanel() { const content = document.getElementById(PANEL_ID + '-content'); if (!content) return; const list = loadBlacklist(); content.innerHTML = ''; if (!list.length) { content.textContent = 'Aucune image blacklistée.'; return; } list.forEach((it) => { const box = document.createElement('div'); Object.assign(box.style, { display: 'flex', flexDirection: 'column', alignItems: 'center', boxSizing: 'border-box', }); const img = document.createElement('img'); img.dataset.blacklistPreview = 'true'; img.src = it.display || it.original; if (img.src.includes('default.jpg') && it.original) img.src = it.original; // avatars Object.assign(img.style, { maxWidth: '100px', maxHeight: '90px', objectFit: 'contain', border: '1px solid #444', background: '#111', padding: '4px', boxSizing: 'border-box', pointerEvents: 'none', // impossible à re-blacklister/bloquer depuis le panneau }); const rm = document.createElement('button'); rm.textContent = 'Retirer'; Object.assign(rm.style, { marginTop: '6px', backgroundColor: '#8a2b2b', color: '#fff', border: 'none', borderRadius: '4px', padding: '4px 8px', cursor: 'pointer', fontSize: '12px', }); rm.onclick = () => { removeFromBlacklist(it.basename); renderPanel(); }; box.appendChild(img); box.appendChild(rm); content.appendChild(box); }); } // ---------- extraction d'URL ---------- function getOrig(img) { return img.dataset.src || img.getAttribute('risibank-original-src') || img.getAttribute('data-src') || img.alt || img.src; } function getDisp(img) { return img.dataset.src || img.currentSrc || img.getAttribute('data-src') || img.src; } // ---------- bouton & attachement ---------- function wrapImage(img) { if (img.closest('.smileys, .smileys__modal, .smileys__table')) return img.parentElement; // jamais wrapper le panneau d'émojis const wrapper = document.createElement('span'); wrapper.style.display = 'inline-block'; wrapper.style.position = 'relative'; img.parentNode.insertBefore(wrapper, img); wrapper.appendChild(img); return wrapper; } function attachButtons() { const list = loadBlacklist(); updateCSS(list); // set de basenames pour lookup rapide const banned = new Set(list.map((it) => it.basename)); document.querySelectorAll('.conteneur-message img').forEach((img) => { if (img.dataset.jvcBL) return; // ignorer images du panneau d'émojis et vignettes de panneau if (img.closest('.smileys, .smileys__modal, .smileys__table') || img.dataset.blacklistPreview === 'true') { img.dataset.jvcBL = '1'; return; } const display = getDisp(img) || ''; const original = getOrig(img) || ''; if (EXCEPTIONS.includes(display) || EXCEPTIONS.includes(original)) { img.dataset.jvcBL = '1'; return; } const bnOrig = basenameOf(original); const bnDisp = basenameOf(display); // --- masquage immédiat (lazy Noelshack / data-src) --- if (banned.has(bnOrig) || banned.has(bnDisp)) { img.style.display = 'none'; // masque tout de suite img.style.pointerEvents = 'none'; img.dataset.jvcBL = '1'; return; } // --- sinon on pose le bouton --- const wrapper = wrapImage(img); const btn = document.createElement('button'); btn.textContent = '⛔'; Object.assign(btn.style, { position: 'absolute', top: '4px', right: '4px', backgroundColor: 'rgba(0,0,0,0.55)', color: '#fff', border: 'none', borderRadius: '4px', fontSize: '12px', padding: '2px 6px', cursor: 'pointer', display: 'none', zIndex: 9999, lineHeight: '1', }); wrapper.addEventListener('mouseenter', () => { btn.style.display = 'block'; }); wrapper.addEventListener('mouseleave', () => { btn.style.display = 'none'; }); // clic sur ⛔ : empêcher toute ouverture + enregistrer btn.addEventListener('click', (e) => { e.preventDefault(); e.stopImmediatePropagation(); e.stopPropagation(); const link = img.closest('a'); if (link) { link.removeAttribute('href'); link.onclick = (ev) => { ev.preventDefault(); return false; }; } const bn = bnOrig || bnDisp || basenameOf(display || original); addToBlacklist({ original, display, basename: bn }); renderPanel(); }, { capture: true }); wrapper.appendChild(btn); img.dataset.jvcBL = '1'; }); } // ---------- boot ---------- function init() { createStyle(); createPanel(); createToggle(); updateCSS(loadBlacklist()); updateToggle(loadBlacklist()); attachButtons(); const obs = new MutationObserver(() => attachButtons()); obs.observe(document.body, { childList: true, subtree: true }); } init(); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址