diff --git a/.changeset/itchy-falcons-dream.md b/.changeset/itchy-falcons-dream.md new file mode 100644 index 000000000..4c1091ec8 --- /dev/null +++ b/.changeset/itchy-falcons-dream.md @@ -0,0 +1,5 @@ +--- +'slate-react': patch +--- + +Fix firefox table selection if table is contentedtiable diff --git a/packages/slate-react/src/plugin/react-editor.ts b/packages/slate-react/src/plugin/react-editor.ts index f2e56ba30..3653c99c0 100644 --- a/packages/slate-react/src/plugin/react-editor.ts +++ b/packages/slate-react/src/plugin/react-editor.ts @@ -836,16 +836,66 @@ export const ReactEditor: ReactEditorInterface = { const firstRange = domRange.getRangeAt(0) const lastRange = domRange.getRangeAt(domRange.rangeCount - 1) - // Right to left - if (firstRange.startContainer === focusNode) { - anchorNode = lastRange.endContainer - anchorOffset = lastRange.endOffset - focusOffset = firstRange.startOffset + // Here we are in the contenteditable mode of a table in firefox + if ( + focusNode instanceof HTMLTableRowElement && + firstRange.startContainer instanceof HTMLTableRowElement && + lastRange.startContainer instanceof HTMLTableRowElement + ) { + // HTMLElement, becouse Element is a slate element + function getLastChildren(element: HTMLElement): HTMLElement { + if (element.childElementCount > 0) { + return getLastChildren(element.children[0]) + } else { + return element + } + } + + const firstNodeRow = firstRange.startContainer + const lastNodeRow = lastRange.startContainer + + // This should never fail as "The HTMLElement interface represents any HTML element." + const firstNode = getLastChildren( + firstNodeRow.children[firstRange.startOffset] + ) + const lastNode = getLastChildren( + lastNodeRow.children[lastRange.startOffset] + ) + + // Zero, as we allways take the right one as the anchor point + focusOffset = 0 + + if (lastNode.childNodes.length > 0) { + anchorNode = lastNode.childNodes[0] + } else { + anchorNode = lastNode + } + + if (firstNode.childNodes.length > 0) { + focusNode = firstNode.childNodes[0] + } else { + focusNode = firstNode + } + + if (lastNode instanceof HTMLElement) { + anchorOffset = (lastNode).innerHTML.length + } else { + // Fallback option + anchorOffset = 0 + } } else { - // Left to right - anchorNode = firstRange.startContainer - anchorOffset = firstRange.endOffset - focusOffset = lastRange.startOffset + // This is the read only mode of a firefox table + // Right to left + if (firstRange.startContainer === focusNode) { + anchorNode = lastRange.endContainer + anchorOffset = lastRange.endOffset + focusOffset = firstRange.startOffset + } else { + // Left to right + anchorNode = firstRange.startContainer + anchorOffset = firstRange.endOffset + focusOffset = lastRange.startOffset + } } } else { anchorNode = domRange.anchorNode