Hides sponsored posts in FB's news-feed (Sept 2021)
当前为
// ==UserScript==
// @name facebook - ad block v3
// @version 3.06
// @description Hides sponsored posts in FB's news-feed (Sept 2021)
// @author zbluebugz
// @match https://*.facebook.com/*
// @-icon https://www.google.com/s2/favicons?domain=facebook.com
// @-icon64URL https://www.google.com/s2/favicons?domain=facebook.com
// @run-at document-idle
// @namespace https://greasyfork.org/users/812551
// ==/UserScript==
/*
Comments:
original: https://pastebin.com/raw/vmaiA8jJ
05/09/2021: FB has changed the way sponsored posts are marked - made harder to detect
- this script detects the new way.
06/09/2021: Detected a couple of slight variations in how sponsored posts are marked
14/09/2021: Detected another slight variation in how sponsored posts are marked
14/09/2021: Fixed bug with getting textNode values.
18/09/2021: Detected another variation how sponsored posts are marked. Code detection rewritten.
*/
(function () {
'use strict';
var title = 'facebook - ad block';
// -- START KEYWORDS
// Keyword: Sponsored posts'
// - if more than one keyword, use this format: ['keyword 1', 'keyword 2']
var SPONSORED_WORDS = ['Sponsored'];
// Keyword: Sponsored like posts - (often flagged as sponsored posts - not all the time)
// var suggestions = ['Shop Now', 'Learn More', 'Sign Up', 'Download', 'Get Offer', 'Apply Now', 'Book Now', 'Play Game', 'Get Quote'];
// var suggestions = ['Shop Now', 'Sign Up', 'Download', 'Get Offer', 'Book Now', 'Play Game', 'Get Quote'];
var suggestions = [];
// Hide certain promotional elements ...
const TOGGLE_SUGGESTED_CONTENT = false;
const TOGGLE_SUGGESTED_EVENTS = false;
const TOGGLE_PEOPLE_YOU_MAY_KNOW = true;
const TOGGLE_SUGGESTED_PAGES = true ;
const TOGGLE_PAID_PARTNERSHIP = true;
const TOGGLE_SUGGESTED_GROUPS = false;
const TOGGLE_CREATE_ROOM = true;
// Keywords: text to find for certain promotional elements
if(TOGGLE_SUGGESTED_CONTENT) suggestions.push('Suggested for you');
if(TOGGLE_SUGGESTED_EVENTS) suggestions.push('Suggested Events');
if(TOGGLE_PEOPLE_YOU_MAY_KNOW) suggestions.push('People you may know');
if(TOGGLE_SUGGESTED_PAGES) suggestions.push('Suggested Pages');
if(TOGGLE_PAID_PARTNERSHIP) suggestions.push('Paid partnership');
if(TOGGLE_SUGGESTED_GROUPS) suggestions.push('Suggested groups');
// -- END KEYWORDS
// -- rest of code - no more keywords to adjust.
// hide or highlight the selected posts
let HIDE_STYLE = (true) ? 'display:none !important' : 'border:3px solid yellow !important';
// how often to run this script (milliseconds)
const CHECK_RATE_MS = 100;
function hide(el) {
return el.setAttribute('style',HIDE_STYLE);
}
function doChanges() {
if(TOGGLE_CREATE_ROOM){
var create_room = document.querySelector('div[data-pagelet="VideoChatHomeUnitNoDDD"]');
if(create_room) hide(create_room);
}
function findSponsoredPosts() {
// get collection of posts, ignore those already read by this script.
let posts = Array.from(
document.querySelectorAll('div[data-pagelet*=FeedUnit]:not([adbpr])')
// next line for use in debugging - ignores the posts that have been already processed.
//document.querySelectorAll('div[data-pagelet*=FeedUnit]')
);
// loop through each post to see if it is a sponsored one or not
let hidePosts = [];
let csr; // window.getComputedStyle(element) results
posts.forEach(
post => {
// flag this post as not to be read/processed again
post.setAttribute('adbpr', true);
// within this unread post, find the SPAN element(s) having aria-label = Sponsored
// (usually only one is found)
let alSpans = Array.from(post.querySelectorAll('span[aria-label="Sponsored"]'));
// is the word "Sponsored" visible?
// - there are several spans having single letters - all randomised, but will make up "sponsored" when certain span tags are "visible".
alSpans.forEach(sp => {
let daText = '';
// get the next sibling from the <span aria-label="Sponsored"></span>
let nsp = sp.nextSibling;
// note that this sibling is a "parent" ...
// .. sometimes it has a textNode (as firstChild) ...
if (nsp.tagName === "SPAN") {
if (nsp.firstChild.tagName === 'SPAN') {
// no immediate textNode (nothing to do)
}
else {
csr = window.getComputedStyle(nsp);
if (csr.position === 'relative' && csr.display === 'inline') {
// visible ... (need both styles)
// - ok, grab the textNode's value.
daText += nsp.firstChild.textContent ;
}
}
}
//console.info("--::", daText);
// the "parent" has childNodes (spans) ...
nsp = nsp.firstChild;
do {
if (nsp.tagName === 'SPAN') {
csr = window.getComputedStyle(nsp);
if (csr.position === 'relative' && csr.display === 'inline') {
// visible ... (need both styles)
// - ok, grab the textNode's value.
if (nsp.innerText.length === 1) {
daText += nsp.firstChild.textContent ;
}
}
}
nsp = nsp.nextSibling;
} while (nsp);
// console.info("--is Sponsored post:", daText, (SPONSORED_WORDS.indexOf(daText) > -1));
// do we hide this post?
if (SPONSORED_WORDS.indexOf(daText) > -1 ) {
hidePosts.push(sp);
}
});
// suggestions
if (suggestions) {
// scan the a tags
let els = Array.from(post.querySelectorAll('a'));
let skip = false;
for (let x = 0; x < els.length; x++) {
if (suggestions.includes(els[x].textContent)) {
hidePosts.push(els[x]);
skip = true;
break;
}
}
// scan the span tags
if (!skip) {
els = Array.from(post.querySelectorAll('span'));
for (let x = 0; x < els.length; x++) {
if (suggestions.includes(els[x].textContent)) {
hidePosts.push(els[x]);
break;
}
}
}
}
}
);
return hidePosts;
}
function kill(element) {
try {
if(element) {
var limit = 0;
while(limit++ < 100) {
if(typeof element.getAttribute('data-pagelet') == "string")
{
if(element.getAttribute('data-pagelet').contains('FeedUnit'))
{
hide(element);
return;
}
}
element = element.parentNode;
}
}
}
catch (e) {
}
};
findSponsoredPosts().forEach( e => kill(e) );
};
const callback = function () {
try {
doChanges();
} catch (e) {
console.warn(title, e);
}
};
setInterval(callback, CHECK_RATE_MS);
})();