diff --git a/src/components/Editor/EditorReducer.js b/src/components/Editor/EditorReducer.js index 547feec0..51e1cb7d 100644 --- a/src/components/Editor/EditorReducer.js +++ b/src/components/Editor/EditorReducer.js @@ -132,17 +132,33 @@ const reducer = state => ({ state.didSetPos = true } this.dropRedos() + // Update body: const key1 = nodes[0].key - const index1 = state.body.findIndex(each => each.key === key1) - if (index1 === -1) { - throw new Error("FIXME") - } const key2 = nodes[nodes.length - 1].key - const index2 = !atEnd ? state.body.findIndex(each => each.key === key2) : state.body.length - 1 - if (index2 === -1) { + + let index1 = -1; + let index2 = -1; + if(atEnd){ + index2 = state.body.length - 1; + } + for(let i = 0; i < state.body.length; i++) { + let item = state.body[i]; + if(index1 === -1 && item.key === key1){ + index1 = i; + } + if(index2 === -1 && item.key === key2){ + index2 = i; + } + if(index1 !== -1 && index2 !== -1){ + break; + } + } + + if (index1 === -1 || index2 === -1) { throw new Error("FIXME") } + state.body.splice(index1, (index2 + 1) - index1, ...nodes) // Update data, pos1, and pos2: const data = state.body.map(each => each.data).join("\n") diff --git a/src/components/Editor/helpers/getPosFromRange2.js b/src/components/Editor/helpers/getPosFromRange2.js index 1c12c7eb..3e1a4350 100644 --- a/src/components/Editor/helpers/getPosFromRange2.js +++ b/src/components/Editor/helpers/getPosFromRange2.js @@ -5,46 +5,41 @@ function getPosFromRange2(rootNode, node, offset) { y: 0, // The paragraph index pos: 0, // The cursor position } + // NOTE: Gecko/Firefox can select the end element node if (node.nodeType === Node.ELEMENT_NODE && offset && !(offset < node.childNodes.length)) { // return getPosFromRange2(rootNode, null, 0) node = null offset = 0 } - const recurse = startNode => { - const { childNodes } = startNode - let index = 0 - while (index < childNodes.length) { - if (childNodes[index] === node) { - Object.assign(pos, { - x: pos.x + offset, - pos: pos.pos + offset, - }) - return true - } - const { length } = (childNodes[index].nodeValue || "") - Object.assign(pos, { - x: pos.x + length, - pos: pos.pos + length, - }) - if (recurse(childNodes[index])) { - return true - } - const { nextSibling } = childNodes[index] - if (nextSibling && nextSibling.nodeType === Node.ELEMENT_NODE && - // nextSibling.hasAttribute("data-node")) { - (nextSibling.hasAttribute("data-compound-node") || nextSibling.hasAttribute("data-node"))) { - Object.assign(pos, { - x: 0, // Reset - y: pos.y + 1, - pos: pos.pos + 1, - }) + + let walker = document.createTreeWalker(rootNode, NodeFilter.SHOW_ALL, null, false); + + while(walker.nextNode()){ + var cur = walker.currentNode; + if(cur.nodeType === Node.ELEMENT_NODE && + (cur.hasAttribute("data-node") || cur.hasAttribute("data-compound-node")) + ) { + pos.x = 0; + if(pos.pos !== 0){ + pos.y += 1; + pos.pos += 1; } - index++ } - return false + + if(cur === node) { + pos.x += offset; + pos.pos += offset; + return pos; + } + + if(cur.nodeValue){ + const len = cur.nodeValue.length; + pos.x += len; + pos.pos += len; + } } - recurse(rootNode) + return pos }