diff --git a/packages/slate/src/commands/at-range.js b/packages/slate/src/commands/at-range.js
index 52d92bd94..1a13fa9a4 100644
--- a/packages/slate/src/commands/at-range.js
+++ b/packages/slate/src/commands/at-range.js
@@ -662,15 +662,11 @@ Commands.insertBlockAtRange = (editor, range, block) => {
const startInline = document.getClosestInline(startKey)
const parent = document.getParent(startBlock.key)
const index = parent.nodes.indexOf(startBlock)
+ const insertionMode = getInsertionMode(editor, range)
- if (editor.isVoid(startBlock)) {
- const extra = start.isAtEndOfNode(startBlock) ? 1 : 0
- editor.insertNodeByKey(parent.key, index + extra, block)
- } else if (!startInline && startBlock.text === '') {
- editor.insertNodeByKey(parent.key, index + 1, block)
- } else if (start.isAtStartOfNode(startBlock)) {
+ if (insertionMode === 'before') {
editor.insertNodeByKey(parent.key, index, block)
- } else if (start.isAtEndOfNode(startBlock)) {
+ } else if (insertionMode === 'behind') {
editor.insertNodeByKey(parent.key, index + 1, block)
} else {
if (startInline && editor.isVoid(startInline)) {
@@ -694,6 +690,34 @@ Commands.insertBlockAtRange = (editor, range, block) => {
}
}
+/**
+ * Check if current block should be split or new block should be added before or behind it.
+ *
+ * @param {Editor} editor
+ * @param {Range} range
+ */
+
+const getInsertionMode = (editor, range) => {
+ const { value } = editor
+ const { document } = value
+ const { start } = range
+ const startKey = start.key
+ const startBlock = document.getClosestBlock(startKey)
+ const startInline = document.getClosestInline(startKey)
+
+ if (editor.isVoid(startBlock)) {
+ if (start.isAtEndOfNode(startBlock)) return 'behind'
+ else return 'before'
+ } else if (!startInline && startBlock.text === '') {
+ return 'behind'
+ } else if (start.isAtStartOfNode(startBlock)) {
+ return 'before'
+ } else if (start.isAtEndOfNode(startBlock)) {
+ return 'behind'
+ }
+ return 'split'
+}
+
/**
* Insert a `fragment` at a `range`.
*
@@ -744,7 +768,12 @@ Commands.insertFragmentAtRange = (editor, range, fragment) => {
insertionNode === fragment &&
(firstChild.hasBlockChildren() || lastChild.hasBlockChildren())
) {
- fragment.nodes.reverse().forEach(node => {
+ // check if reversal is necessary or not
+ const insertionMode = getInsertionMode(editor, range)
+ const nodes =
+ insertionMode === 'before' ? fragment.nodes : fragment.nodes.reverse()
+
+ nodes.forEach(node => {
editor.insertBlockAtRange(range, node)
})
return
diff --git a/packages/slate/test/commands/at-current-range/insert-fragment/fragment-nested-blocks-end-of-node.js b/packages/slate/test/commands/at-current-range/insert-fragment/fragment-nested-blocks-end-of-node.js
new file mode 100644
index 000000000..06fb7ce9b
--- /dev/null
+++ b/packages/slate/test/commands/at-current-range/insert-fragment/fragment-nested-blocks-end-of-node.js
@@ -0,0 +1,40 @@
+/** @jsx h */
+
+import h from '../../../helpers/h'
+
+export default function(editor) {
+ editor.insertFragment(
+
+
+ one
+ two
+
+ after quote
+
+ )
+}
+
+export const input = (
+
+
+
+ word
+
+
+
+)
+
+export const output = (
+
+
+ word
+
+ one
+ two
+
+
+ after quote
+
+
+
+)
diff --git a/packages/slate/test/commands/at-current-range/insert-fragment/fragment-nested-blocks-start-of-node.js b/packages/slate/test/commands/at-current-range/insert-fragment/fragment-nested-blocks-start-of-node.js
new file mode 100644
index 000000000..f150204e4
--- /dev/null
+++ b/packages/slate/test/commands/at-current-range/insert-fragment/fragment-nested-blocks-start-of-node.js
@@ -0,0 +1,40 @@
+/** @jsx h */
+
+import h from '../../../helpers/h'
+
+export default function(editor) {
+ editor.insertFragment(
+
+
+ one
+ two
+
+ after quote
+
+ )
+}
+
+export const input = (
+
+
+
+ word
+
+
+
+)
+
+export const output = (
+
+
+
+ one
+ two
+
+
+ after quote
+
+ word
+
+
+)