cilium
136 строк · 5.1 Кб
1function runWhenDOMLoaded(cb) {2if (document.readyState !== "loading") {3cb();4} else if (document.addEventListener) {5document.addEventListener("DOMContentLoaded", cb);6} else {7document.attachEvent("onreadystatechange", function() {8if (document.readyState == "complete") cb();9});10}11}
12
13function codeCellId(index) {14return "codecell" + index;15}
16
17function clearSelection() {18if (window.getSelection) {19window.getSelection().removeAllRanges();20} else if (document.selection) {21document.selection.empty();22}23}
24
25function addCopyButtonToCodeCells() {26if (window.ClipboardJS === undefined) {27setTimeout(addCopyButtonToCodeCells, 1000);28return;29}30const promptRegExp = /^\s*(\$|#)\s/;31var codeCells = document.querySelectorAll(".rst-content pre");32codeCells.forEach(function(codeCell, index) {33var wrapper = document.createElement("div");34wrapper.className = "code-wrapper";35codeCell.parentNode.insertBefore(wrapper, codeCell);36wrapper.appendChild(codeCell);37var id = codeCellId(index);38codeCell.setAttribute("id", id);39function clipboardButton(id) {40var lines = codeCell.textContent.trim().split("\n");41var linesCount = lines.length;42var buttonHtml = [];43buttonHtml.push('<div class="copybutton-wrapper">');44buttonHtml.push(45'<img class="copy-icon" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAMAAABF0y+mAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAACiUExURUdwTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJkEv5MAAAA1dFJOUwAwnr/H5BShnG3DCRPPm5OdyC4jGzHhB7o4AmkDyTJE1vn6ymWjbAHtTIQE6dwNoGH71I2zlJ78SQAAAI9JREFUKM/t0kcOwkAMhWGnTZhUOoQWeu8w979aJEDiOWhGOQD/wpL1LbwxER32ivUU9E0e6zXsngDOfWLJGBZVwl36i6H4FL3mCDGfeqygDegkFjYZ9wEbQ37ZVoCu5Oj/sSLaBnSCTjPUYSv2upkOqSeigRbJcPPdYs1xNYMlPbHvvWyXgOcHe/vbdUPmCj5KFX8s6tJBAAAAAElFTkSuQmCC" alt="" />'46);47buttonHtml.push(48'<a class="copybutton" data-clipboard-mode="first-line" data-clipboard-target="#' +49id +50'">'51);52buttonHtml.push(linesCount > 1 ? "Copy First Line" : "Copy Line");53buttonHtml.push("</a>");54if (linesCount > 1) {55/*56* Add a button to print commands for literal and code blocks that may
57* have prompt symbols to distinguish the commands from their output.
58*
59* Add it to:
60* - "code-block" with language "shell-session", with a parent of class
61* ".highlight-shell-session"
62* - Literal blocks ("::"), with a parent of class ".highlight-default"
63* - Parsed literal blocks, with a parent of class ".literal-block"
64*
65* Do not add it to a "code-block" with a language other than
66* "shell-session".
67*/
68if (codeCell.closest(".highlight-shell-session") ||69codeCell.closest(".highlight-default") ||70codeCell.closest("literal-block")) {71for (const l of lines) {72/* Additionally, only add button if we find at least one command */73if (promptRegExp.test(l)) {74buttonHtml.push(75'<a class="copybutton" data-clipboard-mode="commands" data-clipboard-target="#' +76id +77'">'78);79buttonHtml.push("Copy Commands");80buttonHtml.push("</a>");81break;82}83}84}85
86buttonHtml.push(87'<a class="copybutton" data-clipboard-mode="all" data-clipboard-target="#' +88id +89'">'90);91buttonHtml.push("Copy All");92buttonHtml.push("</a>");93}94buttonHtml.push("</div>");95return buttonHtml.join("\n");96}97codeCell.insertAdjacentHTML("afterend", clipboardButton(id));98});99
100new ClipboardJS(".copybutton", {101text: function(trigger) {102var parent = trigger.parentNode.parentNode;103var code = parent.querySelector("pre");104var mode = trigger.getAttribute("data-clipboard-mode");105if (mode === "first-line") {106return code.textContent107.split("\n")[0]108.trim()109.replace(/^\$/, "")110.trim();111} else if (mode === "commands") {112/*113* Copy lines with "commands": each line starting with a prompt symbol
114* ($ or #), plus the continuation lines, for commands ending with a
115* backslash.
116*/
117var cmds = "";118var continuation = false;119var lines = code.textContent.split("\n");120for (const l of lines) {121if (promptRegExp.test(l) || continuation) {122/* Keep line but remove prompt */123cmds += l.replace(promptRegExp, "") + "\n";124/* Expect a continuation line if command ends with a backslash */125continuation = /\\\s*$/.test(l);126}127}128return cmds;129} else {130return code.textContent;131}132}133});134}
135
136runWhenDOMLoaded(addCopyButtonToCodeCells);137