您需要先安装一个扩展,例如 篡改猴、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== const CONFIG = { /** * A higher number means more message space. * A value of 1 will make the chat area as tall as the chat iframe's body. */ 'CHAT_HEIGHT': 2 }; const FILTER = [ { 'streamer': /^/, 'author': /$./, // Filters out non-Japanese messages (allows 'w' (笑)) 'message': /[abcdefghijklmnopqrstuvxyz]/i, 'requireBadge': true, 'queueTime': 1000, 'stopOnHover': true } ]; (() => { if (window.frameElement.id !== 'chatframe') { return; } (function style() { const addStyle = (sheet, selector, rules) => { const ruleString = rules.map( ([selector, rule]) => `${selector}:${typeof rule === 'function' ? rule() : rule} !important;` ); sheet.insertRule(`${selector}{${ruleString.join('')}}`); }; const styleElement = document.createElement('style'); const {sheet} = document.head.appendChild(styleElement); const styles = [ ['#item-offset', [ ['height', `${document.body.clientHeight * CONFIG.CHAT_HEIGHT}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 valid filter 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 trimPosts() { const chat = chatElements.accepted; const container = chat.parentElement; const {top} = container.getBoundingClientRect(); for (let topPost = chat.firstChild; topPost.getBoundingClientRect().top - top < 0; topPost = chat.firstChild) { topPost.remove(); } } function showPost(post) { const container = chatElements.accepted; container.appendChild(post); // Save memory by deleting passed posts trimPosts(); queuedPost = undefined; if (filter.queueTime > 0) { // Start queueing doQueue = true; window.setTimeout(() => { doQueue = false; // Unqueue acceptPost(); }, filter.queueTime); } } function acceptPost(post = queuedPost) { if (!post) { return; } if (doQueue || (filter.stopOnHover && hovered)) { queuedPost = post; } else { showPost(post); } } window.document.body.addEventListener('mouseenter', () => { hovered = true; }); window.document.body.addEventListener('mouseleave', () => { hovered = false; /** Unqueue iff: * - Nothing was queued at the most recent unqueue * - No posts have been shown since the last unqueue * - A post is queued */ acceptPost(); }); function processPost(post) { chatElements.held.parentElement.style.removeProperty('height'); try { if ( filter.author.test(post.querySelector('#author-name').textContent) || filter.message.test(post.querySelector('#message').textContent) || (filter.requireBadge && !post.querySelector('#chat-badges').hasChildNodes()) ) { // Save memory by deleting rejected posts post.remove(); } else { acceptPost(post); } } 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} ); }; })();