chore: enchance copy link action (#8797)

What's Changed

* enhance copy link action
* detect compatibility
* fall back to `document.execCommand`
This commit is contained in:
fundon
2024-11-13 08:07:08 +00:00
parent b3b1ea2f33
commit f85dfae63b
5 changed files with 130 additions and 34 deletions

View File

@@ -0,0 +1,49 @@
const createFakeElement = (text: string) => {
const isRTL = document.documentElement.getAttribute('dir') === 'rtl';
const fakeElement = document.createElement('textarea');
// Prevent zooming on iOS
fakeElement.style.fontSize = '12pt';
// Reset box model
fakeElement.style.border = '0';
fakeElement.style.padding = '0';
fakeElement.style.margin = '0';
// Move element out of screen horizontally
fakeElement.style.position = 'absolute';
fakeElement.style[isRTL ? 'right' : 'left'] = '-9999px';
// Move element to the same position vertically
const yPosition = window.pageYOffset || document.documentElement.scrollTop;
fakeElement.style.top = `${yPosition}px`;
fakeElement.setAttribute('readonly', '');
fakeElement.value = text;
return fakeElement;
};
function command(type: string) {
try {
return document.execCommand(type);
} catch (err) {
console.error(err);
return false;
}
}
export const fakeCopyAction = (text: string, container = document.body) => {
let success = false;
const fakeElement = createFakeElement(text);
container.append(fakeElement);
try {
fakeElement.select();
fakeElement.setSelectionRange(0, fakeElement.value.length);
success = command('copy');
} catch (err) {
console.error(err);
}
fakeElement.remove();
return success;
};

View File

@@ -0,0 +1,54 @@
import { type Clipboard as BlockStdScopeClipboard } from '@blocksuite/affine/block-std';
import { fakeCopyAction } from './fake';
const clipboardWriteIsSupported =
'clipboard' in navigator && 'write' in navigator.clipboard;
const clipboardWriteTextIsSupported =
'clipboard' in navigator && 'writeText' in navigator.clipboard;
export const copyTextToClipboard = async (text: string) => {
// 1. try using Async API first, works on HTTPS domain
if (clipboardWriteTextIsSupported) {
try {
await navigator.clipboard.writeText(text);
return true;
} catch (err) {
console.error(err);
}
}
// 2. try using `document.execCommand`
// https://github.com/zenorocha/clipboard.js/blob/master/src/actions/copy.js
return fakeCopyAction(text);
};
export const copyLinkToBlockStdScopeClipboard = async (
text: string,
clipboard?: BlockStdScopeClipboard
) => {
let success = false;
if (!clipboard) return success;
if (clipboardWriteIsSupported) {
try {
await clipboard.writeToClipboard(items => {
items['text/plain'] = text;
// wrap a link
items['text/html'] = `<a href="${text}">${text}</a>`;
return items;
});
success = true;
} catch (error) {
console.error(error);
}
}
if (!success) {
success = await copyTextToClipboard(text);
}
return success;
};