diff --git a/packages/slate/src/commands/by-path.js b/packages/slate/src/commands/by-path.js
index 836f496cd..c3615e6c1 100644
--- a/packages/slate/src/commands/by-path.js
+++ b/packages/slate/src/commands/by-path.js
@@ -194,6 +194,12 @@ Commands.mergeNodeByPath = (change, path) => {
Commands.moveNodeByPath = (change, path, newPath, newIndex) => {
const { value } = change
+ // If the operation path and newPath are the same,
+ // this should be considered a NOOP
+ if (PathUtils.isEqual(path, newPath)) {
+ return change
+ }
+
change.applyOperation({
type: 'move_node',
value,
diff --git a/packages/slate/src/controllers/change.js b/packages/slate/src/controllers/change.js
index 5594722e6..a26a0c5b0 100644
--- a/packages/slate/src/controllers/change.js
+++ b/packages/slate/src/controllers/change.js
@@ -353,6 +353,10 @@ function getDirtyPaths(operation) {
let parentPath = PathUtils.lift(path)
let newParentPath = PathUtils.lift(newPath)
+ if (PathUtils.isEqual(path, newPath)) {
+ return []
+ }
+
// HACK: this clause only exists because the `move_path` logic isn't
// consistent when it deals with siblings.
if (!PathUtils.isSibling(path, newPath)) {
diff --git a/packages/slate/src/operations/apply.js b/packages/slate/src/operations/apply.js
index de782e7e5..9a93abf75 100644
--- a/packages/slate/src/operations/apply.js
+++ b/packages/slate/src/operations/apply.js
@@ -1,6 +1,7 @@
import Debug from 'debug'
import Operation from '../models/operation'
+import PathUtils from '../utils/path-utils'
/**
* Debug.
@@ -50,6 +51,11 @@ function applyOperation(value, op) {
case 'move_node': {
const { path, newPath } = op
+
+ if (PathUtils.isEqual(path, newPath)) {
+ return value
+ }
+
const next = value.moveNode(path, newPath)
return next
}
diff --git a/packages/slate/src/operations/invert.js b/packages/slate/src/operations/invert.js
index fb68a175d..781a18dbd 100644
--- a/packages/slate/src/operations/invert.js
+++ b/packages/slate/src/operations/invert.js
@@ -37,6 +37,11 @@ function invertOperation(op) {
case 'move_node': {
const { newPath, path } = op
+
+ if (PathUtils.isEqual(newPath, path)) {
+ return op
+ }
+
let inversePath = newPath
let inverseNewPath = path
diff --git a/packages/slate/test/commands/by-path/move-node-by-path/path-equals-new-path.js b/packages/slate/test/commands/by-path/move-node-by-path/path-equals-new-path.js
new file mode 100644
index 000000000..148145a4e
--- /dev/null
+++ b/packages/slate/test/commands/by-path/move-node-by-path/path-equals-new-path.js
@@ -0,0 +1,34 @@
+/** @jsx h */
+
+import h from '../../../helpers/h'
+import PathUtils from '../../../../src/utils/path-utils'
+import assert from 'assert'
+
+const pathA = PathUtils.create([0])
+const pathB = PathUtils.create([1])
+
+export default function(change) {
+ change.moveNodeByPath(pathA, pathA, 0)
+ change.moveNodeByPath(pathA, pathA, 1)
+ change.moveNodeByPath(pathB, pathB, 0)
+ change.moveNodeByPath(pathB, pathB, 1)
+ assert(change.operations.size === 0)
+}
+
+export const input = (
+
+
+ 1
+ 2
+
+
+)
+
+export const output = (
+
+
+ 1
+ 2
+
+
+)
diff --git a/packages/slate/test/operations/apply/move-node/path-equals-new-path.js b/packages/slate/test/operations/apply/move-node/path-equals-new-path.js
new file mode 100644
index 000000000..6dda7b5ba
--- /dev/null
+++ b/packages/slate/test/operations/apply/move-node/path-equals-new-path.js
@@ -0,0 +1,29 @@
+/** @jsx h */
+
+import h from '../../../helpers/h'
+
+export default [
+ {
+ type: 'move_node',
+ path: [0],
+ newPath: [0],
+ },
+]
+
+export const input = (
+
+
+ 1
+ 2
+
+
+)
+
+export const output = (
+
+
+ 1
+ 2
+
+
+)