Skip to content

Commit

Permalink
Fix contenteditalbe firefox table selection (#5491)
Browse files Browse the repository at this point in the history
* Fix firefox contenteditable table selection

* Add changeset

* Update changeset
  • Loading branch information
WcaleNieWolny committed Jul 31, 2023
1 parent c8236ee commit a5576e5
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changeset/itchy-falcons-dream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'slate-react': patch
---

Fix firefox table selection if table is contentedtiable
68 changes: 59 additions & 9 deletions packages/slate-react/src/plugin/react-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(<HTMLElement>element.children[0])
} else {
return element
}
}

const firstNodeRow = <HTMLTableRowElement>firstRange.startContainer
const lastNodeRow = <HTMLTableRowElement>lastRange.startContainer

// This should never fail as "The HTMLElement interface represents any HTML element."
const firstNode = getLastChildren(
<HTMLElement>firstNodeRow.children[firstRange.startOffset]
)
const lastNode = getLastChildren(
<HTMLElement>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 = (<HTMLElement>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
Expand Down

0 comments on commit a5576e5

Please sign in to comment.