diff --git a/src/main/java/run/halo/highlightjs/HighlightJSHeadProcessor.java b/src/main/java/run/halo/highlightjs/HighlightJSHeadProcessor.java
index f17604d..1288f75 100644
--- a/src/main/java/run/halo/highlightjs/HighlightJSHeadProcessor.java
+++ b/src/main/java/run/halo/highlightjs/HighlightJSHeadProcessor.java
@@ -75,8 +75,8 @@ private String highlightJsScript(BasicConfig basicConfig) {
-
-
+
+
diff --git a/src/main/resources/static/plugins/highlightjs-copy.css b/src/main/resources/static/plugins/highlightjs-copy.css
new file mode 100644
index 0000000..cd3a93f
--- /dev/null
+++ b/src/main/resources/static/plugins/highlightjs-copy.css
@@ -0,0 +1,61 @@
+.hljs-copy-wrapper {
+ position: relative;
+ overflow: hidden;
+}
+.hljs-copy-wrapper:hover .hljs-copy-button,
+.hljs-copy-button:focus {
+ transform: translateX(0);
+}
+.hljs-copy-button {
+ position: absolute;
+ transform: translateX(calc(100% + 1.125em));
+ top: 0.5em;
+ right: 0.5em;
+ width: 2rem;
+ height: 2rem;
+ text-indent: -9999px;
+ color: var(--hljs-theme-color);
+ border-radius: 0.25rem;
+ border: 1px solid;
+ border-color: color-mix(in srgb, var(--hljs-theme-color), transparent 80%);
+ background-color: var(--hljs-theme-background);
+ transition: background-color 200ms ease, transform 200ms ease-out;
+ overflow: hidden;
+}
+.hljs-copy-button:not([data-copied="true"])::before {
+ content: "";
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ background-color: currentColor;
+ mask: url('data:image/svg+xml;utf-8,');
+ mask-repeat: no-repeat;
+ mask-size: 1rem;
+ mask-position: center center;
+}
+.hljs-copy-button:hover {
+ background-color: color-mix(in srgb, var(--hljs-theme-color), transparent 90%);
+}
+.hljs-copy-button:active {
+ border-color: color-mix(in srgb, var(--hljs-theme-color), transparent 60%);
+}
+.hljs-copy-button[data-copied="true"] {
+ text-indent: 0;
+ width: auto;
+}
+@media (prefers-reduced-motion) {
+ .hljs-copy-button {
+ transition: none;
+ }
+}
+.hljs-copy-alert {
+ clip: rect(0 0 0 0);
+ clip-path: inset(50%);
+ height: 1px;
+ overflow: hidden;
+ position: absolute;
+ white-space: nowrap;
+ width: 1px;
+}
diff --git a/src/main/resources/static/plugins/highlightjs-copy.js b/src/main/resources/static/plugins/highlightjs-copy.js
new file mode 100644
index 0000000..a257c0b
--- /dev/null
+++ b/src/main/resources/static/plugins/highlightjs-copy.js
@@ -0,0 +1,82 @@
+class CopyButtonPlugin {
+ constructor(options = {}) {
+ self.hook = options.hook;
+ self.callback = options.callback;
+ self.lang = options.lang || document.documentElement.lang || "en";
+ }
+ "after:highlightElement"({ el, text }) {
+ let button = Object.assign(document.createElement("button"), {
+ innerHTML: locales[lang]?.[0] || "Copy",
+ className: "hljs-copy-button",
+ });
+ button.dataset.copied = false;
+ el.parentElement.classList.add("hljs-copy-wrapper");
+ el.parentElement.appendChild(button);
+ el.parentElement.style.setProperty("--hljs-theme-background", window.getComputedStyle(el).backgroundColor);
+ el.parentElement.style.setProperty("--hljs-theme-color", window.getComputedStyle(el).color);
+ button.onclick = function () {
+ let newText = text;
+
+ if (hook && typeof hook === "function") {
+ newText = hook(text, el) || text;
+ }
+
+ const copyText = () => {
+ if (navigator.clipboard) {
+ return navigator.clipboard.writeText(newText);
+ } else {
+ const textArea = document.createElement("textarea");
+ textArea.value = newText;
+ textArea.style.position = "fixed";
+ document.body.appendChild(textArea);
+ textArea.focus();
+ textArea.select();
+
+ try {
+ const successful = document.execCommand("copy");
+ document.body.removeChild(textArea);
+ return successful ? Promise.resolve() : Promise.reject();
+ } catch (err) {
+ document.body.removeChild(textArea);
+ return Promise.reject(err);
+ }
+ }
+ };
+
+ copyText()
+ .then(function () {
+ button.innerHTML = locales[lang]?.[1] || "Copied!";
+ button.dataset.copied = true;
+ let alert = Object.assign(document.createElement("div"), {
+ role: "status",
+ className: "hljs-copy-alert",
+ innerHTML: locales[lang]?.[2] || "Copied to clipboard",
+ });
+ el.parentElement.appendChild(alert);
+ setTimeout(() => {
+ button.innerHTML = locales[lang]?.[0] || "Copy";
+ button.dataset.copied = false;
+ el.parentElement.removeChild(alert);
+ alert = null;
+ }, 2e3);
+ })
+ .then(function () {
+ if (typeof callback === "function") return callback(newText, el);
+ });
+ };
+ }
+}
+if (typeof module != "undefined") {
+ module.exports = CopyButtonPlugin;
+}
+const locales = {
+ en: ["Copy", "Copied!", "Copied to clipboard"],
+ es: ["Copiar", "¡Copiado!", "Copiado al portapapeles"],
+ fr: ["Copier", "Copié !", "Copié dans le presse-papier"],
+ de: ["Kopieren", "Kopiert!", "In die Zwischenablage kopiert"],
+ ja: ["コピー", "コピーしました!", "クリップボードにコピーしました"],
+ ko: ["복사", "복사됨!", "클립보드에 복사됨"],
+ ru: ["Копировать", "Скопировано!", "Скопировано в буфер обмена"],
+ zh: ["复制", "已复制!", "已复制到剪贴板"],
+ "zh-tw": ["複製", "已複製!", "已複製到剪貼簿"],
+};
diff --git a/src/main/resources/static/plugins/highlightjs-copy.min.css b/src/main/resources/static/plugins/highlightjs-copy.min.css
deleted file mode 100644
index 6ea1128..0000000
--- a/src/main/resources/static/plugins/highlightjs-copy.min.css
+++ /dev/null
@@ -1 +0,0 @@
-.hljs-copy-wrapper{position:relative;overflow:hidden}.hljs-copy-wrapper:hover .hljs-copy-button,.hljs-copy-button:focus{transform:translateX(0)}.hljs-copy-button{position:absolute;transform:translateX(calc(100% + 1.125em));top:.5em;right:.5em;width:2rem;height:2rem;text-indent:-9999px;color:var(--hljs-theme-color);border-radius:.25rem;border:1px solid;border-color:color-mix(in srgb,var(--hljs-theme-color),transparent 80%);background-color:var(--hljs-theme-background);transition:background-color 200ms ease,transform 200ms ease-out;overflow:hidden}.hljs-copy-button:not([data-copied="true"])::before{content:"";top:0;left:0;width:100%;height:100%;position:absolute;background-color:currentColor;mask:url('data:image/svg+xml;utf-8,');mask-repeat:no-repeat;mask-size:1rem;mask-position:center center}.hljs-copy-button:hover{background-color:color-mix(in srgb,var(--hljs-theme-color),transparent 90%)}.hljs-copy-button:active{border-color:color-mix(in srgb,var(--hljs-theme-color),transparent 60%)}.hljs-copy-button[data-copied="true"]{text-indent:0;width:auto}@media(prefers-reduced-motion){.hljs-copy-button{transition:none}}.hljs-copy-alert{clip:rect(0 0 0 0);clip-path:inset(50%);height:1px;overflow:hidden;position:absolute;white-space:nowrap;width:1px}
diff --git a/src/main/resources/static/plugins/highlightjs-copy.min.js b/src/main/resources/static/plugins/highlightjs-copy.min.js
deleted file mode 100644
index 8621c5e..0000000
--- a/src/main/resources/static/plugins/highlightjs-copy.min.js
+++ /dev/null
@@ -1 +0,0 @@
-class CopyButtonPlugin{constructor(options={}){self.hook=options.hook;self.callback=options.callback;self.lang=options.lang||document.documentElement.lang||"en"}"after:highlightElement"({el,text}){let button=Object.assign(document.createElement("button"),{innerHTML:locales[lang]?.[0]||"Copy",className:"hljs-copy-button"});button.dataset.copied=false;el.parentElement.classList.add("hljs-copy-wrapper");el.parentElement.appendChild(button);el.parentElement.style.setProperty("--hljs-theme-background",window.getComputedStyle(el).backgroundColor);el.parentElement.style.setProperty("--hljs-theme-color",window.getComputedStyle(el).color);button.onclick=function(){if(!navigator.clipboard)return;let newText=text;if(hook&&typeof hook==="function"){newText=hook(text,el)||text}navigator.clipboard.writeText(newText).then(function(){button.innerHTML=locales[lang]?.[1]||"Copied!";button.dataset.copied=true;let alert=Object.assign(document.createElement("div"),{role:"status",className:"hljs-copy-alert",innerHTML:locales[lang]?.[2]||"Copied to clipboard"});el.parentElement.appendChild(alert);setTimeout(()=>{button.innerHTML=locales[lang]?.[0]||"Copy";button.dataset.copied=false;el.parentElement.removeChild(alert);alert=null},2e3)}).then(function(){if(typeof callback==="function")return callback(newText,el)})}}}if(typeof module!="undefined"){module.exports=CopyButtonPlugin}const locales={en:["Copy","Copied!","Copied to clipboard"],es:["Copiar","¡Copiado!","Copiado al portapapeles"],fr:["Copier","Copié !","Copié dans le presse-papier"],de:["Kopieren","Kopiert!","In die Zwischenablage kopiert"],ja:["コピー","コピーしました!","クリップボードにコピーしました"],ko:["복사","복사됨!","클립보드에 복사됨"],ru:["Копировать","Скопировано!","Скопировано в буфер обмена"],zh:["复制","已复制!","已复制到剪贴板"],"zh-tw":["複製","已複製!","已複製到剪貼簿"]};
\ No newline at end of file