Github Reply Comments

Easy reply to Github comments

当前为 2019-02-02 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Github Reply Comments
  3. // @namespace https://github.com/jerone/UserScripts
  4. // @description Easy reply to Github comments
  5. // @author jerone
  6. // @copyright 2016+, jerone (http://jeroenvanwarmerdam.nl)
  7. // @license CC-BY-NC-SA-4.0; https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode
  8. // @license GPL-3.0-or-later; http://www.gnu.org/licenses/gpl-3.0.txt
  9. // @homepage https://github.com/jerone/UserScripts/tree/master/Github_Reply_Comments
  10. // @homepageURL https://github.com/jerone/UserScripts/tree/master/Github_Reply_Comments
  11. // @supportURL https://github.com/jerone/UserScripts/issues
  12. // @contributionURL https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=VCYMHWQ7ZMBKW
  13. // @version 1.0.0
  14. // @icon https://assets-cdn.github.com/pinned-octocat.svg
  15. // @grant none
  16. // @include https://github.com/*
  17. // @include https://gist.github.com/*
  18. // @require https://unpkg.com/turndown@5.0.3/dist/turndown.js
  19. // @require https://unpkg.com/turndown-plugin-gfm@1.0.2/dist/turndown-plugin-gfm.js
  20. // @require https://unpkg.com/turndown-plugin-github-code-snippet@1.0.0/turndown-plugin-github-code-snippet.js
  21. // ==/UserScript==
  22.  
  23. (function () {
  24.  
  25. String.format = function (string) {
  26. var args = Array.prototype.slice.call(arguments, 1, arguments.length);
  27. return string.replace(/{(\d+)}/g, function (match, number) {
  28. return typeof args[number] !== "undefined" ? args[number] : match;
  29. });
  30. };
  31.  
  32. var turndownService = new TurndownService();
  33. turndownService.use(turndownPluginGfm.gfm);
  34. turndownService.use(turndownPluginGithubCodeSnippet);
  35.  
  36. function getCommentTextarea(replyBtn) {
  37. var newComment = replyBtn;
  38. while (newComment && !newComment.classList.contains("js-quote-selection-container")) {
  39. newComment = newComment.parentNode;
  40. }
  41.  
  42. var inlineComment = newComment.querySelector(".js-inline-comment-form-container");
  43. if (inlineComment) {
  44. inlineComment.classList.add("open");
  45. }
  46.  
  47. var textareas = newComment.querySelectorAll(":scope > :not(.last-review-thread) .comment-form-textarea");
  48. return textareas[textareas.length - 1];
  49. }
  50.  
  51. function getCommentMarkdown(comment) {
  52. var commentText = "";
  53.  
  54. // Use raw comment when available.
  55. var commentForm = comment.querySelector(".comment-form-textarea");
  56. if (commentForm) {
  57. commentText = commentForm.value;
  58. }
  59.  
  60. // Convert comment HTML to markdown.
  61. if (!commentText) {
  62. var commentBody = comment.querySelector(".comment-body").innerHTML;
  63. commentText = turndownService.turndown(commentBody);
  64. }
  65.  
  66. return commentText;
  67. }
  68.  
  69. function addReplyButtons() {
  70. Array.prototype.forEach.call(document.querySelectorAll(".comment, .review-comment"), function (comment) {
  71. var oldReply = comment.querySelector(".GithubReplyComments, .GithubCommentEnhancerReply");
  72. if (oldReply) {
  73. oldReply.parentNode.removeChild(oldReply);
  74. }
  75.  
  76. var header = comment.querySelector(":scope > :not(.minimized-comment) .timeline-comment-header"),
  77. actions = comment.querySelector(":scope > :not(.minimized-comment) .timeline-comment-actions");
  78.  
  79. if (!header) {
  80. header = actions;
  81. }
  82.  
  83. if (!actions) {
  84. if (!header) {
  85. return;
  86. }
  87. actions = document.createElement("div");
  88. actions.classList.add("timeline-comment-actions");
  89. header.insertBefore(actions, header.firstElementChild);
  90. }
  91.  
  92. var reply = document.createElement("button");
  93. reply.setAttribute("type", "button");
  94. reply.setAttribute("title", "Reply to this comment");
  95. reply.setAttribute("aria-label", "Reply to this comment");
  96. reply.classList.add("GithubReplyComments", "btn-link", "timeline-comment-action", "tooltipped", "tooltipped-ne");
  97. reply.addEventListener("click", function (e) {
  98. e.preventDefault();
  99.  
  100. var timestamp = comment.querySelector(".timestamp");
  101.  
  102. var commentText = getCommentMarkdown(comment);
  103. commentText = commentText.trim().split("\n").map(function (line) {
  104. return "> " + line;
  105. }).join("\n");
  106.  
  107. var newComment = getCommentTextarea(this);
  108.  
  109. var text = newComment.value.length > 0 ? "\n" : "";
  110. text += String.format('[**@{0}**]({1}/{0}) commented on [{2}]({3} "{4} - Replied by Github Reply Comments"):\n{5}\n\n',
  111. comment.querySelector(".author").textContent,
  112. location.origin,
  113. timestamp.firstElementChild.getAttribute("title"),
  114. timestamp.href,
  115. timestamp.firstElementChild.getAttribute("datetime"),
  116. commentText);
  117.  
  118. newComment.value += text;
  119. newComment.setSelectionRange(newComment.value.length, newComment.value.length);
  120. newComment.focus();
  121. });
  122.  
  123. var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
  124. svg.classList.add("octicon", "octicon-mail-reply");
  125. svg.setAttribute("height", "16");
  126. svg.setAttribute("width", "16");
  127. reply.appendChild(svg);
  128. var path = document.createElementNS("http://www.w3.org/2000/svg", "path");
  129. path.setAttribute("d", "M6 2.5l-6 4.5 6 4.5v-3c1.73 0 5.14 0.95 6 4.38 0-4.55-3.06-7.05-6-7.38v-3z");
  130. svg.appendChild(path);
  131.  
  132. actions.appendChild(reply);
  133. });
  134. }
  135.  
  136. // init;
  137. addReplyButtons();
  138.  
  139. // on pjax;
  140. document.addEventListener('pjax:end', addReplyButtons);
  141.  
  142. })();

QingJ © 2025

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