GreasyFork 一键回报垃圾评论

在 Greasy Fork 一键回报垃圾评论

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

  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.1
  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.  
  20. const onIframeLoad = async (evt) => {
  21. const iframe = evt.target;
  22. if (!(evt.target instanceof HTMLIFrameElement)) return;
  23.  
  24.  
  25. const onNewUrl = async () => {
  26.  
  27. alert('reported');
  28. await new Promise(requestAnimationFrame);
  29. iframe.remove();
  30.  
  31. }
  32. const onAbort = async () => {
  33. await new Promise(requestAnimationFrame);
  34. iframe.remove();
  35. }
  36. if (!iframe.contentDocument) {
  37. alert('Iframe Access Error. Action aborted.');
  38. onAbort();
  39. return;
  40. }
  41. const reportReasonRadio = iframe.contentDocument.querySelector('input[name="report[reason]"]');
  42. if (reportReasonRadio) {
  43. reportReasonRadio.scrollIntoView();
  44. await new Promise(requestAnimationFrame);
  45. reportReasonRadio.click();
  46. const form = reportReasonRadio.closest('form');
  47. let currentUrl = iframe.contentWindow.location.pathname;
  48. if (TEST_MODE) {
  49.  
  50. iframe.contentWindow.location.href = 'https://greasyfork.org/'
  51. } else {
  52. form.submit();
  53. }
  54. let cid = setInterval(() => {
  55. if (!cid) return;
  56. let nextUrl = iframe.contentWindow.location.pathname;
  57. if (nextUrl !== currentUrl) {
  58. clearInterval(cid)
  59. cid = 0;
  60. setTimeout(onNewUrl, 300);
  61. }
  62. }, 100)
  63.  
  64. } else if (iframe.contentDocument.querySelector('#open-report-:not(:empty)')) {
  65. alert("The spam report is already submitted for moderator's review. Action aborted.");
  66. onAbort();
  67.  
  68. } else {
  69. alert('Cannot find the report[reason] radio button. Action aborted.');
  70. onAbort();
  71. }
  72.  
  73. };
  74. const clickHandler = (evt) => {
  75. evt.preventDefault();
  76. if (!(evt.target instanceof HTMLElement)) return;
  77. let url = evt.target.getAttribute('ohref');
  78. if (!url) return;
  79. let userid = /id=(\d+)\b/.exec(url);
  80. if (userid) userid = userid[1];
  81. let r = window.confirm(`Confirm to report user#${userid || "------"} ?`);
  82. if (!r) return;
  83. const iframe = document.createElement('iframe');
  84. iframe.name = "u423323"
  85. iframe.src = url;
  86. Object.assign(iframe.style, {
  87. display: 'block',
  88. position: 'fixed',
  89. top: '0px',
  90. left: '0px',
  91. width: '300px',
  92. height: '300px',
  93. 'contain': 'strict',
  94. });
  95. iframe.addEventListener('load', onIframeLoad, false);
  96. document.body.appendChild(iframe)
  97. }
  98.  
  99.  
  100. for (const anchor of document.querySelectorAll('a[href*="/reports/new?item_class=comment&item_id="],a[href*="/reports/new?item_class=discussion&item_id="]')) {
  101.  
  102. let anchorNode = anchor;
  103. if (anchor.parentNode.firstElementChild === anchor.parentNode.lastElementChild) {
  104. anchorNode = anchorNode.parentNode;
  105. }
  106. let newAnchorNode = anchorNode.cloneNode(true);
  107. let newAnchor = newAnchorNode.querySelector('a[href]') || newAnchorNode;
  108. newAnchor.setAttribute('ohref', newAnchor.getAttribute('href'));
  109. newAnchor.setAttribute('href', '#');
  110. newAnchor.addEventListener('click', clickHandler, false)
  111. newAnchor.textContent = 'Report Spam';
  112. anchorNode.parentNode.insertBefore(newAnchorNode, anchorNode.nextSibling);
  113.  
  114.  
  115. }
  116. })();