123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- "use strict";
- var deselectCurrent = require("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);
- }
- function copy(text, options) {
- var debug,
- message,
- reselectPrevious,
- range,
- selection,
- mark,
- success = false;
- if (!options) {
- options = {};
- }
- debug = options.debug || false;
- try {
- reselectPrevious = deselectCurrent();
- range = document.createRange();
- 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";
- mark.style.MozUserSelect = "text";
- mark.style.msUserSelect = "text";
- mark.style.userSelect = "text";
- mark.addEventListener("copy", function(e) {
- e.stopPropagation();
- if (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");
- window.clipboardData.clearData();
- var format = clipboardToIE11Formatting[options.format] || clipboardToIE11Formatting["default"]
- window.clipboardData.setData(format, text);
- } else { // all other browsers
- e.clipboardData.clearData();
- e.clipboardData.setData(options.format, text);
- }
- }
- if (options.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 {
- window.clipboardData.setData(options.format || "text", 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();
- }
- return success;
- }
- module.exports = copy;
|