阻止 safari 在 clipboard.write 中破坏 HTML

Stop safari from mangling HTML in clipboard.write

如果我尝试使用 navigator.clipboard.write 将一些 html 写入剪贴板,safari 将对其进行大量更改,包括删除注释,并添加一堆随机 css 属性。我将元数据存储在评论中,所以我真的希望他们不要这样做,否则它会破坏我的应用程序内 copy/paste 机制。有没有一种方法可以在不更改 Safari 的情况下将 html 复制到剪贴板?

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

预期结果:

<!-- data in comment --><div>Some content</div>

结果chrome:

<meta charset='utf-8'><!-- data in comment --><div>Some content</div>

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>

请注意,注释已完全删除,我需要其中的数据。

查看 WebKit 的代码,看起来 sanitizing/normalization 是故意的,无法绕过,但似乎保留了数据属性,因此您可以使用这些属性传递附加数据。

根据您未详细说明的用例,您可以使用例如<div data-settings="data in attribute"></div><div>Some content</div>(甚至似乎保留了空元素),或者只是为该示例设置属性 div 或在某个级别使用包装元素。

为确保该元素不影响内容并且不出现在辅助功能树中:

<div data-settings="foo" style="position: absolute; top: -9999px; left: -9999px; visibility: hidden;"></div>

WebKit 还尝试尽可能将通用样式信息放在最外层元素中,因此使用包装器元素可以使数据更易于阅读,这可能会简化调试。

注意:使用 display: none 将再次从粘贴的 HTML 中删除该元素。我找不到保留元素的简单列表,但 WebKit 基本上将粘贴的 HTML 视为一种富文本。您可能应该单独测试将要使用的每个元素,并在必要时将它们转换为带有数据属性的 divs。