You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

clipboard.js 2.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. const {copy_success, copy_error} = window.config.i18n;
  2. function onSuccess(btn) {
  3. btn.setAttribute('data-variation', 'inverted tiny');
  4. $(btn).popup('destroy');
  5. const oldContent = btn.getAttribute('data-content');
  6. btn.setAttribute('data-content', copy_success);
  7. $(btn).popup('show');
  8. btn.setAttribute('data-content', oldContent || '');
  9. }
  10. function onError(btn) {
  11. btn.setAttribute('data-variation', 'inverted tiny');
  12. const oldContent = btn.getAttribute('data-content');
  13. $(btn).popup('destroy');
  14. btn.setAttribute('data-content', copy_error);
  15. $(btn).popup('show');
  16. btn.setAttribute('data-content', oldContent || '');
  17. }
  18. // Fallback to use if navigator.clipboard doesn't exist. Achieved via creating
  19. // a temporary textarea element, selecting the text, and using document.execCommand
  20. function fallbackCopyToClipboard(text) {
  21. if (!document.execCommand) return false;
  22. const tempTextArea = document.createElement('textarea');
  23. tempTextArea.value = text;
  24. // avoid scrolling
  25. tempTextArea.style.top = 0;
  26. tempTextArea.style.left = 0;
  27. tempTextArea.style.position = 'fixed';
  28. document.body.appendChild(tempTextArea);
  29. tempTextArea.select();
  30. // if unsecure (not https), there is no navigator.clipboard, but we can still
  31. // use document.execCommand to copy to clipboard
  32. const success = document.execCommand('copy');
  33. document.body.removeChild(tempTextArea);
  34. return success;
  35. }
  36. // For all DOM elements with [data-clipboard-target] or [data-clipboard-text],
  37. // this copy-to-clipboard will work for them
  38. export default function initGlobalCopyToClipboardListener() {
  39. document.addEventListener('click', (e) => {
  40. let target = e.target;
  41. // in case <button data-clipboard-text><svg></button>, so we just search
  42. // up to 3 levels for performance
  43. for (let i = 0; i < 3 && target; i++) {
  44. const text = target.getAttribute('data-clipboard-text') || document.querySelector(target.getAttribute('data-clipboard-target'))?.value;
  45. if (text) {
  46. e.preventDefault();
  47. (async() => {
  48. try {
  49. await navigator.clipboard.writeText(text);
  50. onSuccess(target);
  51. } catch {
  52. if (fallbackCopyToClipboard(text)) {
  53. onSuccess(target);
  54. } else {
  55. onError(target);
  56. }
  57. }
  58. })();
  59. break;
  60. }
  61. target = target.parentElement;
  62. }
  63. });
  64. }