@iicoding/utils
Version:
Browser 端 - 类型判断 - 类似 koa 的异步compose - sleep - 扩展对象属性 - 扩展 storage 对象功能
118 lines (117 loc) • 4 kB
JavaScript
import { toggleSelection } from "./toggle-selection";
var clipboardToIE11Formatting = {
'text/plain': 'Text',
'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);
}
export function copy(text, options) {
var debug,
message,
reselectPrevious,
range,
selection,
mark,
success = false;
if (!options) {
options = {};
}
// eslint-disable-next-line prefer-const
debug = options.debug || false;
try {
reselectPrevious = toggleSelection();
range = document.createRange();
// @ts-ignore
selection = document.getSelection();
mark = document.createElement('span');
mark.textContent = text;
// avoid screen readers from reading out loud the text
mark.ariaHidden = 'true';
// reset user styles for span element
mark.style.all = 'unset';
// prevents scrolling to the end of the page
mark.style.position = 'fixed';
mark.style.top = '0';
mark.style.clip = 'rect(0, 0, 0, 0)';
// used to preserve spaces and line breaks
mark.style.whiteSpace = 'pre';
// do not inherit user-select (it may be `none`)
mark.style.webkitUserSelect = 'text';
// @ts-ignore
mark.style.MozUserSelect = 'text';
// @ts-ignore
mark.style.msUserSelect = 'text';
mark.style.userSelect = 'text';
mark.addEventListener('copy', function (e) {
var _options, _options2;
e.stopPropagation();
if ((_options = options) !== null && _options !== void 0 && _options.format) {
e.preventDefault();
if (typeof e.clipboardData === 'undefined') {
// IE 11
debug && console.warn('unable to use e.clipboardData');
debug && console.warn('trying IE specific stuff');
// @ts-ignore
window.clipboardData.clearData();
var _format = clipboardToIE11Formatting[options.format] || clipboardToIE11Formatting['default'];
// @ts-ignore
window.clipboardData.setData(_format, text);
} else {
var _e$clipboardData, _e$clipboardData2;
// all other browsers
(_e$clipboardData = e.clipboardData) === null || _e$clipboardData === void 0 || _e$clipboardData.clearData();
(_e$clipboardData2 = e.clipboardData) === null || _e$clipboardData2 === void 0 || _e$clipboardData2.setData(options.format, text);
}
}
if ((_options2 = options) !== null && _options2 !== void 0 && _options2.onCopy) {
e.preventDefault();
options.onCopy(e.clipboardData);
}
});
document.body.appendChild(mark);
range.selectNodeContents(mark);
selection.addRange(range);
var successful = document.execCommand('copy');
if (!successful) {
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 {
// @ts-ignore
window.clipboardData.setData(options.format || 'text', text);
// @ts-ignore
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 {
// @ts-ignore
if (selection) {
if (typeof selection.removeRange == 'function') {
// @ts-ignore
selection.removeRange(range);
} else {
selection.removeAllRanges();
}
}
// @ts-ignore
if (mark) {
document.body.removeChild(mark);
}
// @ts-ignore
reselectPrevious();
}
return success;
}
export default copy;