fix: fix copy text

This commit is contained in:
fantasticit 2022-05-06 23:57:55 +08:00
parent c03d1ab00d
commit 009d7782a4
2 changed files with 49 additions and 136 deletions

View File

@ -3,143 +3,66 @@
var deselectCurrent = require('toggle-selection'); var deselectCurrent = require('toggle-selection');
var clipboardToIE11Formatting = { function copy(text, onCopy) {
'text/plain': 'Text', var reselectPrevious,
'text/html': 'Url',
'default': 'Text',
};
var defaultMessage = 'Copy to clipboard: #{key}, Enter';
function format(message) {
var copyKey = (/mac os x/i.test(navigator.userAgent) ? '⌘' : 'Ctrl') + '+C';
return message.replace(/#{\s*key\s*}/g, copyKey);
}
function copy(text, options) {
var debug,
message,
reselectPrevious,
range, range,
selection, selection,
mark, mark,
success = false; success = false;
if (!options) {
options = {};
}
debug = options.debug || false;
try {
reselectPrevious = deselectCurrent();
reselectPrevious = deselectCurrent();
range = document.createRange(); range = document.createRange();
selection = document.getSelection(); selection = document.getSelection();
mark = document.createElement('span'); mark = document.createElement('span');
mark.textContent = text; mark.textContent = text;
// reset user styles for span element
mark.style.all = 'unset'; mark.style.all = 'unset';
// prevents scrolling to the end of the page
mark.style.position = 'fixed'; mark.style.position = 'fixed';
mark.style.top = 0; mark.style.top = 0;
mark.style.clip = 'rect(0, 0, 0, 0)'; mark.style.clip = 'rect(0, 0, 0, 0)';
// used to preserve spaces and line breaks
mark.style.whiteSpace = 'pre'; mark.style.whiteSpace = 'pre';
// do not inherit user-select (it may be `none`)
mark.style.webkitUserSelect = 'text'; mark.style.webkitUserSelect = 'text';
mark.style.MozUserSelect = 'text'; mark.style.MozUserSelect = 'text';
mark.style.msUserSelect = 'text'; mark.style.msUserSelect = 'text';
mark.style.userSelect = 'text'; mark.style.userSelect = 'text';
mark.addEventListener('copy', function (e) { mark.addEventListener('copy', function (e) {
e.stopPropagation(); var data = [];
if (options.format) {
e.preventDefault(); if (typeof text === 'string') {
if (typeof e.clipboardData === 'undefined') { data = [{ format: 'text/plain', text: text }];
// IE 11 } else if (Array.isArray(text)) {
debug && console.warn('unable to use e.clipboardData');
debug && console.warn('trying IE specific stuff');
window.clipboardData.clearData();
var format = clipboardToIE11Formatting[options.format] || clipboardToIE11Formatting['default'];
if (Array.isArray(text)) {
text.forEach(function (item) { text.forEach(function (item) {
if (typeof item === 'string') { data.push({
window.clipboardData.setData(item, item); format: item.format || 'text/plain',
} else { text: item.text || item,
window.clipboardData.setData(item.format || format, item.text || item); });
}
}); });
} else { } else {
window.clipboardData.setData(format, text); data.push({
} format: 'text/plain',
} else { text: text,
// all other browsers
e.clipboardData.clearData();
if (Array.isArray(text)) {
text.forEach(function (item) {
if (typeof item === 'string') {
e.clipboardData.setData(item, item);
} else {
e.clipboardData.setData(item.format || format, item.text || item);
}
}); });
} else {
e.clipboardData.setData(format, text);
} }
}
} data.forEach(function (item) {
if (options.onCopy) { e.clipboardData.setData(item.format, item.text);
});
e.preventDefault(); e.preventDefault();
options.onCopy(e.clipboardData);
} onCopy && onCopy();
}); });
document.body.appendChild(mark); document.body.appendChild(mark);
range.selectNodeContents(mark); range.selectNodeContents(mark);
selection.addRange(range); selection.addRange(range);
var successful = document.execCommand('copy'); var successful = document.execCommand('copy');
if (!successful) { if (!successful) {
throw new Error('copy command was unsuccessful'); throw new Error('copy command was unsuccessful');
} }
success = true;
} catch (err) {
debug && console.error('unable to copy using execCommand: ', err);
debug && console.warn('trying IE specific stuff');
try {
if (Array.isArray(text)) {
text.forEach(function (item) {
if (typeof item === 'string') {
window.clipboardData.setData(item, item);
} else {
window.clipboardData.setData(item.format || format, item.text || item);
}
});
} else {
window.clipboardData.setData(format, text);
}
options.onCopy && options.onCopy(window.clipboardData);
success = true;
} catch (err) {
debug && console.error('unable to copy using clipboardData: ', err);
debug && console.error('falling back to prompt');
message = format('message' in options ? options.message : defaultMessage);
window.prompt(message, text);
}
} finally {
if (selection) {
if (typeof selection.removeRange == 'function') {
selection.removeRange(range);
} else {
selection.removeAllRanges();
}
}
if (mark) {
document.body.removeChild(mark);
}
reselectPrevious();
}
success = true;
return success; return success;
} }

View File

@ -1,16 +1,6 @@
import _copy from './copy-to-clipboard'; import _copy from './copy-to-clipboard';
import { Toast } from '@douyinfe/semi-ui'; import { Toast } from '@douyinfe/semi-ui';
interface Options { export function copy(text: string | { text: string; format: string }[]) {
debug?: boolean; return _copy(text, () => Toast.success('复制成功'));
message?: string;
format?: string; // MIME type
onCopy?: (clipboardData: object) => void;
}
export function copy(text: string | { text: string; format: string }[], options?: Options) {
options = options || {};
options.onCopy = options.onCopy || (() => Toast.success(options.message || '复制成功'));
options.format = options.format || 'text/plain';
return _copy(text, options);
} }