您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Filters messages in YouTube stream chat.
当前为
// ==UserScript== // @name YouTube Chat Filter // @namespace https://greasyfork.org/users/696211-ctl2 // @version 0.1 // @description Filters messages in YouTube stream chat. // @author Callum Latham // @match *://www.youtube.com/* // @match *://youtube.com/* // @grant none // ==/UserScript== (() => { if (window.frameElement.id !== 'chatframe') { return; } const FILTER = [ { 'streamer': /^/, 'author': /$./, 'message': /[abcdefghijklmnopqrstuvxyz]/i, 'requireBadge': true, 'limit': 1000, 'stopOnHover': true } ]; const {clientHeight} = window.document.body; const spaces = Math.floor(clientHeight / 20); (function style() { const addStyle = (sheet, selector, rules) => { const ruleString = rules.map( ([selector, rule]) => `${selector}:${typeof rule === 'function' ? rule() : rule};` ); sheet.insertRule(`${selector}{${ruleString.join('')}}`); }; const styleElement = document.createElement('style'); const {sheet} = document.head.appendChild(styleElement); const styles = [ ['#item-offset', [ ['height', `${clientHeight * 0.91}px`] ]], ['#items:not(.cf)', [ ['display', 'none'] ]], ['#items.cf > :nth-child(even)', [ ['background-color', '#1f1f1f'] ]] ]; for (const style of styles) { addStyle(sheet, style[0], style[1]); } })(); window.onload = async () => { const filter = (() => { const streamer = parent.document.querySelector('#meta').querySelector('#channel-name').innerText; for (const {'streamer': regex, ...filter} of FILTER) { if (regex.test(streamer)) { return filter; } } })(); // Terminate if there's no filter to apply if (!filter) { return; } const chatElements = {'held': document.body.querySelector('#chat').querySelector('#items')}; chatElements.accepted = chatElements.held.cloneNode(false); chatElements.accepted.classList.add('cf'); chatElements.held.parentElement.appendChild(chatElements.accepted); let queuedPost; let doQueue = false; let hovered = false; function acceptPost(post = queuedPost) { if (!post) { return; } const doDelay = (doQueue || (filter.stopOnHover && hovered)); if (doDelay) { queuedPost = post; } else { const container = chatElements.accepted; container.appendChild(post); // Save memory by deleting passed posts while (container.children.length > spaces) { container.firstChild.remove(); } doQueue = true; queuedPost = undefined; } } // Unqueue at regular intervals window.setInterval(() => { doQueue = false; acceptPost(); }, filter.limit); window.document.body.addEventListener('mouseenter', () => { hovered = true; }); window.document.body.addEventListener('mouseleave', () => { hovered = false; acceptPost(); }); function processPost(post) { chatElements.held.parentElement.style.removeProperty('height'); try { const isValid = !( filter.author.test(post.querySelector('#author-name').textContent) || filter.message.test(post.querySelector('#message').textContent) || (filter.requireBadge && !post.querySelector('#chat-badges').hasChildNodes()) ); if (isValid) { acceptPost(post); } else { // Save memory by deleting rejected posts post.remove(); } } catch (e) { console.group('STRANGE POST'); console.warn(post); console.warn(e); console.groupEnd(); } } new MutationObserver((mutations) => { for (const {addedNodes} of mutations) { addedNodes.forEach(processPost); } }).observe( chatElements.held, {childList: true} ); }; })();