index.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. Object.defineProperty(exports, "__esModule", {
  4. value: true
  5. });
  6. exports.default = void 0;
  7. var _toggleSelection = _interopRequireDefault(require("./toggle-selection"));
  8. const clipboardToIE11Formatting = {
  9. 'text/plain': 'Text',
  10. 'text/html': 'Url',
  11. default: 'Text'
  12. };
  13. const defaultMessage = 'Copy to clipboard: #{key}, Enter';
  14. function format(message) {
  15. const copyKey = (/mac os x/i.test(navigator.userAgent) ? '⌘' : 'Ctrl') + '+C';
  16. return message.replace(/#{\s*key\s*}/g, copyKey);
  17. }
  18. function copy(text, options) {
  19. let message,
  20. reselectPrevious,
  21. range,
  22. selection,
  23. mark,
  24. success = false;
  25. if (!options) {
  26. options = {};
  27. }
  28. const debug = options.debug || false;
  29. try {
  30. reselectPrevious = (0, _toggleSelection.default)();
  31. range = document.createRange();
  32. selection = document.getSelection();
  33. mark = document.createElement('span');
  34. mark.textContent = text;
  35. // reset user styles for span element
  36. mark.style.all = 'unset';
  37. // prevents scrolling to the end of the page
  38. mark.style.position = 'fixed';
  39. mark.style.top = 0;
  40. mark.style.clip = 'rect(0, 0, 0, 0)';
  41. // used to preserve spaces and line breaks
  42. mark.style.whiteSpace = 'pre';
  43. // do not inherit user-select (it may be `none`)
  44. mark.style.webkitUserSelect = 'text';
  45. mark.style.MozUserSelect = 'text';
  46. mark.style.msUserSelect = 'text';
  47. mark.style.userSelect = 'text';
  48. mark.addEventListener('copy', function (e) {
  49. e.stopPropagation();
  50. if (options.format) {
  51. e.preventDefault();
  52. if (typeof e.clipboardData === 'undefined') {
  53. // IE 11
  54. debug && console.warn('unable to use e.clipboardData');
  55. debug && console.warn('trying IE specific stuff');
  56. window.clipboardData.clearData();
  57. const format = clipboardToIE11Formatting[options.format] || clipboardToIE11Formatting['default'];
  58. window.clipboardData.setData(format, text);
  59. } else {
  60. // all other browsers
  61. e.clipboardData.clearData();
  62. e.clipboardData.setData(options.format, text);
  63. }
  64. }
  65. if (options.onCopy) {
  66. e.preventDefault();
  67. options.onCopy(e.clipboardData);
  68. }
  69. });
  70. document.body.appendChild(mark);
  71. range.selectNodeContents(mark);
  72. selection.addRange(range);
  73. const successful = document.execCommand('copy');
  74. if (!successful) {
  75. throw new Error('copy command was unsuccessful');
  76. }
  77. success = true;
  78. } catch (err) {
  79. debug && console.error('unable to copy using execCommand: ', err);
  80. debug && console.warn('trying IE specific stuff');
  81. try {
  82. window.clipboardData.setData(options.format || 'text', text);
  83. options.onCopy && options.onCopy(window.clipboardData);
  84. success = true;
  85. } catch (err) {
  86. debug && console.error('unable to copy using clipboardData: ', err);
  87. debug && console.error('falling back to prompt');
  88. message = format('message' in options ? options.message : defaultMessage);
  89. window.prompt(message, text);
  90. }
  91. } finally {
  92. if (selection) {
  93. if (typeof selection.removeRange == 'function') {
  94. selection.removeRange(range);
  95. } else {
  96. selection.removeAllRanges();
  97. }
  98. }
  99. if (mark) {
  100. document.body.removeChild(mark);
  101. }
  102. reselectPrevious();
  103. }
  104. return success;
  105. }
  106. var _default = exports.default = copy;