1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-13 18:53:59 +02:00

fix(react-editor): reset focus offset when triple clicking (#4512)

* fix(react-editor): reset focus offset when triple clicking

* fix(react editor): remove commented-out code
This commit is contained in:
Trang Le
2021-09-13 23:59:42 +07:00
committed by GitHub
parent 2af6868d41
commit cc7cb623cf

View File

@@ -572,36 +572,49 @@ export const ReactEditor = {
// beginning of the next block // beginning of the next block
if ( if (
IS_CHROME && IS_CHROME &&
anchorNode?.nodeType !== focusNode?.nodeType && anchorNode &&
focusNode &&
anchorNode.nodeType !== focusNode.nodeType &&
domRange.anchorOffset === 0 && domRange.anchorOffset === 0 &&
domRange.focusOffset === 0 && domRange.focusOffset === 0 &&
focusNode?.nodeValue == null focusNode.nodeValue == null
) { ) {
// If an anchorNode is an element node when triple clicked, then the focusNode // If an anchorNode is an element node when triple clicked, then the focusNode
// should also be the same as anchorNode when triple clicked. // should also be the same as anchorNode when triple clicked.
if (anchorNode!.nodeType === 1) { // Otherwise, anchorNode is a text node and we need to
focusNode = anchorNode // - climb up the DOM tree to get the farthest element node that receives
} else { // triple click. It should have atribute 'data-slate-node' = "element"
// Otherwise, anchorNode is a text node and we need to // - get the last child of that element node
// - climb up the DOM tree to get the farthest element node that receives // - climb down the DOM tree to get the text node of the last child
// triple click. It should have atribute 'data-slate-node' = "element" // - this is also the end of the selection aka the focusNode
// - get the last child of that element node const anchorElement = anchorNode.parentNode as HTMLElement
// - climb down the DOM tree to get the text node of the last child const selectedBlock = anchorElement.closest(
// - this is also the end of the selection aka the focusNode '[data-slate-node="element"]'
const anchorElement = anchorNode!.parentNode as HTMLElement )
const tripleClickedBlock = anchorElement.closest( if (selectedBlock) {
'[data-slate-node="element"]' // The Slate Text nodes are leaf-level and contains document's text.
) // However, when represented in the DOM, they are actually Element nodes
const focusElement = tripleClickedBlock!.lastElementChild // and different from the DOM's Text nodes
// Get the element node that holds the focus text node const { childElementCount: slateTextNodeCount } = selectedBlock
// Not every Slate element node contains a child node with `data-slate-string`, if (slateTextNodeCount === 1) {
// such as void nodes, so the result below could be null. focusNode = anchorNode as Text
const innermostFocusElement = focusElement!.querySelector( focusOffset = focusNode.length
'[data-slate-string]' } else if (slateTextNodeCount > 1) {
) // A element with attribute data-slate-node="element" can have multiple
if (innermostFocusElement) { // children with attribute data-slate-node="text". But these children only have
const lastTextNode = innermostFocusElement.childNodes[0] // one child at each level.
focusNode = lastTextNode // <span data-slate-node="text">
// <span data-slate-leaf="">
// <span data-slate-string=""></span>
// </span>
// </span>
const focusElement = selectedBlock.lastElementChild as HTMLElement
const nodeIterator = document.createNodeIterator(
focusElement,
NodeFilter.SHOW_TEXT
)
focusNode = nodeIterator.nextNode() as Text
focusOffset = focusNode.length
} }
} }
} }