diff --git a/.changeset/heavy-pants-cover.md b/.changeset/heavy-pants-cover.md
new file mode 100644
index 000000000..4a425bc58
--- /dev/null
+++ b/.changeset/heavy-pants-cover.md
@@ -0,0 +1,5 @@
+---
+'slate': patch
+---
+
+Fix: The `split: true` option on `Transforms.wrapNodes` does not work correctly when one or more points is at the start or end of a text node.
diff --git a/packages/slate/src/transforms-node/wrap-nodes.ts b/packages/slate/src/transforms-node/wrap-nodes.ts
index af2e15760..cae00d9d3 100644
--- a/packages/slate/src/transforms-node/wrap-nodes.ts
+++ b/packages/slate/src/transforms-node/wrap-nodes.ts
@@ -6,6 +6,7 @@ import { Element } from '../interfaces/element'
import { Text } from '../interfaces/text'
import { Range } from '../interfaces/range'
import { Transforms } from '../interfaces/transforms'
+import { Point } from '../interfaces'
export const wrapNodes: NodeTransforms['wrapNodes'] = (
editor,
@@ -33,11 +34,35 @@ export const wrapNodes: NodeTransforms['wrapNodes'] = (
if (split && Range.isRange(at)) {
const [start, end] = Range.edges(at)
+
const rangeRef = Editor.rangeRef(editor, at, {
affinity: 'inward',
})
- Transforms.splitNodes(editor, { at: end, match, voids })
- Transforms.splitNodes(editor, { at: start, match, voids })
+
+ // Always split if we're in the middle of a block, to ensure that text
+ // node boundaries are handled correctly.
+ const isAtBlockEdge = (point: Point) => {
+ const blockAbove = Editor.above(editor, {
+ at: point,
+ match: n => Element.isElement(n) && Editor.isBlock(editor, n),
+ })
+ return blockAbove && Editor.isEdge(editor, point, blockAbove[1])
+ }
+
+ Transforms.splitNodes(editor, {
+ at: end,
+ match,
+ voids,
+ always: !isAtBlockEdge(end),
+ })
+
+ Transforms.splitNodes(editor, {
+ at: start,
+ match,
+ voids,
+ always: !isAtBlockEdge(start),
+ })
+
at = rangeRef.unref()!
if (options.at == null) {
diff --git a/packages/slate/test/transforms/wrapNodes/split-block/block-mark.tsx b/packages/slate/test/transforms/wrapNodes/split-block/block-mark.tsx
new file mode 100644
index 000000000..9b746ee29
--- /dev/null
+++ b/packages/slate/test/transforms/wrapNodes/split-block/block-mark.tsx
@@ -0,0 +1,39 @@
+/** @jsx jsx */
+import { Transforms } from 'slate'
+import { jsx } from '../../..'
+
+export const input = (
+
+
+
+ one
+
+
+ two
+
+
+ three
+
+
+
+)
+export const run = editor => {
+ Transforms.wrapNodes(editor, , { split: true })
+}
+export const output = (
+
+ one
+
+
+
+
+ two
+
+
+
+
+
+ three
+
+
+)
diff --git a/packages/slate/test/transforms/wrapNodes/split-inline/inline-mark.tsx b/packages/slate/test/transforms/wrapNodes/split-inline/inline-mark.tsx
new file mode 100644
index 000000000..9d1ddad1c
--- /dev/null
+++ b/packages/slate/test/transforms/wrapNodes/split-inline/inline-mark.tsx
@@ -0,0 +1,37 @@
+/** @jsx jsx */
+import { Transforms } from 'slate'
+import { jsx } from '../../..'
+
+export const input = (
+
+
+
+ one
+
+
+ two
+
+
+ three
+
+
+
+)
+export const run = editor => {
+ Transforms.wrapNodes(editor, , { split: true })
+}
+export const output = (
+
+
+ one
+
+
+
+ two
+
+
+
+ three
+
+
+)