Need to gather HTML (to strip some of the styling) during the copy event.
Currently, attempting to do the following:
Add a listener for the 'copy' event
document.addEventListener('copy', (e) => {
console.log("e.target:" + e.target);
});
And then use clipboard api to copy the item Along the lines of:
var blob = new Blob([html], {type: "text/html"});
var item = new ClipboardItem({"text/html": blob});
navigator.clipboard.write([item])
However, when attempting to gather html on copy event I am using e.target to gather the HTML. It appears that e.target.nextElementSibling when called recursively should give the value of the next element. However, when items are selected from a list (without the entire list being selected) it does not appear to work as expected.
As example:
<html>
<head>
<title> The simplest HTML example
</title>
</head>
<body>
<h1> This is an HTML Page </h1>
<ul>
<li>
<a href="https://www.google.com/">goog</a>
</li>
<li>
<a href="https://www.bing.com/">bing</a>
</li>
</ul>
Not in list:
<a href="https://www.google.com/">goog</a>
<a href="https://www.bing.com/">bing</a>
</body>
</html>
document.addEventListener('copy', (e) => {
console.log("e.target:" + e.target);
console.log("e.target:" + e.target.nextElementSibling);
});
JSFiddle: https://jsfiddle.net/q8d9vogu/9/
Selecting the Not in list: goog bing shows both of the elements. While selecting the list goog & bing ONLY shows google one (e.target.nextElementSibling is null).
How should we go about gathering the HTML that is copied within the copy event? (context: this is running within VSCode extension)
Answering my own question with potential solution in case others run into this. The following seems to be doing the trick of grabbing HTML and copying it into clipboard:
document.addEventListener('copy', (e) => {
const htmlSelection = getHTMLOfSelection();
if (htmlSelection !== undefined){
copyToClipboard(htmlSelection);
}
});
/**
* Based off of: https://stackoverflow.com/a/5084044/7858768
* */
function getHTMLOfSelection () {
let range;
if (document.selection && document.selection.createRange) {
range = document.selection.createRange();
return range.htmlText;
}
else if (window.getSelection) {
const selection = window.getSelection();
if (selection.rangeCount > 0) {
range = selection.getRangeAt(0);
const clonedSelection = range.cloneContents();
const div = document.createElement('div');
div.appendChild(clonedSelection);
return div.innerHTML;
}
else {
return undefined;
}
}
else {
return undefined;
}
}
/**
Based off of:
* https://stackoverflow.com/a/64711198/7858768
* https://stackoverflow.com/a/57279336/7858768
*/
function copyToClipboard(html) {
const container = document.createElement('div');
container.innerHTML = html;
container.style.position = 'fixed';
container.style.pointerEvents = 'none';
container.style.opacity = 0;
const blob = new Blob([html], {type: "text/html"});
const item = new ClipboardItem({"text/html": blob});
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);
});
}
```