clipboard.ts 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import { Plugin } from '@grafana/slate-react';
  2. import { Editor as CoreEditor } from 'slate';
  3. const getCopiedText = (textBlocks: string[], startOffset: number, endOffset: number) => {
  4. if (!textBlocks.length) {
  5. return undefined;
  6. }
  7. const excludingLastLineLength = textBlocks.slice(0, -1).join('').length + textBlocks.length - 1;
  8. return textBlocks.join('\n').slice(startOffset, excludingLastLineLength + endOffset);
  9. };
  10. export default function ClipboardPlugin(): Plugin {
  11. const clipboardPlugin = {
  12. onCopy(event: ClipboardEvent, editor: CoreEditor) {
  13. event.preventDefault();
  14. const { document, selection } = editor.value;
  15. const {
  16. start: { offset: startOffset },
  17. end: { offset: endOffset },
  18. } = selection;
  19. const selectedBlocks = document
  20. .getLeafBlocksAtRange(selection)
  21. .toArray()
  22. .map(block => block.text);
  23. const copiedText = getCopiedText(selectedBlocks, startOffset, endOffset);
  24. if (copiedText) {
  25. event.clipboardData.setData('Text', copiedText);
  26. }
  27. return true;
  28. },
  29. onPaste(event: ClipboardEvent, editor: CoreEditor) {
  30. event.preventDefault();
  31. const pastedValue = event.clipboardData.getData('Text');
  32. const lines = pastedValue.split('\n');
  33. if (lines.length) {
  34. editor.insertText(lines[0]);
  35. for (const line of lines.slice(1)) {
  36. editor.splitBlock().insertText(line);
  37. }
  38. }
  39. return true;
  40. },
  41. };
  42. return {
  43. ...clipboardPlugin,
  44. onCut(event: ClipboardEvent, editor: CoreEditor) {
  45. clipboardPlugin.onCopy(event, editor);
  46. editor.deleteAtRange(editor.value.selection);
  47. return true;
  48. },
  49. };
  50. }