| <!DOCTYPE html> |
| <meta name="viewport" content="width=device-width, initial-scale=1"> |
| <style> |
| html, body { |
| width: 100%; |
| height: 100%; |
| } |
| </style> |
| <body contenteditable> |
| <div id="source">Copy me</div> |
| <pre id="output"> |
| To manually test, copy the above text and paste anywhere in the body. |
| This will dump the contents of the DataTransfer on copy and paste events as output text. |
| You should see the custom types "text" and "url" written to the DataTransfer as custom |
| data exposed on the DataTransfer's item list, on both copy and paste. |
| </pre> |
| </body> |
| <script> |
| |
| function write(markup) { |
| output.insertAdjacentHTML("beforeend", markup); |
| } |
| |
| function outputForFile(file) { |
| return file ? `(name = '${file.name}', size = ${file.size} bytes, type = '${file.type}')` : "(null)"; |
| } |
| |
| globalStringLoadCount = 0; |
| currentStringLoadCount = 0; |
| |
| function loadString(item) { |
| currentStringLoadCount++; |
| const outputElementId = `string-${++globalStringLoadCount}`; |
| item.getAsString(string => { |
| document.getElementById(outputElementId).textContent = string; |
| currentStringLoadCount--; |
| if (!currentStringLoadCount && window.didFinishLoadingAllStrings) |
| didFinishLoadingAllStrings(); |
| }); |
| return `<span id=${outputElementId}></span>`; |
| } |
| |
| function writeOutputForEvent(event) { |
| write(`<br><h3>*** Handling ${event.type} ***</h3>`); |
| write(`<div><strong>Types => data</strong></div>`); |
| for (const type of event.clipboardData.types) |
| write(`<div>${type} => "${event.clipboardData.getData(type)}"</div>`); |
| let index = 0; |
| write(`<div><strong>Item list</strong></div>`); |
| for (const item of event.clipboardData.items) { |
| if (item.kind === "file") |
| write(`<div>[${index++}] => ${outputForFile(item.getAsFile())}</div>`); |
| else |
| write(`<div>[${index++}] => (type = "${item.type}", string = "${loadString(item)}")</div>`); |
| } |
| write(`<div><strong>File list</strong></div>`); |
| index = 0; |
| for (const file of event.clipboardData.files) |
| write(`<div>[${index++}] => ${outputForFile(file)}</div>`); |
| } |
| |
| function setCustomData(event) { |
| output.textContent = ""; |
| |
| event.clipboardData.setData("text/html", "<i>HTML data written using setData</i>"); |
| event.clipboardData.items.add("plain text data written using items.add", "text/plain"); |
| event.clipboardData.items.add("https://www.webkit.org/", "text/uri-list"); |
| event.clipboardData.setData("using setData", "data written using DataTransfer.setData"); |
| event.clipboardData.items.add("data written using DataTransferItemList.add", "using add"); |
| |
| // Per the spec, "text" and "url" will be normalized to "text/plain" and "text/uri-list" when using |
| // DataTransfer.getData. However, this custom data should still be accessible through DataTransferItems. |
| event.clipboardData.items.add("this should be custom data", "text"); |
| event.clipboardData.items.add("this should also be custom data", "url"); |
| |
| writeOutputForEvent(event); |
| } |
| |
| getSelection().setBaseAndExtent(source, 0, source, 1); |
| |
| document.body.addEventListener("paste", event => { |
| event.preventDefault(); |
| writeOutputForEvent(event); |
| }); |
| source.addEventListener("copy", event => { |
| event.preventDefault(); |
| setCustomData(event); |
| }); |
| |
| if (window.testRunner && window.internals) { |
| internals.settings.setCustomPasteboardDataEnabled(true); |
| testRunner.waitUntilDone(); |
| testRunner.dumpAsText(); |
| |
| document.execCommand("Copy"); |
| document.execCommand("Paste"); |
| |
| didFinishLoadingAllStrings = () => testRunner.notifyDone(); |
| } |
| </script> |