(editor: T)
| 14 | import { Editable } from './editable' |
| 15 | |
| 16 | export const withDataTransfer = <T extends Editor>(editor: T) => { |
| 17 | const e = editor as T & Editable |
| 18 | |
| 19 | e.toDataTransfer = range => { |
| 20 | const fragment = e.getFragment(range) |
| 21 | const fragmentString = fragmentToString(fragment) |
| 22 | |
| 23 | const text = fragment.map(node => TextSerializer.transformWithEditor(e, node)).join('\n') |
| 24 | |
| 25 | let html = fragment.map(node => HTMLSerializer.transformWithEditor(e, node)).join('') |
| 26 | html = `<div ${DATA_EDITABLE_FRAGMENT}="${fragmentString}">${html}</div>` |
| 27 | html = `<html><head><meta name="source" content="${DATA_EDITABLE_FRAGMENT}" /></head><body>${html}</body></html>` |
| 28 | const dataTransfer = new DataTransfer() |
| 29 | dataTransfer.setData(TEXT_PLAIN, text) |
| 30 | dataTransfer.setData(TEXT_HTML, html) |
| 31 | dataTransfer.setData(APPLICATION_FRAGMENT_TYPE, fragmentString) |
| 32 | return dataTransfer |
| 33 | } |
| 34 | |
| 35 | e.onCut = event => { |
| 36 | if (event.defaultPrevented) return |
| 37 | const { selection } = e |
| 38 | const { clipboardData } = event |
| 39 | if (clipboardData) writeClipboardData(clipboardData) |
| 40 | if (selection) { |
| 41 | if (Range.isExpanded(selection)) { |
| 42 | Editor.deleteFragment(e) |
| 43 | } else { |
| 44 | const node = Node.parent(e, selection.anchor.path) |
| 45 | if (Editor.isVoid(e, node)) { |
| 46 | Transforms.delete(e) |
| 47 | } |
| 48 | } |
| 49 | } |
| 50 | e.emit('cut', event) |
| 51 | } |
| 52 | |
| 53 | e.onCopy = event => { |
| 54 | if (event.defaultPrevented) return |
| 55 | const { clipboardData } = event |
| 56 | if (clipboardData) writeClipboardData(clipboardData) |
| 57 | e.emit('copy', event) |
| 58 | } |
| 59 | |
| 60 | e.onPaste = event => { |
| 61 | if (event.defaultPrevented) return |
| 62 | const { clipboardData } = event |
| 63 | if (!clipboardData) return |
| 64 | event.preventDefault() |
| 65 | const { text, fragment, html, files } = parseDataTransfer(clipboardData) |
| 66 | const isPasteText = event.type === 'pasteText' |
| 67 | if (!isPasteText && fragment.length > 0) { |
| 68 | e.insertFragment(fragment) |
| 69 | } else if (!isPasteText && html) { |
| 70 | const document = new DOMParser().parseFromString(html, TEXT_HTML) |
| 71 | const fragment = HTMLDeserializer.transformWithEditor(e, document.body) |
| 72 | e.insertFragment(fragment) |
| 73 | } else { |
no test coverage detected