clipboard-polyfill
Version:
A polyfill for the asynchronous clipboard API
242 lines (231 loc) • 7.62 kB
JavaScript
// src/clipboard-polyfill/ClipboardItem/data-types.ts
var TEXT_PLAIN = "text/plain";
// src/clipboard-polyfill/debug.ts
var debugLogImpl = function(s) {
};
function debugLog(s) {
debugLogImpl(s);
}
function warnOrLog() {
(console.warn || console.log).apply(console, arguments);
}
var warn = warnOrLog.bind("[clipboard-polyfill]");
// src/clipboard-polyfill/builtins/window-globalThis.ts
var originalWindow = typeof window === "undefined" ? void 0 : window;
var originalGlobalThis = typeof globalThis === "undefined" ? void 0 : globalThis;
// src/clipboard-polyfill/builtins/promise-constructor.ts
var _a, _b, _c;
var promiseConstructorImpl = (_c = (_a = originalWindow) == null ? void 0 : _a.Promise) != null ? _c : (_b = originalGlobalThis) == null ? void 0 : _b.Promise;
function getPromiseConstructor() {
if (!promiseConstructorImpl) {
throw new Error(
"No `Promise` implementation available for `clipboard-polyfill`. Consider using: https://github.com/lgarron/clipboard-polyfill#flat-file-version-with-promise-included"
);
}
return promiseConstructorImpl;
}
// src/clipboard-polyfill/builtins/builtin-globals.ts
var originalNavigator = typeof navigator === "undefined" ? void 0 : navigator;
var originalNavigatorClipboard = originalNavigator == null ? void 0 : originalNavigator.clipboard;
var _a2;
var originalNavigatorClipboardRead = (_a2 = originalNavigatorClipboard == null ? void 0 : originalNavigatorClipboard.read) == null ? void 0 : _a2.bind(
originalNavigatorClipboard
);
var _a3;
var originalNavigatorClipboardReadText = (_a3 = originalNavigatorClipboard == null ? void 0 : originalNavigatorClipboard.readText) == null ? void 0 : _a3.bind(
originalNavigatorClipboard
);
var _a4;
var originalNavigatorClipboardWrite = (_a4 = originalNavigatorClipboard == null ? void 0 : originalNavigatorClipboard.write) == null ? void 0 : _a4.bind(
originalNavigatorClipboard
);
var _a5;
var originalNavigatorClipboardWriteText = (_a5 = originalNavigatorClipboard == null ? void 0 : originalNavigatorClipboard.writeText) == null ? void 0 : _a5.bind(
originalNavigatorClipboard
);
var _a6;
var originalWindowClipboardItem = (_a6 = originalWindow) == null ? void 0 : _a6.ClipboardItem;
var promiseConstructor = getPromiseConstructor();
// src/clipboard-polyfill/strategies/internet-explorer.ts
var ieWindow = originalWindow;
function seemToBeInIE() {
return typeof ClipboardEvent === "undefined" && typeof (ieWindow == null ? void 0 : ieWindow.clipboardData) !== "undefined" && typeof (ieWindow == null ? void 0 : ieWindow.clipboardData.setData) !== "undefined";
}
function writeTextIE(text) {
if (!ieWindow.clipboardData) {
return false;
}
var success = ieWindow.clipboardData.setData("Text", text);
if (success) {
debugLog("writeTextIE worked");
}
return success;
}
// src/clipboard-polyfill/strategies/dom.ts
function copyListener(tracker, data, e) {
debugLog("listener called");
tracker.success = true;
for (var type in data) {
var value = data[type];
var clipboardData = e.clipboardData;
clipboardData.setData(type, value);
if (type === TEXT_PLAIN && clipboardData.getData(type) !== value) {
debugLog("setting text/plain failed");
tracker.success = false;
}
}
e.preventDefault();
}
function execCopy(data) {
var tracker = { success: false };
var listener = copyListener.bind(this, tracker, data);
document.addEventListener("copy", listener);
try {
document.execCommand("copy");
} finally {
document.removeEventListener("copy", listener);
}
return tracker.success;
}
function copyUsingTempSelection(e, data) {
selectionSet(e);
var success = execCopy(data);
selectionClear();
return success;
}
function copyUsingTempElem(data) {
var tempElem = document.createElement("div");
tempElem.setAttribute("style", "-webkit-user-select: text !important");
tempElem.textContent = "temporary element";
document.body.appendChild(tempElem);
var success = copyUsingTempSelection(tempElem, data);
document.body.removeChild(tempElem);
return success;
}
function copyTextUsingDOM(str) {
debugLog("copyTextUsingDOM");
var tempElem = document.createElement("div");
tempElem.setAttribute("style", "-webkit-user-select: text !important");
var spanParent = tempElem;
if (tempElem.attachShadow) {
debugLog("Using shadow DOM.");
spanParent = tempElem.attachShadow({ mode: "open" });
}
var span = document.createElement("span");
span.innerText = str;
spanParent.appendChild(span);
document.body.appendChild(tempElem);
selectionSet(span);
var result = document.execCommand("copy");
selectionClear();
document.body.removeChild(tempElem);
return result;
}
function selectionSet(elem) {
var sel = document.getSelection();
if (sel) {
var range = document.createRange();
range.selectNodeContents(elem);
sel.removeAllRanges();
sel.addRange(range);
}
}
function selectionClear() {
var sel = document.getSelection();
if (sel) {
sel.removeAllRanges();
}
}
// src/clipboard-polyfill/implementations/write-fallback.ts
function writeFallback(stringItem) {
var hasTextPlain = TEXT_PLAIN in stringItem;
if (seemToBeInIE()) {
if (!hasTextPlain) {
throw new Error("No `text/plain` value was specified.");
}
if (writeTextIE(stringItem[TEXT_PLAIN])) {
return true;
} else {
throw new Error("Copying failed, possibly because the user rejected it.");
}
}
if (execCopy(stringItem)) {
debugLog("regular execCopy worked");
return true;
}
if (navigator.userAgent.indexOf("Edge") > -1) {
debugLog('UA "Edge" => assuming success');
return true;
}
if (copyUsingTempSelection(document.body, stringItem)) {
debugLog("copyUsingTempSelection worked");
return true;
}
if (copyUsingTempElem(stringItem)) {
debugLog("copyUsingTempElem worked");
return true;
}
if (copyTextUsingDOM(stringItem[TEXT_PLAIN])) {
debugLog("copyTextUsingDOM worked");
return true;
}
return false;
}
// src/clipboard-polyfill/promise/promise-compat.ts
var voidPromise = promiseConstructor.resolve();
var falsePromise = promiseConstructor.resolve(false);
function rejectThrownErrors(executor) {
return new promiseConstructor(function(resolve, reject) {
try {
resolve(executor());
} catch (e) {
reject(e);
}
});
}
// src/clipboard-polyfill/implementations/text.ts
function stringToStringItem(s) {
var stringItem = {};
stringItem[TEXT_PLAIN] = s;
return stringItem;
}
function writeText(s) {
if (originalNavigatorClipboardWriteText) {
debugLog("Using `navigator.clipboard.writeText()`.");
return originalNavigatorClipboardWriteText(s).catch(
function() {
return writeTextStringFallbackPromise(s);
}
);
}
return writeTextStringFallbackPromise(s);
}
function writeTextStringFallbackPromise(s) {
return rejectThrownErrors(
function() {
return promiseConstructor.resolve(writeTextStringFallback(s));
}
);
}
function writeTextStringFallback(s) {
if (!writeFallback(stringToStringItem(s))) {
throw new Error("writeText() failed");
}
}
// src/demo/readme-examples/main.ts
function handler() {
writeText("This text is plain.").then(
function() {
console.log("success!");
},
function() {
console.log("error!");
}
);
}
window.addEventListener("DOMContentLoaded", function() {
var button = document.body.appendChild(document.createElement("button"));
button.textContent = "Copy";
button.addEventListener("click", handler);
});
//# sourceMappingURL=main.js.map