Facebook Hide Ads (a.k.a. sponsored posts)

Removes ads (a.k.a. sponsored posts) from feed and sidebar

  1. // ==UserScript==
  2. // @name Facebook Hide Ads (a.k.a. sponsored posts)
  3. // @namespace https://openuserjs.org/users/burn
  4. // @version 0.5.2
  5. // @description Removes ads (a.k.a. sponsored posts) from feed and sidebar
  6. // @author burn
  7. // @copyright 2020, burn (https://openuserjs.org/users/burn)
  8. // @license MIT
  9. // @match https://www.facebook.com/*
  10. // @match https://web.facebook.com/*
  11. // @grant none
  12. // @run-at document-idle
  13. // ==/UserScript==
  14.  
  15. (function() {
  16. 'use strict';
  17. let languages = { // thanks to Ciscoheat https://greasyfork.org/en/users/51960-ciscoheat
  18. 'af': ['Geborg'],
  19. 'am': ['የተከፈለበት ማስታወቂያ'],
  20. 'ar': ['إعلان مُموَّل'],
  21. 'as': ['পৃষ্ঠপোষকতা কৰা'],
  22. 'ay': ['Yatiyanaka'],
  23. 'az': ['Sponsor dəstəkli'],
  24. 'be': ['Рэклама'],
  25. 'bg': ['Спонсорирано'],
  26. 'br': ['Paeroniet'],
  27. 'bs': ['Sponzorirano'],
  28. 'bn': ['সৌজন্যে'],
  29. 'ca': ['Patrocinat'],
  30. 'cb': ['پاڵپشتیکراو'],
  31. 'co': ['Spunsurizatu'],
  32. 'cs': ['Sponzorováno'],
  33. 'cx': ['Giisponsoran'],
  34. 'cy': ['Noddwyd'],
  35. 'da': ['Sponsoreret'],
  36. 'de': ['Gesponsert'],
  37. 'el': ['Χορηγούμενη'],
  38. 'en': ['Sponsored', 'Chartered'],
  39. 'eo': ['Reklamo'],
  40. 'es': ['Publicidad', 'Patrocinado'],
  41. 'et': ['Sponsitud'],
  42. 'eu': ['Babestua'],
  43. 'fa': ['دارای پشتیبانی مالی'],
  44. 'fi': ['Sponsoroitu'],
  45. 'fo': ['Stuðlað'],
  46. 'fr': ['Commandité', 'Sponsorisé'],
  47. 'fy': ['Sponsore'],
  48. 'ga': ['Urraithe'],
  49. 'gl': ['Patrocinado'],
  50. 'gn': ['Oñepatrosinapyre'],
  51. 'gx': ['Χορηγούμενον'],
  52. 'hi': ['प्रायोजित'],
  53. 'hu': ['Hirdetés'],
  54. 'id': ['Bersponsor'],
  55. 'it': ['Sponsorizzata'],
  56. 'ja': ['広告'],
  57. 'jv': ['Disponsori'],
  58. 'kk': ['Демеушілік көрсеткен'],
  59. 'km': ['បានឧបត្ថម្ភ'],
  60. 'lo': ['ໄດ້ຮັບການສະໜັບສະໜູນ'],
  61. 'mk': ['Спонзорирано'],
  62. 'ml': ['സ്പോൺസർ ചെയ്തത്'],
  63. 'mn': ['Ивээн тэтгэсэн'],
  64. 'mr': ['प्रायोजित'],
  65. 'ms': ['Ditaja'],
  66. 'ne': ['प्रायोजित'],
  67. 'nl': ['Gesponsord'],
  68. 'or': ['ପ୍ରଯୋଜିତ'],
  69. 'pa': ['ਸਰਪ੍ਰਸਤੀ ਪ੍ਰਾਪਤ'],
  70. 'pl': ['Sponsorowane'],
  71. 'ps': ['تمويل شوي'],
  72. 'pt': ['Patrocinado'],
  73. 'ru': ['Реклама'],
  74. 'sa': ['प्रायोजितः |'],
  75. 'si': ['අනුග්‍රහය දක්වන ලද'],
  76. 'so': ['La maalgeliyey'],
  77. 'sv': ['Sponsrad'],
  78. 'te': ['స్పాన్సర్ చేసినవి'],
  79. 'th': ['ได้รับการสนับสนุน'],
  80. 'tl': ['May Sponsor'],
  81. 'tr': ['Sponsorlu'],
  82. 'tz': ['ⵉⴷⵍ'],
  83. 'uk': ['Реклама'],
  84. 'ur': ['تعاون کردہ'],
  85. 'vi': ['Được tài trợ'],
  86. 'zh-Hans': ['赞助内容'],
  87. 'zh-Hant': ['贊助']
  88. },
  89. qS = function (el, scope) {
  90. scope = (typeof scope == 'object') ? scope : document;
  91. return scope.querySelector(el) || false;
  92. },
  93. qSall = function (els, scope) {
  94. scope = (typeof scope == 'object') ? scope : document;
  95. return scope.querySelectorAll(els) || false;
  96. },
  97. targetNode = qS('body'),
  98. observerConfig = {
  99. attributes: false,
  100. childList: true,
  101. subtree: true
  102. },
  103. getParentEl = function (elmChild) {
  104. return elmChild.closest('[data-pagelet^="FeedUnit_"]') || false;
  105. },
  106. removeAdsInFeed = function (ads) {
  107. Array.prototype.forEach.call(ads, function (el) {
  108. let wrapper = getParentEl(el);
  109. if (wrapper !== false) {
  110. console.log("Found wrapper for " + el);
  111. if (wrapper.parentNode != null)
  112. wrapper.parentNode.removeChild(wrapper);
  113. else {
  114. const evt = new Event('mouseenter');
  115. wrapper.dispatchEvent(evt);
  116. //console.log("event dispatched");
  117. }
  118. }
  119. });
  120. },
  121. removeAbsoluteSpans = function (elm) {
  122. Array.prototype.forEach.call(qSall('span[style="position: absolute; top: 3em;"]', elm), function (el) {
  123. console.log("rimuovo " + el.tagName);
  124. el.parentNode.removeChild(el);
  125. });
  126. },
  127. callback = function (mutationsList, observer) {
  128. mutationsList.forEach(function (mutation) {
  129. var entry = {
  130. mutation: mutation,
  131. el: mutation.target,
  132. value: mutation.target.textContent,
  133. oldValue: mutation.oldValue
  134. };
  135.  
  136. removeAbsoluteSpans(entry.el);
  137.  
  138. // ads in right sidebar, old fb design
  139. let ego_wrapper = qS('#pagelet_ego_pane', entry.el);
  140. if (ego_wrapper) ego_wrapper.parentNode.removeChild(ego_wrapper);
  141.  
  142. /* new fb 2020 design */
  143. let lang = languages[document.documentElement.lang] || languages.en;
  144. if (lang.indexOf(entry.value) >= 0) {
  145. //console.log("sponsored found for " + entry.el);
  146. removeAdsInFeed([entry.el]);
  147. }
  148. });
  149. };
  150.  
  151. removeAbsoluteSpans(qS('body'));
  152. // ads in right sidebar, old fb design
  153. let ego_wrapper = qS('#pagelet_ego_pane');
  154. if (ego_wrapper) ego_wrapper.parentNode.removeChild(ego_wrapper);
  155.  
  156. var observer = new MutationObserver(callback);
  157. observer.observe(targetNode, observerConfig);
  158. })();