11// ==UserScript==
22// @name Hide Bot Comments
33// @namespace https://theusaf.org
4- // @version 1.6.3
4+ // @version 1.7.0
55// @description Removes comments made by bots on websites such as YouTube.
66// @author theusaf
77// @match https://www.youtube.com/**
8+ // @match https://www.facebook.com/plugins/comments.php*
9+ // @match https://www.facebook.com/plugins/feedback.php*
810// @copyright 2022 theusaf
911// @license MIT
1012// @grant none
1113// ==/UserScript==
1214
1315const SITES = Object . freeze ( {
14- YOUTUBE : [
15- // starts with too much whitespace
16- / ^ \s { 2 , } / ,
17- // only links and other punctuation
18- / ^ ( \s * @ .+ ) ? \s * ( h t t p s : \/ \/ [ ^ \s ] + ) ( h t t p s : \/ \/ [ ^ \s ] + | \n .\s ] ) + $ / ,
19- // all caps and a link
20- / ^ ( \s * @ .+ ) ? \s * [ A - Z \s \r \n ! ] * h t t p s : \/ \/ [ ^ \s ] + [ A - Z \s \r \n ! ] * $ / ,
21- // A link and a random message afterwards
22- / ^ ( \s * @ .+ ) ? \s * h t t p s : \/ \/ [ ^ \s ] + ( \n | .| \s ) * ( I t ' l l b l o w y o u r m i n d \. | [ d D ] o n ' ? t [ m M ] i s s | B o t s f o r u | F i n a l l y | 💜 | f a x | o n l y u n t i l | B o t s a r e | : ] | I f o u n d i t : | D o n o t m i s s t h i s | : \) | Y e [ s p ] ¤ ? ( t r u e | e x a c t l y ) | ( ...? $ ) ) / i,
23- // word + link
24- / ^ ( \s * @ .+ ) ? \s * ( T h i s | [ W w ] o w ! ? ) \s * h t t p s : \/ \/ [ ^ \s ] + / ,
25- // phrase + line + link
26- / ( F i n a l l y i t ' s h e r e \. ? | d e c e i v e s .* s u b s c r i b e r s : \. { 1 , } | [ \u0401 \u0451 \u0410 - \u044f , . : ] { 15 , } .* | E X P O S E D : | I S F R E A K ! | I S G A R B A G E ! { 1 , } | s h o c k i n g t r u t h .* | h i s s u b s c r i b e r s .* | w i l l s t o p w a t c h i n g .* | y e s \. ? | T H E G A M E .* | A f t e r w a t c h i n g t h i s v i d e o y o u w i l l n e v e r l o v e .* ) ( \n | \s ) ( \n | .) * h t t p s : \/ \/ [ ^ \s ] + / ,
27- // link + random "word"
28- / ^ ( \s * @ .+ ) ? \s * h t t p s : \/ \/ [ ^ \s ] + \s * [ a - z ] + \s * $ / ,
29- // link with a star at the end??
30- / h t t p s : \/ \/ y o u t u .b e \/ \w + \* / ,
31- // ...
32- / P R I V A T E S \* X | o v e r 1 8 | A n n a i s a b e a u t i f u l g i r l / i,
33- // suspicious websites
34- / b e a u t y z o n e \. \w + | \. c a m | l u s t \. \w + | \. h o s t | a s i a n \w * \. \w + | \w * t e e n \. \w + / i,
35- // too many "-"
36- / - { 5 , } / ,
37- // single, somewhat strange word
38- / ^ ( H i i | Y e | B r u h h | A a w w w ? ) $ / ,
39- // common phrase
40- / ( ● ´ ω ` ● ) ✨ 💕 | I c a n r e a d y o u m i n d b r o t h e r | S P E C I A L F O R Y O U | l 1 k e m y v 1 d e o | s m a l l c h a n n e l t r y i n g t o g r o w | Y o u T \* b e r | M Y C O N T E N T | M y v i d e o | p e d o p h i l e 😱 | M Y W O R L D R E C O R D | ( ^ Y e s .{ 0 , 5 } $ ) | s a i d t h i s t o a f a n | R e a d m y n a m e | [ M m ] y m o m .* s u b s c r i b e r s | l i t e r a l l y b e g g i n g | M Y V I D E O S ? | m y p l a y l i s t | f u c k i n g c r i n g e | [ D d ] [ O o ] [ N n ] ' ? [ T t ] r e a d m y n a m e / ,
41- // replies to bots
42- / @ D o n ' ? t r e a d m y | ^ ( r o ) ? b o t + $ / i,
43- // upside down chars
44- / [ ㄥ ϛ ㄣ Ɛ ᄅ Ɩ ⅄ Λ ∩ ┴ ɹ Ԁ ˥ ʞ ſ פ Ⅎ Ǝ Ɔ ∀ ʎ ʍ ʌ ʇ ɹ ɯ ʞ ɾ ᴉ ɥ ƃ ɟ ǝ ɔ ɐ ] / ,
45- // just a single, weird character
46- / ^ .$ / ,
47- ( text ) => {
48- const charSets = [
49- {
50- regex : / [ \u{fe27} - \u{fe2f} \u{1df5} - \u{1dff} \u{1dc0} - \u{1de6} \u{1ab0} - \u{1abe} \u{0300} - \u{0333} \u{0339} - \u{033f} \u{0346} - \u{034a} \u{034b} - \u{034e} \u{0350} - \u{0357} \u{0358} - \u{035b} ] / gu, // weird combining characters
51- matchPercent : 0.4
52- } ,
53- {
54- regex : / [ ᴀ ʙ ᴄ ᴅ ᴇ ғ ɢ ʜ ɪ ᴊ ᴋ ʟ ᴍ ɴ ᴏ ᴘ ᴏ ̨ ʀ s ᴛ ᴜ ᴠ ᴡ x ʏ ᴢ \s ] / g,
55- matchPercent : 0.5
56- } ,
57- {
58- regex : / [ \u{1D538} - \u{1D56B} \u{1D400} - \u{1D433} ] / gu, // math letter symbols
59- matchPercent : 0.3
60- } ,
61- ] ;
62- for ( const check of charSets ) {
63- const { regex, matchPercent } = check ,
64- matches = text . match ( regex ) ?. length ?? 0 ;
65- if ( matches / text . length > matchPercent && text . length > 10 ) {
66- return true ;
16+ YOUTUBE : {
17+ checks : [
18+ // starts with too much whitespace
19+ / ^ \s { 2 , } / ,
20+ // only links and other punctuation
21+ / ^ ( \s * @ .+ ) ? \s * ( h t t p s : \/ \/ [ ^ \s ] + ) ( h t t p s : \/ \/ [ ^ \s ] + | \n .\s ] ) + $ / ,
22+ // all caps and a link
23+ / ^ ( \s * @ .+ ) ? \s * [ A - Z \s \r \n ! ] * h t t p s : \/ \/ [ ^ \s ] + [ A - Z \s \r \n ! ] * $ / ,
24+ // A link and a random message afterwards
25+ / ^ ( \s * @ .+ ) ? \s * h t t p s : \/ \/ [ ^ \s ] + ( \n | .| \s ) * ( I t ' l l b l o w y o u r m i n d \. | [ d D ] o n ' ? t [ m M ] i s s | B o t s f o r u | F i n a l l y | 💜 | f a x | o n l y u n t i l | B o t s a r e | : ] | I f o u n d i t : | D o n o t m i s s t h i s | : \) | Y e [ s p ] ¤ ? ( t r u e | e x a c t l y ) | ( ...? $ ) ) / i,
26+ // word + link
27+ / ^ ( \s * @ .+ ) ? \s * ( T h i s | [ W w ] o w ! ? ) \s * h t t p s : \/ \/ [ ^ \s ] + / ,
28+ // phrase + line + link
29+ / ( F i n a l l y i t ' s h e r e \. ? | d e c e i v e s .* s u b s c r i b e r s : \. { 1 , } | [ \u0401 \u0451 \u0410 - \u044f , . : ] { 15 , } .* | E X P O S E D : | I S F R E A K ! | I S G A R B A G E ! { 1 , } | s h o c k i n g t r u t h .* | h i s s u b s c r i b e r s .* | w i l l s t o p w a t c h i n g .* | y e s \. ? | T H E G A M E .* | A f t e r w a t c h i n g t h i s v i d e o y o u w i l l n e v e r l o v e .* ) ( \n | \s ) ( \n | .) * h t t p s : \/ \/ [ ^ \s ] + / ,
30+ // link + random "word"
31+ / ^ ( \s * @ .+ ) ? \s * h t t p s : \/ \/ [ ^ \s ] + \s * [ a - z ] + \s * $ / ,
32+ // link with a star at the end??
33+ / h t t p s : \/ \/ y o u t u .b e \/ \w + \* / ,
34+ // ...
35+ / P R I V A T E S \* X | o v e r 1 8 | A n n a i s a b e a u t i f u l g i r l / i,
36+ // suspicious websites
37+ / b e a u t y z o n e \. \w + | \. c a m | l u s t \. \w + | \. h o s t | a s i a n \w * \. \w + | \w * t e e n \. \w + / i,
38+ // too many "-"
39+ / - { 5 , } / ,
40+ // single, somewhat strange word
41+ / ^ ( H i i | Y e | B r u h h | A a w w w ? ) $ / ,
42+ // common phrase
43+ / ( ● ´ ω ` ● ) ✨ 💕 | I c a n r e a d y o u m i n d b r o t h e r | S P E C I A L F O R Y O U | l 1 k e m y v 1 d e o | s m a l l c h a n n e l t r y i n g t o g r o w | Y o u T \* b e r | M Y C O N T E N T | M y v i d e o | p e d o p h i l e 😱 | M Y W O R L D R E C O R D | ( ^ Y e s .{ 0 , 5 } $ ) | s a i d t h i s t o a f a n | R e a d m y n a m e | [ M m ] y m o m .* s u b s c r i b e r s | l i t e r a l l y b e g g i n g | M Y V I D E O S ? | m y p l a y l i s t | f u c k i n g c r i n g e | [ D d ] [ O o ] [ N n ] ' ? [ T t ] r e a d m y n a m e / ,
44+ // replies to bots
45+ / @ D o n ' ? t r e a d m y | ^ ( r o ) ? b o t + $ / i,
46+ // upside down chars
47+ / [ ㄥ ϛ ㄣ Ɛ ᄅ Ɩ ⅄ Λ ∩ ┴ ɹ Ԁ ˥ ʞ ſ פ Ⅎ Ǝ Ɔ ∀ ʎ ʍ ʌ ʇ ɹ ɯ ʞ ɾ ᴉ ɥ ƃ ɟ ǝ ɔ ɐ ] / ,
48+ // just a single, weird character
49+ / ^ .$ / ,
50+ ( text ) => {
51+ const charSets = [
52+ {
53+ regex : / [ \u{fe27} - \u{fe2f} \u{1df5} - \u{1dff} \u{1dc0} - \u{1de6} \u{1ab0} - \u{1abe} \u{0300} - \u{0333} \u{0339} - \u{033f} \u{0346} - \u{034a} \u{034b} - \u{034e} \u{0350} - \u{0357} \u{0358} - \u{035b} ] / gu, // weird combining characters
54+ matchPercent : 0.4
55+ } ,
56+ {
57+ regex : / [ ᴀ ʙ ᴄ ᴅ ᴇ ғ ɢ ʜ ɪ ᴊ ᴋ ʟ ᴍ ɴ ᴏ ᴘ ᴏ ̨ ʀ s ᴛ ᴜ ᴠ ᴡ x ʏ ᴢ \s ] / g,
58+ matchPercent : 0.5
59+ } ,
60+ {
61+ regex : / [ \u{1D538} - \u{1D56B} \u{1D400} - \u{1D433} ] / gu, // math letter symbols
62+ matchPercent : 0.3
63+ } ,
64+ ] ;
65+ for ( const check of charSets ) {
66+ const { regex, matchPercent } = check ,
67+ matches = text . match ( regex ) ?. length ?? 0 ;
68+ if ( matches / text . length > matchPercent && text . length > 10 ) {
69+ return true ;
70+ }
6771 }
6872 }
73+ ]
74+ } ,
75+ FACEBOOK_EMBED : {
76+ checks : [
77+ // "Easy cash" scams
78+ / e a s y c a s h | w o r k o n l i n e /
79+ ] ,
80+ options : {
81+ initialScan : ( ) => {
82+ return document . querySelectorAll ( ".clearfix" ) ;
83+ }
6984 }
70- ]
85+ }
7186 } ) ,
7287 site = getCurrentSite ( ) ,
7388 commentMutationListener = new MutationObserver ( ( mutations ) => {
@@ -95,8 +110,8 @@ commentMutationListener.observe(document.body, {
95110 * @param {Object } site The website the comment is from
96111 * @return {Boolean }
97112 */
98- function isCommentLikelyBotComment ( text , siteChecks ) {
99- for ( const check of siteChecks ) {
113+ function isCommentLikelyBotComment ( text , site ) {
114+ for ( const check of site . checks ) {
100115 if ( typeof check === "function" ) {
101116 if ( check ( text ) ) {
102117 console . log ( "Filter Check Failed" ) ;
@@ -122,6 +137,21 @@ function getCommentText(node, site) {
122137 if ( node . nodeName === "YTD-COMMENT-RENDERER" ) {
123138 return node . querySelector ( "#content-text" ) . textContent ;
124139 }
140+ break ;
141+ }
142+ case SITES . FACEBOOK_EMBED : {
143+ if ( node . classList ?. contains ( "clearfix" ) ) {
144+ try {
145+ return node ?. lastElementChild
146+ . lastElementChild
147+ . lastElementChild
148+ . firstElementChild
149+ . children [ 1 ]
150+ . textContent ;
151+ } catch ( err ) {
152+ return null ;
153+ }
154+ }
125155 }
126156 }
127157 return null ;
@@ -132,5 +162,20 @@ function getCurrentSite() {
132162 case "www.youtube.com" : {
133163 return SITES . YOUTUBE ;
134164 }
165+ case "www.facebook.com" : {
166+ return SITES . FACEBOOK_EMBED ;
167+ }
168+ }
169+ }
170+
171+ if ( site . options ?. initialScan ) {
172+ const items = site . options . initialScan ( ) ;
173+ for ( const node of items ) {
174+ const text = getCommentText ( node , site ) ;
175+ if ( text ) {
176+ if ( isCommentLikelyBotComment ( text , site ) ) {
177+ node . style . display = "none" ;
178+ }
179+ }
135180 }
136181}
0 commit comments