@lexical/offset
Advanced tools
Comparing version 0.8.1 to 0.9.0
@@ -18,7 +18,10 @@ /** | ||
} | ||
createSelectionFromOffsets(originalStart, originalEnd, diffOffsetView) { | ||
const firstNode = this._firstNode; | ||
if (firstNode === null) { | ||
return null; | ||
} | ||
let start = originalStart; | ||
@@ -28,2 +31,3 @@ let end = originalEnd; | ||
let endOffsetNode = $searchForNodeWithOffset(firstNode, end, this._blockOffsetSize); | ||
if (diffOffsetView !== undefined) { | ||
@@ -35,5 +39,7 @@ start = $getAdjustedOffsetFromDiff(start, startOffsetNode, diffOffsetView, this, this._blockOffsetSize); | ||
} | ||
if (startOffsetNode === null || endOffsetNode === null) { | ||
return null; | ||
} | ||
let startKey = startOffsetNode.key; | ||
@@ -43,5 +49,7 @@ let endKey = endOffsetNode.key; | ||
const endNode = lexical.$getNodeByKey(endKey); | ||
if (startNode === null || endNode === null) { | ||
return null; | ||
} | ||
let startOffset = 0; | ||
@@ -51,9 +59,11 @@ let endOffset = 0; | ||
let endType = 'element'; | ||
if (startOffsetNode.type === 'text') { | ||
startOffset = start - startOffsetNode.start; | ||
startType = 'text'; | ||
// If we are at the edge of a text node and we | ||
startType = 'text'; // If we are at the edge of a text node and we | ||
// don't have a collapsed selection, then let's | ||
// try and correct the offset node. | ||
const sibling = startNode.getNextSibling(); | ||
if (start !== end && startOffset === startNode.getTextContentSize() && lexical.$isTextNode(sibling)) { | ||
@@ -67,2 +77,3 @@ startOffset = 0; | ||
} | ||
if (endOffsetNode.type === 'text') { | ||
@@ -75,6 +86,9 @@ endOffset = end - endOffsetNode.start; | ||
} | ||
const selection = lexical.$createRangeSelection(); | ||
if (selection === null) { | ||
return null; | ||
} | ||
selection.anchor.set(startKey, startOffset, startType); | ||
@@ -84,2 +98,3 @@ selection.focus.set(endKey, endOffset, endType); | ||
} | ||
getOffsetsFromSelection(selection) { | ||
@@ -93,4 +108,6 @@ const anchor = selection.anchor; | ||
let end = -1; | ||
if (anchor.type === 'text') { | ||
const offsetNode = offsetMap.get(anchor.key); | ||
if (offsetNode !== undefined) { | ||
@@ -101,4 +118,6 @@ start = offsetNode.start + anchorOffset; | ||
const node = anchor.getNode().getDescendantByIndex(anchorOffset); | ||
if (node !== null) { | ||
const offsetNode = offsetMap.get(node.getKey()); | ||
if (offsetNode !== undefined) { | ||
@@ -110,4 +129,6 @@ const isAtEnd = node.getIndexWithinParent() !== anchorOffset; | ||
} | ||
if (focus.type === 'text') { | ||
const offsetNode = offsetMap.get(focus.key); | ||
if (offsetNode !== undefined) { | ||
@@ -118,4 +139,6 @@ end = offsetNode.start + focus.offset; | ||
const node = focus.getNode().getDescendantByIndex(focusOffset); | ||
if (node !== null) { | ||
const offsetNode = offsetMap.get(node.getKey()); | ||
if (offsetNode !== undefined) { | ||
@@ -127,5 +150,8 @@ const isAtEnd = node.getIndexWithinParent() !== focusOffset; | ||
} | ||
return [start, end]; | ||
} | ||
} | ||
function $getAdjustedOffsetFromDiff(offset, offsetNode, prevOffsetView, offsetView, blockOffsetSize) { | ||
@@ -137,2 +163,3 @@ const prevOffsetMap = prevOffsetView._offsetMap; | ||
let currentNode = offsetNode; | ||
while (currentNode !== null) { | ||
@@ -143,2 +170,3 @@ const key = currentNode.key; | ||
visited.add(key); | ||
if (prevNode === undefined) { | ||
@@ -148,2 +176,3 @@ adjustedOffset += diff; | ||
const prevDiff = prevNode.end - prevNode.start; | ||
if (prevDiff !== diff) { | ||
@@ -153,3 +182,5 @@ adjustedOffset += diff - prevDiff; | ||
} | ||
const sibling = currentNode.prev; | ||
if (sibling !== null) { | ||
@@ -159,5 +190,8 @@ currentNode = sibling; | ||
} | ||
let parent = currentNode.parent; | ||
while (parent !== null) { | ||
let parentSibling = parent.prev; | ||
if (parentSibling !== null) { | ||
@@ -168,2 +202,3 @@ const parentSiblingKey = parentSibling.key; | ||
visited.add(parentSiblingKey); | ||
if (prevParentSibling === undefined) { | ||
@@ -173,2 +208,3 @@ adjustedOffset += parentDiff; | ||
const prevParentDiff = prevParentSibling.end - prevParentSibling.start; | ||
if (prevParentDiff !== parentDiff) { | ||
@@ -178,16 +214,21 @@ adjustedOffset += parentDiff - prevParentDiff; | ||
} | ||
parentSibling = parentSibling.prev; | ||
} | ||
parent = parent.parent; | ||
} | ||
break; | ||
} | ||
// Now traverse through the old offsets nodes and find any nodes we missed | ||
} // Now traverse through the old offsets nodes and find any nodes we missed | ||
// above, because they were not in the latest offset node view (they have been | ||
// deleted). | ||
const prevFirstNode = prevOffsetView._firstNode; | ||
if (prevFirstNode !== null) { | ||
currentNode = $searchForNodeWithOffset(prevFirstNode, offset, blockOffsetSize); | ||
let alreadyVisitedParentOfCurrentNode = false; | ||
while (currentNode !== null) { | ||
@@ -198,10 +239,14 @@ if (!visited.has(currentNode.key)) { | ||
} | ||
currentNode = currentNode.parent; | ||
} | ||
if (!alreadyVisitedParentOfCurrentNode) { | ||
while (currentNode !== null) { | ||
const key = currentNode.key; | ||
if (!visited.has(key)) { | ||
const node = offsetMap.get(key); | ||
const prevDiff = currentNode.end - currentNode.start; | ||
if (node === undefined) { | ||
@@ -211,2 +256,3 @@ adjustedOffset -= prevDiff; | ||
const diff = node.end - node.start; | ||
if (prevDiff !== diff) { | ||
@@ -217,2 +263,3 @@ adjustedOffset += diff - prevDiff; | ||
} | ||
currentNode = currentNode.prev; | ||
@@ -222,10 +269,15 @@ } | ||
} | ||
return adjustedOffset; | ||
} | ||
function $searchForNodeWithOffset(firstNode, offset, blockOffsetSize) { | ||
let currentNode = firstNode; | ||
while (currentNode !== null) { | ||
const end = currentNode.end + (currentNode.type !== 'element' || blockOffsetSize === 0 ? 1 : 0); | ||
if (offset < end) { | ||
const child = currentNode.child; | ||
if (child !== null) { | ||
@@ -235,12 +287,18 @@ currentNode = child; | ||
} | ||
return currentNode; | ||
} | ||
const sibling = currentNode.next; | ||
if (sibling === null) { | ||
break; | ||
} | ||
currentNode = sibling; | ||
} | ||
return null; | ||
} | ||
function $createInternalOffsetNode(child, type, start, end, key, parent) { | ||
@@ -258,4 +316,6 @@ return { | ||
} | ||
function $createOffsetNode(state, key, parent, nodeMap, offsetMap, blockOffsetSize) { | ||
const node = nodeMap.get(key); | ||
if (node === undefined) { | ||
@@ -266,10 +326,11 @@ { | ||
} | ||
const start = state.offset; | ||
if (lexical.$isElementNode(node)) { | ||
const childKeys = createChildrenArray(node, nodeMap); | ||
const blockIsEmpty = childKeys.length === 0; | ||
const child = blockIsEmpty ? null : $createOffsetChild(state, childKeys, null, nodeMap, offsetMap, blockOffsetSize); | ||
const child = blockIsEmpty ? null : $createOffsetChild(state, childKeys, null, nodeMap, offsetMap, blockOffsetSize); // If the prev node was not a block or the block is empty, we should | ||
// account for the user being able to selection the block (due to the \n). | ||
// If the prev node was not a block or the block is empty, we should | ||
// account for the user being able to selection the block (due to the \n). | ||
if (!state.prevIsBlock || blockIsEmpty) { | ||
@@ -279,6 +340,9 @@ state.prevIsBlock = true; | ||
} | ||
const offsetNode = $createInternalOffsetNode(child, 'element', start, start, key, parent); | ||
if (child !== null) { | ||
child.parent = offsetNode; | ||
} | ||
const end = state.offset; | ||
@@ -289,2 +353,3 @@ offsetNode.end = end; | ||
} | ||
state.prevIsBlock = false; | ||
@@ -298,2 +363,3 @@ const isText = lexical.$isTextNode(node); | ||
} | ||
function $createOffsetChild(state, children, parent, nodeMap, offsetMap, blockOffsetSize) { | ||
@@ -303,5 +369,7 @@ let firstNode = null; | ||
const childrenLength = children.length; | ||
for (let i = 0; i < childrenLength; i++) { | ||
const childKey = children[i]; | ||
const offsetNode = $createOffsetNode(state, childKey, parent, nodeMap, offsetMap, blockOffsetSize); | ||
if (currentNode === null) { | ||
@@ -313,11 +381,16 @@ firstNode = offsetNode; | ||
} | ||
currentNode = offsetNode; | ||
} | ||
return firstNode; | ||
} | ||
function createChildrenArray(element, nodeMap) { | ||
const children = []; | ||
let nodeKey = element.__first; | ||
while (nodeKey !== null) { | ||
const node = nodeMap === null ? lexical.$getNodeByKey(nodeKey) : nodeMap.get(nodeKey); | ||
if (node === null || node === undefined) { | ||
@@ -328,5 +401,7 @@ { | ||
} | ||
children.push(nodeKey); | ||
nodeKey = node.__next; | ||
} | ||
return children; | ||
@@ -333,0 +408,0 @@ } |
@@ -11,6 +11,6 @@ { | ||
"license": "MIT", | ||
"version": "0.8.1", | ||
"version": "0.9.0", | ||
"main": "LexicalOffset.js", | ||
"peerDependencies": { | ||
"lexical": "0.8.1" | ||
"lexical": "0.9.0" | ||
}, | ||
@@ -17,0 +17,0 @@ "repository": { |
20309
389