forked from arronhunt/highlightjs-copy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
118 lines (106 loc) · 4.02 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/**
* @file highlight-copy.js
* @author Arron Hunt <[email protected]>
* @copyright Copyright 2021. All rights reserved.
*/
/**
* Adds a copy button to highlightjs code blocks
*/
class CopyButtonPlugin {
/**
* Create a new CopyButtonPlugin class instance
* @param {Object} [options] - Functions that will be called when a copy event fires
* @param {CopyCallback} [options.callback]
* @param {Hook} [options.hook]
* @param {String} [options.lang] Defaults to the document body's lang attribute and falls back to "en"
*/
// https://github.com/arronhunt/highlightjs-copy/pull/24
constructor(options = {}) {
this.hook = options.hook;
this.callback = options.callback;
this.lang = options.lang || document.documentElement.lang || "en";
this.autohide =
typeof options.autohide !== "undefined" ? options.autohide : true;
}
"after:highlightElement"({ el, text }) {
let { hook, callback, lang, autohide } = this;
// Create the copy button and append it to the codeblock.
let button = Object.assign(document.createElement("button"), {
innerHTML: locales[lang]?.[0] || "Copy",
className: "hljs-copy-button",
});
button.dataset.copied = false;
button.dataset.autohide = autohide;
el.parentElement.classList.add("hljs-copy-wrapper");
el.parentElement.appendChild(button);
// Add a custom proprety to the code block so that the copy button can reference and match its background-color value.
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;
}, 2000);
})
.then(function () {
if (typeof callback === "function") return callback(newText, el);
});
};
}
}
// Check if the NodeJS environment is available before exporting the class
if (typeof module != "undefined") {
module.exports = CopyButtonPlugin;
}
/**
* Basic support for localization. Please submit a PR
* to help add more languages.
* https://github.com/arronhunt/highlightjs-copy/pulls
*/
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": ["複製", "已複製!", "已複製到剪貼簿"],
};
/**
* @typedef {function} CopyCallback
* @param {string} text - The raw text copied to the clipboard.
* @param {HTMLElement} el - The code block element that was copied from.
* @returns {undefined}
*/
/**
* @typedef {function} Hook
* @param {string} text - The raw text copied to the clipboard.
* @param {HTMLElement} el - The code block element that was copied from.
* @returns {string|undefined}
*/