No Apple News

Remove Apple related entries in news sites

  1. // ==UserScript==
  2. // @name No Apple News
  3. // @description Remove Apple related entries in news sites
  4. // @version 0.1.3
  5. // @grant none
  6. // @author Lucie Cupcakes
  7. // @namespace https://lucdev.net
  8. // @license UNLICENSE - https://unlicense.org/
  9. // @match *://news.ycombinator.com/
  10. // @match *://news.ycombinator.com/news*
  11. // @match *://lobste.rs/
  12. // @match *://lobste.rs/page/*
  13. // ==/UserScript==
  14. (() => {
  15. const filterWords = ([
  16. 'airbook',
  17. 'apple',
  18. 'icloud',
  19. 'ios',
  20. 'ipad',
  21. 'iphone',
  22. 'ipod',
  23. 'm1',
  24. 'mac',
  25. 'macbook',
  26. 'macos',
  27. 'safari',
  28. 'siri',
  29. ]).map(el => ` ${el} `);
  30.  
  31. const domReady = (cb) => {
  32. if (document.readyState === 'complete') {
  33. return cb();
  34. }
  35. document.addEventListener('readystatechange', domReady.bind(
  36. null, cb));
  37. };
  38.  
  39. const titleMatches = (str) => {
  40. for (const el of filterWords) {
  41. if (str.startsWith(`${el.trim()} `) || str.includes(el)) {
  42. return true;
  43. }
  44. }
  45. return false;
  46. };
  47.  
  48. const removeHtmlElement = (el) => el.parentElement.removeChild(el);
  49.  
  50. const filterArticlesByHostname = {
  51. 'news.ycombinator.com': () => {
  52. return Array.from(document.querySelectorAll(
  53. '.title > .titleline > a'))
  54. .map((el) => {
  55. // Check if matches blocklist
  56. if (!titleMatches(el.innerText
  57. .toLowerCase())) {
  58. return null;
  59. }
  60. // Grab metadata
  61. const articleTr = el.parentElement
  62. .parentElement.parentElement;
  63. const id = articleTr.id.repeat(1);
  64. const title = el.innerText.repeat(1);
  65. const link = el.href.repeat(1);
  66. // Remove entry
  67. (() => {
  68. [
  69. document.querySelector(
  70. `.athing[id="${id}"]`
  71. ), // articleTr
  72. document.querySelector(
  73. `.athing[id="${id}"] + tr`
  74. ), //subtext
  75. document.querySelector(
  76. `.athing[id="${id}"] + tr + tr.spacer`
  77. ),
  78. ]
  79. .filter((el) => el !== null)
  80. .forEach(removeHtmlElement);
  81. })();
  82. // Return metadata
  83. return {
  84. title,
  85. link,
  86. id,
  87. };
  88. })
  89. .filter((el) => el !== null);
  90. },
  91. 'lobste.rs': () => {
  92. return Array.from(document.querySelectorAll(
  93. '.story .u-url'))
  94. .map((el) => {
  95. // Check if matches blocklist
  96. if (!titleMatches(el.innerText
  97. .toLowerCase())) {
  98. return null;
  99. }
  100. // Grab metadata
  101. const title = el.innerText.repeat(1);
  102. const link = el.href.repeat(1);
  103. // Remove entry
  104. (() => {
  105. const articleDiv =
  106. el.parentElement.parentElement
  107. .parentElement.parentElement;
  108. removeHtmlElement(articleDiv);
  109. })();
  110. // Return metadata
  111. return {
  112. title,
  113. link,
  114. };
  115. })
  116. .filter((el) => el !== null);
  117. },
  118. };
  119.  
  120. domReady(() => {
  121. const articles = filterArticlesByHostname[location.hostname]
  122. ();
  123. console.log(`Filtered ${articles.length} article(s).`,
  124. articles);
  125. });
  126. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址