If I try to write some html into the clipboard using navigator.clipboard.write safari will change it a lot including stripping comments, and adding a bunch of random css properties. I store metadata in the comments so I'd really like them to not do that otherwise it breaks my in-app copy/paste mechanisms. Is there a way to copy html to the clipboard without safari changing it?
const html = "<!-- data in comment --><div>Some content</div>"
document.querySelector('button').addEventListener('click', function() {
navigator.clipboard.write([new ClipboardItem({
"text/html": new Blob([html], {type: "text/html"})
})])
})
https://codepen.io/msfeldstein/pen/jOwEXGw?editors=0010
Expected result:
<!-- data in comment --><div>Some content</div>
Result in chrome:
<meta charset='utf-8'><!-- data in comment --><div>Some content</div>
Result in safari:
<div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;">Some content</div>
Note that the comment is totally stripped out, and i need the data in there.
Looking at WebKit's code, looks like the sanitizing/normalization is intentional and cannot be circumvented, but it seems that data attributes are preserved so you could pass the additional data using those.
Depending on your use case which you do not elaborate, you could use e.g. <div data-settings="data in attribute"></div><div>Some content</div> (even empty elements seem to be preserved), or just set the attribute for that example div or use a wrapper element at some level.
To make sure the element doesn't affect the content and also doesn't appear in the accessibility tree:
<div data-settings="foo" style="position: absolute; top: -9999px; left: -9999px; visibility: hidden;"></div>
WebKit also tries to put the common styling information in the outermost element possible, so using a wrapper element makes the data easier to read, which will probably ease debugging.
Note: using display: none will remove the element from the pasted HTML again. I couldn't find a simple list of elements that are preserved, but WebKit basically treats pasted HTML as kind of a rich text. You should probably test separately every element you are going to use and translate them to divs with data-attributes if necessary.