forked from loilo-archive/HtmlToClipboard
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathhtml-to-clipboard.min.js
73 lines (73 loc) · 3.49 KB
/
html-to-clipboard.min.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
function HtmlToClipboard(options) {
let settings = {
limitTarget: null,
listenOnCopy: !1,
raw: !1
}, justCopied = !1;
if ("object" == typeof options) for (let option in options) settings[option] = options[option];
if ("boolean" != typeof settings.raw) throw "'raw' option must be boolean";
if (settings.limitTarget && "string" != typeof settings.limitTarget && !(settings.limitTarget instanceof HTMLElement)) throw "'target' option must be either a selector or a DOM node";
let getTarget = function(limitTarget) {
let target = limitTarget;
if ("string" == typeof target) {
let el = document.querySelector(target);
if (null === el) throw `Element with selector '${target}' does not exist in the DOM`;
return el;
}
if (document.contains(target)) return target;
throw "Target element is not present in the DOM";
}, getSelection = function(limitTarget) {
let selection = window.getSelection();
if (limitTarget) {
let target = getTarget(limitTarget);
if (void 0 !== target.selectionStart) return target.value.substring(target.selectionStart, target.selectionEnd);
for (let i = 0; i < selection.rangeCount; i++) {
let range = selection.getRangeAt(i), sliceStart = 0, sliceEnd = null;
if (range.intersectsNode(target)) {
let lengthBefore = range.toString().length;
range.setStart(target, 0);
let lengthAfter = range.toString().length;
return lengthAfter > lengthBefore && (sliceStart = lengthAfter - lengthBefore),
lengthBefore = range.toString().length, range.setEnd(target, target.childNodes.length),
lengthAfter = range.toString().length, sliceEnd = lengthAfter > lengthBefore ? lengthBefore : lengthAfter,
range.toString().substr(sliceStart, sliceEnd);
}
}
return "";
}
return void 0 !== document.activeElement.selectionStart ? document.activeElement.value.substring(document.activeElement.selectionStart, document.activeElement.selectionEnd) : selection.toString();
}, copyToClipboard = function(data, raw) {
"boolean" != typeof raw && (raw = !0);
let tmpEl = document.createElement(raw ? "textarea" : "div");
tmpEl.style.opacity = 0, tmpEl.style.position = "absolute", tmpEl.style.pointerEvents = "none",
tmpEl.style.zIndex = -1, tmpEl.setAttribute("tabindex", "-1"), tmpEl.innerHTML = data,
document.body.appendChild(tmpEl);
let focused = document.activeElement;
if (tmpEl.focus(), raw) tmpEl.select(); else {
window.getSelection().removeAllRanges();
let range = document.createRange();
range.setStartBefore(tmpEl.firstChild), range.setEndAfter(tmpEl.lastChild), window.getSelection().addRange(range);
}
let success = !1;
try {
justCopied = !0, setTimeout(function() {
justCopied = !1;
}), success = document.execCommand("copy");
} catch (err) {
console.error(err);
}
success || console.error("execCommand failed!"), window.getSelection().removeAllRanges(),
document.body.removeChild(tmpEl), focused.focus();
};
if (settings.listenOnCopy) {
let eventTarget = document;
settings.limitTarget && (eventTarget = getTarget(settings.limitTarget));
let self = this;
eventTarget.addEventListener("copy", function(e) {
justCopied || (e.preventDefault(), self.copy());
});
}
this.copy = function(data) {
"string" != typeof data && (data = getSelection(settings.limitTarget)), "" !== data && copyToClipboard(data, settings.raw);
};
}