feat(editor): Migrate copyPaste mixin to composables (no-changelog) (#8179)

This commit is contained in:
Alex Grozav
2023-12-29 12:13:24 +02:00
committed by GitHub
parent 216ec079c9
commit f5a4bfe40c
27 changed files with 212 additions and 332 deletions

View File

@@ -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);
});
});
});

View 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,
};
}

View File

@@ -1,5 +0,0 @@
import copyToClipboard from 'copy-to-clipboard';
export function useCopyToClipboard(): (text: string) => void {
return copyToClipboard;
}