Ver código fonte

adding copy code function to codeblocks

Medowar 1 mês atrás
pai
commit
ecc6c0734c

+ 45 - 0
themes/tailwind-custom/css/style.css

@@ -150,4 +150,49 @@
 
 .recent-posts > ul {
 	padding-left: 15px;
+}
+
+/* Copy to clipboard button on code blocks */
+.prose pre:has(code) {
+	position: relative;
+}
+
+.prose pre .copy-code {
+	position: absolute;
+	top: .4rem;
+	right: .4rem;
+	padding: .35rem;
+	border: none;
+	border-radius: 6px;
+	background-color: transparent;
+	color: rgb(156 163 175);
+	line-height: 0;
+	cursor: pointer;
+	opacity: 0;
+	transition: opacity .2s ease, background-color .2s ease, color .2s ease;
+}
+
+.prose pre .copy-code svg {
+	display: block;
+	width: 1.05rem;
+	height: 1.05rem;
+	margin: 0;
+}
+
+.prose pre:hover .copy-code,
+.prose pre .copy-code:focus-visible {
+	opacity: .75;
+}
+
+.prose pre .copy-code:hover {
+	opacity: 1;
+	color: rgb(243 244 246);
+	background-color: rgb(75 85 99);
+}
+
+/* Touch devices have no hover, so keep the button visible. */
+@media (hover: none) {
+	.prose pre .copy-code {
+		opacity: 1;
+	}
 }

+ 55 - 2
themes/tailwind-custom/js/functions.js

@@ -21,6 +21,59 @@
 	sc &&
 		sc.addEventListener("click", function () {
 			document.body.classList.contains("is-search-open") ? document.body.classList.remove("is-search-open") : document.body.classList.add("is-search-open");
-		});	
-		
+		});
+
+})();
+
+/* Copy to clipboard button on code blocks */
+(function () {
+	function icon(paths) {
+		return (
+			'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" ' +
+			'stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">' +
+			paths +
+			"</svg>"
+		);
+	}
+
+	var copyIcon = icon('<rect x="8" y="8" width="14" height="14" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/>');
+	var doneIcon = icon('<path d="M20 6 9 17l-5-5"/>');
+	var failIcon = icon('<path d="M18 6 6 18"/><path d="m6 6 12 12"/>');
+
+	if (!navigator.clipboard) return;
+
+	document.querySelectorAll("pre").forEach(function (block) {
+		var code = block.querySelector("code");
+		if (!code) return;
+
+		var button = document.createElement("button");
+		button.className = "copy-code";
+		button.type = "button";
+		button.innerHTML = copyIcon;
+		button.title = "Copy code";
+		button.setAttribute("aria-label", "Copy code to clipboard");
+		block.appendChild(button);
+
+		button.addEventListener("click", function () {
+			navigator.clipboard.writeText(code.innerText).then(
+				function () {
+					button.innerHTML = doneIcon;
+					button.title = "Copied!";
+				},
+				function () {
+					button.innerHTML = failIcon;
+					button.title = "Copy failed";
+				}
+			);
+			setTimeout(function () {
+				button.innerHTML = copyIcon;
+				button.title = "Copy code";
+			}, 1000);
+		});
+
+		// Keep the button in place while the block scrolls horizontally.
+		block.addEventListener("scroll", function () {
+			button.style.transform = "translateX(" + block.scrollLeft + "px)";
+		});
+	});
 })();