Auto-Add A Comment When Closing

Automatically adds a comment with details of the close reason, so that the OP can see why their question may be being downvoted, and improve it, before it is closed (disabled for Duplicate, Off-topic > Migrate, and Off-topic > Other)

  1. // ==UserScript==
  2. // @name Auto-Add A Comment When Closing
  3. // @description Automatically adds a comment with details of the close reason, so that the OP can see why their question may be being downvoted, and improve it, before it is closed (disabled for Duplicate, Off-topic > Migrate, and Off-topic > Other)
  4. // @namespace http://stackoverflow.com/users/1563422/danny-beckett
  5. // @version 1.4
  6. // @grant
  7. // @match http://*.askubuntu.com/questions/*
  8. // @match http://*.mathoverflow.net/questions/*
  9. // @match http://*.onstartups.com/questions/*
  10. // @match http://*.serverfault.com/questions/*
  11. // @match http://*.stackapps.com/questions/*
  12. // @match http://*.stackexchange.com/questions/*
  13. // @match http://*.stackoverflow.com/questions/*
  14. // @match http://*.superuser.com/questions/*
  15. // ==/UserScript==
  16.  
  17. // Hijacks all AJAX requests, and adds stateChanged() to the close popup
  18. XMLHttpRequest.prototype.originalOpen = XMLHttpRequest.prototype.open;
  19. function hijackAJAX(method, url, async, username, password)
  20. {
  21. if(url.indexOf("/close/popup") > 0)
  22. this.addEventListener("readystatechange", function(){ stateChanged(this); });
  23. this.originalOpen(method, url, async, username, password);
  24. }
  25. XMLHttpRequest.prototype.open = hijackAJAX;
  26.  
  27. // Receives an XHR's state changes, and runs popupLoaded() when the popup is open
  28. function stateChanged(XHR)
  29. {
  30. if(XHR.readyState === 4 && XHR.status === 200)
  31. setTimeout(popupLoaded, 1);
  32. }
  33.  
  34. // Adds a submit listener to the close popup
  35. function popupLoaded()
  36. {
  37. var popup = document.getElementById('close-question-form');
  38. popup.addEventListener("submit", function(){ getText(popup); });
  39. }
  40.  
  41. // On submit, receives a popup and gets the text for the close reason chosen
  42. function getText(popup)
  43. {
  44. var text, reasons;
  45. var reason = popup.elements["close-reason"].value;
  46.  
  47. // Skip duplicates
  48. if(reason === "Duplicate")
  49. return;
  50.  
  51. else if(reason === "OffTopic")
  52. {
  53. reason = popup.elements["close-as-off-topic-reason"].value;
  54. reasons = document.getElementsByName("close-as-off-topic-reason");
  55. for(var i = 0; i < reasons.length; i++)
  56. {
  57. if(reasons[i].value === reason)
  58. {
  59. // Skip migrations & other
  60. if(reasons[i].getAttribute("data-subpane-name") === "migration" || typeof reasons[i].parentNode.parentNode.getElementsByClassName("off-topic-other-comment-container")[0] !== "undefined")
  61. return;
  62.  
  63. text = reasons[i].parentNode.getElementsByClassName("action-name")[0].innerHTML;
  64. }
  65. }
  66. }
  67.  
  68. else
  69. {
  70. reasons = document.getElementsByName("close-reason");
  71. for(var i = 0; i < reasons.length; i++)
  72. if(reasons[i].value === reason)
  73. text = reasons[i].parentNode.getElementsByClassName("action-desc")[0].innerHTML;
  74. }
  75.  
  76. addComment(text);
  77. }
  78.  
  79. // Receieves the close reason text, formats it in Markdown, and adds it to a new comment
  80. function addComment(text)
  81. {
  82. text = text.replace(/<span(.*)<\/span>/gim, ""); // Remove [2] counter, showing how many other users voted on this reason
  83. text = text.trim(); // Trim whitespace, newlines and tabs
  84. text = text.replace(/<b>|<\/b>/gim, "**"); // Bold
  85. text = text.replace(/<i>|<\/i>/gim, "*"); // Italics
  86. text = text.replace(/<a href="(.*?)"( target=".*?"){0,}( rel=".*?"){0,}>(.*?)<\/a>/gim, "[$4]($1)"); // Links (strip rel and target attrs if present)
  87.  
  88. document.getElementsByClassName("comments-link")[0].click();
  89. document.getElementsByName("comment")[0].innerText = text;
  90. setTimeout(submitComment, 250);
  91. }
  92.  
  93. // After a short delay, submits the comment
  94. function submitComment()
  95. {
  96. document.getElementsByName("comment")[0].parentNode.parentNode.getElementsByTagName("input")[0].click();
  97. }

QingJ © 2025

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