无涯拦截

Blocks rendering of elements with class or id containing "regwall"

当前为 2023-12-24 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Paywall Element Blocker
  3. // @name:zh-CN 无涯拦截
  4. // @namespace regwall-element-blocker
  5. // @version 1.3.3
  6. // @description Blocks rendering of elements with class or id containing "regwall"
  7. // @description:zh-cn 经济学人、财富网和dealine付费区拦截插件
  8. // @match *://*.economist.com/*
  9. // @match *://*.fortune.com/*
  10. // @match *://*.deadline.com/*
  11. // @run-at document-start
  12. // @author TIME
  13. // @license MIT
  14. // @grant none
  15. // ==/UserScript==
  16.  
  17.  
  18. (function() {
  19. 'use strict';
  20.  
  21. let loadCustomPage = () => {
  22. var xhr = new XMLHttpRequest();
  23. xhr.open("GET", window.location.href, true);
  24. xhr.onerror = function () {
  25. document.documentElement.innerHTML = "Error getting Page!";
  26. };
  27. xhr.send();
  28. xhr.onreadystatechange = function() {
  29. let states = [
  30. "Removing the Subscription...",
  31. "Initiating the Request...",
  32. "Establishing the Server...",
  33. "Request Received...",
  34. "Processing the Request...",
  35. "Error Finding the Page!"
  36. ];
  37. document.documentElement.innerHTML = states[this.readyState] || "Error Finding the Page!";
  38. if (this.readyState == 4 && this.status == 200) {
  39. let newHtml = processHtml(this.responseText);
  40. document.documentElement.innerHTML = newHtml.innerHTML;
  41. }
  42. };
  43. };
  44.  
  45. function processHtml(htmlContentStr) {
  46. let wrapper = document.createElement("DIV");
  47. wrapper.innerHTML = htmlContentStr;
  48. removeElementsWithAdClass(wrapper);
  49. if (matchDomain('fortune.com')) {
  50. imgHandler(wrapper);
  51. } else if (matchDomain('economist.com')) {
  52. console.log(htmlContentStr);
  53. } else if (matchDomain('deadline.com')) {
  54. imgHandler(wrapper);
  55. }
  56. return wrapper;
  57. }
  58.  
  59. function imgHandler(wrapper) {
  60. // Remove all img elements with src starting with "data:image"
  61. var base64Images = wrapper.querySelectorAll('img[src^="data:image"]');
  62. base64Images.forEach(function(img) {
  63. img.remove();
  64. });
  65.  
  66. // Update images` attribute of data-lazy-src to src
  67. var imgTags = wrapper.querySelectorAll('img');
  68. imgTags.forEach(function(img) {
  69. var lazySrc = img.getAttribute('data-lazy-src');
  70. if (lazySrc) {
  71. img.setAttribute('src', lazySrc);
  72. }
  73. });
  74.  
  75. // Change all noscript elements to div
  76. var noscripts = wrapper.querySelectorAll('noscript');
  77. noscripts.forEach(function(noscript) {
  78. var replacementDiv = document.createElement('div');
  79. replacementDiv.innerHTML = noscript.innerHTML;
  80. noscript.parentNode.replaceChild(replacementDiv, noscript);
  81. });
  82. return wrapper;
  83. }
  84.  
  85. // Define a function to remove elements with class containing "adComponent" or "advert"
  86. function removeElementsWithAdClass(wrapper) {
  87. // Select elements with class containing "adComponent" or "advert"
  88. let sensitiveAdCharacters = ['adComponent','advert','admz','header-ad']
  89. let selectors = sensitiveAdCharacters.map(className => `[class*="${className}"]`).join(', ');
  90. var adElements = wrapper.querySelectorAll(selectors);
  91. console.log('elements:',adElements);
  92. // Remove the selected elements
  93. adElements.forEach(function(element) {
  94. element.remove();
  95. });
  96. return wrapper;
  97. }
  98.  
  99. window.stop();
  100. loadCustomPage();
  101.  
  102. function matchDomain(domains) {
  103. const hostname = window.location.hostname;
  104. if (typeof domains === 'string') { domains = [domains]; }
  105. return domains.some(domain => hostname === domain || hostname.endsWith('.' + domain));
  106. }
  107.  
  108. })();