RPS Hide Read Posts

Hides posts on the RPS homepage when they're clicked & adds a "Mark all as read" button

目前为 2021-01-26 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name RPS Hide Read Posts
  3. // @description Hides posts on the RPS homepage when they're clicked & adds a "Mark all as read" button
  4. // @version 4
  5. // @namespace https://github.com/insin/greasemonkey
  6. // @grant none
  7. // @match https://www.rockpapershotgun.com/
  8. // ==/UserScript==
  9.  
  10. // @ts-ignore
  11. let debug = false
  12.  
  13. let $style = document.createElement('style')
  14. $style.innerText = `
  15. /* Prevent the top section taking up space when posts are removed */
  16. #content_above {
  17. min-height: unset !important;
  18. }
  19. `
  20. document.head.appendChild($style)
  21.  
  22. /**
  23. * @param {HTMLElement} section
  24. * @returns {boolean}
  25. */
  26. function areAllPostsHidden(section) {
  27. return Array.from(section.querySelectorAll('article.summary')).every(
  28. (article) => article.parentElement.style.display === 'none'
  29. )
  30. }
  31.  
  32. /**
  33. * @param {HTMLElement} target
  34. * @returns {string}
  35. */
  36. function getPostClickHref(target) {
  37. if (target.tagName === 'A' && target.closest('article.summary')) {
  38. return /** @type {HTMLAnchorElement} */ (target).pathname
  39. }
  40. return ''
  41. }
  42.  
  43. function postsPage() {
  44. /** @type {string[]} */
  45. let clickedPosts = JSON.parse(localStorage.getItem('clickedPosts') || '[]')
  46.  
  47. function hideEmptySections() {
  48. for (let section of /** @type {NodeListOf<HTMLElement>} */ (document.querySelectorAll(
  49. '#content_above, section.featured_tag_shelf, section.latest_shelf, section.shelf, section.supporters_shelf'
  50. ))) {
  51. if (section.style.display === 'none') continue
  52. if (areAllPostsHidden(section)) {
  53. section.style.display = 'none'
  54. }
  55. }
  56. }
  57.  
  58. function hideClickedPosts() {
  59. for (let link of /** @type {NodeListOf<HTMLAnchorElement>} */ (document.querySelectorAll(
  60. 'a.link_overlay'
  61. ))) {
  62. if (clickedPosts.includes(link.pathname)) {
  63. let nodeToHide = link.closest('li')
  64. if (nodeToHide && nodeToHide.style.display !== 'none') {
  65. nodeToHide.style.display = 'none'
  66. }
  67. }
  68. }
  69. hideEmptySections()
  70. }
  71.  
  72. function markAllAsRead(e) {
  73. e.preventDefault()
  74. for (let link of /** @type {NodeListOf<HTMLAnchorElement>} */ (document.querySelectorAll(
  75. 'a.link_overlay'
  76. ))) {
  77. if (!clickedPosts.includes(link.pathname)) {
  78. clickedPosts.unshift(link.pathname)
  79. }
  80. }
  81. localStorage.setItem('clickedPosts', JSON.stringify(clickedPosts))
  82. hideClickedPosts()
  83. }
  84.  
  85. document.addEventListener('click', (e) => {
  86. let target = /** @type {HTMLElement} */ (e.target)
  87. if (e.button === 0 && getPostClickHref(target)) {
  88. // Hold ctrl + shift when clicking a post to hide it without opening it
  89. if (debug || (e.shiftKey && e.ctrlKey)) e.preventDefault()
  90. clickedPosts.unshift(getPostClickHref(target))
  91. localStorage.setItem('clickedPosts', JSON.stringify(clickedPosts))
  92. hideClickedPosts()
  93. }
  94. })
  95.  
  96. document.addEventListener('auxclick', (e) => {
  97. let target = /** @type {HTMLElement} */ (e.target)
  98. if (e.button === 1 && getPostClickHref(target)) {
  99. // Hold ctrl when middle-clicking a post to hide it without opening it
  100. if (debug || e.ctrlKey) e.preventDefault()
  101. clickedPosts.unshift(getPostClickHref(target))
  102. localStorage.setItem('clickedPosts', JSON.stringify(clickedPosts))
  103. hideClickedPosts()
  104. }
  105. })
  106.  
  107. let topButtons = document.querySelector('div.commercial.button_group')
  108. if (topButtons != null) {
  109. let button = document.createElement('a')
  110. button.className = 'button supporter'
  111. button.innerText = 'Mark all as read'
  112. button.href = '#'
  113. button.addEventListener('click', markAllAsRead)
  114. topButtons.appendChild(button)
  115. }
  116.  
  117. hideClickedPosts()
  118. }
  119.  
  120. if (location.pathname === '/') {
  121. postsPage()
  122. }