Commit b4857fe7 authored by Alejandro Celaya's avatar Alejandro Celaya Committed by Alejandro Celaya

Copy raw HTML to clipboard together with rich HTML

parent 1bbcc6d6
......@@ -58,16 +58,23 @@ export async function copyHTML(
/* istanbul ignore next - test seam */
document_ = document,
) {
// We want to copy the `text` both with plain and html media types, to make
// sure it is possible to paste in both rich text and plain text contexts.
// For the second one, the raw HTML markup will be pasted.
const types = ['text/html', 'text/plain'];
if (navigator_.clipboard.write) {
const type = 'text/html';
const blob = new Blob([text], { type });
await navigator_.clipboard.write([new ClipboardItem({ [type]: blob })]);
const blobs = types.reduce<Record<string, Blob>>((acc, type) => {
acc[type] = new Blob([text], { type });
return acc;
}, {});
await navigator_.clipboard.write([new ClipboardItem(blobs)]);
} else {
// Fallback to deprecated document.execCommand('copy') on the assumptions
// that all browsers will implement the new clipboard API before removing
// the deprecated one.
const copyHandler = (e: ClipboardEvent) => {
e.clipboardData?.setData('text/html', text);
types.forEach(type => e.clipboardData?.setData(type, text));
e.preventDefault();
};
......
......@@ -72,7 +72,17 @@ describe('copy-to-clipboard', () => {
await copyHTML(text, createFakeNavigator({ write }));
assert.called(write);
assert.calledOnce(write);
const [clipboardItem] = write.lastCall.args[0];
const getTextForType = async type => {
const blob = await clipboardItem.getType(type);
return blob.text();
};
assert.deepEqual(clipboardItem.types, ['text/html', 'text/plain']);
assert.equal(await getTextForType('text/html'), text);
assert.equal(await getTextForType('text/plain'), text);
});
it('falls back to execCommand if clipboard API is not supported', async () => {
......@@ -92,6 +102,7 @@ describe('copy-to-clipboard', () => {
assert.calledWith(document.execCommand, 'copy');
assert.equal(clipboardData.getData('text/html'), text);
assert.equal(clipboardData.getData('text/plain'), text);
});
});
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment