|
9 | 9 | return; |
10 | 10 | } |
11 | 11 |
|
12 | | - var ClipboardJS = window.ClipboardJS || undefined; |
13 | | - |
14 | | - if (!ClipboardJS && typeof require === 'function') { |
15 | | - ClipboardJS = require('clipboard'); |
| 12 | + /** |
| 13 | + * When the given elements is clicked by the user, the given text will be copied to clipboard. |
| 14 | + * |
| 15 | + * @param {HTMLElement} element |
| 16 | + * @param {CopyInfo} copyInfo |
| 17 | + * |
| 18 | + * @typedef CopyInfo |
| 19 | + * @property {() => string} getText |
| 20 | + * @property {() => void} success |
| 21 | + * @property {(reason: unknown) => void} error |
| 22 | + */ |
| 23 | + function registerClipboard(element, copyInfo) { |
| 24 | + element.addEventListener('click', function () { |
| 25 | + copyTextToClipboard(copyInfo); |
| 26 | + }); |
16 | 27 | } |
17 | 28 |
|
18 | | - var callbacks = []; |
| 29 | + // https://stackoverflow.com/a/30810322/7595472 |
| 30 | + |
| 31 | + /** @param {CopyInfo} copyInfo */ |
| 32 | + function fallbackCopyTextToClipboard(copyInfo) { |
| 33 | + var textArea = document.createElement("textarea"); |
| 34 | + textArea.value = copyInfo.getText(); |
19 | 35 |
|
20 | | - if (!ClipboardJS) { |
21 | | - var script = document.createElement('script'); |
22 | | - var head = document.querySelector('head'); |
| 36 | + // Avoid scrolling to bottom |
| 37 | + textArea.style.top = "0"; |
| 38 | + textArea.style.left = "0"; |
| 39 | + textArea.style.position = "fixed"; |
23 | 40 |
|
24 | | - script.onload = function () { |
25 | | - ClipboardJS = window.ClipboardJS; |
| 41 | + document.body.appendChild(textArea); |
| 42 | + textArea.focus(); |
| 43 | + textArea.select(); |
26 | 44 |
|
27 | | - if (ClipboardJS) { |
28 | | - while (callbacks.length) { |
29 | | - callbacks.pop()(); |
| 45 | + try { |
| 46 | + var successful = document.execCommand('copy'); |
| 47 | + setTimeout(function () { |
| 48 | + if (successful) { |
| 49 | + copyInfo.success(); |
| 50 | + } else { |
| 51 | + copyInfo.error(); |
30 | 52 | } |
31 | | - } |
32 | | - }; |
| 53 | + }, 1); |
| 54 | + } catch (err) { |
| 55 | + setTimeout(function () { |
| 56 | + copyInfo.error(err); |
| 57 | + }, 1); |
| 58 | + } |
33 | 59 |
|
34 | | - script.src = 'https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js'; |
35 | | - head.appendChild(script); |
| 60 | + document.body.removeChild(textArea); |
| 61 | + } |
| 62 | + /** @param {CopyInfo} copyInfo */ |
| 63 | + function copyTextToClipboard(copyInfo) { |
| 64 | + if (navigator.clipboard) { |
| 65 | + navigator.clipboard.writeText(copyInfo.getText()).then(copyInfo.success, copyInfo.error); |
| 66 | + } else { |
| 67 | + fallbackCopyTextToClipboard(copyInfo); |
| 68 | + } |
| 69 | + } |
| 70 | + |
| 71 | + /** |
| 72 | + * Selects the text content of the given element. |
| 73 | + * |
| 74 | + * @param {Element} element |
| 75 | + */ |
| 76 | + function selectElementText(element) { |
| 77 | + // https://stackoverflow.com/a/20079910/7595472 |
| 78 | + window.getSelection().selectAllChildren(element) |
36 | 79 | } |
37 | 80 |
|
38 | 81 | /** |
|
74 | 117 | linkCopy.textContent = settings['copy']; |
75 | 118 | linkCopy.setAttribute('type', 'button'); |
76 | 119 |
|
77 | | - if (!ClipboardJS) { |
78 | | - callbacks.push(registerClipboard); |
79 | | - } else { |
80 | | - registerClipboard(); |
81 | | - } |
82 | | - |
83 | | - return linkCopy; |
84 | | - |
85 | | - function registerClipboard() { |
86 | | - var clip = new ClipboardJS(linkCopy, { |
87 | | - 'text': function () { |
88 | | - return element.textContent; |
89 | | - } |
90 | | - }); |
91 | | - |
92 | | - clip.on('success', function () { |
| 120 | + registerClipboard(linkCopy, { |
| 121 | + getText: function () { |
| 122 | + return element.textContent; |
| 123 | + }, |
| 124 | + success: function () { |
93 | 125 | linkCopy.textContent = settings['copy-success']; |
94 | 126 |
|
95 | 127 | resetText(); |
96 | | - }); |
97 | | - clip.on('error', function () { |
| 128 | + }, |
| 129 | + error: function () { |
98 | 130 | linkCopy.textContent = settings['copy-error']; |
99 | 131 |
|
| 132 | + setTimeout(function () { |
| 133 | + selectElementText(element); |
| 134 | + }, 1); |
| 135 | + |
100 | 136 | resetText(); |
101 | | - }); |
102 | | - } |
| 137 | + } |
| 138 | + }); |
| 139 | + |
| 140 | + return linkCopy; |
103 | 141 |
|
104 | 142 | function resetText() { |
105 | 143 | setTimeout(function () { |
|
0 commit comments