clipboard-polyfill
Version:
A polyfill for the asynchronous clipboard API
193 lines (180 loc) • 6.97 kB
HTML
<html>
<head>
<meta charset="utf-8" />
<title>clipboard-polyfill</title>
<link rel="stylesheet" href="index.css">
<meta name="viewport" content="width=device-width, initial-scale=0.75">
<!-- NOTE: this is synchronous ES5, therefore no type="module" -->
<script src="./demo.js"></script>
<script>
// Workaround for:
// - IE9 (can't bind console functions directly), and
// - Edge Issue #14495220 (referencing `console` without F12 Developer Tools can cause an exception)
var infoOrLog = function () {
(console.info || console.log).apply(console, arguments);
};
// clipboard.setDebugLog(infoOrLog);
var imgBytes = [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0A, 0x08, 0x04, 0x00, 0x00, 0x00, 0x3D, 0x07, 0xE7,
0xB8, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xAE, 0xCE, 0x1C, 0xE9, 0x00, 0x00, 0x00, 0x02, 0x62, 0x4B, 0x47, 0x44, 0x00, 0xFF, 0x87, 0x8F, 0xCC, 0xBF, 0x00, 0x00, 0x00, 0x09,
0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0B, 0x13, 0x00, 0x00, 0x0B, 0x13, 0x01, 0x00, 0x9A, 0x9C, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4D, 0x45, 0x07, 0xDC, 0x03, 0x1B, 0x15, 0x1C, 0x15, 0xF8, 0xD7, 0x04, 0x97, 0x00, 0x00, 0x00, 0x19, 0x49, 0x44, 0x41, 0x54, 0x08, 0xD7, 0x63, 0x64, 0xF8, 0xFF, 0x9F, 0x81, 0x91, 0x01, 0x82, 0x99, 0x10, 0x4C, 0x46, 0x06,
0x46, 0x3A, 0xC9, 0x00, 0x00, 0x2B, 0x1C, 0x23, 0x06, 0x17, 0x1A, 0xE1, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82];
function stringToBlob(type, str) {
return new Blob([str], {
type: type,
});
}
function handleResult(resultFieldID, promise) {
var resultField = document.getElementById(resultFieldID)
promise.then(function (result) {
resultField.textContent = result;
resultField.class = ""; // Can't use `classList`, so we set the entire `class`.
}, function (err) {
resultField.textContent = err;
resultField.setAttribute("class", "error"); // Can't use `classList`, so we set the entire `class`.
})
}
function handleVoidResult(resultFieldID, promise) {
var resultField = document.getElementById(resultFieldID)
promise.then(function (result) {
resultField.textContent = "success";
resultField.class = ""; // Can't use `classList`, so we set the entire `class`.
}, function (err) {
resultField.textContent = err;
resultField.setAttribute("class", "error"); // Can't use `classList`, so we set the entire `class`.
})
}
</script>
<style>
.editable {
min-width: 20px;
min-height: 1em;
border: 1px solid #AAA;
}
.error {
color: #F55;
}
</style>
</head>
<body>
<header>
<img src="./clipboard-polyfill-logo.svg">
<h1>
<a href="https://github.com/lgarron/clipboard-polyfill">clipboard-polyfill</a>
<br>
Demo/test page
</h1>
</header>
<table>
<tr>
<td>
Plain text
</td>
<td>
<button id="plain-copy">Copy text (plain)</button>
</td>
<td>
<span id="plain-copy-result"></span>
<script>
document.getElementById("plain-copy").addEventListener("click", function () {
handleVoidResult("plain-copy-result", clipboard.writeText("This text is plain."));
});
</script>
</td>
</tr>
<tr>
<td>
Markup
</td>
<td>
<button id="markup-copy">Copy text (markup)</button>
</td>
<td>
<span id="markup-copy-result"></span>
<script>
document.getElementById("markup-copy").addEventListener("click", function () {
// var data = [new ClipboardItem({ "text/plain": new Blob(["Text data"], { type: "text/plain" }) })];
var item = new clipboard.ClipboardItem({
"text/html": stringToBlob("text/html", "<i>Markup</i> <b>text</b>. Paste me into a rich text editor."),
"text/plain": stringToBlob("text/plain", "Fallback markup text. Paste me into a rich text editor.")
});
handleVoidResult("markup-copy-result", clipboard.write([item]));
});
</script>
</td>
</tr>
<tr>
<td>
DOM node
</td>
<td>
<button id="markup-dom-copy">Copy markup (DOM node → markup)</button>
<br>
<span id="markup-dom-copy-source" style="font-family: Helvetica;"><i><span
style="font-size: 150%">T</span>his</i>
<span style="background: orange; padding: 0px 2px">will be</span> <b>copied</b>.</span>
</td>
<td>
<span id="markup-dom-copy-result"></span>
<script>
document.getElementById("markup-dom-copy").addEventListener("click", function () {
var blob = new Blob([new XMLSerializer().serializeToString(document.getElementById("markup-dom-copy-source"))], { type: "text/html" });//stringToBlob("text/plain", document.getElementById("markup-dom-copy-source").innerText);
var items = [new clipboard.ClipboardItem({
"text/html": blob
})];
// var dt = new clipboard.DT();
// dt.setData("text/html", new XMLSerializer().serializeToString(document.getElementById("markup-dom-copy-source")));
// dt.setData("text/plain", document.getElementById("markup-dom-copy-source").innerText);
handleVoidResult("markup-dom-copy-result", clipboard.write(items));
});
</script>
</td>
</tr>
<tr>
<td>
Image (PNG)
</td>
<td>
<button id="image-png-copy">Copy image (PNG)</button>
</td>
<td>
<span id="image-png-copy-result"></span>
<br>
<script>
document.getElementById("image-png-copy").addEventListener("click", function () {
var blob = new Blob([new Uint8Array(imgBytes)], { type: "image/png" });//stringToBlob("text/plain", document.getElementById("markup-dom-copy-source").innerText);
var items = [new clipboard.ClipboardItem({
"image/png": blob
})];
handleVoidResult("image-png-copy-result", clipboard.write(items));
});
</script>
</td>
</tr>
<tr>
<td>
Paste text
</td>
<td>
<button id="paste">Paste text</button>
</td>
<td>
<span id="paste-result"></span>
<script>
document.getElementById("paste").addEventListener("click", function () {
handleResult("paste-result", clipboard.readText())
});
</script>
</td>
</tr>
<tr>
<td>
Paste area
</td>
<td colspan="2">
<div contenteditable="true" class="editable"></div>
</td>
</tr>
</table>
</body>
</html>