GreasyFork 一键回报垃圾评论

在 Greasy Fork 一键回报垃圾评论

当前为 2023-09-13 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name GreasyFork: One Click Report Spam
  3. // @name:zh-TW GreasyFork 一鍵回報垃圾評論
  4. // @name:zh-CN GreasyFork 一键回报垃圾评论
  5. // @namespace UserScripts
  6. // @match https://greasyfork.org/*
  7. // @grant none
  8. // @version 1.2
  9. // @author CY Fung
  10. // @license MIT
  11. // @description To report spam comments in Greasy Fork with one click
  12. // @description:zh-TW 在 Greasy Fork 一鍵回報垃圾評論
  13. // @description:zh-CN 在 Greasy Fork 一键回报垃圾评论
  14. // ==/UserScript==
  15.  
  16. (() => {
  17.  
  18. const TEST_MODE = 0;
  19. let skipMode = false;
  20.  
  21. const onIframeLoad = async (evt) => {
  22. const iframe = evt.target;
  23. if (!(iframe instanceof HTMLIFrameElement)) return;
  24.  
  25. if(skipMode) return;
  26.  
  27.  
  28. const onNewUrl = async () => {
  29. skipMode = true;
  30.  
  31. alert('reported');
  32. await new Promise(requestAnimationFrame);
  33. iframe.remove();
  34.  
  35. }
  36. const onAbort = async () => {
  37. skipMode = true;
  38.  
  39. await new Promise(requestAnimationFrame);
  40. iframe.remove();
  41. }
  42.  
  43. iframe.removeEventListener('load', onIframeLoad, false);
  44.  
  45. if (!iframe.contentDocument) {
  46. alert('Iframe Access Error. Action aborted.');
  47. onAbort();
  48. return;
  49. }
  50.  
  51. const reportReasonRadio = iframe.contentDocument.querySelector('input[name="report[reason]"]');
  52. if (reportReasonRadio) {
  53. reportReasonRadio.scrollIntoView();
  54. await new Promise(requestAnimationFrame);
  55. reportReasonRadio.click();
  56. const form = reportReasonRadio.closest('form');
  57. let currentUrl = iframe.contentWindow.location.pathname;
  58. skipMode = true;
  59. if (TEST_MODE) {
  60.  
  61. iframe.contentWindow.location.href = 'https://greasyfork.org/'
  62. } else {
  63. form.submit();
  64. }
  65. let cid = setInterval(() => {
  66. if (!cid) return;
  67. let nextUrl = iframe.contentWindow.location.pathname;
  68. if (nextUrl !== currentUrl) {
  69. clearInterval(cid)
  70. cid = 0;
  71. setTimeout(onNewUrl, 300);
  72. }
  73. }, 100)
  74.  
  75. } else if (iframe.contentDocument.querySelector('#open-report-:not(:empty)')) {
  76. alert("The spam report is already submitted for moderator's review. Action aborted.");
  77. onAbort();
  78.  
  79. } else {
  80. alert('Cannot find the report[reason] radio button. Action aborted.');
  81. onAbort();
  82. }
  83.  
  84. };
  85. const clickHandler = (evt) => {
  86. evt.preventDefault();
  87. if (!(evt.target instanceof HTMLElement)) return;
  88. let url = evt.target.getAttribute('ohref');
  89. if (!url) return;
  90. let userid = /id=(\d+)\b/.exec(url);
  91. if (userid) userid = userid[1];
  92. let r = window.confirm(`Confirm to report user#${userid || "------"} ?`);
  93. if (!r) return;
  94. const iframe = document.createElement('iframe');
  95. iframe.name = "u423323"
  96. iframe.src = url;
  97. Object.assign(iframe.style, {
  98. display: 'block',
  99. position: 'fixed',
  100. top: '0px',
  101. left: '0px',
  102. width: '300px',
  103. height: '300px',
  104. 'contain': 'strict',
  105. });
  106. iframe.addEventListener('load', onIframeLoad, false);
  107. document.body.appendChild(iframe)
  108. }
  109.  
  110.  
  111. for (const anchor of document.querySelectorAll('a[href*="/reports/new?item_class=comment&item_id="],a[href*="/reports/new?item_class=discussion&item_id="]')) {
  112.  
  113. let anchorNode = anchor;
  114. if (anchor.parentNode.firstElementChild === anchor.parentNode.lastElementChild) {
  115. anchorNode = anchorNode.parentNode;
  116. }
  117. let newAnchorNode = anchorNode.cloneNode(true);
  118. let newAnchor = newAnchorNode.querySelector('a[href]') || newAnchorNode;
  119. newAnchor.setAttribute('ohref', newAnchor.getAttribute('href'));
  120. newAnchor.setAttribute('href', '#');
  121. newAnchor.addEventListener('click', clickHandler, false)
  122. newAnchor.textContent = 'Report Spam';
  123. anchorNode.parentNode.insertBefore(newAnchorNode, anchorNode.nextSibling);
  124.  
  125.  
  126. }
  127. })();