diff --git a/src/transforms/at-current-range.js b/src/transforms/at-current-range.js index cf683a67a..adb130ac3 100644 --- a/src/transforms/at-current-range.js +++ b/src/transforms/at-current-range.js @@ -312,10 +312,28 @@ export function splitBlock(transform, depth = 1) { state = transform.state document = state.document - const { startKey } = selection - const startNode = document.getDescendant(startKey) - const nextNode = document.getNextText(startNode.key) - const after = selection.collapseToStartOf(nextNode) + const { startKey, startOffset } = selection + const startText = document.getNode(startKey) + const startBlock = document.getClosestBlock(startKey) + const startInline = startBlock.getFurthestInline(startKey) + const nextText = document.getNextText(startText.key) + let after + + // If the selection is at the start of the highest inline child inside the + // block, the starting text node won't need to be split. + if ( + (startOffset == 0) && + (startBlock.text != '') && + (!startInline || startInline.getOffset(startText.key) == 0) + ) { + after = selection.collapseToStartOf(startText) + } + + // Otherwise, we'll need to move the selection forward one to account for the + // text node that was split. + else { + after = selection.collapseToStartOf(nextText) + } return transform.moveTo(after) } diff --git a/test/transforms/fixtures/at-current-range/split-block/before-inline/index.js b/test/transforms/fixtures/at-current-range/split-block/before-inline/index.js new file mode 100644 index 000000000..09cb21230 --- /dev/null +++ b/test/transforms/fixtures/at-current-range/split-block/before-inline/index.js @@ -0,0 +1,29 @@ + +import assert from 'assert' + +export default function (state) { + const { document, selection } = state + const texts = document.getTexts() + const second = texts.get(1) + const range = selection.merge({ + anchorKey: second.key, + anchorOffset: 0, + focusKey: second.key, + focusOffset: 0 + }) + + const next = state + .transform() + .moveTo(range) + .splitBlock() + .apply() + + const updated = next.document.getTexts().get(1) + + assert.deepEqual( + next.selection.toJS(), + range.collapseToStartOf(updated).toJS() + ) + + return next +} diff --git a/test/transforms/fixtures/at-current-range/split-block/before-inline/input.yaml b/test/transforms/fixtures/at-current-range/split-block/before-inline/input.yaml new file mode 100644 index 000000000..cd77b2980 --- /dev/null +++ b/test/transforms/fixtures/at-current-range/split-block/before-inline/input.yaml @@ -0,0 +1,16 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: word + - kind: inline + type: link + data: + href: 'website.com' + nodes: + - kind: text + text: hyperlink + - kind: text + text: word diff --git a/test/transforms/fixtures/at-current-range/split-block/before-inline/output.yaml b/test/transforms/fixtures/at-current-range/split-block/before-inline/output.yaml new file mode 100644 index 000000000..aeb0b0161 --- /dev/null +++ b/test/transforms/fixtures/at-current-range/split-block/before-inline/output.yaml @@ -0,0 +1,19 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: word + - kind: block + type: paragraph + nodes: + - kind: inline + type: link + data: + href: 'website.com' + nodes: + - kind: text + text: hyperlink + - kind: text + text: word