<html>
<head>
<title>Clipboard API Usage - RJM Programming - July, 2022</title>
<style>
#destination {
width:70%;
height:200px;
}

td {
vertical-align: top;
}
</style>
</head>
<body ontouchstart='onc(event);' onmousedown='onc(event);' onload='onl();' style='background-color:transparent;'>
<div id=ourldiv></div>
<h1>Clipboard API Usage</h1>
<h3>RJM Programming - July, 2022</h3>
<h4>Thanks to <a target=_blank title='https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API' href='//developer.mozilla.org/en-US/docs/Web/API/Clipboard_API'>https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API</a></h4>

<table border=10 cellpadding=5>
<tr><th colspan=5>Clipboard Text ...</tr>
<tr><td><button onclick="pasteinto('after');">Append Below ...</button></td><td><button onclick="pasteinto('before');">Prepend Below ...</button><td><button onclick="pasteinto('cursor');">At Cursor ...</button></td><td><button onclick="pasteinto('cutpaste');">Cut (Highlight Below) and Paste ...</button></td><td><button onclick="pasteinto('setclipboard');">Set Clipboard (to Highlight Below) ...</button></td></tr>
</table><br><br>
<textarea id=mytao class=editor rows=7 cols=120 onmousedown="mustnot=true; setTimeout(mnoff, 2000);" ontouchstart="mustnot=true; setTimeout(mnoff, 2000);"></textarea><br><br>
<table border=10 cellpadding=5>
<tr><th colspan=5>Clipboard Image ...</tr>
<tr><td><button onclick="pasteinto('mafter');">Append Below ...</button></td><td><button onclick="pasteinto('mbefore');">Prepend Below ...</button><td><button onclick="mustnot=true; pasteinto('mcursor'); setTimeout(mnoff, 2000);" ontouchstart='mustnot=true; setTimeout(mnoff, 2000);' onmousedown='mustnot=true; setTimeout(mnoff, 2000);'>At Click ...</button></td><td><button onclick="pasteinto('mcutpaste');">Cut (Highlight Below) and Paste ...</button></td><td><button onclick="pasteinto('msetclipboard');">Set Clipboard (to Highlight Below) ...</button></td></tr>
</table><br><br>
<details id=mydetails><summary id=mysummary></summary>
<table id=ctable>
<tbody id=ctbody><tr id=trcanvas><td id=tdcanvas1>
<canvas onclick='setib(this);' width=0 height=0 id=mycanvas1 class=meditor style="width:0px;height:0px;border:2px solid red;display:none;" title='Click here to paste image clipboard data'></canvas>
</td></tr></tbody></table></details>
<br><img id=destination title='Click here to paste image clipboard data'></img><br><img src='./clipboard_api_test.jpg' style=display:none;></img>

<script type='text/javascript'>
var mustnot=false;
var xis=-1, yis=-1;
var pos3=-1, pos4=-1;
var thiscellis=-1;
var sofar = '';
var sofarbefore='', sofarafter='', sofarmid='';
var msofar = '';
var msofarbefore='', msofarafter='', msofarmid='';
var ctx=null, cnv=null;
var filem=null;
var destinationImage=null;
var mmode='mbefore', prevmmode='mbefore';
var imgz=null;
var prevw=0, prevh=0;
var wo=null;
var curtr=0;
var tdtemplate='';

function pasteinto(inmode) {
//event.stopPropagation();
console.log('here at pasteinto');
sofar = document.querySelector(".editor").value;
console.log('here at pasteinto sofar=' + sofar + ' with sofarbefore=*' + sofarbefore + '* and sofarafter=*' + sofarafter + '*');

//if (('' + cnv.style.width + ' ').substring(0,1) == '0') {
//mmode='mbefore';
//} else {
mmode=inmode;
//}
console.log('mmode=' + mmode);

switch (inmode) {
case 'before':
navigator.clipboard.readText().then(
(clipText) => document.querySelector(".editor").value = clipText + sofar);
break;

case 'after':
navigator.clipboard.readText().then(
(clipText) => document.querySelector(".editor").value += clipText);
break;

case 'setclipboard':
if (document.querySelector(".editor").selectionStart == document.querySelector(".editor").selectionEnd) {
sofarmid='';
} else {
sofarmid=document.querySelector(".editor").value.substring(document.querySelector(".editor").selectionStart, document.querySelector(".editor").selectionEnd);
}
navigator.clipboard.writeText(sofarmid).then(function() {
/* clipboard successfully set */
}, function() {
/* clipboard write failed */
});
break;

case 'cutpaste':
if (document.querySelector(".editor").selectionStart == document.querySelector(".editor").selectionEnd) {
sofarmid='';
} else {
sofarmid=document.querySelector(".editor").value.substring(document.querySelector(".editor").selectionStart, document.querySelector(".editor").selectionEnd);
}
navigator.clipboard.readText().then(
(clipText) => document.querySelector(".editor").value = sofarbefore + clipText + sofarafter.substring(sofarmid.length));
break;

case 'cursor':
console.log('at cursor');
navigator.clipboard.readText().then(
(clipText) => document.querySelector(".editor").value = sofarbefore + clipText + sofarafter);
break;

case 'mbefore':
destinationImage.click();
break;

case 'mafter':
destinationImage.click();
break;

case 'msetclipboard':
document.getElementById('mydetails').setAttribute('open',true); //destinationImage.click();
if (document.getElementById('mysummary').innerHTML.indexOf(' Images below ') == -1) {
document.getElementById('mysummary').innerHTML='Accumulated Images below ...';
}
if (document.getElementById('mysummary').innerHTML.indexOf(' click ') == -1) {
document.getElementById('mysummary').innerHTML+=' please click image below to copy to clipboard ... ';
}
break;

case 'mcutpaste':
document.getElementById('mydetails').setAttribute('open',true); //destinationImage.click();
if (document.getElementById('mysummary').innerHTML.indexOf(' Images below ') == -1) {
document.getElementById('mysummary').innerHTML='Accumulated Images below ...';
}
if (document.getElementById('mysummary').innerHTML.indexOf(' click ') == -1) {
document.getElementById('mysummary').innerHTML+=' please click image below to change for clipboard contents ... ';
}
break;

case 'mcursor':
xis=pos3;
yis=pos4;
destinationImage.click();
break;

default:
console.log('at cursor');
navigator.clipboard.readText().then(
(clipText) => document.querySelector(".editor").value = sofarbefore + clipText + sofarafter);
break;
}

}

//document.getElementById('mytao').addEventListener('click', showposition); // click
document.querySelector(".editor").addEventListener('click', showposition); // click
document.querySelector(".editor").addEventListener('keyup', showpositionkp); // click
//document.querySelector(".editor").addEventListener('losefocus', showpositionkp); // click

function showposition(event) { // thanks to https://stackoverflow.com/questions/62310186/how-do-you-get-the-current-cursor-position-in-a-textarea-whenever-the-cursor-o
console.log(event.target.selectionStart);
if (document.querySelector(".editor").value != '') {
//onsole.log('yes, here');
sofarbefore=document.querySelector(".editor").value.substring(0, event.target.selectionStart);
sofarafter=document.querySelector(".editor").value.substring(event.target.selectionStart);
//console.log('sofarbefore=' + sofarbefore + ' and sofarafter=' + sofarafter);
}
document.querySelector(".editor").focus();
}

function showpositionkp(event) { // thanks to https://stackoverflow.com/questions/62310186/how-do-you-get-the-current-cursor-position-in-a-textarea-whenever-the-cursor-o
//event.stopPropagation();
console.log(event.target.selectionStart);
if (document.querySelector(".editor").value != '') {
console.log('yes, here');
if (event.target.selectionStart == event.target.selectionEnd) {
sofarmid='';
sofarbefore=document.querySelector(".editor").value.substring(0, event.target.selectionStart);
sofarafter=document.querySelector(".editor").value.substring(event.target.selectionStart);
} else {
sofarmid=ocument.querySelector(".editor").value.substring(event.target.selectionStart, event.target.selectionEnd);
sofarbefore=document.querySelector(".editor").value.substring(0, event.target.selectionStart);
sofarafter=document.querySelector(".editor").value.substring(event.target.selectionStart);
}
console.log('sofarbefore=' + sofarbefore + ' and sofarafter=' + sofarafter + ' and sofarmid=' + sofarmid);
}
}

function onl() {
cnv=document.getElementById("mycanvas1");
destinationImage = document.querySelector('#destination')
destinationImage.addEventListener('click', pasteImage);
//document.querySelector(".meditor").addEventListener('click', pasteImage);
tdtemplate=document.getElementById("tdcanvas1").outerHTML;

ctx=document.getElementById("mycanvas1").getContext("2d");
//document.getElementById("mycanvas1").addEventListener("drop", onDrop);
//window.addEventListener("paste", onPaste);
document.getElementById("mytao").focus();
}

function onDrop(event) {
console.log('here od');
event.preventDefault();
const file = event.dataTransfer.files[0];
this.createRasterFromFile(file);
}

function onPaste(event) {
mustnot=true;
console.log('here op');
event.preventDefault();
event.stopPropagation();
setTimeout(mnoff, 2000);
console.log('event.clipboardData=' + event.clipboardData);
console.log('window.clipboardData=' + window.clipboardData);
console.log('event.clipboardData.files=' + event.clipboardData.files);
//console.log('window.clipboardData.files=' + window.clipboardData.files);
//console.log('event.clipboardData.items=' + event.clipboardData.items);
//console.log('window.clipboardData.items=' + window.clipboardData.items);
filem = (event.clipboardData || window.clipboardData).files;
console.log('here op2');
//createRasterFromFile(filem[0].getAsFile());
createRasterFromFile(filem[0]);
console.log('here op3');
}

function createRasterFromFile(filex) {
console.log('here cr');
if (filex && (filex.type == 'image/png' || filex.type == 'image/jpeg')) {
console.log('here CR');
const reader = new FileReader();
reader.onload = function () {
// Image data stored in reader.result
console.log('here');
ctx.drawImage(reader.result, 0, 0);
}.bind(this);
reader.readAsDataURL(filex);
} else if (filex) {
console.log('not here ' + filex.type);
} else if (filem) {
console.log('here filem ' + filem.type);
} else {
console.log('not here filem');
}
}


async function pasteImage() {
//event.stopPropagation();
try {
const permission = await navigator.permissions.query({ name: 'clipboard-read' });
if (permission.state === 'denied') {
throw new Error('Not allowed to read clipboard.');
}
const clipboardContents = await navigator.clipboard.read();
for (const item of clipboardContents) {
if (!item.types.includes('image/png')) {
throw new Error('Clipboard contains non-image data.');
}
const blob = await item.getType('image/png');
imgz = new Image();
anothercell();
imgz.onload = () => {
destinationImage.style.width='' + imgz.width + 'px';
destinationImage.style.height='' + imgz.height + 'px';
prevw=eval('' + ('' + cnv.style.width).replace('px',''));
prevh=eval('' + ('' + cnv.style.height).replace('px',''));
console.log('canvas width becomes ' + eval('' + cnv.width) + ' + ' + eval('' + imgz.width) + ' = ' + '' + eval(eval('' + cnv.width) + eval('' + imgz.width)) + 'px');
cnv.style.width='' + eval(eval('' + ('' + cnv.style.width).replace('px','')) + eval('' + imgz.width)) + 'px';
cnv.style.height='' + eval(eval('' + ('' + cnv.style.height).replace('px','')) + eval('' + imgz.height)) + 'px';
cnv.width='' + ('' + cnv.style.width).replace('px','') + 'px';
cnv.height='' + ('' + cnv.style.height).replace('px','') + 'px';
if (mmode == 'mbefore' || 1 == 1) {
ctx.drawImage(imgz, prevw, prevh);
if (wo) {
wo.close();
wo=null;
}
cnv.style.display='block';
//wo=window.open('','_blank','top=50,left=50,height=600,width=600');
//wo.document.write(cnv.toDataURL('image/png'));
}
};
imgz.src = URL.createObjectURL(blob);
destinationImage.src = URL.createObjectURL(blob);
//cnv.style.backgroundRepeat=(('' + cnv.style.backgroundRepeat) + ',no-repeat').replace(/^\,/g,'');
//if (('' + cnv.style.background + ' ').trim() != '') { document.getElementById('mysummary').innerHTML='Accumulated Images below ...'; }
cnv.style.background=(('' + cnv.style.background) + ',url(' + destinationImage.src + ') no-repeat').replace(/^\,/g,'');
//document.querySelector(".editor").style.display='block';
//destinationImage.style.display='none';
setTimeout(anothercellz, 6000);
}
}
catch (error) {
console.error(error.message);
}
}

function thiscell(icurtr) {
//curtr++;
//alert(tdtemplate.replace(/1/g, '' + curtr));
var wastrih=document.getElementById('trcanvas').innerHTML;
console.log('Mmode=' + mmode);
cnv=document.getElementById('mycanvas' + icurtr);
ctx=document.getElementById("mycanvas" + icurtr).getContext("2d");
cnv.style.width='0px';
cnv.style.height='0px';
cnv.style.background='';
if (1 == 6) {
imgz.onload = () => {
destinationImage.style.width='' + imgz.width + 'px';
destinationImage.style.height='' + imgz.height + 'px';
prevw=0;
prevh=0;
console.log('canvas width becomes ' + eval('' + cnv.width) + ' + ' + eval('' + imgz.width) + ' = ' + '' + eval(eval('' + cnv.width) + eval('' + imgz.width)) + 'px');
cnv.style.width='' + eval(0 + eval('' + imgz.width)) + 'px';
cnv.style.height='' + eval(0 + eval('' + imgz.height)) + 'px';
cnv.width='' + ('' + cnv.style.width).replace('px','') + 'px';
cnv.height='' + ('' + cnv.style.height).replace('px','') + 'px';
if (mmode == 'mbefore' || 1 == 1) {
ctx.drawImage(imgz, prevw, prevh);
if (wo) {
wo.close();
wo=null;
}
cnv.style.display='block';
//wo=window.open('','_blank','top=50,left=50,height=600,width=600');
//wo.document.write(cnv.toDataURL('image/png'));
}
};
imgz.src = URL.createObjectURL(blob);
destinationImage.src = URL.createObjectURL(blob);
//cnv.style.backgroundRepeat=(('' + cnv.style.backgroundRepeat) + ',no-repeat').replace(/^\,/g,'');
//if (('' + cnv.style.background + ' ').trim() != '') { document.getElementById('mysummary').innerHTML='Accumulated Images below ...'; }
cnv.style.background=(('') + ',url(' + destinationImage.src + ') no-repeat').replace(/^\,/g,'');
//document.querySelector(".editor").style.display='block';
//destinationImage.style.display='none';
}
}

function anothercell() {
var ouro=document.getElementById('trcanvas');
if (thiscellis >= 0) {
thiscell(thiscellis);
thiscellis=-1;
} else {
curtr++;
//alert(tdtemplate.replace(/1/g, '' + curtr));
var ourtdtemplate=tdtemplate;
if (('' + xis).indexOf('-') == -1) {
ourtdtemplate=ourtdtemplate.replace(' style="', ' style="position:absolute;z-index:-99;opacity:0.6;left:' + xis + 'px;top:' + yis + 'px;');
xis=-1;
yis=-1;
ouro=document.getElementById('ourldiv');
ourtdtemplate='<canvas' + ourtdtemplate.split('<canvas')[1].split('</td>')[0];
//alert(ourtdtemplate);
}
var wastrih=document.getElementById('trcanvas').innerHTML;
console.log('Mmode=' + mmode);
if (!document.getElementById('tdcanvas' + curtr)) {
if (mmode != 'mbefore') {
ouro.innerHTML+=ourtdtemplate.replace(/1/g, '' + curtr);
} else {
ouro.innerHTML=ourtdtemplate.replace(/1/g, '' + curtr) + wastrih;
}
cnv=document.getElementById('mycanvas' + curtr);
ctx=document.getElementById("mycanvas" + curtr).getContext("2d");
}
//cnv=document.getElementById('mycanvas' + curtr);
//ctx=document.getElementById("mycanvas" + curtr).getContext("2d");
//document.getElementById('mysummary').innerHTML='Accumulated Images below ...';
//prevmmode=mmode;
}
}

function anothercellz() {
//cnv=document.getElementById('mycanvas' + curtr);
//ctx=document.getElementById("mycanvas" + curtr).getContext("2d");
if (document.getElementById('mysummary').innerHTML.indexOf(' Images below ') == -1) {
document.getElementById('mysummary').innerHTML='Accumulated Images below ...';
}
prevmmode=mmode;
}

function onDone() {}

function onError(therr) {}

function wassetib(canvas) { //, onDone, onError) {
if (mmode == 'mcutpaste') {
canvas.style.border='2px dashed yellow';
thiscell(eval(canvas.id.replace('mycanvas','')));
} else {
canvas.style.border='2px dotted blue';

var type = "image/png";
var blob = new Blob([canvas], { type });
var data = [new ClipboardItem({ [type]: blob })];


navigator.clipboard.write(data).then(function () {
onDone();
}, function (err) {
onError(err);
});
}
}

function setib(inb) {
var inbb=inb.outerHTML.split('url(')[1].split(')')[0].replace("'","").replace("'","").replace('"','').replace('"','').replace(/\"\;/g,'');
if (mmode == 'mcutpaste') {
inb.style.border='2px dashed yellow';
thiscellis=eval(inb.id.replace('mycanvas','')); //destinationImage.click(); //url2blob(inbb);
//thiscell(eval(inb.id.replace('mycanvas','')));
destinationImage.click();
} else {
inb.style.borderColor='blue';
console.log(inbb);
url2blob(inbb);
// var dinbb = [new ClipboardItem({ [type]: blob })];

// navigator.clipboard.write(dinbb).then(
// function () {
// /* success */
// },
// function () {
// /* failure */
// }
// );
}
}

async function url2blob(url) { // thanks to https://stackoverflow.com/questions/44070437/how-to-get-a-file-or-blob-from-an-url-in-javascript
try {
const data = await fetch(url);
const blob = await data.blob();
await navigator.clipboard.write([
new ClipboardItem({
[blob.type]: blob
})
]);
console.log("Success.");
} catch (err) {
console.error(err.name, err.message);
}
}

function onc(e) {

e = e || window.event;
e.preventDefault();
// get the mouse cursor position at startup:
//pos3 = e.clientX;
//pos4 = e.clientY;
if (!mustnot) {
if (e.touches) {
if (e.touches[0].pageX) {
pos3 = e.touches[0].pageX;
pos4 = e.touches[0].pageY;
} else {
pos3 = e.touches[0].clientX;
pos4 = e.touches[0].clientY;
}
console.log('pos3=' + pos3 + ',pos4=' + pos4);
} else if (e.clientX || e.clientY) {
pos3 = e.clientX;
pos4 = e.clientY;
} else {
pos3 = e.pageX;
pos4 = e.pageY;
}
}
mustnot=false;
}

function mnoff() {
mustnot=false;
}

</script>
</body>
</html>