// ==UserScript==
// @name Facebook remove suggested sponsored ads blocks
// @version 1.20.12
// @description Remove suggested/sponsored blocks from Facebook
// @author Sly_North
// @match https://www.facebook.com/*
// @exclude https://www.facebook.com/*/about
// @exclude https://www.facebook.com/login/*
// @exclude https://www.facebook.com/groups/*
// @exclude https://www.facebook.com/privacy/*
// @exclude https://www.facebook.com/photo/*
// @exclude https://www.facebook.com/settings/*
// @exclude https://www.facebook.com/marketplace/*
// @exclude https://www.facebook.com/*/about
// @exclude https://www.facebook.com/*/photos
// @exclude https://www.facebook.com/*/friends
// @namespace https://greasyfork.org/en/users/759669-sly-north
// @license MIT
// @grant none
// @icon https://www.facebook.com/favicon.ico
// @run-at document-start
// ==/UserScript==
console.log('Start RemoveAllSponsored Facebook');
const maxPostHeight = 1000;
// Rebuild texts that are scrambled, like "Sponsored" where each letter is in a different div, which are not present in the word letter order.
function getVisibleContent(e) {
var t = e.innerText.replaceAll("\n","");
var children = e.childNodes;
while (children.length == 1) children = children[0].childNodes;
var spanBottom = e.getBoundingClientRect().bottom;
children = Array.from(children).filter((c) => c.getBoundingClientRect && c.getBoundingClientRect().top <= spanBottom);
var a = [];
for (var c of children) {
var order = getComputedStyle(c).order;
if (order && window.getComputedStyle(c).display !== 'none') {
a[order] = c.innerText;
// console.log(c.style.order,'=',c.innerText, ' y=',c.getBoundingClientRect().top,' vs span.bottom=', spanBottom);
}
}
if (a.length == 0) a = t.split();
var intext = a.join().replaceAll(",","").replaceAll("\n","");
// if (a.length > 0) console.log('Array = ', intext, ' -OR- ', a.join().replaceAll(",","").replaceAll("\n",""));
if (intext == "") intext = t;
return intext;
}
function getWholePost(e, maxParentHeightDiff = 150) {
let parent = e.parentElement.parentElement.parentElement.parentElement;
let h = parent.getBoundingClientRect().height;
if (h > maxPostHeight) return null;
while (h < 90) {
parent = parent.parentElement;
h = parent.getBoundingClientRect().height;
}
let h2 = 0;
const postMaxWidth = window.innerWidth*0.8;
while (true) {
if (!parent.parentElement) { console.warn('Err: element has no parent H=', parent.getBoundingClientRect().height); break; }
const parentBR = parent.parentElement.getBoundingClientRect();
h2 = parentBR.height;
if (h2 > maxPostHeight || h2 - h > maxParentHeightDiff) break;
if (parentBR.width > postMaxWidth && parentBR.height > window.innerHeight/2) {
const br = e.getBoundingClientRect();
console.log('- Fb ads - Could not find parent, was selecting whole screen from elt tag=', e.tagName, ' w=', br.width, ' h=', br.height);
e.style.display = "block"; // Prevent this script from running again on this element.
return null;
}
parent = parent.parentElement;
h = h2;
}
return parent;
}
function removeElement(type, e, parent) {
const height = parent.getBoundingClientRect().height;
if (height === 0 || height > maxPostHeight) {
console.log('- Fb ads - could not find parent for ', type, ' tag= ', parent.tagName, ' H=', height, ' ', e.innerText);
return;
}
console.log('- Fb ads ', type, ' tag= ', parent.tagName, ' H=', height, ' ',
parent.innerText.replaceAll("\n"," ").replaceAll(/Facebook *Facebook */g, ""), ' from ', e.innerText);
e.style.display = "none";
parent.style.display = "none";
// e.style.display = "block"; parent.style.display = "block"; parent.style.background = "red"; // Debug - in red instead of hidden
}
function RemoveAllSponsored()
{
setTimeout(RemoveAllSponsored, 750);
// Remove top right corner ads
for (let e of Array.from(document.getElementsByTagName('h3')).filter((e) => {
const br = e.getBoundingClientRect();
return br.top < 150 && br.left > window.innerWidth*0.6 && br.width > 200 && br.width < 500 && br.height > 10 && br.height < 100;
})) {
let parent = e.parentElement.parentElement.parentElement;
while (parent.parentElement.getBoundingClientRect().height < 500) parent = parent.parentElement;
if (parent && parent.getBoundingClientRect().height > 200) {
console.log('- Removing Fb top right ads - bounding rect: ', parent.getBoundingClientRect());
// parent.style.background = 'red';
parent.innerHTML = "";
}
}
// Remove the "suggestion" posts
if (document.URL.match(/facebook.com\/*(\?.*)*/)) {
for (tag of ['a', 'use']) {
const maybeAds = Array.from(document.getElementsByTagName(tag)).filter(e => {
const br = e.getBoundingClientRect();
return !e.style.display && // Already filtered-out
// e.innerText === '' && // Content must be hidden in shadow block
br.left < window.innerWidth*0.7 && // Comment in photo view
br.left > window.innerWidth/2 && br.width > 60 && br.width < 200 && br.top > 100;
});
for (let e of maybeAds) {
const parent = getWholePost(e);
if (!parent) { console.log(' - Fb ads sponsored element: parent element not found!'); continue; }
if (parent.innerText.match(/Create new account/) || parent.innerText.match(/shared a memory/)) continue;
removeElement('sponsored post', e, parent);
}
}
// "Learn more" suggestions
const maybeAds = Array.from(document.getElementsByTagName('span')).filter(e => e.textContent === 'Learn more');
for (let e of maybeAds) {
const parent = getWholePost(e);
if (!parent) { console.log(' - Fb ads sponsored element: parent element not found!'); continue; }
removeElement('learn more', e, parent);
}
}
// Unwanted elements
var elts = Array.from(document.getElementsByTagName('span'));
elts = elts.filter((e) => {var br = e.getBoundingClientRect(); return !e.style.display && br.bottom >= 0 && br.top <= window.innerHeight + 1000 && !e.style.display});
elts = elts.filter((e) => {
const t = e.innerText;
const br = e.getBoundingClientRect();
if (br.height === 0) return false;
return t === 'Suggested for you' || t === 'Remember Password' || t === 'Reels and short videos' || t === 'Reels 和短视频' || t === 'Suggested for you' || t === 'People You May Know' ||
t.match(/groups you might like/) || t.match(/groups suggested just for you/) || t === 'Follow' || t === 'Join';
});
for (let e of elts) {
const parent = getWholePost(e);
if (!parent) { console.log(' - Fb ads/block remover: parent element not found!'); continue; }
const br = e.getBoundingClientRect();
const parentBr = parent.getBoundingClientRect();
if (br.height === 0 || parentBr.height > 1000 || br.top-parentBr.top > 500) { // Ignore post citing post
// console.log(' - Fb ads/block: NOT removing tag=', e.tagName, ' H=', e.getBoundingClientRect().height, ' parent tag= ', parent.tagName, 'H=', parent.getBoundingClientRect().height, ' ', parent.innerText.replaceAll("\n", " ").substring(0, 200));
continue;
}
removeElement('ads/block', e, parent);
}
// Old Style - rare but still appears from time to time.
var elts = Array.from(document.getElementsByTagName('span'));
elts = elts.filter((e) => {
var br = e.getBoundingClientRect();
return e.parentElement.tagName === 'SPAN' && br.bottom >= 0 && br.top <= window.innerHeight + 1000 && !e.style.display
});
const keywords = [ /Sponsored/,/Commandvit/, /Sponsori/,/Reklamo/, /Publicid/,/Gesponser/, /Patrocinado/,/sugerisdos/, /贊助/, /RememberPassword/];
var nbrSpans = elts.length;
for (var i = elts.length - 1; i >= 0; --i)
{
var e = elts[i];
var boundingRect = e.getBoundingClientRect();
if (boundingRect.width == 0 || boundingRect.height == 0) continue; // Not visible
var intext = getVisibleContent(e);
if (intext.length > 0) for (k of keywords) {
if (intext.match(k)) {
let parent = e.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement
.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement;
parent.style.display = "none";
e.style.display = "none";
++nbrRemovedAds;
console.log('- Removing Sponsored ads span', i, '[', parent.innerText.replaceAll("\n", " ").substring(0, 200), '] matching ', k, ' at ', intext);
break;
}
}
}
}
setTimeout(RemoveAllSponsored, 1000);