feat(editor): Migrate copyPaste mixin to composables (no-changelog) (#8179)
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
import { render } from '@testing-library/vue';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { defineComponent, h, ref } from 'vue';
|
||||
import { useClipboard } from '@/composables/useClipboard';
|
||||
|
||||
const testValue = 'This is a test';
|
||||
|
||||
const TestComponent = defineComponent({
|
||||
setup() {
|
||||
const pasted = ref('');
|
||||
const clipboard = useClipboard({
|
||||
onPaste(data) {
|
||||
pasted.value = data;
|
||||
},
|
||||
});
|
||||
|
||||
return () =>
|
||||
h('div', [
|
||||
h('button', {
|
||||
'data-test-id': 'copy',
|
||||
onClick: () => {
|
||||
void clipboard.copy(testValue);
|
||||
},
|
||||
}),
|
||||
h('div', { 'data-test-id': 'paste' }, pasted.value),
|
||||
]);
|
||||
},
|
||||
});
|
||||
|
||||
describe('useClipboard()', () => {
|
||||
beforeAll(() => {
|
||||
userEvent.setup();
|
||||
});
|
||||
|
||||
describe('copy()', () => {
|
||||
it('should copy text value', async () => {
|
||||
const { getByTestId } = render(TestComponent);
|
||||
|
||||
const copyButton = getByTestId('copy');
|
||||
copyButton.click();
|
||||
expect((window.navigator.clipboard as unknown as { items: string[] }).items).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('onClipboardPasteEvent()', () => {
|
||||
it('should trigger on clipboard paste event', async () => {
|
||||
const { getByTestId } = render(TestComponent);
|
||||
|
||||
const pasteElement = getByTestId('paste');
|
||||
await userEvent.paste(testValue);
|
||||
expect(pasteElement.textContent).toEqual(testValue);
|
||||
});
|
||||
});
|
||||
});
|
||||
80
packages/editor-ui/src/composables/useClipboard.ts
Normal file
80
packages/editor-ui/src/composables/useClipboard.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import { onBeforeUnmount, onMounted, ref } from 'vue';
|
||||
import { debounce } from 'lodash-es';
|
||||
import { useClipboard as useClipboardCore } from '@vueuse/core';
|
||||
|
||||
type ClipboardEventFn = (data: string, event?: ClipboardEvent) => void;
|
||||
|
||||
export function useClipboard(
|
||||
options: {
|
||||
onPaste: ClipboardEventFn;
|
||||
} = {
|
||||
onPaste() {},
|
||||
},
|
||||
) {
|
||||
const { copy, copied, isSupported, text } = useClipboardCore();
|
||||
|
||||
const ignoreClasses = ['el-messsage-box', 'ignore-key-press'];
|
||||
const initialized = ref(false);
|
||||
|
||||
const onPasteCallback = ref<ClipboardEventFn | null>(options.onPaste || null);
|
||||
|
||||
/**
|
||||
* Handles copy/paste events
|
||||
* @param event
|
||||
*/
|
||||
function onPaste(event: ClipboardEvent) {
|
||||
if (!onPasteCallback.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the event got emitted from a message box or from something
|
||||
// else which should ignore the copy/paste
|
||||
const path = event.composedPath?.() as HTMLElement[];
|
||||
for (const pathElement of path) {
|
||||
if (
|
||||
pathElement.className &&
|
||||
ignoreClasses.some((className) => pathElement.className.includes?.(className))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const clipboardData = event.clipboardData;
|
||||
if (clipboardData !== null) {
|
||||
const clipboardValue = clipboardData.getData('text/plain');
|
||||
onPasteCallback.value(clipboardValue, event);
|
||||
}
|
||||
}
|
||||
|
||||
const debouncedOnPaste = debounce(onPaste, 1000, { leading: true });
|
||||
|
||||
/**
|
||||
* Initialize copy/paste elements and events
|
||||
*/
|
||||
onMounted(() => {
|
||||
if (initialized.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
document.addEventListener('paste', debouncedOnPaste);
|
||||
|
||||
initialized.value = true;
|
||||
});
|
||||
|
||||
/**
|
||||
* Remove copy/paste elements and events
|
||||
*/
|
||||
onBeforeUnmount(() => {
|
||||
if (initialized.value) {
|
||||
document.removeEventListener('paste', debouncedOnPaste);
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
copy,
|
||||
copied,
|
||||
isSupported,
|
||||
text,
|
||||
onPaste: onPasteCallback,
|
||||
};
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
import copyToClipboard from 'copy-to-clipboard';
|
||||
|
||||
export function useCopyToClipboard(): (text: string) => void {
|
||||
return copyToClipboard;
|
||||
}
|
||||
Reference in New Issue
Block a user