您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Enhances Github comments
当前为
// ==UserScript== // @id Github_Comment_Enhancer@https://github.com/jerone/UserScripts // @name Github Comment Enhancer // @namespace https://github.com/jerone/UserScripts // @description Enhances Github comments // @author jerone // @homepage https://github.com/jerone/UserScripts/tree/master/Github_Comment_Enhancer // @homepageURL https://github.com/jerone/UserScripts/tree/master/Github_Comment_Enhancer // @version 1.3 // @grant none // @run-at document-end // @include https://github.com/*/*/issues/* // @include https://github.com/*/*/pull/* // @include https://github.com/*/*/commit/* // @include https://github.com/*/*/wiki/* // @include https://gist.github.com/* // ==/UserScript== /* global unsafeWindow */ (function() { String.format = function(string) { var args = Array.prototype.slice.call(arguments, 1, arguments.length); return string.replace(/{(\d+)}/g, function(match, number) { return typeof args[number] !== "undefined" ? args[number] : match; }); }; // Source: https://github.com/gollum/gollum/blob/9c714e768748db4560bc017cacef4afa0c751a63/lib/gollum/public/gollum/javascript/editor/langs/markdown.js var MarkDown = { "function-bold": { search: /^(\s*)([\s\S]*?)(\s*)$/g, replace: "$1**$2**$3" }, "function-italic": { search: /^(\s*)([\s\S]*?)(\s*)$/g, replace: "$1_$2_$3" }, "function-strikethrough": { search: /^(\s*)([\s\S]*?)(\s*)$/g, replace: "$1~~$2~~$3" }, "function-h1": { search: /(.+)([\n]?)/g, replace: "# $1$2", forceNewline: true }, "function-h2": { search: /(.+)([\n]?)/g, replace: "## $1$2", forceNewline: true }, "function-h3": { search: /(.+)([\n]?)/g, replace: "### $1$2", forceNewline: true }, "function-h4": { search: /(.+)([\n]?)/g, replace: "#### $1$2", forceNewline: true }, "function-h5": { search: /(.+)([\n]?)/g, replace: "##### $1$2", forceNewline: true }, "function-h6": { search: /(.+)([\n]?)/g, replace: "###### $1$2", forceNewline: true }, "function-link": { exec: function(txt, selText, commentForm, next) { var selTxt = selText.trim(), isUrl = selTxt && /(?:https?:\/\/)|(?:www\.)/.test(selTxt), href = window.prompt("Link href:", isUrl ? selTxt : ""), text = window.prompt("Link text:", isUrl ? "" : selTxt); if (href) { next(String.format("{2}", text || href, href, (/\s+$/.test(selText) ? " " : ""))); } } }, "function-image": { exec: function(txt, selText, commentForm, next) { var selTxt = selText.trim(), isUrl = selTxt && /(?:https?:\/\/)|(?:www\.)/.test(selTxt), href = window.prompt("Image href:", isUrl ? selTxt : ""), text = window.prompt("Image text:", isUrl ? "" : selTxt); if (href) { next(String.format("{2}", text || href, href, (/\s+$/.test(selText) ? " " : ""))); } } }, "function-ul": { search: /(.+)([\n]?)/g, replace: "* $1$2", forceNewline: true }, "function-ol": { exec: function(txt, selText, commentForm, next) { var repText = ""; if (!selText) { repText = "1. "; } else { var lines = selText.split("\n"), hasContent = /[\w]+/; for (var i = 0; i < lines.length; i++) { if (hasContent.test(lines[i])) { repText += String.format("$0. $1\n", i + 1, lines[i]); } } } next(repText); } }, "function-checklist": { search: /(.+)([\n]?)/g, replace: "* [ ] $1$2", forceNewline: true }, "function-code": { exec: function(txt, selText, commentForm, next) { var rt = selText.indexOf("\n") > -1 ? "$1\n```\n$2\n```$3" : "$1`$2`$3"; next(selText.replace(/^(\s*)([\s\S]*?)(\s*)$/g, rt)); } }, "function-blockquote": { search: /(.+)([\n]?)/g, replace: "> $1$2", forceNewline: true }, "function-hr": { append: "\n***\n", forceNewline: true }, "function-table": { append: "\n" + "| Head | Head | Head |\n" + "| :--- | :--: | ---: |\n" + "| Cell | Cell | Cell |\n" + "| Cell | Cell | Cell |\n", forceNewline: true }, "function-clear": { exec: function(txt, selText, commentForm, next) { commentForm.value = ""; next(""); } } }; var editorHTML = (function() { return '<div id="gollum-editor-function-buttons" style="float: left;">' + ' <div class="button-group">' + ' <a href="#" id="function-bold" class="minibutton function-button" title="Bold" tabindex="-1">' + ' <b>B</b>' + ' </a>' + ' <a href="#" id="function-italic" class="minibutton function-button" title="Italic" tabindex="-1">' + ' <em>i</em>' + ' </a>' + ' <a href="#" id="function-strikethrough" class="minibutton function-button" title="Strikethrough" tabindex="-1">' + ' <s>S</s>' + ' </a>' + ' </div>' + ' <div class="button-group">' + ' <div class="select-menu js-menu-container js-select-menu js-composer-assignee-picker">' + ' <span aria-haspopup="true" title="Headers" role="button" class="minibutton select-menu-button icon-only js-menu-target" style="padding:0 18px 0 7px; width:auto; border-bottom-right-radius:3px; border-top-right-radius:3px;">' + ' <b>h#</b>' + ' </span>' + ' <div aria-hidden="false" class="select-menu-modal-holder js-menu-content js-navigation-container js-active-navigation-container" style="top: 26px;">' + ' <div class="select-menu-modal" style="width:auto;">' + ' <div class="select-menu-header">' + ' <span class="select-menu-title">Choose header</span>' + ' <span class="octicon octicon-remove-close js-menu-close"></span>' + ' </div>' + ' <div class="button-group">' + ' <a href="#" id="function-h1" class="minibutton function-button js-menu-close" title="Header 1" tabindex="-1">' + ' <b>h1</b>' + ' </a>' + ' <a href="#" id="function-h2" class="minibutton function-button js-menu-close" title="Header 2" tabindex="-1">' + ' <b>h2</b>' + ' </a>' + ' <a href="#" id="function-h3" class="minibutton function-button js-menu-close" title="Header 3" tabindex="-1">' + ' <b>h3</b>' + ' </a>' + ' <a href="#" id="function-h4" class="minibutton function-button js-menu-close" title="Header 4" tabindex="-1">' + ' <b>h4</b>' + ' </a>' + ' <a href="#" id="function-h5" class="minibutton function-button js-menu-close" title="Header 5" tabindex="-1">' + ' <b>h5</b>' + ' </a>' + ' <a href="#" id="function-h6" class="minibutton function-button js-menu-close" title="Header 6" tabindex="-1">' + ' <b>h6</b>' + ' </a>' + ' </div>' + ' </div>' + ' </div>' + ' </div>' + ' </div>' + ' <div class="button-group">' + ' <a href="#" id="function-link" class="minibutton function-button" title="Link" tabindex="-1">' + ' <span class="octicon octicon-link"></span>' + ' </a>' + ' <a href="#" id="function-image" class="minibutton function-button" title="Image" tabindex="-1">' + ' <span class="octicon octicon-file-media"></span>' + ' </a>' + ' </div>' + ' <div class="button-group">' + ' <a href="#" id="function-ul" class="minibutton function-button" title="Unordered List" tabindex="-1">' + ' <span class="octicon octicon-list-unordered"></span>' + ' </a>' + ' <a href="#" id="function-ol" class="minibutton function-button" title="Ordered List" tabindex="-1">' + ' <span class="octicon octicon-list-ordered"></span>' + ' </a>' + ' <a href="#" id="function-checklist" class="minibutton function-button" title="Task List" tabindex="-1">' + ' <span class="octicon octicon-checklist"></span>' + ' </a>' + ' </div>' + ' <div class="button-group">' + ' <a href="#" id="function-code" class="minibutton function-button" title="Code" tabindex="-1">' + ' <span class="octicon octicon-code"></span>' + ' </a>' + ' <a href="#" id="function-blockquote" class="minibutton function-button" title="Blockquote" tabindex="-1">' + ' <span class="octicon octicon-quote"></span>' + ' </a>' + ' <a href="#" id="function-hr" class="minibutton function-button" title="Horizontal Rule" tabindex="-1">' + ' <span class="octicon octicon-horizontal-rule"></span>' + ' </a>' + ' <a href="#" id="function-table" class="minibutton function-button" title="Table" tabindex="-1">' + ' <span class="octicon octicon-three-bars"></span>' + ' </a>' + ' </div>' + '</div>' + '<div class="button-group" style="float:right;">' + ' <a href="#" id="function-clear" class="minibutton function-button" title="Clear" tabindex="-1">' + ' <span class="octicon octicon-circle-slash"></span>' + ' </a>' + '</div>'; })(); // Source: https://github.com/gollum/gollum/blob/9c714e768748db4560bc017cacef4afa0c751a63/lib/gollum/public/gollum/javascript/editor/gollum.editor.js#L516 function executeAction(definitionObject, commentForm) { var txt = commentForm.value, selPos = { start: commentForm.selectionStart, end: commentForm.selectionEnd }, selText = txt.substring(selPos.start, selPos.end), repText = selText, reselect = true, cursor = null; // execute replacement function; if (definitionObject.exec) { definitionObject.exec(txt, selText, commentForm, function(repText) { replaceFieldSelection(commentForm, repText); }); return; } // execute a search; var searchExp = new RegExp(definitionObject.search || /([^\n]+)/gi); // replace text; if (definitionObject.replace) { var rt = definitionObject.replace; repText = repText.replace(searchExp, rt); repText = repText.replace(/\$[\d]/g, ""); if (repText === "") { cursor = rt.indexOf("$1"); repText = rt.replace(/\$[\d]/g, ""); if (cursor === -1) { cursor = Math.floor(rt.length / 2); } } } // append if necessary; if (definitionObject.append) { if (repText === selText) { reselect = false; } repText += definitionObject.append; } if (repText) { if (definitionObject.forceNewline === true && (selPos.start > 0 && txt.substr(Math.max(0, selPos.start - 1), 1) !== "\n")) { repText = "\n" + repText; } replaceFieldSelection(commentForm, repText, reselect, cursor); } } // Source: https://github.com/gollum/gollum/blob/9c714e768748db4560bc017cacef4afa0c751a63/lib/gollum/public/gollum/javascript/editor/gollum.editor.js#L708 function replaceFieldSelection(commentForm, replaceText, reselect, cursorOffset) { var txt = commentForm.value, selPos = { start: commentForm.selectionStart, end: commentForm.selectionEnd }; var selectNew = true; if (reselect === false) { selectNew = false; } var scrollTop = null; if (commentForm.scrollTop) { scrollTop = commentForm.scrollTop; } commentForm.value = txt.substring(0, selPos.start) + replaceText + txt.substring(selPos.end); commentForm.focus(); // Gist Github requires that the comment form change event be triggered to update the preview; unsafeWindow.$(commentForm).trigger("change"); if (selectNew) { if (cursorOffset) { commentForm.setSelectionRange(selPos.start + cursorOffset, selPos.start + cursorOffset); } else { commentForm.setSelectionRange(selPos.start, selPos.start + replaceText.length); } } if (scrollTop) { commentForm.scrollTop = scrollTop; } } function isWiki() { return /\/wiki\//.test(location.href); } var functionButtonClick = function(e) { e.preventDefault(); executeAction(MarkDown[this.id], this.commentForm); return false; }; function addToolbar() { if (isWiki()) { // Override existing language with improved & missing functions and remove existing click events; unsafeWindow.$.GollumEditor.defineLanguage("markdown", MarkDown); unsafeWindow.$(".function-button:not(#function-help)").unbind("click"); // Remove existing click events when changing languages; document.getElementById("wiki_format").addEventListener("change", function() { unsafeWindow.$(".function-button:not(#function-help)").unbind("click"); Array.forEach(document.querySelectorAll(".comment-form-textarea .function-button"), function(button) { button.removeEventListener("click", functionButtonClick); }); }); } Array.forEach(document.querySelectorAll(".comment-form-textarea,.js-comment-field"), function(commentForm) { if (commentForm.classList.contains("GithubCommentEnhancer")) { return; } commentForm.classList.add("GithubCommentEnhancer"); var gollumEditor; if (isWiki()) { gollumEditor = document.getElementById("gollum-editor-function-bar"); var temp = document.createElement("div"); temp.innerHTML = editorHTML; temp.firstChild.appendChild(document.getElementById("function-help")); // restore the help button; gollumEditor.replaceChild(temp.querySelector("#gollum-editor-function-buttons"), document.getElementById("gollum-editor-function-buttons")); Array.forEach(temp.children, function(elm) { elm.style.position = "absolute"; elm.style.right = "30px"; elm.style.top = "0"; commentForm.parentNode.insertBefore(elm, commentForm); }); temp = null; } else { gollumEditor = document.createElement("div"); gollumEditor.innerHTML = editorHTML; gollumEditor.id = "gollum-editor-function-bar"; gollumEditor.style.border = "0 none"; gollumEditor.style.height = "26px"; gollumEditor.style.margin = "10px 0"; gollumEditor.style.paddingBottom = "10px"; gollumEditor.classList.add("active"); commentForm.parentNode.insertBefore(gollumEditor, commentForm); } Array.forEach(gollumEditor.parentNode.querySelectorAll(".function-button"), function(button) { button.style.padding = "0px"; button.style.textAlign = "center"; button.style.width = "30px"; button.firstElementChild.style.marginRight = "0px"; button.commentForm = commentForm; // remove event listener doesn't accept `bind`; button.addEventListener("click", functionButtonClick); }); }); } // init; addToolbar(); // on pjax; unsafeWindow.$(document).on("pjax:success", addToolbar); // on page update; unsafeWindow.$.pageUpdate(function() { window.setTimeout(function() { addToolbar(); }, 1); }); })();