<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>
<table><tr><td><textarea id=mytao class=editor rows=7 cols=120 onmousedown="mustnot=true;  setTimeout(mnoff, 2000);" ontouchstart="mustnot=true;  setTimeout(mnoff, 2000);"></textarea></td></TR><TR><td id=emailsms style=display:none;vertical-align:top;> <a target=_blank href='mailto:?subject=My%20Selection%20...&body=' id=aemail title=Email>📧</a> <a target=_blank onmouseover="if (smsee.length == 0 && origsmsurl.indexOf('sms:&') != -1) { smsee=prompt('Please enter SMS number to send to.', ''); if (smsee == null) { smsee=''; } else { origsmsurl=origsmsurl.replace('sms:&','sms:' + smsee + '&'); asmsurl=asmsurl.replace('sms:&','sms:' + smsee + '&'); this.href=asmsurl;  }   }" href='sms:&body=My%20Selection%20...' id=asms title=SMS>📟</a></td></tr></table><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>
<table><tr><td><textarea id=mytao class=editor rows=10 cols=80></textarea></td><td id=emailsms style=display:none;vertical-align:top;> <a target=_blank href='mailto:?subject=My%20Selection%20...&body=' id=aemail title=Email>📧</a> <a target=_blank onmouseover="if (smsee.length == 0 && origsmsurl.indexOf('sms:&') != -1) { smsee=prompt('Please enter SMS number to send to.', ''); if (smsee == null) { smsee=''; } else { origsmsurl=origsmsurl.replace('sms:&','sms:' + smsee + '&'); asmsurl=asmsurl.replace('sms:&','sms:' + smsee + '&'); this.href=asmsurl;  }   }" ontouchstart="if (smsee.length == 0 && origsmsurl.indexOf('sms:&') != -1) { smsee=prompt('Please enter SMS number to send to.', ''); if (smsee == null) { smsee=''; } else { origsmsurl=origsmsurl.replace('sms:&','sms:' + smsee + '&'); asmsurl=asmsurl.replace('sms:&','sms:' + smsee + '&'); this.href=asmsurl;  }   }" href='sms:&body=My%20Selection%20...' id=asms title=SMS>📟</a></td></tr></table>
<script type='text/javascript'>
 var origemailurl='mailto:?subject=My%20Selection%20...&body=';
 var origsmsurl='sms:&body=My%20Selection%20...';
 var smsee='';
 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;
  }
  
// addEventListener version
document.addEventListener('selectionchange', () => {
  document.getElementById('emailsms').style.display='table-cell';
  document.getElementById('mytao').title=document.getSelection().toString();
  aemailurl=origemailurl + encodeURIComponent(document.getSelection().toString());
  document.getElementById('aemail').href=aemailurl;
  asmsurl=origsmsurl + encodeURIComponent(String.fromCharCode(10) + document.getSelection().toString());
  document.getElementById('asms').href=asmsurl;
  console.log(document.getSelection().toString());
});
// addEventListener version
document.addEventListener('selectstart', () => {
  document.getElementById('mytao').title='';
  aemailurl=origemailurl;
  asmsurl=origsmsurl;
  console.log('Selection started');
});
</script>
</body>
</html>