// ==UserScript== // @name Facebook - Hides Suggested and Sponsored Posts // @namespace http://tampermonkey.net/ // @version 0.3 // @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 maxChar = 256; const debugHighlightAds = false; const obfuscationTextSizeLimit = 41; const debouncedFindAndHide = debounce(findAndHide, debounceTimeout, false); function cleanup(s) { if(s.length < obfuscationTextSizeLimit) { return s.replace(/[^Sponsored]+/g, '').replace(/(.)\1+/g, '$1'); } return s; } function isPresent(s, q) { // Count occurrences of all // characters in s. const freq = new Array(maxChar); freq.fill(0); for (let i = 0; i < s.length; i++) freq[s[i]]++; // Check if number of occurrences of // every character in q is less than // or equal to that in s. for (let i = 0; i < q.length; i++) { freq[q[i]]--; if (freq[q[i]] < 0) return false; } return true; } 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) => { const elText = cleanup($(el).text()); if(elText.length < obfuscationTextSizeLimit && (elText === 'Sponsored' || isPresent('Sponsored', elText))) { 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) => { const elText = cleanup($(el).text()); if(elText.length < obfuscationTextSizeLimit && (elText === 'Sponsored' || isPresent('Sponsored', elText))) { 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(isPresent('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(); })();