1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | 1× 18× 18× 18× 18× 6× 12× 10× 2× 2× 18× 1× 6× 6× 6× 6× 6× 6× 6× 6× 6× 6× 1× 1× 1× 1× 1× 6× 1× 10× 10× 10× 10× 10× 10× 10× 10× 10× 10× 10× 22× 22× 22× 22× 22× 22× 31× 31× 22× 10× 10× 10× 7× 3× 3× 10× 10× 10× 6× 4× 4× 10× 1× 2× 2× 2× 2× 2× 8× 2× 2× | import { cloneDeep, forEach } from '../util' import Document from './Document' import documentHelpers from './documentHelpers' import { isFirst, isLast } from './selectionHelpers' /** Creates a new document instance containing only the selected content @param {Object} args object with `selection` @return {Object} with a `doc` property that has a fresh doc with the copied content */ export default function copySelection(doc, selection) { Iif (!selection) throw new Error("'selection' is mandatory.") let copy = null Eif (!selection.isNull() && !selection.isCollapsed()) { // return a simplified version if only a piece of text is selected if (selection.isPropertySelection()) { copy = _copyPropertySelection(doc, selection) } else if (selection.isContainerSelection()) { copy = _copyContainerSelection(doc, selection) } else Eif (selection.isNodeSelection()) { copy = _copyNodeSelection(doc, selection) } else { console.error('Copy is not yet supported for selection type.') } } return copy } function _copyPropertySelection(doc, selection) { let path = selection.start.path let offset = selection.start.offset let endOffset = selection.end.offset let text = doc.get(path) let snippet = doc.createSnippet() let containerNode = snippet.getContainer() snippet.create({ type: doc.schema.getDefaultTextType(), id: Document.TEXT_SNIPPET_ID, content: text.substring(offset, endOffset) }) containerNode.show(Document.TEXT_SNIPPET_ID) let annotations = doc.getIndex('annotations').get(path, offset, endOffset) forEach(annotations, function(anno) { let data = cloneDeep(anno.toJSON()) let path = [Document.TEXT_SNIPPET_ID, 'content'] data.start = { path: path, offset: Math.max(offset, anno.start.offset)-offset } data.end = { path: path, offset: Math.min(endOffset, anno.end.offset)-offset } snippet.create(data) }) return snippet } function _copyContainerSelection(tx, sel) { let snippet = tx.createSnippet() let container = snippet.getContainer() let nodeIds = sel.getNodeIds() let L = nodeIds.length Iif (L === 0) return snippet let start = sel.start let end = sel.end let skippedFirst = false let skippedLast = false // First copy the whole covered nodes let created = {} for(let i = 0; i<L; i++) { let id = nodeIds[i] let node = tx.get(id) // skip NIL selections, such as cursor at the end of first node or cursor at the start of last node. Iif (i===0 && isLast(tx, start)) { skippedFirst = true continue } Iif (i===L-1 && isFirst(tx, end)) { skippedLast = true continue } Eif (!created[id]) { documentHelpers.copyNode(node).forEach((nodeData) => { let copy = snippet.create(nodeData) created[copy.id] = true }) container.show(id) } } Eif (!skippedFirst) { // ATTENTION: we need the root node here, e.g. the list, not the list items let startNode = snippet.get(start.getNodeId()).getRoot() if (startNode.isText()) { documentHelpers.deleteTextRange(snippet, null, start) } else Eif (startNode.isList()) { documentHelpers.deleteListRange(snippet, startNode, null, start) } } Eif (!skippedLast) { // ATTENTION: we need the root node here, e.g. the list, not the list items let endNode = snippet.get(end.getNodeId()).getRoot() if (endNode.isText()) { documentHelpers.deleteTextRange(snippet, end, null) } else Eif (endNode.isList()) { documentHelpers.deleteListRange(snippet, endNode, end, null) } } return snippet } function _copyNodeSelection(doc, selection) { let snippet = doc.createSnippet() let containerNode = snippet.getContainer() let nodeId = selection.getNodeId() let node = doc.get(nodeId) documentHelpers.copyNode(node).forEach((nodeData) => { snippet.create(nodeData) }) containerNode.show(node.id) return snippet } |