'Chrome 76 Copy Content to Clipboard using navigator
I just updated to chrome 76 stable and am trying to use the new clipboard API to copy some text (and later on, images) to the clipboard. However, navigator.clipboard.write(data) does not seem to be working. Here is my code:
setInterval(function() {
console.log("Wriing to clipbard");
navigator.permissions.query({ name: 'clipboard-write' }).then(result => {
if (result.state === 'granted') {
var data = new Blob(["Text data"], {type : "text/plain"});
navigator.clipboard.write(data).then(function() {
console.log("Copied to clipboard successfully!");
}, function(error) {
console.error("unable to write to clipboard. Error:");
console.log(error);
});
} else {
console.log("clipboard-permissoin not granted: " + result);
}
});
}, 3000);
I am running this in a chrome extension content script, with clipboard permissions set, so the permissions indeed get granted. The eror that gets thrown is:
unable to write to clipboard. Error:
TypeError: Failed to execute 'write' on 'Clipboard': Iterator getter is not callable.
Strangely enough, when I use navigator.clipboard.write text(text) instead of navigator.clipboard.write(data), everything works perfectly. The thing is, I want to use write(data) because later on I want to write images to the clipboard as well. Any ideas why it's not working? Thank you.
EDIT: I got the code from the specsheet https://w3c.github.io/clipboard-apis/#dom-clipboard-write
UPDATE: Okay, I got the text-copying to work by using ClipboardItem (see my answer below) but if I do the same with a dataURL encoded image, the whole webpage crashes with an "Aw snap" message. So not sure what's going on there. Here is the code that will crash the site and force a reload:
setInterval(function() {
console.log("Wriing to clipbard");
navigator.permissions.query({ name: 'clipboard-write' }).then(result => {
if (result.state === 'granted') {
//var blob = new Blob(['hello'], {type: 'text/plain'});
var data = new Blob(["iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg=="], {type : "image/png"});
var item = new ClipboardItem({'image/png': data});
navigator.clipboard.write([item]).then(function() {
console.log("Copied to clipboard successfully!");
}, function(error) {
console.error("unable to write to clipboard. Error:");
console.log(error);
});
} else {
console.log("clipboard-permissoin not granted: " + result);
}
});
}, 3000);
Solution 1:[1]
A more complete solution:
After having several problems trying to solve this issue, I have a solution that works with Safari, but also with all the others browsers.
We need to try the two scenarios (for Safari and for the rest):
getImage (canvas, width = 200, height = 200) {
return new Promise((resolve) => {
const tmpCanvas = document.createElement('canvas')
tmpCanvas.width = width
tmpCanvas.height = height
const ctx = tmpCanvas.getContext('2d')
ctx.drawImage(canvas, 0, 0, canvas.width, canvas.height, 0, 0, width, height)
tmpCanvas.toBlob(resolve)
})
}
copyImg () {
const canvas = document.getElementsByTagName('canvas')[0]
if (canvas instanceof HTMLCanvasElement) {
try {
// Trying for only Safari browser
const image = getImage(canvas)
navigator.clipboard.write([new ClipboardItem({ 'image/png': image })])
console.log('Copied')
} catch (safariError: any) {
try {
// Trying for rest of browsers
canvas.toBlob(blob => navigator.clipboard.write([new ClipboardItem({ 'image/png': blob })]))
console.log('Copied')
} catch (anotherBrowserError: any) {
console.log(safariError.message + ' - ' + anotherBrowserError.message)
}
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Villapalos |
