// ==UserScript== // @name Facebook - Hides Suggested and Sponsored Posts // @namespace http://tampermonkey.net/ // @version 0.4 // @description Hides Suggested For You, sponsored posts on the main feed & those silly sponsored ads in Marketplace // @author ArthurG // @match https://www.facebook.com/* // @require https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js // @grant none // @downloadURL none // ==/UserScript== (function() { 'use strict'; const pollTimeout = 3000; const debounceTimeout = 2000; const debugHighlightAds = true; const obfuscationTextSizeLimit = 45; const debouncedFindAndHide = debounce(findAndHide, debounceTimeout, false); /** * Checks for the word in a set of random characters. Doesn't allow repeat of characters. * Taken from https://stackoverflow.com/questions/58323445/how-can-i-check-a-word-is-made-of-letters-in-different-array */ function isWordValid(attemptedWord, validLetters) { const validLettersSplitted = validLetters.split(""); const attemptedWordSplitted = attemptedWord.split(""); return attemptedWordSplitted.every(attemptedLetter => { const letterIndex = validLettersSplitted.indexOf(attemptedLetter); if(letterIndex > -1){ validLettersSplitted.splice(letterIndex, 1); return true; } else { return false } }); } function isWorthScrutinizing(el) { return $(el).text().length < obfuscationTextSizeLimit; } function cleanupObsucatingDom(el) { $(el).find('[style="display:none"]').remove(); $(el).find('[style="display:none;"]').remove(); $(el).find('[style="display: none;"]').remove() $(el).find('[style="display: none"]').remove(); $(el).find('[style*="position:absolute"]').remove(); $(el).find('[style*="position:absolute;"]').remove(); $(el).find('[style*="position: absolute"]').remove(); $(el).find('[style*="position: absolute;"]').remove(); } function cleanupObsucatingText(s) { if(s.length < obfuscationTextSizeLimit) { return s.replace(/[^Sponsored]+/g, '').replace(/(.)\1+/g, '$1'); } return s; } function elIsRealSponsored(el) { if(isWorthScrutinizing(el)) { const $elUnderScrutiny = $(el).clone(); cleanupObsucatingDom($elUnderScrutiny); const elText = cleanupObsucatingText($elUnderScrutiny.text()); if(elText === 'Sponsored' || isWordValid('Sponsored', elText)) { return true; } } else { return false; } } function debounce(func, wait, immediate) { var timeout; return function() { var context = this, args = arguments; var later = function() { timeout = null; if (!immediate) func.apply(context, args); }; var callNow = immediate && !timeout; clearTimeout(timeout); timeout = window.__fbNativeSetTimeout(later, wait); if (callNow) func.apply(context, args); }; }; function findAndHide(skipPoll) { // Suggested For You $( "span:contains('Suggested for you')" ).closest('[data-pagelet*="FeedUnit"]').hide(); //Sponsored Ads in the Feed $('a[href*="/ads/"]').closest('[data-pagelet*="FeedUnit"]').hide(); $('[data-pagelet*="FeedUnit"] a[href="#"]').each((index, el) => { if(elIsRealSponsored(el)) { if(debugHighlightAds) { $(el).closest('[data-pagelet*="FeedUnit"]').get(0).style.border = "thick solid #FF0000"; } else { $(el).closest('[data-pagelet*="FeedUnit"]').hide(); } } }); $('[data-pagelet*="FeedUnit"] [aria-label="Shared with Public"]').parent().parent().parent().parent().each((index, el) => { if(elIsRealSponsored(el)) { if(debugHighlightAds) { $(el).closest('[data-pagelet*="FeedUnit"]').get(0).style.border = "thick solid #FF0000"; } else { $(el).closest('[data-pagelet*="FeedUnit"]').hide(); } } }); $('[data-pagelet*="FeedUnit"] [role="button"]').each((index, el) => { const elText = $(el).text(); if(elText.includes('Sponsored')) { if(debugHighlightAds) { $(el).closest('[data-pagelet*="FeedUnit"]').get(0).style.border = "thick solid #FF0000"; } else { $(el).closest('[data-pagelet*="FeedUnit"]').hide(); } } }); $('[data-pagelet*="RightRail"] h3').each((i, j) => { if(isWordValid('Sponsored', $(j).text())) { $(j).parent().parent().parent().parent().parent().parent().parent().hide(); } } ); //Sponsored Ads in Marketplace $('a[href*="/ads/"]').closest('span > div > a > div > div > div').parent().parent().parent().parent().parent().parent().hide(); //Hide Sponsored Ads Header in Marketplace $(`a[href*="/ads/about"] span:contains('Sponsored')`).parent().parent().hide(); console.log('Found and hid!'); if(!skipPoll) { window.__fbNativeSetTimeout(function() { findAndHide(); }, pollTimeout); } } $(window).scroll(debounce(() => { findAndHide(true); }, debounceTimeout, true)); //Kick off the polling findAndHide(); })();