您需要先安装一个扩展,例如 篡改猴、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 less messages are shown
- 'SPACE_DIVIDER': 20,
- // A higher number means more message space
- 'HEIGHT_MULTIPLIER': 0.91
- };
- const FILTER = [
- {
- 'streamer': /^/,
- 'author': /$./,
- // Filters out non-Japanese messages (allows 'w' (笑))
- 'message': /[abcdefghijklmnopqrstuvxyz]/i,
- 'requireBadge': true,
- 'limit': 1000,
- 'stopOnHover': true
- }
- ];
- (() => {
- if (window.frameElement.id !== 'chatframe') {
- return;
- }
- const {clientHeight} = window.document.body;
- const spaces = Math.floor(clientHeight / CONFIG.SPACE_DIVIDER);
- (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 * CONFIG.HEIGHT_MULTIPLIER}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 showPost(post) {
- 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;
- }
- function acceptPost(post = queuedPost) {
- if (!post) {
- return;
- }
- if (doQueue || (filter.stopOnHover && hovered)) {
- queuedPost = post;
- } else {
- showPost(post);
- }
- }
- // 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;
- /** 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}
- );
- };
- })();