您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
A userscript that adds a code wrap toggle button
当前为
// ==UserScript== // @name GitHub Toggle Code Wrap // @version 1.0.0 // @description A userscript that adds a code wrap toggle button // @license https://creativecommons.org/licenses/by-sa/4.0/ // @namespace https://github.com/StylishThemes // @include https://github.com/* // @run-at document-idle // @grant GM_registerMenuCommand // @grant GM_getValue // @grant GM_setValue // @grant GM_addStyle // @author StylishThemes // ==/UserScript== /* global GM_registerMenuCommand, GM_getValue, GM_setValue, GM_addStyle */ /*jshint unused:true */ (function() { "use strict"; /* This code is also part of the GitHub-Dark Script (https://github.com/StylishThemes/GitHub-Dark-Script) Extracted out into a separate userscript in case users only want to add this functionality */ var busy = false, // set by GM popup menu globalWrap = GM_getValue("github-global-code-wrap", true), wrapIcon = "<svg xmlns='http://www.w3.org/2000/svg' width='768' height='768' viewBox='0 0 768 768'><path d='M544.5 352.5q52.5 0 90 37.5t37.5 90-37.5 90-90 37.5H480V672l-96-96 96-96v64.5h72q25.5 0 45-19.5t19.5-45-19.5-45-45-19.5H127.5v-63h417zm96-192v63h-513v-63h513zm-513 447v-63h192v63h-192z'/></svg>", // inline code wrap css wrapCss = { "wrapped" : "white-space: pre-wrap !important; word-break: break-all !important; display: block !important;", "unwrap" : "white-space: pre !important; word-break: normal !important; display: block !important;" }, findWrap = function(event) { var target = event.target; if (target.classList.contains("ghd-wrap-toggle")) { toggleClasses(target); } }, // equivalent to .next("code, pre, .highlight, .diff-table"); findNext = function(el) { var nextSib = el.nextElementSibling; if (/code|pre/i.test(nextSib.nodeName) || nextSib && (nextSib.classList.contains("highlight") || nextSib.classList.contains("diff-table"))) { return nextSib; } else { return el; } }, toggleClasses = function(icon) { var css, code = findNext(icon); if (code.querySelector("code")) { code = code.querySelector("code"); } if (!code) { console.error("Code wrap icon associated code not found", icon); return; } busy = true; // code with line numbers if (code.nodeName === "TABLE") { if (code.className.indexOf("wrap-table") < 0) { css = !globalWrap; } else { css = code.classList.contains("ghd-unwrap-table"); } if (css) { code.classList.add("ghd-wrap-table"); code.classList.remove("ghd-unwrap-table"); icon.classList.add("wrapped"); icon.classList.remove("unwrap"); } else { code.classList.remove("ghd-wrap-table"); code.classList.add("ghd-unwrap-table"); icon.classList.remove("wrapped"); icon.classList.add("unwrap"); } } else { css = code.getAttribute("style") || ""; if (css === "") { css = wrapCss[globalWrap ? "unwrap" : "wrapped"]; } else { css = wrapCss[css === wrapCss.wrapped ? "unwrap" : "wrapped"]; } code.setAttribute("style", css); if (css === wrapCss.wrapped) { icon.classList.add("wrapped"); icon.classList.remove("unwrap"); } else { icon.classList.add("unwrap"); icon.classList.remove("wrapped"); } } busy = false; }, getPrevSib = function(el, name) { var prev = el.previousSibling; while (prev) { if (prev.nodeType !== 1 || !prev.classList.contains(name)) { prev = prev.previousSibling; } else { return prev; } } return null; }, // Add code wrap toggle buildCodeWrap = function() { // mutation events happen quick, so we still add an update flag busy = true; // add wrap code icons var tmp, wrapper = document.querySelectorAll(".blob-wrapper"), indx = wrapper ? wrapper.length : 0, // <div class='ghd-wrap-toggle tooltipped tooltipped-w' aria-label='Toggle code wrap'> icon = document.createElement("div"); icon.className = "ghd-wrap-toggle tooltipped tooltipped-w"; icon.setAttribute("aria-label", "Toggle code wrap"); icon.innerHTML = wrapIcon; // $(".blob-wrapper").prepend(wrapIcon); while (indx--) { if (!wrapper[indx].querySelector(".ghd-wrap-toggle")) { wrapper[indx].insertBefore(icon.cloneNode(true), wrapper[indx].childNodes[0]); } } // $(".markdown-body pre").before(wrapIcon); wrapper = document.querySelectorAll(".markdown-body pre"); indx = wrapper ? wrapper.length : 0; while (indx--) { tmp = getPrevSib(wrapper[indx], "ghd-wrap-toggle"); if (!tmp) { wrapper[indx].parentNode.insertBefore(icon.cloneNode(true), wrapper[indx]); } } busy = false; }, init = function() { document.addEventListener("click", findWrap); if (!globalWrap) { document.querySelector("body").classList.add("nowrap"); } buildCodeWrap(); }, // DOM targets - to detect GitHub dynamic ajax page loading targets = document.querySelectorAll([ "#js-repo-pjax-container", // targeted by ZenHub "#js-repo-pjax-container > .container", "#js-pjax-container", ".js-preview-body" ].join(",")); // don't initialize if GitHub Dark Script is active if (!document.querySelector("#ghd-menu")) { GM_addStyle([ // icons next to a pre ".ghd-wrap-toggle { position:absolute; right:1.4em; margin-top:.2em; -moz-user-select:none; -webkit-user-select:none; cursor:pointer; z-index:20; }", // file & diff code tables ".ghd-wrap-table td.blob-code-inner { white-space: pre-wrap !important; word-break: break-all !important; }", ".ghd-unwrap-table td.blob-code-inner { white-space: pre !important; word-break: normal !important; }", // icons inside a wrapper immediatly around a pre ".highlight > .ghd-wrap-toggle { right:.5em; top:.5em; margin-top:0; }", // icons for non-syntax highlighted code blocks; see https://github.com/gjtorikian/html-proofer/blob/master/README.md ".markdown-body:not(.comment-body) .ghd-wrap-toggle:not(:first-child) { right: 3.4em; }", ".ghd-wrap-toggle svg { height:1.25em; width:1.25em; fill:rgba(110,110,110,.4); pointer-events:none; }", ".ghd-wrap-toggle.unwrap:hover svg, .ghd-wrap-toggle:hover svg { fill:#8b0000; }", // wrap disabled (red) "body:not(.nowrap) .ghd-wrap-toggle:not(.unwrap):hover svg, .ghd-wrap-toggle.wrapped:hover svg { fill:#006400; }", // wrap enabled (green) ".blob-wrapper, .markdown-body pre, .markdown-body .highlight { position:relative; }", // global code wrap ".blob-code-inner,", ".markdown-body pre > code,", ".markdown-body .highlight > pre {", "white-space: pre-wrap !important;", "word-break: break-all !important;", "display: block !important;", "}", "td.blob-code-inner {display: table-cell !important;}" ].join("")); // update TOC when content changes Array.prototype.forEach.call(targets, function(target) { new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { // preform checks before adding code wrap to minimize function calls if (!busy && mutation.target === target) { buildCodeWrap(); } }); }).observe(target, { childList: true, subtree: true }); }); // Add GM options GM_registerMenuCommand("Set Global Code Wrap Option", function() { var body = document.querySelector("body"), val = prompt("Global Code Wrap (true/false):", globalWrap); globalWrap = /^t/.test(val); GM_setValue("github-global-code-wrap", globalWrap); if (!globalWrap) { body.classList.add("nowrap"); } else { body.classList.remove("nowrap"); } }); init(); } })();