Repository: ianstormtaylor/slate
File: packages/slate-react/src/plugin/react-editor.ts (TypeScript)

Code before:

        // COMPAT: In read-only editors the leaf is not rendered.
        if (!leafNode) {
          offset = 1
        } else {
          textNode = leafNode.closest('[data-slate-node="text"]')!
          domNode = leafNode
          offset = domNode.textContent!.length
          domNode.querySelectorAll('[data-slate-zero-width]').forEach(el => {
            offset -= el.textContent!.length
          })
        }
      } else if (nonEditableNode) {
        // Find the edge of the nearest leaf in `searchDirection` from the
        // non-editable node
        const leafNodes = Array.from(
          editorEl.querySelectorAll(
            // This editor's leaves (not those of a nested editor)
            '[data-slate-leaf]:not(:scope [data-slate-editor] [data-slate-leaf])'
          )
        )
        leafNode =
          (searchDirection === 'forward'
            ? leafNodes.find(leaf => isAfter(nonEditableNode, leaf))
            : leafNodes.findLast(leaf => isBefore(nonEditableNode, leaf))) ??
          null

        if (!leafNode) {
          offset = 1
        } else {
          textNode = leafNode.closest('[data-slate-node="text"]')!
          domNode = leafNode
          if (searchDirection === 'forward') {
            offset = 0
          } else {
            offset = domNode.textContent!.length
            domNode.querySelectorAll('[data-slate-zero-width]').forEach(el => {
              offset -= el.textContent!.length
            })
          }
        }
      }

      if (
        domNode &&
        offset === domNode.textContent!.length &&
        // COMPAT: Android IMEs might remove the zero width space while composing,
        // and we don't add it for line-breaks.
        IS_ANDROID &&
        domNode.getAttribute('data-slate-zero-width') === 'z' &&
        domNode.textContent?.startsWith('\uFEFF') &&

Review comment (suggestion):
I've thought of a possible optimization here. Currently, `leafNodes` is a collection of all leaf nodes in the entire editor. But since all Slate elements contain leaves, the furthest we should have to search from the `nonEditableNode` is one element away. I'm going to edit this so that `leafNodes` contains only the leaf nodes in the current Slate element and the element next to it in `searchDirection`. That should remove a lot of unnecessary iteration in the `.find` or `.findLast` call.

Code after:

        // COMPAT: In read-only editors the leaf is not rendered.
        if (!leafNode) {
          offset = 1
        } else {
          textNode = leafNode.closest('[data-slate-node="text"]')!
          domNode = leafNode
          offset = domNode.textContent!.length
          domNode.querySelectorAll('[data-slate-zero-width]').forEach(el => {
            offset -= el.textContent!.length
          })
        }
      } else if (nonEditableNode) {
        // Find the edge of the nearest leaf in `searchDirection`
        const getLeafNodes = (node: DOMElement | null | undefined) =>
          node
            ? node.querySelectorAll(
                // Exclude leaf nodes in nested editors
                '[data-slate-leaf]:not(:scope [data-slate-editor] [data-slate-leaf])'
              )
            : []
        const elementNode = nonEditableNode.closest(
          '[data-slate-node="element"]'
        )

        if (searchDirection === 'forward') {
          const leafNodes = [
            ...getLeafNodes(elementNode),
            ...getLeafNodes(elementNode?.nextElementSibling),
          ]
          leafNode =
            leafNodes.find(leaf => isAfter(nonEditableNode, leaf)) ?? null
        } else {
          const leafNodes = [
            ...getLeafNodes(elementNode?.previousElementSibling),
            ...getLeafNodes(elementNode),
          ]
          leafNode =
            leafNodes.findLast(leaf => isBefore(nonEditableNode, leaf)) ?? null
        }

        if (leafNode) {
          textNode = leafNode.closest('[data-slate-node="text"]')!
          domNode = leafNode
          if (searchDirection === 'forward') {
            offset = 0
          } else {
            offset = domNode.textContent!.length
            domNode.querySelectorAll('[data-slate-zero-width]').forEach(el => {
              offset -= el.textContent!.length
            })